feat: 新增 Agent、Memory、Skill 模块

- handler: agent_handler, memory_handler, skill_handler
- model: agent.go, skill.go
- repository: agent_repo, skill_repo
- service: agent_service, memory_service, skill_service
- 新增 migrations 目录

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 16:25:48 +08:00
parent c6a4b28bf6
commit fc1204a033
11 changed files with 1179 additions and 4 deletions

View File

@@ -0,0 +1,141 @@
package handler
import (
"net/http"
"x-agents/server/internal/service"
"github.com/gin-gonic/gin"
)
// AgentHandler Agent 处理器
type AgentHandler struct {
agentService *service.AgentService
}
// NewAgentHandler 创建 Agent 处理器
func NewAgentHandler(agentService *service.AgentService) *AgentHandler {
return &AgentHandler{
agentService: agentService,
}
}
// ChatRequest 对话请求
type ChatRequest struct {
AgentID int `json:"agent_id" binding:"required"`
Message string `json:"message" binding:"required"`
SessionID string `json:"session_id"`
}
// ChatResponse 对话响应
type ChatResponse struct {
AgentID int `json:"agent_id"`
Reply string `json:"reply"`
ToolsUsed []string `json:"tools_used"`
SessionID string `json:"session_id"`
TokensUsed int `json:"tokens_used"`
DurationMs int `json:"duration_ms"`
Metadata interface{} `json:"metadata"`
}
// Chat 单智能体对话
func (h *AgentHandler) Chat(c *gin.Context) {
var req ChatRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 获取用户 ID从认证中间件获取
userID := 1 // TODO: 从 c.Get("user_id") 获取
pythonReq := service.AgentChatRequest{
AgentID: req.AgentID,
Message: req.Message,
UserID: userID,
SessionID: req.SessionID,
}
result, err := h.agentService.Chat(pythonReq)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 转换工具调用
toolsUsed := make([]string, 0)
for _, tool := range result.ToolCalls {
if toolMap, ok := tool.(map[string]interface{}); ok {
if skillID, ok := toolMap["skill_id"].(string); ok {
toolsUsed = append(toolsUsed, skillID)
}
}
}
c.JSON(http.StatusOK, ChatResponse{
AgentID: result.AgentID,
Reply: result.Response,
ToolsUsed: toolsUsed,
SessionID: result.SessionID,
TokensUsed: result.TokensUsed,
DurationMs: result.DurationMs,
Metadata: nil,
})
}
// TeamChatRequest 多智能体群聊请求
type TeamChatRequest struct {
SupervisorAgentID int `json:"supervisor_agent_id" binding:"required"`
MemberAgentIDs []int `json:"member_agent_ids" binding:"required"`
Message string `json:"message" binding:"required"`
SessionID string `json:"session_id"`
Strategy string `json:"strategy"`
}
// TeamChatResponse 多智能体群聊响应
type TeamChatResponse struct {
SupervisorAgentID int `json:"supervisor_agent_id"`
Reply string `json:"reply"`
SubtaskResults interface{} `json:"subtask_results"`
Strategy string `json:"strategy"`
SessionID string `json:"session_id"`
DurationMs int `json:"duration_ms"`
Metadata interface{} `json:"metadata"`
}
// TeamChat 多智能体群聊
func (h *AgentHandler) TeamChat(c *gin.Context) {
var req TeamChatRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 获取用户 ID
userID := 1 // TODO: 从 c.Get("user_id") 获取
pythonReq := service.TeamChatRequest{
SupervisorAgentID: req.SupervisorAgentID,
MemberAgentIDs: req.MemberAgentIDs,
Message: req.Message,
UserID: userID,
SessionID: req.SessionID,
Strategy: req.Strategy,
}
result, err := h.agentService.TeamChat(pythonReq)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, TeamChatResponse{
SupervisorAgentID: result.SupervisorAgentID,
Reply: result.Response,
SubtaskResults: result.SubtaskResults,
Strategy: result.Strategy,
SessionID: result.SessionID,
DurationMs: result.DurationMs,
Metadata: nil,
})
}