Files
HomeAgent/internal/sdk/llm_impl.go
root f0dacef281 lua: 吸收 llmsproxy 适配器高级特性(worker 池/静态预提取/动态签名钩子)
- 适配器 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 全部预加载
2026-08-10 11:29:57 +08:00

147 lines
3.7 KiB
Go

package sdk
import (
"context"
"fmt"
agentAPI "gitcode.com/JianFeeeee/HomeAgent/internal/agent/api"
internalConfig "gitcode.com/JianFeeeee/HomeAgent/internal/config"
luaVM "gitcode.com/JianFeeeee/HomeAgent/internal/lua"
)
type llmImpl struct {
mgr *agentAPI.ProviderManager
cfgReg *internalConfig.ConfigRegistry
lua *luaVM.VM
baseAPIKey string
}
func NewLLM(mgr *agentAPI.ProviderManager, cfgReg *internalConfig.ConfigRegistry, lua *luaVM.VM, baseAPIKey string) LLMAPI {
return &llmImpl{mgr: mgr, cfgReg: cfgReg, lua: lua, baseAPIKey: baseAPIKey}
}
func (l *llmImpl) ListSources() []string {
if l.mgr == nil {
return nil
}
return l.mgr.List()
}
func (l *llmImpl) SetSource(name string) error {
if l.mgr == nil {
return nil
}
return l.mgr.SetDefault(name)
}
func (l *llmImpl) CurrentSource() string {
if l.mgr == nil {
return ""
}
p := l.mgr.Default()
if p == nil {
return ""
}
return p.Name()
}
func (l *llmImpl) Chat(ctx context.Context, req *LLMCompletionRequest) (*LLMCompletionResponse, error) {
if l.mgr == nil {
return nil, fmt.Errorf("llm: provider manager not available")
}
p := l.mgr.Default()
if p == nil {
return nil, fmt.Errorf("llm: no default provider")
}
apiReq := &agentAPI.CompletionRequest{
Model: req.Model,
Temperature: req.Temperature,
MaxTokens: req.MaxTokens,
Stream: req.Stream,
Tools: req.Tools,
ToolChoice: req.ToolChoice,
DisableThinking: req.DisableThinking,
}
if len(req.Messages) > 0 {
apiReq.Messages = make([]agentAPI.Message, len(req.Messages))
for i, m := range req.Messages {
msg := agentAPI.Message{
Role: m.Role,
Content: m.Content,
ReasoningContent: m.ReasoningContent,
ToolCallID: m.ToolCallID,
}
if len(m.ToolCalls) > 0 {
msg.ToolCalls = make([]agentAPI.ToolCall, len(m.ToolCalls))
for j, tc := range m.ToolCalls {
msg.ToolCalls[j] = agentAPI.ToolCall{ID: tc.ID, Name: tc.Name, Arguments: tc.Arguments}
}
}
apiReq.Messages[i] = msg
}
}
resp, err := p.Chat(ctx, apiReq)
if err != nil {
return nil, err
}
out := &LLMCompletionResponse{
Content: resp.Content,
ReasoningContent: resp.ReasoningContent,
FinishReason: resp.FinishReason,
TokenUsage: LLMTokenUsage{
Prompt: resp.TokenUsage.Prompt,
Completion: resp.TokenUsage.Completion,
Total: resp.TokenUsage.Total,
},
}
for _, tc := range resp.ToolCalls {
out.ToolCalls = append(out.ToolCalls, LLMToolCall{ID: tc.ID, Name: tc.Name, Arguments: tc.Arguments})
}
return out, nil
}
func (l *llmImpl) ReloadFromConfig() error {
if l.mgr == nil || l.cfgReg == nil || l.lua == nil {
return nil
}
cfg := l.cfgReg.ToConfig()
if cfg == nil {
return nil
}
l.mgr.Reset()
adapterConcurrency := map[string]int{}
for _, src := range cfg.LLM.Sources {
if !agentAPI.IsValidSourceConfig(src.Name, src.BaseURL, src.Model, src.Adapter) {
continue
}
key := src.APIKey
if key == "" {
key = l.baseAPIKey
}
provider := agentAPI.NewLuaAdaptedProvider(agentAPI.BaseConfig{
Model: src.Model,
BaseURL: src.BaseURL,
APIKey: key,
Temperature: cfg.LLM.Temperature,
MaxTokens: cfg.LLM.MaxTokens,
ContextWindow: src.ContextWindow,
MaxConcurrent: src.MaxConcurrent,
}, l.lua, src.Name, src.Adapter)
l.mgr.Register(src.Name, provider)
if src.Adapter != "" {
adapterConcurrency[src.Adapter] += src.MaxConcurrent
}
}
if l.lua != nil {
l.lua.ConfigureConcurrency(adapterConcurrency)
}
if cfg.LLM.Provider != "" {
if l.mgr.Get(cfg.LLM.Provider) != nil {
_ = l.mgr.SetDefault(cfg.LLM.Provider)
}
}
return nil
}
var _ LLMAPI = (*llmImpl)(nil)