From 7c973750dddca84353bd7e8ec2ea84de8e4ce599 Mon Sep 17 00:00:00 2001 From: wolter <11@gmail> Date: Wed, 10 Dec 2025 15:23:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=84=8F=E5=9B=BE=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E6=8B=86=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/biz/router.go | 98 ++++++++++++++++++++++++++++++- internal/data/constants/caller.go | 8 +++ internal/entitys/recognize.go | 14 ++--- internal/entitys/types.go | 4 +- 4 files changed, 114 insertions(+), 10 deletions(-) diff --git a/internal/biz/router.go b/internal/biz/router.go index 183ee89..c164c31 100644 --- a/internal/biz/router.go +++ b/internal/biz/router.go @@ -2,8 +2,11 @@ package biz import ( "ai_scheduler/internal/biz/do" + "ai_scheduler/internal/data/constants" "ai_scheduler/internal/gateway" "context" + "encoding/json" + "time" "ai_scheduler/internal/entitys" @@ -77,6 +80,99 @@ func (r *AiRouterBiz) RouteWithSocket(client *gateway.Client, req *entitys.ChatS } func (r *AiRouterBiz) SetRec(ctx context.Context, requireData *entitys.RequireData) (match entitys.Recognize, err error) { - //TODO 叙平 + // 参数空值检查 + if requireData == nil || requireData.Req == nil { + return match, err + } + + // 1. 系统提示词 + match.SystemPrompt = requireData.Sys.SysPrompt + + // 2. 用户输入和文件处理 + match.UserContent, err = r.buildUserContent(requireData) + if err != nil { + log.Errorf("构建用户内容失败: %s", err.Error()) + return + } + + // 3. 聊天记录 - 只有在有历史记录时才构建 + if len(requireData.Histories) > 0 { + match.ChatHis = r.buildChatHistory(requireData) + } + + // 4. 任务列表 - 预分配切片容量 + if len(requireData.Tasks) > 0 { + match.Tasks = make([]entitys.RegistrationTask, 0, len(requireData.Tasks)) + for _, task := range requireData.Tasks { + taskConfig := entitys.TaskConfigDetail{} + if err = json.Unmarshal([]byte(task.Config), &taskConfig); err != nil { + log.Errorf("解析任务配置失败: %s, 任务ID: %s", err.Error(), task.Index) + continue // 解析失败时跳过该任务,而不是直接返回错误 + } + + match.Tasks = append(match.Tasks, entitys.RegistrationTask{ + Name: task.Index, + Desc: task.Desc, + TaskConfigDetail: taskConfig, // 直接使用解析后的配置,避免重复构建 + }) + } + } + + match.Ch = requireData.Ch return } + +// buildUserContent 构建用户内容 +func (r *AiRouterBiz) buildUserContent(requireData *entitys.RequireData) (*entitys.RecognizeUserContent, error) { + // 预分配文件切片容量(最多2个文件:File和Img) + files := make([]*entitys.RecognizeFile, 0, 2) + + // 处理文件和图片 + fileUrls := []string{requireData.Req.File, requireData.Req.Img} + for _, url := range fileUrls { + if url != "" { + files = append(files, &entitys.RecognizeFile{FileUrl: url}) + } + } + + // 构建并返回用户内容 + return &entitys.RecognizeUserContent{ + Text: requireData.Req.Text, + File: files, + ActionCardUrl: "", // TODO: 后续实现操作卡片功能 + Tag: requireData.Req.Tags, + }, nil +} + +// buildChatHistory 构建聊天历史 +func (r *AiRouterBiz) buildChatHistory(requireData *entitys.RequireData) entitys.ChatHis { + // 预分配消息切片容量(每个历史记录生成2条消息) + messages := make([]entitys.HisMessage, 0, len(requireData.Histories)*2) + + // 构建聊天记录 + for _, h := range requireData.Histories { + // 用户消息 + messages = append(messages, entitys.HisMessage{ + Role: constants.RoleUser, // 用户角色 + Content: h.Ans, // 用户输入内容 + Timestamp: h.CreateAt.Format(time.DateTime), + }) + + // 助手消息 + messages = append(messages, entitys.HisMessage{ + Role: constants.RoleAssistant, // 助手角色 + Content: h.Ques, // 助手回复内容 + Timestamp: h.CreateAt.Format(time.DateTime), + }) + } + + // 构建聊天历史上下文 + return entitys.ChatHis{ + SessionId: requireData.Session, + Messages: messages, + Context: entitys.HisContext{ + UserLanguage: constants.LangZhCN, // 默认中文 + SystemMode: constants.SystemModeTechnicalSupport, // 默认技术支持模式 + }, + } +} diff --git a/internal/data/constants/caller.go b/internal/data/constants/caller.go index 74493f3..0df9b33 100644 --- a/internal/data/constants/caller.go +++ b/internal/data/constants/caller.go @@ -13,6 +13,14 @@ const ( // 分页默认条数 ChatHistoryLimit = 10 + + // 语言 + LangZhCN = "zh-CN" // 中文 + + // 系统模式 + SystemModeDefault = "default" // 默认模式 + // 系统模式 "technical_support", // 技术支持模式 + SystemModeTechnicalSupport = "technical_support" // 技术支持模式 ) func (c Caller) String() string { diff --git a/internal/entitys/recognize.go b/internal/entitys/recognize.go index fc8b55f..45d9fcc 100644 --- a/internal/entitys/recognize.go +++ b/internal/entitys/recognize.go @@ -5,9 +5,9 @@ import ( ) type Recognize struct { - SystemPrompt string - UserContent *RecognizeUserContent - ChatHis ChatHis + SystemPrompt string // 系统提示内容 + UserContent *RecognizeUserContent // 用户输入内容 + ChatHis ChatHis // 会话历史记录 Tasks []RegistrationTask Ch chan Response } @@ -19,10 +19,10 @@ type RegistrationTask struct { } type RecognizeUserContent struct { - Text string - File []*RecognizeFile - ActionCardUrl string - Tag string + Text string // 用户输入的文本内容 + File []*RecognizeFile // 文件内容 + ActionCardUrl string // 操作卡片链接 + Tag string // 工具标签 } type FileData []byte diff --git a/internal/entitys/types.go b/internal/entitys/types.go index ef229a7..72ecd6c 100644 --- a/internal/entitys/types.go +++ b/internal/entitys/types.go @@ -138,8 +138,8 @@ type HisMessage struct { } type HisContext struct { - UserLanguage string `json:"user_language"` - SystemMode string `json:"system_mode"` + UserLanguage string `json:"user_language"` // 用户语言 + SystemMode string `json:"system_mode"` // 系统模式, } type RequireData struct {