75 lines
2.7 KiB
Go
75 lines
2.7 KiB
Go
package flow
|
|
|
|
import (
|
|
"sort"
|
|
|
|
"ai-agent/workflow/model/entity"
|
|
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
)
|
|
|
|
// segmentGenerateMaxAttempts 视频段生成最大尝试次数(失败自动重试 1 次,共 2 次尝试),参数化可调
|
|
const segmentGenerateMaxAttempts = 2
|
|
|
|
// hasDistinctSegmentIndex 判断各段参数是否都带 segment_index 且互不重复。
|
|
// 段级续跑依赖 segment_index 作为段的稳定身份;缺失或重复(如视频节点误用批量拆分)时
|
|
// 不得启用复用/落库,否则续跑会拿同一段结果拼出 N 段重复视频(静默损坏)。
|
|
func hasDistinctSegmentIndex(paramsList []map[string]any) bool {
|
|
seen := make(map[int]bool, len(paramsList))
|
|
for _, params := range paramsList {
|
|
v, ok := params["segment_index"]
|
|
if !ok {
|
|
return false
|
|
}
|
|
idx := gconv.Int(v)
|
|
if seen[idx] {
|
|
return false
|
|
}
|
|
seen[idx] = true
|
|
}
|
|
return len(paramsList) > 0
|
|
}
|
|
|
|
// planSegmentResume 段级续跑决策:把 paramsList 各段映射到"是否需重新生成"。
|
|
// savedMap 为该节点已成功段(段序号 → {key,url});段在表中缺失或地址为空则需重新生成。
|
|
// 返回值与 paramsList 对齐。全新执行(savedMap 为 nil/空)时全部需生成。
|
|
func planSegmentResume(paramsList []map[string]any, savedMap map[int]entity.SegmentRef) (idxList []int, needGen []bool) {
|
|
idxList = make([]int, len(paramsList))
|
|
needGen = make([]bool, len(paramsList))
|
|
for i, params := range paramsList {
|
|
idx := gconv.Int(params["segment_index"])
|
|
idxList[i] = idx
|
|
ref, ok := savedMap[idx]
|
|
needGen[i] = !ok || ref.URL == ""
|
|
}
|
|
return
|
|
}
|
|
|
|
// mergeSegmentOutputs 把复用段与新生段按段序号升序合并为 concat 输入列表(列表顺序即拼接顺序)。
|
|
// 复用段重建 {key:url} 记录(key 保持模型原输出字段,避免下游引用失配);新生段沿用模型原输出。
|
|
// 任一段既无复用又无生成结果(生成空)则跳过——与现有"空段贡献空"行为一致,最终由 concat 校验兜底。
|
|
func mergeSegmentOutputs(idxList []int, needGen []bool, newRes [][]map[string]any, savedMap map[int]entity.SegmentRef) []map[string]any {
|
|
type segOutput struct {
|
|
idx int
|
|
recs []map[string]any
|
|
}
|
|
out := make([]segOutput, 0, len(idxList))
|
|
for i, idx := range idxList {
|
|
if needGen[i] {
|
|
if len(newRes[i]) > 0 {
|
|
out = append(out, segOutput{idx: idx, recs: newRes[i]})
|
|
}
|
|
continue
|
|
}
|
|
if ref, ok := savedMap[idx]; ok && ref.URL != "" {
|
|
out = append(out, segOutput{idx: idx, recs: []map[string]any{{ref.Key: ref.URL}}})
|
|
}
|
|
}
|
|
sort.SliceStable(out, func(a, b int) bool { return out[a].idx < out[b].idx })
|
|
var merged []map[string]any
|
|
for _, o := range out {
|
|
merged = append(merged, o.recs...)
|
|
}
|
|
return merged
|
|
}
|