fix(hitl): 审批弹窗可靠化(状态轮询兜底)+ 审批节点入调色板并改橙色

两个实测发现的问题:
1. 审批条偶发不弹、任务卡「运行中」:exec 的 await 事件走实时 core NATS(无回放),
   UI 的 EventSource 晚连一拍就漏掉 → 永远不弹审批。改为轮询持久化的任务状态
   (GET /tasks/:id,每 1.5s),status==waiting 即弹审批条,不再依赖易抢跑的 exec 事件;
   exec 事件仅用于丰富摘要。新增 api.taskStatus + RunState.lifecycle/detail +
   App.tsx 轮询 + 终态停轮询;BottomDrawer 审批条触发改以 lifecycle==waiting 为准。
2. Studio 左侧调色板没有「人工审批」节点(只加了 NODE_KINDS,漏了 NODE_ORDER),
   且其配色与「输入」同为 amber 难以区分:补进 NODE_ORDER(分支与并行之间),
   配色改 orange(橙)与输入的 amber(琥珀金)区分。

验证:桌面端 live 重启确认审批条可靠弹出 + 批准/拒绝两条路径正常;左侧节点列表与
画布配色区分清晰。tsc 干净 + vitest 36 过。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-06-24 14:51:37 +08:00
parent 16a6c4b1aa
commit d7c6fab933
5 changed files with 39 additions and 4 deletions
+9
View File
@@ -109,6 +109,15 @@ export async function submitTask(dsl: TaskDsl, id: Identity): Promise<string> {
return data.task_id;
}
// taskStatus: GET /api/v1/tasks/:id —— 任务生命周期状态(submitted/running/waiting/done/failed/timeout/rejected)。
// 轮询它来可靠捕获 waiting(审批中断)—— 不依赖易抢跑的实时 exec 事件。
export async function taskStatus(taskId: string): Promise<{ status: string; detail: string }> {
const res = guard401(await fetch(`${GATEWAY}/api/v1/tasks/${taskId}`, { headers: bearer() }));
if (!res.ok) throw new Error(`status failed: ${res.status}`);
const d = (await res.json()) as { status?: string; detail?: string };
return { status: d.status ?? "", detail: d.detail ?? "" };
}
// approveTask: POST /api/v1/tasks/:id/approve —— HITL 人工审批决定(批准放行 / 拒绝中止)。
export async function approveTask(taskId: string, approved: boolean, opts?: { node?: string; note?: string }): Promise<void> {
const res = guard401(
+2
View File
@@ -15,6 +15,8 @@ export interface RunState {
events: RunEvent[];
exec: ExecEvent[]; // 后端回流的节点级执行轨迹(运行·观测)
error?: string;
lifecycle?: string; // 轮询到的后端任务状态(waiting 时弹审批;done/rejected 等终态)
detail?: string; // 状态附带说明(如审批标题)
}
export const emptyRun: RunState = { phase: "idle", output: "", events: [], exec: [] };