- 新增同会话+同工作流最近执行失败且参数一致时断点续跑逻辑 - exec_workflow/exec_chat 新增 error 字段存储原始错误,error_message 仅存友好提示 - 新增 UpdateExecChatReq 与 exec_chat_dao Update 方法 - 新增 GetLatestBySessionAndFlow 查询最近执行记录 - 修正 ListDates 分组与排序 SQL 表达式 - 新增 pipeline 配置结构,删除旧设计文档
128 lines
3.9 KiB
Go
128 lines
3.9 KiB
Go
package node
|
||
|
||
import (
|
||
"context"
|
||
"strconv"
|
||
|
||
"ai-agent/gateway"
|
||
"ai-agent/workflow/consts/model"
|
||
"ai-agent/workflow/consts/node"
|
||
nodeDto "ai-agent/workflow/model/dto/node"
|
||
"ai-agent/workflow/service/flow/processor"
|
||
|
||
"github.com/gogf/gf/v2/frame/g"
|
||
)
|
||
|
||
var NodeLibraryService = &nodeLibraryService{}
|
||
|
||
type nodeLibraryService struct{}
|
||
|
||
func (s *nodeLibraryService) GetNodeLibrary(ctx context.Context, req *nodeDto.WorkflowNodeTreeReq) (*nodeDto.WorkflowNodeTreeRes, error) {
|
||
tree := node.GetFilterNodeTree([]node.NodeGroup{node.NodeGroupBase})
|
||
if opts, err := videoModelOptions(ctx); err != nil {
|
||
g.Log().Warningf(ctx, "加载视频模型选项失败,节点库降级返回: %v", err)
|
||
} else {
|
||
applyVideoModelOptions(tree, opts)
|
||
}
|
||
// 前置/后置方法下拉填充处理器注册表数据
|
||
if opts, err := processorOptions(ctx); err != nil {
|
||
g.Log().Warningf(ctx, "加载工作流前后置处理器选项失败,节点库降级返回: %v", err)
|
||
} else {
|
||
applyProcessorOptions(tree, opts)
|
||
}
|
||
return &nodeDto.WorkflowNodeTreeRes{
|
||
Groups: tree,
|
||
}, nil
|
||
}
|
||
|
||
// processorOptions 从处理器注册表构建前置/后置方法下拉选项:key=处理器名,value=描述(无描述回落名称)。
|
||
func processorOptions(ctx context.Context) ([]node.SelectOption, error) {
|
||
list, err := processor.List(ctx)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
opts := make([]node.SelectOption, 0, len(list))
|
||
for _, p := range list {
|
||
if p == nil || p.Name == "" || !p.IsShow {
|
||
continue
|
||
}
|
||
value := p.Description
|
||
if value == "" {
|
||
value = p.Name
|
||
}
|
||
opts = append(opts, node.SelectOption{
|
||
Key: p.Name,
|
||
Value: value,
|
||
})
|
||
}
|
||
return opts, nil
|
||
}
|
||
|
||
// applyProcessorOptions 把处理器选项填充进模型节点的 preTool/postTool 下拉。
|
||
// 深拷贝 PreToolOption/PostToolOption 后再改,避免改写全局 NodeTypeMetaList。
|
||
func applyProcessorOptions(tree []node.NodeGroupTree, opts []node.SelectOption) {
|
||
for gi := range tree {
|
||
for ni := range tree[gi].Nodes {
|
||
n := &tree[gi].Nodes[ni]
|
||
if n.Key != node.NodeTypeModel {
|
||
continue
|
||
}
|
||
n.PreToolOption = withProcessorOptions(n.PreToolOption, opts)
|
||
n.PostToolOption = withProcessorOptions(n.PostToolOption, opts)
|
||
return
|
||
}
|
||
}
|
||
}
|
||
|
||
// withProcessorOptions 返回 preTool/postTool 字段列表的深拷贝,并把 select 类型字段的 Options 替换为处理器选项。
|
||
func withProcessorOptions(fields []node.NodePresetField, opts []node.SelectOption) []node.NodePresetField {
|
||
out := append([]node.NodePresetField(nil), fields...)
|
||
for i := range out {
|
||
if out[i].Type == "select" {
|
||
out[i].Options = opts
|
||
}
|
||
}
|
||
return out
|
||
}
|
||
|
||
// videoModelOptions 按视频模型类型(600)查模型网关,转成 modelId 下拉选项:key=模型ID,value=模型名称。
|
||
func videoModelOptions(ctx context.Context) ([]node.SelectOption, error) {
|
||
res, err := gateway.ListModelManage(ctx, &gateway.ListModelManageReq{ModelType: model.TypeVideo})
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
opts := make([]node.SelectOption, 0, len(res.List))
|
||
for _, item := range res.List {
|
||
if item == nil || item.Id <= 0 || item.ModelName == "" {
|
||
continue
|
||
}
|
||
opts = append(opts, node.SelectOption{
|
||
Key: strconv.FormatInt(item.Id, 10),
|
||
Value: item.ModelName,
|
||
})
|
||
}
|
||
return opts, nil
|
||
}
|
||
|
||
// applyVideoModelOptions 把 script_transcribe 节点的 modelId 预设下拉替换为视频模型选项。
|
||
// 深拷贝 PresetOption 后再改,避免改写全局 NodeTypeMetaList。
|
||
func applyVideoModelOptions(tree []node.NodeGroupTree, opts []node.SelectOption) {
|
||
for gi := range tree {
|
||
for ni := range tree[gi].Nodes {
|
||
n := &tree[gi].Nodes[ni]
|
||
if n.Key != node.NodeTypeScriptTranscribe {
|
||
continue
|
||
}
|
||
presets := append([]node.NodePresetField(nil), n.PresetOption...)
|
||
for pi := range presets {
|
||
if presets[pi].Field == "modelId" {
|
||
presets[pi].Options = opts
|
||
break
|
||
}
|
||
}
|
||
n.PresetOption = presets
|
||
return
|
||
}
|
||
}
|
||
}
|