mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 09:28:14 +00:00
webui: 修复 '删除源/服务器' 只置 <nil> 不真删的问题
前端 deleteSource/deleteMCPServer 通过 PUT value:null 删除,但后端 handleSettings PUT 只 SetCore/SetPlugin(fmt.Sprint(nil) → 字面 '<nil>'),导致 core.llm.sources.<name>.* 等键残留不可达的 <nil> 行,污染 LLM 源与探活。 - SettingsAPI 新增 RemoveCore/RemovePlugin;settingsImpl 接入 ConfigRegistry.Delete - webui handleSettings PUT:body.Value==null 时改走删除分支(核心表/插件表均适配) - 现状验证:mocktest.* 残留已从本机 config.db 清除,sources=3,无无效源
This commit is contained in:
@ -49,8 +49,8 @@ type Handler struct {
|
||||
status sdk.StatusAPI
|
||||
llm sdk.LLMAPI
|
||||
|
||||
sessionMu sync.Mutex
|
||||
sessions map[string]time.Time
|
||||
sessionMu sync.Mutex
|
||||
sessions map[string]time.Time
|
||||
|
||||
chatMu sync.Mutex
|
||||
chatHistory []ChatMsg
|
||||
@ -282,12 +282,18 @@ func (h *Handler) getWebUIConfig() (apiKey, username, password string, ttl time.
|
||||
if v, _ := h.settings.Get("session_ttl_hours"); v != nil {
|
||||
switch n := v.(type) {
|
||||
case float64:
|
||||
if n > 0 { ttl = time.Duration(n) * time.Hour }
|
||||
if n > 0 {
|
||||
ttl = time.Duration(n) * time.Hour
|
||||
}
|
||||
case string:
|
||||
if i, err := strconv.Atoi(n); err == nil && i > 0 { ttl = time.Duration(i) * time.Hour }
|
||||
if i, err := strconv.Atoi(n); err == nil && i > 0 {
|
||||
ttl = time.Duration(i) * time.Hour
|
||||
}
|
||||
}
|
||||
}
|
||||
if username == "" { username = "admin" }
|
||||
if username == "" {
|
||||
username = "admin"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -426,7 +432,10 @@ func (h *Handler) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusServiceUnavailable, map[string]string{"error": "webui username/password not configured"})
|
||||
return
|
||||
}
|
||||
var body struct { Username string `json:"username"`; Password string `json:"password"` }
|
||||
var body struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid request"})
|
||||
return
|
||||
@ -1156,16 +1165,29 @@ func (h *Handler) handleSettings(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid request"})
|
||||
return
|
||||
}
|
||||
deleting := body.Value == nil
|
||||
if strings.HasPrefix(body.Key, "plugin.") {
|
||||
parts := strings.SplitN(body.Key, ".", 3)
|
||||
if len(parts) >= 3 {
|
||||
if err := h.settings.SetPlugin(parts[1], parts[2], body.Value); err != nil {
|
||||
var err error
|
||||
if deleting {
|
||||
err = h.settings.RemovePlugin(parts[1], parts[2])
|
||||
} else {
|
||||
err = h.settings.SetPlugin(parts[1], parts[2], body.Value)
|
||||
}
|
||||
if err != nil {
|
||||
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := h.settings.SetCore(body.Key, body.Value); err != nil {
|
||||
var err error
|
||||
if deleting {
|
||||
err = h.settings.RemoveCore(body.Key)
|
||||
} else {
|
||||
err = h.settings.SetCore(body.Key, body.Value)
|
||||
}
|
||||
if err != nil {
|
||||
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
@ -1320,8 +1342,8 @@ func (h *Handler) writeOpenAIStream(w http.ResponseWriter, model, content, reaso
|
||||
"model": model,
|
||||
"choices": []map[string]interface{}{
|
||||
{
|
||||
"index": 0,
|
||||
"delta": map[string]interface{}{},
|
||||
"index": 0,
|
||||
"delta": map[string]interface{}{},
|
||||
"finish_reason": "stop",
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user