适配多个 LLM 源 (anthropic/gemini/mistral/groq/github) + SQLite 配置收敛 + 测试插件

This commit is contained in:
root
2026-07-03 14:03:51 +08:00
parent b1b90ae09f
commit 988de228eb
16 changed files with 2059 additions and 161 deletions

View File

@ -6,7 +6,6 @@ import (
"os"
"os/signal"
"path/filepath"
"strconv"
"syscall"
"time"
@ -18,11 +17,14 @@ import (
"gitcode.com/JianFeeeee/HomeAgent/config"
internalConfig "gitcode.com/JianFeeeee/HomeAgent/internal/config"
"gitcode.com/JianFeeeee/HomeAgent/internal/events"
"gitcode.com/JianFeeeee/HomeAgent/internal/plugins/test_deepseek"
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/plugin/sdk"
"gitcode.com/JianFeeeee/HomeAgent/internal/knowledge"
luapkg "gitcode.com/JianFeeeee/HomeAgent/internal/lua"
"gitcode.com/JianFeeeee/HomeAgent/internal/memory"
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/document"
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/pipeline"
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/social"
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/text"
"gitcode.com/JianFeeeee/HomeAgent/internal/onebot"
"gitcode.com/JianFeeeee/HomeAgent/internal/plugin"
@ -78,6 +80,12 @@ func main() {
memIdx := memory.NewIndexer(memDB)
// === Social Store(人物特质与关系网)===
socialStore := social.New(memDB)
if memDB != nil {
log.Printf("[homed] social store initialized")
}
// === Memory Pipeline ===
distiller := pipeline.NewDistiller(memDB, cfg.Daemon.DataDir, pipeline.DistillerConfig{
Interval: 10 * time.Minute,
@ -107,20 +115,15 @@ func main() {
return onebot.NewDevice(name, wsURL, accessToken, iom), nil
})
// === Config Registry (统一配置中心,供插件读写) ===
cfgReg := internalConfig.NewConfigRegistry(filepath.Join(cfg.Daemon.DataDir, "settings.json"))
cfgReg.Register("core.daemon.listen_addr", cfg.Daemon.ListenAddr)
cfgReg.Register("core.daemon.data_dir", cfg.Daemon.DataDir)
cfgReg.Register("core.daemon.heartbeat_interval", cfg.Daemon.HeartbeatInterval.String())
cfgReg.Register("core.daemon.check_interval", cfg.Daemon.CheckInterval.String())
cfgReg.Register("core.daemon.log_level", cfg.Daemon.LogLevel)
cfgReg.Register("core.llm.provider", "lua_deepseek")
cfgReg.Register("core.llm.model", cfg.LLM.Model)
cfgReg.Register("core.llm.base_url", cfg.LLM.BaseURL)
cfgReg.Register("core.llm.temperature", strconv.FormatFloat(cfg.LLM.Temperature, 'f', 2, 64))
cfgReg.Register("core.llm.max_tokens", strconv.Itoa(cfg.LLM.MaxTokens))
// === Config Registry (统一配置中心,SQLite 持久化) ===
// 所有配置收敛到 SQLite,YAML 仅作首次 seed
cfgReg := internalConfig.NewConfigRegistry(filepath.Join(cfg.Daemon.DataDir, "config.db"))
defer cfgReg.Close()
cfgReg.SeedFrom(cfg)
cfg = cfgReg.ToConfig() // 此后全从 DB 读取
pluginReg.SetConfigRegistry(cfgReg)
log.Printf("[homed] config registry active with %d keys", len(cfgReg.List("")))
log.Printf("[homed] config registry seeded from YAML, %d keys in SQLite", len(cfgReg.List("")))
// === Supervisor ===
sup := supervisor.New(cfg)
@ -207,18 +210,33 @@ func main() {
}
}
// === API Provider (唯一输出路径) ===
// === API Provider Manager(多 LLM 源,通过 Lua 适配器兼容不同 API)===
apiKey := cfg.LLM.APIKey
if apiKey == "" {
apiKey = os.Getenv("DEEPSEEK_API_KEY")
}
provider := agentAPI.NewOpenAIProvider(agentAPI.BaseConfig{
Model: cfg.LLM.Model,
BaseURL: cfg.LLM.BaseURL,
APIKey: apiKey,
Temperature: cfg.LLM.Temperature,
MaxTokens: cfg.LLM.MaxTokens,
})
baseAPIKey := apiKey
providerMgr := agentAPI.NewProviderManager()
for _, src := range cfg.LLM.Sources {
key := src.APIKey
if key == "" {
key = baseAPIKey
}
luaProvider := agentAPI.NewLuaAdaptedProvider(agentAPI.BaseConfig{
Model: src.Model,
BaseURL: src.BaseURL,
APIKey: key,
Temperature: cfg.LLM.Temperature,
MaxTokens: cfg.LLM.MaxTokens,
}, luaVM, src.Adapter)
providerMgr.Register(src.Name, luaProvider)
}
// 默认源由 config 指定
if cfg.LLM.Provider != "" {
providerMgr.SetDefault(cfg.LLM.Provider)
}
provider := providerMgr.Default()
// === Personality (固定人格内核) ===
personalPath := filepath.Join(cfg.Daemon.DataDir, "personal", "personal.md")
@ -253,6 +271,17 @@ func main() {
stageHost.SyncFromRegistry(pluginReg)
log.Printf("[homed] stage host initialized with %d plugin sdks", pluginReg.SDKPluginCount())
// === Test DeepSeek Plugin ===
tdBus := sdk.NewInProcessBus()
tdPlugin := test_deepseek.New(tdBus)
// 插件作用域的配置表(RegisterPluginAPI 自动设置 config_test_deepseek 表)
if err := pluginReg.RegisterPluginAPI(tdPlugin); err != nil {
log.Printf("[homed] warning: register test_deepseek plugin: %v", err)
} else {
stageHost.RegisterPlugin(tdPlugin)
log.Printf("[homed] test_deepseek plugin registered (config table: config_test_deepseek)")
}
// === Single Agent Core ===
agent := agentCore.New(agentCore.AgentConfig{
ID: "main",
@ -266,16 +295,25 @@ func main() {
1. memory_recall — 查询图记忆(历史/个人信息)
2. memory_commit — 写入图记忆(记住新信息)
3. memory_introspect — 查看记忆统计
4. knowledge_search — 搜索知识库
5. doc_query — 查询文档记忆
6. doc_commit — 写入文档记忆
7. plgreload — 热重载插件
4. person_query — 查询人物特质与社交关系网
5. person_set_trait — 记录人物特质(性格/喜好等)
6. person_relate — 建立人物间社交关系
7. person_network — 查看社交网络
8. knowledge_search — 搜索知识库
9. doc_query — 查询文档记忆
10. doc_commit — 写入文档记忆
11. plgreload — 热重载插件
12. llm_list_sources — 列出所有可用的 LLM 源
13. llm_set_source — 切换到指定 LLM 源
当用户问及个人信息或历史时,调用 memory_recall。
当用户告诉了你新的个人信息时,调用 memory_commit。
当用户提到某个人的性格、喜好或人际关系时,使用 person_set_trait 和 person_relate 记录。
需要查询知识时使用 knowledge_search。
如需切换 LLM 供应商(如从 DeepSeek 切到 OpenAI),使用 llm_list_sources 查看可用源,再用 llm_set_source 切换。
回复你的真实想法,用自然语言与用户交流。`,
Provider: provider,
Provider: provider,
ProviderManager: providerMgr,
IO: iom,
Memory: memDB,
Indexer: memIdx,
@ -284,6 +322,8 @@ func main() {
MaxToolTurns: 10,
DocStore: docStore,
Knowledge: ks,
SocialStore: socialStore,
TextMemory: textMem,
Personality: personality,
PluginReg: pluginReg,
PluginDir: filepath.Join(cfg.Daemon.DataDir, "plugins"),
@ -298,7 +338,8 @@ func main() {
sup.SetTracker(trk)
sup.RegisterAgent("main")
log.Printf("[homed] main agent started, model=%s base=%s", cfg.LLM.Model, cfg.LLM.BaseURL)
log.Printf("[homed] main agent started, model=%s base=%s sources=%d adapters=%d",
cfg.LLM.Model, cfg.LLM.BaseURL, len(cfg.LLM.Sources), len(luaVM.ListAdapters()))
// === Built-in HTTP API & WebUI Plugin ===
webui := api.NewWebUIPlugin(