@zhushanwen/subagent-core 0.2.0 → 0.5.1

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 (347) hide show
  1. package/README.md +45 -2
  2. package/agents/analyst.md +60 -0
  3. package/agents/coder.md +69 -0
  4. package/agents/debugger.md +66 -0
  5. package/agents/doc-reviewer.md +49 -0
  6. package/agents/explorer.md +63 -0
  7. package/agents/general-purpose.md +32 -0
  8. package/agents/orchestrator.md +61 -0
  9. package/agents/planner.md +53 -0
  10. package/agents/researcher.md +67 -0
  11. package/agents/reviewer.md +73 -0
  12. package/dist/chunk-43ONBFZX.js +240 -0
  13. package/dist/chunk-APZY4IME.js +27 -0
  14. package/dist/chunk-V3VHZ2VX.js +59 -0
  15. package/dist/execution/engine/engines/zcode/constants.cjs +62 -9
  16. package/dist/execution/engine/engines/zcode/constants.d.cts +116 -12
  17. package/dist/execution/engine/engines/zcode/constants.d.ts +116 -12
  18. package/dist/execution/engine/engines/zcode/constants.js +39 -7
  19. package/dist/execution/engine/engines/zcode/reader.d.cts +2 -1
  20. package/dist/execution/engine/engines/zcode/reader.d.ts +2 -1
  21. package/dist/execution/engine/engines/zcode/reader.js +4 -234
  22. package/dist/execution/engine/paths.js +7 -19
  23. package/dist/index.cjs +18234 -1277
  24. package/dist/index.d.cts +5646 -673
  25. package/dist/index.d.ts +5646 -673
  26. package/dist/index.js +17828 -1277
  27. package/dist/{types-BxyAidGf.d.cts → types-Dv4QhSJ_.d.cts} +678 -112
  28. package/dist/{types-BxyAidGf.d.ts → types-Dv4QhSJ_.d.ts} +678 -112
  29. package/package.json +7 -4
  30. package/src/__tests__/agent-opts-resolver-schema-prompt.test.ts +0 -1
  31. package/src/__tests__/append-system-prompt-assembly.test.ts +8 -7
  32. package/src/__tests__/fr4-get-state-handshake.test.ts +2 -2
  33. package/src/__tests__/m2-append-content-probe.test.ts +0 -1
  34. package/src/__tests__/manifest-store.test.ts +10 -9
  35. package/src/__tests__/record-store-cache.test.ts +0 -2
  36. package/src/__tests__/record-store-index.test.ts +1 -2
  37. package/src/__tests__/review-fix-loop-script.test.ts +93 -3
  38. package/src/__tests__/review-fix-loop-utils.test.ts +31 -10
  39. package/src/__tests__/robustness-low-batch1.test.ts +6 -5
  40. package/src/__tests__/robustness-medium-batch1.test.ts +2 -2
  41. package/src/__tests__/robustness-medium-batch2.test.ts +17 -6
  42. package/src/__tests__/robustness-medium-batch4.test.ts +2 -2
  43. package/src/__tests__/session-runner.test.ts +1 -1
  44. package/src/__tests__/smoke.test.ts +9 -2
  45. package/src/core/__tests__/host-services.test.ts +2 -2
  46. package/src/core/__tests__/logger.test.ts +1 -1
  47. package/src/core/error-message.ts +9 -0
  48. package/src/core/host-services.ts +21 -5
  49. package/src/core/notify-ports.ts +18 -5
  50. package/src/execution/__tests__/agent-profile.test.ts +232 -0
  51. package/src/execution/__tests__/agent-registry.test.ts +370 -0
  52. package/src/execution/__tests__/agent-result-mapper.test.ts +18 -2
  53. package/src/execution/__tests__/agents-assembly.test.ts +219 -0
  54. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +6 -6
  55. package/src/execution/__tests__/chat-engine-routing.test.ts +136 -30
  56. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +5 -4
  57. package/src/execution/__tests__/cold-resurrect.test.ts +283 -0
  58. package/src/execution/__tests__/create-concurrency-pool.test.ts +194 -0
  59. package/src/execution/__tests__/delivery-methods.test.ts +77 -62
  60. package/src/execution/__tests__/descendant-sweep-guards.test.ts +220 -0
  61. package/src/execution/__tests__/descendant-sweep.test.ts +269 -0
  62. package/src/execution/__tests__/dialog-queue.test.ts +199 -1
  63. package/src/execution/__tests__/engine-model-validation.test.ts +741 -0
  64. package/src/execution/__tests__/epipe-fallback.test.ts +31 -24
  65. package/src/execution/__tests__/execute-and-await-worktree.test.ts +21 -91
  66. package/src/execution/__tests__/execute-nesting.test.ts +34 -188
  67. package/src/execution/__tests__/execution-record.test.ts +217 -60
  68. package/src/execution/__tests__/execution-runtime-face.test.ts +272 -0
  69. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +3 -3
  70. package/src/execution/__tests__/finalize-record.test.ts +278 -16
  71. package/src/execution/__tests__/gc-timer.test.ts +57 -2
  72. package/src/execution/__tests__/get-record-for-action-restart.test.ts +14 -12
  73. package/src/execution/__tests__/get-state-handshake.test.ts +127 -0
  74. package/src/execution/__tests__/helpers/mock-extension-api.ts +1 -1
  75. package/src/execution/__tests__/helpers/session-runner-mocks.ts +113 -0
  76. package/src/execution/__tests__/helpers/spawn-mock.ts +150 -3
  77. package/src/execution/__tests__/helpers/subagent-service-mocks.ts +137 -0
  78. package/src/execution/__tests__/keep-alive-no-progress.test.ts +280 -0
  79. package/src/execution/__tests__/kill-all-escalation.test.ts +196 -0
  80. package/src/execution/__tests__/lifecycle-manager-idle-timer-identity.test.ts +117 -0
  81. package/src/execution/__tests__/lifecycle-manager.test.ts +39 -0
  82. package/src/execution/__tests__/lifecycle-predicates.test.ts +1 -2
  83. package/src/execution/__tests__/manifest-parentid.test.ts +4 -4
  84. package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +99 -0
  85. package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +113 -0
  86. package/src/execution/__tests__/model-resolver.test.ts +2 -2
  87. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +23 -121
  88. package/src/execution/__tests__/nested-visibility.test.ts +2 -0
  89. package/src/execution/__tests__/notify-ledger.test.ts +1249 -0
  90. package/src/execution/__tests__/output-collector.test.ts +117 -6
  91. package/src/execution/__tests__/pi-invocation.test.ts +1 -1
  92. package/src/execution/__tests__/record-store-orphan-revive.test.ts +159 -0
  93. package/src/execution/__tests__/record-store.test.ts +89 -5
  94. package/src/execution/__tests__/records-cwd-isolation.test.ts +2 -2
  95. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +29 -132
  96. package/src/execution/__tests__/recursive-visibility-env.test.ts +55 -179
  97. package/src/execution/__tests__/rpc-mode.test.ts +2 -2
  98. package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +387 -0
  99. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +19 -9
  100. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +5 -4
  101. package/src/execution/__tests__/run-spawn-edges.test.ts +418 -26
  102. package/src/execution/__tests__/run-spawn-integration.test.ts +3 -3
  103. package/src/execution/__tests__/run-spawn-resume.test.ts +2 -2
  104. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +2 -2
  105. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +16 -8
  106. package/src/execution/__tests__/service-kill-escalation.test.ts +91 -0
  107. package/src/execution/__tests__/session-context-resolver.test.ts +0 -2
  108. package/src/execution/__tests__/session-file-gc.test.ts +35 -0
  109. package/src/execution/__tests__/session-pending.test.ts +471 -0
  110. package/src/execution/__tests__/session-reconstructor.test.ts +366 -15
  111. package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +110 -0
  112. package/src/execution/__tests__/session-runner-close-prune.test.ts +181 -0
  113. package/src/execution/__tests__/session-runner-dispatch.test.ts +489 -0
  114. package/src/execution/__tests__/session-runner-epipe.test.ts +4 -3
  115. package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +227 -0
  116. package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +290 -0
  117. package/src/execution/__tests__/session-runner-schema-env.test.ts +7 -5
  118. package/src/execution/__tests__/settled-watchdog.test.ts +524 -0
  119. package/src/execution/__tests__/spawn-args.test.ts +11 -10
  120. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +26 -23
  121. package/src/execution/__tests__/spawn-event-adapter.test.ts +1 -1
  122. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +5 -4
  123. package/src/execution/__tests__/spawned-children.test.ts +155 -11
  124. package/src/execution/__tests__/start-sync-model-guard.test.ts +4 -4
  125. package/src/execution/__tests__/stdin-writer.test.ts +6 -4
  126. package/src/execution/__tests__/stream-sink-retirement.test.ts +6 -6
  127. package/src/execution/__tests__/subagent-actions-core.test.ts +1017 -0
  128. package/src/execution/__tests__/subagent-service-message-close.test.ts +99 -35
  129. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +174 -0
  130. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +271 -0
  131. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +33 -29
  132. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +341 -0
  133. package/src/execution/__tests__/subagent-service.test.ts +37 -30
  134. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +88 -12
  135. package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +75 -0
  136. package/src/execution/__tests__/subprocess-agent-runner.test.ts +22 -20
  137. package/src/execution/__tests__/temp-prompt.test.ts +1 -1
  138. package/src/execution/__tests__/timeout-integration.test.ts +13 -12
  139. package/src/execution/__tests__/turn-limiter-semantics.test.ts +1 -1
  140. package/src/execution/__tests__/turn-limiter.test.ts +1 -1
  141. package/src/execution/__tests__/ui-request-handler-factory.test.ts +107 -7
  142. package/src/execution/__tests__/ui-request-handler.test.ts +4 -3
  143. package/src/execution/__tests__/ui-request-queue.test.ts +167 -2
  144. package/src/execution/__tests__/worktree-git-ops.test.ts +571 -0
  145. package/src/execution/__tests__/worktree-manager.test.ts +14 -5
  146. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +4 -3
  147. package/src/execution/__tests__/worktree-reconcile-aging.test.ts +204 -0
  148. package/src/execution/agent-registry.ts +298 -30
  149. package/src/execution/agent-result-mapper.ts +3 -0
  150. package/src/execution/agents-assembly.ts +88 -0
  151. package/src/execution/cold-resurrect.ts +199 -0
  152. package/src/execution/concurrency-pool.ts +71 -9
  153. package/src/execution/dialog-queue.ts +101 -3
  154. package/src/execution/engine/__tests__/common/capability-gate.test.ts +91 -0
  155. package/src/execution/engine/__tests__/common/data-dir.test.ts +1 -1
  156. package/src/execution/engine/__tests__/common/journal-wiring.test.ts +84 -0
  157. package/src/execution/engine/__tests__/common/kill-chain.test.ts +34 -7
  158. package/src/execution/engine/__tests__/common/persona-router.test.ts +4 -5
  159. package/src/execution/engine/__tests__/common/pool-manager.test.ts +211 -51
  160. package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +149 -0
  161. package/src/execution/engine/__tests__/common/session-view-service.test.ts +499 -0
  162. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +56 -99
  163. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +88 -15
  164. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +33 -7
  165. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +1 -1
  166. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +75 -54
  167. package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +128 -0
  168. package/src/execution/engine/__tests__/engine-discovery.test.ts +15 -3
  169. package/src/execution/engine/__tests__/model-prompt.test.ts +15 -3
  170. package/src/execution/engine/__tests__/registry.test.ts +94 -3
  171. package/src/execution/engine/__tests__/routing.test.ts +115 -6
  172. package/src/execution/engine/common/capability-gate.ts +92 -0
  173. package/src/execution/engine/common/journal-wiring.ts +97 -0
  174. package/src/execution/engine/common/kill-chain.ts +42 -10
  175. package/src/execution/engine/common/nesting-guard.ts +66 -0
  176. package/src/execution/engine/common/persona-router.ts +18 -8
  177. package/src/execution/engine/common/pool-manager.ts +332 -78
  178. package/src/execution/engine/common/session-view-service.ts +506 -0
  179. package/src/execution/engine/common/session-view-types.ts +125 -0
  180. package/src/execution/engine/engine-discovery.ts +12 -16
  181. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +174 -28
  182. package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +257 -0
  183. package/src/execution/{argv-mirror.ts → engine/engines/pi/argv-mirror.ts} +43 -21
  184. package/src/execution/{get-state-handshake.ts → engine/engines/pi/get-state-handshake.ts} +86 -11
  185. package/src/execution/{output-collector.ts → engine/engines/pi/output-collector.ts} +108 -19
  186. package/src/execution/engine/engines/pi/pi-engine.ts +434 -38
  187. package/src/execution/{pi-invocation.ts → engine/engines/pi/pi-invocation.ts} +2 -2
  188. package/src/execution/engine/engines/pi/reader.ts +11 -0
  189. package/src/execution/engine/engines/pi/registration.ts +4 -2
  190. package/src/execution/engine/engines/pi/session-runner.ts +2840 -0
  191. package/src/execution/{spawn-event-adapter.ts → engine/engines/pi/spawn-event-adapter.ts} +75 -34
  192. package/src/execution/{stdin-writer.ts → engine/engines/pi/stdin-writer.ts} +10 -9
  193. package/src/execution/{temp-prompt.ts → engine/engines/pi/temp-prompt.ts} +2 -2
  194. package/src/execution/{turn-limiter.ts → engine/engines/pi/turn-limiter.ts} +1 -1
  195. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +301 -0
  196. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +36 -0
  197. package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +321 -0
  198. package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +473 -0
  199. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +7 -210
  200. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +6 -110
  201. package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +247 -0
  202. package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +451 -0
  203. package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +792 -0
  204. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +782 -0
  205. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +168 -0
  206. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +210 -0
  207. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +353 -0
  208. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +282 -0
  209. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +372 -0
  210. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +65 -47
  211. package/src/execution/engine/engines/zcode/appserver-launcher.ts +167 -0
  212. package/src/execution/engine/engines/zcode/connection.ts +598 -0
  213. package/src/execution/engine/engines/zcode/constants.ts +147 -14
  214. package/src/execution/engine/engines/zcode/golden-sample.ts +42 -34
  215. package/src/execution/engine/engines/zcode/parser.ts +12 -346
  216. package/src/execution/engine/engines/zcode/preparer.ts +22 -150
  217. package/src/execution/engine/engines/zcode/session-channel.ts +968 -0
  218. package/src/execution/engine/engines/zcode/zcode-engine.ts +1023 -250
  219. package/src/execution/engine/host-task-spec.ts +32 -36
  220. package/src/execution/engine/model-validation.ts +177 -0
  221. package/src/execution/engine/port.ts +65 -7
  222. package/src/execution/engine/registry.ts +53 -0
  223. package/src/execution/engine/routing.ts +75 -1
  224. package/src/execution/engine/types.ts +30 -103
  225. package/src/execution/execution-record.ts +222 -144
  226. package/src/execution/finalize-record.ts +181 -85
  227. package/src/execution/idle-gc.ts +28 -0
  228. package/src/execution/lifecycle-manager.ts +27 -3
  229. package/src/execution/lifecycle-predicates.ts +1 -1
  230. package/src/execution/manifest-store.ts +53 -62
  231. package/src/execution/notifier.ts +10 -10
  232. package/src/execution/notify-host.ts +212 -0
  233. package/src/execution/notify-ledger.ts +117 -16
  234. package/src/execution/record-entry.ts +8 -2
  235. package/src/execution/record-store.ts +148 -88
  236. package/src/execution/round-settlement.ts +93 -0
  237. package/src/execution/session-file-gc.ts +96 -62
  238. package/src/execution/session-pending.ts +213 -62
  239. package/src/execution/session-reconstructor.ts +256 -143
  240. package/src/execution/sessions-index.ts +127 -102
  241. package/src/execution/settled-watchdog.ts +311 -0
  242. package/src/execution/subagent-actions-core.ts +686 -0
  243. package/src/execution/subagent-service.ts +1106 -907
  244. package/src/execution/subprocess-agent-runner.ts +144 -97
  245. package/src/execution/types.ts +9 -0
  246. package/src/execution/ui-request-handler-factory.ts +126 -75
  247. package/src/execution/ui-request-queue.ts +50 -19
  248. package/src/execution/worktree-git-ops.ts +397 -0
  249. package/src/execution/worktree-manager.ts +72 -10
  250. package/src/execution/worktree-registry.ts +6 -12
  251. package/src/index.ts +542 -9
  252. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +42 -3
  253. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +3 -5
  254. package/src/orchestration/__tests__/agent-call-stream.test.ts +2 -2
  255. package/src/orchestration/__tests__/args-meta.test.ts +358 -0
  256. package/src/orchestration/__tests__/args-validator.test.ts +14 -0
  257. package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +312 -0
  258. package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +384 -0
  259. package/src/orchestration/__tests__/execute-agent-call.test.ts +151 -11
  260. package/src/orchestration/__tests__/file-run-store-prune.test.ts +168 -0
  261. package/src/orchestration/__tests__/file-run-store-throttle.test.ts +168 -0
  262. package/src/orchestration/__tests__/file-run-store.test.ts +390 -0
  263. package/src/orchestration/__tests__/helpers/flush-microtasks.ts +13 -0
  264. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +34 -0
  265. package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +357 -0
  266. package/src/orchestration/__tests__/lifecycle-recover-crashed.test.ts +289 -0
  267. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +3 -3
  268. package/src/orchestration/__tests__/lifecycle.test.ts +84 -5
  269. package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +1 -1
  270. package/src/orchestration/__tests__/run-snapshot.test.ts +356 -0
  271. package/src/orchestration/__tests__/script-generate.test.ts +314 -0
  272. package/src/orchestration/__tests__/script-lint.test.ts +17 -0
  273. package/src/orchestration/__tests__/test-mocks.ts +2 -0
  274. package/src/orchestration/__tests__/worker-exit-without-result.test.ts +7 -6
  275. package/src/orchestration/__tests__/worker-message-pump-finalize-run.test.ts +229 -0
  276. package/src/orchestration/__tests__/{error-recovery-handlers.test.ts → worker-message-pump-handlers.test.ts} +28 -27
  277. package/src/orchestration/__tests__/{error-recovery-postmessage-defense.test.ts → worker-message-pump-postmessage-defense.test.ts} +8 -8
  278. package/src/orchestration/__tests__/{error-recovery-serialize-failed-result.test.ts → worker-message-pump-serialize-failed-result.test.ts} +2 -2
  279. package/src/orchestration/__tests__/{error-recovery-workflow-call.test.ts → worker-message-pump-workflow-call.test.ts} +1 -1
  280. package/src/orchestration/__tests__/worker-pending-timeout-abort.test.ts +275 -0
  281. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +78 -1
  282. package/src/orchestration/__tests__/worker-script-builder.test.ts +1 -1
  283. package/src/orchestration/__tests__/workflow-files.test.ts +186 -0
  284. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +1 -1
  285. package/src/orchestration/__tests__/workflow-run-summary.test.ts +119 -0
  286. package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +124 -0
  287. package/src/orchestration/agent-opts-resolver.ts +8 -8
  288. package/src/orchestration/args-meta.ts +198 -0
  289. package/src/orchestration/args-validator.ts +53 -31
  290. package/src/orchestration/execute-agent-call.ts +25 -79
  291. package/src/orchestration/file-run-store.ts +327 -0
  292. package/src/orchestration/launcher.ts +160 -104
  293. package/src/orchestration/lifecycle.ts +371 -97
  294. package/src/orchestration/models/agent-call.ts +7 -7
  295. package/src/orchestration/models/budget.ts +5 -5
  296. package/src/orchestration/models/ports.ts +4 -4
  297. package/src/orchestration/models/run-runtime.ts +15 -15
  298. package/src/orchestration/models/trace.ts +9 -9
  299. package/src/orchestration/models/types.ts +111 -22
  300. package/src/orchestration/models/workflow-run.ts +28 -28
  301. package/src/orchestration/models/workflow-script.ts +4 -4
  302. package/src/orchestration/run-snapshot.ts +266 -0
  303. package/src/orchestration/script-generate.ts +154 -0
  304. package/src/orchestration/script-lint.ts +123 -90
  305. package/src/orchestration/worker-handle.ts +10 -10
  306. package/src/orchestration/worker-host.ts +10 -10
  307. package/src/orchestration/{error-recovery.ts → worker-message-pump.ts} +498 -221
  308. package/src/orchestration/worker-script-builder.ts +401 -346
  309. package/src/orchestration/workflow-files.ts +37 -11
  310. package/src/orchestration/workflow-run-summary.ts +69 -0
  311. package/src/orchestration/workflow-script-registry-impl.ts +31 -9
  312. package/src/shared/__tests__/agent-ref.test.ts +209 -2
  313. package/src/shared/__tests__/atomic-write.test.ts +267 -0
  314. package/src/shared/__tests__/bounded-serialize.test.ts +236 -0
  315. package/src/shared/__tests__/injection-render.test.ts +518 -0
  316. package/src/shared/__tests__/meta-parser.test.ts +151 -0
  317. package/src/shared/__tests__/resource-discovery-host-roots.test.ts +474 -0
  318. package/src/shared/__tests__/resource-discovery.test.ts +261 -217
  319. package/src/shared/agent-ref.ts +143 -2
  320. package/src/shared/atomic-write.ts +323 -0
  321. package/src/shared/bounded-serialize.ts +154 -0
  322. package/src/shared/injection-render.ts +279 -0
  323. package/src/shared/meta-parser.ts +182 -68
  324. package/src/shared/model-ref.ts +15 -2
  325. package/src/shared/resource-discovery.ts +97 -204
  326. package/src/shared/resource-meta.ts +14 -0
  327. package/src/shared/schema-jsonify.ts +1 -1
  328. package/src/shared/xml-injection.ts +9 -9
  329. package/workflows/README.md +9 -9
  330. package/workflows/chain.js +4 -2
  331. package/workflows/map-reduce.js +5 -3
  332. package/workflows/parallel.js +5 -3
  333. package/workflows/review-fix-loop-utils.cjs +165 -92
  334. package/workflows/review-fix-loop-utils.d.cts +287 -0
  335. package/workflows/review-fix-loop.js +18 -7
  336. package/workflows/scatter-gather.js +4 -2
  337. package/dist/chunk-3VOERJPJ.js +0 -22
  338. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
  339. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  340. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  341. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  342. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  343. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -580
  344. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  345. package/src/execution/execute-options-mapper.ts +0 -115
  346. package/src/execution/session-runner.ts +0 -1789
  347. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -288
@@ -6,12 +6,13 @@
6
6
  // 为什么单独一层:执行层现有四个核心类型(ExecuteOptions/AgentEvent/AgentResult/AgentRunner
7
7
  // port)的中立是「碰巧的,不是设计的」——thinkingLevel 是 pi 7 档枚举、skillPath 假设引擎有
8
8
  // --skill flag、conversation/idleTimeoutMs 是 pi chatMode 专属形态(设计 §2.1)。本文件把
9
- // 「agent 调用」的引擎无关语义显式化为 AgentTaskSpec / AgentOutcome 等类型,EnginePort
10
- // (port.ts)与其下各引擎适配器都以本层为唯一契约点。
9
+ // 「agent 调用」的引擎无关语义显式化为 AgentOutcome 等类型,EnginePort(port.ts)与其下
10
+ // 各引擎适配器都以本层为唯一契约点。
11
11
  //
12
- // 泛化原则(D2):从现有类型泛化,不另起炉灶——字段与 execution/types.ts
13
- // ExecuteOptions、orchestration/models/types.ts 的 AgentResult 逐一锚定,标注「泛化」的
14
- // 条目语义有变,标注「新增」为引擎层新引入。
12
+ // [D6 任务形状合流] 原本层的任务声明类型 AgentTaskSpec/PersonaSpec 已并入
13
+ // orchestration/models/types.ts 的 AgentCallOpts(单一任务形状,SAR 直产、pi 边界一次
14
+ // 直出——docs/design/subagent-dual-track-convergence.md §3.3 D6)。本文件不再定义任务
15
+ // 声明;EnginePort.run 的入参即 AgentCallOpts(字段裁定与裁撤记录见其类型注释)。
15
16
  //
16
17
  // AgentResult 消歧(设计 §2.1/§3.3.5):仓内有两个同名 AgentResult——
17
18
  // ① orchestration 层 workflow 消费的那份(orchestration/models/types.ts,主字段
@@ -21,8 +22,8 @@
21
22
  // ——record 内部投影,保持原名不动。
22
23
  // 引擎层终态命名 AgentOutcome,与两者不同名,消除「同名不同义」。
23
24
 
24
- import type { AgentUsage, ToolCallEntry } from "../../orchestration/models/types.ts";
25
- import type { AgentUsageTotal, ToolCall, WorktreeHandle } from "../types.ts";
25
+ import type { AgentFailureKind, AgentUsage, ToolCallEntry } from "../../orchestration/models/types.ts";
26
+ import type { AgentUsageTotal, ToolCall } from "../types.ts";
26
27
 
27
28
  // AgentEvent 8 种事件原样保留,唯一权威定义仍是 execution/types.ts——引擎层 re-export
28
29
  // 不复制第二份(设计 §3.3.5);经 shared/agent-event.ts 的既有出口转发,维持「shared/
@@ -30,101 +31,6 @@ import type { AgentUsageTotal, ToolCall, WorktreeHandle } from "../types.ts";
30
31
  // 一次 turn_end)由 conformance 套件断言(P4),不在类型层编码。
31
32
  export type { AgentEvent } from "../../shared/agent-event.ts";
32
33
 
33
- // ============================================================
34
- // AgentTaskSpec(= 现有 ExecuteOptions 泛化,D2)
35
- // ============================================================
36
-
37
- /** 人设(persona)注入规格:原 skillPath + appendSystemPrompt 收拢进一个语义单元(D2)。 */
38
- export interface PersonaSpec {
39
- /**
40
- * agent 名/路径。与 AgentTaskSpec.agent 的分工:agent 是 resolveIdentity 的身份解析
41
- * 键(模型/系统提示等身份语义);agentRef 是 persona 注入通道的定位符——引擎按
42
- * capabilities.personaInjection 决定注入通道(file/flag/prompt)时用它定位人设。
43
- * pi 引擎不消费此字段(身份解析走 spec.agent),留给 flag/file 通道的引擎。
44
- */
45
- agentRef?: string;
46
- /**
47
- * 原 ExecuteOptions.skillPath。公共 persona 路由三策略(file/flag/prompt)的分流
48
- * 载体(D4)——超长 prompt 时优先 file/flag 通道分流的落点。
49
- */
50
- skillPath?: string;
51
- /** 追加系统提示内容数组(原样透传;schema 仿真段由公共降级层拼装后放入,P2)。 */
52
- appendSystemPrompt?: string[];
53
- }
54
-
55
- /**
56
- * 引擎无关的 agent 任务声明(= ExecuteOptions 泛化,字段逐条锚定设计 §3.3.5)。
57
- *
58
- * 与 ExecuteOptions 的差异(泛化点):
59
- * - thinkingLevel(pi 7 档枚举语义)→ effort?: string,各引擎自行映射或忽略;
60
- * - skillPath + appendSystemPrompt → persona(PersonaSpec);
61
- * - conversation/idleTimeoutMs 保留原名透传——属 interact 交互控制面的 task 标志(D1),
62
- * 不是 pi 专有语义的泄漏,而是「任务声明里声明交互模式」的中立表达;
63
- * - 删字段去向:signal/ctxModel/onComplete 是运行期句柄,移入 RunContext(port.ts);
64
- * schemaEnv 内化到 PiEngine(从 task.schema 派生,见 engines/pi/task-spec-mapper.ts)。
65
- *
66
- * 新增(为后续 wave 预留形状,P1 无生产写入方):
67
- * - denyTools:中立工具 denylist(附录 A 该行的载体);
68
- * - permissionMode:中立权限模式(映射按 capabilities.permissionMode)。
69
- */
70
- export interface AgentTaskSpec {
71
- /** 原样(ExecuteOptions.task)。 */
72
- task: string;
73
- /** 原样(ExecuteOptions.slug,≤35 字符)。 */
74
- slug: string;
75
- /** 原样(ExecuteOptions.agent,resolveIdentity 的 agent ref)。 */
76
- agent?: string;
77
- /** 原样(ExecuteOptions.model;在引擎 provider 体系内解释,D9②)。 */
78
- model?: string;
79
- /**
80
- * 泛化:原 ExecuteOptions.thinkingLevel。引擎无关的推理投入档位字符串——
81
- * pi 引擎把它原值映射回 thinkingLevel 7 档;其他引擎自行映射(CC 5 档)或忽略
82
- * (kimi ❌)。不定义联合枚举:档位集合是引擎私有语义,中立层只透传字符串。
83
- */
84
- effort?: string;
85
- /** 泛化:原 skillPath + appendSystemPrompt 收拢(D2)。 */
86
- persona?: PersonaSpec;
87
- /**
88
- * 原样(ExecuteOptions.schema)。native/emulated 分流依据(D4 硬边界):pi 的
89
- * PI_WORKFLOW_SCHEMA env 注入链路按 native 直传,公共仿真层只服务 emulated 引擎。
90
- */
91
- schema?: Record<string, unknown>;
92
- /**
93
- * 原样(ExecuteOptions.maxTurns)。pi 引擎专属(turn limiter + spawn watchdog
94
- * 估算依赖 pi 的 turn_end 事件流);其他引擎 prepare 期显式拒绝(U4,同 fork 模式)。
95
- * 显式 0 压过 SPAWN_WATCHDOG_ENV 兑底(SP-6 参数 > env,U5);undefined 未传才由
96
- * env 兑底。
97
- */
98
- maxTurns?: number;
99
- /** 原样(ExecuteOptions.graceTurns)。 */
100
- graceTurns?: number;
101
- /** 原样(ExecuteOptions.fork)。pi 专属;其他引擎 prepare 期按 capabilities 拒绝。 */
102
- fork?: boolean;
103
- /**
104
- * 原样(ExecuteOptions.worktree)。公共层职责(worktree-manager),非引擎职责——
105
- * 引擎只把它当 spawn cwd 的来源之一。
106
- */
107
- worktree?: boolean | WorktreeHandle;
108
- /** 原样(ExecuteOptions.cwd)。 */
109
- cwd?: string;
110
- /** 原样(ExecuteOptions.conversation,interact 控制面的 task 标志,D1)。 */
111
- conversation?: boolean;
112
- /** 原样(ExecuteOptions.idleTimeoutMs,同上)。 */
113
- idleTimeoutMs?: number;
114
- /** 新增:中立工具 denylist。各引擎做语法映射(附录 A「工具 denylist」行的载体)。 */
115
- denyTools?: string[];
116
- /** 新增:中立权限模式。映射按 capabilities.permissionMode(kimi fixed auto = ignored)。 */
117
- permissionMode?: string;
118
- /**
119
- * [P4 形状预留,D9① 守卫 b 的独立载体] 任务对引擎能力的显式依赖声明。
120
- * 首期无生产写入方:守卫 b 与守卫 a 合流(显式 engine 即能力依赖声明)——调用方
121
- * 按引擎 id 表达依赖。下钻时机(AgentTaskSpec 泛化成熟后):调用方改按能力表达
122
- * (如 requires: { sandbox: 'native' }),路由层将本字段与各引擎 capabilities()
123
- * 对照,无引擎满足时报 engine_capability_unsupported(调用前拒绝,D11 处置三级)。
124
- */
125
- requires?: Partial<EngineCapabilities>;
126
- }
127
-
128
34
  // ============================================================
129
35
  // AgentOutcome(锚定 orchestration 层 AgentResult,§3.3.5)
130
36
  // ============================================================
@@ -136,6 +42,13 @@ export interface AgentTaskSpec {
136
42
  export interface AgentOutcome {
137
43
  /** 原样(AgentResult.content)。 */
138
44
  content: string;
45
+ /**
46
+ * 原样(AgentResult.failureKind,D5-③ 失败分诊结构化标签)。产出侧唯一识别点 =
47
+ * engines/pi/output-collector(collectResult 分类写入);缺省 = unknown = 可重试
48
+ * (消费侧 executeAgentCall 只读字段分诊,不扫 error 文案)。非 pi 引擎不产出,
49
+ * 恒缺省(unknown 语义)。
50
+ */
51
+ failureKind?: AgentFailureKind;
139
52
  /**
140
53
  * 原样(AgentResult.parsedOutput)。native 引擎直传 / 仿真层 ajv 产出(D4 硬分流:
141
54
  * native 路径公共层不做二次校验、不改写其结果)。
@@ -274,6 +187,15 @@ export interface EngineCapabilities {
274
187
  interrupt: "native" | "kill-only";
275
188
  /** kimi headless 固定 auto = ignored;GUI 据此隐藏/提示。 */
276
189
  permissionMode: "native" | "fixed" | "ignored";
190
+ /**
191
+ * [D3-④ r3 裁定] maxTurns 轮数上限的执行能力位(pi = true:turn limiter + spawn
192
+ * watchdog 估算兑现;zcode = false:无 turn_end 语义,静默丢弃会造成「传了上限却
193
+ * 失控」假象)。调用前预检(common/capability-gate)按本位拦「声明不支持的能力」
194
+ * ——pi 不拦 maxTurns(已支持能力,由 turn-limiter 执行)、zcode 同步拒绝。
195
+ * 现状 11 个能力位无可承载 maxTurns 的语义位(fork 拦截可借 session 分叉通道族判,
196
+ * maxTurns 无可借位),故扩位而非保留引擎内硬编码 shape 检查。
197
+ */
198
+ maxTurns: boolean;
277
199
  }
278
200
 
279
201
  // ============================================================
@@ -296,7 +218,12 @@ export interface ProbeReport {
296
218
  * 声明 conversation unsupported 的引擎调用前拒绝(engine_capability_unsupported)。
297
219
  */
298
220
  export type InteractAction =
299
- | { kind: "message"; payload: string }
221
+ /**
222
+ * interrupt:true = steer(抢占)/ false|缺省 = followUp(排队)——pi streamingBehavior
223
+ * 语义的中立承载(D1 §3.3.5「后续 wave 如需抢占语义再扩展 InteractAction」的兑现,
224
+ * chat 域投递经 engine.interact 接通时落地;不支持抢占的引擎忽略)。
225
+ */
226
+ | { kind: "message"; payload: string; interrupt?: boolean }
300
227
  | { kind: "close"; payload?: { force: boolean } }
301
228
  | { kind: "cancel" };
302
229
 
@@ -104,26 +104,34 @@ function truncateLabel(label: string): string {
104
104
  return label.length > TOOL_LABEL_MAX ? label.slice(0, TOOL_LABEL_MAX) : label;
105
105
  }
106
106
 
107
+ /** usage 单字段求和(undefined 视为 0——与旧 `(a ?? 0) + (b ?? 0)` 内联式逐字等价)。 */
108
+ function sumUsageField(a: number | undefined, b: number | undefined): number {
109
+ return (a ?? 0) + (b ?? 0);
110
+ }
111
+
112
+ /** prev 为空时 next 的规范化拷贝(cost 保留原值,可能 undefined——与旧首条分支逐字等价)。 */
113
+ function usageFromNext(next: AgentUsage): AgentUsage {
114
+ return {
115
+ input: next.input ?? 0,
116
+ output: next.output ?? 0,
117
+ cacheRead: next.cacheRead ?? 0,
118
+ cacheWrite: next.cacheWrite ?? 0,
119
+ cost: next.cost,
120
+ };
121
+ }
122
+
107
123
  /**
108
124
  * 累加两个 AgentUsage(field-wise)。prev 为空时返回 next 的拷贝。
109
125
  * 供 message_end 把 usage 增量并入 turn.usageDelta。
110
126
  */
111
127
  function addUsage(prev: AgentUsage | undefined, next: AgentUsage): AgentUsage {
112
- if (prev === undefined) {
113
- return {
114
- input: next.input ?? 0,
115
- output: next.output ?? 0,
116
- cacheRead: next.cacheRead ?? 0,
117
- cacheWrite: next.cacheWrite ?? 0,
118
- cost: next.cost,
119
- };
120
- }
128
+ if (prev === undefined) return usageFromNext(next);
121
129
  return {
122
- input: (prev.input ?? 0) + (next.input ?? 0),
123
- output: (prev.output ?? 0) + (next.output ?? 0),
124
- cacheRead: (prev.cacheRead ?? 0) + (next.cacheRead ?? 0),
125
- cacheWrite: (prev.cacheWrite ?? 0) + (next.cacheWrite ?? 0),
126
- cost: (prev.cost ?? 0) + (next.cost ?? 0),
130
+ input: sumUsageField(prev.input, next.input),
131
+ output: sumUsageField(prev.output, next.output),
132
+ cacheRead: sumUsageField(prev.cacheRead, next.cacheRead),
133
+ cacheWrite: sumUsageField(prev.cacheWrite, next.cacheWrite),
134
+ cost: sumUsageField(prev.cost, next.cost),
127
135
  };
128
136
  }
129
137
 
@@ -274,6 +282,141 @@ function indexToolStart(record: ExecutionRecord, turn: Turn, toolName: string):
274
282
  }
275
283
  }
276
284
 
285
+ // ── 各事件处理器(updateFromEvent 按 case 分发,每个处理器单一职责)──
286
+
287
+ /** text_delta:流式累积进当前 turn 的 text(完整内容,非切片)。 */
288
+ function applyTextDelta(
289
+ record: ExecutionRecord,
290
+ event: Extract<AgentEvent, { type: "text_delta" }>,
291
+ ): void {
292
+ currentTurn(record).text += event.delta;
293
+ }
294
+
295
+ /** thinking_delta:流式累积进当前 turn 的 thinking(完整内容)。 */
296
+ function applyThinkingDelta(
297
+ record: ExecutionRecord,
298
+ event: Extract<AgentEvent, { type: "thinking_delta" }>,
299
+ ): void {
300
+ currentTurn(record).thinking += event.delta;
301
+ }
302
+
303
+ /** tool_start:push 一个 running 的 InternalToolCall(带 startedTs)+ 弹尾索引入册。 */
304
+ function applyToolStart(
305
+ record: ExecutionRecord,
306
+ event: Extract<AgentEvent, { type: "tool_start" }>,
307
+ ): void {
308
+ const tc: InternalToolCall = {
309
+ toolName: event.toolName,
310
+ args: event.args,
311
+ result: undefined,
312
+ isError: false,
313
+ _status: "running",
314
+ startedTs: Date.now(),
315
+ };
316
+ const turn = currentTurn(record);
317
+ turn.toolCalls.push(tc);
318
+ indexToolStart(record, turn, event.toolName);
319
+ }
320
+
321
+ /**
322
+ * tool_end 定位:索引弹尾 O(1) 命中 running 同名 toolCall;索引 miss(无记录 / 槽位
323
+ * 已非 running)回退 findRunningToolCall 跨 turn 倒序全扫兜底。
324
+ * 返回 [turn, index];两路都 miss 返回 undefined。
325
+ */
326
+ function matchRunningToolCall(
327
+ record: ExecutionRecord,
328
+ toolName: string,
329
+ ): readonly [Turn, number] | undefined {
330
+ const byName = runningToolIndex.get(record);
331
+ const arr = byName?.get(toolName);
332
+ if (arr !== undefined && arr.length > 0) {
333
+ const item = arr[arr.length - 1];
334
+ arr.pop();
335
+ const tc = item.turn.toolCalls[item.idx];
336
+ if (tc !== undefined && tc._status === "running") {
337
+ return [item.turn, item.idx] as const;
338
+ }
339
+ }
340
+ // 兜底:重建 record 的历史 running toolCall(索引未覆盖)、索引项被外部路径
341
+ // 置非 running 等场景——保持与旧实现一致的跨 turn 倒序全扫。
342
+ return findRunningToolCall(record, toolName);
343
+ }
344
+
345
+ /**
346
+ * tool_end:命中则回填 result/isError/_status;未命中(SDK 发了 tool_end 但无对应
347
+ * tool_start,如外部注入的工具)直接 push 一个已完成的 InternalToolCall,避免数据丢失。
348
+ */
349
+ function applyToolEnd(
350
+ record: ExecutionRecord,
351
+ event: Extract<AgentEvent, { type: "tool_end" }>,
352
+ ): void {
353
+ const matched = matchRunningToolCall(record, event.toolName);
354
+ if (matched !== undefined) {
355
+ const [turn, i] = matched;
356
+ const tc = turn.toolCalls[i]!;
357
+ tc.args = event.args ?? tc.args;
358
+ tc.result = event.result;
359
+ tc.isError = event.isError ?? false;
360
+ tc._status = event.isError ? "failed" : "done";
361
+ return;
362
+ }
363
+ currentTurn(record).toolCalls.push({
364
+ toolName: event.toolName,
365
+ args: event.args,
366
+ result: event.result,
367
+ isError: event.isError ?? false,
368
+ _status: event.isError ? "failed" : "done",
369
+ startedTs: Date.now(),
370
+ });
371
+ }
372
+
373
+ /**
374
+ * turn_end:闭合当前 turn,记 closedTs(真实墙钟),turnCount++,清 lastError。
375
+ * 正常闭合清 lastError:瞬态 error 恢复后不应误判 success=false
376
+ * (若 turn_end 后 message_end 报 error,会在 message_end 处理器重新写回)。
377
+ */
378
+ function applyTurnEnd(record: ExecutionRecord): void {
379
+ const turn = currentTurn(record);
380
+ turn.closed = true;
381
+ turn.closedTs = Date.now();
382
+ record.turnCount += 1;
383
+ record.lastError = undefined;
384
+ }
385
+
386
+ /**
387
+ * message_end:usage 增量存进末 turn.usageDelta(直接写末 turn,不开新 turn);
388
+ * totalTokens 累加;error(stopReason=error)记进 lastError。
389
+ *
390
+ * usageDelta 按 message_end **累加**(非覆盖)——同一 turn 内若多次 message_end
391
+ * 到达(或 turn_end 后的滞后 message_end 落到 currentTurn 开的新 turn),
392
+ * 累加保证不丢 usage。getTotalUsage 扁平求和所有 turn,归属 turn 的精确性
393
+ * 不影响最终 total(无消费方读单 turn usage)。
394
+ */
395
+ function applyMessageEnd(
396
+ record: ExecutionRecord,
397
+ event: Extract<AgentEvent, { type: "message_end" }>,
398
+ ): void {
399
+ if (event.usage) {
400
+ const turn = currentTurn(record);
401
+ turn.usageDelta = addUsage(turn.usageDelta, event.usage);
402
+ // totalTokens 累加四项之和(保留旧语义,投影直接读)
403
+ record.totalTokens +=
404
+ (event.usage.input ?? 0) + (event.usage.output ?? 0) +
405
+ (event.usage.cacheRead ?? 0) + (event.usage.cacheWrite ?? 0);
406
+ }
407
+ if (event.error) {
408
+ record.lastError = event.error;
409
+ }
410
+ }
411
+
412
+ /** error:存 record.lastError(getEventLog 派生 error 条目用)。 */
413
+ function applyErrorEvent(
414
+ record: ExecutionRecord,
415
+ event: Extract<AgentEvent, { type: "error" }>,
416
+ ): void {
417
+ record.lastError = event.message;
418
+ }
419
+
277
420
  /**
278
421
  * 从 AgentEvent 更新 record。所有数据收口进 record.turns[]。
279
422
  * - text/thinking:流式累积进 currentTurn()(完整内容,非切片)
@@ -293,116 +436,32 @@ function indexToolStart(record: ExecutionRecord, turn: Turn, toolName: string):
293
436
  export function updateFromEvent(record: ExecutionRecord, event: AgentEvent): void {
294
437
  switch (event.type) {
295
438
  // ── text / thinking:流式累积进当前 turn ──
296
- case "text_delta": {
297
- currentTurn(record).text += event.delta;
298
- return;
299
- }
300
- case "thinking_delta": {
301
- currentTurn(record).thinking += event.delta;
302
- return;
303
- }
304
-
305
- // ── tool_start:push 一个 running 的 InternalToolCall(带 startedTs)──
306
- case "tool_start": {
307
- const tc: InternalToolCall = {
308
- toolName: event.toolName,
309
- args: event.args,
310
- result: undefined,
311
- isError: false,
312
- _status: "running",
313
- startedTs: Date.now(),
314
- };
315
- const turn = currentTurn(record);
316
- turn.toolCalls.push(tc);
317
- indexToolStart(record, turn, event.toolName);
318
- return;
319
- }
439
+ case "text_delta":
440
+ return applyTextDelta(record, event);
441
+ case "thinking_delta":
442
+ return applyThinkingDelta(record, event);
320
443
 
321
- // ── tool_end:索引弹尾 O(1) 定位 running 同名 toolCall,miss 回退全扫兜底 ──
322
- case "tool_end": {
323
- let matched: readonly [Turn, number] | undefined;
324
- const byName = runningToolIndex.get(record);
325
- const arr = byName?.get(event.toolName);
326
- if (arr !== undefined && arr.length > 0) {
327
- const item = arr[arr.length - 1];
328
- arr.pop();
329
- const tc = item.turn.toolCalls[item.idx];
330
- if (tc !== undefined && tc._status === "running") {
331
- matched = [item.turn, item.idx] as const;
332
- }
333
- }
334
- if (matched === undefined) {
335
- // 兜底:重建 record 的历史 running toolCall(索引未覆盖)、索引项被外部路径
336
- // 置非 running 等场景——保持与旧实现一致的跨 turn 倒序全扫。
337
- matched = findRunningToolCall(record, event.toolName);
338
- }
339
- if (matched !== undefined) {
340
- const [turn, i] = matched;
341
- const tc = turn.toolCalls[i]!;
342
- tc.args = event.args ?? tc.args;
343
- tc.result = event.result;
344
- tc.isError = event.isError ?? false;
345
- tc._status = event.isError ? "failed" : "done";
346
- return;
347
- }
348
- // 匹配失败(SDK 发了 tool_end 但无对应 tool_start,如外部注入的工具):
349
- // 直接 push 一个已完成的 InternalToolCall,避免数据丢失。
350
- currentTurn(record).toolCalls.push({
351
- toolName: event.toolName,
352
- args: event.args,
353
- result: event.result,
354
- isError: event.isError ?? false,
355
- _status: event.isError ? "failed" : "done",
356
- startedTs: Date.now(),
357
- });
358
- return;
359
- }
444
+ // ── tool_start/end:push 进 currentTurn().toolCalls(含完整 result)──
445
+ case "tool_start":
446
+ return applyToolStart(record, event);
447
+ case "tool_end":
448
+ return applyToolEnd(record, event);
360
449
 
361
- // ── turn_end:闭合当前 turn,记 closedTs,turnCount++,清 lastError ──
362
- case "turn_end": {
363
- const turn = currentTurn(record);
364
- turn.closed = true;
365
- turn.closedTs = Date.now();
366
- record.turnCount += 1;
367
- // turn 正常闭合意味着本段执行成功——清掉运行期可能记录的瞬态 error,
368
- // 避免瞬态 error 恢复后 session-runner 仍据 lastError 误判 success=false。
369
- // (若 turn_end 后 message_end 报 error,会在 message_end 分支重新写回 lastError。)
370
- record.lastError = undefined;
371
- return;
372
- }
450
+ // ── turn_end:闭合当前 turn ──
451
+ case "turn_end":
452
+ return applyTurnEnd(record);
373
453
 
374
- // ── message_end:usage 增量累加进 currentTurn().usageDelta,totalTokens 累加 ──
375
- //
376
- // usageDelta 按 message_end **累加**(非覆盖)——同一 turn 内若多次 message_end
377
- // 到达(或 turn_end 后的滞后 message_end 落到 currentTurn 开的新 turn),
378
- // 累加保证不丢 usage。getTotalUsage 扁平求和所有 turn,归属 turn 的精确性
379
- // 不影响最终 total(无消费方读单 turn usage)。
380
- case "message_end": {
381
- if (event.usage) {
382
- const turn = currentTurn(record);
383
- turn.usageDelta = addUsage(turn.usageDelta, event.usage);
384
- // totalTokens 累加四项之和(保留旧语义,投影直接读)
385
- record.totalTokens +=
386
- (event.usage.input ?? 0) + (event.usage.output ?? 0) +
387
- (event.usage.cacheRead ?? 0) + (event.usage.cacheWrite ?? 0);
388
- }
389
- // message_end 的 error(stopReason=error)也记进 lastError
390
- if (event.error) {
391
- record.lastError = event.error;
392
- }
393
- return;
394
- }
454
+ // ── message_end:usage 增量累加 + totalTokens 累加 ──
455
+ case "message_end":
456
+ return applyMessageEnd(record, event);
395
457
 
396
- // ── error:存 record.lastError(getEventLog 派生 error 条目)──
397
- case "error": {
398
- record.lastError = event.message;
399
- return;
400
- }
458
+ // ── error:存 record.lastError ──
459
+ case "error":
460
+ return applyErrorEvent(record, event);
401
461
 
402
462
  // ── compaction:不产生数据(不变)──
403
- case "compaction": {
463
+ case "compaction":
404
464
  return;
405
- }
406
465
 
407
466
  default: {
408
467
  // 穷尽性检查:新增 AgentEvent variant 时编译期报错
@@ -881,6 +940,46 @@ export function snapshot(record: ExecutionRecord): RecordSnapshot {
881
940
  /** subprocess JSONL 事件(JSON.parse 结果)。duck-typed,对应 SDK SdkEvent。 */
882
941
  type JsonlEvent = Record<string, unknown>;
883
942
 
943
+ // ── 各 case 翻译器(jsonlToAgentEvent 按 case 分发,每个翻译器单一职责)──
944
+
945
+ /** tool_execution_start → tool_start。toolName 非字符串归一空串(与原实现一致)。 */
946
+ function translateToolExecutionStart(raw: JsonlEvent): AgentEvent[] {
947
+ const toolName = typeof raw.toolName === "string" ? raw.toolName : "";
948
+ return [{ type: "tool_start", toolName, args: raw.args }];
949
+ }
950
+
951
+ /** tool_execution_end → tool_end。isError 仅在 === true 时成立;result 原样透传。 */
952
+ function translateToolExecutionEnd(raw: JsonlEvent): AgentEvent[] {
953
+ const toolName = typeof raw.toolName === "string" ? raw.toolName : "";
954
+ const isError = raw.isError === true;
955
+ return [{
956
+ type: "tool_end",
957
+ toolName,
958
+ args: raw.args,
959
+ result: raw.result as ToolCallResult | undefined,
960
+ isError,
961
+ }];
962
+ }
963
+
964
+ /**
965
+ * message_update → thinking_delta / text_delta。
966
+ * ame.type === "thinking_delta"(delta 非字符串归一空串)
967
+ * 其余 ame(delta 有值)→ text_delta(delta 非字符串 String() 归一)
968
+ * ame 缺失 / delta 缺失 → 不产出。
969
+ */
970
+ function translateMessageUpdate(raw: JsonlEvent): AgentEvent[] {
971
+ const ame = raw.assistantMessageEvent as Record<string, unknown> | undefined;
972
+ if (ame?.type === "thinking_delta") {
973
+ const delta = typeof ame.delta === "string" ? ame.delta : "";
974
+ return [{ type: "thinking_delta", delta }];
975
+ }
976
+ if (ame !== undefined && ame.delta !== undefined) {
977
+ const delta = typeof ame.delta === "string" ? ame.delta : String(ame.delta);
978
+ return [{ type: "text_delta", delta }];
979
+ }
980
+ return [];
981
+ }
982
+
884
983
  /**
885
984
  * 把一条 JSONL 事件翻译成 AgentEvent。
886
985
  *
@@ -900,35 +999,14 @@ export function jsonlToAgentEvent(raw: JsonlEvent): AgentEvent[] {
900
999
  case "tool_execution_update":
901
1000
  return [];
902
1001
 
903
- case "tool_execution_start": {
904
- const toolName = typeof raw.toolName === "string" ? raw.toolName : "";
905
- return [{ type: "tool_start", toolName, args: raw.args }];
906
- }
1002
+ case "tool_execution_start":
1003
+ return translateToolExecutionStart(raw);
907
1004
 
908
- case "tool_execution_end": {
909
- const toolName = typeof raw.toolName === "string" ? raw.toolName : "";
910
- const isError = raw.isError === true;
911
- return [{
912
- type: "tool_end",
913
- toolName,
914
- args: raw.args,
915
- result: raw.result as ToolCallResult | undefined,
916
- isError,
917
- }];
918
- }
1005
+ case "tool_execution_end":
1006
+ return translateToolExecutionEnd(raw);
919
1007
 
920
- case "message_update": {
921
- const ame = raw.assistantMessageEvent as Record<string, unknown> | undefined;
922
- if (ame?.type === "thinking_delta") {
923
- const delta = typeof ame.delta === "string" ? ame.delta : "";
924
- return [{ type: "thinking_delta", delta }];
925
- }
926
- if (ame !== undefined && ame.delta !== undefined) {
927
- const delta = typeof ame.delta === "string" ? ame.delta : String(ame.delta);
928
- return [{ type: "text_delta", delta }];
929
- }
930
- return [];
931
- }
1008
+ case "message_update":
1009
+ return translateMessageUpdate(raw);
932
1010
 
933
1011
  case "turn_end": {
934
1012
  return [{ type: "turn_end" }];