| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- import type { JourneyEdge, JourneyStep, TaskCycle } from "@/lib/types";
- export function buildTaskCycles(steps: JourneyStep[], edges: JourneyEdge[]): TaskCycle[] {
- const groups = new Map<string, JourneyStep[]>();
- for (const step of steps) {
- const values = groups.get(step.task_id) ?? [];
- values.push(step);
- groups.set(step.task_id, values);
- }
- return [...groups.entries()]
- .map(([taskId, values]) => {
- const plan = values.find((step) => step.step_type === "plan");
- const last = values.at(-1)!;
- return {
- taskId,
- title: plan?.contract?.output ?? plan?.title.replace("Planner 规划·", "") ?? last.title,
- status: last.status,
- steps: values,
- goals: plan?.contract?.goals ?? [],
- loopCount: edges.filter(
- (edge) =>
- edge.relation === "loop" && values.some((step) => step.step_id === edge.source),
- ).length,
- parallel: values.some((step) => Boolean(step.parallel_group_id)),
- };
- })
- .sort((left, right) => left.steps[0].sequence - right.steps[0].sequence);
- }
- export type StepGroup =
- | { kind: "single"; id: string; steps: [JourneyStep] }
- | { kind: "parallel"; id: string; steps: JourneyStep[] };
- export function groupParallelSteps(steps: JourneyStep[]): StepGroup[] {
- const ordered = [...steps].sort((left, right) => left.sequence - right.sequence);
- const output: StepGroup[] = [];
- const consumed = new Set<string>();
- for (const step of ordered) {
- if (consumed.has(step.step_id)) continue;
- if (step.parallel_group_id && step.step_type === "execute") {
- const parallel = ordered.filter(
- (candidate) =>
- candidate.step_type === "execute" &&
- candidate.parallel_group_id === step.parallel_group_id,
- );
- parallel.forEach((candidate) => consumed.add(candidate.step_id));
- output.push({ kind: "parallel", id: step.parallel_group_id, steps: parallel });
- continue;
- }
- consumed.add(step.step_id);
- output.push({ kind: "single", id: step.step_id, steps: [step] });
- }
- return output;
- }
- export function statusLabel(status: string): string {
- return {
- accept: "已接受",
- accepted: "已接受",
- completed: "已完成",
- passed: "已通过",
- failed: "未通过",
- retry: "重新执行",
- revise: "正在修订",
- split: "已拆分",
- block: "阶段等待",
- blocked: "阶段等待",
- running: "进行中",
- submitted: "已提交",
- needs_replan: "等待决策",
- }[status.toLowerCase()] ?? status;
- }
|