@tea-agent/loop-agent 0.37.0 → 0.37.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/AGENTS.md +2 -6
  2. package/CHANGELOG.md +71 -144
  3. package/README.md +1 -1
  4. package/bin/loop-agent.js +1 -37
  5. package/dist/application/task-lifecycle/advance.js +0 -1
  6. package/dist/application/task-lifecycle/observe.js +0 -15
  7. package/dist/application/task-lifecycle/plan-transitions.js +0 -15
  8. package/dist/cli/command-definitions.js +0 -7
  9. package/dist/cli/program.js +3 -8
  10. package/dist/commands/init-upgrade.js +19 -351
  11. package/dist/commands/init.js +67 -14
  12. package/dist/commands/run-dag-progress.js +0 -14
  13. package/dist/commands/task-advance.js +3 -33
  14. package/dist/executors/dag-pi-executor.js +30 -47
  15. package/dist/executors/pi-sdk-executor.js +0 -34
  16. package/dist/executors/shell-executor.js +95 -6
  17. package/dist/shared/operator/capabilities.js +13 -200
  18. package/dist/shared/package-metadata.js +0 -42
  19. package/dist/task/contract/project.js +0 -4
  20. package/dist/task/source-prepare/completeness.js +0 -53
  21. package/dist/task/source-prepare/parse-intent.js +12 -82
  22. package/dist/task/source-prepare/prepare.js +5 -102
  23. package/dist/task/source-prepare/semantic-intake.js +23 -144
  24. package/dist/worker/console/chat/artifact-card.js +1 -8
  25. package/dist/worker/console/chat/chat-event-store.js +0 -152
  26. package/dist/worker/console/chat/human-gate-card.js +1 -9
  27. package/dist/worker/console/chat/operation-card.js +2 -71
  28. package/dist/worker/console/chat/pi-runtime.js +62 -111
  29. package/dist/worker/console/chat/routes.js +10 -43
  30. package/dist/worker/console/chat/session-store.js +1 -9
  31. package/dist/worker/console/chat/shortcuts.js +7 -9
  32. package/dist/worker/console/chat/turn-process.js +23 -204
  33. package/dist/worker/console/chat/workspace-landing.js +1 -2
  34. package/dist/worker/console/operation-runner.js +6 -155
  35. package/dist/worker/console/operator-actions.js +14 -391
  36. package/dist/worker/console/operator-user-error.js +0 -4
  37. package/dist/worker/console/recovery-cta.js +3 -50
  38. package/dist/worker/console/static/assets/index-HX1pbOyl.css +1 -0
  39. package/dist/worker/console/static/assets/index-M0BLEBfh.js +56 -0
  40. package/dist/worker/console/static/index.html +2 -2
  41. package/dist/worker/console/static-src/app/console-types.js +9 -13
  42. package/dist/worker/console/static-src/app/useOperatorActions.js +2 -4
  43. package/dist/worker/console/static-src/app/useRecoveryActions.js +56 -65
  44. package/dist/worker/console/static-src/app/useRecoveryConsole.js +1 -73
  45. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +30 -114
  46. package/dist/worker/console/static-src/operator-chat/refs.js +0 -3
  47. package/dist/worker/console/static-src/operator-chat/spatial-overlay.js +1 -2
  48. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +13 -67
  49. package/dist/worker/console/static-src/operator-chat/useChatThread.js +6 -12
  50. package/dist/worker/console/static-src/operator-chat/useComposer.js +8 -45
  51. package/dist/worker/console/static-src/operator-chat/workspace-layout-mode.js +3 -7
  52. package/dist/worker/loop-agent/loop-agent-client.js +3 -17
  53. package/dist/worker/observability/read-model.js +0 -20
  54. package/dist/worker/observe/spec-evidence.js +8 -3
  55. package/dist/worker/observe/static/operator-chrome.d.ts +0 -1
  56. package/dist/worker/observe/static/operator-chrome.js +3 -10
  57. package/dist/worker/observe/static/views/dag-inspector.js +71 -6
  58. package/dist/worker/observe/static/views/dag.js +0 -12
  59. package/dist/worker/preflight.js +1 -2
  60. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +707 -37
  61. package/dist/workflows/dag/backend-test-case-manifest.js +4 -0
  62. package/dist/workflows/dag/backend-test-markdown-workflow.js +109 -7
  63. package/dist/workflows/dag/backend-test-module-stem.js +5 -0
  64. package/dist/workflows/dag/backend-test-pytest-collection.js +345 -24
  65. package/dist/workflows/dag/backend-test-scenario-param.js +890 -164
  66. package/dist/workflows/dag/backend-test-writer-completeness.js +47 -16
  67. package/dist/workflows/dag/dynamic-runtime/map.js +24 -8
  68. package/dist/workflows/dag/dynamic-runtime/shared.js +1 -9
  69. package/dist/workflows/dag/frontend-implementation-contract.js +39 -233
  70. package/dist/workflows/dag/frontend-prewrite-gate.js +61 -364
  71. package/dist/workflows/dag/frontend-repair.js +18 -219
  72. package/dist/workflows/dag/frontend-verification-trace.js +32 -47
  73. package/dist/workflows/dag/init-hybrid.js +82 -165
  74. package/dist/workflows/dag/node-execution.js +0 -89
  75. package/dist/workflows/dag/recovery-recommendation.js +0 -58
  76. package/dist/workflows/dag/runner.js +15 -333
  77. package/dist/workflows/dag/scheduler.js +3 -257
  78. package/dist/workflows/dag/types.js +9 -130
  79. package/docs/README.md +3 -3
  80. package/docs/architecture/evolution.md +67 -102
  81. package/docs/templates/backend-test-dag.json +50 -32
  82. package/docs/templates/init-managed-agents.md +2 -5
  83. package/harness.json +2 -2
  84. package/package.json +3 -9
  85. package/skills/loop-agent/SKILL.md +0 -1
  86. package/skills/loop-agent/references/command-reference.md +0 -4
  87. package/dist/build-stamp.json +0 -6
  88. package/dist/commands/dag-request-interrupt.js +0 -20
  89. package/dist/worker/console/chat/assistant-content.js +0 -121
  90. package/dist/worker/console/chat/semantic-activity.js +0 -477
  91. package/dist/worker/console/operation-run-facts.js +0 -190
  92. package/dist/worker/console/operation-wait.js +0 -355
  93. package/dist/worker/console/recovery-error-copy.js +0 -198
  94. package/dist/worker/console/static/assets/abnfDiagram-N423BO3Z-DSvF6RXQ.js +0 -1
  95. package/dist/worker/console/static/assets/arc-DuI4ogtJ.js +0 -1
  96. package/dist/worker/console/static/assets/architectureDiagram-T3A2C74G-DdBbgD4y.js +0 -36
  97. package/dist/worker/console/static/assets/blockDiagram-VBNYF7ZC-xQC2HELm.js +0 -132
  98. package/dist/worker/console/static/assets/c4Diagram-5PPSVZJV-DPMSgwIZ.js +0 -10
  99. package/dist/worker/console/static/assets/channel-DLVz9TYW.js +0 -1
  100. package/dist/worker/console/static/assets/chunk-2GRJ4B5K-WTEKTxin.js +0 -1
  101. package/dist/worker/console/static/assets/chunk-2Q5K7J3B-B6vZ0Pv_.js +0 -1
  102. package/dist/worker/console/static/assets/chunk-5RXB4S5H-BrerNAix.js +0 -231
  103. package/dist/worker/console/static/assets/chunk-5VM5RSS4-D_ch2aaI.js +0 -15
  104. package/dist/worker/console/static/assets/chunk-6Q2QTUOP-VvfacNrq.js +0 -88
  105. package/dist/worker/console/static/assets/chunk-GF5L2VYU-B-uGFIg2.js +0 -206
  106. package/dist/worker/console/static/assets/chunk-JWPE2WC7-BlysCtod.js +0 -1
  107. package/dist/worker/console/static/assets/chunk-KBJHAD2P-BjAUAfcT.js +0 -1
  108. package/dist/worker/console/static/assets/chunk-RYQCIY6F-BeZnBmb-.js +0 -1
  109. package/dist/worker/console/static/assets/chunk-XXDRQBXY-Bbfe3UJG.js +0 -1
  110. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BeAuGcO9.js +0 -1
  111. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BeAuGcO9.js +0 -1
  112. package/dist/worker/console/static/assets/cose-bilkent-JH36ORCC-BKJQnYVM.js +0 -1
  113. package/dist/worker/console/static/assets/cynefin-VYW2F7L2-B1wtI3hU.js +0 -166
  114. package/dist/worker/console/static/assets/cynefinDiagram-MW4NZA55-DCF6DBSu.js +0 -62
  115. package/dist/worker/console/static/assets/cytoscape.esm-yzknjiTM.js +0 -321
  116. package/dist/worker/console/static/assets/dagre-VZM6K2ZE-BJyNGRlP.js +0 -4
  117. package/dist/worker/console/static/assets/defaultLocale-DX6XiGOO.js +0 -1
  118. package/dist/worker/console/static/assets/diagram-7IWD3JNH-B7j1-VsZ.js +0 -30
  119. package/dist/worker/console/static/assets/diagram-B4RE2ZJO-BREJ140a.js +0 -3
  120. package/dist/worker/console/static/assets/diagram-LBJQPF4R-CDPHmHGH.js +0 -24
  121. package/dist/worker/console/static/assets/diagram-Q27KOJAE-BtZLrez1.js +0 -24
  122. package/dist/worker/console/static/assets/diagram-UB23O5K3-mzybu8oU.js +0 -41
  123. package/dist/worker/console/static/assets/ebnfDiagram-BXEA7PRR-Dk3I2uO6.js +0 -1
  124. package/dist/worker/console/static/assets/erDiagram-JOGREHBK-BT97u_tQ.js +0 -85
  125. package/dist/worker/console/static/assets/flowDiagram-UKHOOZJN-CMOtYzui.js +0 -156
  126. package/dist/worker/console/static/assets/ganttDiagram-PKOTCBZU-DiNydkuY.js +0 -292
  127. package/dist/worker/console/static/assets/gitGraphDiagram-DS77QQ5N-Cwt6fLkl.js +0 -106
  128. package/dist/worker/console/static/assets/graph-DOmOIIwC.js +0 -1
  129. package/dist/worker/console/static/assets/index-DQxiso1w.js +0 -325
  130. package/dist/worker/console/static/assets/index-_j0Hzo69.css +0 -1
  131. package/dist/worker/console/static/assets/infoDiagram-6WML65LV-AsGIGKKB.js +0 -2
  132. package/dist/worker/console/static/assets/init-Gi6I4Gst.js +0 -1
  133. package/dist/worker/console/static/assets/ishikawaDiagram-WSZJBQD7-BL8ITZh3.js +0 -70
  134. package/dist/worker/console/static/assets/journeyDiagram-NVQOT4AX-VPKAUX8M.js +0 -139
  135. package/dist/worker/console/static/assets/kanban-definition-27J2QSJJ-BL56hfGp.js +0 -89
  136. package/dist/worker/console/static/assets/layout-D-LzfAck.js +0 -1
  137. package/dist/worker/console/static/assets/linear-BmSG3nIZ.js +0 -1
  138. package/dist/worker/console/static/assets/map-DxJ2ADlA.js +0 -1
  139. package/dist/worker/console/static/assets/mermaid.core-DWGK9kwP.js +0 -308
  140. package/dist/worker/console/static/assets/mindmap-definition-FAOFIHXS--vvKLjo0.js +0 -96
  141. package/dist/worker/console/static/assets/ordinal-Cboi1Yqb.js +0 -1
  142. package/dist/worker/console/static/assets/pegDiagram-VL7TDLO6-B41mxb2-.js +0 -1
  143. package/dist/worker/console/static/assets/pieDiagram-7S7Q4E2Y-DTlu77sw.js +0 -39
  144. package/dist/worker/console/static/assets/quadrantDiagram-CIZ2JOQS-Bk5A7alv.js +0 -7
  145. package/dist/worker/console/static/assets/railroadDiagram-AXF67PYL-Csf9jzQy.js +0 -1
  146. package/dist/worker/console/static/assets/requirementDiagram-LRYGKXZP-CeptoSNx.js +0 -84
  147. package/dist/worker/console/static/assets/sankeyDiagram-W5VNT64P-A-DLCLer.js +0 -40
  148. package/dist/worker/console/static/assets/sequenceDiagram-SI44F4Z6-22VbPdOI.js +0 -162
  149. package/dist/worker/console/static/assets/sizeCapture-X5ZJPWSS-DWvAyBC9.js +0 -1
  150. package/dist/worker/console/static/assets/stateDiagram-OKZ733FA-qICZ75yT.js +0 -1
  151. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DzKvfHTX.js +0 -1
  152. package/dist/worker/console/static/assets/swimlanes-SLNWSIFB-xi7lcMyp.js +0 -2
  153. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Cxqr_qM1.js +0 -8
  154. package/dist/worker/console/static/assets/timeline-definition-Z64GVDOM-Bu6Nl6O2.js +0 -120
  155. package/dist/worker/console/static/assets/vennDiagram-T6HMQDX7-BzMz4Bn9.js +0 -34
  156. package/dist/worker/console/static/assets/wardleyDiagram-T6FBY63Y-CxaJnzc5.js +0 -78
  157. package/dist/worker/console/static/assets/xychartDiagram-ELKLHX3M-5JK-omQK.js +0 -7
  158. package/dist/worker/console/static/fonts/katex/KaTeX_AMS-Regular.woff2 +0 -0
  159. package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Bold.woff2 +0 -0
  160. package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Regular.woff2 +0 -0
  161. package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Bold.woff2 +0 -0
  162. package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Regular.woff2 +0 -0
  163. package/dist/worker/console/static/fonts/katex/KaTeX_Main-Bold.woff2 +0 -0
  164. package/dist/worker/console/static/fonts/katex/KaTeX_Main-BoldItalic.woff2 +0 -0
  165. package/dist/worker/console/static/fonts/katex/KaTeX_Main-Italic.woff2 +0 -0
  166. package/dist/worker/console/static/fonts/katex/KaTeX_Main-Regular.woff2 +0 -0
  167. package/dist/worker/console/static/fonts/katex/KaTeX_Math-BoldItalic.woff2 +0 -0
  168. package/dist/worker/console/static/fonts/katex/KaTeX_Math-Italic.woff2 +0 -0
  169. package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Bold.woff2 +0 -0
  170. package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Italic.woff2 +0 -0
  171. package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Regular.woff2 +0 -0
  172. package/dist/worker/console/static/fonts/katex/KaTeX_Script-Regular.woff2 +0 -0
  173. package/dist/worker/console/static/fonts/katex/KaTeX_Size1-Regular.woff2 +0 -0
  174. package/dist/worker/console/static/fonts/katex/KaTeX_Size2-Regular.woff2 +0 -0
  175. package/dist/worker/console/static/fonts/katex/KaTeX_Size3-Regular.woff2 +0 -0
  176. package/dist/worker/console/static/fonts/katex/KaTeX_Size4-Regular.woff2 +0 -0
  177. package/dist/worker/console/static/fonts/katex/KaTeX_Typewriter-Regular.woff2 +0 -0
  178. package/dist/worker/console/static-src/operator-chat/activity-journey.js +0 -125
  179. package/dist/worker/console/static-src/operator-chat/activity-rail-presentation.js +0 -73
  180. package/dist/worker/console/static-src/operator-chat/activity-references.js +0 -20
  181. package/dist/worker/console/static-src/operator-chat/slash-palette-layout.js +0 -24
  182. package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +0 -141
  183. package/dist/worker/console/static-src/operator-chat/useActivityRailTransition.js +0 -59
  184. package/dist/worker/observability/interrupt-eligibility.js +0 -264
  185. package/dist/workflows/dag/contract-output-registry.js +0 -14
  186. package/dist/workflows/dag/contract-validator-registrations.js +0 -8
  187. package/dist/workflows/dag/frontend-recovery-plan.js +0 -73
  188. package/dist/workflows/dag/frontend-recovery-root-manifest.js +0 -123
  189. package/dist/workflows/dag/frontend-recovery-run.js +0 -539
  190. package/dist/workflows/dag/frontend-writer-recovery.js +0 -106
  191. package/dist/workflows/dag/frontend-writer-rollback.js +0 -821
  192. package/dist/workflows/dag/interrupt-request.js +0 -559
@@ -1,121 +0,0 @@
1
- /**
2
- * Assistant content-block helpers shared by Pi event mapping and Operator Chat UI.
3
- * Mirrors pi-web `lib/message-display.ts` (process vs answer split) without deferred fetch.
4
- */
5
- function asRecord(value) {
6
- if (!value || typeof value !== "object")
7
- return undefined;
8
- return value;
9
- }
10
- function readString(value) {
11
- return typeof value === "string" ? value : undefined;
12
- }
13
- /** Parse a persisted/SSE content array; unknown shapes are dropped. */
14
- export function parseAssistantContent(value) {
15
- if (!Array.isArray(value))
16
- return undefined;
17
- const blocks = [];
18
- for (const item of value) {
19
- const rec = asRecord(item);
20
- if (!rec)
21
- continue;
22
- const type = readString(rec.type) ?? "";
23
- if (type === "thinking" || type === "reasoning") {
24
- const thinking = readString(rec.thinking) ?? readString(rec.text) ?? "";
25
- blocks.push({ type: "thinking", thinking });
26
- continue;
27
- }
28
- if (type === "toolCall" ||
29
- type === "tool_call" ||
30
- type === "toolUse" ||
31
- type === "tool_use") {
32
- const toolCallId = readString(rec.toolCallId) ?? readString(rec.id) ?? "";
33
- if (!toolCallId)
34
- continue;
35
- const toolName = readString(rec.toolName) ?? readString(rec.name);
36
- blocks.push({
37
- type: "toolCall",
38
- toolCallId,
39
- ...(toolName ? { toolName } : {}),
40
- });
41
- continue;
42
- }
43
- if (type === "text" || type === "output_text" || type === "") {
44
- const text = readString(rec.text);
45
- if (text !== undefined)
46
- blocks.push({ type: "text", text });
47
- }
48
- }
49
- return blocks;
50
- }
51
- /**
52
- * Extract ordered assistant content blocks from a Pi SDK message object.
53
- * Thinking/reasoning blocks keep their own type so they never leak into answer text.
54
- */
55
- export function extractAssistantContentBlocks(message) {
56
- const rec = asRecord(message);
57
- if (!rec)
58
- return [];
59
- const contents = Array.isArray(rec.content) ? rec.content : [];
60
- const parts = Array.isArray(rec.parts) ? rec.parts : [];
61
- const fromArrays = parseAssistantContent([...contents, ...parts]) ?? [];
62
- if (fromArrays.length > 0)
63
- return fromArrays;
64
- const top = readString(rec.text);
65
- return top ? [{ type: "text", text: top }] : [];
66
- }
67
- /**
68
- * Pi emits message_end for user / toolResult / custom too. Only assistant
69
- * payloads belong in the Operator Chat assistant bubble (pi-web same split).
70
- */
71
- export function isAssistantSdkMessage(message) {
72
- const rec = asRecord(message);
73
- if (!rec)
74
- return false;
75
- const role = readString(rec.role);
76
- return role === undefined || role === "assistant";
77
- }
78
- /**
79
- * Latest assistant answer text (text blocks only). Thinking is excluded.
80
- * Preserves the historical `{ text }` / `{ parts: [{ text }] }` fallbacks.
81
- */
82
- export function extractAssistantText(message) {
83
- return extractAssistantContentBlocks(message)
84
- .filter((block) => block.type === "text")
85
- .map((block) => block.text)
86
- .join("");
87
- }
88
- export function isEmptyThinkingBlock(block, options = {}) {
89
- return (block.type === "thinking" &&
90
- !options.isStreaming &&
91
- block.thinking.trim() === "");
92
- }
93
- export function getDisplayableAssistantBlocks(blocks, options = {}) {
94
- return blocks.filter((block) => !isEmptyThinkingBlock(block, options));
95
- }
96
- function isFinalAnswerBlock(block) {
97
- return block.type === "text";
98
- }
99
- export function splitFinalAssistantBlocks(blocks, options = {}) {
100
- const displayable = getDisplayableAssistantBlocks(blocks, options);
101
- let lastProcessIndex = -1;
102
- for (let i = displayable.length - 1; i >= 0; i--) {
103
- if (!isFinalAnswerBlock(displayable[i])) {
104
- lastProcessIndex = i;
105
- break;
106
- }
107
- }
108
- if (lastProcessIndex === -1) {
109
- return { answerBlocks: displayable, processBlocks: [] };
110
- }
111
- return {
112
- answerBlocks: displayable.slice(lastProcessIndex + 1),
113
- processBlocks: displayable.slice(0, lastProcessIndex + 1),
114
- };
115
- }
116
- export function joinAssistantText(blocks) {
117
- return blocks
118
- .filter((block) => block.type === "text")
119
- .map((block) => block.text)
120
- .join("");
121
- }
@@ -1,477 +0,0 @@
1
- const TECHNICAL_ONLY_TOOLS = new Set([
2
- "operatorCapabilities",
3
- "operationList",
4
- "operationGet",
5
- "operationEventSummary",
6
- "statsContext",
7
- "sourceInstructions",
8
- "spineCheck",
9
- "inspect",
10
- "observeLink",
11
- ]);
12
- export function semanticToolPresentation(toolName) {
13
- if (TECHNICAL_ONLY_TOOLS.has(toolName))
14
- return "technical-only";
15
- if (toolName === "doctor")
16
- return "inline-detail";
17
- return "activity-detail";
18
- }
19
- const OPERATION_TITLES = {
20
- newTask: "创建任务",
21
- importPrd: "任务需求",
22
- contractShow: "任务边界",
23
- contractApply: "更新任务契约",
24
- contractDiff: "任务契约差异",
25
- contractDraftSave: "任务契约草稿",
26
- contractValidate: "检查任务契约",
27
- taskAdvance: "推进任务准备",
28
- dagRunTask: "执行流程",
29
- dagValidate: "校验执行流程",
30
- prepareDagConfirmation: "执行确认",
31
- confirmDagConfirmation: "确认执行边界",
32
- prepareDagExecution: "执行边界",
33
- runDag: "任务执行",
34
- operationWait: "执行监督",
35
- operationGet: "任务活动详情",
36
- operationList: "会话活动",
37
- operationEventSummary: "执行进展摘要",
38
- dagStatus: "执行状态",
39
- dagDoctor: "执行诊断",
40
- dagReport: "执行结果",
41
- dagRerunPlan: "恢复评估",
42
- dagInterruptEligibility: "中止资格",
43
- standaloneTaskRerun: "恢复执行",
44
- workerTaskRetry: "重试任务",
45
- promoteRun: "任务推进",
46
- status: "任务状态",
47
- };
48
- const TOOL_SEMANTICS = {
49
- newTask: {
50
- running: "正在创建任务",
51
- success: "任务已经创建",
52
- error: "创建任务时遇到问题",
53
- },
54
- importPrd: {
55
- running: "正在整理并导入任务需求",
56
- success: "任务需求已经导入",
57
- error: "导入任务需求时遇到问题",
58
- },
59
- contractShow: {
60
- running: "正在读取任务目标和执行边界",
61
- success: "任务目标与执行边界已经读取",
62
- error: "读取任务边界时遇到问题",
63
- },
64
- taskAdvance: {
65
- running: "正在推进任务契约并准备执行流程",
66
- success: "任务已经推进到下一安全阶段",
67
- error: "任务推进被契约或执行边界阻塞",
68
- },
69
- dagRunTask: {
70
- running: "正在生成并校验执行流程",
71
- success: "执行流程已经准备好",
72
- error: "准备执行流程时遇到问题",
73
- },
74
- prepareDagExecution: {
75
- running: "正在确认任务可以安全执行",
76
- success: "执行边界已经确认",
77
- error: "执行边界尚未通过确认",
78
- },
79
- runDag: {
80
- running: "正在启动任务执行",
81
- success: "任务执行已经启动",
82
- error: "启动任务执行时遇到问题",
83
- },
84
- dagReport: {
85
- running: "正在读取本次执行结果",
86
- success: "本次执行结果已经读取",
87
- error: "读取执行结果时遇到问题",
88
- },
89
- dagRerunPlan: {
90
- running: "正在评估能否从失败位置继续",
91
- success: "恢复条件评估已经完成",
92
- error: "暂时无法确定安全的恢复方式",
93
- },
94
- dagInterruptEligibility: {
95
- running: "正在检查能否协作中止此运行",
96
- success: "中止资格已经确认",
97
- error: "当前运行不能协作中止",
98
- },
99
- standaloneTaskRerun: {
100
- running: "正在从失败位置恢复执行",
101
- success: "已经从失败位置继续执行",
102
- error: "从失败位置恢复执行时遇到问题",
103
- },
104
- promoteRun: {
105
- running: "正在推进任务状态",
106
- success: "任务状态已经更新",
107
- error: "推进任务状态时遇到问题",
108
- },
109
- status: {
110
- running: "正在读取任务状态",
111
- success: "任务状态已经更新",
112
- error: "读取任务状态时遇到问题",
113
- },
114
- contractApply: {
115
- running: "正在应用任务契约变更",
116
- success: "任务契约已经更新",
117
- error: "应用任务契约变更时遇到问题",
118
- },
119
- contractDiff: {
120
- running: "正在比较任务契约版本",
121
- success: "任务契约差异已经读取",
122
- error: "比较任务契约时遇到问题",
123
- },
124
- contractDraftSave: {
125
- running: "正在保存任务契约草稿",
126
- success: "任务契约草稿已经保存",
127
- error: "保存任务契约草稿时遇到问题",
128
- },
129
- contractValidate: {
130
- running: "正在检查任务契约",
131
- success: "任务契约检查已经完成",
132
- error: "任务契约检查没有通过",
133
- },
134
- dagValidate: {
135
- running: "正在校验执行流程",
136
- success: "执行流程校验已经通过",
137
- error: "执行流程校验没有通过",
138
- },
139
- prepareDagConfirmation: {
140
- running: "正在准备执行确认",
141
- success: "执行确认已经准备好",
142
- error: "准备执行确认时遇到问题",
143
- },
144
- confirmDagConfirmation: {
145
- running: "正在确认执行边界",
146
- success: "执行边界已经确认",
147
- error: "执行边界尚未通过确认",
148
- },
149
- operationGet: {
150
- running: "正在读取任务活动详情",
151
- success: "任务活动详情已经读取",
152
- error: "读取任务活动详情时遇到问题",
153
- },
154
- operationList: {
155
- running: "正在读取本次对话的活动",
156
- success: "本次对话的活动已经读取",
157
- error: "读取对话活动时遇到问题",
158
- },
159
- operationEventSummary: {
160
- running: "正在汇总执行进展",
161
- success: "执行进展已经汇总",
162
- error: "汇总执行进展时遇到问题",
163
- },
164
- dagStatus: {
165
- running: "正在读取执行状态",
166
- success: "执行状态已经更新",
167
- error: "读取执行状态时遇到问题",
168
- },
169
- dagDoctor: {
170
- running: "正在诊断本次任务执行",
171
- success: "任务执行诊断已经完成",
172
- error: "诊断任务执行时遇到问题",
173
- },
174
- workerTaskRetry: {
175
- running: "正在重试失败的任务",
176
- success: "失败任务已经重新开始",
177
- error: "重试失败任务时遇到问题",
178
- },
179
- doctor: {
180
- running: "正在检查运行环境",
181
- success: "运行环境检查已经完成",
182
- error: "运行环境检查发现问题",
183
- },
184
- inspect: {
185
- running: "正在读取详细运行信息",
186
- success: "详细运行信息已经读取",
187
- error: "读取详细运行信息时遇到问题",
188
- },
189
- observeLink: {
190
- running: "正在准备运行看板入口",
191
- success: "运行看板入口已经准备好",
192
- error: "准备运行看板入口时遇到问题",
193
- },
194
- operatorCapabilities: {
195
- running: "正在读取可用操作能力",
196
- success: "可用操作能力已经读取",
197
- error: "读取可用操作能力时遇到问题",
198
- },
199
- sourceInstructions: {
200
- running: "正在读取任务来源说明",
201
- success: "任务来源说明已经读取",
202
- error: "读取任务来源说明时遇到问题",
203
- },
204
- spineCheck: {
205
- running: "正在检查计划执行步骤",
206
- success: "计划执行步骤检查已经完成",
207
- error: "计划执行步骤检查发现问题",
208
- },
209
- statsContext: {
210
- running: "正在统计上下文使用情况",
211
- success: "上下文使用情况已经统计完成",
212
- error: "统计上下文使用情况时遇到问题",
213
- },
214
- };
215
- const NODE_LABELS = [
216
- {
217
- pattern: /(?:^|-)contract(?:-pi)?$/i,
218
- running: "正在核对任务目标和执行边界",
219
- finished: "任务目标与执行边界已确认",
220
- error: "任务边界存在冲突,需要先处理",
221
- },
222
- {
223
- pattern: /scout-src/i,
224
- running: "正在梳理与任务相关的代码",
225
- finished: "相关代码范围已梳理",
226
- error: "梳理相关代码时遇到问题",
227
- },
228
- {
229
- pattern: /scout-tests/i,
230
- running: "正在检查现有测试和验证方式",
231
- finished: "现有测试与验证方式已确认",
232
- error: "检查现有测试时遇到问题",
233
- },
234
- {
235
- pattern: /plan/i,
236
- running: "正在整理具体实施步骤",
237
- finished: "实施步骤已经准备好",
238
- error: "实施方案还需要进一步完善",
239
- },
240
- {
241
- pattern: /implement|writer/i,
242
- running: "正在修改并保存相关文件",
243
- finished: "文件修改已经完成",
244
- error: "修改文件时遇到问题",
245
- },
246
- {
247
- pattern: /verify|reverify/i,
248
- running: "正在验证本次修改",
249
- finished: "本次修改已通过验证",
250
- error: "验证没有通过,正在检查原因",
251
- },
252
- {
253
- pattern: /review/i,
254
- running: "正在检查改动是否完整",
255
- finished: "改动完整性检查已通过",
256
- error: "发现需要补充或修正的内容",
257
- },
258
- {
259
- pattern: /closeout/i,
260
- running: "正在整理交付结果",
261
- finished: "任务已经完成并形成交付记录",
262
- error: "交付结果尚未整理完整",
263
- },
264
- ];
265
- function asRecord(value) {
266
- if (!value || typeof value !== "object")
267
- return undefined;
268
- return value;
269
- }
270
- function parseJsonRecord(value) {
271
- if (value && typeof value === "object")
272
- return value;
273
- if (typeof value !== "string")
274
- return undefined;
275
- try {
276
- return asRecord(JSON.parse(value));
277
- }
278
- catch {
279
- return undefined;
280
- }
281
- }
282
- function operationIdFromArgs(args) {
283
- const record = parseJsonRecord(args);
284
- const operationId = record?.operationId;
285
- return typeof operationId === "string" && operationId ? operationId : undefined;
286
- }
287
- function maxWaitSeconds(args) {
288
- const record = parseJsonRecord(args);
289
- const raw = record?.maxWaitMs;
290
- if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0)
291
- return undefined;
292
- return Math.max(1, Math.round(raw / 1000));
293
- }
294
- function activityRefForTool(tool) {
295
- // Plan A (2026-08-16): server backfills operationId on the persisted tool
296
- // entry (and live tool_result frames carry it in the result payload), so
297
- // prefer the authoritative link before parsing args/result fallbacks.
298
- const operationId = tool.operationId ??
299
- operationIdFromArgs(tool.args) ??
300
- operationIdFromArgs(tool.result) ??
301
- operationIdFromArgs(tool.resultText);
302
- return operationId ? `operation:${operationId}` : `tool:${tool.id}`;
303
- }
304
- function semanticKindForStatus(status) {
305
- if (status === "running")
306
- return "progress";
307
- if (status === "error")
308
- return "error";
309
- return "success";
310
- }
311
- function resultRecord(tool) {
312
- return parseJsonRecord(tool.resultText ?? tool.result);
313
- }
314
- function eventMessages(record) {
315
- if (!Array.isArray(record.events))
316
- return [];
317
- return record.events.flatMap((value) => {
318
- const event = asRecord(value);
319
- if (!event)
320
- return [];
321
- const message = event.messagePreview ?? event.message;
322
- return typeof message === "string" ? [message] : [];
323
- });
324
- }
325
- function nodeActivityFromMessages(messages, id, activityRef) {
326
- const facts = [];
327
- for (const message of messages) {
328
- for (const match of message.matchAll(/node-(started|finished)[^\n]*?node=([^\s,]+)/gi)) {
329
- const lifecycle = match[1]?.toLowerCase();
330
- const node = match[2] ?? "";
331
- const statusMatch = message.match(/status=([^\s,]+)/i)?.[1]?.toUpperCase();
332
- let status = "finished";
333
- if (statusMatch === "ERROR" || statusMatch === "FAILED")
334
- status = "error";
335
- else if (lifecycle === "started")
336
- status = "running";
337
- facts.push({ node, status });
338
- }
339
- }
340
- const latest = facts.at(-1);
341
- if (!latest)
342
- return undefined;
343
- const scoutSrcFinished = facts.some((fact) => /scout-src/i.test(fact.node) && fact.status === "finished");
344
- const scoutTestsFinished = facts.some((fact) => /scout-tests/i.test(fact.node) && fact.status === "finished");
345
- if (scoutSrcFinished && scoutTestsFinished) {
346
- return {
347
- id,
348
- kind: "success",
349
- title: "代码与测试的影响范围已确认",
350
- activityRef,
351
- };
352
- }
353
- const label = NODE_LABELS.find((candidate) => candidate.pattern.test(latest.node));
354
- if (!label) {
355
- return { id, kind: "success", title: "执行状态已经更新", activityRef };
356
- }
357
- if (latest.status === "running") {
358
- return { id, kind: "progress", title: label.running, activityRef };
359
- }
360
- if (latest.status === "error") {
361
- return { id, kind: "error", title: label.error, activityRef };
362
- }
363
- return { id, kind: "success", title: label.finished, activityRef };
364
- }
365
- function operationWaitActivity(tool) {
366
- const activityRef = activityRefForTool(tool);
367
- const id = `activity:${tool.id}`;
368
- const seconds = maxWaitSeconds(tool.args);
369
- if (tool.status === "running") {
370
- return {
371
- id,
372
- kind: "progress",
373
- title: seconds
374
- ? `正在等待新的执行进展,最长等待时间 ${seconds} 秒`
375
- : "正在等待新的执行进展",
376
- activityRef,
377
- };
378
- }
379
- if (tool.status === "error") {
380
- return {
381
- id,
382
- kind: "error",
383
- title: "等待执行进展时遇到问题",
384
- activityRef,
385
- };
386
- }
387
- let rawResult = "";
388
- if (typeof tool.resultText === "string")
389
- rawResult = tool.resultText;
390
- else if (typeof tool.result === "string")
391
- rawResult = tool.result;
392
- const record = resultRecord(tool);
393
- const nodeActivity = nodeActivityFromMessages([rawResult, ...(record ? eventMessages(record) : [])], id, activityRef);
394
- if (nodeActivity)
395
- return nodeActivity;
396
- if (record) {
397
- if (record.timedOut === true || record.changed === false) {
398
- return {
399
- id,
400
- kind: "warning",
401
- title: "等待期间没有新的执行进展",
402
- activityRef,
403
- };
404
- }
405
- if (record.changed === true) {
406
- return {
407
- id,
408
- kind: "success",
409
- title: "已经收到新的执行进展",
410
- activityRef,
411
- };
412
- }
413
- }
414
- return {
415
- id,
416
- kind: "success",
417
- title: "执行状态已经更新",
418
- activityRef,
419
- };
420
- }
421
- /**
422
- * Return a deterministic, human-written semantic event for Operator tools.
423
- * Ordinary read/bash/edit tools intentionally return undefined and retain the
424
- * existing technical ToolCard representation.
425
- */
426
- export function semanticActivityForTool(tool) {
427
- const presentation = semanticToolPresentation(tool.toolName);
428
- if (presentation === "technical-only" || presentation === "inline-detail") {
429
- return undefined;
430
- }
431
- if (tool.toolName === "operationWait")
432
- return operationWaitActivity(tool);
433
- const semantic = TOOL_SEMANTICS[tool.toolName];
434
- if (!semantic)
435
- return undefined;
436
- let title = semantic.success;
437
- if (tool.status === "running")
438
- title = semantic.running;
439
- else if (tool.status === "error")
440
- title = semantic.error;
441
- return {
442
- id: `activity:${tool.id}`,
443
- kind: semanticKindForStatus(tool.status),
444
- title,
445
- activityRef: activityRefForTool(tool),
446
- };
447
- }
448
- export function semanticOperationTitle(action) {
449
- return OPERATION_TITLES[action] ?? "任务活动";
450
- }
451
- export function semanticOperationState(state) {
452
- switch (state) {
453
- case "starting":
454
- return { label: "正在启动", kind: "progress" };
455
- case "running":
456
- return { label: "运行中", kind: "progress" };
457
- case "succeeded":
458
- case "finished":
459
- case "FINISHED":
460
- case "pass":
461
- return { label: "已完成", kind: "success" };
462
- case "failed":
463
- case "partial_failed":
464
- case "ERROR":
465
- case "FAILED":
466
- case "timed-out":
467
- return { label: "未完成", kind: "error" };
468
- case "needs-reconcile":
469
- return { label: "需要同步", kind: "warning" };
470
- case "cancelled":
471
- case "abandoned":
472
- case "superseded":
473
- return { label: "已停止", kind: "warning" };
474
- default:
475
- return { label: "状态已更新", kind: "success" };
476
- }
477
- }