@zhushanwen/pi-subagent-workflow 8.5.0 → 8.7.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 (336) hide show
  1. package/package.json +13 -16
  2. package/relay/relay.mjs +1 -1
  3. package/src/host/__tests__/pi-host.test.ts +214 -0
  4. package/src/host/pi-host.ts +109 -0
  5. package/src/index.ts +142 -32
  6. package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
  7. package/src/injectors/__tests__/engine-section-stability.test.ts +341 -0
  8. package/src/injectors/__tests__/subagent-list-injector.test.ts +5 -5
  9. package/src/injectors/__tests__/workflow-list-injector.test.ts +5 -5
  10. package/src/injectors/engine-awareness.ts +123 -0
  11. package/src/injectors/model-list-injector.ts +1 -1
  12. package/src/injectors/subagent-list-injector.ts +8 -8
  13. package/src/injectors/workflow-list-injector.ts +8 -8
  14. package/src/interface/__tests__/detectors.test.ts +3 -3
  15. package/src/interface/__tests__/subagent-tool-path-guard.test.ts +157 -0
  16. package/src/interface/__tests__/subagent-tool-prompt.test.ts +12 -0
  17. package/src/interface/__tests__/tool-workflow-script-generate.test.ts +2 -2
  18. package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +1 -1
  19. package/src/interface/bg-notify-render.ts +34 -13
  20. package/src/interface/commands.ts +3 -3
  21. package/src/interface/format.ts +2 -2
  22. package/src/interface/helpers.ts +3 -3
  23. package/src/interface/list-component.ts +4 -4
  24. package/src/interface/list-shared.ts +2 -2
  25. package/src/interface/list-view.ts +2 -2
  26. package/src/interface/subagent-actions.ts +288 -19
  27. package/src/interface/subagent-tool-schema.ts +163 -0
  28. package/src/interface/subagent-tool.ts +65 -129
  29. package/src/interface/subagents.ts +5 -5
  30. package/src/interface/tool-render.ts +34 -2
  31. package/src/interface/tool-workflow-script.ts +4 -4
  32. package/src/interface/tool-workflow.ts +6 -6
  33. package/src/interface/views/WorkflowsView.ts +5 -5
  34. package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +3 -3
  35. package/src/interface/views/__tests__/detail-content-session-file.test.ts +2 -2
  36. package/src/interface/views/detail-content.ts +4 -4
  37. package/src/interface/views/format.ts +4 -4
  38. package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +132 -18
  39. package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +0 -53
  40. package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +0 -1
  41. package/src/execution/__tests__/agent-registry.test.ts +0 -363
  42. package/src/execution/__tests__/agent-result-mapper.test.ts +0 -150
  43. package/src/execution/__tests__/alive-store.test.ts +0 -147
  44. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  45. package/src/execution/__tests__/before-agent-start-injection.test.ts +0 -132
  46. package/src/execution/__tests__/bg-notify-render.test.ts +0 -256
  47. package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
  48. package/src/execution/__tests__/chat-engine-routing.test.ts +0 -597
  49. package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +0 -365
  50. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -190
  51. package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +0 -215
  52. package/src/execution/__tests__/concurrency-pool.test.ts +0 -250
  53. package/src/execution/__tests__/config.test.ts +0 -110
  54. package/src/execution/__tests__/conversation-wiring.test.ts +0 -198
  55. package/src/execution/__tests__/crash-recovery.test.ts +0 -320
  56. package/src/execution/__tests__/delivery-methods.test.ts +0 -385
  57. package/src/execution/__tests__/dialog-queue.test.ts +0 -299
  58. package/src/execution/__tests__/epipe-fallback.test.ts +0 -241
  59. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -243
  60. package/src/execution/__tests__/execute-nesting.test.ts +0 -323
  61. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -189
  62. package/src/execution/__tests__/execution-record.test.ts +0 -1284
  63. package/src/execution/__tests__/finalize-record.test.ts +0 -368
  64. package/src/execution/__tests__/finalized-marker.test.ts +0 -82
  65. package/src/execution/__tests__/format-schema-instruction.test.ts +0 -138
  66. package/src/execution/__tests__/format.test.ts +0 -458
  67. package/src/execution/__tests__/gc-timer.test.ts +0 -184
  68. package/src/execution/__tests__/get-record-for-action-restart.test.ts +0 -254
  69. package/src/execution/__tests__/gui-mode-dispatch.test.ts +0 -59
  70. package/src/execution/__tests__/helpers/mock-extension-api.ts +0 -30
  71. package/src/execution/__tests__/helpers/spawn-mock.ts +0 -238
  72. package/src/execution/__tests__/host-mode.test.ts +0 -87
  73. package/src/execution/__tests__/index-session-start-identity.test.ts +0 -371
  74. package/src/execution/__tests__/index-session-start.test.ts +0 -593
  75. package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
  76. package/src/execution/__tests__/lifecycle-manager.test.ts +0 -337
  77. package/src/execution/__tests__/lifecycle-predicates.test.ts +0 -116
  78. package/src/execution/__tests__/list-component.test.ts +0 -401
  79. package/src/execution/__tests__/list-fields.test.ts +0 -109
  80. package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
  81. package/src/execution/__tests__/model-resolver.test.ts +0 -413
  82. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +0 -287
  83. package/src/execution/__tests__/nested-visibility.test.ts +0 -325
  84. package/src/execution/__tests__/notifier-flush.test.ts +0 -574
  85. package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
  86. package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
  87. package/src/execution/__tests__/output-collector.test.ts +0 -61
  88. package/src/execution/__tests__/parent-child-matrix.test.ts +0 -336
  89. package/src/execution/__tests__/path-encoding.test.ts +0 -104
  90. package/src/execution/__tests__/pi-invocation.test.ts +0 -134
  91. package/src/execution/__tests__/record-store.test.ts +0 -1057
  92. package/src/execution/__tests__/records-cwd-isolation.test.ts +0 -91
  93. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +0 -339
  94. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -273
  95. package/src/execution/__tests__/relay-agent.test.ts +0 -448
  96. package/src/execution/__tests__/relay-env.test.ts +0 -42
  97. package/src/execution/__tests__/resource-policy.test.ts +0 -109
  98. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  99. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -267
  100. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -253
  101. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -644
  102. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  103. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  104. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  105. package/src/execution/__tests__/sdk-contract.test.ts +0 -273
  106. package/src/execution/__tests__/session-context-resolver.test.ts +0 -167
  107. package/src/execution/__tests__/session-file-gc.test.ts +0 -293
  108. package/src/execution/__tests__/session-pending.test.ts +0 -197
  109. package/src/execution/__tests__/session-reconstructor.test.ts +0 -379
  110. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -178
  111. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -311
  112. package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
  113. package/src/execution/__tests__/spawn-args.test.ts +0 -434
  114. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -189
  115. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  116. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -207
  117. package/src/execution/__tests__/spawned-children.test.ts +0 -92
  118. package/src/execution/__tests__/startup-config-declaration.test.ts +0 -35
  119. package/src/execution/__tests__/status-refactor.test.ts +0 -345
  120. package/src/execution/__tests__/stdin-writer.test.ts +0 -463
  121. package/src/execution/__tests__/stream-sink-retirement.test.ts +0 -261
  122. package/src/execution/__tests__/subagent-service-abort.test.ts +0 -60
  123. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -629
  124. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +0 -180
  125. package/src/execution/__tests__/subagent-service.test.ts +0 -788
  126. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -310
  127. package/src/execution/__tests__/subprocess-agent-runner.test.ts +0 -506
  128. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  129. package/src/execution/__tests__/timeout-integration.test.ts +0 -397
  130. package/src/execution/__tests__/tombstone-store.test.ts +0 -73
  131. package/src/execution/__tests__/tool-action.test.ts +0 -385
  132. package/src/execution/__tests__/truncline-snapshot.test.ts +0 -81
  133. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  134. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  135. package/src/execution/__tests__/ui-channels.test.ts +0 -187
  136. package/src/execution/__tests__/ui-interaction-model.test.ts +0 -67
  137. package/src/execution/__tests__/ui-request-handler-factory.test.ts +0 -370
  138. package/src/execution/__tests__/ui-request-handler.test.ts +0 -204
  139. package/src/execution/__tests__/ui-request-observability.test.ts +0 -114
  140. package/src/execution/__tests__/ui-request-queue.test.ts +0 -133
  141. package/src/execution/__tests__/worktree-manager.test.ts +0 -633
  142. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -229
  143. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +0 -181
  144. package/src/execution/__tests__/worktree-registry.test.ts +0 -199
  145. package/src/execution/agent-registry.ts +0 -193
  146. package/src/execution/agent-result-mapper.ts +0 -90
  147. package/src/execution/alive-store.ts +0 -92
  148. package/src/execution/argv-mirror.ts +0 -109
  149. package/src/execution/best-effort.ts +0 -38
  150. package/src/execution/channel-registry-access.ts +0 -144
  151. package/src/execution/concurrency-pool.ts +0 -116
  152. package/src/execution/config.ts +0 -96
  153. package/src/execution/dialog-queue.ts +0 -330
  154. package/src/execution/engine/__tests__/common/data-dir.test.ts +0 -53
  155. package/src/execution/engine/__tests__/common/errors.test.ts +0 -132
  156. package/src/execution/engine/__tests__/common/event-journal.test.ts +0 -177
  157. package/src/execution/engine/__tests__/common/kill-chain.test.ts +0 -192
  158. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +0 -81
  159. package/src/execution/engine/__tests__/common/persona-router.test.ts +0 -123
  160. package/src/execution/engine/__tests__/common/pool-manager.test.ts +0 -154
  161. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  162. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  163. package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +0 -141
  164. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +0 -109
  165. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +0 -101
  166. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +0 -77
  167. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +0 -104
  168. package/src/execution/engine/__tests__/conformance/contract.relay.test.ts +0 -342
  169. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +0 -201
  170. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +0 -76
  171. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +0 -79
  172. package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -87
  173. package/src/execution/engine/__tests__/engines-declaration.test.ts +0 -36
  174. package/src/execution/engine/__tests__/model-prompt.test.ts +0 -85
  175. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  176. package/src/execution/engine/__tests__/registry.test.ts +0 -120
  177. package/src/execution/engine/__tests__/routing.test.ts +0 -231
  178. package/src/execution/engine/common/data-dir.ts +0 -62
  179. package/src/execution/engine/common/errors.ts +0 -183
  180. package/src/execution/engine/common/event-journal.ts +0 -254
  181. package/src/execution/engine/common/journal-replay.ts +0 -62
  182. package/src/execution/engine/common/kill-chain.ts +0 -221
  183. package/src/execution/engine/common/nesting-guard.ts +0 -50
  184. package/src/execution/engine/common/persona-router.ts +0 -108
  185. package/src/execution/engine/common/pool-manager.ts +0 -226
  186. package/src/execution/engine/common/schema-emulation.ts +0 -189
  187. package/src/execution/engine/common/session-view-projection.ts +0 -51
  188. package/src/execution/engine/engine-discovery.ts +0 -65
  189. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -469
  190. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  191. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  192. package/src/execution/engine/engines/pi/pi-engine.ts +0 -415
  193. package/src/execution/engine/engines/pi/reader.ts +0 -48
  194. package/src/execution/engine/engines/pi/registration.ts +0 -35
  195. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  196. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  197. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  198. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -246
  199. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -228
  200. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  201. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -64
  202. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -127
  203. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -567
  204. package/src/execution/engine/engines/zcode/constants.ts +0 -43
  205. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -39
  206. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  207. package/src/execution/engine/engines/zcode/parser.ts +0 -436
  208. package/src/execution/engine/engines/zcode/preparer.ts +0 -363
  209. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  210. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  211. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -648
  212. package/src/execution/engine/host-task-spec.ts +0 -47
  213. package/src/execution/engine/model-prompt.ts +0 -59
  214. package/src/execution/engine/paths.ts +0 -42
  215. package/src/execution/engine/port.ts +0 -153
  216. package/src/execution/engine/registry.ts +0 -123
  217. package/src/execution/engine/routing.ts +0 -218
  218. package/src/execution/engine/types.ts +0 -304
  219. package/src/execution/execute-options-mapper.ts +0 -111
  220. package/src/execution/execution-record.ts +0 -906
  221. package/src/execution/finalize-record.ts +0 -251
  222. package/src/execution/finalized-marker.ts +0 -51
  223. package/src/execution/get-state-handshake.ts +0 -104
  224. package/src/execution/host-mode.ts +0 -56
  225. package/src/execution/idle-gc.ts +0 -47
  226. package/src/execution/lifecycle-manager.ts +0 -491
  227. package/src/execution/lifecycle-predicates.ts +0 -65
  228. package/src/execution/manifest-store.ts +0 -256
  229. package/src/execution/model-config-service.ts +0 -204
  230. package/src/execution/model-resolver.ts +0 -276
  231. package/src/execution/notifier.ts +0 -260
  232. package/src/execution/output-collector.ts +0 -88
  233. package/src/execution/path-encoding.ts +0 -60
  234. package/src/execution/pi-invocation.ts +0 -120
  235. package/src/execution/record-entry.ts +0 -132
  236. package/src/execution/record-store.ts +0 -1234
  237. package/src/execution/relay-env.ts +0 -37
  238. package/src/execution/session-context-resolver.ts +0 -64
  239. package/src/execution/session-file-gc.ts +0 -120
  240. package/src/execution/session-pending.ts +0 -164
  241. package/src/execution/session-reconstructor.ts +0 -678
  242. package/src/execution/session-runner.ts +0 -1548
  243. package/src/execution/sessions-index.ts +0 -304
  244. package/src/execution/spawn-event-adapter.ts +0 -363
  245. package/src/execution/stdin-writer.ts +0 -198
  246. package/src/execution/stream-sink.ts +0 -126
  247. package/src/execution/subagent-service.ts +0 -2119
  248. package/src/execution/subprocess-agent-runner.ts +0 -303
  249. package/src/execution/temp-prompt.ts +0 -62
  250. package/src/execution/tombstone-store.ts +0 -72
  251. package/src/execution/turn-limiter.ts +0 -102
  252. package/src/execution/types.ts +0 -910
  253. package/src/execution/ui-channels.ts +0 -216
  254. package/src/execution/ui-interaction-model.ts +0 -48
  255. package/src/execution/ui-request-handler-factory.ts +0 -212
  256. package/src/execution/ui-request-observability.ts +0 -81
  257. package/src/execution/ui-request-queue.ts +0 -174
  258. package/src/execution/worktree-manager.ts +0 -688
  259. package/src/execution/worktree-registry.ts +0 -222
  260. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +0 -336
  261. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -208
  262. package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -157
  263. package/src/orchestration/__tests__/args-validator.test.ts +0 -143
  264. package/src/orchestration/__tests__/concurrency-gate.test.ts +0 -125
  265. package/src/orchestration/__tests__/config-loader.test.ts +0 -503
  266. package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -724
  267. package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +0 -405
  268. package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +0 -56
  269. package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +0 -166
  270. package/src/orchestration/__tests__/execute-agent-call.test.ts +0 -314
  271. package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
  272. package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
  273. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -277
  274. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
  275. package/src/orchestration/__tests__/lifecycle.test.ts +0 -625
  276. package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -1971
  277. package/src/orchestration/__tests__/script-lint.test.ts +0 -831
  278. package/src/orchestration/__tests__/skill-discovery.test.ts +0 -157
  279. package/src/orchestration/__tests__/test-mocks.ts +0 -197
  280. package/src/orchestration/__tests__/worker-host.test.ts +0 -120
  281. package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +0 -164
  282. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +0 -520
  283. package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
  284. package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -110
  285. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -317
  286. package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +0 -110
  287. package/src/orchestration/__tests__/workflows-e2e.test.ts +0 -537
  288. package/src/orchestration/agent-opts-resolver.ts +0 -93
  289. package/src/orchestration/args-validator.ts +0 -127
  290. package/src/orchestration/concurrency-gate.ts +0 -69
  291. package/src/orchestration/config-loader.ts +0 -315
  292. package/src/orchestration/error-recovery.ts +0 -862
  293. package/src/orchestration/execute-agent-call.ts +0 -217
  294. package/src/orchestration/launcher.ts +0 -410
  295. package/src/orchestration/lifecycle.ts +0 -396
  296. package/src/orchestration/models/__tests__/budget.test.ts +0 -367
  297. package/src/orchestration/models/__tests__/trace.test.ts +0 -408
  298. package/src/orchestration/models/agent-call.ts +0 -83
  299. package/src/orchestration/models/budget.ts +0 -148
  300. package/src/orchestration/models/ports.ts +0 -164
  301. package/src/orchestration/models/run-runtime.ts +0 -89
  302. package/src/orchestration/models/run-spec.ts +0 -83
  303. package/src/orchestration/models/run-state.ts +0 -44
  304. package/src/orchestration/models/trace.ts +0 -183
  305. package/src/orchestration/models/types.ts +0 -292
  306. package/src/orchestration/models/workflow-run.ts +0 -254
  307. package/src/orchestration/models/workflow-script-registry.ts +0 -35
  308. package/src/orchestration/models/workflow-script.ts +0 -117
  309. package/src/orchestration/script-lint.ts +0 -766
  310. package/src/orchestration/skill-discovery.ts +0 -92
  311. package/src/orchestration/worker-handle.ts +0 -115
  312. package/src/orchestration/worker-host.ts +0 -98
  313. package/src/orchestration/worker-script-builder.ts +0 -408
  314. package/src/orchestration/workflow-files.ts +0 -85
  315. package/src/orchestration/workflow-script-registry-impl.ts +0 -133
  316. package/src/shared/__tests__/agent-ref.test.ts +0 -34
  317. package/src/shared/__tests__/meta-parser.test.ts +0 -304
  318. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -280
  319. package/src/shared/__tests__/resource-discovery.test.ts +0 -736
  320. package/src/shared/__tests__/resource-meta.test.ts +0 -51
  321. package/src/shared/__tests__/schema-jsonify.test.ts +0 -81
  322. package/src/shared/agent-event.ts +0 -13
  323. package/src/shared/agent-ref.ts +0 -57
  324. package/src/shared/meta-parser.ts +0 -261
  325. package/src/shared/resource-discovery.ts +0 -811
  326. package/src/shared/resource-meta.ts +0 -65
  327. package/src/shared/schema-jsonify.ts +0 -56
  328. package/src/shared/xml-injection.ts +0 -35
  329. package/workflows/README.md +0 -81
  330. package/workflows/_shared/agent-refs.cjs +0 -40
  331. package/workflows/chain.js +0 -131
  332. package/workflows/map-reduce.js +0 -174
  333. package/workflows/parallel.js +0 -148
  334. package/workflows/review-fix-loop-utils.cjs +0 -1307
  335. package/workflows/review-fix-loop.js +0 -1396
  336. package/workflows/scatter-gather.js +0 -178
@@ -1,276 +0,0 @@
1
- // src/core/model-resolver.ts
2
- //
3
- // 模型解析(三层):
4
- // 1. 用户显式 override(tool 参数 model,平铺在 subagent params 顶层)→ registry lookup + auth
5
- // 2. agent .md frontmatter model(agent 作者指定)→ registry lookup + auth
6
- // 3. 主 agent 当前模型(ctx.model)→ 直接透传,无需 lookup
7
- //
8
- // 设计:默认与主 agent 同模型(零配置)。只有「有人显式指定 model」时才查
9
- // registry 做解析 + 鉴权校验。thinkingLevel 同链路,无指定时 undefined。
10
-
11
- /**
12
- * ModelRegistry 的最小接口(duck-typed,测试可 mock)。
13
- * 字段结构与 Pi SDK 的 ctx.modelRegistry 对齐。
14
- */
15
- export interface ModelRegistryLike {
16
- /** 返回所有已配置鉴权的可用模型。 */
17
- getAvailable(): ModelInfo[];
18
- /** 按 (provider, modelId) 查找。 */
19
- find(provider: string, modelId: string): ModelInfo | undefined;
20
- /** 校验模型鉴权是否就绪。 */
21
- hasConfiguredAuth(model: unknown): boolean;
22
- }
23
-
24
- /**
25
- * 模型信息(registry 返回元素 / ctx.model 鸭子类型兼容)。
26
- * ctx.model(SDK Model<Api>)是此类型的超集,运行时直接当 ModelInfo 用。
27
- */
28
- export interface ModelInfo {
29
- id: string;
30
- name: string;
31
- provider: string;
32
- reasoning: boolean;
33
- thinkingLevelMap?: Record<string, unknown>;
34
- contextWindow?: number;
35
- }
36
-
37
- /** agent .md frontmatter 解析结果。 */
38
- export interface AgentConfig {
39
- /** agent 名(文件名 basename)。 */
40
- name: string;
41
- /** system prompt(markdown 正文)。 */
42
- systemPrompt: string;
43
- /** tool allowlist(三层过滤之一)。 */
44
- tools?: string[];
45
- /** 默认模型 override("provider/modelId")。agent 作者显式指定。 */
46
- model?: string;
47
- /** 默认 thinkingLevel override。 */
48
- thinkingLevel?: string;
49
- /** 默认 background 模式(true 时无显式 wait 走 background)。 */
50
- defaultBackground?: boolean;
51
- /**
52
- * 执行引擎 id(agent .md frontmatter engine 字段,D9 per-agent 主通道)。
53
- * 解析期已对注册表校验(未注册 id 在 agent-registry 抛 EngineNotFoundError);
54
- * 执行侧(P4 路由层)按 调用参数 > 本字段 > 全局默认 三层取值。
55
- */
56
- engine?: string;
57
- }
58
-
59
- /** 解析结果(model 实例 + 生效的 thinkingLevel)。 */
60
- export interface ResolvedModel {
61
- model: ModelInfo;
62
- thinkingLevel: string | undefined;
63
- }
64
-
65
- // ============================================================
66
- // 常量
67
- // ============================================================
68
-
69
- /** thinking level 支持顺序(低→高),用于 clamp 到 model 可用级别。
70
- * SSOT(单一权威源):新增 thinking 级别只改此处,subagent-tool 的 thinkingLevel 枚举
71
- * 从本常量派生,避免两处硬编码不同步。 */
72
- export const THINKING_ORDER = ["off", "minimal", "low", "medium", "high", "xhigh", "max"] as const;
73
-
74
- /** 解析失败时错误信息列出的可用模型上限(防超长错误信息)。 */
75
- const MODEL_LIST_LIMIT = 20;
76
-
77
- // ============================================================
78
- // 解析
79
- // ============================================================
80
-
81
- /**
82
- * 三层模型解析:
83
- *
84
- * ╔═══════════════════════════════════════════════════════════════╗
85
- // ║ 优先级(高→低): ║
86
- // ║ 1. paramOverride.model (调用方显式指定,tool 参数) ║
87
- // ║ 2. agentConfig.model (agent .md frontmatter) ║
88
- // ║ 3. ctxModel (主 agent 当前模型,直接透传) ║
89
- // ║ ║
90
- // ║ 1/2 级查 registry + auth 校验;3 级无需 lookup(主 agent 在用 ║
91
- // ║ 说明 auth OK)。thinkingLevel 无显式指定时兜底「模型最高可用档」║
92
- // ║ (maxThinkingForModel,含 "max" 时用 max)——不落回 pi 默认 ║
93
- // ║ medium,subagent 任务需要最大推理深度。 ║
94
- // ║ ║
95
- // ║ 显式指定但 lookup/auth 失败 → 抛错(不静默降级到主 agent, ║
96
- // ║ 因为用户明确要求了某个 model,降级会造成「以为用了 X 实际用 Y」║
97
- // ╚════════════════════════════════════════════════════════════════╝
98
- *
99
- * @param agentConfig agent .md 解析结果(查 model override + thinkingLevel)
100
- * @param modelRegistry registry(仅 override 路径用)
101
- * @param paramOverride 调用方显式 override(最高优先级)
102
- * @param ctxModel 主 agent 当前模型(兜底,直接透传)
103
- */
104
- export function resolveModel(
105
- agentConfig: AgentConfig | undefined,
106
- modelRegistry: ModelRegistryLike,
107
- paramOverride?: { model?: string; thinkingLevel?: string },
108
- ctxModel?: ModelInfo,
109
- ): ResolvedModel {
110
- // 1. paramOverride(最高优先级)。显式指定但 lookup/auth 失败 → 直接抛错,
111
- // 不降级到下层(避免「以为用了 X 实际用 Y」的静默错误)。
112
- if (paramOverride?.model) {
113
- return lookupAndResolve(
114
- paramOverride.model,
115
- paramOverride.thinkingLevel ?? agentConfig?.thinkingLevel,
116
- modelRegistry,
117
- "paramOverride",
118
- );
119
- }
120
-
121
- // 2. agentConfig.model(agent 作者指定)。同样显式 → 失败即抛错。
122
- if (agentConfig?.model) {
123
- return lookupAndResolve(
124
- agentConfig.model,
125
- agentConfig.thinkingLevel,
126
- modelRegistry,
127
- "agentConfig",
128
- );
129
- }
130
-
131
- // 3. 主 agent model(直接透传)。无显式 thinking → 兜底最高可用档。
132
- if (ctxModel) {
133
- return {
134
- model: ctxModel,
135
- thinkingLevel: paramOverride?.thinkingLevel ?? agentConfig?.thinkingLevel
136
- ?? maxThinkingForModel(ctxModel),
137
- };
138
- }
139
-
140
- // 全部不可用 → 列出可用模型辅助调试
141
- const available = modelRegistry.getAvailable().map((m) => `${m.provider}/${m.id}`);
142
- throw new Error(
143
- `No available model. Main agent has no active model, and no override was resolved.` +
144
- (available.length > 0
145
- ? `\nAvailable models:\n ${available.slice(0, MODEL_LIST_LIMIT).join("\n ")}`
146
- : ""),
147
- );
148
- }
149
-
150
- /**
151
- * lookup + auth 校验 + thinkingLevel clamp。显式指定但失败 → 抛错(不降级)。
152
- *
153
- * 错误信息区分两种失败(避免误导排查方向):
154
- * - model 不存在 → 提示检查拼写 + 列出相近可用 model
155
- * - model 存在但 auth 未配置 → 提示在 models.json 配置鉴权
156
- */
157
- function lookupAndResolve(
158
- modelStr: string,
159
- requestedThinking: string | undefined,
160
- registry: ModelRegistryLike,
161
- source: "paramOverride" | "agentConfig",
162
- ): ResolvedModel {
163
- const model = lookupModel(modelStr, registry);
164
- if (!model) {
165
- throw new Error(
166
- `Model "${modelStr}" (${source}) not found in registry. ` +
167
- suggestSimilarModels(modelStr, registry),
168
- );
169
- }
170
- if (!registry.hasConfiguredAuth(model)) {
171
- throw new Error(
172
- `Model "${modelStr}" (${source}) exists but auth is not configured. ` +
173
- `Configure auth in models.json or switch to an authorized model.`,
174
- );
175
- }
176
- return {
177
- model,
178
- // 无显式请求时兜底「模型最高可用档」(不落 pi 默认 medium)。
179
- thinkingLevel: resolveThinkingLevel(model, requestedThinking ?? maxThinkingForModel(model)),
180
- };
181
- }
182
-
183
- /**
184
- * subagent 默认 thinking:模型最高可用档。
185
- *
186
- * - thinkingLevelMap 配置了级别 → map 中最高档(模型显式配置 "max" 时即 max)
187
- * - reasoning 但无 map → "xhigh"(pi 合法最高档;"max" 非 pi 合法值——
188
- * spawn 侧 model:"max" 后缀会被 pi 判为非法 thinking 后缀导致 model 解析失败,
189
- * 故无 map 时不能直接用 "max")
190
- * - 非 reasoning 模型 → undefined(不支持 thinking)
191
- */
192
- function maxThinkingForModel(
193
- model: { reasoning: boolean; thinkingLevelMap?: Record<string, unknown> },
194
- ): string | undefined {
195
- const levels = availableThinkingLevels(model);
196
- if (levels.length > 0) return levels[levels.length - 1];
197
- return model.reasoning ? "xhigh" : undefined;
198
- }
199
-
200
- /**
201
- * 解析 "provider/modelId" 并查 registry。
202
- *
203
- * 容错:剥离尾部 ":thinkingLevel" 后缀(off/minimal/low/medium/high/xhigh)。
204
- * 原因:LLM 常把平台复合标识 "provider/modelId:thinkingLevel"(如
205
- * "deepseek-router/ds-pro:xhigh")整体当 model 参数传入。registry 仅存
206
- * "provider/modelId"(无后缀),不剥离则 modelId="ds-pro:xhigh" 查不到。
207
- * 剥离后 thinkingLevel 仍由独立的 thinkingLevel 参数/resolveThinkingLevel 处理。
208
- *
209
- * modelId 可含 /,按第一个 / 分割 provider 与 modelId。
210
- */
211
- function lookupModel(modelStr: string, registry: ModelRegistryLike): ModelInfo | undefined {
212
- const cleanStr = stripThinkingSuffix(modelStr);
213
- const idx = cleanStr.indexOf("/");
214
- if (idx <= 0) return undefined;
215
- return registry.find(cleanStr.slice(0, idx), cleanStr.slice(idx + 1));
216
- }
217
-
218
- /**
219
- * 剥离模型字符串尾部 ":thinkingLevel" 后缀(如 "ds-pro:xhigh" → "ds-pro")。
220
- * 仅匹配合法 thinking level,避免误剥 "foo:bar" 这类无关冒号。
221
- * 返回去除后缀的字符串;无后缀则原样返回。
222
- */
223
- function stripThinkingSuffix(modelStr: string): string {
224
- // THINKING_ORDER 含 off/minimal/low/medium/high/xhigh,按长度降序拼正则避免短串误匹配
225
- const alt = THINKING_ORDER.slice().sort((a, b) => b.length - a.length).join("|");
226
- return modelStr.replace(new RegExp(`:(${alt})$`), "");
227
- }
228
-
229
- /**
230
- * 为 not-found 错误生成「相近可用 model」建议,辅助定位拼写错误。
231
- * 策略:取 provider/modelId 的末段,与每个可用 model 的末段做小写包含匹配,
232
- * 命中则列出。无命中则列出前 N 个全部可用 model(兜底)。空 registry 不列。
233
- */
234
- function suggestSimilarModels(modelStr: string, registry: ModelRegistryLike): string {
235
- const available = registry.getAvailable();
236
- if (available.length === 0) return "Registry has no available models.";
237
- const target = modelStr.split("/").pop()?.toLowerCase() ?? "";
238
- // ponytail: 末段子串包含足够定位拼写错误,无需编辑距离/相似度库
239
- const similar = available
240
- .filter((m) => m.id.toLowerCase().includes(target) || target.includes(m.id.toLowerCase()))
241
- .map((m) => `${m.provider}/${m.id}`)
242
- .slice(0, MODEL_LIST_LIMIT);
243
- const list = similar.length > 0 ? similar : available.slice(0, MODEL_LIST_LIMIT).map((m) => `${m.provider}/${m.id}`);
244
- return `Check the model string (maybe a typo, or a ":thinkingLevel" suffix that should be passed via the thinkingLevel param instead). Similar available models:\n ${list.join("\n ")}`;
245
- }
246
-
247
- /**
248
- * 从 model.thinkingLevelMap 提取可用级别,clamp 到最高可用。
249
- * model.reasoning === false → undefined(不支持 thinking)
250
- */
251
- function resolveThinkingLevel(
252
- model: { reasoning: boolean; thinkingLevelMap?: Record<string, unknown> },
253
- requested?: string,
254
- ): string | undefined {
255
- const levels = availableThinkingLevels(model);
256
- if (levels.length === 0) return model.reasoning ? requested : undefined;
257
- if (requested && levels.includes(requested)) return requested;
258
- // requested 不可用 → 降级到最高可用
259
- return levels[levels.length - 1];
260
- }
261
-
262
- /**
263
- * 列出 model 实际支持的 thinking level(升序)。
264
- *
265
- * - model.reasoning === false → [] (不支持 thinking)
266
- * - 无 thinkingLevelMap → [] (无级别信息,调用方按需透传)
267
- * - 有 map → THINKING_ORDER 中 map[lvl] != null 的子集(保留升序)
268
- */
269
- export function availableThinkingLevels(
270
- model: { reasoning: boolean; thinkingLevelMap?: Record<string, unknown> },
271
- ): readonly string[] {
272
- if (!model.reasoning) return [];
273
- const map = model.thinkingLevelMap;
274
- if (!map) return [];
275
- return THINKING_ORDER.filter((lvl) => map[lvl] != null);
276
- }
@@ -1,260 +0,0 @@
1
- // src/execution/notifier.ts
2
- //
3
- // Background 完成回注主对话。sync 不用(调用方还在 await,结果直接返回)。
4
- //
5
- // 职责(迁移后,U3):
6
- // - buildLlmContent:格式化通知文案(本文件唯一逻辑职责)
7
- // - createNotifier:薄工厂,装配 @xyz-agent/session-delivery 内核
8
- // - 合并窗口 / 去重 / 退避 / flush 全部委托内核
9
- //
10
- // 投递通道:内核 → pi.sendMessage({ deliverAs:"steer", triggerTurn:true }) 注入——
11
- // 当前 turn 结束后唤醒父 agent 处理结果(steer 不打断 streaming、不锁滚动)
12
-
13
- import { createDelivery, type DeliveryHandle, type DeliveryPort } from "@xyz-agent/session-delivery";
14
-
15
- /**
16
- * 一条待发送的完成通知记录。
17
- * SP-1: done/failed/crashed 合并为 closed + closedReason L2 子枚举。
18
- */
19
- export interface BgNotifyRecord {
20
- id: string;
21
- /**
22
- * 完成状态。v4 B-1 两态收敛:closed(终态,含 cancelled,closedReason 表达 L2 原因)
23
- * 或 running(对话模式轮次完成,旧 idle 折入 running,携带本轮结果送回主 agent)。
24
- * toNotifyRecord 守卫放行后经此联合穷尽。
25
- */
26
- status: "running" | "closed";
27
- /** L2 关闭原因子枚举(仅 status="closed" 时有意义)。供通知文案按需展示。 */
28
- closedReason?: import("./types.ts").ClosedReason;
29
- agent: string;
30
- /** 执行所用 model(RecordSnapshot.model),用于完成通知显示。 */
31
- model?: string;
32
- result?: string;
33
- error?: string;
34
- startedAt: number;
35
- endedAt: number | undefined;
36
- /**
37
- * 对话轮次计数(仅 idle 有意义)。dedup key 按 `id:round` 去重——对话模式每轮 round
38
- * 不同,60s 内多轮不被吞;非 chatMode round 恒定(0/undefined),key 同旧 id 行为不变。
39
- */
40
- round?: number;
41
- /** [MF#1] worktree 模式下子 agent 改动的 patch 路径(worktree 外,cleanup 后留存)。
42
- * done 时通知文本显式提示 `git apply`,否则 background 子 agent 在隔离 worktree 的改动
43
- * 会静默丢失——父 LLM 不知 patch 路径,无法应用。 */
44
- patchFile?: string;
45
- /** [wave2] 子 agent session 文件路径(增量语义的全文恢复通道)。
46
- * 仅 chatMode 透传(toNotifyRecord 条件透传)——轮次/完成通知末尾追加
47
- * "Full transcript: <path>" 指针行,父 LLM 可按需读全文;one-shot 不透传,
48
- * 通知输出逐字节不变。缺失时 buildLlmContent 省略整行。 */
49
- sessionFile?: string;
50
- /** [C-2] close 终态通知的轮次统计(文案 "completed after N rounds." 用)。
51
- * 仅 chatMode close 语义(notifyClosed)构造时携带——此时 dedup 身份 round 已被
52
- * 置 undefined(与轮次通知的 id:round key 区分,终态不被吞),轮数改由本字段进
53
- * 文案。one-shot 完成通知不设置,文案保持 "completed. Result:" 逐字节(G4)。 */
54
- totalRounds?: number;
55
- }
56
-
57
- /** notifier 依赖的宿主最小接口(解耦,便于测试)。
58
- * 迁移后:仅用于构造 DeliveryPort 的底层依赖。 */
59
- export interface NotifierHost {
60
- /** 注入消息到主对话。 */
61
- sendMessage(
62
- message: { customType: string; content: string; display: boolean; details?: unknown },
63
- options?: { triggerTurn?: boolean; deliverAs?: "steer" | "followUp" | "nextTurn" },
64
- ): void;
65
- /** 是否还有 running 的 background 任务(用于滑动窗口立即 flush 判断)。 */
66
- hasRunningBackground(): boolean;
67
- /** 主 agent 是否空闲(非 streaming)。可选:未注入时 flush 不 gate。 */
68
- isIdle?: () => boolean;
69
- /**
70
- * 原生 settled 事件订阅能力(D8):注册 handler 监听主 agent settled 边沿。
71
- * 无退订语义(pi 0.84.1 的 `pi.on(...)` 全部重载返回 void、无 off——实装锚点:
72
- * node_modules `@earendil-works/pi-coding-agent` dist/core/extensions/types.d.ts
73
- * `on()` 系列重载,0.84.1 实测)——退订由本模块的 disposed
74
- * 标志包装兑现(见下方 port 装配)。可选:未注入时内核退化退避轮询(busy 消息
75
- * 靠退避达上限强发,不走 settled 边沿驱动)。
76
- */
77
- onAgentSettled?(handler: () => void): void;
78
- }
79
-
80
- /** 发送给主对话的 customType(bg-notify-render 消费)。 */
81
- const NOTIFY_CUSTOM_TYPE = "subagent-bg-notify";
82
-
83
- /**
84
- * 将 BgNotifyRecord 格式化为 LLM 可读的 notification content。
85
- *
86
- * 模块内唯一消费方是下方 createNotifier 的 notify()(预格式化后传 delivery.send,
87
- * 内核只做拼接——多条以 "\n\n---\n\n" join)。
88
- */
89
- function buildLlmContent(record: BgNotifyRecord): string {
90
- const agent = record.agent;
91
- const id = record.id;
92
- // [wave2 指针行] 增量语义下轮次通知只携带本轮增量,异步 flush 窗口丢失时不可重发
93
- //(见 subagent-service.ts onRoundSettled 注释),恢复通道是 session 文件全文。
94
- // 仅 chatMode 透传 sessionFile,one-shot 通知不含该行;cancelled/gc-failed 不追加
95
- //(无成功结果可读,指针无意义);缺失时省略整行(追加空串 = 输出逐字节不变)。
96
- const transcriptPointer = record.sessionFile
97
- ? `\n\nFull transcript: ${record.sessionFile}`
98
- : "";
99
- switch (record.status) {
100
- case "closed": {
101
- // v4 B-1: closed 统一终态(含 cancelled)。按 closedReason 派生通知文案。
102
- const reason = record.closedReason ?? "gc";
103
- if (reason === "cancelled") {
104
- return `Subagent "${agent}" (${id}) cancelled.`;
105
- }
106
- // 失败场景(gc + 有 error):展示错误。判定必须先于 patchFile——失败轮也会写
107
- // patchFile(doFinalizeRecord Step 0 对 worktreeHandle 无条件 collectPatch),若
108
- // patch 分支在前,gc 失败 + worktree 并存时 LLM 被告知 completed。顺序与三处
109
- // 同构契约的另外两处一致(shared/subagent.ts deriveClosedDisplay、
110
- // bg-notify-render.ts renderRecordLines:cancelled → gc+error → patch/result)。
111
- if (record.error && reason === "gc") {
112
- return `Subagent "${agent}" (${id}) failed: ${record.error}`;
113
- }
114
- // 成功完成(user-close)或通用结束(gc/parent-shutdown 等):展示结果。
115
- // [C-2] chatMode close 终态通知附轮次统计(设计 D2 路径①"completed after N rounds")。
116
- // totalRounds 仅 close 语义携带(notifyClosed);one-shot 完成通知不设置(round 无轮次
117
- // 语义),文案保持 "completed. Result:" 逐字节(G4 硬约束,one-shot 字节锁测试锚定)。
118
- const roundsSuffix =
119
- record.totalRounds != null && record.totalRounds > 0
120
- ? ` after ${record.totalRounds} round${record.totalRounds === 1 ? "" : "s"}`
121
- : "";
122
- const base = `Subagent "${agent}" (${id}) completed${roundsSuffix}. Result:\n${record.result ?? "(empty)"}`;
123
- if (record.patchFile) {
124
- // [wave2 review] 长 return 拆行:模板串内不可直接换行(会改变输出内容),提取 patchHint 中转变量
125
- const patchHint = `\n\nThis subagent ran in an isolated worktree; its file changes were captured as a patch:\n ${record.patchFile}\nTo bring these changes into the current repo, run: \`git apply ${record.patchFile}\``;
126
- return `${base}${patchHint}${transcriptPointer}`;
127
- }
128
- return `${base}${transcriptPointer}`;
129
- }
130
- case "running":
131
- // v4 B-1: 对话模式轮次完成(旧 idle 折入 running):携带本轮结果送回主 agent,等待下一轮 message。
132
- return `Subagent "${agent}" (${id}) finished a round. Reply:\n${record.result ?? "(empty)"}${transcriptPointer}`;
133
- }
134
- }
135
-
136
- /**
137
- * Background 完成通知器接口(迁移后由内核实现)。
138
- *
139
- * 保持与旧 BgNotifier 类相同的公共 API,避免消费方(subagent-service)改动面过大。
140
- */
141
- export interface BgNotifier {
142
- /** 入队一条完成通知(去重 + 合批窗口合并)。dispose 后短路。 */
143
- notify(record: BgNotifyRecord): void;
144
- /** 立即 flush(session_shutdown 调用,防丢失)。 */
145
- flushPendingNotifications(): void;
146
- /** session 结束:清队列,dispose 内核 handle。 */
147
- dispose(): void;
148
- /** /resume /fork /new 后复活。 */
149
- revive(): void;
150
- }
151
-
152
- /**
153
- * 创建 Background 完成通知器(薄工厂,装配 @xyz-agent/session-delivery 内核)。
154
- *
155
- * 内核接管:gate(isIdle 退避)/ 合批窗口(滑动 60s)/ dedup(按 id:round)/ flush / shutdown flush。
156
- * 本函数职责:将 BgNotifyRecord → DeliveryMessage 映射 + buildLlmContent 预格式化。
157
- *
158
- * @param host 宿主能力注入(pi.sendMessage + hasRunningBackground + isIdle)
159
- * @returns BgNotifier 接口(与旧类同形)
160
- */
161
- export function createNotifier(host: NotifierHost): BgNotifier {
162
- let disposed = false;
163
-
164
- // 构造 DeliveryPort:intent → pi 参数翻译在适配器内(D3)
165
- const port: DeliveryPort = {
166
- supportedPayloads: ["custom"],
167
- isIdle: () => {
168
- if (host.isIdle) {
169
- return host.isIdle();
170
- }
171
- // 未注入 isIdle → 视为 idle(不 gate,向后兼容旧 host)
172
- return true;
173
- },
174
- hasPendingMessages: () => false, // notifier 不关心 hasPendingMessages
175
- // D8(must-fix #4):settled 边沿驱动装配——内核 busy 入队后由 settled 事件唤醒
176
- // flush(watch-dog 兜底事件丢失),替代无订阅时的退避轮询。host 只注入原生订阅
177
- // 能力;disposed 标志包装(兑现退订语义——pi.on 返回 void 且无 off)在此完成。
178
- subscribeSettled:
179
- host.onAgentSettled === undefined
180
- ? undefined
181
- : (cb) => {
182
- let disposed = false;
183
- host.onAgentSettled?.(() => {
184
- if (!disposed) cb();
185
- });
186
- return () => {
187
- disposed = true;
188
- };
189
- },
190
- send: (msg, intent) => {
191
- host.sendMessage(
192
- {
193
- customType: NOTIFY_CUSTOM_TYPE,
194
- content: msg.payload.content,
195
- display: true,
196
- details: msg.payload.kind === "custom" ? msg.payload.details : undefined,
197
- },
198
- intent === "interrupt-at-turn-boundary"
199
- ? { triggerTurn: true, deliverAs: "steer" }
200
- : { triggerTurn: true, deliverAs: "followUp" },
201
- );
202
- },
203
- };
204
-
205
- // #5(must-fix):内核 handle 的 disposed 不可逆——dispose 后 revive 必须重建 handle,
206
- // 否则 revive 后所有 notify() 被内核静默吞(外层标志复位救不回已销毁的内核)。
207
- // revive = 新生命周期:合批窗口 / 在途批次 / dedup LRU 随重建自然复位(可接受)。
208
- const createHandle = (): DeliveryHandle =>
209
- createDelivery(port, {
210
- intent: "interrupt-at-turn-boundary", // D3:turn 边界抢占(F1 教训内化)
211
- mergeWindowMs: 60_000, // 滑动窗口合批(继承 MERGE_WINDOW_MS=60s)
212
- mergeHoldActive: () => host.hasRunningBackground(), // D4 must-fix #1:禁止用 isIdle 代替
213
- busyPolicy: "retry-force", // settled 边沿驱动 + 退避达上限强发
214
- backoff: { ms: 100, max: 50 }, // 继承 FLUSH_BACKOFF_MS/MAX
215
- // dedup LRU:语义与旧 DEDUP_TTL_MS=60s **不同**——按 key 永久去重(仅 LRU 逐出后
216
- // 同 key 可再入)。当前 key 空间(id / id:round,id 每 spawn 唯一)无实际差异;
217
- // 后续复用方勿按「60s 内不重复」假设接入(同 key 通知会被永久吞)。
218
- dedupe: { maxKeys: 1000 },
219
- });
220
- let handle: DeliveryHandle = createHandle();
221
-
222
- return {
223
- notify(record: BgNotifyRecord): void {
224
- if (disposed) return;
225
-
226
- // dedup key:idle(对话模式每轮完成)按 id:round 去重——不同轮次不互相掩蔽;
227
- // 非 idle(closed/cancelled)round 恒定 undefined,key 同旧行为不变。
228
- const dedupeKey = record.round != null ? `${record.id}:${record.round}` : record.id;
229
-
230
- handle.send({
231
- payload: {
232
- kind: "custom",
233
- customType: NOTIFY_CUSTOM_TYPE,
234
- content: buildLlmContent(record),
235
- display: true,
236
- details: record,
237
- },
238
- dedupeKey,
239
- });
240
- },
241
-
242
- flushPendingNotifications(): void {
243
- handle.flush();
244
- },
245
-
246
- dispose(): void {
247
- disposed = true;
248
- handle.dispose();
249
- },
250
-
251
- revive(): void {
252
- disposed = false;
253
- // #5:内核 disposed 不可逆——revive 必须重建 handle(/resume /fork /new 后的
254
- // session_start 时序:disposeAll → initSession → revive)。旧 handle 若仍存活
255
- // (首次 session_start 的 revive)dispose 为幂等清理,无副作用。
256
- handle.dispose();
257
- handle = createHandle();
258
- },
259
- };
260
- }
@@ -1,88 +0,0 @@
1
- // src/core/output-collector.ts
2
- //
3
- // 结果收集器(Record + CollectResultArgs → AgentResult)。
4
- //
5
- // 收口设计(2026-06-22):collectResult 全部从 record 读——
6
- // text ← getFullText(record)(聚合 turns[].text,不再读 session.messages)
7
- // turns ← record.turnCount
8
- // toolCalls ← getAllToolCalls(record)(扁平化 turns[].toolCalls)
9
- // usage ← getTotalUsage(record)(聚合 turns[].usageDelta)
10
- //
11
- // 基础层模块:依赖 execution-record(派生函数)+ types。
12
-
13
- import type {
14
- AgentResult,
15
- ExecutionRecord,
16
- ToolCall,
17
- } from "./types.ts";
18
- import {
19
- getAllToolCalls,
20
- getFullText,
21
- getTotalUsage,
22
- } from "./execution-record.ts";
23
-
24
- // ============================================================
25
- // Result 收集
26
- // ============================================================
27
-
28
- /** collectResult 的入参(session 身份 + 执行控制字段,执行内容从 record 读)。 */
29
- export interface CollectResultArgs {
30
- startTime: number;
31
- success: boolean;
32
- error: string | undefined;
33
- sessionId: string;
34
- sessionFile: string | undefined;
35
- }
36
-
37
- /** structured-output tool 名(与 structured-output 扩展 TOOL_NAME 一致,见 session-runner.ts)。 */
38
- const STRUCTURED_OUTPUT_TOOL = "structured-output";
39
-
40
- /**
41
- * 从 toolCalls 提取 structured-output 的 result.details(schema 模式产出)。
42
- * schema enforcement 保证 agent 调过该 tool(漏调会 steer 重试);这里只做逆向提取。
43
- * 未调或无 details 返回 undefined。
44
- *
45
- * 导出以便直接单测(纯函数契约)。
46
- */
47
- export function extractParsedOutput(toolCalls: ToolCall[]): unknown {
48
- for (let i = toolCalls.length - 1; i >= 0; i--) {
49
- const tc = toolCalls[i]!;
50
- if (tc.toolName === STRUCTURED_OUTPUT_TOOL && tc.result?.details !== undefined) {
51
- return tc.result.details;
52
- }
53
- }
54
- return undefined;
55
- }
56
-
57
- /**
58
- * 从 record + args 组装 AgentResult。每个字段来源单一且收口于 record:
59
- * text ← getFullText(record)(聚合 turns[].text,单一数据源)
60
- * turns ← record.turnCount
61
- * toolCalls ← getAllToolCalls(record)(扁平化 turns[].toolCalls)
62
- * usage ← getTotalUsage(record)(聚合 turns[].usageDelta,全零则 undefined)
63
- * parsedOutput ← extractParsedOutput(toolCalls)
64
- *
65
- * startTime 算 durationMs。
66
- *
67
- * success 双来源判定(调用方传入):
68
- * ① session.prompt() 抛错 → args.success=false
69
- * ② prompt 成功但 record.lastError 非空(message_end stopReason=error)→ success=false
70
- */
71
- export function collectResult(
72
- record: ExecutionRecord,
73
- args: CollectResultArgs,
74
- ): AgentResult {
75
- const toolCalls = getAllToolCalls(record);
76
- return {
77
- text: getFullText(record),
78
- turns: record.turnCount,
79
- durationMs: Date.now() - args.startTime,
80
- success: args.success,
81
- error: args.error,
82
- sessionId: args.sessionId,
83
- toolCalls,
84
- usage: getTotalUsage(record),
85
- sessionFile: args.sessionFile,
86
- parsedOutput: extractParsedOutput(toolCalls),
87
- };
88
- }