mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 17:38:10 +00:00
- 适配器 worker 池化:单 LState+全局锁(串行瓶颈)→ 每 adapter 一个 gopher-lua LState 池,按使用该 adapter 的源并发上限求和配置池大小,并发 transform 互不阻塞 - staticInfo 预提取:name/version/endpoint/headers 加载期编译缓存,Endpoint/Headers 读缓存不占 worker;加载即预编译首个 worker - build_headers 动态钩子 + hmac/sha256/base64/tohex 全局:签名型上游(kimicode 等)可接入 - provider applyAdapterHeaders 接入动态头(url/method/body/api_key/timestamp/source 元数据), 未定义时回落静态 headers,缺省补 Authorization - LLMSource.MaxConcurrent + core.llm.sources.<name>.max_concurrent,注册时汇总 VM.ConfigureConcurrency - 新增 Lua VM 测试(load/transform/build_headers/并发) 验证: go test ./... 27 包 0 失败;Windows 交叉编译通过;部署后 9 adapter 全部预加载
137 lines
3.2 KiB
Go
137 lines
3.2 KiB
Go
package lua
|
|
|
|
import (
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
func TestVMLoadAndTransform(t *testing.T) {
|
|
vm := NewVM(t.TempDir())
|
|
if err := vm.Start(); err != nil {
|
|
t.Fatalf("start vm: %v", err)
|
|
}
|
|
defer vm.Stop()
|
|
|
|
out, err := vm.CallTransformRequest("openai", `{"model":"x"}`)
|
|
if err != nil {
|
|
t.Fatalf("transform_request: %v", err)
|
|
}
|
|
if !strings.Contains(out, `"model":"x"`) {
|
|
t.Fatalf("unexpected output: %s", out)
|
|
}
|
|
|
|
ep := vm.GetAdapterEndpoint("openai")
|
|
if ep == "" {
|
|
t.Fatal("openai endpoint empty")
|
|
}
|
|
hdrs := vm.GetAdapterHeaders("openai")
|
|
if hdrs == nil {
|
|
t.Fatal("openai headers nil")
|
|
}
|
|
}
|
|
|
|
func TestVMLoadCustomAdapter(t *testing.T) {
|
|
vm := NewVM(t.TempDir())
|
|
if err := vm.Start(); err != nil {
|
|
t.Fatalf("start vm: %v", err)
|
|
}
|
|
defer vm.Stop()
|
|
|
|
code := `
|
|
local adapter = {}
|
|
adapter.name = "testa"
|
|
adapter.version = "1.0"
|
|
adapter.endpoint = "/x"
|
|
adapter.headers = { ["X-A"] = "1" }
|
|
function adapter.transform_request(raw) return "REQ" end
|
|
function adapter.build_headers(meta) return { ["X-Key"] = "k" } end
|
|
function adapter.transform_response(raw) return "RESP" end
|
|
function adapter.transform_stream_chunk(raw) return "CHUNK" end
|
|
return adapter
|
|
`
|
|
if err := vm.LoadAdapterSource("testa", code); err != nil {
|
|
t.Fatalf("load adapter: %v", err)
|
|
}
|
|
|
|
if out, err := vm.CallTransformRequest("testa", "x"); err != nil || out != "REQ" {
|
|
t.Fatalf("req=%q err=%v", out, err)
|
|
}
|
|
if out, err := vm.CallTransformResponse("testa", "x"); err != nil || out != "RESP" {
|
|
t.Fatalf("resp=%q err=%v", out, err)
|
|
}
|
|
if out, err := vm.CallTransformStreamChunk("testa", "x"); err != nil || out != "CHUNK" {
|
|
t.Fatalf("chunk=%q err=%v", out, err)
|
|
}
|
|
|
|
meta := map[string]interface{}{"url": "http://x", "api_key": "k1"}
|
|
hdrs, err := vm.BuildHeaders("testa", meta)
|
|
if err != nil {
|
|
t.Fatalf("build_headers: %v", err)
|
|
}
|
|
if hdrs["X-Key"] != "k" {
|
|
t.Fatalf("missing dynamic header: %v", hdrs)
|
|
}
|
|
|
|
if ep := vm.GetAdapterEndpoint("testa"); ep != "/x" {
|
|
t.Fatalf("endpoint=%q", ep)
|
|
}
|
|
if st := vm.GetAdapterHeaders("testa"); st["X-A"] != "1" {
|
|
t.Fatalf("static headers=%v", st)
|
|
}
|
|
}
|
|
|
|
func TestVMLoadStaticHeaderFallback(t *testing.T) {
|
|
vm := NewVM(t.TempDir())
|
|
if err := vm.Start(); err != nil {
|
|
t.Fatalf("start vm: %v", err)
|
|
}
|
|
defer vm.Stop()
|
|
|
|
code := `
|
|
local adapter = {}
|
|
adapter.name = "statics"
|
|
adapter.headers = { ["X-S"] = "s" }
|
|
function adapter.transform_request(raw) return raw end
|
|
return adapter
|
|
`
|
|
if err := vm.LoadAdapterSource("statics", code); err != nil {
|
|
t.Fatalf("load: %v", err)
|
|
}
|
|
hdrs, err := vm.BuildHeaders("statics", nil)
|
|
if err != nil {
|
|
t.Fatalf("build_headers: %v", err)
|
|
}
|
|
if hdrs["X-S"] != "s" {
|
|
t.Fatalf("expected static fallback, got %v", hdrs)
|
|
}
|
|
}
|
|
|
|
func TestVMConcurrentCalls(t *testing.T) {
|
|
vm := NewVM(t.TempDir())
|
|
if err := vm.Start(); err != nil {
|
|
t.Fatalf("start vm: %v", err)
|
|
}
|
|
defer vm.Stop()
|
|
|
|
var wg sync.WaitGroup
|
|
errs := make(chan error, 40)
|
|
for i := 0; i < 20; i++ {
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
for j := 0; j < 10; j++ {
|
|
_, err := vm.CallTransformRequest("openai", `{"model":"x"}`)
|
|
if err != nil {
|
|
errs <- err
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
close(errs)
|
|
for err := range errs {
|
|
t.Fatalf("concurrent call: %v", err)
|
|
}
|
|
} |