2026-05-18 19:19:17 +08:00
|
|
|
|
package prompt
|
2026-05-12 13:59:15 +08:00
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"context"
|
|
|
|
|
|
"encoding/json"
|
|
|
|
|
|
"errors"
|
|
|
|
|
|
"fmt"
|
2026-05-27 09:36:26 +08:00
|
|
|
|
"prompts-core/service/session"
|
2026-05-12 13:59:15 +08:00
|
|
|
|
|
2026-05-18 19:19:17 +08:00
|
|
|
|
"gitea.com/red-future/common/beans"
|
|
|
|
|
|
"gitea.com/red-future/common/utils"
|
2026-05-12 13:59:15 +08:00
|
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
2026-05-20 11:36:39 +08:00
|
|
|
|
|
|
|
|
|
|
"prompts-core/common/util"
|
|
|
|
|
|
"prompts-core/consts/public"
|
|
|
|
|
|
"prompts-core/dao"
|
|
|
|
|
|
"prompts-core/model/dto"
|
|
|
|
|
|
"prompts-core/model/entity"
|
|
|
|
|
|
"prompts-core/service/gateway"
|
2026-05-12 13:59:15 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2026-05-18 19:19:17 +08:00
|
|
|
|
// ComposeMessages 核心拼接提示词主流程
|
2026-05-20 11:36:39 +08:00
|
|
|
|
func ComposeMessages(ctx context.Context, req *dto.ComposeMessagesReq) (*dto.ComposeMessagesRes, error) {
|
2026-05-29 17:54:19 +08:00
|
|
|
|
//1) 获取模型信息
|
2026-05-18 19:19:17 +08:00
|
|
|
|
chatModel, aiModel, err := GetModelMessage(ctx, req)
|
2026-05-12 13:59:15 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
2026-05-29 17:54:19 +08:00
|
|
|
|
//2) 校验用户表单
|
2026-05-22 09:49:46 +08:00
|
|
|
|
if err = validateUserForm(req, aiModel); err != nil {
|
2026-05-20 11:36:39 +08:00
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
2026-05-29 17:54:19 +08:00
|
|
|
|
//3) 处理不同类型
|
2026-05-15 09:45:51 +08:00
|
|
|
|
switch req.BuildType {
|
2026-05-20 11:36:39 +08:00
|
|
|
|
case public.BuildTypePrompt:
|
|
|
|
|
|
return handlePromptBuild(ctx, req, chatModel, aiModel) // 提示词构建
|
|
|
|
|
|
case public.BuildTypeNode:
|
|
|
|
|
|
return handleNodeBuild(ctx, req, chatModel, aiModel) // 节点构建
|
|
|
|
|
|
default:
|
2026-05-22 09:49:46 +08:00
|
|
|
|
return nil, errors.New("BuildType 不支持")
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-12 13:59:15 +08:00
|
|
|
|
|
2026-05-22 09:49:46 +08:00
|
|
|
|
// GetModelMessage 获取模型信息
|
|
|
|
|
|
func GetModelMessage(ctx context.Context, req *dto.ComposeMessagesReq) (*entity.AsynchModel, *entity.AsynchModel, error) {
|
|
|
|
|
|
userInfo, err := utils.GetUserInfo(ctx)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, nil, fmt.Errorf("获取用户信息失败: %w", err)
|
|
|
|
|
|
}
|
2026-05-27 09:36:26 +08:00
|
|
|
|
chatModel, err := dao.Model.Get(ctx, &entity.AsynchModel{
|
|
|
|
|
|
SQLBaseDO: beans.SQLBaseDO{Creator: userInfo.UserName},
|
|
|
|
|
|
IsChatModel: new(1),
|
|
|
|
|
|
})
|
2026-05-22 09:49:46 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, nil, err
|
|
|
|
|
|
}
|
2026-05-27 09:36:26 +08:00
|
|
|
|
if chatModel == nil {
|
|
|
|
|
|
return nil, nil, errors.New("当前没有对话模型,请添加")
|
|
|
|
|
|
}
|
2026-05-29 17:54:19 +08:00
|
|
|
|
aiModels, err := dao.Model.Get(ctx, &entity.AsynchModel{
|
2026-05-27 09:36:26 +08:00
|
|
|
|
SQLBaseDO: beans.SQLBaseDO{Creator: userInfo.UserName},
|
|
|
|
|
|
ModelName: req.ModelName,
|
|
|
|
|
|
})
|
2026-05-22 09:49:46 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-29 17:54:19 +08:00
|
|
|
|
if aiModels == nil {
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return nil, nil, errors.New("需要构建的模型不存在")
|
|
|
|
|
|
}
|
2026-05-29 17:54:19 +08:00
|
|
|
|
return chatModel, aiModels, nil
|
2026-05-22 09:49:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-20 11:36:39 +08:00
|
|
|
|
// validateUserForm 校验用户表单
|
2026-05-22 09:49:46 +08:00
|
|
|
|
func validateUserForm(req *dto.ComposeMessagesReq, model *entity.AsynchModel) error {
|
2026-05-20 11:36:39 +08:00
|
|
|
|
if len(req.UserForm) == 0 {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
isValid, exceedTokens, err := util.CheckUserFormWithinWindow(req.UserForm, model.TokenConfig)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return fmt.Errorf("校验用户表单失败: %w", err)
|
|
|
|
|
|
}
|
2026-05-12 13:59:15 +08:00
|
|
|
|
|
2026-05-20 11:36:39 +08:00
|
|
|
|
if !isValid {
|
|
|
|
|
|
availableWindow := util.GetAvailableWindow(model.TokenConfig)
|
|
|
|
|
|
return fmt.Errorf("UserForm 内容超出窗口大小: 超出 %d tokens,可用窗口 %d tokens,请精简后重试",
|
|
|
|
|
|
exceedTokens, availableWindow)
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// handlePromptBuild 处理提示词构建(BuildType=1)
|
|
|
|
|
|
func handlePromptBuild(ctx context.Context, req *dto.ComposeMessagesReq, chatModel, aiModel *entity.AsynchModel) (*dto.ComposeMessagesRes, error) {
|
2026-05-22 09:49:46 +08:00
|
|
|
|
// 获取历史会话
|
2026-05-27 09:36:26 +08:00
|
|
|
|
history, err := session.GetHistoryMessages(ctx, req.SessionId)
|
2026-05-20 11:36:39 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
g.Log().Errorf(ctx, "获取历史会话失败: %v,将不使用历史会话", err)
|
|
|
|
|
|
history = nil
|
|
|
|
|
|
}
|
2026-05-22 09:49:46 +08:00
|
|
|
|
// 调用推理模型
|
2026-05-27 09:36:26 +08:00
|
|
|
|
taskID, id, err := callInferenceModel(ctx, req, chatModel, aiModel, history)
|
2026-05-20 11:36:39 +08:00
|
|
|
|
if err != nil {
|
2026-05-22 09:49:46 +08:00
|
|
|
|
return nil, fmt.Errorf("调用推理模型失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 保存任务记录
|
2026-05-27 09:36:26 +08:00
|
|
|
|
_, err = dao.ComposeTask.Insert(ctx, &entity.ComposeTask{
|
|
|
|
|
|
TaskId: taskID,
|
|
|
|
|
|
ModelName: req.ModelName,
|
|
|
|
|
|
SkillName: req.SkillName,
|
|
|
|
|
|
BuildType: req.BuildType,
|
|
|
|
|
|
CallbackUrl: req.CallbackUrl,
|
|
|
|
|
|
RequestPayload: util.MustMarshalToMap(req),
|
|
|
|
|
|
Status: public.ComposeStatusPending,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
2026-05-22 09:49:46 +08:00
|
|
|
|
return nil, fmt.Errorf("保存任务记录失败: %w", err)
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
return &dto.ComposeMessagesRes{
|
2026-05-27 09:36:26 +08:00
|
|
|
|
TaskId: taskID,
|
|
|
|
|
|
EpicycleId: id,
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// handleNodeBuild 处理节点构建(BuildType=2)
|
|
|
|
|
|
func handleNodeBuild(ctx context.Context, req *dto.ComposeMessagesReq, chatModel, aiModel *entity.AsynchModel) (*dto.ComposeMessagesRes, error) {
|
2026-05-27 09:36:26 +08:00
|
|
|
|
taskID, id, err := callInferenceModel(ctx, req, chatModel, aiModel, nil)
|
2026-05-20 11:36:39 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("调用推理模型失败: %w", err)
|
|
|
|
|
|
}
|
2026-05-27 09:36:26 +08:00
|
|
|
|
// 保存任务记录
|
|
|
|
|
|
_, err = dao.ComposeTask.Insert(ctx, &entity.ComposeTask{
|
2026-05-20 11:36:39 +08:00
|
|
|
|
TaskId: taskID,
|
|
|
|
|
|
ModelName: req.ModelName,
|
|
|
|
|
|
SkillName: req.SkillName,
|
2026-05-22 09:49:46 +08:00
|
|
|
|
BuildType: req.BuildType,
|
|
|
|
|
|
CallbackUrl: req.CallbackUrl,
|
2026-05-23 18:08:09 +08:00
|
|
|
|
RequestPayload: util.MustMarshalToMap(req),
|
2026-05-20 11:36:39 +08:00
|
|
|
|
Status: public.ComposeStatusPending,
|
|
|
|
|
|
})
|
2026-05-15 09:45:51 +08:00
|
|
|
|
if err != nil {
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return nil, fmt.Errorf("保存任务记录失败: %w", err)
|
2026-05-15 09:45:51 +08:00
|
|
|
|
}
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return &dto.ComposeMessagesRes{
|
|
|
|
|
|
TaskId: taskID,
|
|
|
|
|
|
EpicycleId: id,
|
|
|
|
|
|
}, nil
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-27 09:36:26 +08:00
|
|
|
|
// callInferenceModel 调用推理模型
|
|
|
|
|
|
func callInferenceModel(ctx context.Context, req *dto.ComposeMessagesReq, chatModel *entity.AsynchModel, aiModel *entity.AsynchModel, history []map[string]any) (string, int64, error) {
|
|
|
|
|
|
taskReq, err := buildInferenceRequest(ctx, req, chatModel, aiModel, history)
|
2026-05-15 09:45:51 +08:00
|
|
|
|
if err != nil {
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return "", 0, fmt.Errorf("构建推理请求失败: %w", err)
|
2026-05-15 09:45:51 +08:00
|
|
|
|
}
|
2026-05-29 17:54:19 +08:00
|
|
|
|
id := int64(0)
|
|
|
|
|
|
if req.SessionId != "" {
|
|
|
|
|
|
id, err = dao.ComposeSession.Insert(ctx, &entity.ComposeSession{
|
|
|
|
|
|
SessionId: req.SessionId,
|
|
|
|
|
|
RequestContent: util.GetUserMessage(taskReq),
|
|
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", 0, fmt.Errorf("保存历史会话失败: %w", err)
|
|
|
|
|
|
}
|
2026-05-12 13:59:15 +08:00
|
|
|
|
}
|
2026-05-18 19:19:17 +08:00
|
|
|
|
taskID, err := gateway.CreateGatewayTask(ctx, taskReq)
|
2026-05-12 13:59:15 +08:00
|
|
|
|
if err != nil {
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return "", 0, fmt.Errorf("创建网关任务失败: %w", err)
|
2026-05-12 13:59:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if taskID == "" {
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return "", 0, errors.New("网关未返回taskId")
|
2026-05-12 13:59:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return taskID, id, nil
|
2026-05-22 09:49:46 +08:00
|
|
|
|
}
|
2026-05-15 09:45:51 +08:00
|
|
|
|
|
2026-05-22 09:49:46 +08:00
|
|
|
|
// Callback 回调处理
|
|
|
|
|
|
func Callback(ctx context.Context, req *dto.CallbackReq) error {
|
|
|
|
|
|
g.Log().Infof(ctx, "[Callback][RECV] taskId=%s state=%d ossFile=%s fileType=%s textLen=%d",
|
2026-05-27 09:36:26 +08:00
|
|
|
|
req.TaskId, req.State, req.OssFile, req.FileType, len(req.Messages))
|
2026-05-23 18:08:09 +08:00
|
|
|
|
// 查询任务
|
2026-05-22 09:49:46 +08:00
|
|
|
|
composeTask, err := dao.ComposeTask.Get(ctx, &entity.ComposeTask{
|
|
|
|
|
|
TaskId: req.TaskId,
|
|
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return fmt.Errorf("查询任务失败: %w", err)
|
|
|
|
|
|
}
|
2026-05-23 18:08:09 +08:00
|
|
|
|
model, err := dao.Model.Get(ctx, &entity.AsynchModel{
|
|
|
|
|
|
SQLBaseDO: beans.SQLBaseDO{Creator: composeTask.Creator},
|
|
|
|
|
|
ModelName: composeTask.ModelName,
|
|
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return fmt.Errorf("查询模型失败: %w", err)
|
2026-05-22 09:49:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
//处理失败
|
|
|
|
|
|
if req.State == 3 {
|
|
|
|
|
|
_, err = dao.ComposeTask.Update(ctx, &entity.ComposeTask{
|
|
|
|
|
|
TaskId: req.TaskId,
|
|
|
|
|
|
Status: public.ComposeStatusFailed,
|
|
|
|
|
|
ErrorMessage: req.ErrorMsg,
|
|
|
|
|
|
GatewayState: req.State,
|
|
|
|
|
|
OssFile: req.OssFile,
|
|
|
|
|
|
FileType: req.FileType,
|
2026-05-27 09:36:26 +08:00
|
|
|
|
ResultText: req.Messages,
|
2026-05-22 09:49:46 +08:00
|
|
|
|
})
|
|
|
|
|
|
// 用更新后的值发送回调
|
|
|
|
|
|
if composeTask.CallbackUrl != "" {
|
|
|
|
|
|
failedTask := &entity.ComposeTask{
|
|
|
|
|
|
TaskId: req.TaskId,
|
|
|
|
|
|
Status: public.ComposeStatusFailed,
|
|
|
|
|
|
ErrorMessage: req.ErrorMsg,
|
|
|
|
|
|
CallbackUrl: composeTask.CallbackUrl,
|
|
|
|
|
|
Messages: composeTask.Messages,
|
|
|
|
|
|
}
|
|
|
|
|
|
gateway.SendCallback(ctx, failedTask)
|
2026-05-15 09:45:51 +08:00
|
|
|
|
}
|
2026-05-22 09:49:46 +08:00
|
|
|
|
return err
|
2026-05-12 13:59:15 +08:00
|
|
|
|
}
|
2026-05-22 09:49:46 +08:00
|
|
|
|
//处理成功
|
|
|
|
|
|
if req.State == 2 {
|
|
|
|
|
|
// 1. 根据 BuildType 解析结果
|
2026-05-23 18:08:09 +08:00
|
|
|
|
var messages map[string]any
|
2026-05-22 09:49:46 +08:00
|
|
|
|
switch composeTask.BuildType {
|
|
|
|
|
|
case public.BuildTypePrompt: // 提示词构建解析
|
2026-05-27 09:36:26 +08:00
|
|
|
|
messages = ParsePromptResult(req.Messages)
|
2026-05-22 09:49:46 +08:00
|
|
|
|
case public.BuildTypeNode: // 节点构建解析
|
2026-05-27 09:36:26 +08:00
|
|
|
|
messages = ParseNodeResult(req.Messages)
|
2026-05-22 09:49:46 +08:00
|
|
|
|
default:
|
2026-05-27 09:36:26 +08:00
|
|
|
|
messages = req.Messages
|
2026-05-22 09:49:46 +08:00
|
|
|
|
}
|
2026-05-23 18:08:09 +08:00
|
|
|
|
// 2. 处理附加字段
|
|
|
|
|
|
messages = util.MergeConsult(composeTask.RequestPayload, messages, model.ExtendMapping)
|
|
|
|
|
|
// 3. 更新数据库
|
2026-05-22 09:49:46 +08:00
|
|
|
|
_, err = dao.ComposeTask.Update(ctx, &entity.ComposeTask{
|
|
|
|
|
|
TaskId: req.TaskId,
|
|
|
|
|
|
Status: public.ComposeStatusSuccess,
|
|
|
|
|
|
Messages: messages,
|
|
|
|
|
|
GatewayState: req.State,
|
|
|
|
|
|
OssFile: req.OssFile,
|
|
|
|
|
|
FileType: req.FileType,
|
2026-05-27 09:36:26 +08:00
|
|
|
|
ResultText: req.Messages,
|
2026-05-22 09:49:46 +08:00
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
g.Log().Errorf(ctx, "[Callback] 更新成功状态失败 taskId=%s err=%v", req.TaskId, err)
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
// 4. 发送回调给业务方
|
|
|
|
|
|
if composeTask.CallbackUrl != "" {
|
|
|
|
|
|
successTask := &entity.ComposeTask{
|
|
|
|
|
|
TaskId: req.TaskId,
|
|
|
|
|
|
Status: public.ComposeStatusSuccess,
|
|
|
|
|
|
Messages: messages,
|
|
|
|
|
|
CallbackUrl: composeTask.CallbackUrl,
|
|
|
|
|
|
}
|
|
|
|
|
|
gateway.SendCallback(ctx, successTask)
|
|
|
|
|
|
}
|
2026-05-12 13:59:15 +08:00
|
|
|
|
}
|
2026-05-22 09:49:46 +08:00
|
|
|
|
return err
|
|
|
|
|
|
}
|
2026-05-21 14:23:34 +08:00
|
|
|
|
|
2026-05-23 18:08:09 +08:00
|
|
|
|
// ParsePromptResult 解析提示词构建结果
|
2026-05-27 09:36:26 +08:00
|
|
|
|
func ParsePromptResult(raw map[string]any) map[string]any {
|
|
|
|
|
|
contentStr, ok := raw["content"].(string)
|
2026-05-20 11:36:39 +08:00
|
|
|
|
if !ok || contentStr == "" {
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return raw
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-21 14:23:34 +08:00
|
|
|
|
if roundsArray := tryParseAsMapArray(contentStr); roundsArray != nil {
|
2026-05-23 18:08:09 +08:00
|
|
|
|
return map[string]any{
|
|
|
|
|
|
"total_rounds": len(roundsArray),
|
|
|
|
|
|
"rounds": roundsArray,
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-21 14:23:34 +08:00
|
|
|
|
if singleRound := tryParseAsMap(contentStr); singleRound != nil {
|
2026-05-23 18:08:09 +08:00
|
|
|
|
return map[string]any{
|
|
|
|
|
|
"total_rounds": 1,
|
|
|
|
|
|
"rounds": []map[string]any{singleRound},
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return map[string]any{"content": contentStr}
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-21 14:23:34 +08:00
|
|
|
|
func tryParseAsMapArray(jsonStr string) []map[string]any {
|
|
|
|
|
|
var arr []map[string]any
|
|
|
|
|
|
if err := json.Unmarshal([]byte(jsonStr), &arr); err != nil {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(arr) == 0 {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
return arr
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func tryParseAsMap(jsonStr string) map[string]any {
|
|
|
|
|
|
var obj map[string]any
|
|
|
|
|
|
if err := json.Unmarshal([]byte(jsonStr), &obj); err != nil {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(obj) == 0 {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
return obj
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-27 09:36:26 +08:00
|
|
|
|
func ParseNodeResult(raw map[string]any) map[string]any {
|
|
|
|
|
|
contentStr, ok := raw["content"].(string)
|
|
|
|
|
|
if ok && contentStr != "" {
|
2026-05-22 09:49:46 +08:00
|
|
|
|
var inner map[string]any
|
|
|
|
|
|
if err := json.Unmarshal([]byte(contentStr), &inner); err == nil {
|
2026-05-27 09:36:26 +08:00
|
|
|
|
return map[string]any{
|
|
|
|
|
|
"total_rounds": 1,
|
|
|
|
|
|
"rounds": []map[string]any{inner},
|
|
|
|
|
|
}
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}
|
2026-05-12 13:59:15 +08:00
|
|
|
|
}
|
2026-05-23 18:08:09 +08:00
|
|
|
|
return map[string]any{
|
|
|
|
|
|
"total_rounds": 1,
|
2026-05-27 09:36:26 +08:00
|
|
|
|
"rounds": []map[string]any{raw},
|
2026-05-20 11:36:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-18 19:19:17 +08:00
|
|
|
|
// GetComposeTask 查询任务结果
|
2026-05-20 11:36:39 +08:00
|
|
|
|
func GetComposeTask(ctx context.Context, taskID string) (*dto.GetComposeTaskRes, error) {
|
2026-05-18 19:19:17 +08:00
|
|
|
|
record, err := dao.ComposeTask.Get(ctx, &entity.ComposeTask{
|
|
|
|
|
|
TaskId: taskID,
|
|
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
2026-05-20 11:36:39 +08:00
|
|
|
|
return nil, fmt.Errorf("查询任务失败: %w", err)
|
2026-05-18 19:19:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
if record == nil {
|
|
|
|
|
|
return nil, fmt.Errorf("未找到任务(taskId=%s)", taskID)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-20 11:36:39 +08:00
|
|
|
|
messages := parseMessagesForResponse(record.Messages)
|
2026-05-18 19:19:17 +08:00
|
|
|
|
|
2026-05-20 11:36:39 +08:00
|
|
|
|
return &dto.GetComposeTaskRes{
|
2026-05-18 19:19:17 +08:00
|
|
|
|
TaskId: record.TaskId,
|
|
|
|
|
|
Status: record.Status,
|
|
|
|
|
|
ErrorMessage: record.ErrorMessage,
|
|
|
|
|
|
Messages: messages,
|
|
|
|
|
|
}, nil
|
|
|
|
|
|
}
|
2026-05-20 11:36:39 +08:00
|
|
|
|
|
|
|
|
|
|
// parseMessagesForResponse 解析用于响应的消息
|
|
|
|
|
|
func parseMessagesForResponse(messages any) any {
|
|
|
|
|
|
str, ok := messages.(string)
|
|
|
|
|
|
if !ok || str == "" {
|
|
|
|
|
|
return messages
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var parsed any
|
|
|
|
|
|
if err := json.Unmarshal([]byte(str), &parsed); err == nil {
|
|
|
|
|
|
return parsed
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return messages
|
|
|
|
|
|
}
|