package controllers import ( "errors" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/utils" "go.uber.org/zap" "fwh-toolbox-server/config" "fwh-toolbox-server/middleware" "fwh-toolbox-server/services" "fwh-toolbox-server/utils/agentserver" ) // 新 AI 助手(AgentServer)接口,见 docs/ai-assistant-agentserver/technical-design.md §3.4、§3.5 var agentService *services.AgentService // InitAgent 初始化新 AI 助手 func InitAgent(cfg config.AgentConfig) { agentService = services.NewAgentService(cfg) zap.L().Info("[Agent] 初始化", zap.Bool("enabled", cfg.Enabled), zap.String("server", cfg.ServerURL)) } func agentEnabled(c *fiber.Ctx) bool { return agentService != nil && agentService.Enabled(middleware.AuthGetRoleNameList(c)) } // AgentGuard 未开启或角色不允许时,/agent/* 一律返回 403(/agent/config 除外) func AgentGuard(c *fiber.Ctx) error { if !agentEnabled(c) { return Forbidden(c, "AI 助手未开启或无权使用") } return c.Next() } // GetAgentConfig 新助手对当前用户是否可用 // GET /agent/config func GetAgentConfig(c *fiber.Ctx) error { return Success(c, fiber.Map{"enabled": agentEnabled(c)}) } // ListAgentSessions 本人会话列表 // GET /agent/sessions func ListAgentSessions(c *fiber.Ctx) error { list, err := agentService.ListSessions(c.UserContext(), middleware.AuthGetUserName(c)) if err != nil { return Error(c, "获取会话列表失败: "+err.Error()) } return Success(c, list) } // CreateAgentSession 新建会话 // POST /agent/sessions func CreateAgentSession(c *fiber.Ctx) error { item, err := agentService.CreateSession(c.UserContext(), middleware.AuthGetUserName(c), middleware.AuthGetRoleNameList(c)) if err != nil { zap.L().Warn("[Agent] 创建会话失败", zap.Error(err)) return Error(c, "创建会话失败: "+err.Error()) } return Success(c, fiber.Map{"sessionId": item.SessionId, "title": item.Title, "profileId": item.ProfileId}) } // UpdateAgentSession 修改会话标题 // PATCH /agent/sessions/:id func UpdateAgentSession(c *fiber.Ctx) error { sessionId := utils.CopyString(c.Params("id")) var req struct { Title string `json:"title"` } if err := c.BodyParser(&req); err != nil { return Fail(c, "Invalid request body") } err := agentService.RenameSession(c.UserContext(), middleware.AuthGetUserName(c), sessionId, req.Title) if errors.Is(err, services.ErrAgentSessionNotFound) { return NotFound(c, err.Error()) } if err != nil { return Error(c, "修改标题失败: "+err.Error()) } return Success[any](c, nil, "标题已更新") } // DeleteAgentSession 删除会话 // DELETE /agent/sessions/:id func DeleteAgentSession(c *fiber.Ctx) error { sessionId := utils.CopyString(c.Params("id")) err := agentService.DeleteSession(c.UserContext(), middleware.AuthGetUserName(c), sessionId) if errors.Is(err, services.ErrAgentSessionNotFound) { return NotFound(c, err.Error()) } if err != nil { return Error(c, "删除会话失败: "+err.Error()) } return Success[any](c, nil, "会话已删除") } // ProxyAgentServer AgentServer 代理,响应原样透传(不包装 Success) // ALL /agent/v1/* func ProxyAgentServer(c *fiber.Ctx) error { if !agentEnabled(c) { return agentserver.WriteError(c, fiber.StatusForbidden, "forbidden", "AI 助手未开启或无权使用") } rest := utils.CopyString(c.Params("*")) return agentService.Proxy().Handle(c, middleware.AuthGetUserName(c), rest) }