@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,108 +0,0 @@
1
- // src/execution/engine/common/persona-router.ts
2
- //
3
- // persona 路由与 argv 预算(P2 公共降级层)。设计权威源:
4
- // docs/architecture/subagent-engine-abstraction.md D4(persona 路由按 capabilities
5
- // 选择 file/flag/prompt 三策略,兼作 argv 长度分流)+ D5(preparer 在 spawn 前估算
6
- // argv 总长度:仅 argv 投递的引擎超长时在 prepare 期报 prompt_too_large,禁止 spawn
7
- // 后撞 E2BIG 才失败)+ §3.3.3 prompt_too_large 行。
8
- //
9
- // 路由产出按 capabilities.personaInjection 三分(中立层只决策通道与内容,具体 flag
10
- // 组装归各引擎 launcher):
11
- // - 'file' → fileCandidate(人设全文落盘为文件,argv 只带文件路径——kimi
12
- // --agent-file 形态);promptSegment 为空(人设不进 prompt)。
13
- // - 'flag' → promptSegment 为人设全文(launcher 组 --system-prompt 类 flag 直传)。
14
- // - 'prompt'→ promptSegment 为带引导结构的人设段(拼进最终 prompt——zcode 形态)。
15
-
16
- import { promptTooLargeError } from "./errors.ts";
17
- import type { EngineCapabilities, PersonaSpec } from "../types.ts";
18
-
19
- // ============================================================
20
- // persona 三策略路由
21
- // ============================================================
22
-
23
- /** applyPersona 的返回:按通道产出人设载体。 */
24
- export interface PersonaRouting {
25
- /** 进 prompt / flag 通道的人设文本(file 通道为空串)。 */
26
- promptSegment: string;
27
- /** file 通道的人设文件落盘候选(suggestedPath 相对池目录,preparer 负责落位)。 */
28
- fileCandidate?: { suggestedPath: string; content: string };
29
- }
30
-
31
- /** file 通道的人设文件建议名(相对池目录——preparer 知道池根,router 不感知)。 */
32
- const PERSONA_FILE_NAME = "persona.md";
33
-
34
- /**
35
- * 按 capabilities.personaInjection 路由 persona 的注入通道。
36
- *
37
- * router 不解析 agent .md / skill 文件内容(身份解析归宿主 resolveIdentity)——
38
- * 只把 PersonaSpec 声明的内容组装成通道载体:appendSystemPrompt 是人设正文,
39
- * agentRef/skillPath 以引用提示行进文本(prompt 通道)或正文头(file 通道)。
40
- */
41
- export function applyPersona(persona: PersonaSpec, capabilities: EngineCapabilities): PersonaRouting {
42
- switch (capabilities.personaInjection) {
43
- case "file": {
44
- const content = buildPersonaBody(persona);
45
- // 全空 persona 走 file 通道无意义(空文件白占 argv 一段)——降级为无载体
46
- if (content === "") return { promptSegment: "" };
47
- return { promptSegment: "", fileCandidate: { suggestedPath: PERSONA_FILE_NAME, content } };
48
- }
49
- case "flag":
50
- // flag 直传:纯正文(launcher 把它作为 --append-system-prompt 类 flag 的值)
51
- return { promptSegment: buildPersonaBody(persona) };
52
- case "prompt":
53
- return { promptSegment: buildPromptSegment(persona) };
54
- }
55
- }
56
-
57
- /** 人设正文:appendSystemPrompt join + agentRef/skillPath 头部引用行。 */
58
- function buildPersonaBody(persona: PersonaSpec): string {
59
- const parts: string[] = [];
60
- if (persona.agentRef !== undefined) parts.push(`# Agent: ${persona.agentRef}`);
61
- if (persona.skillPath !== undefined) parts.push(`Skill context: ${persona.skillPath}`);
62
- const body = persona.appendSystemPrompt?.join("\n") ?? "";
63
- if (body !== "") parts.push(body);
64
- return parts.join("\n");
65
- }
66
-
67
- /** prompt 通道的人设段(带结构头,拼进最终 prompt)。 */
68
- function buildPromptSegment(persona: PersonaSpec): string {
69
- const body = buildPersonaBody(persona);
70
- if (body === "") return "";
71
- return `## Persona\n${body}`;
72
- }
73
-
74
- // ============================================================
75
- // argv 长度预算(prepare 期前置拦截)
76
- // ============================================================
77
-
78
- /**
79
- * argv 预算默认上限(128KB)。依据:POSIX ARG_MAX 通常 ≥ 256KB(Linux 单字符串
80
- * MAX_ARG_STRLEN 128KB 是更紧的硬顶)——预算取 128KB 留出参数个数与 env 余量,
81
- * spawn 前拦截,绝不 spawn 后撞 E2BIG(D5)。可经 assertArgvBudget 第二参覆盖。
82
- */
83
- export const DEFAULT_ARGV_BUDGET_BYTES =
84
- // eslint-disable-next-line no-magic-numbers -- 128KB = 128 * 1024 bytes 预算换算常数
85
- 128 * 1024;
86
-
87
- /**
88
- * 估算 argv 总字节数:各参数 UTF-8 字节数之和 + 每参数一个 NUL 分隔符。
89
- * execve 按字节计算参数区,估算口径与内核一致(字符数会低估多字节文本)。
90
- */
91
- export function estimateArgvBytes(argv: string[]): number {
92
- let total = 0;
93
- for (const arg of argv) {
94
- total += Buffer.byteLength(arg, "utf8") + 1;
95
- }
96
- return total;
97
- }
98
-
99
- /**
100
- * argv 预算断言:估算超限抛 EngineError(prompt_too_large)(恢复指引三条:缩短 task /
101
- * persona 移 file 通道 / 换 stdin 引擎)。调用点在 preparer(进程创建前,D5)。
102
- */
103
- export function assertArgvBudget(argv: string[], limitBytes: number = DEFAULT_ARGV_BUDGET_BYTES): void {
104
- const actual = estimateArgvBytes(argv);
105
- if (actual > limitBytes) {
106
- throw promptTooLargeError(actual, limitBytes);
107
- }
108
- }
@@ -1,226 +0,0 @@
1
- // src/execution/engine/common/pool-manager.ts
2
- //
3
- // 隔离目录池管理(P2 公共降级层)。设计权威源:
4
- // docs/architecture/subagent-engine-abstraction.md D5(隔离目录池化保留,随 record
5
- // 生命周期回收,清理只做到池粒度)+ §3.3.9(目录布局 / refs 方案)。
6
- //
7
- // P2 口径(与 §3.3.9 完整设计的差异,签名所限):引用计数是**进程内注册表**——
8
- // acquire/release 的任务书签名无 taskId,refs.json 文件形态(登记 taskId + ts)留给
9
- // 后续 wave 在 preparer/host 接线时落地(宿主是唯一写者,升级为文件形态不改变本模块
10
- // 的 acquire/release 语义边界)。
11
- //
12
- // 删除边界(D5 三条硬规则):
13
- // 1. 只删引擎原生状态(隔离 HOME / config / db.sqlite,均可由 preparer 重建);
14
- // 2. journal-*.jsonl 不随池删——生命周期跟随 record,避免「池删导致仍存 record 的
15
- // 历史从②级静默跌③级」;
16
- // 3. 删除失败置 .pool-cleanup-failed 标记文件(可观测不静默),启动期扫描该标记告警。
17
-
18
- import { mkdir, readdir, rm, rmdir, writeFile } from "node:fs/promises";
19
- import { join } from "node:path";
20
-
21
- import { getLogger } from "@zhushanwen/pi-extension-logger";
22
-
23
- import { resolvePoolDir } from "../paths.ts";
24
-
25
- const logger = getLogger("subagents");
26
-
27
- /** 清理失败标记文件名(置于池目录内;内容为 JSON 失败清单)。 */
28
- export const POOL_CLEANUP_FAILED_MARKER = ".pool-cleanup-failed";
29
-
30
- /** readdir withFileTypes 的条目结构子集。 */
31
- interface DirEntryLike {
32
- name: string;
33
- isDirectory(): boolean;
34
- }
35
-
36
- /** 池管理的文件系统依赖面(结构接口:测试注入 fake,免 vi.mock 整个 fs 模块)。 */
37
- export interface PoolFsDeps {
38
- mkdir(path: string, opts: { recursive: boolean }): Promise<unknown>;
39
- readdir(path: string): Promise<DirEntryLike[]>;
40
- rm(path: string, opts: { recursive: boolean; force: boolean }): Promise<void>;
41
- rmdir(path: string): Promise<void>;
42
- writeFile(path: string, data: string): Promise<void>;
43
- }
44
-
45
- // ============================================================
46
- // 进程内池注册表(引用计数)
47
- // ============================================================
48
-
49
- /**
50
- * key = 池目录绝对路径 → 活跃引用计数。进程级单例状态,用 globalThis[Symbol.for]
51
- * 持有防 jiti 双路径加载分裂(development-guide §7.5),不用模块级 const。
52
- */
53
- const POOL_REFS_SLOT_KEY = Symbol.for("@zhushanwen/pi-subagent-workflow.poolRefs");
54
-
55
- function getPoolRefs(): Map<string, number> {
56
- // globalThis 无 symbol 索引签名,但运行时支持 symbol 键——用 Reflect 安全读写,
57
- // 避免双重断言(同 model-config-service.ts 先例)。
58
- let refs = Reflect.get(globalThis, POOL_REFS_SLOT_KEY) as Map<string, number> | undefined;
59
- if (!refs) {
60
- refs = new Map();
61
- Reflect.set(globalThis, POOL_REFS_SLOT_KEY, refs);
62
- }
63
- return refs;
64
- }
65
-
66
- /** 测试隔离专用:清空进程内注册表(生产禁用——会丢失活跃引用计数)。 */
67
- export function resetPoolRegistryForTests(): void {
68
- getPoolRefs().clear();
69
- }
70
-
71
- // ============================================================
72
- // acquire / release
73
- // ============================================================
74
-
75
- /**
76
- * 获取池目录:mkdir -p(幂等)+ 进程内引用计数 +1,返回池目录绝对路径。
77
- * 路径一律经 paths.ts resolvePoolDir 派生(双端同源,禁自拼)。
78
- */
79
- export async function acquirePool(
80
- dataDir: string,
81
- engineId: string,
82
- poolKey: string,
83
- fs: Pick<PoolFsDeps, "mkdir"> = nodeFs,
84
- ): Promise<string> {
85
- const poolDir = resolvePoolDir(dataDir, engineId, poolKey);
86
- await fs.mkdir(poolDir, { recursive: true });
87
- const poolRefs = getPoolRefs();
88
- poolRefs.set(poolDir, (poolRefs.get(poolDir) ?? 0) + 1);
89
- return poolDir;
90
- }
91
-
92
- /**
93
- * 释放一次池引用(record GC / 删除时调用):计数递减;归零删整池——只删引擎原生
94
- * 状态,journal-*.jsonl 保留(D5);删除失败置标记文件并 warn,不静默不 throw
95
- * (清理失败不是 record GC 的失败)。
96
- */
97
- export async function releasePoolRef(
98
- dataDir: string,
99
- engineId: string,
100
- poolKey: string,
101
- fs: PoolFsDeps = nodeFs,
102
- ): Promise<void> {
103
- const poolDir = resolvePoolDir(dataDir, engineId, poolKey);
104
- const poolRefs = getPoolRefs();
105
- const current = poolRefs.get(poolDir);
106
- // 无计数(进程重启后释放 / 未 acquire 的释放)→ 保守不删池:删池决策必须有本进程
107
- // 内的归零证据,凭空删除可能误删其他进程正在使用的池
108
- if (current === undefined || current <= 0) {
109
- poolRefs.delete(poolDir);
110
- logger.debug(`[pool-manager] release without live ref, skip pool deletion: ${poolDir}`);
111
- return;
112
- }
113
- if (current > 1) {
114
- poolRefs.set(poolDir, current - 1);
115
- return;
116
- }
117
- // 归零:删引擎原生状态(journal 保留)
118
- poolRefs.delete(poolDir);
119
- await deletePoolNativeState(poolDir, fs);
120
- }
121
-
122
- /** journal 文件名判定(与 paths.ts 的 journal-<taskId>.jsonl 命名约定一致)。 */
123
- function isJournalFile(name: string): boolean {
124
- return name.startsWith("journal-") && name.endsWith(".jsonl");
125
- }
126
-
127
- /** 删池内引擎原生状态:逐条目删除(跳过 journal),目录清空后移除目录本身。 */
128
- async function deletePoolNativeState(poolDir: string, fs: PoolFsDeps): Promise<void> {
129
- const failures: string[] = [];
130
- let entries: DirEntryLike[];
131
- try {
132
- entries = await fs.readdir(poolDir);
133
- } catch {
134
- // 池目录不存在(从未创建 / 已删)= 无原生状态可清,视为成功
135
- return;
136
- }
137
- for (const entry of entries) {
138
- if (isJournalFile(entry.name)) continue;
139
- try {
140
- await fs.rm(join(poolDir, entry.name), { recursive: true, force: true });
141
- } catch (err) {
142
- failures.push(`${entry.name}: ${err instanceof Error ? err.message : String(err)}`);
143
- }
144
- }
145
- if (failures.length > 0) {
146
- await markCleanupFailed(poolDir, failures, fs);
147
- return;
148
- }
149
- try {
150
- // 目录内只剩 journal(或已空):只剩 journal 时保留目录(journal 生命周期跟 record)
151
- const remaining = await fs.readdir(poolDir);
152
- if (remaining.every((e) => isJournalFile(e.name))) return;
153
- await fs.rmdir(poolDir);
154
- } catch (err) {
155
- await markCleanupFailed(
156
- poolDir,
157
- [`(rmdir): ${err instanceof Error ? err.message : String(err)}`],
158
- fs,
159
- );
160
- }
161
- }
162
-
163
- /** 置 .pool-cleanup-failed 标记(失败清单 JSON)+ warn——可观测不静默(D5)。 */
164
- async function markCleanupFailed(poolDir: string, failures: string[], fs: PoolFsDeps): Promise<void> {
165
- const marker = join(poolDir, POOL_CLEANUP_FAILED_MARKER);
166
- const payload = JSON.stringify({ ts: Date.now(), failures });
167
- logger.warn(
168
- `[pool-manager] pool cleanup failed for ${poolDir} (${failures.length} item(s)); ` +
169
- `marker written to ${marker} — re-run cleanup after fixing the underlying error`,
170
- );
171
- try {
172
- await fs.writeFile(marker, `${payload}\n`);
173
- } catch (err) {
174
- // 标记本身也写不进(目录只读/磁盘满)——error 级留痕是最后防线,不再上抛
175
- logger.warn(
176
- `[pool-manager] failed to write cleanup-failed marker ${marker}: ` +
177
- `${err instanceof Error ? err.message : String(err)}`,
178
- );
179
- }
180
- }
181
-
182
- // ============================================================
183
- // 单次性产物清理(spawnedFiles)
184
- // ============================================================
185
-
186
- /** cleanupSpawnedFiles 选项。 */
187
- export interface SpawnedFilesCleanupOpts {
188
- /**
189
- * resume 场景保留:true = 全部保留(no-op)。resume 续接原 session,prompt 文件
190
- * 等单次性产物不再重写(§3.3.7 preparer resume 语义),清理留给 record 终局。
191
- */
192
- keepForResume: boolean;
193
- }
194
-
195
- /**
196
- * 清理单次性产物(preparer 的 spawnedFiles:临时 prompt / persona 文件)。
197
- * 任务结束即清理(D5);单条失败收集 warn 不 throw(部分清理优于整体失败),ENOENT
198
- * 幂等忽略。
199
- */
200
- export async function cleanupSpawnedFiles(
201
- paths: string[],
202
- opts: SpawnedFilesCleanupOpts,
203
- fs: Pick<PoolFsDeps, "rm"> = nodeFs,
204
- ): Promise<void> {
205
- if (opts.keepForResume) return;
206
- for (const p of paths) {
207
- try {
208
- await fs.rm(p, { recursive: true, force: true });
209
- } catch (err) {
210
- logger.warn(
211
- `[pool-manager] spawned file cleanup failed for ${p}: ` +
212
- `${err instanceof Error ? err.message : String(err)}`,
213
- );
214
- }
215
- }
216
- }
217
-
218
- // ── 默认 fs 实现 ────────────────────────────────────────────────
219
-
220
- const nodeFs: PoolFsDeps = {
221
- mkdir: (p, o) => mkdir(p, o),
222
- readdir: (p) => readdir(p, { withFileTypes: true }) as Promise<DirEntryLike[]>,
223
- rm: (p, o) => rm(p, o),
224
- rmdir: (p) => rmdir(p),
225
- writeFile: (p, d) => writeFile(p, d, "utf8"),
226
- };
@@ -1,189 +0,0 @@
1
- // src/execution/engine/common/schema-emulation.ts
2
- //
3
- // schema 仿真降级(P2 公共降级层)。设计权威源:
4
- // docs/architecture/subagent-engine-abstraction.md D4(native/emulated 硬分流)+ §3.3.3
5
- // schema_emulation_failed 行 + §5 P2 行。
6
- //
7
- // ─── D4 硬分流(违反 = 历史事故形态) ───────────────────────────────
8
- // 本模块只服务 capabilities.schemaEnforcement === 'emulated' 的引擎
9
- // (zcode / opencode / kimi-code)。capabilities.schemaEnforcement === 'native' 的引擎
10
- // (pi 的 PI_WORKFLOW_SCHEMA env 注入链路、claude-code --json-schema、codex
11
- // --output-schema)**禁止** import 本模块做二次校验或改写其结果——宿主侧再叠一层
12
- // ajv 会制造第二校验权威,恰是 structured-output 方案 A [HISTORICAL]
13
- // (2026-08-01「校验自报 schema 致修复静默丢失」事故)的形态。
14
- // ajv 只允许出现在 emulated 路径(本模块),这是全仓唯一例外。
15
- //
16
- // 重试语义:本模块两个函数保持纯——校验失败/提取失败由调用方(宿主编排层)决定
17
- // 重试,语义与 structured-output 的 workflow-hook 对齐(重试一次、强化 prompt;
18
- // 仍失败报 schema_emulation_failed,错误含原始输出尾部)。
19
- //
20
- // 文案对齐:错误回显风格对齐 structured-output 的 execute.ts("Schema validation
21
- // failed: ..."),但不 import 其内部模块(公共层自实现;structured-output 是
22
- // peer 依赖且可选,import 会造成公共层对 sibling extension 的硬依赖)。
23
-
24
- import Ajv, { type ValidateFunction } from "ajv";
25
-
26
- /** 原始输出尾部回显长度(结果对象的 tail 字段,供错误展示与重试 prompt 回灌)。 */
27
- export const SCHEMA_EMULATION_TAIL_CHARS = 500;
28
-
29
- // ============================================================
30
- // prompt 注入段
31
- // ============================================================
32
-
33
- /**
34
- * 构造 prompt 注入段:schema 声明 + 输出格式约定(emulated 引擎的 launcher 把它拼进
35
- * 最终 prompt,替代引擎不存在的 schema 强制通道)。
36
- *
37
- * 文案风格对齐 structured-output 的 promptGuidelines("Do not output JSON in text":emulated 引擎没有工具可调,JSON 必须出现在文本里)。
38
- */
39
- export function buildSchemaEmulationSegment(schema: object): string {
40
- const schemaJson = JSON.stringify(schema);
41
- return [
42
- "## Structured Output Requirement",
43
- "Your final answer MUST contain exactly one JSON value conforming to this JSON Schema (draft-07):",
44
- schemaJson,
45
- "Output rules:",
46
- "- Output ONLY the JSON value — no prose before or after it.",
47
- "- If you wrap it in a markdown code fence, use a single ```json fence.",
48
- "- Do not output multiple JSON values; the first complete JSON value is extracted.",
49
- ].join("\n");
50
- }
51
-
52
- // ============================================================
53
- // 三级容错提取 + ajv 校验
54
- // ============================================================
55
-
56
- /** 提取结果联合:ok=true 携带通过校验的 parsed;ok=false 携带 error 简述 + 原始输出尾部。 */
57
- export type StructuredOutputResult =
58
- | { ok: true; parsed: unknown }
59
- | { ok: false; error: string; tail: string };
60
-
61
- /**
62
- * 从模型文本输出提取并校验结构化 JSON(三级容错 → ajv)。
63
- *
64
- * 三级容错(逐级降级,任一级提取成功即进 ajv):
65
- * 1. 直接 JSON.parse(trim 后整体是合法 JSON);
66
- * 2. 剥 markdown code fence(```json ... ``` / ``` ... ```)取围栏内内容;
67
- * 3. 首尾括号扫描(首个 '{'/'[' 到末个 '}'/']' 的子串——容纳前后杂文本)。
68
- *
69
- * ajv 校验失败/三级提取失败返回 ok:false(不 throw)——重试与否是宿主编排层的
70
- * 决策(见文件头重试语义),本函数每次调用独立无状态。
71
- */
72
- export function extractAndValidateStructuredOutput(
73
- text: string,
74
- schema: object,
75
- ): { ok: true; parsed: unknown } | { ok: false; error: string; tail: string } {
76
- return extractImpl(text, schema);
77
- }
78
-
79
- /** 实现体(签名拆分只为让导出签名与契约声明逐字一致,见 StructuredOutputResult)。 */
80
- function extractImpl(text: string, schema: object): StructuredOutputResult {
81
- const tail = text.length > SCHEMA_EMULATION_TAIL_CHARS
82
- ? text.slice(text.length - SCHEMA_EMULATION_TAIL_CHARS)
83
- : text;
84
-
85
- const extracted = extractJsonCandidate(text);
86
- if (extracted === undefined) {
87
- return {
88
- ok: false,
89
- error:
90
- "could not extract JSON from model output after 3-stage fallback " +
91
- "(direct parse -> code-fence strip -> bracket scan)",
92
- tail,
93
- };
94
- }
95
-
96
- const validate = getOrCompileValidator(schema);
97
- if (validate === undefined) {
98
- return {
99
- ok: false,
100
- error: "host-side JSON Schema compilation failed (invalid schema object)",
101
- tail,
102
- };
103
- }
104
-
105
- const valid = validate(extracted);
106
- if (!valid) {
107
- // 错误格式对齐 structured-output:"instancePath message" 逐条 join
108
- const errors = validate.errors?.map((err) => `${err.instancePath} ${err.message}`).join("; ");
109
- return {
110
- ok: false,
111
- error: `Schema validation failed: ${errors ?? "(no detail)"}`,
112
- tail,
113
- };
114
- }
115
- return { ok: true, parsed: extracted };
116
- }
117
-
118
- // ── 内部:三级提取 ──────────────────────────────────────────────
119
-
120
- /** 三级容错提取 JSON candidate;全部失败返回 undefined。 */
121
- function extractJsonCandidate(text: string): unknown {
122
- // 第 1 级:整体直接 parse(最常见——严格遵守输出约定的模型)
123
- const direct = tryParse(text.trim());
124
- if (direct.ok) return direct.value;
125
-
126
- // 第 2 级:markdown code fence 剥离(模型爱用 ```json 包裹)
127
- const fenced = extractFirstFencedBlock(text);
128
- if (fenced !== undefined) {
129
- const parsed = tryParse(fenced.trim());
130
- if (parsed.ok) return parsed.value;
131
- }
132
-
133
- // 第 3 级:首尾括号扫描(前后杂文本:"Here is the result: {...} Hope this helps")
134
- const scanned = extractByBracketScan(text);
135
- if (scanned !== undefined) {
136
- const parsed = tryParse(scanned.trim());
137
- if (parsed.ok) return parsed.value;
138
- }
139
-
140
- return undefined;
141
- }
142
-
143
- /** JSON.parse 包装:失败返回 ok:false(malformed 不是异常态,是三级降级的输入)。 */
144
- function tryParse(raw: string): { ok: true; value: unknown } | { ok: false } {
145
- if (raw === "") return { ok: false };
146
- try {
147
- return { ok: true, value: JSON.parse(raw) };
148
- } catch {
149
- return { ok: false };
150
- }
151
- }
152
-
153
- /** 取第一个 markdown code fence 块内容(```json / ``` 均可);无 fence 返回 undefined。 */
154
- function extractFirstFencedBlock(text: string): string | undefined {
155
- const match = /```(?:json)?\s*([\s\S]*?)\s*```/.exec(text);
156
- return match?.[1];
157
- }
158
-
159
- /** 首尾括号扫描:首个 '{'/'[' 到末个 '}'/']' 的子串;边界不合法返回 undefined。 */
160
- function extractByBracketScan(text: string): string | undefined {
161
- const objOpen = text.indexOf("{");
162
- const arrOpen = text.indexOf("[");
163
- const open = objOpen === -1 ? arrOpen : arrOpen === -1 ? objOpen : Math.min(objOpen, arrOpen);
164
- const objClose = text.lastIndexOf("}");
165
- const arrClose = text.lastIndexOf("]");
166
- const close = Math.max(objClose, arrClose);
167
- if (open === -1 || close === -1 || open >= close) return undefined;
168
- return text.slice(open, close + 1);
169
- }
170
-
171
- // ── 内部:ajv 编译缓存 ──────────────────────────────────────────
172
-
173
- // WeakMap 缓存(schema 对象引用即 key,GC 友好)——模式对齐 structured-output 的
174
- // ajv-validator.ts(自实现,不跨包 import;见文件头依赖边界说明)。
175
- const ajvCache = new WeakMap<object, ValidateFunction>();
176
-
177
- /** 编译(或取缓存)validator;schema 非法(ajv 抛错)返回 undefined 由调用方报错。 */
178
- function getOrCompileValidator(schema: object): ValidateFunction | undefined {
179
- const cached = ajvCache.get(schema);
180
- if (cached) return cached;
181
- try {
182
- // strict:false 对齐 structured-output 的宽容度(非标 keyword 不炸编译)
183
- const validate = new Ajv({ strict: false }).compile(schema);
184
- ajvCache.set(schema, validate);
185
- return validate;
186
- } catch {
187
- return undefined;
188
- }
189
- }
@@ -1,51 +0,0 @@
1
- // src/execution/engine/common/session-view-projection.ts
2
- //
3
- // Turn → ReplayedTurn 投影 + usage 聚合的单一实现(P5 收敛)。此前三份同构副本:
4
- // common/journal-replay.ts(journal 重放投影)、engines/pi/pi-engine.ts read()(内联
5
- // 重写)、engines/pi/reader.ts(native reader)——投影语义唯一(strip 内部态 + closed
6
- // 恒 true + usageDelta 聚合),实现也必须唯一(防三处漂移)。
7
- //
8
- // 纯函数、零运行时依赖(仅类型 import):reader.ts 的双端复用约束(设计 §3.3.7,
9
- // xyz-agent runtime 可 import)对本模块同样成立。
10
- //
11
- // 设计权威源:docs/architecture/subagent-engine-abstraction.md §3.3.6(重放等价性)。
12
-
13
- import type { AgentUsageTotal, InternalToolCall, ToolCall, Turn } from "../../types.ts";
14
- import type { ReplayedTurn } from "../types.ts";
15
-
16
- /** InternalToolCall → ToolCall(导出纯净形状,不泄漏 running/done/failed 内部状态机)。 */
17
- function toExportedToolCall(tc: InternalToolCall): ToolCall {
18
- return {
19
- toolName: tc.toolName,
20
- ...(tc.args !== undefined ? { args: tc.args } : {}),
21
- ...(tc.result !== undefined ? { result: tc.result } : {}),
22
- ...(tc.isError !== undefined ? { isError: tc.isError } : {}),
23
- };
24
- }
25
-
26
- /** Turn → ReplayedTurn:剥离内部态(closed 恒 true——重放物无进行时语义,§3.3.6)。 */
27
- export function toReplayedTurn(turn: Turn): ReplayedTurn {
28
- return {
29
- text: turn.text,
30
- thinking: turn.thinking,
31
- toolCalls: turn.toolCalls.map(toExportedToolCall),
32
- closed: true,
33
- };
34
- }
35
-
36
- /** 各 turn usageDelta 聚合为 AgentUsageTotal(无任何 usage 数据时 undefined)。 */
37
- export function aggregateUsage(turns: readonly Turn[]): AgentUsageTotal | undefined {
38
- let acc: AgentUsageTotal | undefined;
39
- for (const turn of turns) {
40
- const d = turn.usageDelta;
41
- if (!d) continue;
42
- if (!acc) acc = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, total: 0 };
43
- acc.input += d.input;
44
- acc.output += d.output;
45
- acc.cacheRead += d.cacheRead;
46
- acc.cacheWrite += d.cacheWrite;
47
- acc.cost += d.cost ?? 0;
48
- }
49
- if (acc) acc.total = acc.input + acc.output + acc.cacheRead + acc.cacheWrite;
50
- return acc;
51
- }
@@ -1,65 +0,0 @@
1
- // src/execution/engine/engine-discovery.ts
2
- //
3
- // [U7] 引擎列表状态文件同步(registry → <agentDir>/subagents/engines.json)。
4
- //
5
- // 为什么落文件而不是 session entry:Settings 引擎选择器在无活跃 session 时也要可开
6
- // (冷启动/全局设置),session entry 绑定会话生命周期兜不住;engines.json 是进程外
7
- // 可读的全局状态,extension(pi 进程)为唯一写入者,runtime RPC 读——数据所有权清晰。
8
- //
9
- // 动态性(用户要求):清单来自代码注册表(registerEngine 调用点),未来新增引擎
10
- // (AcpEngine 等)零改动出现在 GUI——本文件与前端都不枚举引擎。
11
-
12
- import * as fs from "node:fs";
13
- import * as path from "node:path";
14
-
15
- import { SUBAGENTS_ENGINES_FILENAME, type SubagentEnginesFile } from "@xyz-agent/extension-protocol";
16
-
17
- import { listEngines } from "./registry.ts";
18
-
19
- /** engines.json 绝对路径(与 config.json 同目录;config.ts 的 getGlobalConfigPath 同构)。 */
20
- export function getEnginesFilePath(agentDir: string): string {
21
- return path.join(agentDir, "subagents", SUBAGENTS_ENGINES_FILENAME);
22
- }
23
-
24
- /**
25
- * 把注册表引擎列表同步到 engines.json(session_start 时调用)。
26
- *
27
- * 幂等:内容与现文件一致时零写入(mtime 不动——读侧无谓失效);写入走 tmp+rename
28
- * 原子替换(与池 config 同防线)。fail-safe:任何 IO 异常吞掉(可发现性降级不阻塞
29
- * session 启动——GUI 兜底显示 ['pi'])。
30
- */
31
- export function syncEnginesFile(agentDir: string): void {
32
- try {
33
- const filePath = getEnginesFilePath(agentDir);
34
- const payload: SubagentEnginesFile = { v: 1, engines: listEngines(), updatedAt: Date.now() };
35
- const serialized = JSON.stringify(payload, null, 2);
36
- try {
37
- const existing = fs.readFileSync(filePath, "utf8");
38
- const parsed = JSON.parse(existing) as Partial<SubagentEnginesFile>;
39
- // 引擎清单未变则跳过(updatedAt 仅诊断,不参与判变)
40
- if (
41
- Array.isArray(parsed.engines) &&
42
- JSON.stringify(parsed.engines) === JSON.stringify(payload.engines) &&
43
- parsed.v === 1
44
- ) {
45
- return;
46
- }
47
- } catch {
48
- // 现文件缺失/损坏 → 走写入
49
- }
50
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
51
- const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
52
- try {
53
- fs.writeFileSync(tmp, serialized, "utf8");
54
- fs.renameSync(tmp, filePath);
55
- } finally {
56
- try {
57
- if (fs.existsSync(tmp)) fs.unlinkSync(tmp);
58
- } catch {
59
- // rename 失败路径的残留清理 best-effort
60
- }
61
- }
62
- } catch {
63
- // 吞掉:见文件头 fail-safe 说明
64
- }
65
- }