feat: 添加执行费用统计及token信息记录

在流程执行和节点执行中新增 TotalFee 和 TokenInfo 字段,用于记录每次模型调用的详细计费数据;流程执行完成时汇总所有节点的 token 消耗和费用;重构 token 更新逻辑,从响应字段提取改为使用回调返回的 billingData;优化 URL 后缀提取方法以正确处理带查询参数的链接。
This commit is contained in:
2026-07-01 19:34:31 +08:00
parent f5be9d8a40
commit e548f20b6e
7 changed files with 97 additions and 27 deletions
+23 -3
View File
@@ -6,12 +6,14 @@ import (
"ai-agent/workflow/consts/public"
fileDao "ai-agent/workflow/dao/file"
flowDao "ai-agent/workflow/dao/flow"
nodeDao "ai-agent/workflow/dao/node"
"ai-agent/workflow/model/dto"
fileDto "ai-agent/workflow/model/dto/file"
flowDto "ai-agent/workflow/model/dto/flow"
nodeDto "ai-agent/workflow/model/dto/node"
"ai-agent/workflow/model/entity"
"context"
"fmt"
"path/filepath"
"strconv"
"strings"
"sync"
@@ -86,7 +88,7 @@ func JudgeLambda(ctx context.Context, input any) (string, error) {
if err != nil {
return "", err
}
composeResult, err := GetComposeResult(ctx, 2, getIsChatModel.Model.ModelName, "", "", []map[string]any{{"prompt": strings.Join(branchIdNameLines, "\n")}}, []map[string]any{{"prompt": contextParts}}, nodeInput.Global.FileUrl, nodeInput.Global.SessionId, nodeInput.Config.Id, "判断节点")
composeResult, err := GetComposeResult(ctx, nodeInput.NodeExecutionId, 2, getIsChatModel.Model.ModelName, "", "", []map[string]any{{"prompt": strings.Join(branchIdNameLines, "\n")}}, []map[string]any{{"prompt": contextParts}}, nodeInput.Global.FileUrl, nodeInput.Global.SessionId, nodeInput.Config.Id, "判断节点")
if err != nil {
return "", err
}
@@ -299,7 +301,7 @@ func VideoModelLambda(ctx context.Context, input any) (any, error) {
return nil, fmt.Errorf("下载图片失败: %w", err)
}
// 构造文件名
fileName := fmt.Sprintf("ai_video_%d%s", time.Now().UnixMilli(), strings.ToLower(filepath.Ext(videoURL[0])))
fileName := fmt.Sprintf("ai_video_%d%s", time.Now().UnixMilli(), GetUrlSuffix(videoURL[0], true))
// 上传到你的OSS(你项目已有的Upload方法)
var upResp *dto.UploadFileBytesRes
upResp, err = Upload(ctx, &dto.UploadFileBytesReq{
@@ -650,10 +652,28 @@ func SummaryLambda(ctx context.Context, input any) (any, error) {
return err
}
res, _, err := nodeDao.NodeExecutionDao.ListByFlowExecutionId(ctx, &nodeDto.ListNodeExecutionByFlowReq{
NodeGroupId: execInput.Global.NodeGroupId,
}, entity.NodeExecutionCol.TokenInfo)
if err != nil {
return err
}
var totalTokens int
var totalFee float64
for _, item := range res {
for _, itemToken := range item.TokenInfo {
m := gconv.Map(itemToken)
totalTokens += gconv.Int(m["total_tokens"])
totalFee += gconv.Float64(m["total_fee"])
}
}
executionReq := flowDto.UpdateFlowExecutionReq{
Id: execInput.Global.ExecutionId,
Status: flow.FlowExecutionStatusSuccess.Code(),
OutputParams: summaryResult,
TotalTokens: totalTokens,
TotalFee: totalFee,
}
_, err = flowDao.FlowExecutionDao.Update(ctx, &executionReq)