@zhushanwen/subagent-core 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/dist/{chunk-4KN4TTG7.js → chunk-43ONBFZX.js} +1 -1
  2. package/dist/{chunk-X7SZ5HLQ.js → chunk-V3VHZ2VX.js} +20 -27
  3. package/dist/execution/engine/engines/zcode/constants.cjs +29 -41
  4. package/dist/execution/engine/engines/zcode/constants.d.cts +65 -53
  5. package/dist/execution/engine/engines/zcode/constants.d.ts +65 -53
  6. package/dist/execution/engine/engines/zcode/constants.js +17 -27
  7. package/dist/execution/engine/engines/zcode/reader.d.cts +2 -1
  8. package/dist/execution/engine/engines/zcode/reader.d.ts +2 -1
  9. package/dist/execution/engine/engines/zcode/reader.js +2 -2
  10. package/dist/index.cjs +16418 -14070
  11. package/dist/index.d.cts +5136 -4016
  12. package/dist/index.d.ts +5136 -4016
  13. package/dist/index.js +16343 -14048
  14. package/dist/{types-DpUO16pj.d.cts → types-Dv4QhSJ_.d.cts} +215 -112
  15. package/dist/{types-DpUO16pj.d.ts → types-Dv4QhSJ_.d.ts} +215 -112
  16. package/package.json +3 -3
  17. package/src/__tests__/agent-opts-resolver-schema-prompt.test.ts +0 -1
  18. package/src/__tests__/append-system-prompt-assembly.test.ts +8 -7
  19. package/src/__tests__/fr4-get-state-handshake.test.ts +2 -2
  20. package/src/__tests__/m2-append-content-probe.test.ts +0 -1
  21. package/src/__tests__/manifest-store.test.ts +10 -9
  22. package/src/__tests__/record-store-cache.test.ts +0 -2
  23. package/src/__tests__/record-store-index.test.ts +1 -2
  24. package/src/__tests__/review-fix-loop-script.test.ts +4 -2
  25. package/src/__tests__/review-fix-loop-utils.test.ts +10 -10
  26. package/src/__tests__/robustness-low-batch1.test.ts +6 -5
  27. package/src/__tests__/robustness-medium-batch1.test.ts +2 -2
  28. package/src/__tests__/robustness-medium-batch2.test.ts +17 -6
  29. package/src/__tests__/robustness-medium-batch4.test.ts +2 -2
  30. package/src/__tests__/session-runner.test.ts +1 -1
  31. package/src/core/__tests__/host-services.test.ts +2 -2
  32. package/src/core/__tests__/logger.test.ts +1 -1
  33. package/src/core/error-message.ts +9 -0
  34. package/src/core/host-services.ts +21 -5
  35. package/src/core/notify-ports.ts +18 -5
  36. package/src/execution/__tests__/agent-profile.test.ts +4 -4
  37. package/src/execution/__tests__/agent-registry.test.ts +370 -0
  38. package/src/execution/__tests__/agent-result-mapper.test.ts +18 -2
  39. package/src/execution/__tests__/agents-assembly.test.ts +2 -2
  40. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +6 -6
  41. package/src/execution/__tests__/chat-engine-routing.test.ts +68 -33
  42. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +4 -4
  43. package/src/execution/__tests__/cold-resurrect.test.ts +283 -0
  44. package/src/execution/__tests__/delivery-methods.test.ts +75 -62
  45. package/src/execution/__tests__/descendant-sweep-guards.test.ts +220 -0
  46. package/src/execution/__tests__/descendant-sweep.test.ts +6 -6
  47. package/src/execution/__tests__/dialog-queue.test.ts +2 -2
  48. package/src/execution/__tests__/engine-model-validation.test.ts +741 -0
  49. package/src/execution/__tests__/epipe-fallback.test.ts +29 -24
  50. package/src/execution/__tests__/execute-and-await-worktree.test.ts +21 -91
  51. package/src/execution/__tests__/execute-nesting.test.ts +34 -188
  52. package/src/execution/__tests__/execution-record.test.ts +217 -60
  53. package/src/execution/__tests__/execution-runtime-face.test.ts +5 -5
  54. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +3 -3
  55. package/src/execution/__tests__/finalize-record.test.ts +173 -17
  56. package/src/execution/__tests__/gc-timer.test.ts +55 -2
  57. package/src/execution/__tests__/get-record-for-action-restart.test.ts +12 -12
  58. package/src/execution/__tests__/get-state-handshake.test.ts +1 -1
  59. package/src/execution/__tests__/helpers/mock-extension-api.ts +1 -1
  60. package/src/execution/__tests__/helpers/session-runner-mocks.ts +113 -0
  61. package/src/execution/__tests__/helpers/spawn-mock.ts +150 -3
  62. package/src/execution/__tests__/helpers/subagent-service-mocks.ts +137 -0
  63. package/src/execution/__tests__/keep-alive-no-progress.test.ts +50 -148
  64. package/src/execution/__tests__/kill-all-escalation.test.ts +2 -2
  65. package/src/execution/__tests__/lifecycle-predicates.test.ts +1 -2
  66. package/src/execution/__tests__/manifest-parentid.test.ts +4 -4
  67. package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +1 -1
  68. package/src/execution/__tests__/model-resolver.test.ts +2 -2
  69. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +23 -121
  70. package/src/execution/__tests__/nested-visibility.test.ts +2 -0
  71. package/src/execution/__tests__/notify-ledger.test.ts +973 -18
  72. package/src/execution/__tests__/output-collector.test.ts +117 -6
  73. package/src/execution/__tests__/pi-invocation.test.ts +1 -1
  74. package/src/execution/__tests__/record-store.test.ts +10 -9
  75. package/src/execution/__tests__/records-cwd-isolation.test.ts +2 -2
  76. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +29 -132
  77. package/src/execution/__tests__/recursive-visibility-env.test.ts +55 -179
  78. package/src/execution/__tests__/rpc-mode.test.ts +2 -2
  79. package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +387 -0
  80. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +15 -9
  81. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +4 -4
  82. package/src/execution/__tests__/run-spawn-edges.test.ts +17 -15
  83. package/src/execution/__tests__/run-spawn-integration.test.ts +2 -2
  84. package/src/execution/__tests__/run-spawn-resume.test.ts +2 -2
  85. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +2 -2
  86. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +4 -4
  87. package/src/execution/__tests__/service-kill-escalation.test.ts +7 -5
  88. package/src/execution/__tests__/session-context-resolver.test.ts +0 -2
  89. package/src/execution/__tests__/session-file-gc.test.ts +35 -0
  90. package/src/execution/__tests__/session-pending.test.ts +257 -14
  91. package/src/execution/__tests__/session-reconstructor.test.ts +366 -15
  92. package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +1 -1
  93. package/src/execution/__tests__/session-runner-close-prune.test.ts +2 -2
  94. package/src/execution/__tests__/session-runner-dispatch.test.ts +489 -0
  95. package/src/execution/__tests__/session-runner-epipe.test.ts +3 -3
  96. package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +5 -4
  97. package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +290 -0
  98. package/src/execution/__tests__/session-runner-schema-env.test.ts +7 -5
  99. package/src/execution/__tests__/settled-watchdog.test.ts +282 -47
  100. package/src/execution/__tests__/spawn-args.test.ts +11 -10
  101. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +26 -23
  102. package/src/execution/__tests__/spawn-event-adapter.test.ts +1 -1
  103. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +5 -4
  104. package/src/execution/__tests__/spawned-children.test.ts +2 -1
  105. package/src/execution/__tests__/start-sync-model-guard.test.ts +4 -4
  106. package/src/execution/__tests__/stdin-writer.test.ts +6 -4
  107. package/src/execution/__tests__/stream-sink-retirement.test.ts +6 -6
  108. package/src/execution/__tests__/subagent-actions-core.test.ts +42 -22
  109. package/src/execution/__tests__/subagent-service-message-close.test.ts +29 -26
  110. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +8 -8
  111. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +27 -22
  112. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +30 -29
  113. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +45 -20
  114. package/src/execution/__tests__/subagent-service.test.ts +37 -30
  115. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +88 -12
  116. package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +75 -0
  117. package/src/execution/__tests__/subprocess-agent-runner.test.ts +22 -20
  118. package/src/execution/__tests__/temp-prompt.test.ts +1 -1
  119. package/src/execution/__tests__/timeout-integration.test.ts +6 -5
  120. package/src/execution/__tests__/turn-limiter-semantics.test.ts +1 -1
  121. package/src/execution/__tests__/turn-limiter.test.ts +1 -1
  122. package/src/execution/__tests__/ui-request-handler-factory.test.ts +12 -6
  123. package/src/execution/__tests__/ui-request-handler.test.ts +4 -3
  124. package/src/execution/__tests__/ui-request-queue.test.ts +142 -2
  125. package/src/execution/__tests__/worktree-manager.test.ts +14 -5
  126. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +4 -3
  127. package/src/execution/agent-registry.ts +74 -30
  128. package/src/execution/agent-result-mapper.ts +3 -0
  129. package/src/execution/cold-resurrect.ts +199 -0
  130. package/src/execution/engine/__tests__/common/capability-gate.test.ts +91 -0
  131. package/src/execution/engine/__tests__/common/data-dir.test.ts +1 -1
  132. package/src/execution/engine/__tests__/common/journal-wiring.test.ts +84 -0
  133. package/src/execution/engine/__tests__/common/kill-chain.test.ts +34 -7
  134. package/src/execution/engine/__tests__/common/persona-router.test.ts +4 -5
  135. package/src/execution/engine/__tests__/common/pool-manager.test.ts +211 -51
  136. package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +149 -0
  137. package/src/execution/engine/__tests__/common/session-view-service.test.ts +499 -0
  138. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +22 -112
  139. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +15 -28
  140. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +12 -12
  141. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +1 -1
  142. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +21 -82
  143. package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +4 -7
  144. package/src/execution/engine/__tests__/engine-discovery.test.ts +15 -3
  145. package/src/execution/engine/__tests__/model-prompt.test.ts +15 -3
  146. package/src/execution/engine/__tests__/registry.test.ts +4 -2
  147. package/src/execution/engine/__tests__/routing.test.ts +115 -6
  148. package/src/execution/engine/common/capability-gate.ts +92 -0
  149. package/src/execution/engine/common/journal-wiring.ts +97 -0
  150. package/src/execution/engine/common/kill-chain.ts +42 -10
  151. package/src/execution/engine/common/nesting-guard.ts +66 -0
  152. package/src/execution/engine/common/persona-router.ts +18 -8
  153. package/src/execution/engine/common/pool-manager.ts +332 -78
  154. package/src/execution/engine/common/session-view-service.ts +506 -0
  155. package/src/execution/engine/common/session-view-types.ts +125 -0
  156. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +174 -28
  157. package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +257 -0
  158. package/src/execution/{argv-mirror.ts → engine/engines/pi/argv-mirror.ts} +43 -21
  159. package/src/execution/{get-state-handshake.ts → engine/engines/pi/get-state-handshake.ts} +1 -1
  160. package/src/execution/{output-collector.ts → engine/engines/pi/output-collector.ts} +108 -19
  161. package/src/execution/engine/engines/pi/pi-engine.ts +434 -38
  162. package/src/execution/{pi-invocation.ts → engine/engines/pi/pi-invocation.ts} +2 -2
  163. package/src/execution/engine/engines/pi/reader.ts +11 -0
  164. package/src/execution/engine/engines/pi/registration.ts +4 -2
  165. package/src/execution/{session-runner.ts → engine/engines/pi/session-runner.ts} +617 -412
  166. package/src/execution/{spawn-event-adapter.ts → engine/engines/pi/spawn-event-adapter.ts} +75 -34
  167. package/src/execution/{stdin-writer.ts → engine/engines/pi/stdin-writer.ts} +10 -9
  168. package/src/execution/{temp-prompt.ts → engine/engines/pi/temp-prompt.ts} +2 -2
  169. package/src/execution/{turn-limiter.ts → engine/engines/pi/turn-limiter.ts} +1 -1
  170. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +54 -27
  171. package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +321 -0
  172. package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +13 -12
  173. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +7 -210
  174. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +6 -110
  175. package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +247 -0
  176. package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +451 -0
  177. package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +20 -8
  178. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +77 -110
  179. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +25 -319
  180. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +210 -0
  181. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +353 -0
  182. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +282 -0
  183. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +372 -0
  184. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +48 -148
  185. package/src/execution/engine/engines/zcode/appserver-launcher.ts +167 -0
  186. package/src/execution/engine/engines/zcode/connection.ts +24 -11
  187. package/src/execution/engine/engines/zcode/constants.ts +75 -71
  188. package/src/execution/engine/engines/zcode/golden-sample.ts +8 -46
  189. package/src/execution/engine/engines/zcode/parser.ts +12 -346
  190. package/src/execution/engine/engines/zcode/preparer.ts +12 -143
  191. package/src/execution/engine/engines/zcode/session-channel.ts +351 -39
  192. package/src/execution/engine/engines/zcode/zcode-engine.ts +665 -760
  193. package/src/execution/engine/host-task-spec.ts +32 -36
  194. package/src/execution/engine/model-validation.ts +177 -0
  195. package/src/execution/engine/port.ts +24 -6
  196. package/src/execution/engine/routing.ts +75 -1
  197. package/src/execution/engine/types.ts +30 -103
  198. package/src/execution/execution-record.ts +222 -144
  199. package/src/execution/finalize-record.ts +131 -93
  200. package/src/execution/idle-gc.ts +28 -0
  201. package/src/execution/lifecycle-predicates.ts +1 -1
  202. package/src/execution/notify-host.ts +212 -0
  203. package/src/execution/record-store.ts +119 -73
  204. package/src/execution/round-settlement.ts +93 -0
  205. package/src/execution/session-file-gc.ts +96 -62
  206. package/src/execution/session-reconstructor.ts +256 -143
  207. package/src/execution/sessions-index.ts +117 -47
  208. package/src/execution/settled-watchdog.ts +264 -52
  209. package/src/execution/subagent-actions-core.ts +22 -22
  210. package/src/execution/subagent-service.ts +815 -963
  211. package/src/execution/subprocess-agent-runner.ts +144 -97
  212. package/src/execution/types.ts +9 -0
  213. package/src/execution/ui-request-handler-factory.ts +102 -74
  214. package/src/execution/ui-request-queue.ts +50 -19
  215. package/src/index.ts +442 -316
  216. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +1 -1
  217. package/src/orchestration/__tests__/agent-call-stream.test.ts +2 -2
  218. package/src/orchestration/__tests__/args-validator.test.ts +14 -0
  219. package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +1 -1
  220. package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +11 -9
  221. package/src/orchestration/__tests__/execute-agent-call.test.ts +151 -11
  222. package/src/orchestration/__tests__/file-run-store.test.ts +7 -6
  223. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +2 -2
  224. package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +1 -1
  225. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +3 -3
  226. package/src/orchestration/__tests__/lifecycle.test.ts +7 -5
  227. package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +1 -1
  228. package/src/orchestration/__tests__/run-snapshot.test.ts +8 -5
  229. package/src/orchestration/__tests__/script-lint.test.ts +17 -0
  230. package/src/orchestration/__tests__/test-mocks.ts +2 -0
  231. package/src/orchestration/__tests__/worker-exit-without-result.test.ts +7 -6
  232. package/src/orchestration/__tests__/worker-message-pump-finalize-run.test.ts +229 -0
  233. package/src/orchestration/__tests__/{error-recovery-handlers.test.ts → worker-message-pump-handlers.test.ts} +27 -19
  234. package/src/orchestration/__tests__/{error-recovery-postmessage-defense.test.ts → worker-message-pump-postmessage-defense.test.ts} +8 -8
  235. package/src/orchestration/__tests__/{error-recovery-serialize-failed-result.test.ts → worker-message-pump-serialize-failed-result.test.ts} +2 -2
  236. package/src/orchestration/__tests__/{error-recovery-workflow-call.test.ts → worker-message-pump-workflow-call.test.ts} +1 -1
  237. package/src/orchestration/__tests__/worker-pending-timeout-abort.test.ts +1 -1
  238. package/src/orchestration/__tests__/worker-script-builder.test.ts +1 -1
  239. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +1 -1
  240. package/src/orchestration/agent-opts-resolver.ts +1 -1
  241. package/src/orchestration/args-validator.ts +53 -31
  242. package/src/orchestration/execute-agent-call.ts +19 -73
  243. package/src/orchestration/launcher.ts +128 -81
  244. package/src/orchestration/lifecycle.ts +43 -45
  245. package/src/orchestration/models/ports.ts +4 -4
  246. package/src/orchestration/models/run-runtime.ts +2 -2
  247. package/src/orchestration/models/trace.ts +1 -1
  248. package/src/orchestration/models/types.ts +111 -22
  249. package/src/orchestration/models/workflow-run.ts +1 -1
  250. package/src/orchestration/script-lint.ts +91 -58
  251. package/src/orchestration/{error-recovery.ts → worker-message-pump.ts} +157 -150
  252. package/src/shared/__tests__/meta-parser.test.ts +151 -0
  253. package/src/shared/__tests__/resource-discovery.test.ts +258 -215
  254. package/src/shared/atomic-write.ts +12 -9
  255. package/src/shared/meta-parser.ts +158 -84
  256. package/src/shared/model-ref.ts +15 -2
  257. package/src/shared/resource-discovery.ts +9 -183
  258. package/src/shared/schema-jsonify.ts +1 -1
  259. package/workflows/review-fix-loop-utils.cjs +151 -89
  260. package/workflows/review-fix-loop-utils.d.cts +287 -0
  261. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
  262. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  263. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  264. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  265. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  266. package/src/execution/engine/engines/zcode/__tests__/preparer-appserver.test.ts +0 -387
  267. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -710
  268. package/src/execution/engine/engines/zcode/appserver-home.ts +0 -442
  269. package/src/execution/engine/engines/zcode/appserver-probe.ts +0 -141
  270. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  271. package/src/execution/execute-options-mapper.ts +0 -115
  272. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -288
@@ -1,47 +1,43 @@
1
1
  // src/execution/engine/host-task-spec.ts
2
2
  //
3
- // ExecuteOptions → AgentTaskSpec 的宿主侧最小正向映射(U0:chat 工具域引擎分支)。
3
+ // ExecuteOptions → AgentCallOpts 的宿主侧最小正向映射(U0:chat 工具域引擎分支)。
4
4
  //
5
- // engines/pi/task-spec-mapper.ts 的关系:那是 pi 引擎方向的映射(taskSpecToExecuteOptions
6
- // 还原 + schemaEnv 内化派生等 pi 专有语义),归属 pi 引擎模块;本 mapper 服务宿主编排层
7
- // (subagent-service 引擎分支),不 import 任何具体引擎模块(registry.ts 依赖方向纪律:
8
- // 上层按中立类型组装声明,引擎细节归引擎)。字段映射是 ExecuteOptions → AgentTaskSpec
9
- // 的中立直译(task/slug/agent/model 原样;thinkingLevel effort;skillPath +
10
- // appendSystemPrompt → persona;schema/maxTurns/graceTurns/worktree/cwd 原样透传)。
5
+ // [D6 任务形状合流] 产出类型从原 AgentTaskSpec 改为合流形状 AgentCallOpts(单一任务
6
+ // 形状,EnginePort.run 入参——原 AgentTaskSpec 已删除)。字段映射是 ExecuteOptions
7
+ // AgentCallOpts 的中立直译(prompt=task 正文、description=slug 短标签;agent/model/
8
+ // thinkingLevel/skillPath/appendSystemPrompt/schema/maxTurns/graceTurns/worktree/cwd
9
+ // 同名透传)。不 import 任何具体引擎模块(registry.ts 依赖方向纪律:上层按中立类型
10
+ // 组装声明,引擎细节归引擎)。
11
11
  //
12
- // conversation/fork 在调用本 mapper 前已被 assertEngineParamSupport 预检拒绝(非 pi 引擎
13
- // unsupported),透传仅保持映射完整性——未来引擎支持时无需改本函数。
12
+ // schemaEnv 不透传(与原 AgentTaskSpec 形态一致的字段面):pi 边界直出时 schema 派生
13
+ // 优先——透传会在 chat 域引入「opts.schemaEnv 原值 vs compact 派生值」的取值源变化,
14
+ // 维持派生优先保证与合流前行为逐字节一致。
15
+ //
16
+ // conversation/fork 在调用本 mapper 前已被 capability-gate 预检拒绝([D3-④]
17
+ // capabilities 驱动的调用前拒绝,非 pi 引擎 unsupported),透传仅保持映射完整性——
18
+ // 未来引擎支持时无需改本函数。
14
19
 
20
+ import type { AgentCallOpts } from "../../orchestration/models/types.ts";
15
21
  import type { ExecuteOptions } from "../types.ts";
16
- import type { AgentTaskSpec, PersonaSpec } from "./types.ts";
17
22
 
18
- /** 纯函数:ExecuteOptions(chat 域执行选项)→ 引擎中立任务声明。无副作用、幂等。 */
19
- export function executeOptionsToEngineTaskSpec(opts: ExecuteOptions): AgentTaskSpec {
20
- // persona 归并口径与 pi mapper 一致:skillPath / appendSystemPrompt 有其一即建,
21
- // 避免空对象噪声(下游 spread 空数组与 undefined 均为 no-op)。
22
- const persona: PersonaSpec | undefined =
23
- opts.skillPath !== undefined || opts.appendSystemPrompt !== undefined
24
- ? {
25
- ...(opts.skillPath !== undefined ? { skillPath: opts.skillPath } : {}),
26
- ...(opts.appendSystemPrompt !== undefined ? { appendSystemPrompt: opts.appendSystemPrompt } : {}),
27
- }
28
- : undefined;
23
+ /** 纯函数:ExecuteOptions(chat 域执行选项)→ 合流任务声明 AgentCallOpts。无副作用、幂等。 */
24
+ export function executeOptionsToEngineTaskSpec(opts: ExecuteOptions): AgentCallOpts {
29
25
  return {
30
- task: opts.task,
31
- slug: opts.slug,
32
- agent: opts.agent,
33
- model: opts.model,
34
- // pi 7 thinkingLevel 是引擎私有语义——中立层透传 effort 字符串,各引擎自行映射
35
- effort: opts.thinkingLevel,
36
- ...(persona !== undefined ? { persona } : {}),
37
- schema: opts.schema,
38
- maxTurns: opts.maxTurns,
39
- graceTurns: opts.graceTurns,
40
- fork: opts.fork,
41
- worktree: opts.worktree,
42
- cwd: opts.cwd,
43
- conversation: opts.conversation,
44
- idleTimeoutMs: opts.idleTimeoutMs,
26
+ prompt: opts.task,
27
+ ...(opts.slug !== undefined ? { description: opts.slug } : {}),
28
+ ...(opts.agent !== undefined ? { agent: opts.agent } : {}),
29
+ ...(opts.model !== undefined ? { model: opts.model } : {}),
30
+ ...(opts.thinkingLevel !== undefined ? { thinkingLevel: opts.thinkingLevel } : {}),
31
+ ...(opts.skillPath !== undefined ? { skillPath: opts.skillPath } : {}),
32
+ ...(opts.appendSystemPrompt !== undefined ? { appendSystemPrompt: opts.appendSystemPrompt } : {}),
33
+ ...(opts.schema !== undefined ? { schema: opts.schema } : {}),
34
+ ...(opts.maxTurns !== undefined ? { maxTurns: opts.maxTurns } : {}),
35
+ ...(opts.graceTurns !== undefined ? { graceTurns: opts.graceTurns } : {}),
36
+ ...(opts.fork !== undefined ? { fork: opts.fork } : {}),
37
+ ...(opts.worktree !== undefined ? { worktree: opts.worktree } : {}),
38
+ ...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}),
39
+ ...(opts.conversation !== undefined ? { conversation: opts.conversation } : {}),
40
+ ...(opts.idleTimeoutMs !== undefined ? { idleTimeoutMs: opts.idleTimeoutMs } : {}),
45
41
  // 运行期字段(signal/ctxModel)不入声明——归 RunContext(port.ts 删字段去向)。
46
42
  };
47
43
  }
@@ -0,0 +1,177 @@
1
+ // src/execution/engine/model-validation.ts
2
+ //
3
+ // [u-h2] 引擎感知的派发期 model 校验入口 + 错误文案构造。设计权威源:
4
+ // docs/design/timeout-audit-hygiene-batch.md §3.2(D2-1 路由先行 / D2-2 validateModel
5
+ // 可选面 / D2-3「引擎与模型不配套」文案 / D2-4 pi 未命中跨引擎候选)。
6
+ //
7
+ // 背景(§2.2 双重错配):model 校验曾固定用 pi registry 且时机在引擎路由之前——
8
+ // zcode 合法模型被误导性拒绝(F2-A)、pi 模型过校验后到 zcode 执行期才炸(F2-B)。
9
+ // 修复定案:校验源 = 目标引擎 registry(EnginePort.validateModel 可选面),时机 =
10
+ // 路由之后的派发同步期(record 创建前,不产生孤儿 record)。
11
+ //
12
+ // 两个调用点共享本入口与错误文案(D2-2 调用点双路径覆盖):
13
+ // ① chat 路径 subagent-service.executeViaEngine(非 pi 分支);
14
+ // ② workflow 路径 subprocess-agent-runner.run(route.engine.run 之前,非 pi 分支)。
15
+
16
+ import { stripThinkingSuffix } from "../../shared/model-ref.ts";
17
+ import type { EnginePort } from "./port.ts";
18
+ import { DEFAULT_ENGINE_ID } from "./registry.ts";
19
+ import { toErrorMessage } from "../../core/error-message.ts";
20
+
21
+ /** 错误消息中列出的目标引擎可用清单上限(防超长错误信息;与 shared/model-ref 同量级口径)。 */
22
+ const ENGINE_MODEL_LIST_LIMIT = 20;
23
+
24
+ // ============================================================
25
+ // 场景 2:engine+model 不配套的结构化错误(D2-3)
26
+ // ============================================================
27
+
28
+ /**
29
+ * 「引擎与模型不配套」错误(设计 §3.2.1 场景 2)。code 沿用 §3.3.3 错误规格表的
30
+ * model_not_available(与 ZcodePrepareError 同码——同一失败域的早抛形态)。
31
+ */
32
+ class EngineModelMismatchError extends Error {
33
+ readonly code = "model_not_available";
34
+ /** 恢复指引(错误 → 权威源 → 重试闭环;EngineError.recovery 同构字段)。 */
35
+ readonly recovery: string;
36
+
37
+ constructor(message: string, recovery: string) {
38
+ super(message);
39
+ this.name = "EngineModelMismatchError";
40
+ this.recovery = recovery;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * 非 pi 引擎的派发同步期 model 校验(两路径统一入口)。
46
+ *
47
+ * - 引擎实现 validateModel:同步裁决(含 undefined = 查引擎缺省模型),返回 canonical
48
+ * 全名供 record.model 留痕;失败包装为 EngineModelMismatchError(场景 2 文案:
49
+ * 点破 registry 独立 + 目标引擎可用清单 + 按引擎区分的省略语义修正动作)。
50
+ * - 引擎未实现 validateModel:返回 modelRef 原样(透传给其 prepare 期校验兜底——
51
+ * 现状语义,未来引擎零强制接入)。
52
+ *
53
+ * @param engine 路由解析出的目标引擎
54
+ * @param modelRef 显式 model(调用参数或 agent .md frontmatter;undefined = 引擎缺省语义)
55
+ * @returns canonical ref(引擎裁决后全名);未实现校验面时 = modelRef 原样
56
+ */
57
+ export function validateModelForEngine(
58
+ engine: EnginePort,
59
+ modelRef: string | undefined,
60
+ ): string | undefined {
61
+ if (engine.id === DEFAULT_ENGINE_ID) return modelRef; // 防御:pi 不经此入口(走既有三层解析链)
62
+ if (typeof engine.validateModel !== "function") return modelRef;
63
+ try {
64
+ return engine.validateModel(modelRef).canonicalRef;
65
+ } catch (err) {
66
+ throw buildMismatchError(engine, modelRef, err);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * 场景 2 文案构造(D2-3):① 点破 registry 独立;② 列目标引擎可用清单(数据源
72
+ * listModels;引擎未实现时省略清单行,保留引擎原始错误作诊断行);③ 👉 修正动作
73
+ * (清单重试 / 省略 model 用引擎缺省——pi 的「继承主 agent」语义对非 pi 引擎是错误
74
+ * 指引,此处按引擎缺省表述)。
75
+ */
76
+ function buildMismatchError(engine: EnginePort, modelRef: string | undefined, cause: unknown): EngineModelMismatchError {
77
+ const ref = modelRef === undefined || modelRef.trim() === "" ? "(engine default)" : modelRef;
78
+ const lines = [
79
+ `model '${ref}' is not available on engine '${engine.id}'.`,
80
+ `Engine registries are independent — ids in <available_provider_models> (pi registry) do NOT apply to '${engine.id}' dispatches.`,
81
+ ];
82
+ const available = safeListModels(engine);
83
+ if (available.length > 0) {
84
+ lines.push(`${engine.id} models with configured credentials:`);
85
+ lines.push(` ${available.slice(0, ENGINE_MODEL_LIST_LIMIT).join(", ")}${available.length > ENGINE_MODEL_LIST_LIMIT ? ", ..." : ""}`);
86
+ }
87
+ // 引擎缺省模型名(validateModel(undefined) 成功才给——失败时省略句不带具体名,
88
+ // 缺省本身也不可用属于凭据级故障,引擎原始错误行已覆盖诊断)。
89
+ const engineDefault = safeEngineDefault(engine);
90
+ lines.push(
91
+ `👉 Retry with one of the above (exact string), or omit \`model\` to use the '${engine.id}' engine default` +
92
+ (engineDefault !== undefined ? ` (${engineDefault})` : "") +
93
+ `.`,
94
+ );
95
+ // 引擎侧原始裁决失败原因(provider 未配凭据 / 模型未启用等)——诊断行,避免包装层吞掉细节。
96
+ lines.push(`Engine said: ${toErrorMessage(cause)}`);
97
+ const recovery =
98
+ `Retry with an exact model id from the '${engine.id}' list above, or omit the \`model\` param to use the '${engine.id}' engine default` +
99
+ (engineDefault !== undefined ? ` (${engineDefault})` : "") +
100
+ `.`;
101
+ return new EngineModelMismatchError(lines.join("\n"), recovery);
102
+ }
103
+
104
+ // ============================================================
105
+ // 场景 3:pi registry 未命中的跨引擎纠错候选(D2-4)
106
+ // ============================================================
107
+
108
+ /** notFoundError 的结构化标记(shared/model-ref.ts 挂载;跨引擎反查的识别面)。 */
109
+ interface RefNotFoundMarker {
110
+ refNotFound?: boolean;
111
+ refInput?: string;
112
+ }
113
+
114
+ /**
115
+ * pi registry 未命中时反查其他已注册引擎的 listModels(D2-4):**唯一**引擎全等命中
116
+ * (strip thinking 后缀后与清单 id 全等——对齐零宽容原则,模糊匹配不参与建议)才追加
117
+ * 「该 id 属于引擎 X」候选段;多引擎命中/零命中原样返回(既有文案零回归——V2-4③)。
118
+ *
119
+ * @param err resolveModel 抛出的错误(须带 refNotFound 标记才处理)
120
+ * @param engineIds 已注册引擎清单(registry.listEngines 快照)
121
+ * @param getEngineFn 引擎获取(registry.getEngine;测试注入)
122
+ * @returns 原错误(无可附候选)或追加候选段的新错误(不 mutate 原错误)
123
+ */
124
+ export function withCrossEngineHint(
125
+ err: unknown,
126
+ engineIds: readonly string[],
127
+ getEngineFn: (id: string) => EnginePort | undefined,
128
+ ): unknown {
129
+ if (!(err instanceof Error)) return err;
130
+ const marker = err as Error & RefNotFoundMarker;
131
+ if (marker.refNotFound !== true || marker.refInput === undefined) return err;
132
+ const clean = stripThinkingSuffix(marker.refInput);
133
+
134
+ let matchedEngineId: string | undefined;
135
+ let matchCount = 0;
136
+ for (const id of engineIds) {
137
+ if (id === DEFAULT_ENGINE_ID) continue; // pi 是裁决源本身,不参与反查
138
+ const engine = getEngineFn(id);
139
+ if (engine === undefined) continue;
140
+ // 单引擎清单读取失败/无清单(safeListModels → [])不阻塞反查(可发现性降级语义)
141
+ if (safeListModels(engine).includes(clean)) {
142
+ matchCount++;
143
+ matchedEngineId ??= id;
144
+ }
145
+ }
146
+ if (matchCount !== 1 || matchedEngineId === undefined) return err;
147
+ return new Error(
148
+ `${err.message}\n` +
149
+ `This id matches the registry of engine '${matchedEngineId}'.\n` +
150
+ `👉 Retry with engine: '${matchedEngineId}', or use a pi model from <available_provider_models>, ` +
151
+ `or omit \`model\` to inherit the main agent model.`,
152
+ );
153
+ }
154
+
155
+ // ============================================================
156
+ // 内部:引擎面的失败安全读取
157
+ // ============================================================
158
+
159
+ /** 引擎可用清单(listModels 失败安全——校验错误路径不再叠加清单读取故障;null 契约按零清单)。 */
160
+ function safeListModels(engine: EnginePort): string[] {
161
+ if (typeof engine.listModels !== "function") return [];
162
+ try {
163
+ return engine.listModels()?.map((m) => m.id) ?? [];
164
+ } catch {
165
+ return [];
166
+ }
167
+ }
168
+
169
+ /** 引擎缺省模型(validateModel(undefined);失败安全返回 undefined)。 */
170
+ function safeEngineDefault(engine: EnginePort): string | undefined {
171
+ if (typeof engine.validateModel !== "function") return undefined;
172
+ try {
173
+ return engine.validateModel(undefined).canonicalRef;
174
+ } catch {
175
+ return undefined;
176
+ }
177
+ }
@@ -10,6 +10,8 @@
10
10
  // - [R4 已实施 2026-08-30] RunContext.onHandleReady——运行中句柄回填通道
11
11
  // (同设计 §3.4 不变量 3:sessionRef 在 create 应答后经本回调送达编排层,
12
12
  // 与 onPoolResolved 分立两个时点)。
13
+ // - [u-h2 已实施 2026-09-05] EnginePort.validateModel?()——派发同步期 model 校验面。
14
+ // 权威源:docs/design/timeout-audit-hygiene-batch.md §3.2 D2-2。
13
15
  //
14
16
  // 四个能力面(D1):
15
17
  // run —— 主语义:一次性 fire-to-completion 任务执行;
@@ -21,12 +23,12 @@
21
23
 
22
24
  import type { ChildProcess } from "node:child_process";
23
25
 
26
+ import type { AgentCallOpts } from "../../orchestration/models/types.ts";
24
27
  import type { ModelInfo } from "../model-resolver.ts";
25
28
  import type { SubagentStream } from "../stream-sink.ts";
26
29
  import type { AgentEvent } from "../types.ts";
27
30
  import type {
28
31
  AgentOutcome,
29
- AgentTaskSpec,
30
32
  EngineCapabilities,
31
33
  EngineHandle,
32
34
  EngineHandleData,
@@ -41,9 +43,9 @@ import type {
41
43
  // ============================================================
42
44
 
43
45
  /**
44
- * run 的运行期上下文。任务声明(AgentTaskSpec)与运行期句柄分离——signal/ctxModel/
45
- * onComplete 从 ExecuteOptions 移出(设计 §3.3.5 删字段去向),因为它们是宿主注入的
46
- * 运行期对象,不属于跨引擎持久化的任务声明。
46
+ * run 的运行期上下文。任务声明(AgentCallOpts,D6 合流后的单一形状)与运行期句柄
47
+ * 分离——signal/ctxModel/onComplete 从 ExecuteOptions 移出(设计 §3.3.5 删字段去向),
48
+ * 因为它们是宿主注入的运行期对象,不属于跨引擎持久化的任务声明。
47
49
  *
48
50
  * 常驻进程友好(D1):onEvent 回调式(而非迭代器式)+ AbortSignal——引擎内部换常驻
49
51
  * server 实现(未来 driver host)时接口不动。
@@ -158,8 +160,9 @@ export interface EnginePort {
158
160
  /** D7(factory 初始化 + 版本变化检测触发;opts.force 跳过缓存强探)。 */
159
161
  probe(opts?: { force?: boolean }): Promise<ProbeReport>;
160
162
 
161
- /** D1 主语义:fire-to-completion。 */
162
- run(task: AgentTaskSpec, ctx: RunContext): Promise<EngineRunResult>;
163
+ /** D1 主语义:fire-to-completion。[D6 合流] task = AgentCallOpts(单一任务形状,
164
+ * AgentTaskSpec 已并入——字段裁定见 orchestration/models/types.ts)。 */
165
+ run(task: AgentCallOpts, ctx: RunContext): Promise<EngineRunResult>;
163
166
 
164
167
  /**
165
168
  * D1 可选面:交互控制面。pi 首期原生实现(现有 chatMode 行为直通);不支持
@@ -180,6 +183,21 @@ export interface EnginePort {
180
183
  */
181
184
  listModels?(): Array<{ id: string; name?: string }> | null;
182
185
 
186
+ /**
187
+ * [u-h2 D2-2] 可选面:派发同步期 model 校验(引擎 registry 单源裁决)。实现引擎复用其
188
+ * prepare 期同一校验函数(zcode: resolveZcodeModelRef——同一函数两处消费,canonicalRef
189
+ * 归一化与短名缺省 provider 决策不产生双实现漂移);校验失败同步 throw(编排层包装为
190
+ * 「引擎与模型不配套」错误,见 engine/model-validation.ts)。
191
+ *
192
+ * modelRef undefined = 查询引擎缺省模型(D2-1:主 agent 的 pi id 不透传给非 pi 引擎,
193
+ * 缺省语义归引擎——zcode 落 ZCODE_FALLBACK_DEFAULT_MODEL)。返回 canonical 全名供
194
+ * record.model 留痕。
195
+ *
196
+ * 未实现:model 透传,引擎自身 prepare 期校验兜底(现状语义);pi 不实现(pi 链走
197
+ * 既有三层解析 + assertCanonicalModelRef 裁决,搬迁是大重构,设计 D2-2 被否②)。
198
+ */
199
+ validateModel?(modelRef: string | undefined): { canonicalRef: string };
200
+
183
201
  /**
184
202
  * [R1 D6] 可选停机面:释放引擎持有的常驻资源(如 app-server 常驻进程 / 长连接)。
185
203
  * 幂等契约(§3.4 不变量 4):重复调用无副作用;dispose 后首个 run 自动重建(与
@@ -150,7 +150,8 @@ export async function routeEngine(opts: EngineRouteOptions): Promise<EngineRoute
150
150
  }
151
151
  // 守卫 a/b(首期合流):显式指定(调用参数或 step 级)= 能力依赖声明,静默换引擎
152
152
  // 违反意图——沙箱类任务被静默卸除安全能力正是要防的形态(D9① 原文)。守卫 b 的
153
- // 独立载体(AgentTaskSpec.requires)下钻后在本分支前独立判定,首期显式 engine 即声明。
153
+ // 独立载体(合流形状 AgentCallOpts 上的能力依赖声明字段,requires 已随 D6 裁撤)
154
+ // 下钻后在本分支前独立判定,首期显式 engine 即声明。
154
155
  if (routing.source === "call") {
155
156
  throw probeFailedError(routing.engineId, report, "engine 来自调用参数显式指定(能力依赖声明)——不兜底");
156
157
  }
@@ -216,3 +217,76 @@ function describeRoutingSource(routing: EngineRoutingInput): string | undefined
216
217
  }
217
218
  return undefined;
218
219
  }
220
+
221
+ // ============================================================
222
+ // routeEngineForHost:宿主两调用点的统一编排(D3-② 路由单点)
223
+ // ============================================================
224
+
225
+ /** routeEngineForHost 的参数(宿主装配:本地 pi 引擎 + 路由三件注入)。 */
226
+ export interface HostRouteOptions {
227
+ /** 三层路由输入(调用方装配:调用参数 / frontmatter / 全局默认)。 */
228
+ routing: EngineRoutingInput;
229
+ /**
230
+ * 守卫 c 判据:调用方显式指定的 model(与 routeEngine.taskModel 同口径——解析后的
231
+ * 兼底 model 恒非空会把一切兜底误判为 model 绑定命中,故只传显式值)。
232
+ */
233
+ taskModel?: string;
234
+ /** engineRouting.strict(config.json):true = 一切 probe 失败直接报错。 */
235
+ strict: boolean;
236
+ /** 探针执行体(生产 = registry 引擎 .probe();测试可注入)。 */
237
+ probe: (engineId: string) => Promise<ProbeReport>;
238
+ /**
239
+ * 本地 pi 引擎实例(chat 域 = Service 的 chatPiEngine;workflow 域 = SAR 的 per-session
240
+ * DI 实例)。pi 请求与「非 pi 兜底回 pi」两种形态都由它接管——不依赖 registry 全局
241
+ * 注册态(单测注入 mock 时全局单例不可见;生产环境两者是同一进程单例对象)。
242
+ */
243
+ piEngine: EnginePort;
244
+ /** 非 pi 引擎获取(缺省 registry.getEngine;测试注入)。 */
245
+ getEngineFn?: (engineId: string) => EnginePort;
246
+ /** 非 pi 注册表存在性检查(缺省 registry.hasEngine)。 */
247
+ hasEngineFn?: (engineId: string) => boolean;
248
+ /** 非 pi 注册表清单(缺省 registry.listEngines)。 */
249
+ listEnginesFn?: () => string[];
250
+ }
251
+
252
+ /**
253
+ * 宿主侧统一路由编排(D3-②:唯一实现,两调用点——SubagentService.execute 与
254
+ * SAR.run)。把原先散在两调用点的「pi 同步短路 + registry 注入(本地 pi 恒可用,
255
+ * engine_not_found 文案不把本地 pi 漏报成未注册)+ 兜底回 pi 时换本地实例」收敛到本函数。
256
+ *
257
+ * 返回值形态(时序契约):pi 请求路径**同步返回** EngineRouteResult(非 Promise)——
258
+ * 不引入微任务边界,SAR 的「run 内首个 await 前已触达 executeAndAwait」缺省路径时序
259
+ * 与旧形态逐字节一致;非 pi 路径返回 Promise(probe 编排固有异步),调用方统一用
260
+ * `routed instanceof Promise ? await routed : routed` 消费(pi 路径零 await)。
261
+ */
262
+ export function routeEngineForHost(opts: HostRouteOptions): EngineRouteResult | Promise<EngineRouteResult> {
263
+ const routing = resolveEngineRouting(opts.routing);
264
+
265
+ // pi 请求(缺省/显式 pi):本地 DI 实例同步短路——pi 恒免探、无 fallback 可言,
266
+ // 不经 routeEngine 的 await/probe(「缺省路径行为零变化」A1 硬约束)。
267
+ if (routing.engineId === DEFAULT_ENGINE_ID) {
268
+ return {
269
+ engine: opts.piEngine,
270
+ engineId: DEFAULT_ENGINE_ID,
271
+ requestedEngineId: DEFAULT_ENGINE_ID,
272
+ source: routing.source,
273
+ };
274
+ }
275
+
276
+ return routeEngine({
277
+ routing: opts.routing,
278
+ taskModel: opts.taskModel,
279
+ strict: opts.strict,
280
+ probe: opts.probe,
281
+ // 本地 pi 恒可用(per-session DI 绑定)——get/has/list 注入同一口径:
282
+ // probe 失败兜底回 pi 时取本地实例接管,engine_not_found 文案不漏报本地 pi。
283
+ getEngineFn: (engineId) =>
284
+ engineId === DEFAULT_ENGINE_ID ? opts.piEngine : (opts.getEngineFn?.(engineId) ?? getEngine(engineId)),
285
+ hasEngineFn: (engineId) =>
286
+ engineId === DEFAULT_ENGINE_ID || (opts.hasEngineFn?.(engineId) ?? hasEngine(engineId)),
287
+ listEnginesFn: () => {
288
+ const listed = opts.listEnginesFn?.() ?? listEngines();
289
+ return listed.includes(DEFAULT_ENGINE_ID) ? listed : [DEFAULT_ENGINE_ID, ...listed];
290
+ },
291
+ });
292
+ }
@@ -6,12 +6,13 @@
6
6
  // 为什么单独一层:执行层现有四个核心类型(ExecuteOptions/AgentEvent/AgentResult/AgentRunner
7
7
  // port)的中立是「碰巧的,不是设计的」——thinkingLevel 是 pi 7 档枚举、skillPath 假设引擎有
8
8
  // --skill flag、conversation/idleTimeoutMs 是 pi chatMode 专属形态(设计 §2.1)。本文件把
9
- // 「agent 调用」的引擎无关语义显式化为 AgentTaskSpec / AgentOutcome 等类型,EnginePort
10
- // (port.ts)与其下各引擎适配器都以本层为唯一契约点。
9
+ // 「agent 调用」的引擎无关语义显式化为 AgentOutcome 等类型,EnginePort(port.ts)与其下
10
+ // 各引擎适配器都以本层为唯一契约点。
11
11
  //
12
- // 泛化原则(D2):从现有类型泛化,不另起炉灶——字段与 execution/types.ts
13
- // ExecuteOptions、orchestration/models/types.ts 的 AgentResult 逐一锚定,标注「泛化」的
14
- // 条目语义有变,标注「新增」为引擎层新引入。
12
+ // [D6 任务形状合流] 原本层的任务声明类型 AgentTaskSpec/PersonaSpec 已并入
13
+ // orchestration/models/types.ts 的 AgentCallOpts(单一任务形状,SAR 直产、pi 边界一次
14
+ // 直出——docs/design/subagent-dual-track-convergence.md §3.3 D6)。本文件不再定义任务
15
+ // 声明;EnginePort.run 的入参即 AgentCallOpts(字段裁定与裁撤记录见其类型注释)。
15
16
  //
16
17
  // AgentResult 消歧(设计 §2.1/§3.3.5):仓内有两个同名 AgentResult——
17
18
  // ① orchestration 层 workflow 消费的那份(orchestration/models/types.ts,主字段
@@ -21,8 +22,8 @@
21
22
  // ——record 内部投影,保持原名不动。
22
23
  // 引擎层终态命名 AgentOutcome,与两者不同名,消除「同名不同义」。
23
24
 
24
- import type { AgentUsage, ToolCallEntry } from "../../orchestration/models/types.ts";
25
- import type { AgentUsageTotal, ToolCall, WorktreeHandle } from "../types.ts";
25
+ import type { AgentFailureKind, AgentUsage, ToolCallEntry } from "../../orchestration/models/types.ts";
26
+ import type { AgentUsageTotal, ToolCall } from "../types.ts";
26
27
 
27
28
  // AgentEvent 8 种事件原样保留,唯一权威定义仍是 execution/types.ts——引擎层 re-export
28
29
  // 不复制第二份(设计 §3.3.5);经 shared/agent-event.ts 的既有出口转发,维持「shared/
@@ -30,101 +31,6 @@ import type { AgentUsageTotal, ToolCall, WorktreeHandle } from "../types.ts";
30
31
  // 一次 turn_end)由 conformance 套件断言(P4),不在类型层编码。
31
32
  export type { AgentEvent } from "../../shared/agent-event.ts";
32
33
 
33
- // ============================================================
34
- // AgentTaskSpec(= 现有 ExecuteOptions 泛化,D2)
35
- // ============================================================
36
-
37
- /** 人设(persona)注入规格:原 skillPath + appendSystemPrompt 收拢进一个语义单元(D2)。 */
38
- export interface PersonaSpec {
39
- /**
40
- * agent 名/路径。与 AgentTaskSpec.agent 的分工:agent 是 resolveIdentity 的身份解析
41
- * 键(模型/系统提示等身份语义);agentRef 是 persona 注入通道的定位符——引擎按
42
- * capabilities.personaInjection 决定注入通道(file/flag/prompt)时用它定位人设。
43
- * pi 引擎不消费此字段(身份解析走 spec.agent),留给 flag/file 通道的引擎。
44
- */
45
- agentRef?: string;
46
- /**
47
- * 原 ExecuteOptions.skillPath。公共 persona 路由三策略(file/flag/prompt)的分流
48
- * 载体(D4)——超长 prompt 时优先 file/flag 通道分流的落点。
49
- */
50
- skillPath?: string;
51
- /** 追加系统提示内容数组(原样透传;schema 仿真段由公共降级层拼装后放入,P2)。 */
52
- appendSystemPrompt?: string[];
53
- }
54
-
55
- /**
56
- * 引擎无关的 agent 任务声明(= ExecuteOptions 泛化,字段逐条锚定设计 §3.3.5)。
57
- *
58
- * 与 ExecuteOptions 的差异(泛化点):
59
- * - thinkingLevel(pi 7 档枚举语义)→ effort?: string,各引擎自行映射或忽略;
60
- * - skillPath + appendSystemPrompt → persona(PersonaSpec);
61
- * - conversation/idleTimeoutMs 保留原名透传——属 interact 交互控制面的 task 标志(D1),
62
- * 不是 pi 专有语义的泄漏,而是「任务声明里声明交互模式」的中立表达;
63
- * - 删字段去向:signal/ctxModel/onComplete 是运行期句柄,移入 RunContext(port.ts);
64
- * schemaEnv 内化到 PiEngine(从 task.schema 派生,见 engines/pi/task-spec-mapper.ts)。
65
- *
66
- * 新增(为后续 wave 预留形状,P1 无生产写入方):
67
- * - denyTools:中立工具 denylist(附录 A 该行的载体);
68
- * - permissionMode:中立权限模式(映射按 capabilities.permissionMode)。
69
- */
70
- export interface AgentTaskSpec {
71
- /** 原样(ExecuteOptions.task)。 */
72
- task: string;
73
- /** 原样(ExecuteOptions.slug,≤35 字符)。 */
74
- slug: string;
75
- /** 原样(ExecuteOptions.agent,resolveIdentity 的 agent ref)。 */
76
- agent?: string;
77
- /** 原样(ExecuteOptions.model;在引擎 provider 体系内解释,D9②)。 */
78
- model?: string;
79
- /**
80
- * 泛化:原 ExecuteOptions.thinkingLevel。引擎无关的推理投入档位字符串——
81
- * pi 引擎把它原值映射回 thinkingLevel 7 档;其他引擎自行映射(CC 5 档)或忽略
82
- * (kimi ❌)。不定义联合枚举:档位集合是引擎私有语义,中立层只透传字符串。
83
- */
84
- effort?: string;
85
- /** 泛化:原 skillPath + appendSystemPrompt 收拢(D2)。 */
86
- persona?: PersonaSpec;
87
- /**
88
- * 原样(ExecuteOptions.schema)。native/emulated 分流依据(D4 硬边界):pi 的
89
- * PI_WORKFLOW_SCHEMA env 注入链路按 native 直传,公共仿真层只服务 emulated 引擎。
90
- */
91
- schema?: Record<string, unknown>;
92
- /**
93
- * 原样(ExecuteOptions.maxTurns)。pi 引擎专属(turn limiter + spawn watchdog
94
- * 估算依赖 pi 的 turn_end 事件流);其他引擎 prepare 期显式拒绝(U4,同 fork 模式)。
95
- * 显式 0 压过 SPAWN_WATCHDOG_ENV 兑底(SP-6 参数 > env,U5);undefined 未传才由
96
- * env 兑底。
97
- */
98
- maxTurns?: number;
99
- /** 原样(ExecuteOptions.graceTurns)。 */
100
- graceTurns?: number;
101
- /** 原样(ExecuteOptions.fork)。pi 专属;其他引擎 prepare 期按 capabilities 拒绝。 */
102
- fork?: boolean;
103
- /**
104
- * 原样(ExecuteOptions.worktree)。公共层职责(worktree-manager),非引擎职责——
105
- * 引擎只把它当 spawn cwd 的来源之一。
106
- */
107
- worktree?: boolean | WorktreeHandle;
108
- /** 原样(ExecuteOptions.cwd)。 */
109
- cwd?: string;
110
- /** 原样(ExecuteOptions.conversation,interact 控制面的 task 标志,D1)。 */
111
- conversation?: boolean;
112
- /** 原样(ExecuteOptions.idleTimeoutMs,同上)。 */
113
- idleTimeoutMs?: number;
114
- /** 新增:中立工具 denylist。各引擎做语法映射(附录 A「工具 denylist」行的载体)。 */
115
- denyTools?: string[];
116
- /** 新增:中立权限模式。映射按 capabilities.permissionMode(kimi fixed auto = ignored)。 */
117
- permissionMode?: string;
118
- /**
119
- * [P4 形状预留,D9① 守卫 b 的独立载体] 任务对引擎能力的显式依赖声明。
120
- * 首期无生产写入方:守卫 b 与守卫 a 合流(显式 engine 即能力依赖声明)——调用方
121
- * 按引擎 id 表达依赖。下钻时机(AgentTaskSpec 泛化成熟后):调用方改按能力表达
122
- * (如 requires: { sandbox: 'native' }),路由层将本字段与各引擎 capabilities()
123
- * 对照,无引擎满足时报 engine_capability_unsupported(调用前拒绝,D11 处置三级)。
124
- */
125
- requires?: Partial<EngineCapabilities>;
126
- }
127
-
128
34
  // ============================================================
129
35
  // AgentOutcome(锚定 orchestration 层 AgentResult,§3.3.5)
130
36
  // ============================================================
@@ -136,6 +42,13 @@ export interface AgentTaskSpec {
136
42
  export interface AgentOutcome {
137
43
  /** 原样(AgentResult.content)。 */
138
44
  content: string;
45
+ /**
46
+ * 原样(AgentResult.failureKind,D5-③ 失败分诊结构化标签)。产出侧唯一识别点 =
47
+ * engines/pi/output-collector(collectResult 分类写入);缺省 = unknown = 可重试
48
+ * (消费侧 executeAgentCall 只读字段分诊,不扫 error 文案)。非 pi 引擎不产出,
49
+ * 恒缺省(unknown 语义)。
50
+ */
51
+ failureKind?: AgentFailureKind;
139
52
  /**
140
53
  * 原样(AgentResult.parsedOutput)。native 引擎直传 / 仿真层 ajv 产出(D4 硬分流:
141
54
  * native 路径公共层不做二次校验、不改写其结果)。
@@ -274,6 +187,15 @@ export interface EngineCapabilities {
274
187
  interrupt: "native" | "kill-only";
275
188
  /** kimi headless 固定 auto = ignored;GUI 据此隐藏/提示。 */
276
189
  permissionMode: "native" | "fixed" | "ignored";
190
+ /**
191
+ * [D3-④ r3 裁定] maxTurns 轮数上限的执行能力位(pi = true:turn limiter + spawn
192
+ * watchdog 估算兑现;zcode = false:无 turn_end 语义,静默丢弃会造成「传了上限却
193
+ * 失控」假象)。调用前预检(common/capability-gate)按本位拦「声明不支持的能力」
194
+ * ——pi 不拦 maxTurns(已支持能力,由 turn-limiter 执行)、zcode 同步拒绝。
195
+ * 现状 11 个能力位无可承载 maxTurns 的语义位(fork 拦截可借 session 分叉通道族判,
196
+ * maxTurns 无可借位),故扩位而非保留引擎内硬编码 shape 检查。
197
+ */
198
+ maxTurns: boolean;
277
199
  }
278
200
 
279
201
  // ============================================================
@@ -296,7 +218,12 @@ export interface ProbeReport {
296
218
  * 声明 conversation unsupported 的引擎调用前拒绝(engine_capability_unsupported)。
297
219
  */
298
220
  export type InteractAction =
299
- | { kind: "message"; payload: string }
221
+ /**
222
+ * interrupt:true = steer(抢占)/ false|缺省 = followUp(排队)——pi streamingBehavior
223
+ * 语义的中立承载(D1 §3.3.5「后续 wave 如需抢占语义再扩展 InteractAction」的兑现,
224
+ * chat 域投递经 engine.interact 接通时落地;不支持抢占的引擎忽略)。
225
+ */
226
+ | { kind: "message"; payload: string; interrupt?: boolean }
300
227
  | { kind: "close"; payload?: { force: boolean } }
301
228
  | { kind: "cancel" };
302
229