From 8dcce5a3a95b45d20713f5b01540dd68234a716b Mon Sep 17 00:00:00 2001 From: root Date: Mon, 10 Aug 2026 09:51:30 +0800 Subject: [PATCH] =?UTF-8?q?webui=20=E5=88=A0=E9=99=A4=E5=BD=BB=E5=BA=95?= =?UTF-8?q?=E5=8C=96=EF=BC=9A=E6=B8=85=E7=90=86=E6=AE=8B=E7=95=99=20config?= =?UTF-8?q?/defs/provider=20=E6=82=AC=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 审计发现 webui 多处删除只清一处、留下鬼影: - RemovePlugin: 仅 DROP config_ 与 defs,config 表 plugin..* 键永不删 → 补 DELETE config LIKE 'plugin..%' - ConfigRegistry.Delete: 删 core.llm.sources..* 后遗留 ConfigDef、且删 core.llm.* 不更新 guard 快照(重启/failback 会把已删源复活)→ 同步清 source defs + 写 llm 快照 - llm_impl.ReloadFromConfig: 删除默认源后 core.llm.provider 悬空,SetDefault 指向不存在源 → 仅当源仍注册时才 SetDefault - clawhubadapter 测试 mockSettings 补 RemoveCore/RemovePlugin - mcp 服务器删除仍为进程内需 reload 生效(符合既有 removeServerHandler 语义) 验证: go test ./... 26 包 0 失败;本机部署 sources=3、27 插件加载、对话正常 --- internal/config/registry.go | 20 +++++++++++++++++++ .../plugins/clawhubadapter/sidecar_test.go | 2 ++ internal/sdk/llm_impl.go | 4 +++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/internal/config/registry.go b/internal/config/registry.go index 49dea27..1ba35a4 100644 --- a/internal/config/registry.go +++ b/internal/config/registry.go @@ -91,6 +91,9 @@ func (r *ConfigRegistry) RemovePlugin(name string) error { delete(r.defs, k) } } + if _, err := r.db.Exec(`DELETE FROM config WHERE key LIKE ?`, prefix+"%"); err != nil { + return err + } table := r.pluginTableName(name) _, err := r.db.Exec(fmt.Sprintf(`DROP TABLE IF EXISTS %s`, table)) return err @@ -307,6 +310,23 @@ func (r *ConfigRegistry) Delete(key string) error { r.mu.Lock() defer r.mu.Unlock() _, err := r.db.Exec(`DELETE FROM config WHERE key = ?`, key) + if err == nil { + if strings.HasPrefix(key, "core.llm.sources.") { + rest := strings.TrimPrefix(key, "core.llm.sources.") + parts := strings.SplitN(rest, ".", 2) + if len(parts) == 2 { + prefix := "core.llm.sources." + parts[0] + "." + for k := range r.defs { + if strings.HasPrefix(k, prefix) { + delete(r.defs, k) + } + } + } + } + if strings.HasPrefix(key, "core.llm.") { + r.writeLLMSnapshotLocked() + } + } return err } diff --git a/internal/plugins/clawhubadapter/sidecar_test.go b/internal/plugins/clawhubadapter/sidecar_test.go index 3d5a61f..c8b4467 100644 --- a/internal/plugins/clawhubadapter/sidecar_test.go +++ b/internal/plugins/clawhubadapter/sidecar_test.go @@ -29,6 +29,8 @@ func (m *mockSettings) Plugins() []string { return nil } func (m *mockSettings) DefsCore(prefix string) []*sdk.ConfigDef { return nil } func (m *mockSettings) DefsPlugin(plugin, prefix string) []*sdk.ConfigDef { return nil } func (m *mockSettings) Remove(key string) error { return nil } +func (m *mockSettings) RemoveCore(key string) error { return nil } +func (m *mockSettings) RemovePlugin(plugin, key string) error { return nil } func TestLaunchSidecarNoMainJS(t *testing.T) { tmpDir := t.TempDir() diff --git a/internal/sdk/llm_impl.go b/internal/sdk/llm_impl.go index 5262802..7d8c443 100644 --- a/internal/sdk/llm_impl.go +++ b/internal/sdk/llm_impl.go @@ -128,7 +128,9 @@ func (l *llmImpl) ReloadFromConfig() error { l.mgr.Register(src.Name, provider) } if cfg.LLM.Provider != "" { - _ = l.mgr.SetDefault(cfg.LLM.Provider) + if l.mgr.Get(cfg.LLM.Provider) != nil { + _ = l.mgr.SetDefault(cfg.LLM.Provider) + } } return nil }