Why
DAG replan 的目标是对正在执行的规划做纠错、修正或补充,而不是删除旧 workflow 后重新创建。当前引擎已经具备增量合并语义,但 TUI 不一定会在 replan 后立即切换到新拓扑。
服务端 GET /dag/{dagID}/nodes 已只返回 current graph revision;WorkflowReplanned 也会递增持久化的 workflow.graph_rev。但 WorkflowSummary、summary HTTP 响应和 dag.workflow.summary.updated 事件没有携带该 revision。DAG inspector 与 sidebar 展开面板目前仅用节点总数和状态计数拼接刷新签名。
当 replan 做等量替换,或只改写尚未执行节点的定义/依赖时,nodeCount、completedNodes、runningNodes、failedNodes 等聚合值可以完全不变。此时 summary 事件虽然已发出,TUI 仍判断为无变化,不重新读取 current nodes,于是继续显示旧规划,直到后续节点状态变化才偶然刷新。
这会让 replan 看起来像把新内容继续显示在过去的节点/旧拓扑上,而不是明确展示纠错后的当前规划。
Existing semantics to preserve
- replan 保持同一个 workflow ID 和事件历史,不通过删除/重建实现。
- 已完成等终态节点保持不可变;其 durable output 仍可被新节点通过依赖和
input_mapping 使用。
- fragment 可以插入新 node。
- fragment 可以替换 pending、queued、paused 等未来尚未执行节点的定义和依赖;未继续保留的未来节点可被 supersede。
- 当前 revision 的真实失败仍应可见;被新路径绕过的历史失败只退出 current view,不删除 durable truth。
Proposed direction
把现有 workflow.graph_rev 暴露为派生视图的拓扑版本:
DagStore.WorkflowSummary 和 summary 查询返回 graphRev。
packages/schema 的 DagWorkflowSummary、HTTP summary response 和 dag.workflow.summary.updated 携带 graphRev。
- 重新生成 JS SDK。
- DAG inspector 与 sidebar 的节点刷新签名包含
graphRev;revision 变化时,即使所有聚合计数不变,也重新读取 /dag/{dagID}/nodes。
- 保留现有无变化 summary 不触发重复请求的优化。
graphRev 是 topology invalidation token,不要求 TUI 自己聚合 durable events,也不引入轮询。
Acceptance criteria
- 给定 workflow 中已有完成节点 A 以及未来节点 B、C,replan 可让新节点继续依赖 A 并读取 A 的历史输出。
- replan 可插入新节点,并可改写尚未执行节点的 prompt、worker、依赖或条件,而不创建第二个 workflow。
- 当 replan 用相同数量、相同状态分布的新当前节点替换旧未来拓扑时,
graphRev 递增且 summary push 携带新值。
- 已打开的 DAG inspector 在收到新 revision 后只发起一次 authoritative node refresh,并展示
/dag/{dagID}/nodes 返回的新 current revision;旧 superseded 节点不继续占据当前拓扑。
- 已展开的 sidebar DAG 面板具备相同行为。
- 节点总数和状态计数均未变化的 replan 有回归测试;该测试在仅依赖旧计数签名时必须失败。
- revision 未变化且聚合值未变化的重复 summary event 不触发节点重取。
- 历史节点的 durable output、按 ID 审计读取和 event history 不因 UI 刷新机制而删除或覆盖。
Non-goals
- 不通过 cancel/delete 当前 workflow 再 start 新 workflow 来实现 replan。
- 本 issue 不要求增加完整的 revision/attempt 历史浏览器;它只保证当前纠错规划被及时、准确地重新显示。
- 不改变终态节点不可变、running node 显式 restart、max replan attempts 等既有执行约束。
Relevant seams
packages/core/src/dag/core/replan.ts: fragment 合并分类与历史节点保留语义。
packages/opencode/src/dag/dag.ts: replan 事件发布、配置合并、graph revision 推进。
packages/core/src/dag/store.ts: current node view 与 workflow summary。
packages/schema/src/dag-summary.ts: summary/event 公共契约。
packages/opencode/src/server/routes/instance/httpapi/handlers/dag.ts: current nodes 与 summary HTTP 映射。
packages/tui/src/feature-plugins/system/dag-inspector.tsx: inspector 刷新签名。
packages/tui/src/feature-plugins/sidebar/dag-panel.tsx: sidebar 刷新签名。
Related work
Why
DAG replan 的目标是对正在执行的规划做纠错、修正或补充,而不是删除旧 workflow 后重新创建。当前引擎已经具备增量合并语义,但 TUI 不一定会在 replan 后立即切换到新拓扑。
服务端
GET /dag/{dagID}/nodes已只返回 current graph revision;WorkflowReplanned也会递增持久化的workflow.graph_rev。但WorkflowSummary、summary HTTP 响应和dag.workflow.summary.updated事件没有携带该 revision。DAG inspector 与 sidebar 展开面板目前仅用节点总数和状态计数拼接刷新签名。当 replan 做等量替换,或只改写尚未执行节点的定义/依赖时,
nodeCount、completedNodes、runningNodes、failedNodes等聚合值可以完全不变。此时 summary 事件虽然已发出,TUI 仍判断为无变化,不重新读取 current nodes,于是继续显示旧规划,直到后续节点状态变化才偶然刷新。这会让 replan 看起来像把新内容继续显示在过去的节点/旧拓扑上,而不是明确展示纠错后的当前规划。
Existing semantics to preserve
input_mapping使用。Proposed direction
把现有
workflow.graph_rev暴露为派生视图的拓扑版本:DagStore.WorkflowSummary和 summary 查询返回graphRev。packages/schema的DagWorkflowSummary、HTTP summary response 和dag.workflow.summary.updated携带graphRev。graphRev;revision 变化时,即使所有聚合计数不变,也重新读取/dag/{dagID}/nodes。graphRev是 topology invalidation token,不要求 TUI 自己聚合 durable events,也不引入轮询。Acceptance criteria
graphRev递增且 summary push 携带新值。/dag/{dagID}/nodes返回的新 current revision;旧 superseded 节点不继续占据当前拓扑。Non-goals
Relevant seams
packages/core/src/dag/core/replan.ts: fragment 合并分类与历史节点保留语义。packages/opencode/src/dag/dag.ts: replan 事件发布、配置合并、graph revision 推进。packages/core/src/dag/store.ts: current node view 与 workflow summary。packages/schema/src/dag-summary.ts: summary/event 公共契约。packages/opencode/src/server/routes/instance/httpapi/handlers/dag.ts: current nodes 与 summary HTTP 映射。packages/tui/src/feature-plugins/system/dag-inspector.tsx: inspector 刷新签名。packages/tui/src/feature-plugins/sidebar/dag-panel.tsx: sidebar 刷新签名。Related work
/daginspector 的项目级发现兜底,不覆盖 replan 后计数不变时的节点刷新。