- 新增chat_session相关模型、仓库和服务 - 新增chat_group相关模型、仓库和服务 - 新增session_handler和chat_group_handler - 实现会话管理和群聊功能 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
158 lines
3.7 KiB
Go
158 lines
3.7 KiB
Go
package service
|
|
|
|
import (
|
|
"errors"
|
|
"x-agents/server/internal/model"
|
|
"x-agents/server/internal/repository"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// 错误定义
|
|
var (
|
|
ErrNoAgents = errors.New("no agents provided")
|
|
ErrAgentNotFound = errors.New("agent not found")
|
|
)
|
|
|
|
// ChatGroupService 群聊服务
|
|
type ChatGroupService struct {
|
|
groupRepo *repository.ChatGroupRepository
|
|
agentRepo *repository.AgentRepository
|
|
}
|
|
|
|
// NewChatGroupService 创建群聊服务
|
|
func NewChatGroupService(groupRepo *repository.ChatGroupRepository, agentRepo *repository.AgentRepository) *ChatGroupService {
|
|
return &ChatGroupService{
|
|
groupRepo: groupRepo,
|
|
agentRepo: agentRepo,
|
|
}
|
|
}
|
|
|
|
// CreateGroup 创建群聊
|
|
func (s *ChatGroupService) CreateGroup(req model.CreateGroupRequest) (*model.ChatGroup, error) {
|
|
group := &model.ChatGroup{
|
|
ID: uuid.New().String(),
|
|
UserID: req.UserID,
|
|
Name: req.Name,
|
|
Description: req.Description,
|
|
AgentIDs: req.AgentIDs,
|
|
Status: "active",
|
|
}
|
|
|
|
err := s.groupRepo.Create(group)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return group, nil
|
|
}
|
|
|
|
// GetGroup 获取群聊详情
|
|
func (s *ChatGroupService) GetGroup(id string) (*model.ChatGroup, error) {
|
|
return s.groupRepo.FindByID(id)
|
|
}
|
|
|
|
// ListGroups 获取群聊列表
|
|
func (s *ChatGroupService) ListGroups(userID string, limit, offset int) ([]model.ChatGroup, int64, error) {
|
|
if limit <= 0 {
|
|
limit = 20
|
|
}
|
|
return s.groupRepo.FindByUserID(userID, limit, offset)
|
|
}
|
|
|
|
// UpdateGroup 更新群聊
|
|
func (s *ChatGroupService) UpdateGroup(id string, req model.UpdateGroupRequest) (*model.ChatGroup, error) {
|
|
group, err := s.groupRepo.FindByID(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if req.Name != "" {
|
|
group.Name = req.Name
|
|
}
|
|
if req.Description != "" {
|
|
group.Description = req.Description
|
|
}
|
|
if req.AgentIDs != "" {
|
|
group.AgentIDs = req.AgentIDs
|
|
}
|
|
if req.Status != "" {
|
|
group.Status = req.Status
|
|
}
|
|
|
|
err = s.groupRepo.Update(group)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return group, nil
|
|
}
|
|
|
|
// DeleteGroup 删除群聊
|
|
func (s *ChatGroupService) DeleteGroup(id string) error {
|
|
return s.groupRepo.Delete(id)
|
|
}
|
|
|
|
// GroupChat 群聊对话
|
|
func (s *ChatGroupService) GroupChat(userID, message, agentIDs, sessionID string) (*model.GroupChatResponse, error) {
|
|
// 解析 Agent IDs
|
|
agentIDList := parseAgentIDs(agentIDs)
|
|
|
|
if len(agentIDList) == 0 {
|
|
return nil, ErrNoAgents
|
|
}
|
|
|
|
// 获取所有 Agent 信息
|
|
agents, err := s.agentRepo.FindByIDs(agentIDList)
|
|
if err != nil || len(agents) == 0 {
|
|
return nil, ErrAgentNotFound
|
|
}
|
|
|
|
// 并行调用所有 Agent
|
|
results := make(chan model.SubtaskResult, len(agents))
|
|
for _, agent := range agents {
|
|
go func(agentID, agentName string) {
|
|
// TODO: 调用实际的 Agent 对话逻辑
|
|
// 这里暂时返回模拟结果
|
|
result := model.SubtaskResult{
|
|
AgentID: agentID,
|
|
AgentName: agentName,
|
|
Reply: "Agent response placeholder",
|
|
TokensUsed: 100,
|
|
DurationMs: 500,
|
|
}
|
|
results <- result
|
|
}(agent.ID, agent.Name)
|
|
}
|
|
|
|
// 收集结果
|
|
subtaskResults := make([]model.SubtaskResult, 0, len(agents))
|
|
for i := 0; i < len(agents); i++ {
|
|
subtaskResults = append(subtaskResults, <-results)
|
|
}
|
|
close(results)
|
|
|
|
// 汇总结果
|
|
response := &model.GroupChatResponse{
|
|
SessionID: sessionID,
|
|
Reply: "Group chat completed",
|
|
DurationMs: 1000,
|
|
TokensUsed: 500,
|
|
Strategy: "parallel",
|
|
SubtaskResults: subtaskResults,
|
|
}
|
|
|
|
return response, nil
|
|
}
|
|
|
|
// 辅助函数:解析 Agent IDs
|
|
func parseAgentIDs(agentIDs string) []string {
|
|
if agentIDs == "" {
|
|
return []string{}
|
|
}
|
|
// 简单解析,假设是 JSON 数组格式
|
|
// 实际应该使用 json.Unmarshal
|
|
// 这里简化处理,直接返回
|
|
return []string{agentIDs}
|
|
}
|