Files
ai-agent/workflow/service/flow/lambda_tool.go
T
19904408334 d699f7ce14 feat(workflow): 增加工作流计费与执行生命周期管理
- 新增计费模块:执行开始建单、终态结算/取消/失败处理,支持按条/按秒/按token计费
- 新增执行生命周期跟踪:优雅关停时取消运行中执行并等待落库
- 新增异步任务等待/通知机制(Wait/Notify)
- 重构执行记录落库与进度上报,统一失败分类与重试语义
- 重命名文件:async_task.go→async.go、flow_checkpoint_store.go→exec_checkpoint.go、flow_graph_util.go→exec_record.go
- 更新 .gitignore 与数据库密码配置
2026-09-03 13:22:22 +08:00

91 lines
3.4 KiB
Go

package flow
import (
"ai-agent/gateway"
"ai-agent/workflow/consts/model"
"ai-agent/workflow/service/flow/processor"
"context"
"fmt"
"strings"
"github.com/gogf/gf/v2/frame/g"
)
// isVideoModel 判断模型是否为视频模型(模型类型 TypeVideo=600),用于视频节点多视频自动合成判断
func isVideoModel(ctx context.Context, modelId int64) bool {
modelInfo, err := gateway.GetModelInfoById(ctx, &gateway.GetModelInfoByIdReq{ModelId: modelId})
if err != nil {
g.Log().Warningf(ctx, "查询模型配置失败,跳过自动视频合成 modelId=%d err=%v", modelId, err)
return false
}
return modelInfo.ModelManage.ModelType != nil && *modelInfo.ModelManage.ModelType == model.TypeVideo
}
// invokePreTool 执行前置处理器,把模型请求参数转换为模型调用入参列表。
// 前置处理器契约:入参即模型请求参数本体;返回值:
// - map[string]any 一次模型调用,入参为返回值
// - []map[string]any 多次模型调用,逐个入参请求
// - nil 视为异常,节点失败(不允许静默跳过模型调用)
func invokePreTool(ctx context.Context, processorName string, modelParams map[string]any) (paramsList []map[string]any, err error) {
if processorName == "" {
return []map[string]any{stripInternalKeys(modelParams)}, nil
}
data, err := processor.Call(ctx, processorName, modelParams)
if err != nil {
return nil, fmt.Errorf("执行前置处理器[%s]失败: %v", processorName, err)
}
switch v := data.(type) {
case nil:
return nil, fmt.Errorf("前置处理器[%s]返回空", processorName)
case map[string]any:
return []map[string]any{stripInternalKeys(v)}, nil
case []map[string]any:
list := make([]map[string]any, 0, len(v))
for _, m := range v {
list = append(list, stripInternalKeys(m))
}
return list, nil
default:
return nil, fmt.Errorf("前置处理器[%s]返回类型不支持: %T", processorName, data)
}
}
// stripInternalKeys 剥离 __ 前缀的内部键(如 __segment_fields/__produced),
// 模型网关做参数严格校验(CheckParams strictUnknown)会拒绝未知字段,内部标记不得随请求体下发。
func stripInternalKeys(params map[string]any) map[string]any {
if params == nil {
return params
}
for k := range params {
if strings.HasPrefix(k, "__") {
delete(params, k)
}
}
return params
}
// invokePostTool 执行后置处理器,加工模型调用结果。
// 后置处理器契约:入参 {"output": 模型输出结果列表, "request": 原始模型请求参数}(列表须包成对象传入);返回值:
// - []map[string]any 替换模型输出
// - map[string]any 替换为单条输出
// - nil 保留原输出
func invokePostTool(ctx context.Context, processorName string, outputRes []map[string]any, requestParams map[string]any) ([]map[string]any, error) {
if processorName == "" {
return outputRes, nil
}
data, err := processor.Call(ctx, processorName, map[string]any{"output": outputRes, "request": requestParams})
if err != nil {
return nil, fmt.Errorf("执行后置处理器[%s]失败: %v", processorName, err)
}
switch v := data.(type) {
case nil:
return outputRes, nil
case []map[string]any:
return v, nil
case map[string]any:
return []map[string]any{v}, nil
default:
return nil, fmt.Errorf("后置处理器[%s]返回类型不支持: %T", processorName, data)
}
}