@zhushanwen/subagent-core 0.6.0 → 0.7.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 (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,168 +0,0 @@
1
- // zcode-engine-degrade.test.ts —— appserver 错误分类回归门(降级链已删,仅存本主题)。
2
- // 2026-09 单一 app-server 形态重构删除了整条降级机制:CLI spawn 降级重跑、probe 冒烟
3
- // 门控、模式钉扎 env 三态均不复存在——协议漂移类错误直接上报可操作错误,不再换通道
4
- // 保底。原「首败漂移降级」「probe 冒烟」「env 三态」describe 随机制删除,本文件仅存
5
- // 错误规格表回归门:
6
- // - -32603 "Model config is missing" → engine_credential_missing(共享宿主 HOME——
7
- // 凭据在 ZCode 桌面端管理),不换路径(第二任务仍走 app-server,create 帧计数增长);
8
- // - -32004 / -32010 → engine_run_failed 按任务失败上报(非漂移类,无 fallback 标注)。
9
- // 全部跑 __fixtures__/fake-appserver.mjs 子进程(scenario 注入),绝不 spawn 真 zcode.cjs。
10
-
11
- import * as fs from "node:fs";
12
- import * as os from "node:os";
13
- import * as path from "node:path";
14
- import { fileURLToPath } from "node:url";
15
-
16
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
17
-
18
- import type { RunContext } from "../../../port.ts";
19
- import type { AgentCallOpts } from "../../../../../orchestration/models/types.ts";
20
- import { ZCODE_APPSERVER_GOLDEN } from "../golden-sample.ts";
21
- import { ZcodeEngine, type ZcodeEngineDeps } from "../zcode-engine.ts";
22
-
23
- const FAKE_CLI = fileURLToPath(new URL("./__fixtures__/fake-appserver.mjs", import.meta.url));
24
- const PROVIDER = "test-provider";
25
-
26
- const engines: ZcodeEngine[] = [];
27
- let seq = 0;
28
- let tmpRoot: string;
29
- let dataDir: string;
30
- let v2Path: string;
31
-
32
- function writeJson(p: string, v: unknown): void {
33
- fs.mkdirSync(path.dirname(p), { recursive: true });
34
- fs.writeFileSync(p, JSON.stringify(v, null, 2));
35
- }
36
-
37
- beforeEach(() => {
38
- tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "zcode-eng-degrade-"));
39
- dataDir = path.join(tmpRoot, "data");
40
- v2Path = path.join(tmpRoot, "v2.json");
41
- writeJson(v2Path, {
42
- provider: { [PROVIDER]: { options: { apiKey: "k", baseURL: "https://t.example" }, models: { m1: {} } } },
43
- });
44
- });
45
-
46
- afterEach(async () => {
47
- for (const engine of engines.splice(0)) await engine.dispose().catch(() => undefined);
48
- fs.rmSync(tmpRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
49
- });
50
-
51
- interface ErrorScenario {
52
- /** 主连接(常驻)scenario 覆盖:create/send 阶段错误注入。 */
53
- createError?: { code: number; message: string; data?: unknown };
54
- sendError?: { code: number; message: string; data?: unknown };
55
- }
56
-
57
- /** 建一个连到 fake 的引擎(scenario 文件随 env 固化进子进程;每测试独立 state 文件)。 */
58
- function makeEngine(s: ErrorScenario = {}) {
59
- seq += 1;
60
- const stateFile = path.join(tmpRoot, `state-${seq}.jsonl`);
61
- const scenarioFile = path.join(tmpRoot, `scenario-${seq}.json`);
62
- const workspace = path.join(tmpRoot, `ws-${seq}`);
63
- const pushes = [...ZCODE_APPSERVER_GOLDEN.pushStream, ...ZCODE_APPSERVER_GOLDEN.terminal].map((l) =>
64
- typeof l === "string" ? (JSON.parse(l) as Record<string, unknown>) : l,
65
- );
66
- writeJson(scenarioFile, {
67
- createResult: JSON.parse(ZCODE_APPSERVER_GOLDEN.createResponse),
68
- readResult: JSON.parse(ZCODE_APPSERVER_GOLDEN.readResponse),
69
- sendPushes: pushes,
70
- ...(s.createError !== undefined ? { createError: s.createError } : {}),
71
- ...(s.sendError !== undefined ? { sendError: s.sendError } : {}),
72
- });
73
- const deps: ZcodeEngineDeps = {
74
- engineDataDir: () => dataDir,
75
- cliPath: FAKE_CLI,
76
- sources: { v2ConfigPath: v2Path },
77
- processEnv: {
78
- PATH: process.env.PATH ?? "",
79
- FAKE_STATE_FILE: stateFile,
80
- FAKE_SESSION_SCENARIO: scenarioFile,
81
- },
82
- };
83
- const engine = new ZcodeEngine(deps);
84
- engines.push(engine);
85
- return { engine, stateFile, workspace };
86
- }
87
-
88
- // ── 流水读取 helpers(与 zcode-engine-appserver.test.ts 同款) ──
89
-
90
- interface StateEvent {
91
- seq: number;
92
- ev: string;
93
- [key: string]: unknown;
94
- }
95
-
96
- function readState(file: string): StateEvent[] {
97
- try {
98
- return fs
99
- .readFileSync(file, "utf8")
100
- .trim()
101
- .split("\n")
102
- .filter(Boolean)
103
- .map((l) => JSON.parse(l) as StateEvent);
104
- } catch {
105
- return [];
106
- }
107
- }
108
-
109
- function isRecord(v: unknown): v is Record<string, unknown> {
110
- return typeof v === "object" && v !== null && !Array.isArray(v);
111
- }
112
-
113
- function recvFrames(stateFile: string, method: string): Array<{ id: number; params: Record<string, unknown> }> {
114
- return readState(stateFile)
115
- .filter((e) => e.ev === "recv")
116
- .map((e) => e.frame)
117
- .filter(
118
- (f): f is { id: number; params: Record<string, unknown> } =>
119
- isRecord(f) && f.method === method && isRecord(f.params) && typeof f.id === "number",
120
- );
121
- }
122
-
123
- function makeTask(overrides?: Partial<AgentCallOpts>): AgentCallOpts {
124
- return { prompt: "做点什么", description: "s", model: `${PROVIDER}/m1`, ...overrides };
125
- }
126
-
127
- function makeCtx(overrides?: Partial<RunContext>): RunContext {
128
- return { taskId: "sa-degrade", poolKey: "", ...overrides };
129
- }
130
-
131
- // ============================================================
132
- // 错误分类表(非漂移类:-32603 / -32004 / -32010 不降级)
133
- // ============================================================
134
-
135
- describe("错误分类(错误规格表)", () => {
136
- it("-32603 'Model config is missing' → engine_credential_missing,不降级(第二任务仍走 app-server)", async () => {
137
- const { engine, stateFile, workspace } = makeEngine({
138
- createError: { code: -32603, message: "Model config is missing" },
139
- });
140
- const r1 = await engine.run(makeTask({ cwd: workspace }), makeCtx());
141
- expect(r1.outcome.error).toContain("engine_credential_missing");
142
- expect(r1.outcome.engineFallback).toBeUndefined();
143
- const createsBefore = recvFrames(stateFile, "session/create").length;
144
- const r2 = await engine.run(makeTask({ cwd: workspace }), makeCtx());
145
- expect(r2.outcome.error).toContain("engine_credential_missing");
146
- expect(recvFrames(stateFile, "session/create").length).toBeGreaterThan(createsBefore);
147
- }, 20_000);
148
-
149
- it("-32004 'Session is not active' → 任务失败上报,不降级", async () => {
150
- const { engine, workspace } = makeEngine({
151
- createError: { code: -32004, message: "Session is not active" },
152
- });
153
- const r1 = await engine.run(makeTask({ cwd: workspace }), makeCtx());
154
- expect(r1.outcome.error).toContain("engine_run_failed");
155
- expect(r1.outcome.error).toContain("-32004");
156
- expect(r1.outcome.engineFallback).toBeUndefined();
157
- }, 20_000);
158
-
159
- it("-32010(send busy)→ 任务失败上报,不降级", async () => {
160
- const { engine, workspace } = makeEngine({
161
- sendError: { code: -32010, message: "A turn is already running" },
162
- });
163
- const r1 = await engine.run(makeTask({ cwd: workspace }), makeCtx());
164
- expect(r1.outcome.error).toContain("engine_run_failed");
165
- expect(r1.outcome.error).toContain("-32010");
166
- expect(r1.outcome.engineFallback).toBeUndefined();
167
- }, 20_000);
168
- });
@@ -1,210 +0,0 @@
1
- // zcode-engine-dispose.test.ts —— P0-1 U5 dispose 收割(引擎集成面,fake-appserver
2
- // 子进程,绝不 spawn 真 zcode.cjs)。
3
- //
4
- // 设计权威源:docs/design/timeout-zcode-turn-and-settled-watchdog.md §3.4(退化
5
- // 路径)、§6 D7(dispose 收割兜底)、§11 P-Z3。真实现场(真实环境的 close 吞没)
6
- // 归 Gate B;本文件验证引擎层可注入的集成行为:
7
- // ① dispose 时在途 turn 收敛为明确失败(不挂满 turn 预算)且不触发重试轮
8
- // (u-z4 disposed 标志衔接:收割 ≠ 瞬时崩溃——boot 1 / create×1 机械证据);
9
- // ② dispose 全链窗口 = HARVEST_GRACE 量级(与 awaitConnFinalized 同源常量——
10
- // 行为耗时断言 + 源码常量同源静态断言)。
11
- // channel 层 close 吞没形态的机制断言在 session-channel-dispose-harvest.test.ts
12
- // (mock 连接——真实子进程形态下 Node close 事件不可吞没,P-Z3 真实现场归 Gate B)。
13
-
14
- import * as fs from "node:fs";
15
- import * as os from "node:os";
16
- import * as path from "node:path";
17
- import { fileURLToPath } from "node:url";
18
-
19
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
20
-
21
- import type { EngineRunResult, RunContext } from "../../../port.ts";
22
- import type { AgentCallOpts } from "../../../../../orchestration/models/types.ts";
23
- import {
24
- ZCODE_APPSERVER_HARVEST_GRACE_MS,
25
- ZCODE_KILL_GRACE_MS,
26
- } from "../constants.ts";
27
- import { ZCODE_APPSERVER_GOLDEN } from "../golden-sample.ts";
28
- import { ZcodeEngine, type ZcodeEngineDeps } from "../zcode-engine.ts";
29
-
30
- const FAKE_CLI = fileURLToPath(new URL("./__fixtures__/fake-appserver.mjs", import.meta.url));
31
- const PROVIDER = "test-provider";
32
-
33
- const GOLDEN_SESSION_ID = "sess_golden_r3_01";
34
- /** 挂起场景:send 后零推送——turn 无事件无终态(dispose 收割的形态前提)。 */
35
- const HANG_PUSHES: string[] = [];
36
-
37
- const engines: ZcodeEngine[] = [];
38
- let seq = 0;
39
- let tmpRoot: string;
40
- let dataDir: string;
41
- let v2Path: string;
42
-
43
- function writeJson(p: string, v: unknown): void {
44
- fs.mkdirSync(path.dirname(p), { recursive: true });
45
- fs.writeFileSync(p, JSON.stringify(v, null, 2));
46
- }
47
-
48
- beforeEach(() => {
49
- tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "zcode-eng-dispose-"));
50
- dataDir = path.join(tmpRoot, "data");
51
- v2Path = path.join(tmpRoot, "v2.json");
52
- writeJson(v2Path, {
53
- provider: { [PROVIDER]: { options: { apiKey: "k", baseURL: "https://t.example" }, models: { m1: {} } } },
54
- });
55
- });
56
-
57
- afterEach(async () => {
58
- vi.unstubAllEnvs();
59
- for (const engine of engines.splice(0)) await engine.dispose().catch(() => undefined);
60
- fs.rmSync(tmpRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
61
- });
62
-
63
- interface EngineFixture {
64
- engine: ZcodeEngine;
65
- stateFile: string;
66
- scenarioFile: string;
67
- workspace: string;
68
- }
69
-
70
- function makeEngine(): EngineFixture {
71
- seq += 1;
72
- const stateFile = path.join(tmpRoot, `state-${seq}.jsonl`);
73
- const scenarioFile = path.join(tmpRoot, `scenario-${seq}.json`);
74
- const workspace = path.join(tmpRoot, `ws-${seq}`);
75
- writeJson(scenarioFile, {
76
- createResult: JSON.parse(ZCODE_APPSERVER_GOLDEN.createResponse),
77
- readResult: JSON.parse(ZCODE_APPSERVER_GOLDEN.readResponse),
78
- sendPushes: HANG_PUSHES.map((l) => JSON.parse(l) as Record<string, unknown>),
79
- });
80
- const deps: ZcodeEngineDeps = {
81
- engineDataDir: () => dataDir,
82
- cliPath: FAKE_CLI,
83
- sources: { v2ConfigPath: v2Path },
84
- processEnv: {
85
- PATH: process.env.PATH ?? "",
86
- XYZ_ZCODE_MODE: "appserver",
87
- FAKE_STATE_FILE: stateFile,
88
- FAKE_SESSION_SCENARIO: scenarioFile,
89
- },
90
- };
91
- const engine = new ZcodeEngine(deps);
92
- engines.push(engine);
93
- return { engine, stateFile, scenarioFile, workspace };
94
- }
95
-
96
- // ── 流水读取 helpers(与 zcode-engine-timeout.test.ts 同款) ──
97
-
98
- interface StateEvent {
99
- seq: number;
100
- ev: string;
101
- [key: string]: unknown;
102
- }
103
-
104
- function readState(file: string): StateEvent[] {
105
- try {
106
- return fs
107
- .readFileSync(file, "utf8")
108
- .trim()
109
- .split("\n")
110
- .filter(Boolean)
111
- .map((l) => JSON.parse(l) as StateEvent);
112
- } catch {
113
- return [];
114
- }
115
- }
116
-
117
- function isRecord(v: unknown): v is Record<string, unknown> {
118
- return typeof v === "object" && v !== null && !Array.isArray(v);
119
- }
120
-
121
- function sentMethods(stateFile: string): string[] {
122
- return readState(stateFile)
123
- .map((e) => e.frame)
124
- .filter((f): f is Record<string, unknown> => isRecord(f) && typeof f.method === "string")
125
- .map((f) => f.method as string);
126
- }
127
-
128
- function bootCount(stateFile: string): number {
129
- return readState(stateFile).filter((e) => e.ev === "boot").length;
130
- }
131
-
132
- /** 轮询流水直到指定 method 出现(在途 turn 已挂的同步点;超时抛错防静默空转)。 */
133
- async function waitForMethod(stateFile: string, method: string, timeoutMs = 5000): Promise<void> {
134
- const deadline = Date.now() + timeoutMs;
135
- while (Date.now() < deadline) {
136
- if (sentMethods(stateFile).includes(method)) return;
137
- await new Promise((r) => setTimeout(r, 20));
138
- }
139
- throw new Error(`流水 ${timeoutMs}ms 内未出现 ${method}——在途 turn 未建立`);
140
- }
141
-
142
- function makeTask(overrides?: Partial<AgentCallOpts>): AgentCallOpts {
143
- return { prompt: "做点什么", description: "s", model: `${PROVIDER}/m1`, ...overrides };
144
- }
145
-
146
- function makeCtx(overrides?: Partial<RunContext>): RunContext {
147
- return { taskId: "sa-dispose", poolKey: "", ...overrides };
148
- }
149
-
150
- // ============================================================
151
- // dispose 收割(P0-1 U5/D7:在途 turn 收敛 + 不重试 + 窗口量级)
152
- // ============================================================
153
-
154
- describe("dispose 收割(P0-1 U5:引擎集成面)", () => {
155
- it("dispose 时在途 turn 收敛为明确失败且不重试:engine_run_failed、boot 1、create×1(收割≠瞬时崩溃,u-z4 disposed 短路)", async () => {
156
- // 两 timer 显式关闭(规则 19 opt-out 形态)——排除 timeout 判死路径,
157
- // 本用例的失败终态只能来自 dispose 收割链(onClose failAllTurns → dispose
158
- // no-op 幂等;close 吞没变体由 channel 层 mock 测试承载)
159
- vi.stubEnv("XYZ_ZCODE_TURN_IDLE_TIMEOUT_MS", "0");
160
- vi.stubEnv("XYZ_ZCODE_TURN_MAX_TIMEOUT_MS", "0");
161
- const f = makeEngine();
162
- const runPromise: Promise<EngineRunResult> = f.engine.run(makeTask({ cwd: f.workspace }), makeCtx());
163
- await waitForMethod(f.stateFile, "session/send"); // 在途 turn 已建立
164
-
165
- const disposeStartedAt = Date.now();
166
- await f.engine.dispose();
167
- const disposeMs = Date.now() - disposeStartedAt;
168
-
169
- // run promise 在 dispose 窗口内落定(收割生效的结构性证据——5s 保护超时)
170
- const r = await Promise.race([
171
- runPromise,
172
- new Promise<never>((_, rej) =>
173
- setTimeout(() => rej(new Error("run promise 未在 dispose 后 5s 内落定——收割未生效")), 5000),
174
- ),
175
- ]);
176
- expect(r.outcome.error).toMatch(/^engine_run_failed:/);
177
- // 收割错误带连接层崩溃 reason(close 正常到达形态:onClose 主路径先收割)
178
- expect(r.outcome.error).toContain("进程退出");
179
-
180
- // 收割 ≠ 瞬时崩溃:无重试轮、无惰性重建(boot 1 / create×1 机械证据)
181
- const methods = sentMethods(f.stateFile);
182
- expect(methods.filter((m) => m === "session/create").length).toBe(1);
183
- expect(bootCount(f.stateFile)).toBe(1);
184
-
185
- // 窗口量级:dispose 全链不超 kill 链 + HARVEST_GRACE + 进程调度余量——
186
- // 收割在 grace 量级窗口闭合,而非挂满 turn 预算(30min/60min 量级差异)
187
- expect(disposeMs).toBeLessThan(ZCODE_KILL_GRACE_MS + ZCODE_APPSERVER_HARVEST_GRACE_MS + 2000);
188
- }, 30_000);
189
-
190
- it("grace 窗口量级一致性:dispose 收割 race 窗口与 awaitConnFinalized 同源 ZCODE_APPSERVER_HARVEST_GRACE_MS(验收⑤静态断言)", async () => {
191
- const engineSrc = fs.readFileSync(
192
- fileURLToPath(new URL("../zcode-engine.ts", import.meta.url)),
193
- "utf8",
194
- );
195
- // awaitConnFinalized:close 永不到达时同量级兜底(u-z2 先例)
196
- expect(engineSrc).toContain("setTimeout(() => finish(), ZCODE_APPSERVER_HARVEST_GRACE_MS)");
197
- // shutdownRuntimeAndDisposeChannel:dispose 收割 race 窗口(本单元挂接点)
198
- expect(engineSrc).toContain("delayResolved(ZCODE_APPSERVER_HARVEST_GRACE_MS");
199
- // channel dispose 收割本体是同步操作(无自有 timer)——窗口归引擎 race 单点
200
- const channelSrc = fs.readFileSync(
201
- fileURLToPath(new URL("../session-channel.ts", import.meta.url)),
202
- "utf8",
203
- );
204
- const disposeBody = channelSrc.slice(
205
- channelSrc.indexOf(" dispose(): void {"),
206
- channelSrc.indexOf(" /** 连接死亡收割"),
207
- );
208
- expect(disposeBody).not.toContain("setTimeout");
209
- });
210
- });