mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-22 09:58:06 +00:00
吸收 llmsproxy 的调度思想适配 HomeAgent“一源一模型”结构:
- RoutableProvider{Model,Priority} 次级接口(不破坏既有 Provider 实现)
- ProviderManager.OrderedProviders 改为按 (优先级 desc, 可用, 默认优先) 稳定排序,
AUTO/空模型走该优先级链
- 新增 ProviderManager.ResolveForModel:精确模型名路由到归属源,找不到回落 AUTO 链
- LuaAdaptedProvider 不再无条件覆写 req.Model;显式模型名原样转发
- LLMSource.Priority + core.llm.sources.<name>.priority 配置项
- process.go: 显式模型走 ResolveForModel,AUTO 走 OrderedProviders
- 新增路由单测(优先级排序 + byModel 解析)
验证: go test ./... 27 包 0 失败;Windows 交叉编译通过;部署后服务健康
66 lines
2.0 KiB
Go
66 lines
2.0 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
)
|
|
|
|
// stubRoutableProvider implements both Provider and RoutableProvider.
|
|
type stubRoutableProvider struct {
|
|
name string
|
|
model string
|
|
prio int
|
|
}
|
|
|
|
func (s *stubRoutableProvider) Name() string { return s.name }
|
|
func (s *stubRoutableProvider) Model() string { return s.model }
|
|
func (s *stubRoutableProvider) Priority() int { return s.prio }
|
|
func (s *stubRoutableProvider) MaxContextTokens() int { return 4096 }
|
|
func (s *stubRoutableProvider) Chat(context.Context, *CompletionRequest) (*CompletionResponse, error) {
|
|
return &CompletionResponse{Content: s.name}, nil
|
|
}
|
|
func (s *stubRoutableProvider) ChatStream(context.Context, *CompletionRequest) (<-chan StreamChunk, error) {
|
|
ch := make(chan StreamChunk, 1)
|
|
ch <- StreamChunk{Done: true}
|
|
return ch, nil
|
|
}
|
|
|
|
func TestProviderManagerPriorityOrder(t *testing.T) {
|
|
m := NewProviderManager()
|
|
m.Register("low", &stubRoutableProvider{name: "low", prio: 10})
|
|
m.Register("high", &stubRoutableProvider{name: "high", prio: 90})
|
|
m.Register("mid", &stubRoutableProvider{name: "mid", prio: 50})
|
|
|
|
got := m.OrderedProviders()
|
|
wantOrder := []string{"high", "mid", "low"}
|
|
for i, p := range got {
|
|
if p.Name() != wantOrder[i] {
|
|
t.Fatalf("order[%d] = %s, want %s (full=%v)", i, p.Name(), wantOrder[i], names(got))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestProviderManagerResolveForModel(t *testing.T) {
|
|
m := NewProviderManager()
|
|
m.Register("a", &stubRoutableProvider{name: "a", model: "gpt-5"})
|
|
m.Register("b", &stubRoutableProvider{name: "b", model: "deepseek"})
|
|
|
|
got := m.ResolveForModel("deepseek")
|
|
if len(got) == 0 || got[0].Name() != "b" {
|
|
t.Fatalf("resolve deepseek: got %v", names(got))
|
|
}
|
|
|
|
// 未知模型回落 AUTO 链(仍按优先级)
|
|
got2 := m.ResolveForModel("unknown")
|
|
if len(got2) == 0 {
|
|
t.Fatal("unknown model should fall back to auto chain")
|
|
}
|
|
}
|
|
|
|
func names(ps []Provider) []string {
|
|
out := make([]string, len(ps))
|
|
for i, p := range ps {
|
|
out[i] = p.Name()
|
|
}
|
|
return out
|
|
} |