package service import ( "bytes" "context" "encoding/json" "fmt" "net/http" "time" "x-agents/server/internal/model" "x-agents/server/internal/repository" "github.com/google/uuid" ) type ChatService struct { pythonURL string agentRepo *repository.AgentRepository } func NewChatService(pythonURL string, agentRepo *repository.AgentRepository) *ChatService { return &ChatService{ pythonURL: pythonURL, agentRepo: agentRepo, } } type ChatRequest struct { AgentID string `json:"agent_id"` Message string `json:"message"` SessionID string `json:"session_id"` Context map[string]interface{} `json:"context"` } type ChatResponse struct { Reply string `json:"reply"` SessionID string `json:"session_id"` ToolsUsed []string `json:"tools_used"` Metadata map[string]interface{} `json:"metadata"` } // Chat 处理聊天请求 func (s *ChatService) Chat(ctx context.Context, userID string, req model.AgentRequest) (*model.AgentResponse, error) { // 1. 检查 Agent 是否存在 agent, err := s.agentRepo.FindByID(req.AgentID) if err != nil { return nil, fmt.Errorf("agent not found: %w", err) } // 2. 检查用户权限 if !agent.IsActive { return nil, fmt.Errorf("agent is not active") } // 3. 生成会话ID sessionID := req.SessionID if sessionID == "" { sessionID = uuid.New().String() } // 4. 调用 Python 服务 pythonReq := ChatRequest{ AgentID: req.AgentID, Message: req.Message, SessionID: sessionID, Context: req.Context, } pythonResp, err := s.callPythonChat(ctx, pythonReq) if err != nil { return nil, fmt.Errorf("failed to call python service: %w", err) } return &model.AgentResponse{ Reply: pythonResp.Reply, SessionID: pythonResp.SessionID, ToolsUsed: pythonResp.ToolsUsed, Metadata: pythonResp.Metadata, }, nil } func (s *ChatService) callPythonChat(ctx context.Context, req ChatRequest) (*ChatResponse, error) { jsonData, err := json.Marshal(req) if err != nil { return nil, err } httpReq, err := http.NewRequestWithContext( ctx, "POST", s.pythonURL+"/agent/chat", bytes.NewBuffer(jsonData), ) if err != nil { return nil, err } httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{ Timeout: 120 * time.Second, // Agent 可能需要较长时间 } resp, err := client.Do(httpReq) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("python service returned status: %d", resp.StatusCode) } var chatResp ChatResponse if err := json.NewDecoder(resp.Body).Decode(&chatResp); err != nil { return nil, err } return &chatResp, nil } // ListAgents 获取用户可用的 Agent 列表 func (s *ChatService) ListAgents(userID string) ([]model.Agent, error) { return s.agentRepo.FindByOwnerID(userID) } // CreateAgent 创建新的 Agent func (s *ChatService) CreateAgent(userID string, name, description string) (*model.Agent, error) { agent := &model.Agent{ ID: uuid.New().String(), Name: name, Description: description, OwnerID: userID, SecurityLevel: model.SecurityLevelSafe, IsActive: true, Timeout: 60, MemoryLimit: 134217728, // 128MB } if err := s.agentRepo.Create(agent); err != nil { return nil, err } return agent, nil }