Files
X-Agents/server/internal/service/chat_service.go
DESKTOP-72TV0V4\caoxiaozhu 5dc2e403e9 feat: 更新后端服务
- agent_handler.go: 新增agent管理接口
- agent_service.go: 扩展agent服务逻辑
- skill_handler.go: 更新skill接口
- chat_service.go: 更新chat服务
- model相关: 新增model仓库和服务
- main.go: 更新路由配置

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:18:46 +08:00

182 lines
4.4 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 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
modelRepo *repository.ModelRepository
}
func NewChatService(pythonURL string, agentRepo *repository.AgentRepository, modelRepo *repository.ModelRepository) *ChatService {
return &ChatService{
pythonURL: pythonURL,
agentRepo: agentRepo,
modelRepo: modelRepo,
}
}
type ChatRequest struct {
AgentID string `json:"agent_id"`
Message string `json:"message"`
SessionID string `json:"session_id"`
ModelID string `json:"model_id"`
Context map[string]interface{} `json:"context"`
}
// ModelConfig 模型配置,用于传递给 Python 服务
type ModelConfig struct {
Provider string `json:"provider"`
Model string `json:"model"`
APIKey string `json:"api_key"`
BaseURL string `json:"base_url"`
APIEndpoint string `json:"api_endpoint"`
}
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. 如果提供了 ModelID获取模型配置
var modelConfig *ModelConfig
if req.ModelID != "" {
modelInfo, err := s.modelRepo.FindByID(req.ModelID)
if err != nil {
return nil, fmt.Errorf("model not found: %w", err)
}
modelConfig = &ModelConfig{
Provider: modelInfo.Provider,
Model: modelInfo.Model,
APIKey: modelInfo.APIKey,
BaseURL: modelInfo.BaseURL,
APIEndpoint: modelInfo.APIEndpoint,
}
}
// 5. 调用 Python 服务
pythonReq := ChatRequest{
AgentID: req.AgentID,
Message: req.Message,
SessionID: sessionID,
ModelID: req.ModelID,
Context: req.Context,
}
// 将模型配置放入 Context 中传递给 Python 服务
if modelConfig != nil {
pythonReq.Context = make(map[string]interface{})
for k, v := range req.Context {
pythonReq.Context[k] = v
}
pythonReq.Context["model_config"] = modelConfig
}
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,
IsActive: true,
}
if err := s.agentRepo.Create(agent); err != nil {
return nil, err
}
return agent, nil
}