Files
smartmate/backend/api/agent.go
LoveLosita 26c350f378 Version: 0.4.4.dev.260307
feat: 🚀 增强会话管理与缓存机制

* 会话 ID 空值兜底,若 `conversation_id` 为空时自动生成 UUID
* 在响应头写入 `X-Conversation-ID`,供前端使用,保持同一会话状态

perf:  会话状态缓存优化

* 当缓存未命中但 DB 已确认/创建会话后,调用 `SetConversationStatus` 回写 Redis
* 缓存写回失败时记录日志,不中断聊天主流程,确保业务流畅性

fix: 🐛 修复历史消息顺序问题与编译错误

* 修复历史消息顺序问题,保证返回的 N 条历史消息按时间正序喂给模型

  * 通过反转 `created_at desc` 查询结果的切片,确保模型输入顺序正确
* 修复 `fmt.Errorf` 参数不匹配问题,修正编译错误
* 整理 `agent-cache.go` 为标准 UTF-8 编码,避免 Go 编译报错 `invalid UTF-8 encoding`

feat: 🛠️ 独立构建 MCP 服务器

* 使用 `Codex` 构建独立于后端的 MCP 服务器,简化与 Codex 的协作
* 通过该服务器方便 Codex 直接测试和查看 Redis 与 MySQL 中的数据
2026-03-07 15:25:40 +08:00

69 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package api
import (
"io"
"net/http"
"strings"
"github.com/LoveLosita/smartflow/backend/model"
"github.com/LoveLosita/smartflow/backend/respond"
"github.com/LoveLosita/smartflow/backend/service"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
type AgentHandler struct {
svc *service.AgentService
}
// NewAgentHandler 组装 Handler 的“工厂”
func NewAgentHandler(svc *service.AgentService) *AgentHandler {
return &AgentHandler{
svc: svc, // 把传进来的 Service 揣进口袋里
}
}
func (api *AgentHandler) ChatAgent(c *gin.Context) {
// 1. 设置请求头
c.Writer.Header().Set("Content-Type", "text/event-stream")
c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Connection", "keep-alive")
c.Writer.Header().Set("Transfer-Encoding", "chunked")
// 2. 从请求中获取用户输入
var req model.UserSendMessageRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, respond.WrongParamType)
return
}
// 兼容:如果前端没传会话 ID后端兜底创建一个
conversationID := strings.TrimSpace(req.ConversationID)
if conversationID == "" {
conversationID = uuid.NewString()
}
// 把最终生效的会话 ID 回传给前端,方便后续继续同一会话
c.Writer.Header().Set("X-Conversation-ID", conversationID)
userID := c.GetInt("user_id") // 从上下文中获取用户 ID
// 3. 调用 Service 层的聊天方法,获取输出通道和错误通道
outChan, errChan := api.svc.AgentChat(c.Request.Context(), req.Message, req.Thinking, userID, conversationID)
// 4. 循环转发消息/错误
c.Stream(func(w io.Writer) bool {
select {
case err, ok := <-errChan:
if ok && err != nil {
respond.DealWithError(c, err)
}
return false
case msg, ok := <-outChan:
if !ok {
return false
}
c.SSEvent("message", msg) // 发送 SSE 格式消息
return true
case <-c.Request.Context().Done():
return false
}
})
}