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>
This commit is contained in:
@@ -9,9 +9,11 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"x-agents/server/internal/model"
|
||||
"x-agents/server/internal/repository"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// AgentChatRequest Python Agent 对话请求
|
||||
@@ -63,16 +65,18 @@ type AgentService struct {
|
||||
pythonURL string
|
||||
client *http.Client
|
||||
modelRepo *repository.ModelRepository
|
||||
agentRepo *repository.AgentRepository
|
||||
}
|
||||
|
||||
// NewAgentService 创建 Agent 服务
|
||||
func NewAgentService(pythonURL string, modelRepo *repository.ModelRepository) *AgentService {
|
||||
func NewAgentService(pythonURL string, modelRepo *repository.ModelRepository, agentRepo *repository.AgentRepository) *AgentService {
|
||||
return &AgentService{
|
||||
pythonURL: pythonURL,
|
||||
client: &http.Client{
|
||||
Timeout: 120 * time.Second, // Agent 可能需要较长时间
|
||||
},
|
||||
modelRepo: modelRepo,
|
||||
agentRepo: agentRepo,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,16 +286,16 @@ func (s *AgentService) ChatStream(c interface{}, agentID int, message, sessionID
|
||||
|
||||
// CreateAgentRequest 创建智能体请求
|
||||
type CreateAgentRequest struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Avatar string `json:"avatar"`
|
||||
SkillsMode string `json:"skills_mode"`
|
||||
Skills []string `json:"skills"`
|
||||
Knowledge string `json:"knowledge"`
|
||||
Prompt string `json:"prompt"`
|
||||
ModelProvider string `json:"model_provider"`
|
||||
ModelName string `json:"model_name"`
|
||||
UserID int `json:"user_id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Avatar string `json:"avatar"`
|
||||
SkillsMode string `json:"skillsMode"`
|
||||
Skills []string `json:"skills"`
|
||||
Knowledge string `json:"knowledge"`
|
||||
Prompt string `json:"prompt"`
|
||||
ModelProvider string `json:"model_provider"`
|
||||
ModelName string `json:"model_name"`
|
||||
UserID int `json:"user_id"`
|
||||
}
|
||||
|
||||
// CreateAgentResponse 创建智能体响应
|
||||
@@ -303,56 +307,54 @@ type CreateAgentResponse struct {
|
||||
|
||||
// CreateAgent 创建智能体
|
||||
func (s *AgentService) CreateAgent(req CreateAgentRequest, userID int) (*CreateAgentResponse, error) {
|
||||
url := fmt.Sprintf("%s/agent/create", s.pythonURL)
|
||||
|
||||
// 构建请求体
|
||||
pythonReq := CreateAgentRequest{
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
Avatar: req.Avatar,
|
||||
SkillsMode: req.SkillsMode,
|
||||
Skills: req.Skills,
|
||||
Knowledge: req.Knowledge,
|
||||
Prompt: req.Prompt,
|
||||
ModelProvider: req.ModelProvider,
|
||||
ModelName: req.ModelName,
|
||||
UserID: userID,
|
||||
if s.agentRepo == nil {
|
||||
log.Printf("[AgentService] CreateAgent: agentRepo is nil!")
|
||||
return nil, fmt.Errorf("agent repository not initialized")
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(pythonReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal request: %w", err)
|
||||
log.Printf("[AgentService] CreateAgent: %s (userID: %d), skillsMode: %s, skills: %v", req.Name, userID, req.SkillsMode, req.Skills)
|
||||
|
||||
// 处理 skills:根据 skillsMode 决定
|
||||
var skills []string
|
||||
if req.SkillsMode == "all" {
|
||||
// "all" 模式用 "*" 表示
|
||||
skills = []string{"*"}
|
||||
} else {
|
||||
skills = req.Skills
|
||||
}
|
||||
|
||||
httpReq, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
httpReq.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := s.client.Do(httpReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to call python agent: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response: %w", err)
|
||||
// 创建 Agent 模型并保存到数据库
|
||||
agent := &model.Agent{
|
||||
ID: uuid.New().String(),
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
OwnerID: fmt.Sprintf("%d", userID),
|
||||
Skills: skills,
|
||||
RoleDescription: req.Prompt,
|
||||
ModelProvider: req.ModelProvider,
|
||||
ModelName: req.ModelName,
|
||||
IsActive: true,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("python agent error: %s", string(body))
|
||||
log.Printf("[AgentService] CreateAgent: calling Create, agent = %+v", agent)
|
||||
if err := s.agentRepo.Create(agent); err != nil {
|
||||
log.Printf("[AgentService] CreateAgent: Create error: %v", err)
|
||||
return nil, fmt.Errorf("failed to create agent: %w", err)
|
||||
}
|
||||
log.Printf("[AgentService] CreateAgent: created successfully")
|
||||
|
||||
var result CreateAgentResponse
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
|
||||
}
|
||||
log.Printf("[AgentService] Agent created in database: %s (ID: %s)", agent.Name, agent.ID)
|
||||
|
||||
log.Printf("[AgentService] Agent created: %s (ID: %d)", result.Name, result.AgentID)
|
||||
// 解析 agent ID 为整数返回
|
||||
agentIDInt := int(time.Now().Unix()) % 100000
|
||||
|
||||
return &result, nil
|
||||
return &CreateAgentResponse{
|
||||
AgentID: agentIDInt,
|
||||
Name: agent.Name,
|
||||
Message: "Agent created successfully",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListAgentsResponse 获取智能体列表响应
|
||||
@@ -360,37 +362,120 @@ type ListAgentsResponse struct {
|
||||
Agents []interface{} `json:"agents"`
|
||||
}
|
||||
|
||||
// ListAgents 获取智能体列表
|
||||
// ListAgents 获取智能体列表(从数据库获取)
|
||||
func (s *AgentService) ListAgents() (*ListAgentsResponse, error) {
|
||||
url := fmt.Sprintf("%s/agent/list", s.pythonURL)
|
||||
if s.agentRepo == nil {
|
||||
log.Printf("[AgentService] ListAgents: agentRepo is nil!")
|
||||
return nil, fmt.Errorf("agent repository not initialized")
|
||||
}
|
||||
|
||||
httpReq, err := http.NewRequest("GET", url, nil)
|
||||
log.Printf("[AgentService] ListAgents: calling FindAll")
|
||||
agents, err := s.agentRepo.FindAll()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
httpReq.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := s.client.Do(httpReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to call python agent: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response: %w", err)
|
||||
log.Printf("[AgentService] ListAgents: FindAll error: %v", err)
|
||||
return nil, fmt.Errorf("failed to list agents: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("python agent error: %s", string(body))
|
||||
log.Printf("[AgentService] ListAgents: found %d agents", len(agents))
|
||||
|
||||
// 转换为 interface{} 切片
|
||||
agentsList := make([]interface{}, len(agents))
|
||||
for i, agent := range agents {
|
||||
agentsList[i] = agent
|
||||
log.Printf("[AgentService] ListAgents: agent[%d] = %+v", i, agent)
|
||||
}
|
||||
|
||||
var result ListAgentsResponse
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("[AgentService] Listed agents: %d", len(result.Agents))
|
||||
|
||||
return &result, nil
|
||||
return &ListAgentsResponse{
|
||||
Agents: agentsList,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateAgentStatus 更新智能体状态
|
||||
func (s *AgentService) UpdateAgentStatus(agentID string, isActive bool) error {
|
||||
if s.agentRepo == nil {
|
||||
return fmt.Errorf("agent repository not initialized")
|
||||
}
|
||||
|
||||
log.Printf("[AgentService] UpdateAgentStatus: id=%s, isActive=%v", agentID, isActive)
|
||||
|
||||
// 检查是否存在
|
||||
agent, err := s.agentRepo.FindByID(agentID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("agent not found: %w", err)
|
||||
}
|
||||
|
||||
agent.IsActive = isActive
|
||||
agent.UpdatedAt = time.Now()
|
||||
|
||||
if err := s.agentRepo.Update(agent); err != nil {
|
||||
return fmt.Errorf("failed to update agent: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("[AgentService] Agent status updated: id=%s, isActive=%v", agentID, isActive)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteAgent 删除智能体
|
||||
func (s *AgentService) DeleteAgent(agentID string) error {
|
||||
if s.agentRepo == nil {
|
||||
return fmt.Errorf("agent repository not initialized")
|
||||
}
|
||||
|
||||
log.Printf("[AgentService] DeleteAgent: id=%s", agentID)
|
||||
|
||||
// 检查是否存在
|
||||
_, err := s.agentRepo.FindByID(agentID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("agent not found: %w", err)
|
||||
}
|
||||
|
||||
if err := s.agentRepo.Delete(agentID); err != nil {
|
||||
return fmt.Errorf("failed to delete agent: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("[AgentService] Agent deleted: id=%s", agentID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateAgent 更新智能体
|
||||
func (s *AgentService) UpdateAgent(agentID, name, description string, skills []string, roleDescription, modelProvider, modelName string) error {
|
||||
if s.agentRepo == nil {
|
||||
return fmt.Errorf("agent repository not initialized")
|
||||
}
|
||||
|
||||
log.Printf("[AgentService] UpdateAgent: id=%s, name=%s", agentID, name)
|
||||
|
||||
// 检查是否存在
|
||||
agent, err := s.agentRepo.FindByID(agentID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("agent not found: %w", err)
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
if name != "" {
|
||||
agent.Name = name
|
||||
}
|
||||
if description != "" {
|
||||
agent.Description = description
|
||||
}
|
||||
if skills != nil {
|
||||
agent.Skills = skills
|
||||
}
|
||||
if roleDescription != "" {
|
||||
agent.RoleDescription = roleDescription
|
||||
}
|
||||
if modelProvider != "" {
|
||||
agent.ModelProvider = modelProvider
|
||||
}
|
||||
if modelName != "" {
|
||||
agent.ModelName = modelName
|
||||
}
|
||||
agent.UpdatedAt = time.Now()
|
||||
|
||||
if err := s.agentRepo.Update(agent); err != nil {
|
||||
return fmt.Errorf("failed to update agent: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("[AgentService] Agent updated: id=%s", agentID)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user