@zhushanwen/pi-subagent-workflow 8.6.0 → 8.8.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 (364) hide show
  1. package/README.md +5 -11
  2. package/package.json +13 -20
  3. package/relay/relay.mjs +1 -1
  4. package/skills/workflow-script-format/SKILL.md +32 -13
  5. package/src/host/__tests__/pi-host.test.ts +235 -0
  6. package/src/host/pi-host.ts +163 -0
  7. package/src/index.ts +141 -138
  8. package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
  9. package/src/injectors/__tests__/engine-section-stability.test.ts +343 -0
  10. package/src/injectors/__tests__/model-list-injector.test.ts +18 -21
  11. package/src/injectors/__tests__/subagent-list-injector.test.ts +59 -19
  12. package/src/injectors/__tests__/workflow-list-injector.test.ts +31 -17
  13. package/src/injectors/engine-awareness.ts +119 -0
  14. package/src/injectors/model-list-injector.ts +15 -58
  15. package/src/injectors/subagent-list-injector.ts +56 -114
  16. package/src/injectors/workflow-list-injector.ts +37 -70
  17. package/src/interface/__tests__/detectors.test.ts +48 -37
  18. package/src/interface/__tests__/subagent-tool-path-guard.test.ts +2 -2
  19. package/src/interface/__tests__/subagent-tool-prompt.test.ts +6 -3
  20. package/src/interface/__tests__/tool-workflow-run-builtin-name.test.ts +216 -0
  21. package/src/interface/__tests__/tool-workflow-script-generate.test.ts +17 -6
  22. package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +38 -2
  23. package/src/interface/bg-notify-render.ts +7 -17
  24. package/src/interface/command-actions.ts +5 -15
  25. package/src/interface/commands.ts +4 -4
  26. package/src/interface/format.ts +17 -6
  27. package/src/interface/gui-mappers.ts +18 -22
  28. package/src/interface/helpers.ts +9 -130
  29. package/src/interface/list-component.ts +5 -5
  30. package/src/interface/list-shared.ts +3 -3
  31. package/src/interface/list-view.ts +3 -3
  32. package/src/interface/subagent-actions.ts +66 -439
  33. package/src/interface/subagent-tool-schema.ts +21 -17
  34. package/src/interface/subagent-tool.ts +12 -7
  35. package/src/interface/subagents.ts +4 -4
  36. package/src/interface/tool-render.ts +37 -15
  37. package/src/interface/tool-workflow-script.ts +34 -76
  38. package/src/interface/tool-workflow.ts +57 -94
  39. package/src/interface/views/WorkflowsView.ts +8 -16
  40. package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +3 -3
  41. package/src/interface/views/__tests__/detail-content-session-file.test.ts +2 -2
  42. package/src/interface/views/detail-content.ts +4 -4
  43. package/src/interface/views/format.ts +23 -62
  44. package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +137 -225
  45. package/agents/analyst.md +0 -61
  46. package/agents/coder.md +0 -70
  47. package/agents/debugger.md +0 -67
  48. package/agents/doc-reviewer.md +0 -50
  49. package/agents/explorer.md +0 -64
  50. package/agents/general-purpose.md +0 -32
  51. package/agents/orchestrator.md +0 -63
  52. package/agents/planner.md +0 -54
  53. package/agents/researcher.md +0 -65
  54. package/agents/reviewer.md +0 -74
  55. package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +0 -53
  56. package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +0 -1
  57. package/src/execution/__tests__/agent-registry.test.ts +0 -363
  58. package/src/execution/__tests__/agent-result-mapper.test.ts +0 -150
  59. package/src/execution/__tests__/alive-store.test.ts +0 -147
  60. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  61. package/src/execution/__tests__/before-agent-start-injection.test.ts +0 -132
  62. package/src/execution/__tests__/bg-notify-render.test.ts +0 -329
  63. package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
  64. package/src/execution/__tests__/chat-engine-routing.test.ts +0 -601
  65. package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +0 -365
  66. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -190
  67. package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +0 -215
  68. package/src/execution/__tests__/concurrency-pool.test.ts +0 -250
  69. package/src/execution/__tests__/config.test.ts +0 -110
  70. package/src/execution/__tests__/conversation-wiring.test.ts +0 -198
  71. package/src/execution/__tests__/crash-recovery.test.ts +0 -320
  72. package/src/execution/__tests__/delivery-methods.test.ts +0 -422
  73. package/src/execution/__tests__/dialog-queue.test.ts +0 -299
  74. package/src/execution/__tests__/epipe-fallback.test.ts +0 -241
  75. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -243
  76. package/src/execution/__tests__/execute-nesting.test.ts +0 -323
  77. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
  78. package/src/execution/__tests__/execution-record.test.ts +0 -1394
  79. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +0 -171
  80. package/src/execution/__tests__/finalize-record.test.ts +0 -368
  81. package/src/execution/__tests__/finalized-marker.test.ts +0 -82
  82. package/src/execution/__tests__/format-schema-instruction.test.ts +0 -169
  83. package/src/execution/__tests__/format.test.ts +0 -458
  84. package/src/execution/__tests__/gc-timer.test.ts +0 -184
  85. package/src/execution/__tests__/get-record-for-action-restart.test.ts +0 -254
  86. package/src/execution/__tests__/gui-mode-dispatch.test.ts +0 -59
  87. package/src/execution/__tests__/helpers/mock-extension-api.ts +0 -30
  88. package/src/execution/__tests__/helpers/spawn-mock.ts +0 -242
  89. package/src/execution/__tests__/host-mode.test.ts +0 -87
  90. package/src/execution/__tests__/index-session-start-identity.test.ts +0 -371
  91. package/src/execution/__tests__/index-session-start.test.ts +0 -672
  92. package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
  93. package/src/execution/__tests__/lifecycle-manager.test.ts +0 -383
  94. package/src/execution/__tests__/lifecycle-predicates.test.ts +0 -116
  95. package/src/execution/__tests__/list-component.test.ts +0 -401
  96. package/src/execution/__tests__/list-fields.test.ts +0 -140
  97. package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
  98. package/src/execution/__tests__/model-resolver.test.ts +0 -465
  99. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +0 -287
  100. package/src/execution/__tests__/nested-visibility.test.ts +0 -325
  101. package/src/execution/__tests__/notifier-flush.test.ts +0 -612
  102. package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
  103. package/src/execution/__tests__/notify-ledger.test.ts +0 -826
  104. package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
  105. package/src/execution/__tests__/output-collector.test.ts +0 -358
  106. package/src/execution/__tests__/parent-child-matrix.test.ts +0 -336
  107. package/src/execution/__tests__/path-encoding.test.ts +0 -104
  108. package/src/execution/__tests__/pi-invocation.test.ts +0 -134
  109. package/src/execution/__tests__/record-store.test.ts +0 -1057
  110. package/src/execution/__tests__/records-cwd-isolation.test.ts +0 -91
  111. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +0 -339
  112. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -273
  113. package/src/execution/__tests__/relay-agent.test.ts +0 -448
  114. package/src/execution/__tests__/relay-env.test.ts +0 -42
  115. package/src/execution/__tests__/resource-policy.test.ts +0 -109
  116. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  117. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -267
  118. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -253
  119. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -687
  120. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  121. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  122. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  123. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -199
  124. package/src/execution/__tests__/sdk-contract.test.ts +0 -273
  125. package/src/execution/__tests__/session-context-resolver.test.ts +0 -167
  126. package/src/execution/__tests__/session-file-gc.test.ts +0 -293
  127. package/src/execution/__tests__/session-pending.test.ts +0 -197
  128. package/src/execution/__tests__/session-reconstructor.test.ts +0 -379
  129. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -178
  130. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -350
  131. package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
  132. package/src/execution/__tests__/spawn-args.test.ts +0 -445
  133. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -189
  134. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  135. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -207
  136. package/src/execution/__tests__/spawned-children.test.ts +0 -92
  137. package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
  138. package/src/execution/__tests__/startup-config-declaration.test.ts +0 -35
  139. package/src/execution/__tests__/status-refactor.test.ts +0 -345
  140. package/src/execution/__tests__/stdin-writer.test.ts +0 -463
  141. package/src/execution/__tests__/stream-sink-retirement.test.ts +0 -261
  142. package/src/execution/__tests__/subagent-service-abort.test.ts +0 -60
  143. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -629
  144. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +0 -180
  145. package/src/execution/__tests__/subagent-service.test.ts +0 -788
  146. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -310
  147. package/src/execution/__tests__/subprocess-agent-runner.test.ts +0 -599
  148. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  149. package/src/execution/__tests__/timeout-integration.test.ts +0 -615
  150. package/src/execution/__tests__/tombstone-store.test.ts +0 -73
  151. package/src/execution/__tests__/tool-action.test.ts +0 -476
  152. package/src/execution/__tests__/truncline-snapshot.test.ts +0 -81
  153. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  154. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  155. package/src/execution/__tests__/ui-channels.test.ts +0 -187
  156. package/src/execution/__tests__/ui-interaction-model.test.ts +0 -67
  157. package/src/execution/__tests__/ui-request-handler-factory.test.ts +0 -370
  158. package/src/execution/__tests__/ui-request-handler.test.ts +0 -204
  159. package/src/execution/__tests__/ui-request-observability.test.ts +0 -114
  160. package/src/execution/__tests__/ui-request-queue.test.ts +0 -133
  161. package/src/execution/__tests__/worktree-manager.test.ts +0 -633
  162. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -229
  163. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +0 -181
  164. package/src/execution/__tests__/worktree-registry.test.ts +0 -199
  165. package/src/execution/agent-registry.ts +0 -199
  166. package/src/execution/agent-result-mapper.ts +0 -90
  167. package/src/execution/alive-store.ts +0 -92
  168. package/src/execution/argv-mirror.ts +0 -113
  169. package/src/execution/best-effort.ts +0 -38
  170. package/src/execution/channel-registry-access.ts +0 -144
  171. package/src/execution/concurrency-pool.ts +0 -116
  172. package/src/execution/config.ts +0 -96
  173. package/src/execution/dialog-queue.ts +0 -330
  174. package/src/execution/engine/__tests__/common/data-dir.test.ts +0 -53
  175. package/src/execution/engine/__tests__/common/errors.test.ts +0 -132
  176. package/src/execution/engine/__tests__/common/event-journal.test.ts +0 -177
  177. package/src/execution/engine/__tests__/common/kill-chain.test.ts +0 -192
  178. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +0 -81
  179. package/src/execution/engine/__tests__/common/persona-router.test.ts +0 -123
  180. package/src/execution/engine/__tests__/common/pool-manager.test.ts +0 -154
  181. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  182. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  183. package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +0 -141
  184. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +0 -109
  185. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +0 -101
  186. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +0 -77
  187. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +0 -104
  188. package/src/execution/engine/__tests__/conformance/contract.relay.test.ts +0 -342
  189. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +0 -201
  190. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +0 -76
  191. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +0 -79
  192. package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -87
  193. package/src/execution/engine/__tests__/engines-declaration.test.ts +0 -36
  194. package/src/execution/engine/__tests__/model-prompt.test.ts +0 -85
  195. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  196. package/src/execution/engine/__tests__/registry.test.ts +0 -120
  197. package/src/execution/engine/__tests__/routing.test.ts +0 -231
  198. package/src/execution/engine/common/data-dir.ts +0 -62
  199. package/src/execution/engine/common/errors.ts +0 -183
  200. package/src/execution/engine/common/event-journal.ts +0 -254
  201. package/src/execution/engine/common/journal-replay.ts +0 -62
  202. package/src/execution/engine/common/kill-chain.ts +0 -221
  203. package/src/execution/engine/common/nesting-guard.ts +0 -50
  204. package/src/execution/engine/common/persona-router.ts +0 -108
  205. package/src/execution/engine/common/pool-manager.ts +0 -226
  206. package/src/execution/engine/common/schema-emulation.ts +0 -189
  207. package/src/execution/engine/common/session-view-projection.ts +0 -51
  208. package/src/execution/engine/engine-discovery.ts +0 -65
  209. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -469
  210. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  211. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  212. package/src/execution/engine/engines/pi/pi-engine.ts +0 -415
  213. package/src/execution/engine/engines/pi/reader.ts +0 -48
  214. package/src/execution/engine/engines/pi/registration.ts +0 -35
  215. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  216. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  217. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  218. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -246
  219. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -228
  220. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  221. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -64
  222. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -127
  223. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -580
  224. package/src/execution/engine/engines/zcode/constants.ts +0 -43
  225. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -39
  226. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  227. package/src/execution/engine/engines/zcode/parser.ts +0 -436
  228. package/src/execution/engine/engines/zcode/preparer.ts +0 -363
  229. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  230. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  231. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -658
  232. package/src/execution/engine/host-task-spec.ts +0 -47
  233. package/src/execution/engine/model-prompt.ts +0 -59
  234. package/src/execution/engine/paths.ts +0 -42
  235. package/src/execution/engine/port.ts +0 -153
  236. package/src/execution/engine/registry.ts +0 -123
  237. package/src/execution/engine/routing.ts +0 -218
  238. package/src/execution/engine/types.ts +0 -309
  239. package/src/execution/execute-options-mapper.ts +0 -112
  240. package/src/execution/execution-record.ts +0 -965
  241. package/src/execution/finalize-record.ts +0 -251
  242. package/src/execution/finalized-marker.ts +0 -51
  243. package/src/execution/get-state-handshake.ts +0 -104
  244. package/src/execution/host-mode.ts +0 -56
  245. package/src/execution/idle-gc.ts +0 -47
  246. package/src/execution/lifecycle-manager.ts +0 -513
  247. package/src/execution/lifecycle-predicates.ts +0 -65
  248. package/src/execution/manifest-store.ts +0 -256
  249. package/src/execution/model-config-service.ts +0 -219
  250. package/src/execution/model-resolver.ts +0 -248
  251. package/src/execution/notifier.ts +0 -330
  252. package/src/execution/notify-ledger.ts +0 -580
  253. package/src/execution/output-collector.ts +0 -228
  254. package/src/execution/path-encoding.ts +0 -60
  255. package/src/execution/pi-invocation.ts +0 -120
  256. package/src/execution/record-entry.ts +0 -132
  257. package/src/execution/record-store.ts +0 -1234
  258. package/src/execution/relay-env.ts +0 -37
  259. package/src/execution/session-context-resolver.ts +0 -64
  260. package/src/execution/session-file-gc.ts +0 -120
  261. package/src/execution/session-pending.ts +0 -164
  262. package/src/execution/session-reconstructor.ts +0 -678
  263. package/src/execution/session-runner.ts +0 -1781
  264. package/src/execution/sessions-index.ts +0 -304
  265. package/src/execution/spawn-event-adapter.ts +0 -363
  266. package/src/execution/stdin-writer.ts +0 -198
  267. package/src/execution/stream-sink.ts +0 -126
  268. package/src/execution/subagent-service.ts +0 -2141
  269. package/src/execution/subprocess-agent-runner.ts +0 -317
  270. package/src/execution/temp-prompt.ts +0 -62
  271. package/src/execution/tombstone-store.ts +0 -72
  272. package/src/execution/turn-limiter.ts +0 -102
  273. package/src/execution/types.ts +0 -973
  274. package/src/execution/ui-channels.ts +0 -216
  275. package/src/execution/ui-interaction-model.ts +0 -48
  276. package/src/execution/ui-request-handler-factory.ts +0 -212
  277. package/src/execution/ui-request-observability.ts +0 -81
  278. package/src/execution/ui-request-queue.ts +0 -184
  279. package/src/execution/worktree-manager.ts +0 -688
  280. package/src/execution/worktree-registry.ts +0 -222
  281. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +0 -349
  282. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -202
  283. package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -152
  284. package/src/orchestration/__tests__/args-validator.test.ts +0 -143
  285. package/src/orchestration/__tests__/config-loader.test.ts +0 -503
  286. package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -809
  287. package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +0 -405
  288. package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +0 -56
  289. package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +0 -166
  290. package/src/orchestration/__tests__/execute-agent-call.test.ts +0 -451
  291. package/src/orchestration/__tests__/jsonl-run-store-corrupt-entry.test.ts +0 -150
  292. package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
  293. package/src/orchestration/__tests__/jsonl-run-store-retention.test.ts +0 -202
  294. package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
  295. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -600
  296. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
  297. package/src/orchestration/__tests__/lifecycle.test.ts +0 -659
  298. package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +0 -95
  299. package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -2025
  300. package/src/orchestration/__tests__/script-lint.test.ts +0 -831
  301. package/src/orchestration/__tests__/skill-discovery.test.ts +0 -201
  302. package/src/orchestration/__tests__/test-mocks.ts +0 -197
  303. package/src/orchestration/__tests__/worker-exit-without-result.test.ts +0 -368
  304. package/src/orchestration/__tests__/worker-host.test.ts +0 -120
  305. package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +0 -164
  306. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +0 -563
  307. package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
  308. package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -129
  309. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -317
  310. package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +0 -110
  311. package/src/orchestration/__tests__/workflows-e2e.test.ts +0 -537
  312. package/src/orchestration/agent-opts-resolver.ts +0 -174
  313. package/src/orchestration/args-validator.ts +0 -127
  314. package/src/orchestration/config-loader.ts +0 -315
  315. package/src/orchestration/error-recovery.ts +0 -1018
  316. package/src/orchestration/execute-agent-call.ts +0 -256
  317. package/src/orchestration/launcher.ts +0 -455
  318. package/src/orchestration/lifecycle.ts +0 -399
  319. package/src/orchestration/models/__tests__/budget.test.ts +0 -307
  320. package/src/orchestration/models/__tests__/trace.test.ts +0 -408
  321. package/src/orchestration/models/agent-call.ts +0 -83
  322. package/src/orchestration/models/budget.ts +0 -118
  323. package/src/orchestration/models/ports.ts +0 -164
  324. package/src/orchestration/models/run-runtime.ts +0 -104
  325. package/src/orchestration/models/run-spec.ts +0 -83
  326. package/src/orchestration/models/run-state.ts +0 -44
  327. package/src/orchestration/models/trace.ts +0 -183
  328. package/src/orchestration/models/types.ts +0 -301
  329. package/src/orchestration/models/workflow-run.ts +0 -254
  330. package/src/orchestration/models/workflow-script-registry.ts +0 -35
  331. package/src/orchestration/models/workflow-script.ts +0 -117
  332. package/src/orchestration/script-lint.ts +0 -766
  333. package/src/orchestration/skill-discovery.ts +0 -115
  334. package/src/orchestration/worker-handle.ts +0 -115
  335. package/src/orchestration/worker-host.ts +0 -98
  336. package/src/orchestration/worker-script-builder.ts +0 -421
  337. package/src/orchestration/workflow-files.ts +0 -85
  338. package/src/orchestration/workflow-script-registry-impl.ts +0 -133
  339. package/src/shared/__tests__/agent-ref.test.ts +0 -34
  340. package/src/shared/__tests__/meta-parser.test.ts +0 -304
  341. package/src/shared/__tests__/model-ref.test.ts +0 -306
  342. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -280
  343. package/src/shared/__tests__/resource-discovery.test.ts +0 -736
  344. package/src/shared/__tests__/resource-meta.test.ts +0 -51
  345. package/src/shared/__tests__/schema-jsonify.test.ts +0 -81
  346. package/src/shared/__tests__/timer-delay.test.ts +0 -61
  347. package/src/shared/agent-event.ts +0 -13
  348. package/src/shared/agent-ref.ts +0 -57
  349. package/src/shared/meta-parser.ts +0 -261
  350. package/src/shared/model-ref.ts +0 -286
  351. package/src/shared/resource-discovery.ts +0 -811
  352. package/src/shared/resource-meta.ts +0 -65
  353. package/src/shared/schema-env.ts +0 -44
  354. package/src/shared/schema-jsonify.ts +0 -58
  355. package/src/shared/timer-delay.ts +0 -54
  356. package/src/shared/xml-injection.ts +0 -35
  357. package/workflows/README.md +0 -81
  358. package/workflows/_shared/agent-refs.cjs +0 -40
  359. package/workflows/chain.js +0 -131
  360. package/workflows/map-reduce.js +0 -174
  361. package/workflows/parallel.js +0 -148
  362. package/workflows/review-fix-loop-utils.cjs +0 -1309
  363. package/workflows/review-fix-loop.js +0 -1404
  364. package/workflows/scatter-gather.js +0 -178
@@ -1,248 +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
- // [U1 ModelRef 全等裁决] THINKING_ORDER / ThinkingLevel / strip / 裁决入口收拢到
12
- // shared/model-ref.ts(单一权威),此处 re-export 保持既有 import 路径不变
13
- //(subagent-tool / tool-workflow 的 schema 枚举从本模块派生)。
14
- import {
15
- THINKING_ORDER,
16
- assertCanonicalModelRef,
17
- modelRefFromVerified,
18
- } from "../shared/model-ref";
19
-
20
- export { THINKING_ORDER };
21
- export type { ThinkingLevel } from "../shared/model-ref";
22
-
23
- /** 解析失败时错误信息列出的可用模型上限(防超长错误信息)。 */
24
- const MODEL_LIST_LIMIT = 20;
25
-
26
- /**
27
- * ModelRegistry 的最小接口(duck-typed,测试可 mock)。
28
- * 字段结构与 Pi SDK 的 ctx.modelRegistry 对齐。
29
- */
30
- export interface ModelRegistryLike {
31
- /** 返回所有已配置鉴权的可用模型。 */
32
- getAvailable(): ModelInfo[];
33
- /** 按 (provider, modelId) 查找。 */
34
- find(provider: string, modelId: string): ModelInfo | undefined;
35
- /** 校验模型鉴权是否就绪。 */
36
- hasConfiguredAuth(model: unknown): boolean;
37
- }
38
-
39
- /**
40
- * 模型信息(registry 返回元素 / ctx.model 鸭子类型兼容)。
41
- * ctx.model(SDK Model<Api>)是此类型的超集,运行时直接当 ModelInfo 用。
42
- */
43
- export interface ModelInfo {
44
- id: string;
45
- name: string;
46
- provider: string;
47
- reasoning: boolean;
48
- thinkingLevelMap?: Record<string, unknown>;
49
- contextWindow?: number;
50
- }
51
-
52
- /** agent .md frontmatter 解析结果。 */
53
- export interface AgentConfig {
54
- /** agent 名(文件名 basename)。 */
55
- name: string;
56
- /** system prompt(markdown 正文)。 */
57
- systemPrompt: string;
58
- /** tool allowlist(三层过滤之一)。 */
59
- tools?: string[];
60
- /** 默认模型 override("provider/modelId")。agent 作者显式指定。 */
61
- model?: string;
62
- /** 默认 thinkingLevel override。 */
63
- thinkingLevel?: string;
64
- /** 默认 background 模式(true 时无显式 wait 走 background)。 */
65
- defaultBackground?: boolean;
66
- /**
67
- * 执行引擎 id(agent .md frontmatter engine 字段,D9 per-agent 主通道)。
68
- * 解析期已对注册表校验(未注册 id 在 agent-registry 抛 EngineNotFoundError);
69
- * 执行侧(P4 路由层)按 调用参数 > 本字段 > 全局默认 三层取值。
70
- */
71
- engine?: string;
72
- }
73
-
74
- /** 解析结果(model 实例 + 生效的 thinkingLevel)。 */
75
- export interface ResolvedModel {
76
- model: ModelInfo;
77
- thinkingLevel: string | undefined;
78
- }
79
-
80
- // ============================================================
81
- // 常量
82
- // ============================================================
83
-
84
- // MODEL_LIST_LIMIT 与 THINKING_ORDER 随 suggestSimilarModels/lookupModel 一并迁入
85
- // shared/model-ref.ts(U1 裁决单一入口)。
86
-
87
- // ============================================================
88
- // 解析
89
- // ============================================================
90
-
91
- /**
92
- * 三层模型解析:
93
- *
94
- * ╔═══════════════════════════════════════════════════════════════╗
95
- // ║ 优先级(高→低): ║
96
- // ║ 1. paramOverride.model (调用方显式指定,tool 参数) ║
97
- // ║ 2. agentConfig.model (agent .md frontmatter) ║
98
- // ║ 3. ctxModel (主 agent 当前模型,直接透传) ║
99
- // ║ ║
100
- // ║ 1/2 级查 registry + auth 校验;3 级无需 lookup(主 agent 在用 ║
101
- // ║ 说明 auth OK)。thinkingLevel 无显式指定时兜底「模型最高可用档」║
102
- // ║ (maxThinkingForModel,含 "max" 时用 max)——不落回 pi 默认 ║
103
- // ║ medium,subagent 任务需要最大推理深度。 ║
104
- // ║ ║
105
- // ║ 显式指定但 lookup/auth 失败 → 抛错(不静默降级到主 agent, ║
106
- // ║ 因为用户明确要求了某个 model,降级会造成「以为用了 X 实际用 Y」║
107
- // ╚════════════════════════════════════════════════════════════════╝
108
- *
109
- * @param agentConfig agent .md 解析结果(查 model override + thinkingLevel)
110
- * @param modelRegistry registry(仅 override 路径用)
111
- * @param paramOverride 调用方显式 override(最高优先级)
112
- * @param ctxModel 主 agent 当前模型(兜底,直接透传)
113
- */
114
- export function resolveModel(
115
- agentConfig: AgentConfig | undefined,
116
- modelRegistry: ModelRegistryLike,
117
- paramOverride?: { model?: string; thinkingLevel?: string },
118
- ctxModel?: ModelInfo,
119
- ): ResolvedModel {
120
- // 1. paramOverride(最高优先级)。显式指定但 lookup/auth 失败 → 直接抛错,
121
- // 不降级到下层(避免「以为用了 X 实际用 Y」的静默错误)。
122
- if (paramOverride?.model) {
123
- return lookupAndResolve(
124
- paramOverride.model,
125
- paramOverride.thinkingLevel ?? agentConfig?.thinkingLevel,
126
- modelRegistry,
127
- "paramOverride",
128
- );
129
- }
130
-
131
- // 2. agentConfig.model(agent 作者指定)。同样显式 → 失败即抛错。
132
- if (agentConfig?.model) {
133
- return lookupAndResolve(
134
- agentConfig.model,
135
- agentConfig.thinkingLevel,
136
- modelRegistry,
137
- "agentConfig",
138
- );
139
- }
140
-
141
- // 3. 主 agent model(直接透传)。无显式 thinking → 兜底最高可用档。
142
- // [U1 D2 豁免口径] ctxModel 是运行时已验证的 ModelInfo 对象,豁免 registry 存在性
143
- // 复查与 auth 校验;但孪生守卫同等适用(registry 含大小写孪生时拒绝放行,modelRefFromVerified)。
144
- if (ctxModel) {
145
- modelRefFromVerified(ctxModel, modelRegistry);
146
- return {
147
- model: ctxModel,
148
- thinkingLevel: paramOverride?.thinkingLevel ?? agentConfig?.thinkingLevel
149
- ?? maxThinkingForModel(ctxModel),
150
- };
151
- }
152
-
153
- // 全部不可用 → 列出可用模型辅助调试
154
- const available = modelRegistry.getAvailable().map((m) => `${m.provider}/${m.id}`);
155
- throw new Error(
156
- `No available model. Main agent has no active model, and no override was resolved.` +
157
- (available.length > 0
158
- ? `\nAvailable models:\n ${available.slice(0, MODEL_LIST_LIMIT).join("\n ")}`
159
- : ""),
160
- );
161
- }
162
-
163
- /**
164
- * lookup + auth 校验 + thinkingLevel clamp。显式指定但失败 → 抛错(不降级)。
165
- *
166
- * [U1 D1] 模型串裁决经 assertCanonicalModelRef 单一入口(strip 后缀 → provider 精确 →
167
- * 全等匹配 → 孪生守卫;未命中同步抛错并附问句式纠错候选)。放行即与 registry 条目全等。
168
- *
169
- * 错误信息区分两种失败(避免误导排查方向):
170
- * - model 非全等(不存在/大小写不符/孪生歧义)→ assertCanonicalModelRef 的问句式报错
171
- * - model 全等命中但 auth 未配置 → 提示在 models.json 配置鉴权
172
- */
173
- function lookupAndResolve(
174
- modelStr: string,
175
- requestedThinking: string | undefined,
176
- registry: ModelRegistryLike,
177
- source: "paramOverride" | "agentConfig",
178
- ): ResolvedModel {
179
- const ref = assertCanonicalModelRef(modelStr, registry, { source });
180
- const model = registry.find(ref.provider, ref.id);
181
- if (!model) {
182
- // 裁决已按 getAvailable 全等命中;find 独立实现(duck-typed mock 可能不同源)时的
183
- // 类型收窄兜底,非预期路径。
184
- throw new Error(
185
- `Model "${modelStr}" (${source}) passed the canonical ref check but registry.find missed it ` +
186
- `(registry snapshot inconsistent). Retry with an exact entry from the available models list.`,
187
- );
188
- }
189
- if (!registry.hasConfiguredAuth(model)) {
190
- throw new Error(
191
- `Model "${modelStr}" (${source}) exists but auth is not configured. ` +
192
- `Configure auth in models.json or switch to an authorized model.`,
193
- );
194
- }
195
- return {
196
- model,
197
- // 无显式请求时兜底「模型最高可用档」(不落 pi 默认 medium)。
198
- thinkingLevel: resolveThinkingLevel(model, requestedThinking ?? maxThinkingForModel(model)),
199
- };
200
- }
201
-
202
- /**
203
- * subagent 默认 thinking:模型最高可用档。
204
- *
205
- * - thinkingLevelMap 配置了级别 → map 中最高档(模型显式配置 "max" 时即 max)
206
- * - reasoning 但无 map → "xhigh"(pi 合法最高档;"max" 非 pi 合法值——
207
- * spawn 侧 model:"max" 后缀会被 pi 判为非法 thinking 后缀导致 model 解析失败,
208
- * 故无 map 时不能直接用 "max")
209
- * - 非 reasoning 模型 → undefined(不支持 thinking)
210
- */
211
- function maxThinkingForModel(
212
- model: { reasoning: boolean; thinkingLevelMap?: Record<string, unknown> },
213
- ): string | undefined {
214
- const levels = availableThinkingLevels(model);
215
- if (levels.length > 0) return levels[levels.length - 1];
216
- return model.reasoning ? "xhigh" : undefined;
217
- }
218
-
219
- /**
220
- * 从 model.thinkingLevelMap 提取可用级别,clamp 到最高可用。
221
- * model.reasoning === false → undefined(不支持 thinking)
222
- */
223
- function resolveThinkingLevel(
224
- model: { reasoning: boolean; thinkingLevelMap?: Record<string, unknown> },
225
- requested?: string,
226
- ): string | undefined {
227
- const levels = availableThinkingLevels(model);
228
- if (levels.length === 0) return model.reasoning ? requested : undefined;
229
- if (requested && levels.includes(requested)) return requested;
230
- // requested 不可用 → 降级到最高可用
231
- return levels[levels.length - 1];
232
- }
233
-
234
- /**
235
- * 列出 model 实际支持的 thinking level(升序)。
236
- *
237
- * - model.reasoning === false → [] (不支持 thinking)
238
- * - 无 thinkingLevelMap → [] (无级别信息,调用方按需透传)
239
- * - 有 map → THINKING_ORDER 中 map[lvl] != null 的子集(保留升序)
240
- */
241
- export function availableThinkingLevels(
242
- model: { reasoning: boolean; thinkingLevelMap?: Record<string, unknown> },
243
- ): readonly string[] {
244
- if (!model.reasoning) return [];
245
- const map = model.thinkingLevelMap;
246
- if (!map) return [];
247
- return THINKING_ORDER.filter((lvl) => map[lvl] != null);
248
- }
@@ -1,330 +0,0 @@
1
- // src/execution/notifier.ts
2
- //
3
- // Background 完成回注主对话。sync 不用(调用方还在 await,结果直接返回)。
4
- //
5
- // 职责(U2 后):
6
- // - buildLlmContent:格式化通知文案(本文件唯一逻辑职责)
7
- // - createNotifier:薄工厂——ledger 装配时(bindNotifyLedgerHost 已注入)走
8
- // 四步生命周期(写账 → courier 边沿投递 → 回执销账 → notifyId 幂等重放,
9
- // notify-ledger.ts);未装配时退回 @xyz-agent/session-delivery 内核路径
10
- // (合并窗口 / 去重 / 退避 / flush 委托内核,旧装配 / 无 ledger 测试兼容)
11
- //
12
- // 投递通道(D5 单通道化):ledger 路径经 courier 在 settled 边沿直达
13
- // pi.sendMessage({triggerTurn:true});内核路径的 port.send 同样只传
14
- // {triggerTurn:true}——steer / followUp / nextTurn 通道已全部删除(nextTurn 的
15
- // 唯一 drain 点在 session.prompt() 内,主 agent 长 streaming 场景下无限期滞留,
16
- // 设计 D5 实测证伪);busy 场景由 ledger(settled 边沿 + isIdle 二次复查)或内核
17
- // settled 订阅驱动在空闲边沿投递。
18
-
19
- import { getLogger } from "@zhushanwen/pi-extension-logger";
20
- import { createDelivery, type DeliveryHandle, type DeliveryPort } from "@xyz-agent/session-delivery";
21
-
22
- import { deriveOutcome } from "./execution-record.ts";
23
- import { getBoundNotifyLedger, NOTIFY_CUSTOM_TYPE } from "./notify-ledger.ts";
24
- import type { ClosedReason, ExecutionOutcome } from "./types.ts";
25
-
26
- /** U4:delivery warn 出口注入用——与 index.ts 共享同一具名 logger 单例。 */
27
- const notifyLogger = getLogger("subagents");
28
-
29
- /**
30
- * 一条待发送的完成通知记录。
31
- * SP-1: done/failed/crashed 合并为 closed + closedReason L2 子枚举。
32
- */
33
- export interface BgNotifyRecord {
34
- id: string;
35
- /**
36
- * 完成状态。v4 B-1 两态收敛:closed(终态,含 cancelled,closedReason 表达 L2 原因)
37
- * 或 running(对话模式轮次完成,旧 idle 折入 running,携带本轮结果送回主 agent)。
38
- * toNotifyRecord 守卫放行后经此联合穷尽。
39
- */
40
- status: "running" | "closed";
41
- /** L2 关闭原因子枚举(仅 status="closed" 时有意义)。内部诊断 + outcome 兑底派生输入。 */
42
- closedReason?: ClosedReason;
43
- /**
44
- * 终态三态对外语义(U3 C-outcome)。notify() 投影边界物化:closed 入参缺省时按
45
- * deriveOutcome(closedReason, error) 兑底填充(所有可达流程下与 completeRecord
46
- * 冻结的 record.outcome 等价——toNotifyRecord 构造点在 completeRecord 之后;该
47
- * 构造点属 U3 领地外,不透传本字段)。buildLlmContent 与 bg-notify-render 只读本字段。
48
- */
49
- outcome?: ExecutionOutcome;
50
- agent: string;
51
- /** 执行所用 model(RecordSnapshot.model),用于完成通知显示。 */
52
- model?: string;
53
- result?: string;
54
- error?: string;
55
- startedAt: number;
56
- endedAt: number | undefined;
57
- /**
58
- * 对话轮次计数(仅 idle 有意义)。dedup key 按 `id:round` 去重——对话模式每轮 round
59
- * 不同,60s 内多轮不被吞;非 chatMode round 恒定(0/undefined),key 同旧 id 行为不变。
60
- */
61
- round?: number;
62
- /** [MF#1] worktree 模式下子 agent 改动的 patch 路径(worktree 外,cleanup 后留存)。
63
- * done 时通知文本显式提示 `git apply`,否则 background 子 agent 在隔离 worktree 的改动
64
- * 会静默丢失——父 LLM 不知 patch 路径,无法应用。 */
65
- patchFile?: string;
66
- /** [wave2] 子 agent session 文件路径(增量语义的全文恢复通道)。
67
- * 仅 chatMode 透传(toNotifyRecord 条件透传)——轮次/完成通知末尾追加
68
- * "Full transcript: <path>" 指针行,父 LLM 可按需读全文;one-shot 不透传,
69
- * 通知输出逐字节不变。缺失时 buildLlmContent 省略整行。 */
70
- sessionFile?: string;
71
- /** [U2] 通知身份键(投影边界物化 = dedupe key:`id` / `id:round`)。账本条目 /
72
- * 回执匹配 / 幂等去重共用——details 携带(不进文案,G4 字节锁定不受影响),
73
- * 重复注入条目凭此可识别为同一条(G2 at-least-once 幂等键)。 */
74
- notifyId?: string;
75
- /** [C-2] close 终态通知的轮次统计(文案 "completed after N rounds." 用)。
76
- * 仅 chatMode close 语义(notifyClosed)构造时携带——此时 dedup 身份 round 已被
77
- * 置 undefined(与轮次通知的 id:round key 区分,终态不被吞),轮数改由本字段进
78
- * 文案。one-shot 完成通知不设置,文案保持 "completed. Result:" 逐字节(G4)。 */
79
- totalRounds?: number;
80
- }
81
-
82
- /** notifier 依赖的宿主最小接口(解耦,便于测试)。
83
- * 迁移后:仅用于构造 DeliveryPort 的底层依赖。 */
84
- export interface NotifierHost {
85
- /** 注入消息到主对话(U2 单通道:options 只接受 triggerTurn——多通道投递已删)。 */
86
- sendMessage(
87
- message: { customType: string; content: string; display: boolean; details?: unknown },
88
- options?: { triggerTurn?: boolean },
89
- ): void;
90
- /** 是否还有 running 的 background 任务(用于滑动窗口立即 flush 判断)。 */
91
- hasRunningBackground(): boolean;
92
- /** 主 agent 是否空闲(非 streaming)。可选:未注入时 flush 不 gate。 */
93
- isIdle?: () => boolean;
94
- /**
95
- * 原生 settled 事件订阅能力(D8):注册 handler 监听主 agent settled 边沿。
96
- * 无退订语义(pi 0.84.1 的 `pi.on(...)` 全部重载返回 void、无 off——实装锚点:
97
- * node_modules `@earendil-works/pi-coding-agent` dist/core/extensions/types.d.ts
98
- * `on()` 系列重载,0.84.1 实测)——退订由本模块的 disposed
99
- * 标志包装兑现(见下方 port 装配)。可选:未注入时内核退化退避轮询(busy 消息
100
- * 靠退避达上限强发,不走 settled 边沿驱动)。
101
- */
102
- onAgentSettled?(handler: () => void): void;
103
- }
104
-
105
- /**
106
- * 将 BgNotifyRecord 格式化为 LLM 可读的 notification content。
107
- *
108
- * 模块内唯一消费方是下方 createNotifier 的 notify()(预格式化后传 delivery.send,
109
- * 内核只做拼接——多条以 "\n\n---\n\n" join)。
110
- */
111
- function buildLlmContent(record: BgNotifyRecord): string {
112
- const agent = record.agent;
113
- const id = record.id;
114
- // [wave2 指针行] 增量语义下轮次通知只携带本轮增量,异步 flush 窗口丢失时不可重发
115
- //(见 subagent-service.ts onRoundSettled 注释),恢复通道是 session 文件全文。
116
- // 仅 chatMode 透传 sessionFile,one-shot 通知不含该行;cancelled/gc-failed 不追加
117
- //(无成功结果可读,指针无意义);缺失时省略整行(追加空串 = 输出逐字节不变)。
118
- const transcriptPointer = record.sessionFile
119
- ? `\n\nFull transcript: ${record.sessionFile}`
120
- : "";
121
- switch (record.status) {
122
- case "closed": {
123
- // U3 C-outcome:终态文案只读 outcome(notify() 投影边界已物化;?? 兑底为防御
124
- // 完整性——单一权威函数,非同构重写)。判定先于 patchFile——失败轮也会写
125
- // patchFile(doFinalizeRecord Step 0 对 worktreeHandle 无条件 collectPatch),
126
- // failed 分支不展示 patch 提示,否则 worktree 失败并存时 LLM 被告知 completed
127
- // (历史 bug 存档见 deriveOutcome 注释)。
128
- const outcome = record.outcome ?? deriveOutcome(record.closedReason, record.error);
129
- if (outcome === "cancelled") {
130
- return `Subagent "${agent}" (${id}) cancelled.`;
131
- }
132
- if (outcome === "failed") {
133
- return `Subagent "${agent}" (${id}) failed: ${record.error}`;
134
- }
135
- // 成功完成或通用结束:展示结果。
136
- // [C-2] chatMode close 终态通知附轮次统计(设计 D2 路径①"completed after N rounds")。
137
- // totalRounds 仅 close 语义携带(notifyClosed);one-shot 完成通知不设置(round 无轮次
138
- // 语义),文案保持 "completed. Result:" 逐字节(G4 硬约束,one-shot 字节锁测试锚定)。
139
- const roundsSuffix =
140
- record.totalRounds != null && record.totalRounds > 0
141
- ? ` after ${record.totalRounds} round${record.totalRounds === 1 ? "" : "s"}`
142
- : "";
143
- const base = `Subagent "${agent}" (${id}) completed${roundsSuffix}. Result:\n${record.result ?? "(empty)"}`;
144
- if (record.patchFile) {
145
- // [wave2 review] 长 return 拆行:模板串内不可直接换行(会改变输出内容),提取 patchHint 中转变量
146
- 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}\``;
147
- return `${base}${patchHint}${transcriptPointer}`;
148
- }
149
- return `${base}${transcriptPointer}`;
150
- }
151
- case "running":
152
- // v4 B-1: 对话模式轮次完成(旧 idle 折入 running):携带本轮结果送回主 agent,等待下一轮 message。
153
- return `Subagent "${agent}" (${id}) finished a round. Reply:\n${record.result ?? "(empty)"}${transcriptPointer}`;
154
- }
155
- }
156
-
157
- /**
158
- * Background 完成通知器接口(迁移后由内核实现)。
159
- *
160
- * 保持与旧 BgNotifier 类相同的公共 API,避免消费方(subagent-service)改动面过大。
161
- */
162
- export interface BgNotifier {
163
- /** 入队一条完成通知(去重 + 合批窗口合并)。dispose 后短路。 */
164
- notify(record: BgNotifyRecord): void;
165
- /** 立即 flush(session_shutdown 调用,防丢失)。 */
166
- flushPendingNotifications(): void;
167
- /** session 结束:清队列,dispose 内核 handle。 */
168
- dispose(): void;
169
- /** /resume /fork /new 后复活。 */
170
- revive(): void;
171
- }
172
-
173
- /**
174
- * 创建 Background 完成通知器(薄工厂)。
175
- *
176
- * ledger 装配时(bindNotifyLedgerHost):四步生命周期接线(写账 → courier 边沿
177
- * 投递 → 回执销账 → notifyId 幂等,见 notify-ledger.ts)。未装配时:装配
178
- * @xyz-agent/session-delivery 内核——gate(isIdle 退避)/ 合批窗口(滑动 60s)/
179
- * dedup(按 id:round)/ flush / shutdown flush 均委托内核。
180
- * 本函数职责:BgNotifyRecord → 预格式化 content + notifyId 物化。
181
- *
182
- * @param host 宿主能力注入(pi.sendMessage + hasRunningBackground + isIdle)
183
- * @returns BgNotifier 接口(与旧类同形)
184
- */
185
- export function createNotifier(host: NotifierHost): BgNotifier {
186
- let disposed = false;
187
-
188
- // 构造 DeliveryPort:intent → pi 参数翻译在适配器内(D3)
189
- const port: DeliveryPort = {
190
- supportedPayloads: ["custom"],
191
- isIdle: () => {
192
- if (host.isIdle) {
193
- return host.isIdle();
194
- }
195
- // 未注入 isIdle → 视为 idle(不 gate,向后兼容旧 host)
196
- return true;
197
- },
198
- hasPendingMessages: () => false, // notifier 不关心 hasPendingMessages
199
- // D8(must-fix #4):settled 边沿驱动装配——内核 busy 入队后由 settled 事件唤醒
200
- // flush(watch-dog 兜底事件丢失),替代无订阅时的退避轮询。host 只注入原生订阅
201
- // 能力;disposed 标志包装(兑现退订语义——pi.on 返回 void 且无 off)在此完成。
202
- subscribeSettled:
203
- host.onAgentSettled === undefined
204
- ? undefined
205
- : (cb) => {
206
- let disposed = false;
207
- host.onAgentSettled?.(() => {
208
- if (!disposed) cb();
209
- });
210
- return () => {
211
- disposed = true;
212
- };
213
- },
214
- send: (msg, _intent) => {
215
- // D5 单通道:投递意图唯一化——steer/followUp/nextTurn 多通道全部删除,
216
- // 唯一发送形态 = sendCustomMessage({triggerTurn:true})。busy 场景由 ledger
217
- //(settled 边沿 + isIdle 二次复查)或内核 settled 订阅在空闲边沿驱动,
218
- // 不在此层分流。返回 void = 受理成功(同步无异常;SendReceipt 扩展位留待
219
- // 升级方接入)。
220
- host.sendMessage(
221
- {
222
- customType: NOTIFY_CUSTOM_TYPE,
223
- content: msg.payload.content,
224
- display: true,
225
- details: msg.payload.kind === "custom" ? msg.payload.details : undefined,
226
- },
227
- { triggerTurn: true },
228
- );
229
- },
230
- };
231
-
232
- // #5(must-fix):内核 handle 的 disposed 不可逆——dispose 后 revive 必须重建 handle,
233
- // 否则 revive 后所有 notify() 被内核静默吞(外层标志复位救不回已销毁的内核)。
234
- // revive = 新生命周期:合批窗口 / 在途批次 / dedup LRU 随重建自然复位(可接受)。
235
- const createHandle = (): DeliveryHandle =>
236
- createDelivery(port, {
237
- intent: "interrupt-at-turn-boundary", // D3:turn 边界抢占(F1 教训内化)
238
- mergeWindowMs: 60_000, // 滑动窗口合批(继承 MERGE_WINDOW_MS=60s)
239
- mergeHoldActive: () => host.hasRunningBackground(), // D4 must-fix #1:禁止用 isIdle 代替
240
- busyPolicy: "retry-force", // settled 边沿驱动 + 退避达上限强发
241
- backoff: { ms: 100, max: 50 }, // 继承 FLUSH_BACKOFF_MS/MAX
242
- // dedup LRU:语义与旧 DEDUP_TTL_MS=60s **不同**——按 key 永久去重(仅 LRU 逐出后
243
- // 同 key 可再入)。当前 key 空间(id / id:round,id 每 spawn 唯一)无实际差异;
244
- // 后续复用方勿按「60s 内不重复」假设接入(同 key 通知会被永久吞)。
245
- dedupe: { maxKeys: 1000 },
246
- // U4 warn 出口参数化:内核投递失败警告接 extensionLogger(appendEntry 落
247
- // session JSONL + XYZ_AGENT_DEBUG 落 <dataDir>/logs/),不再走 console.warn
248
- // (stderr tee 不到日志盘——排查无痕,设计 §5 U4)。
249
- warn: (msg, err) => notifyLogger.warn(msg, err),
250
- });
251
- let handle: DeliveryHandle = createHandle();
252
-
253
- return {
254
- notify(record: BgNotifyRecord): void {
255
- if (disposed) return;
256
-
257
- // U3 C-outcome:投影边界物化 outcome——closed payload 缺省时按单一权威
258
- // deriveOutcome 兑底填充,content 与 details(GUI pane 消费)均携带一等 outcome;
259
- // 所有可达流程下与 record.outcome 等价(toNotifyRecord 在 completeRecord 之后
260
- // 构造)。running(轮次通知)语义上无 outcome,不物化。消源自 record 的浅拷贝
261
- // ——不改写入方对象(BgNotifyRecord 由调用方持有)。notifyId 同批物化(U2:
262
- // dedupe key 与账本身份键同源,details 携带供回执匹配)。
263
- const notifyId = record.round != null ? `${record.id}:${record.round}` : record.id;
264
- const payload: BgNotifyRecord =
265
- record.status === "closed"
266
- ? { ...record, outcome: record.outcome ?? deriveOutcome(record.closedReason, record.error), notifyId }
267
- : { ...record, notifyId };
268
-
269
- const content = buildLlmContent(payload);
270
-
271
- // U2 B-ledger 四步接线(设计 D4/D5):账本装配时①写账(appendEntry 先于一切
272
- // 投递尝试)→ ②courier 边沿投递(settled 边沿 + 120s 看门狗 + isIdle 二次
273
- // 复查)→ ③回执销账 / ④重放幂等均在 ledger 内。record 返回 false = 同
274
- // notifyId 已在账或已销账(幂等去重,含重启恢复后的已送达账号零重发)。
275
- const ledger = getBoundNotifyLedger();
276
- if (ledger) {
277
- if (!ledger.record(notifyId, content, payload)) return;
278
- ledger.attemptDeliver();
279
- return;
280
- }
281
-
282
- // 无 ledger 装配(旧装配 / 部分测试):内核路径——合批窗口 / settled 边沿 /
283
- // dedupe(按 notifyId,key 规则与旧 dedupeKey 一致:id 或 id:round)不变。
284
- // [C-ext-06 配套] 降级留痕:bind 缺失(含 jiti 单例分裂致跨模块读不到绑定的
285
- // 失效形态)本是无声分岔,U2 at-least-once 在此退化为内核路径——warn 一条
286
- // 供诊断检索,不改变向后兼容行为。
287
- notifyLogger.warn("notify ledger not bound, falling back to delivery kernel path (at-most-once)", {
288
- notifyId,
289
- });
290
- handle.send({
291
- payload: {
292
- kind: "custom",
293
- customType: NOTIFY_CUSTOM_TYPE,
294
- content,
295
- display: true,
296
- details: payload,
297
- },
298
- dedupeKey: notifyId,
299
- });
300
- },
301
-
302
- flushPendingNotifications(): void {
303
- // ledger 路径:立即投递尝试(isIdle 复查,busy 则挂 pending 等边沿——账已落盘,
304
- // 重启恢复兑底);内核路径:flush。
305
- const ledger = getBoundNotifyLedger();
306
- if (ledger) {
307
- ledger.attemptDeliver();
308
- return;
309
- }
310
- handle.flush();
311
- },
312
-
313
- dispose(): void {
314
- disposed = true;
315
- handle.dispose();
316
- // ledger 销毁(清看门狗 + 摘模块级绑定;settled 回调由 disposed 标志静默)。
317
- // 未 bind 时 no-op。bind 归 index.ts session_start 装配,对称免受。
318
- getBoundNotifyLedger()?.dispose();
319
- },
320
-
321
- revive(): void {
322
- disposed = false;
323
- // #5:内核 disposed 不可逆——revive 必须重建 handle(/resume /fork /new 后的
324
- // session_start 时序:disposeAll → initSession → revive)。旧 handle 若仍存活
325
- // (首次 session_start 的 revive)dispose 为幂等清理,无副作用。
326
- handle.dispose();
327
- handle = createHandle();
328
- },
329
- };
330
- }