package server import ( "net/http" "strings" "github.com/gin-gonic/gin" ) func (s *Server) health(c *gin.Context) { ok(c, gin.H{"status": "ok"}) } func (s *Server) config(c *gin.Context) { ok(c, gin.H{ "model": s.cfg.Model, "base_url": s.cfg.BaseURL, "workspace": s.cfg.Workspace, "max_context_tokens": s.cfg.MaxContextTokens, "max_tool_result_chars": s.cfg.MaxToolResultChars, "max_iterations": s.cfg.MaxIterations, "keep_recent_messages": s.cfg.KeepRecentMessages, "api_key_configured": s.cfg.APIKey != "", }) } func (s *Server) dockerConfig(c *gin.Context) { ok(c, gin.H{ "docker_socket": s.dockerCfg.Socket(), "default_socket": s.dockerCfg.DefaultSocket(), "configured": s.dockerCfg.IsConfigured(), }) } func (s *Server) setDockerConfig(c *gin.Context) { var req struct { Socket string `json:"socket"` } if err := c.ShouldBindJSON(&req); err != nil { fail(c, http.StatusBadRequest, "请求体格式错误") return } req.Socket = strings.TrimSpace(req.Socket) // 空字符串表示清除配置、恢复默认本地 Docker if err := s.dockerCfg.SetSocket(req.Socket); err != nil { fail(c, http.StatusInternalServerError, "保存 Docker 配置失败: "+err.Error()) return } ok(c, gin.H{ "docker_socket": s.dockerCfg.Socket(), "default_socket": s.dockerCfg.DefaultSocket(), "configured": s.dockerCfg.IsConfigured(), }) } func (s *Server) llmConfig(c *gin.Context) { apiKey := s.apiCfg.APIKey() ok(c, gin.H{ "provider": s.apiCfg.Provider(), "api_key_configured": apiKey != "", "api_key_masked": maskSecret(apiKey), "base_url": s.apiCfg.BaseURL(), "model": s.apiCfg.Model(), "engine": s.apiCfg.Engine(), "coop_mode": s.apiCfg.CoopMode(), "default_base_url": s.cfg.BaseURL, "default_model": s.cfg.Model, }) } func (s *Server) setLLMConfig(c *gin.Context) { var req struct { APIKey *string `json:"api_key"` BaseURL *string `json:"base_url"` Model *string `json:"model"` Provider *string `json:"provider"` Engine *string `json:"engine"` CoopMode *string `json:"coop_mode"` } if err := c.ShouldBindJSON(&req); err != nil { fail(c, http.StatusBadRequest, "请求体格式错误") return } // 字段为 nil 表示不修改;空字符串表示清除该字段、回退默认 if err := s.apiCfg.Update(req.APIKey, req.BaseURL, req.Model, req.Provider, req.Engine, req.CoopMode); err != nil { fail(c, http.StatusInternalServerError, "保存 LLM 配置失败: "+err.Error()) return } apiKey := s.apiCfg.APIKey() ok(c, gin.H{ "provider": s.apiCfg.Provider(), "api_key_configured": apiKey != "", "api_key_masked": maskSecret(apiKey), "base_url": s.apiCfg.BaseURL(), "model": s.apiCfg.Model(), "engine": s.apiCfg.Engine(), "coop_mode": s.apiCfg.CoopMode(), }) } // maskSecret 对密钥做掩码展示,避免在 Web 页面泄露完整值。 func maskSecret(value string) string { runes := []rune(value) if len(runes) <= 6 { if len(runes) == 0 { return "" } return "****" } return string(runes[:3]) + "****" + string(runes[len(runes)-3:]) }