@zhushanwen/subagent-core 0.6.0 → 0.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 (278) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-KXVBIVOU.js +16 -0
  3. package/dist/chunk-T2SYBW3I.js +24 -0
  4. package/dist/chunk-VURUAGMM.js +2305 -0
  5. package/dist/{types-C3fE3R9x.d.cts → engine-discovery-scan-ocpM8FmI.d.cts} +770 -668
  6. package/dist/{types-C3fE3R9x.d.ts → engine-discovery-scan-ocpM8FmI.d.ts} +770 -668
  7. package/dist/execution/engine/engine-discovery-scan.cjs +2210 -0
  8. package/dist/execution/engine/engine-discovery-scan.d.cts +4 -0
  9. package/dist/execution/engine/engine-discovery-scan.d.ts +4 -0
  10. package/dist/execution/engine/engine-discovery-scan.js +20 -0
  11. package/dist/execution/engine/paths.cjs +6 -23
  12. package/dist/execution/engine/paths.d.cts +1 -8
  13. package/dist/execution/engine/paths.d.ts +1 -8
  14. package/dist/execution/engine/paths.js +1 -1
  15. package/dist/execution/relay-env.cjs +12 -28
  16. package/dist/execution/relay-env.d.cts +1 -33
  17. package/dist/execution/relay-env.d.ts +1 -33
  18. package/dist/execution/relay-env.js +5 -3
  19. package/dist/index.cjs +14045 -16059
  20. package/dist/index.d.cts +1035 -1579
  21. package/dist/index.d.ts +1035 -1579
  22. package/dist/index.js +9838 -13800
  23. package/dist.bundle/index.cjs +28875 -30323
  24. package/package.json +20 -26
  25. package/src/__tests__/record-store-last-line.test.ts +16 -7
  26. package/src/core/error-message.ts +7 -6
  27. package/src/core/host-services.ts +8 -2
  28. package/src/core/notify-ports.ts +17 -2
  29. package/src/execution/__tests__/chat-engine-routing.test.ts +62 -28
  30. package/src/execution/__tests__/chat-round-first-round-watchdog.test.ts +255 -0
  31. package/src/execution/__tests__/collect-coordinator-service.test.ts +36 -47
  32. package/src/execution/__tests__/collect-mixed-dispatch.test.ts +20 -53
  33. package/src/execution/__tests__/delivery-methods.test.ts +179 -237
  34. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -2
  35. package/src/execution/__tests__/execute-nesting.test.ts +20 -13
  36. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +20 -33
  37. package/src/execution/__tests__/gc-timer.test.ts +7 -22
  38. package/src/execution/__tests__/get-record-for-action-restart.test.ts +20 -10
  39. package/src/execution/__tests__/helpers/fake-engine-port.ts +187 -0
  40. package/src/execution/__tests__/helpers/spawn-mock.ts +36 -9
  41. package/src/execution/__tests__/helpers/subagent-service-mocks.ts +1 -1
  42. package/src/execution/__tests__/idle-gc.test.ts +200 -0
  43. package/src/execution/__tests__/lifecycle-predicates.test.ts +26 -21
  44. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +5 -2
  45. package/src/execution/__tests__/reconcile-sweep.test.ts +200 -0
  46. package/src/execution/__tests__/record-store.test.ts +60 -6
  47. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +20 -13
  48. package/src/execution/__tests__/round-supervisor.test.ts +293 -0
  49. package/src/execution/__tests__/session-pending.test.ts +119 -17
  50. package/src/execution/__tests__/stream-sink-retirement.test.ts +10 -10
  51. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +1 -11
  52. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +33 -30
  53. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +2 -9
  54. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +59 -129
  55. package/src/execution/__tests__/subagent-service.test.ts +2 -2
  56. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +109 -7
  57. package/src/execution/__tests__/subprocess-agent-runner.test.ts +108 -36
  58. package/src/execution/__tests__/sync-collect-recovery.test.ts +21 -36
  59. package/src/execution/__tests__/workflow-state-root.test.ts +232 -0
  60. package/src/execution/agent-registry.ts +6 -2
  61. package/src/execution/dialog-queue.ts +6 -73
  62. package/src/execution/engine/__tests__/common/capability-gate.test.ts +115 -15
  63. package/src/execution/engine/__tests__/common/errors.test.ts +11 -18
  64. package/src/execution/engine/__tests__/common/kill-chain.test.ts +7 -0
  65. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +9 -3
  66. package/src/execution/engine/__tests__/common/session-view-service.test.ts +90 -3
  67. package/src/execution/engine/__tests__/conformance/H9-test-disposition.md +116 -0
  68. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/fake-engine-protocol.mjs +377 -0
  69. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/recorded.fixture.json +331 -0
  70. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/smoke-run.fixture.json +213 -0
  71. package/src/execution/engine/__tests__/conformance/chat-round-protocol.test.ts +230 -0
  72. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +69 -42
  73. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +4 -81
  74. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +67 -44
  75. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +81 -54
  76. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +133 -70
  77. package/src/execution/engine/__tests__/conformance/engine-crash.test.ts +143 -0
  78. package/src/execution/engine/__tests__/conformance/fake-engine-capabilities.ts +19 -0
  79. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +7 -2
  80. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +6 -5
  81. package/src/execution/engine/__tests__/conformance/protocol-blackbox.test.ts +398 -0
  82. package/src/execution/engine/__tests__/conformance/registry-fork-filter.test.ts +221 -0
  83. package/src/execution/engine/__tests__/conformance/round-liveness-supervisor.test.ts +302 -0
  84. package/src/execution/engine/__tests__/conformance/static-spawn-guard.test.ts +58 -0
  85. package/src/execution/engine/__tests__/engine-discovery-scan.test.ts +558 -0
  86. package/src/execution/engine/__tests__/host-task-spec.test.ts +45 -0
  87. package/src/execution/engine/__tests__/model-ref-split.test.ts +74 -0
  88. package/src/execution/engine/__tests__/registry.test.ts +206 -1
  89. package/src/execution/engine/__tests__/routing.test.ts +97 -0
  90. package/src/execution/engine/__tests__/run-failure-worktree-cleanup.test.ts +97 -0
  91. package/src/execution/engine/client/__tests__/__fixtures__/fake-engine.mjs +294 -0
  92. package/src/execution/engine/client/__tests__/engine-client.test.ts +516 -0
  93. package/src/execution/engine/client/__tests__/mirror.test.ts +67 -0
  94. package/src/execution/engine/client/__tests__/pid-file.test.ts +257 -0
  95. package/src/execution/engine/client/__tests__/protocol-closure.test.ts +95 -0
  96. package/src/execution/engine/client/__tests__/remote-engine.test.ts +457 -0
  97. package/src/execution/engine/client/client-options.ts +103 -0
  98. package/src/execution/engine/client/engine-client.ts +687 -0
  99. package/src/execution/engine/client/mirror.ts +167 -0
  100. package/src/execution/engine/client/pid-file.ts +392 -0
  101. package/src/execution/engine/client/reaper.ts +95 -0
  102. package/src/execution/engine/client/remote-engine.ts +441 -0
  103. package/src/execution/engine/client/reverse-router.ts +255 -0
  104. package/src/execution/engine/common/capability-gate.ts +109 -22
  105. package/src/execution/engine/common/errors.ts +9 -25
  106. package/src/execution/engine/common/event-journal.ts +4 -50
  107. package/src/execution/engine/common/journal-replay.ts +3 -1
  108. package/src/execution/engine/common/kill-chain.ts +18 -251
  109. package/src/execution/engine/common/nesting-guard.ts +18 -114
  110. package/src/execution/engine/common/pool-manager.ts +4 -0
  111. package/src/execution/engine/common/session-view-service.ts +56 -84
  112. package/src/execution/engine/config.ts +151 -0
  113. package/src/execution/engine/d8-compat.ts +346 -0
  114. package/src/execution/engine/engine-discovery-roots.ts +107 -0
  115. package/src/execution/engine/engine-discovery-scan.ts +269 -0
  116. package/src/execution/engine/engine-discovery.ts +30 -7
  117. package/src/execution/engine/engine-inspect-package.ts +282 -0
  118. package/src/execution/engine/engine-manifest.ts +244 -0
  119. package/src/execution/engine/host/__tests__/host-askuser-endpoint.test.ts +123 -0
  120. package/src/execution/engine/host/__tests__/host-bridge.test.ts +135 -0
  121. package/src/execution/engine/host/__tests__/spawned-children.test.ts +73 -0
  122. package/src/execution/engine/host/host-bridge.ts +150 -0
  123. package/src/execution/engine/host/host-ui-endpoint.ts +47 -0
  124. package/src/execution/engine/host/pi-host-binding.ts +91 -0
  125. package/src/execution/engine/host/spawned-children.ts +139 -0
  126. package/src/execution/engine/host-task-spec.ts +29 -2
  127. package/src/execution/engine/model-validation.ts +55 -2
  128. package/src/execution/engine/paths.ts +16 -41
  129. package/src/execution/engine/port.ts +48 -2
  130. package/src/execution/engine/registry.ts +153 -34
  131. package/src/execution/engine/routing.ts +225 -52
  132. package/src/execution/engine/types.ts +25 -200
  133. package/src/execution/finalize-record.ts +25 -0
  134. package/src/execution/idle-gc.ts +89 -14
  135. package/src/execution/lifecycle-manager.ts +10 -7
  136. package/src/execution/lifecycle-predicates.ts +10 -8
  137. package/src/execution/record-store.ts +29 -2
  138. package/src/execution/relay-env.ts +19 -36
  139. package/src/execution/round-supervisor/domain.ts +89 -0
  140. package/src/execution/round-supervisor/index.ts +33 -0
  141. package/src/execution/round-supervisor/notify-accounting.ts +87 -0
  142. package/src/execution/round-supervisor/reconcile-sweep.ts +235 -0
  143. package/src/execution/round-supervisor/service-binding.test.ts +661 -0
  144. package/src/execution/round-supervisor/service-binding.ts +273 -0
  145. package/src/execution/round-supervisor/supervisor.ts +426 -0
  146. package/src/execution/session-pending.ts +68 -74
  147. package/src/execution/settled-watchdog.ts +39 -0
  148. package/src/execution/subagent-service.ts +746 -400
  149. package/src/execution/subprocess-agent-runner.ts +16 -8
  150. package/src/execution/types.ts +41 -117
  151. package/src/execution/ui-channels.ts +13 -214
  152. package/src/execution/ui-request-handler-factory.ts +7 -4
  153. package/src/execution/ui-request-observability.ts +2 -2
  154. package/src/execution/workflow-state-root.ts +67 -0
  155. package/src/execution/worktree-git-ops.ts +5 -0
  156. package/src/execution/worktree-manager.ts +11 -1
  157. package/src/index.ts +55 -26
  158. package/src/orchestration/__tests__/execute-agent-call.test.ts +1 -1
  159. package/src/orchestration/execute-agent-call.ts +1 -1
  160. package/src/orchestration/file-run-store.ts +144 -59
  161. package/src/orchestration/models/types.ts +43 -42
  162. package/src/shared/zcode-model-ref.ts +31 -0
  163. package/dist/chunk-43ONBFZX.js +0 -240
  164. package/dist/chunk-A4IVZWVX.js +0 -31
  165. package/dist/chunk-APZY4IME.js +0 -27
  166. package/dist/chunk-V3VHZ2VX.js +0 -59
  167. package/dist/execution/engine/engines/zcode/constants.cjs +0 -107
  168. package/dist/execution/engine/engines/zcode/constants.d.cts +0 -135
  169. package/dist/execution/engine/engines/zcode/constants.d.ts +0 -135
  170. package/dist/execution/engine/engines/zcode/constants.js +0 -54
  171. package/dist/execution/engine/engines/zcode/reader.cjs +0 -276
  172. package/dist/execution/engine/engines/zcode/reader.d.cts +0 -21
  173. package/dist/execution/engine/engines/zcode/reader.d.ts +0 -21
  174. package/dist/execution/engine/engines/zcode/reader.js +0 -9
  175. package/src/__tests__/append-system-prompt-assembly.test.ts +0 -243
  176. package/src/__tests__/fr4-get-state-handshake.test.ts +0 -125
  177. package/src/__tests__/session-runner.test.ts +0 -69
  178. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  179. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -191
  180. package/src/execution/__tests__/descendant-sweep-guards.test.ts +0 -220
  181. package/src/execution/__tests__/descendant-sweep.test.ts +0 -269
  182. package/src/execution/__tests__/engine-model-validation.test.ts +0 -741
  183. package/src/execution/__tests__/epipe-fallback.test.ts +0 -248
  184. package/src/execution/__tests__/execution-runtime-face.test.ts +0 -272
  185. package/src/execution/__tests__/get-state-handshake.test.ts +0 -127
  186. package/src/execution/__tests__/helpers/session-runner-mocks.ts +0 -113
  187. package/src/execution/__tests__/keep-alive-no-progress.test.ts +0 -280
  188. package/src/execution/__tests__/kill-all-escalation.test.ts +0 -196
  189. package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +0 -113
  190. package/src/execution/__tests__/output-collector.test.ts +0 -469
  191. package/src/execution/__tests__/pi-invocation.test.ts +0 -166
  192. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -149
  193. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  194. package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +0 -387
  195. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -277
  196. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -254
  197. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -1079
  198. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  199. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  200. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  201. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -207
  202. package/src/execution/__tests__/service-kill-escalation.test.ts +0 -91
  203. package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +0 -110
  204. package/src/execution/__tests__/session-runner-close-prune.test.ts +0 -181
  205. package/src/execution/__tests__/session-runner-dispatch.test.ts +0 -489
  206. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -179
  207. package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +0 -227
  208. package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +0 -290
  209. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -352
  210. package/src/execution/__tests__/settled-watchdog.test.ts +0 -524
  211. package/src/execution/__tests__/spawn-args.test.ts +0 -446
  212. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -192
  213. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  214. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -208
  215. package/src/execution/__tests__/spawned-children.test.ts +0 -236
  216. package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
  217. package/src/execution/__tests__/stdin-writer.test.ts +0 -464
  218. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -693
  219. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  220. package/src/execution/__tests__/timeout-integration.test.ts +0 -616
  221. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  222. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  223. package/src/execution/__tests__/ui-request-handler.test.ts +0 -205
  224. package/src/execution/__tests__/ui-request-queue.test.ts +0 -298
  225. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -230
  226. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  227. package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +0 -149
  228. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  229. package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +0 -128
  230. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  231. package/src/execution/engine/common/schema-emulation.ts +0 -189
  232. package/src/execution/engine/common/session-view-projection.ts +0 -51
  233. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -615
  234. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  235. package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +0 -257
  236. package/src/execution/engine/engines/pi/argv-mirror.ts +0 -135
  237. package/src/execution/engine/engines/pi/get-state-handshake.ts +0 -179
  238. package/src/execution/engine/engines/pi/output-collector.ts +0 -317
  239. package/src/execution/engine/engines/pi/pi-engine.ts +0 -811
  240. package/src/execution/engine/engines/pi/pi-invocation.ts +0 -120
  241. package/src/execution/engine/engines/pi/reader.ts +0 -59
  242. package/src/execution/engine/engines/pi/registration.ts +0 -37
  243. package/src/execution/engine/engines/pi/session-runner.ts +0 -2840
  244. package/src/execution/engine/engines/pi/spawn-event-adapter.ts +0 -404
  245. package/src/execution/engine/engines/pi/stdin-writer.ts +0 -199
  246. package/src/execution/engine/engines/pi/temp-prompt.ts +0 -62
  247. package/src/execution/engine/engines/pi/turn-limiter.ts +0 -102
  248. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +0 -301
  249. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +0 -36
  250. package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +0 -321
  251. package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +0 -473
  252. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -43
  253. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -124
  254. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  255. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -71
  256. package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +0 -247
  257. package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +0 -451
  258. package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +0 -792
  259. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +0 -782
  260. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +0 -168
  261. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +0 -210
  262. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +0 -353
  263. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +0 -282
  264. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +0 -372
  265. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -145
  266. package/src/execution/engine/engines/zcode/appserver-launcher.ts +0 -167
  267. package/src/execution/engine/engines/zcode/connection.ts +0 -598
  268. package/src/execution/engine/engines/zcode/constants.ts +0 -176
  269. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -47
  270. package/src/execution/engine/engines/zcode/parser.ts +0 -102
  271. package/src/execution/engine/engines/zcode/preparer.ts +0 -235
  272. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  273. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  274. package/src/execution/engine/engines/zcode/session-channel.ts +0 -968
  275. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -1431
  276. package/src/execution/round-settlement.ts +0 -93
  277. package/src/execution/ui-request-queue.ts +0 -215
  278. package/src/shared/schema-env.ts +0 -44
@@ -1,27 +1,91 @@
1
1
  // src/execution/engine/routing.ts
2
2
  //
3
- // 配置路由与探针 fallback 编排(P4)。设计权威源:
4
- // docs/architecture/subagent-engine-abstraction.md D9(配置路由三层 + 故障 fallback
5
- // 三守卫 + model/engine 正交 + workflow 脚本不写死 engine)+ D7(探针分级与触发时机)
6
- // + §3.3.3 错误规格(engine_probe_failed / model_not_available 行)。
3
+ // 配置路由与探针 fallback 编排(P4;W3 协议化改造)。设计权威源(现行):
4
+ // docs/design/subagent-engine-protocolization.md §3.8 D4(缺省引擎与 fallback 目标)/
5
+ // §3.5.3(路由与执行时序契约——跨进程后作废「run 内首个 await 前已触达 executeAndAwait」,
6
+ // 改为「首个 await 前完成路由决策;执行经进程边界,时序契约由本设计放宽」);
7
+ // 历史权威源 docs/architecture/subagent-engine-abstraction.md D9(配置路由三层 + 故障
8
+ // fallback 三守卫 + model/engine 正交 + workflow 脚本不写死 engine)+ D7(探针分级与
9
+ // 触发时机)+ §3.3.3 错误规格仍然有效。
7
10
  //
8
11
  // 职责边界:本模块只做「选哪个引擎」的决策(纯路由 + probe 编排),不 spawn、不读
9
12
  // 任务正文。三层优先级与守卫的判定规则集中于此单一权威点——上层(SAR)只消费
10
13
  // routeEngine 的结果,散落的 if engine === ... 分派被结构性排除。
11
14
  //
12
- // probe 触发时机(D7「引擎 factory 初始化与版本变化检测时触发」的 P4 落地口径):
13
- // 路由期触发、结果缓存于引擎实例(probeCache)。缺省引擎 'pi' 免探——pi 契约稳定
14
- // (rpc.md 官方,D7 稳定性光谱的轻探针端)且「缺省路径行为零变化」是 A1 硬约束
15
- // (每次 run 前强探会引入 pi --version 子进程开销与新的失败面);显式 engine='pi'
16
- // 同样免探(fallback 无处可去,守卫 a pi 不可达是自然结果而非缺口)。进程存活
17
- // 期间缓存不失效——版本变化(运行中 CLI 被升级)由 engine_run_failed 运行中兜底
18
- // (D11 规则②封边界的既有设计),重启进程 / registerEngine 覆盖后重探。
15
+ // probe 触发时机(D7 的落地口径):路由期触发、结果缓存于引擎实例(probeCache)。
16
+ // 内置缺省 pi 免探——pi 契约稳定且「缺省路径行为零变化」是 A1 硬约束(每次 run 前
17
+ // 强探会引入 pi --version 子进程开销与新的失败面);显式 engine='pi' 同样免探
18
+ // (fallback 无处可去,守卫 a pi 不可达是自然结果而非缺口)。协议化后 cli 形态
19
+ // 引擎的首个 run 前强制 initialize(协议握手,EngineClient 承担),与 probe 分立。
20
+ // 进程存活期间缓存不失效——版本变化(运行中 CLI 被升级)由 engine_run_failed 运行中
21
+ // 兜底,重启进程 / 重新注册后重探。
22
+
23
+ import { getLogger } from "../../core/logger.ts";
19
24
 
20
25
  import { EngineError } from "./common/errors.ts";
21
26
  import type { EnginePort } from "./port.ts";
22
- import { DEFAULT_ENGINE_ID, EngineNotFoundError, getEngine, hasEngine, listEngines } from "./registry.ts";
27
+ import {
28
+ DEFAULT_ENGINE_ID,
29
+ EngineNotFoundError,
30
+ getEngine,
31
+ hasEngine,
32
+ listEngines,
33
+ listEnginesByDisplayName,
34
+ } from "./registry.ts";
35
+ import {
36
+ ensureEngineDiscovered,
37
+ type DiscoverEnginesOptions,
38
+ } from "./engine-discovery-scan.ts";
23
39
  import type { ProbeReport } from "./types.ts";
24
40
 
41
+ // core log facade(execution 层统一 "subagents" component,模块顶层缓存惯例)。
42
+ const logger = getLogger("subagents");
43
+
44
+ // ============================================================
45
+ // [W8] hasEngine 补扫通道(W4 ensureEngineDiscovered 的存在性校验接线)
46
+ // ============================================================
47
+
48
+ // 补扫发现参数 slot(globalThis[Symbol.for]——防 jiti 双路径加载分裂,对齐 registry
49
+ // slot 惯例)。写入方 = 宿主接线面(runtime 在 W8 subagent-engine-history 的
50
+ // ensureRuntimeEngineWiring 装载;pi 壳接线归后续单元——slot 未设置时本通道与裸
51
+ // hasEngine 等价,零行为变化)。参数与 session_start 发现扫描同源(hostKind/agentDir/
52
+ // dataDir),补扫只读 manifest 不握手(DiscoverEnginesOptions 语义)。
53
+ const RESCAN_OPTS_SLOT_KEY = Symbol.for("@zhushanwen/pi-subagent-workflow.engineDiscoveryRescanOpts");
54
+
55
+ /** 宿主接线:登记补扫发现参数(与发现扫描同源;重复登记覆盖,幂等)。 */
56
+ export function setEngineDiscoveryRescanOptions(opts: DiscoverEnginesOptions): void {
57
+ Reflect.set(globalThis, RESCAN_OPTS_SLOT_KEY, { current: opts });
58
+ }
59
+
60
+ function getEngineDiscoveryRescanOptions(): DiscoverEnginesOptions | undefined {
61
+ const slot = Reflect.get(globalThis, RESCAN_OPTS_SLOT_KEY) as
62
+ | { current: DiscoverEnginesOptions }
63
+ | undefined;
64
+ return slot?.current;
65
+ }
66
+
67
+ /**
68
+ * 存在性校验(快照优先 + 一次补扫):registry 快照命中零开销返回;未命中且宿主已
69
+ * 接线补扫参数 → ensureEngineDiscovered 同步补扫(只读 manifest 不 spawn)后复核;
70
+ * 宿主未接线 → 与裸 hasEngine 等价。补扫异常吞掉返回 false(发现失败 ≠ 配置错误,
71
+ * 由 routeEngine 的 engine_not_found 恢复指引收口)。
72
+ */
73
+ export function hasEngineWithRescan(id: string): boolean {
74
+ if (hasEngine(id)) return true;
75
+ const opts = getEngineDiscoveryRescanOptions();
76
+ if (opts === undefined) return false;
77
+ try {
78
+ return ensureEngineDiscovered(id, opts);
79
+ } catch (err) {
80
+ logger.debug(
81
+ `[engine-routing] rescan for engine '${id}' failed (treated as not discovered): ${
82
+ err instanceof Error ? err.message : String(err)
83
+ }`,
84
+ );
85
+ return false;
86
+ }
87
+ }
88
+
25
89
  // ============================================================
26
90
  // 三层优先级(D9)
27
91
  // ============================================================
@@ -91,6 +155,12 @@ export interface EngineRouteOptions {
91
155
  hasEngineFn?: (engineId: string) => boolean;
92
156
  /** 注册表清单(缺省 registry.listEngines——engine_not_found 文案的数据源)。 */
93
157
  listEnginesFn?: () => string[];
158
+ /**
159
+ * 可用引擎清单(D4 回落目标序:manifest displayName 稳定序;缺省
160
+ * registry.listEnginesByDisplayName)。清单内 id 即视为可用(发现且已注册)——
161
+ * 调用方负责排序口径;routeEngine 按序取第一个 ≠ 请求引擎的 id 作回落目标。
162
+ */
163
+ listAvailableEnginesFn?: () => string[];
94
164
  }
95
165
 
96
166
  export interface EngineRouteResult {
@@ -105,46 +175,128 @@ export interface EngineRouteResult {
105
175
  engineFallback?: { from: string; reason: string };
106
176
  }
107
177
 
178
+ /**
179
+ * D4 缺省引擎回落(default 层专用):配置的缺省引擎 id 不在已发现清单(引擎被卸载 /
180
+ * 未安装任何引擎包)→ warn + 回落第一个可用引擎(manifest displayName 稳定序)+
181
+ * engineFallback 留痕(record 投影)。全不可用(清单空)→ 返回 undefined,调用方抛
182
+ * engine_not_found(「未发现任何引擎包」+ 安装指引),不静默。
183
+ *
184
+ * 宽容回落只作用于 default 层:call/frontmatter 层显式指定的未知 id 是配置错误
185
+ * (agent 作者/调用方写错),保持 engine_not_found 前置暴露(错误规格表第 1 行)——
186
+ * 静默换引擎会违反显式意图(守卫 a 同源)。
187
+ */
188
+ function resolveDefaultEngineFallback(
189
+ requestedId: string,
190
+ available: readonly string[],
191
+ ): { engineId: string; fallback: { from: string; reason: string } } | undefined {
192
+ if (available.length === 0) return undefined;
193
+ const target = available[0]!;
194
+ logger.warn(
195
+ `[engine-routing] default engine '${requestedId}' is not in the discovered engines ` +
196
+ `[${available.join(", ")}]; falling back to first available engine '${target}' (D4, recorded via engineFallback)`,
197
+ );
198
+ return { engineId: target, fallback: { from: requestedId, reason: "engine_not_found" } };
199
+ }
200
+
108
201
  /**
109
202
  * 路由 + 探针 + fallback 编排(SAR run 入口调用)。
110
203
  *
111
204
  * 失败形态(全部抛结构化错误,调用方转 AgentResult.error):
112
- * - 未注册 id(调用参数层漏网):EngineNotFoundError(engine_not_found)
205
+ * - 未注册 id(call/frontmatter 层):EngineNotFoundError(engine_not_found)
206
+ * - default 层缺省引擎不在清单且无任何可用引擎:EngineNotFoundError
207
+ * (「未发现任何引擎包」+ 安装指引,D4)
113
208
  * - strict 或守卫命中:EngineError(engine_probe_failed)
114
209
  * - 守卫 c(显式 model + 将换引擎):EngineError(model_not_available)
115
210
  */
116
211
  export async function routeEngine(opts: EngineRouteOptions): Promise<EngineRouteResult> {
117
- const has = opts.hasEngineFn ?? hasEngine;
118
- const get = opts.getEngineFn ?? getEngine;
212
+ const { has, get, available } = resolveRouteHelpers(opts);
119
213
  const routing = resolveEngineRouting(opts.routing);
120
214
 
121
- // 调用参数层的注册表校验(frontmatter 层已在 agent 解析期抛过;这里兜调用参数
122
- // 直传的未注册 id——错误含注册清单,配置错误前置到路由期而非 getEngine 深处)
215
+ // 注册表校验:call/frontmatter 层未知 id 直接报(配置错误前置暴露);default 层走
216
+ // D4 宽容回落(配置的缺省引擎被卸载 ≠ 用户写错 id——环境变化,回落 + 留痕)。
123
217
  if (!has(routing.engineId)) {
124
- throw new EngineNotFoundError(routing.engineId, opts.listEnginesFn?.() ?? listEngines(), describeRoutingSource(opts.routing));
218
+ return resolveUnregisteredEngine(opts, routing, get, available);
125
219
  }
126
220
 
127
- // 缺省引擎免探(见文件头「probe 触发时机」)——直接取引擎
221
+ // 内置缺省 pi 免探(见文件头「probe 触发时机」)——直接取引擎
128
222
  if (routing.engineId === DEFAULT_ENGINE_ID) {
129
- return {
130
- engine: get(routing.engineId),
131
- engineId: routing.engineId,
132
- requestedEngineId: routing.engineId,
133
- source: routing.source,
134
- };
223
+ return directRoute(get(routing.engineId), routing);
135
224
  }
136
225
 
137
226
  const report = await opts.probe(routing.engineId);
138
227
  if (report.ok) {
139
- return {
140
- engine: get(routing.engineId),
141
- engineId: routing.engineId,
142
- requestedEngineId: routing.engineId,
143
- source: routing.source,
144
- };
228
+ return directRoute(get(routing.engineId), routing);
145
229
  }
146
230
 
147
- // ── probe 失败:strict / 三守卫 / fallback(D9①)──
231
+ return resolveProbeFailedRoute(opts, routing, get, available, report);
232
+ }
233
+
234
+ /**
235
+ * routeEngine 的注入解析。[W8 补扫接线] 缺省存在性校验经 hasEngineWithRescan(快照
236
+ * 未命中触发一次三级补扫,W4 ensureEngineDiscovered 通道——「装了包 → 下次解析即可用」);
237
+ * 宿主显式注入 hasEngineFn 时以注入值为准(测试 / 宿主自定义通道不变)。
238
+ */
239
+ function resolveRouteHelpers(opts: EngineRouteOptions): {
240
+ has: (engineId: string) => boolean;
241
+ get: (engineId: string) => EnginePort;
242
+ available: () => string[];
243
+ } {
244
+ return {
245
+ has: opts.hasEngineFn ?? hasEngineWithRescan,
246
+ get: opts.getEngineFn ?? getEngine,
247
+ available: opts.listAvailableEnginesFn ?? listEnginesByDisplayName,
248
+ };
249
+ }
250
+
251
+ /**
252
+ * 注册表校验失败(请求 id 未发现)的收口:default 层 D4 宽容回落(清单空 → throw
253
+ * 「未发现任何引擎包」+ 安装指引,不静默);call/frontmatter 层配置错误前置暴露。
254
+ */
255
+ function resolveUnregisteredEngine(
256
+ opts: EngineRouteOptions,
257
+ routing: EngineRouting,
258
+ get: (engineId: string) => EnginePort,
259
+ available: () => string[],
260
+ ): EngineRouteResult {
261
+ if (routing.source !== "default") {
262
+ throw new EngineNotFoundError(routing.engineId, opts.listEnginesFn?.() ?? listEngines(), describeRoutingSource(opts.routing));
263
+ }
264
+ const fallback = resolveDefaultEngineFallback(routing.engineId, available());
265
+ if (fallback === undefined) {
266
+ // 全不可用:派发期 engine_not_found(「未发现任何引擎包」+ 安装指引,D4)
267
+ throw new EngineNotFoundError(routing.engineId, [], describeRoutingSource(opts.routing));
268
+ }
269
+ const fallbackTrace = fallback.fallback;
270
+ // 回落目标直接取用不探(probe 已失败一次不重复;目标引擎不可用由 run 期显式失败)
271
+ return {
272
+ engine: get(fallback.engineId),
273
+ engineId: fallback.engineId,
274
+ requestedEngineId: fallbackTrace.from,
275
+ source: routing.source,
276
+ engineFallback: fallbackTrace,
277
+ };
278
+ }
279
+
280
+ /** 直接取用形态(pi 免探 / probe 通过):请求即执行,无 fallback 留痕。 */
281
+ function directRoute(engine: EnginePort, routing: EngineRouting): EngineRouteResult {
282
+ return {
283
+ engine,
284
+ engineId: routing.engineId,
285
+ requestedEngineId: routing.engineId,
286
+ source: routing.source,
287
+ };
288
+ }
289
+
290
+ /**
291
+ * probe 失败收口:strict / 三守卫 / fallback(D9① + D4 回落目标改「首个可用引擎」)。
292
+ */
293
+ function resolveProbeFailedRoute(
294
+ opts: EngineRouteOptions,
295
+ routing: EngineRouting,
296
+ get: (engineId: string) => EnginePort,
297
+ available: () => string[],
298
+ report: ProbeReport,
299
+ ): EngineRouteResult {
148
300
  if (opts.strict) {
149
301
  throw probeFailedError(routing.engineId, report, "engineRouting.strict=true:probe 失败一律报错(不 fallback)");
150
302
  }
@@ -156,7 +308,11 @@ export async function routeEngine(opts: EngineRouteOptions): Promise<EngineRoute
156
308
  throw probeFailedError(routing.engineId, report, "engine 来自调用参数显式指定(能力依赖声明)——不兜底");
157
309
  }
158
310
 
159
- const fallbackId = fallbackTargetId(opts.routing, routing);
311
+ const fallbackId = fallbackTargetId(opts.routing, routing, available());
312
+ // D4:无可用引擎则不 fallback(直接报错)——回「未发现任何引擎包」口径,不静默
313
+ if (fallbackId === undefined) {
314
+ throw probeFailedError(routing.engineId, report, "probe 失败且无其他可用引擎可兜底(D4:不原地重试坏引擎)");
315
+ }
160
316
  // 守卫 c:显式 model 与引擎 provider 体系绑定(D9② model/engine 正交)——换引擎
161
317
  // 后 model 可解析性无法保证,静默换引擎跑 = 「以为用了 X 实际用 Y」。判定取保守
162
318
  // 口径(显式 model + 引擎切换即拒):路由层无各引擎 provider 注册表的访问面,
@@ -179,21 +335,28 @@ export async function routeEngine(opts: EngineRouteOptions): Promise<EngineRoute
179
335
  }
180
336
 
181
337
  /**
182
- * fallback 目标:请求来自 frontmatter/调用参数 全局默认引擎;请求即全局默认
183
- * (defaultEngine 配了坏引擎,source='default')→ 内置缺省 'pi'(零风险回退——设计
184
- * 终态四口径:fallback 回「缺省 pi」而非原地重试坏引擎)。全局默认与请求引擎相同
185
- * (frontmatter engine === defaultEngine,如 agent .md engine: zcode + config
186
- * defaultEngine: zcode)同样回 'pi'——回退到刚 probe 失败的同一引擎 = 原地重试坏
187
- * 引擎(from==to 误导留痕),违背「回缺省 pi」的设计意图。
338
+ * fallback 目标(D4 终态语义:恒 'pi' 改「首个可用引擎」,无可用引擎返回 undefined
339
+ * 由调用方直接报错不 fallback)。available = D4 排序清单(manifest displayName 稳定序)。
340
+ *
341
+ * - 请求来自 frontmatter/调用参数:优先全局默认引擎(可用且 刚失败引擎时);
342
+ * 全局默认不可用/未配置/即请求引擎 首个可用引擎(排除 from——回退到刚 probe
343
+ * 失败的同一引擎 = 原地重试坏引擎,from==to 误导留痕)。
344
+ * - 请求即全局默认(defaultEngine 配了坏引擎,source='default'):首个可用引擎。
345
+ * - 清单排除 from 后为空 → undefined(无可用引擎,直接报错)。
188
346
  */
189
- function fallbackTargetId(routingInput: EngineRoutingInput, resolved: EngineRouting): string {
347
+ function fallbackTargetId(
348
+ routingInput: EngineRoutingInput,
349
+ resolved: EngineRouting,
350
+ available: readonly string[],
351
+ ): string | undefined {
190
352
  // source 与 engineId 由 resolved 承载配对关系,杜绝调用方传错配对的口子
191
- if (resolved.source === "default") return DEFAULT_ENGINE_ID;
192
- const global = routingInput.globalDefaultEngine;
193
- if (hasText(global) && global !== DEFAULT_ENGINE_ID && global !== resolved.engineId) {
194
- return global;
353
+ if (resolved.source !== "default") {
354
+ const global = routingInput.globalDefaultEngine;
355
+ if (hasText(global) && global !== resolved.engineId && available.includes(global)) {
356
+ return global;
357
+ }
195
358
  }
196
- return DEFAULT_ENGINE_ID;
359
+ return available.find((id) => id !== resolved.engineId);
197
360
  }
198
361
 
199
362
  /** engine_probe_failed 的结构化构造(detail 含逐 check 摘要,recovery 用探针产出)。 */
@@ -237,7 +400,7 @@ export interface HostRouteOptions {
237
400
  probe: (engineId: string) => Promise<ProbeReport>;
238
401
  /**
239
402
  * 本地 pi 引擎实例(chat 域 = Service 的 chatPiEngine;workflow 域 = SAR 的 per-session
240
- * DI 实例)。pi 请求与「非 pi 兜底回 pi」两种形态都由它接管——不依赖 registry 全局
403
+ * DI 实例)。pi 请求与「兜底回 pi」两种形态都由它接管——不依赖 registry 全局
241
404
  * 注册态(单测注入 mock 时全局单例不可见;生产环境两者是同一进程单例对象)。
242
405
  */
243
406
  piEngine: EnginePort;
@@ -247,17 +410,21 @@ export interface HostRouteOptions {
247
410
  hasEngineFn?: (engineId: string) => boolean;
248
411
  /** 非 pi 注册表清单(缺省 registry.listEngines)。 */
249
412
  listEnginesFn?: () => string[];
413
+ /** D4 可用引擎清单(缺省 registry.listEnginesByDisplayName;透传 routeEngine)。 */
414
+ listAvailableEnginesFn?: () => string[];
250
415
  }
251
416
 
252
417
  /**
253
418
  * 宿主侧统一路由编排(D3-②:唯一实现,两调用点——SubagentService.execute 与
254
419
  * SAR.run)。把原先散在两调用点的「pi 同步短路 + registry 注入(本地 pi 恒可用,
255
- * engine_not_found 文案不把本地 pi 漏报成未注册)+ 兜底回 pi 时换本地实例」收敛到本函数。
420
+ * engine_not_found 文案不把本地 pi 漏报成未注册)+ 兜底换本地实例」收敛到本函数。
256
421
  *
257
- * 返回值形态(时序契约):pi 请求路径**同步返回** EngineRouteResult(非 Promise)——
258
- * 不引入微任务边界,SAR 的「run 内首个 await 前已触达 executeAndAwait」缺省路径时序
259
- * 与旧形态逐字节一致;非 pi 路径返回 Promise(probe 编排固有异步),调用方统一用
260
- * `routed instanceof Promise ? await routed : routed` 消费(pi 路径零 await)。
422
+ * 时序契约(W3 改写,设计 §3.5.3):pi 请求路径**同步返回** EngineRouteResult(非
423
+ * Promise)——**首个 await 前完成路由决策**(engine id 已定,A2 观测点);其后的执行
424
+ * 经进程边界(cli 形态 spawn + 握手 + 帧往返必经 await),「run 内首个 await 前已触达
425
+ * `executeAndAwait`」的旧时序契约由本设计**作废放宽**。非 pi 路径返回 Promise(probe
426
+ * 编排固有异步),调用方统一用 `routed instanceof Promise ? await routed : routed` 消费
427
+ * (pi 路径零 await)。
261
428
  */
262
429
  export function routeEngineForHost(opts: HostRouteOptions): EngineRouteResult | Promise<EngineRouteResult> {
263
430
  const routing = resolveEngineRouting(opts.routing);
@@ -279,7 +446,7 @@ export function routeEngineForHost(opts: HostRouteOptions): EngineRouteResult |
279
446
  strict: opts.strict,
280
447
  probe: opts.probe,
281
448
  // 本地 pi 恒可用(per-session DI 绑定)——get/has/list 注入同一口径:
282
- // probe 失败兜底回 pi 时取本地实例接管,engine_not_found 文案不漏报本地 pi。
449
+ // probe 失败兜底时取本地实例接管,engine_not_found 文案不漏报本地 pi。
283
450
  getEngineFn: (engineId) =>
284
451
  engineId === DEFAULT_ENGINE_ID ? opts.piEngine : (opts.getEngineFn?.(engineId) ?? getEngine(engineId)),
285
452
  hasEngineFn: (engineId) =>
@@ -288,5 +455,11 @@ export function routeEngineForHost(opts: HostRouteOptions): EngineRouteResult |
288
455
  const listed = opts.listEnginesFn?.() ?? listEngines();
289
456
  return listed.includes(DEFAULT_ENGINE_ID) ? listed : [DEFAULT_ENGINE_ID, ...listed];
290
457
  },
458
+ // D4 可用清单透传(缺省 displayName 稳定序;注入缺失时本地 pi 仍须在清单内,
459
+ // 否则 fallback「首个可用引擎」会把本地 pi 漏掉)
460
+ listAvailableEnginesFn: () => {
461
+ const available = opts.listAvailableEnginesFn?.() ?? listEnginesByDisplayName();
462
+ return available.includes(DEFAULT_ENGINE_ID) ? available : [DEFAULT_ENGINE_ID, ...available];
463
+ },
291
464
  });
292
465
  }
@@ -3,111 +3,48 @@
3
3
  // 引擎中立类型层(P1)。设计权威源:docs/architecture/subagent-engine-abstraction.md
4
4
  // §3.3.5(EnginePort 与中立类型完整契约)+ §3.3.6(EngineHandle/journal/SessionView 格式)。
5
5
  //
6
- // 为什么单独一层:执行层现有四个核心类型(ExecuteOptions/AgentEvent/AgentResult/AgentRunner
7
- // port)的中立是「碰巧的,不是设计的」——thinkingLevel pi 7 档枚举、skillPath 假设引擎有
8
- // --skill flag、conversation/idleTimeoutMs 是 pi chatMode 专属形态(设计 §2.1)。本文件把
9
- // 「agent 调用」的引擎无关语义显式化为 AgentOutcome 等类型,EnginePort(port.ts)与其下
10
- // 各引擎适配器都以本层为唯一契约点。
11
- //
12
- // [D6 任务形状合流] 原本层的任务声明类型 AgentTaskSpec/PersonaSpec 已并入
13
- // orchestration/models/types.ts 的 AgentCallOpts(单一任务形状,SAR 直产、pi 边界一次
14
- // 直出——docs/design/subagent-dual-track-convergence.md §3.3 D6)。本文件不再定义任务
15
- // 声明;EnginePort.run 的入参即 AgentCallOpts(字段裁定与裁撤记录见其类型注释)。
6
+ // [S4 簇 3 收编] 契约类型单源化(type-only):AgentOutcome / EngineHandleData /
7
+ // ReplayedTurn / SessionView / EngineCapabilities / ProbeReport / InteractAction /
8
+ // InteractResult 的本地定义已删除,自 @zhushanwen/subagent-engine-sdk re-export
9
+ // (SDK protocol/contract-types.ts 是类型闭包 SSOT,core 反向 re-export 保上层消费面
10
+ // ——import 方路径零改动;结构等价由 protocol-closure.test.ts 断言族守卫)。
11
+ // EngineHandle 留守本地:SDK 无此类型(协议面用裸 data 载荷),宿主侧句柄包装接口
12
+ // core 域概念。
16
13
  //
17
14
  // AgentResult 消歧(设计 §2.1/§3.3.5):仓内有两个同名 AgentResult——
18
15
  // ① orchestration 层 workflow 消费的那份(orchestration/models/types.ts,主字段
19
- // content/parsedOutput/usage/error)——中立层锚定这份,AgentOutcome 的字段就是它的
20
- // 超集(+ engineId/engineFallback/exitCode);
16
+ // content/parsedOutput/usage/error)——SDK AgentOutcome 锚定这份;
21
17
  // ② execution 层的同名类型(execution/types.ts,主字段 text/turns/sessionId/toolCalls)
22
18
  // ——record 内部投影,保持原名不动。
23
19
  // 引擎层终态命名 AgentOutcome,与两者不同名,消除「同名不同义」。
24
20
 
25
- import type { AgentFailureKind, AgentUsage, ToolCallEntry } from "../../orchestration/models/types.ts";
26
- import type { AgentUsageTotal, ToolCall } from "../types.ts";
21
+ import type { EngineHandleData } from "@zhushanwen/subagent-engine-sdk";
27
22
 
28
- // AgentEvent 8 种事件原样保留,唯一权威定义仍是 execution/types.ts——引擎层 re-export
29
- // 不复制第二份(设计 §3.3.5);经 shared/agent-event.ts 的既有出口转发,维持「shared/
30
- // 是类型共享层」的架构约定。新增粗粒度约束(coarse 引擎至少合成一次 message_end +
31
- // 一次 turn_end)由 conformance 套件断言(P4),不在类型层编码。
23
+ // AgentEvent 8 种事件:权威定义在 SDK contract-types,经 execution/types.ts re-export
24
+ // shared/agent-event.ts 转发层 → 本文件(链条保持,维持「shared/ 是类型共享层」的
25
+ // 架构约定)。新增粗粒度约束(coarse 引擎至少合成一次 message_end + 一次 turn_end)
26
+ // conformance 套件断言(P4),不在类型层编码。
32
27
  export type { AgentEvent } from "../../shared/agent-event.ts";
33
28
 
34
29
  // ============================================================
35
- // AgentOutcome(锚定 orchestration AgentResult,§3.3.5
30
+ // SDK 契约类型 re-export(单源收编,S4 3)
36
31
  // ============================================================
37
32
 
38
- /**
39
- * 一次引擎执行的终态。锚定 orchestration/models/types.ts 的 AgentResult(workflow
40
- * 引擎消费的那份——content/parsedOutput/usage/error)并追加引擎层字段;见文件头消歧说明。
41
- */
42
- export interface AgentOutcome {
43
- /** 原样(AgentResult.content)。 */
44
- content: string;
45
- /**
46
- * 原样(AgentResult.failureKind,D5-③ 失败分诊结构化标签)。产出侧唯一识别点 =
47
- * engines/pi/output-collector(collectResult 分类写入);缺省 = unknown = 可重试
48
- * (消费侧 executeAgentCall 只读字段分诊,不扫 error 文案)。非 pi 引擎不产出,
49
- * 恒缺省(unknown 语义)。
50
- */
51
- failureKind?: AgentFailureKind;
52
- /**
53
- * 原样(AgentResult.parsedOutput)。native 引擎直传 / 仿真层 ajv 产出(D4 硬分流:
54
- * native 路径公共层不做二次校验、不改写其结果)。
55
- */
56
- parsedOutput?: unknown;
57
- /** 原样(AgentResult.usage,orchestration 版 AgentUsage:含 contextTokens/turns)。 */
58
- usage?: AgentUsage;
59
- /** 原样(AgentResult.durationMs)。 */
60
- durationMs?: number;
61
- /** 原样(AgentResult.error,错误码前缀格式见设计 §3.3.3 错误规格表)。 */
62
- error?: string;
63
- /** 原样(AgentResult.sessionId,引擎语义 session id)。 */
64
- sessionId?: string;
65
- /** 原样(AgentResult.sessionFile)。 */
66
- sessionFile?: string;
67
- /** 原样(AgentResult.worktreePath,仅诊断——目录可能已被 finalize 清理)。 */
68
- worktreePath?: string;
69
- /** 原样(AgentResult.toolCalls,ToolCallEntry[])。 */
70
- toolCalls?: ToolCallEntry[];
71
- /** 新增:实际执行引擎(fallback 后可能 ≠ 请求值,D9①)。 */
72
- engineId: string;
73
- /** 新增:fallback 留痕(record 同步投影,GUI 警告条数据源)。P1 恒缺省(无 fallback 路由)。 */
74
- engineFallback?: { from: string; reason: string };
75
- /** 新增:null = 被信号杀死(杀链/abort 合成终态的判据)。P1 pi 链路不暴露 exit code,恒缺省。 */
76
- exitCode?: number | null;
77
- }
33
+ export type {
34
+ AgentOutcome,
35
+ EngineCapabilities,
36
+ EngineHandleData,
37
+ InteractAction,
38
+ InteractResult,
39
+ ProbeReport,
40
+ ReplayedTurn,
41
+ SessionView,
42
+ } from "@zhushanwen/subagent-engine-sdk";
78
43
 
79
44
  // ============================================================
80
- // EngineHandle(run/interact/read 三面的连接件,D1/§3.3.6
45
+ // EngineHandle(run/interact/read 三面的连接件,D1/§3.3.6)——core 域类型留宿主侧
81
46
  // ============================================================
82
47
 
83
- /**
84
- * EngineHandle 的持久化形态(设计 §3.3.6,JSON v1)。
85
- * 内存态 EngineHandle = 本数据 + 引擎运行时引用(各引擎自持)。
86
- */
87
- export interface EngineHandleData {
88
- v: 1;
89
- /** 引擎 id('pi' | 'zcode' | ...,registry key)。 */
90
- engineId: string;
91
- /**
92
- * 引擎自定义键值(定位符)。pi = { recordId?, sessionFile? }——recordId 是
93
- * interact 控制面的 key(subagent record id),sessionFile 是 read 第①级(JSONL
94
- * 直读)的定位符;zcode = { sessionId, dbPath }。
95
- */
96
- sessionRef: Record<string, string>;
97
- /** 隔离池定位(设计 §3.3.9)。pi 无池化(PI_CODING_AGENT_DIR 全局一份)恒 'shared'。 */
98
- poolKey: string;
99
- /**
100
- * journal 绝对路径(read 第②级数据源;runtime 读前校验前缀白名单)。
101
- * P2 event journal 落地后由宿主回填;P1 无 journal 写入者,缺省 undefined——
102
- * read 降级链第②级不可达,直接走 ①/③。
103
- */
104
- journalPath?: string;
105
- /** probe 实测版本(漂移排查锚点)。 */
106
- engineVersion?: string;
107
- /** 适配器版本(golden 样本对齐排查)。 */
108
- adapterVersion: string;
109
- }
110
-
111
48
  /**
112
49
  * 引擎会话句柄(run 返回、interact/read 入参)。
113
50
  *
@@ -122,115 +59,3 @@ export interface EngineHandle {
122
59
  /** 持久化数据。上层不得解构其内部字段(见契约三条)。 */
123
60
  readonly data: EngineHandleData;
124
61
  }
125
-
126
- // ============================================================
127
- // SessionView(read 返回,D6/§3.3.6)
128
- // ============================================================
129
-
130
- /**
131
- * read(handle) 的返回:turns[] 派生数据。与 Turn 同构但无内部态(_status/startedTs
132
- * 剥离,closed 恒 true)。
133
- */
134
- export interface ReplayedTurn {
135
- text: string;
136
- thinking: string;
137
- /** 导出的纯净形状(execution 层 ToolCall,无 _status)。 */
138
- toolCalls: ToolCall[];
139
- closed: true;
140
- }
141
-
142
- /**
143
- * session 历史的引擎中立视图。降级链三级(D6):①引擎原生读取(pi JSONL / zcode
144
- * sqlite)→ ②宿主 event journal 重放(P2)→ ③outcome-only。source 字段是 GUI 降级
145
- * 标记数据源(A8)。
146
- */
147
- export interface SessionView {
148
- engineId: string;
149
- sessionId?: string;
150
- /** turns[] 派生数据(重放/重建产物)。 */
151
- turns: ReplayedTurn[];
152
- /** 各 turn usageDelta 聚合(execution 层 AgentUsageTotal)。 */
153
- usage?: AgentUsageTotal;
154
- source: "native" | "journal" | "outcome-only";
155
- }
156
-
157
- // ============================================================
158
- // EngineCapabilities(D3,三级声明)
159
- // ============================================================
160
-
161
- /**
162
- * 引擎能力声明(设计 D3 原样落地)。三级:native / emulated / unsupported。
163
- *
164
- * 易错点(D3):声明的是**本仓 subagent 链路实际接通的能力**,不是引擎 RPC 层的理论
165
- * 能力——pi 的 RPC 有 steer 但现有 spawn 链路未接通(session-runner steer no-op),
166
- * 故 PiEngine 声明 unsupported,接通后再升级。上层据声明选择策略(schema 为 emulated
167
- * 时自动走公共降级层;steer/conversation unsupported 时 UI 隐藏对应入口),而非
168
- * try-catch 运行时试错。
169
- */
170
- export interface EngineCapabilities {
171
- /** native: --json-schema/--output-schema/env 注入(pi = PI_WORKFLOW_SCHEMA 链路)。 */
172
- schemaEnforcement: "native" | "emulated";
173
- /** 注意区分「引擎 RPC 层有此能力」与「subagent 链路已接通」。 */
174
- steer: "native" | "emulated" | "unsupported";
175
- /** interact 控制面(message/close/cancel + idle)。 */
176
- conversation: "native" | "unsupported";
177
- /** 决定 persona 路由策略(公共降级层按此选择 file/flag/prompt 通道)。 */
178
- personaInjection: "file" | "flag" | "prompt";
179
- /** 粗粒度引擎:GUI 显示降级为阶段态。 */
180
- eventGranularity: "stream" | "coarse";
181
- /** emulated = worktree 隔离(无 OS sandbox 的引擎用文件写维度隔离补齐)。 */
182
- sandbox: "native" | "emulated" | "none";
183
- /** 重建历史的能力(read 降级链第①级的保真度上限)。 */
184
- sessionRead: "full" | "partial" | "outcome-only";
185
- resume: "native" | "cold" | "unsupported";
186
- /** 优雅中断 or 只能杀进程(公共杀链兜底,见 D1 abort 分级)。 */
187
- interrupt: "native" | "kill-only";
188
- /** kimi headless 固定 auto = ignored;GUI 据此隐藏/提示。 */
189
- permissionMode: "native" | "fixed" | "ignored";
190
- /**
191
- * [D3-④ r3 裁定] maxTurns 轮数上限的执行能力位(pi = true:turn limiter + spawn
192
- * watchdog 估算兑现;zcode = false:无 turn_end 语义,静默丢弃会造成「传了上限却
193
- * 失控」假象)。调用前预检(common/capability-gate)按本位拦「声明不支持的能力」
194
- * ——pi 不拦 maxTurns(已支持能力,由 turn-limiter 执行)、zcode 同步拒绝。
195
- * 现状 11 个能力位无可承载 maxTurns 的语义位(fork 拦截可借 session 分叉通道族判,
196
- * maxTurns 无可借位),故扩位而非保留引擎内硬编码 shape 检查。
197
- */
198
- maxTurns: boolean;
199
- }
200
-
201
- // ============================================================
202
- // probe(D7)与 interact(D1)的负载类型
203
- // ============================================================
204
-
205
- /** 引擎探针报告(probe() 返回)。探针在引擎 factory 初始化与版本变化检测时触发(P4 接线)。 */
206
- export interface ProbeReport {
207
- ok: boolean;
208
- /** 实测版本(handle.engineVersion 数据源)。探测不到时为空串。 */
209
- engineVersion: string;
210
- /** 二进制存在/版本解析/干跑回归逐项。 */
211
- checks: Array<{ name: string; ok: boolean; detail?: string }>;
212
- /** engine_probe_failed 的恢复指引(设计 §3.3.3 终态四样例;ok=false 时必填)。 */
213
- error?: { code: string; recovery: string };
214
- }
215
-
216
- /**
217
- * interact 的 action(D1 交互控制面)。pi 首期原生实现(现有 chatMode 行为直通);
218
- * 声明 conversation unsupported 的引擎调用前拒绝(engine_capability_unsupported)。
219
- */
220
- export type InteractAction =
221
- /**
222
- * interrupt:true = steer(抢占)/ false|缺省 = followUp(排队)——pi streamingBehavior
223
- * 语义的中立承载(D1 §3.3.5「后续 wave 如需抢占语义再扩展 InteractAction」的兑现,
224
- * chat 域投递经 engine.interact 接通时落地;不支持抢占的引擎忽略)。
225
- */
226
- | { kind: "message"; payload: string; interrupt?: boolean }
227
- | { kind: "close"; payload?: { force: boolean } }
228
- | { kind: "cancel" };
229
-
230
- /**
231
- * interact 的结果。失败码取自设计 §3.3.3:engine_session_not_resumable(死 handle)/
232
- * engine_capability_unsupported(能力声明拒绝)等。
233
- */
234
- export type InteractResult =
235
- | { ok: true; delivered: true }
236
- | { ok: false; code: string; message: string };