Procházet zdrojové kódy

feat(任务树): 按 display_path 构建动态业务层级

新增数值化路径排序和父子森林构建函数,支持 Planner Turn 的 visible_task_ids 回放。集中提供任务类型和状态的中文业务标签,避免 UI 组件重复解释协议字段。
SamLee před 15 hodinami
rodič
revize
9f70d4bbce
1 změnil soubory, kde provedl 73 přidání a 0 odebrání
  1. 73 0
      visualization/frontend/lib/task-tree.ts

+ 73 - 0
visualization/frontend/lib/task-tree.ts

@@ -0,0 +1,73 @@
+import type { TaskNode } from "@/lib/types";
+
+export interface TaskBranch {
+  task: TaskNode;
+  children: TaskBranch[];
+}
+
+function pathParts(path: string) {
+  return path.split(".").map((part) => Number.parseInt(part, 10));
+}
+
+export function compareTaskPath(left: TaskNode, right: TaskNode) {
+  const a = pathParts(left.display_path);
+  const b = pathParts(right.display_path);
+  const length = Math.max(a.length, b.length);
+  for (let index = 0; index < length; index += 1) {
+    const delta = (a[index] ?? -1) - (b[index] ?? -1);
+    if (delta !== 0) return delta;
+  }
+  return 0;
+}
+
+export function buildTaskForest(tasks: TaskNode[], visibleIds?: Set<string>): TaskBranch[] {
+  const visible = tasks.filter((task) => !visibleIds || visibleIds.has(task.task_id));
+  const byParent = new Map<string | null, TaskNode[]>();
+  for (const task of visible) {
+    const siblings = byParent.get(task.parent_task_id) ?? [];
+    siblings.push(task);
+    byParent.set(task.parent_task_id, siblings);
+  }
+  for (const siblings of byParent.values()) siblings.sort(compareTaskPath);
+  const walk = (task: TaskNode): TaskBranch => ({
+    task,
+    children: (byParent.get(task.task_id) ?? []).map(walk),
+  });
+  return (byParent.get(null) ?? []).map(walk);
+}
+
+export function taskKindLabel(kind: string) {
+  const labels: Record<string, string> = {
+    root: "创作总目标",
+    direction: "创作方向",
+    "pattern-retrieval": "模式检索",
+    "external-retrieval": "外部检索",
+    "candidate-portfolio": "脚本候选集",
+    compose: "整稿组合",
+    structure: "脚本结构",
+    paragraph: "脚本段落",
+    "element-set": "内容元素",
+    compare: "候选比较",
+  };
+  return labels[kind] ?? kind;
+}
+
+export function statusLabel(status: string) {
+  const labels: Record<string, string> = {
+    completed: "已验收",
+    waiting_children: "等待子任务",
+    needs_replan: "等待 Planner",
+    in_progress: "执行中",
+    pending: "待执行",
+    awaiting_validation: "等待验收",
+    awaiting_decision: "等待决策",
+    blocked: "阶段边界",
+    cancelled: "已取消",
+    failed: "失败",
+    stopped: "已停止",
+    submitted: "已提交",
+    passed: "通过",
+    accept: "采用",
+  };
+  return labels[status] ?? status;
+}