feat: 增强会话管理和 Agent 服务
- 优化 session_handler 会话处理逻辑 - 增强 agent_service Agent 服务功能 - 新增 chat_repository 仓储方法 - 更新 agent_handler 和 chat_group_handler - 更新数据模型 agent 和 chat_session Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@ import (
|
||||
|
||||
// AgentChatRequest Python Agent 对话请求
|
||||
type AgentChatRequest struct {
|
||||
AgentID int `json:"agent_id"`
|
||||
AgentID string `json:"agent_id"` // 支持 UUID 字符串
|
||||
Message string `json:"message"`
|
||||
UserID int `json:"user_id"`
|
||||
SessionID string `json:"session_id,omitempty"`
|
||||
@@ -32,7 +32,7 @@ type AgentChatRequest struct {
|
||||
|
||||
// AgentChatResponse Python Agent 对话响应
|
||||
type AgentChatResponse struct {
|
||||
AgentID int `json:"agent_id"`
|
||||
AgentID string `json:"agent_id"` // 支持 UUID 字符串
|
||||
Response string `json:"response"`
|
||||
ToolCalls []interface{} `json:"tool_calls"`
|
||||
TokensUsed int `json:"tokens_used"`
|
||||
@@ -66,10 +66,11 @@ type AgentService struct {
|
||||
client *http.Client
|
||||
modelRepo *repository.ModelRepository
|
||||
agentRepo *repository.AgentRepository
|
||||
chatRepo *repository.ChatRepository
|
||||
}
|
||||
|
||||
// NewAgentService 创建 Agent 服务
|
||||
func NewAgentService(pythonURL string, modelRepo *repository.ModelRepository, agentRepo *repository.AgentRepository) *AgentService {
|
||||
func NewAgentService(pythonURL string, modelRepo *repository.ModelRepository, agentRepo *repository.AgentRepository, chatRepo *repository.ChatRepository) *AgentService {
|
||||
return &AgentService{
|
||||
pythonURL: pythonURL,
|
||||
client: &http.Client{
|
||||
@@ -77,6 +78,7 @@ func NewAgentService(pythonURL string, modelRepo *repository.ModelRepository, ag
|
||||
},
|
||||
modelRepo: modelRepo,
|
||||
agentRepo: agentRepo,
|
||||
chatRepo: chatRepo,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,16 +197,19 @@ func (s *AgentService) TeamChat(req TeamChatRequest) (*TeamChatResponse, error)
|
||||
}
|
||||
|
||||
// ChatStream 流式对话
|
||||
func (s *AgentService) ChatStream(c interface{}, agentID int, message, sessionID, modelID string, userID int) error {
|
||||
func (s *AgentService) ChatStream(c interface{}, agentID string, message, sessionID, modelID string, userID int) error {
|
||||
// 获取 gin.Context
|
||||
ginCtx, ok := c.(*gin.Context)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid context type")
|
||||
}
|
||||
|
||||
log.Printf("[ChatStream] Request: agentID=%s, message=%s, sessionID=%s, modelID=%s, userID=%d",
|
||||
agentID, message, sessionID, modelID, userID)
|
||||
|
||||
// 初始化请求体
|
||||
reqBody := map[string]interface{}{
|
||||
"agent_id": agentID,
|
||||
"agent_id": agentID, // 传递字符串类型的 agent_id,支持 UUID
|
||||
"message": message,
|
||||
"user_id": userID,
|
||||
"session_id": sessionID,
|
||||
@@ -267,8 +272,10 @@ func (s *AgentService) ChatStream(c interface{}, agentID int, message, sessionID
|
||||
for {
|
||||
n, err := resp.Body.Read(buf)
|
||||
if n > 0 {
|
||||
log.Printf("[ChatStream] Received %d bytes from Python", n)
|
||||
_, writeErr := ginCtx.Writer.Write(buf[:n])
|
||||
if writeErr != nil {
|
||||
log.Printf("[ChatStream] Write error: %v", writeErr)
|
||||
break
|
||||
}
|
||||
// 强制刷新到客户端
|
||||
@@ -277,6 +284,7 @@ func (s *AgentService) ChatStream(c interface{}, agentID int, message, sessionID
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("[ChatStream] Done reading from Python, err: %v", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -300,9 +308,10 @@ type CreateAgentRequest struct {
|
||||
|
||||
// CreateAgentResponse 创建智能体响应
|
||||
type CreateAgentResponse struct {
|
||||
AgentID int `json:"agent_id"`
|
||||
Name string `json:"name"`
|
||||
Message string `json:"message"`
|
||||
AgentID int `json:"agent_id"` // 保留兼容性
|
||||
AgentIDStr string `json:"agent_id_str"` // 返回实际的 UUID
|
||||
Name string `json:"name"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// CreateAgent 创建智能体
|
||||
@@ -329,6 +338,7 @@ func (s *AgentService) CreateAgent(req CreateAgentRequest, userID int) (*CreateA
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
OwnerID: fmt.Sprintf("%d", userID),
|
||||
Avatar: req.Avatar,
|
||||
Skills: skills,
|
||||
RoleDescription: req.Prompt,
|
||||
ModelProvider: req.ModelProvider,
|
||||
@@ -347,13 +357,11 @@ func (s *AgentService) CreateAgent(req CreateAgentRequest, userID int) (*CreateA
|
||||
|
||||
log.Printf("[AgentService] Agent created in database: %s (ID: %s)", agent.Name, agent.ID)
|
||||
|
||||
// 解析 agent ID 为整数返回
|
||||
agentIDInt := int(time.Now().Unix()) % 100000
|
||||
|
||||
// 返回数据库中实际的 Agent ID (UUID字符串)
|
||||
return &CreateAgentResponse{
|
||||
AgentID: agentIDInt,
|
||||
Name: agent.Name,
|
||||
Message: "Agent created successfully",
|
||||
AgentIDStr: agent.ID,
|
||||
Name: agent.Name,
|
||||
Message: "Agent created successfully",
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -429,6 +437,14 @@ func (s *AgentService) DeleteAgent(agentID string) error {
|
||||
return fmt.Errorf("agent not found: %w", err)
|
||||
}
|
||||
|
||||
// 先删除该智能体的所有会话和消息
|
||||
if s.chatRepo != nil {
|
||||
if err := s.chatRepo.DeleteSessionsByAgentID(agentID); err != nil {
|
||||
log.Printf("[AgentService] DeleteAgent: failed to delete sessions: %v", err)
|
||||
// 继续尝试删除 agent,不因为 session 删除失败而中止
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.agentRepo.Delete(agentID); err != nil {
|
||||
return fmt.Errorf("failed to delete agent: %w", err)
|
||||
}
|
||||
@@ -438,7 +454,7 @@ func (s *AgentService) DeleteAgent(agentID string) error {
|
||||
}
|
||||
|
||||
// UpdateAgent 更新智能体
|
||||
func (s *AgentService) UpdateAgent(agentID, name, description string, skills []string, roleDescription, modelProvider, modelName string) error {
|
||||
func (s *AgentService) UpdateAgent(agentID, name, description, avatar string, skills []string, roleDescription, modelProvider, modelName string) error {
|
||||
if s.agentRepo == nil {
|
||||
return fmt.Errorf("agent repository not initialized")
|
||||
}
|
||||
@@ -458,6 +474,9 @@ func (s *AgentService) UpdateAgent(agentID, name, description string, skills []s
|
||||
if description != "" {
|
||||
agent.Description = description
|
||||
}
|
||||
if avatar != "" {
|
||||
agent.Avatar = avatar
|
||||
}
|
||||
if skills != nil {
|
||||
agent.Skills = skills
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user