@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.
- package/README.md +1 -1
- package/dist/chunk-KXVBIVOU.js +16 -0
- package/dist/chunk-T2SYBW3I.js +24 -0
- package/dist/chunk-VURUAGMM.js +2305 -0
- package/dist/{types-C3fE3R9x.d.cts → engine-discovery-scan-ocpM8FmI.d.cts} +770 -668
- package/dist/{types-C3fE3R9x.d.ts → engine-discovery-scan-ocpM8FmI.d.ts} +770 -668
- package/dist/execution/engine/engine-discovery-scan.cjs +2210 -0
- package/dist/execution/engine/engine-discovery-scan.d.cts +4 -0
- package/dist/execution/engine/engine-discovery-scan.d.ts +4 -0
- package/dist/execution/engine/engine-discovery-scan.js +20 -0
- package/dist/execution/engine/paths.cjs +6 -23
- package/dist/execution/engine/paths.d.cts +1 -8
- package/dist/execution/engine/paths.d.ts +1 -8
- package/dist/execution/engine/paths.js +1 -1
- package/dist/execution/relay-env.cjs +12 -28
- package/dist/execution/relay-env.d.cts +1 -33
- package/dist/execution/relay-env.d.ts +1 -33
- package/dist/execution/relay-env.js +5 -3
- package/dist/index.cjs +14045 -16059
- package/dist/index.d.cts +1035 -1579
- package/dist/index.d.ts +1035 -1579
- package/dist/index.js +9838 -13800
- package/dist.bundle/index.cjs +28875 -30323
- package/package.json +20 -26
- package/src/__tests__/record-store-last-line.test.ts +16 -7
- package/src/core/error-message.ts +7 -6
- package/src/core/host-services.ts +8 -2
- package/src/core/notify-ports.ts +17 -2
- package/src/execution/__tests__/chat-engine-routing.test.ts +62 -28
- package/src/execution/__tests__/chat-round-first-round-watchdog.test.ts +255 -0
- package/src/execution/__tests__/collect-coordinator-service.test.ts +36 -47
- package/src/execution/__tests__/collect-mixed-dispatch.test.ts +20 -53
- package/src/execution/__tests__/delivery-methods.test.ts +179 -237
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -2
- package/src/execution/__tests__/execute-nesting.test.ts +20 -13
- package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +20 -33
- package/src/execution/__tests__/gc-timer.test.ts +7 -22
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +20 -10
- package/src/execution/__tests__/helpers/fake-engine-port.ts +187 -0
- package/src/execution/__tests__/helpers/spawn-mock.ts +36 -9
- package/src/execution/__tests__/helpers/subagent-service-mocks.ts +1 -1
- package/src/execution/__tests__/idle-gc.test.ts +200 -0
- package/src/execution/__tests__/lifecycle-predicates.test.ts +26 -21
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +5 -2
- package/src/execution/__tests__/reconcile-sweep.test.ts +200 -0
- package/src/execution/__tests__/record-store.test.ts +60 -6
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +20 -13
- package/src/execution/__tests__/round-supervisor.test.ts +293 -0
- package/src/execution/__tests__/session-pending.test.ts +119 -17
- package/src/execution/__tests__/stream-sink-retirement.test.ts +10 -10
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +1 -11
- package/src/execution/__tests__/subagent-service-notify-gate.test.ts +33 -30
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +2 -9
- package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +59 -129
- package/src/execution/__tests__/subagent-service.test.ts +2 -2
- package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +109 -7
- package/src/execution/__tests__/subprocess-agent-runner.test.ts +108 -36
- package/src/execution/__tests__/sync-collect-recovery.test.ts +21 -36
- package/src/execution/__tests__/workflow-state-root.test.ts +232 -0
- package/src/execution/agent-registry.ts +6 -2
- package/src/execution/dialog-queue.ts +6 -73
- package/src/execution/engine/__tests__/common/capability-gate.test.ts +115 -15
- package/src/execution/engine/__tests__/common/errors.test.ts +11 -18
- package/src/execution/engine/__tests__/common/kill-chain.test.ts +7 -0
- package/src/execution/engine/__tests__/common/nesting-guard.test.ts +9 -3
- package/src/execution/engine/__tests__/common/session-view-service.test.ts +90 -3
- package/src/execution/engine/__tests__/conformance/H9-test-disposition.md +116 -0
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/fake-engine-protocol.mjs +377 -0
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/recorded.fixture.json +331 -0
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/smoke-run.fixture.json +213 -0
- package/src/execution/engine/__tests__/conformance/chat-round-protocol.test.ts +230 -0
- package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +69 -42
- package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +4 -81
- package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +67 -44
- package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +81 -54
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +133 -70
- package/src/execution/engine/__tests__/conformance/engine-crash.test.ts +143 -0
- package/src/execution/engine/__tests__/conformance/fake-engine-capabilities.ts +19 -0
- package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +7 -2
- package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +6 -5
- package/src/execution/engine/__tests__/conformance/protocol-blackbox.test.ts +398 -0
- package/src/execution/engine/__tests__/conformance/registry-fork-filter.test.ts +221 -0
- package/src/execution/engine/__tests__/conformance/round-liveness-supervisor.test.ts +302 -0
- package/src/execution/engine/__tests__/conformance/static-spawn-guard.test.ts +58 -0
- package/src/execution/engine/__tests__/engine-discovery-scan.test.ts +558 -0
- package/src/execution/engine/__tests__/host-task-spec.test.ts +45 -0
- package/src/execution/engine/__tests__/model-ref-split.test.ts +74 -0
- package/src/execution/engine/__tests__/registry.test.ts +206 -1
- package/src/execution/engine/__tests__/routing.test.ts +97 -0
- package/src/execution/engine/__tests__/run-failure-worktree-cleanup.test.ts +97 -0
- package/src/execution/engine/client/__tests__/__fixtures__/fake-engine.mjs +294 -0
- package/src/execution/engine/client/__tests__/engine-client.test.ts +516 -0
- package/src/execution/engine/client/__tests__/mirror.test.ts +67 -0
- package/src/execution/engine/client/__tests__/pid-file.test.ts +257 -0
- package/src/execution/engine/client/__tests__/protocol-closure.test.ts +95 -0
- package/src/execution/engine/client/__tests__/remote-engine.test.ts +457 -0
- package/src/execution/engine/client/client-options.ts +103 -0
- package/src/execution/engine/client/engine-client.ts +687 -0
- package/src/execution/engine/client/mirror.ts +167 -0
- package/src/execution/engine/client/pid-file.ts +392 -0
- package/src/execution/engine/client/reaper.ts +95 -0
- package/src/execution/engine/client/remote-engine.ts +441 -0
- package/src/execution/engine/client/reverse-router.ts +255 -0
- package/src/execution/engine/common/capability-gate.ts +109 -22
- package/src/execution/engine/common/errors.ts +9 -25
- package/src/execution/engine/common/event-journal.ts +4 -50
- package/src/execution/engine/common/journal-replay.ts +3 -1
- package/src/execution/engine/common/kill-chain.ts +18 -251
- package/src/execution/engine/common/nesting-guard.ts +18 -114
- package/src/execution/engine/common/pool-manager.ts +4 -0
- package/src/execution/engine/common/session-view-service.ts +56 -84
- package/src/execution/engine/config.ts +151 -0
- package/src/execution/engine/d8-compat.ts +346 -0
- package/src/execution/engine/engine-discovery-roots.ts +107 -0
- package/src/execution/engine/engine-discovery-scan.ts +269 -0
- package/src/execution/engine/engine-discovery.ts +30 -7
- package/src/execution/engine/engine-inspect-package.ts +282 -0
- package/src/execution/engine/engine-manifest.ts +244 -0
- package/src/execution/engine/host/__tests__/host-askuser-endpoint.test.ts +123 -0
- package/src/execution/engine/host/__tests__/host-bridge.test.ts +135 -0
- package/src/execution/engine/host/__tests__/spawned-children.test.ts +73 -0
- package/src/execution/engine/host/host-bridge.ts +150 -0
- package/src/execution/engine/host/host-ui-endpoint.ts +47 -0
- package/src/execution/engine/host/pi-host-binding.ts +91 -0
- package/src/execution/engine/host/spawned-children.ts +139 -0
- package/src/execution/engine/host-task-spec.ts +29 -2
- package/src/execution/engine/model-validation.ts +55 -2
- package/src/execution/engine/paths.ts +16 -41
- package/src/execution/engine/port.ts +48 -2
- package/src/execution/engine/registry.ts +153 -34
- package/src/execution/engine/routing.ts +225 -52
- package/src/execution/engine/types.ts +25 -200
- package/src/execution/finalize-record.ts +25 -0
- package/src/execution/idle-gc.ts +89 -14
- package/src/execution/lifecycle-manager.ts +10 -7
- package/src/execution/lifecycle-predicates.ts +10 -8
- package/src/execution/record-store.ts +29 -2
- package/src/execution/relay-env.ts +19 -36
- package/src/execution/round-supervisor/domain.ts +89 -0
- package/src/execution/round-supervisor/index.ts +33 -0
- package/src/execution/round-supervisor/notify-accounting.ts +87 -0
- package/src/execution/round-supervisor/reconcile-sweep.ts +235 -0
- package/src/execution/round-supervisor/service-binding.test.ts +661 -0
- package/src/execution/round-supervisor/service-binding.ts +273 -0
- package/src/execution/round-supervisor/supervisor.ts +426 -0
- package/src/execution/session-pending.ts +68 -74
- package/src/execution/settled-watchdog.ts +39 -0
- package/src/execution/subagent-service.ts +746 -400
- package/src/execution/subprocess-agent-runner.ts +16 -8
- package/src/execution/types.ts +41 -117
- package/src/execution/ui-channels.ts +13 -214
- package/src/execution/ui-request-handler-factory.ts +7 -4
- package/src/execution/ui-request-observability.ts +2 -2
- package/src/execution/workflow-state-root.ts +67 -0
- package/src/execution/worktree-git-ops.ts +5 -0
- package/src/execution/worktree-manager.ts +11 -1
- package/src/index.ts +55 -26
- package/src/orchestration/__tests__/execute-agent-call.test.ts +1 -1
- package/src/orchestration/execute-agent-call.ts +1 -1
- package/src/orchestration/file-run-store.ts +144 -59
- package/src/orchestration/models/types.ts +43 -42
- package/src/shared/zcode-model-ref.ts +31 -0
- package/dist/chunk-43ONBFZX.js +0 -240
- package/dist/chunk-A4IVZWVX.js +0 -31
- package/dist/chunk-APZY4IME.js +0 -27
- package/dist/chunk-V3VHZ2VX.js +0 -59
- package/dist/execution/engine/engines/zcode/constants.cjs +0 -107
- package/dist/execution/engine/engines/zcode/constants.d.cts +0 -135
- package/dist/execution/engine/engines/zcode/constants.d.ts +0 -135
- package/dist/execution/engine/engines/zcode/constants.js +0 -54
- package/dist/execution/engine/engines/zcode/reader.cjs +0 -276
- package/dist/execution/engine/engines/zcode/reader.d.cts +0 -21
- package/dist/execution/engine/engines/zcode/reader.d.ts +0 -21
- package/dist/execution/engine/engines/zcode/reader.js +0 -9
- package/src/__tests__/append-system-prompt-assembly.test.ts +0 -243
- package/src/__tests__/fr4-get-state-handshake.test.ts +0 -125
- package/src/__tests__/session-runner.test.ts +0 -69
- package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -191
- package/src/execution/__tests__/descendant-sweep-guards.test.ts +0 -220
- package/src/execution/__tests__/descendant-sweep.test.ts +0 -269
- package/src/execution/__tests__/engine-model-validation.test.ts +0 -741
- package/src/execution/__tests__/epipe-fallback.test.ts +0 -248
- package/src/execution/__tests__/execution-runtime-face.test.ts +0 -272
- package/src/execution/__tests__/get-state-handshake.test.ts +0 -127
- package/src/execution/__tests__/helpers/session-runner-mocks.ts +0 -113
- package/src/execution/__tests__/keep-alive-no-progress.test.ts +0 -280
- package/src/execution/__tests__/kill-all-escalation.test.ts +0 -196
- package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +0 -113
- package/src/execution/__tests__/output-collector.test.ts +0 -469
- package/src/execution/__tests__/pi-invocation.test.ts +0 -166
- package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -149
- package/src/execution/__tests__/rpc-mode.test.ts +0 -89
- package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +0 -387
- package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -277
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -254
- package/src/execution/__tests__/run-spawn-edges.test.ts +0 -1079
- package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
- package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
- package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
- package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -207
- package/src/execution/__tests__/service-kill-escalation.test.ts +0 -91
- package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +0 -110
- package/src/execution/__tests__/session-runner-close-prune.test.ts +0 -181
- package/src/execution/__tests__/session-runner-dispatch.test.ts +0 -489
- package/src/execution/__tests__/session-runner-epipe.test.ts +0 -179
- package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +0 -227
- package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +0 -290
- package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -352
- package/src/execution/__tests__/settled-watchdog.test.ts +0 -524
- package/src/execution/__tests__/spawn-args.test.ts +0 -446
- package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -192
- package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
- package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -208
- package/src/execution/__tests__/spawned-children.test.ts +0 -236
- package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
- package/src/execution/__tests__/stdin-writer.test.ts +0 -464
- package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -693
- package/src/execution/__tests__/temp-prompt.test.ts +0 -53
- package/src/execution/__tests__/timeout-integration.test.ts +0 -616
- package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
- package/src/execution/__tests__/turn-limiter.test.ts +0 -65
- package/src/execution/__tests__/ui-request-handler.test.ts +0 -205
- package/src/execution/__tests__/ui-request-queue.test.ts +0 -298
- package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -230
- package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
- package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +0 -149
- package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
- package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +0 -128
- package/src/execution/engine/__tests__/paths.test.ts +0 -39
- package/src/execution/engine/common/schema-emulation.ts +0 -189
- package/src/execution/engine/common/session-view-projection.ts +0 -51
- package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -615
- package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
- package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +0 -257
- package/src/execution/engine/engines/pi/argv-mirror.ts +0 -135
- package/src/execution/engine/engines/pi/get-state-handshake.ts +0 -179
- package/src/execution/engine/engines/pi/output-collector.ts +0 -317
- package/src/execution/engine/engines/pi/pi-engine.ts +0 -811
- package/src/execution/engine/engines/pi/pi-invocation.ts +0 -120
- package/src/execution/engine/engines/pi/reader.ts +0 -59
- package/src/execution/engine/engines/pi/registration.ts +0 -37
- package/src/execution/engine/engines/pi/session-runner.ts +0 -2840
- package/src/execution/engine/engines/pi/spawn-event-adapter.ts +0 -404
- package/src/execution/engine/engines/pi/stdin-writer.ts +0 -199
- package/src/execution/engine/engines/pi/temp-prompt.ts +0 -62
- package/src/execution/engine/engines/pi/turn-limiter.ts +0 -102
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +0 -301
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +0 -36
- package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +0 -321
- package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +0 -473
- package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -43
- package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -124
- package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
- package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -71
- package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +0 -247
- package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +0 -451
- package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +0 -792
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +0 -782
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +0 -168
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +0 -210
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +0 -353
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +0 -282
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +0 -372
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -145
- package/src/execution/engine/engines/zcode/appserver-launcher.ts +0 -167
- package/src/execution/engine/engines/zcode/connection.ts +0 -598
- package/src/execution/engine/engines/zcode/constants.ts +0 -176
- package/src/execution/engine/engines/zcode/golden-sample.ts +0 -47
- package/src/execution/engine/engines/zcode/parser.ts +0 -102
- package/src/execution/engine/engines/zcode/preparer.ts +0 -235
- package/src/execution/engine/engines/zcode/reader.ts +0 -381
- package/src/execution/engine/engines/zcode/registration.ts +0 -37
- package/src/execution/engine/engines/zcode/session-channel.ts +0 -968
- package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -1431
- package/src/execution/round-settlement.ts +0 -93
- package/src/execution/ui-request-queue.ts +0 -215
- package/src/shared/schema-env.ts +0 -44
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// capability-gate.test.ts —— [D3-④ 预检 capabilities 化] 拦截矩阵单测。
|
|
2
|
-
// 设计权威源:docs/design/subagent-
|
|
2
|
+
// 设计权威源:docs/design/subagent-engine-protocolization.md §3.3「能力位」段(manifest
|
|
3
|
+
// 权威双向处置)+ 历史源 subagent-dual-track-convergence.md §3.3 D3-④(r3 裁定:
|
|
3
4
|
// EngineCapabilities +maxTurns 位 pi=true/zcode=false,不保留硬编码 shape 检查)+
|
|
4
5
|
// §3.4 错误规格第 1 行 + §4 V4④⑤(正反向验收)。
|
|
5
6
|
//
|
|
@@ -7,21 +8,41 @@
|
|
|
7
8
|
// 1. per-engine 拦截矩阵:pi 全放行(含 maxTurns/fork/conversation/worktree——V4⑤
|
|
8
9
|
// 反向守护,pi 既有合法能力零拦截);zcode 四参数全拦(fork/conversation/
|
|
9
10
|
// maxTurns/worktree)
|
|
10
|
-
// 2. 错误族:engine_capability_unsupported + recovery
|
|
11
|
-
//
|
|
12
|
-
//
|
|
11
|
+
// 2. 错误族:engine_capability_unsupported + recovery 含可操作指引(调参数 / 修
|
|
12
|
+
// manifest / 升级引擎包——W3 协议化口径,不再指向「engine: pi」内置兜底)
|
|
13
|
+
// 3. fork 判据(借位裁定):session 分叉通道族任一可用即放行(OR 语义,A6⑦)——
|
|
14
|
+
// pi conversation=native 放行(steer 虽 unsupported 不参与否决);通道族全缺才拦
|
|
15
|
+
// 4. [W3] 方向判定②:manifest 多声明 → assertGateCapabilitiesMatched 抛
|
|
16
|
+
// engine_capability_mismatch(gate 位逐位正反例 + 非 gate 位不判定)
|
|
13
17
|
|
|
14
18
|
import { describe, expect, it } from "vitest";
|
|
15
19
|
|
|
16
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
assertGateCapabilitiesMatched,
|
|
22
|
+
assertTaskShapeSupported,
|
|
23
|
+
type TaskShapeForGate,
|
|
24
|
+
} from "../../common/capability-gate.ts";
|
|
17
25
|
import { EngineError } from "../../common/errors.ts";
|
|
26
|
+
import { readFileSync } from "node:fs";
|
|
27
|
+
import { dirname, join } from "node:path";
|
|
28
|
+
import { fileURLToPath } from "node:url";
|
|
29
|
+
|
|
18
30
|
import type { EngineCapabilities } from "../../types.ts";
|
|
19
|
-
import { PiEngine } from "../../engines/pi/pi-engine.ts";
|
|
20
|
-
import { ZcodeEngine } from "../../engines/zcode/zcode-engine.ts";
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
// W10(§2.10 ②):gate 判据源改读引擎包 manifest(package.json xyz-agent.capabilities
|
|
33
|
+
// ——协议化后同步成员唯一源),不再深路径构造内建引擎实例(W11 删除)。
|
|
34
|
+
function manifestCaps(relPkg: string): EngineCapabilities {
|
|
35
|
+
const pkg = JSON.parse(
|
|
36
|
+
readFileSync(
|
|
37
|
+
join(dirname(fileURLToPath(import.meta.url)), "../../../../../../", relPkg, "package.json"),
|
|
38
|
+
"utf8",
|
|
39
|
+
),
|
|
40
|
+
) as { "xyz-agent": { subagentEngine: { capabilities: EngineCapabilities } } };
|
|
41
|
+
return pkg["xyz-agent"].subagentEngine.capabilities;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const PI_CAPS = manifestCaps("pi-subagent-cli");
|
|
45
|
+
const ZCODE_CAPS = manifestCaps("zcode-subagent-cli");
|
|
25
46
|
|
|
26
47
|
/** 会话分叉通道族可用的 zcode 形态变体(fork 判据用)。 */
|
|
27
48
|
const ZCODE_CAPS_WITH_CONVERSATION: EngineCapabilities = { ...ZCODE_CAPS, conversation: "native" };
|
|
@@ -34,12 +55,24 @@ function gate(
|
|
|
34
55
|
assertTaskShapeSupported(engineId, caps, task);
|
|
35
56
|
}
|
|
36
57
|
|
|
37
|
-
|
|
58
|
+
/** 断言载体(结构化面):EngineError(core)与 EngineSdkError(SDK 构造器)共用
|
|
59
|
+
* code/message/recovery 契约,测试按结构断言不绑类。 */
|
|
60
|
+
interface GateErrorShape {
|
|
61
|
+
code: string;
|
|
62
|
+
message: string;
|
|
63
|
+
recovery: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function gateError(caps: EngineCapabilities, task: TaskShapeForGate, engineId = "zcode"): GateErrorShape {
|
|
38
67
|
try {
|
|
39
68
|
gate(caps, task, engineId);
|
|
40
69
|
} catch (err) {
|
|
41
|
-
|
|
42
|
-
|
|
70
|
+
// [W1 交接防漂移项落地] conversation 分支抛 SDK EngineSdkError
|
|
71
|
+
//(engineConversationUnsupportedError——core 与引擎侧判据单源,W3 接线);其余
|
|
72
|
+
// 分支仍为 core EngineError。code/recovery/message 前缀契约两侧一致。
|
|
73
|
+
expect(err).toHaveProperty("code");
|
|
74
|
+
expect(err).toHaveProperty("recovery");
|
|
75
|
+
return err as unknown as GateErrorShape;
|
|
43
76
|
}
|
|
44
77
|
throw new Error("expected assertTaskShapeSupported to throw");
|
|
45
78
|
}
|
|
@@ -71,8 +104,10 @@ describe("capability-gate(D3-④ 拦截矩阵)", () => {
|
|
|
71
104
|
expect(err.code).toBe("engine_capability_unsupported");
|
|
72
105
|
expect(err.message).toMatch(pattern);
|
|
73
106
|
expect(err.message).toContain("capabilities");
|
|
74
|
-
// 错误信息可操作(§3.4
|
|
75
|
-
|
|
107
|
+
// 错误信息可操作(§3.4 + W3 协议化口径):恢复指引 = 调整参数 / 修 manifest /
|
|
108
|
+
// 升级引擎包(能力声明的载体),不再指向「engine: pi」内置兜底
|
|
109
|
+
expect(err.recovery).toMatch(/去掉|不传/);
|
|
110
|
+
expect(err.recovery).toMatch(/修 manifest|升级引擎包/);
|
|
76
111
|
}
|
|
77
112
|
});
|
|
78
113
|
|
|
@@ -89,3 +124,68 @@ describe("capability-gate(D3-④ 拦截矩阵)", () => {
|
|
|
89
124
|
expect(() => gate({ ...ZCODE_CAPS, steer: "native" }, { fork: true })).not.toThrow();
|
|
90
125
|
});
|
|
91
126
|
});
|
|
127
|
+
|
|
128
|
+
// ============================================================
|
|
129
|
+
// [W3] 方向判定②:manifest 多声明 → engine_capability_mismatch(impl-plan §2.3)
|
|
130
|
+
// ============================================================
|
|
131
|
+
|
|
132
|
+
describe("assertGateCapabilitiesMatched(manifest vs initialize 应答,gate 位方向判定)", () => {
|
|
133
|
+
function mismatchError(
|
|
134
|
+
manifestCaps: EngineCapabilities,
|
|
135
|
+
answeredCaps: EngineCapabilities,
|
|
136
|
+
): EngineError {
|
|
137
|
+
try {
|
|
138
|
+
assertGateCapabilitiesMatched("fake", manifestCaps, answeredCaps);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
expect(err).toBeInstanceOf(EngineError);
|
|
141
|
+
return err as EngineError;
|
|
142
|
+
}
|
|
143
|
+
throw new Error("expected assertGateCapabilitiesMatched to throw");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
it("conversation:manifest 非 unsupported、应答 unsupported → engine_capability_mismatch", () => {
|
|
147
|
+
const err = mismatchError(
|
|
148
|
+
{ ...ZCODE_CAPS, conversation: "native" },
|
|
149
|
+
{ ...ZCODE_CAPS, conversation: "unsupported" },
|
|
150
|
+
);
|
|
151
|
+
expect(err.code).toBe("engine_capability_mismatch");
|
|
152
|
+
expect(err.message).toContain("conversation");
|
|
153
|
+
expect(err.recovery).toMatch(/manifest|升级引擎包/);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("fork 通道族(OR 对偶):manifest 任一可用、应答双 unsupported → mismatch", () => {
|
|
157
|
+
const err = mismatchError(
|
|
158
|
+
{ ...ZCODE_CAPS, steer: "native" },
|
|
159
|
+
{ ...ZCODE_CAPS, steer: "unsupported", conversation: "unsupported" },
|
|
160
|
+
);
|
|
161
|
+
expect(err.code).toBe("engine_capability_mismatch");
|
|
162
|
+
expect(err.message).toContain("fork");
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("maxTurns:manifest true、应答 false → mismatch", () => {
|
|
166
|
+
const err = mismatchError({ ...ZCODE_CAPS, maxTurns: true }, { ...ZCODE_CAPS, maxTurns: false });
|
|
167
|
+
expect(err.code).toBe("engine_capability_mismatch");
|
|
168
|
+
expect(err.message).toContain("maxTurns");
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("sandbox:manifest 非 none、应答 none → mismatch", () => {
|
|
172
|
+
const err = mismatchError({ ...ZCODE_CAPS, sandbox: "emulated" }, { ...ZCODE_CAPS, sandbox: "none" });
|
|
173
|
+
expect(err.code).toBe("engine_capability_mismatch");
|
|
174
|
+
expect(err.message).toContain("sandbox");
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("应答强于 manifest(引擎兑现更多)→ 不抛;同值对齐 → 不抛(无多声明)", () => {
|
|
178
|
+
const weak = { ...ZCODE_CAPS, conversation: "unsupported" as const, maxTurns: false, sandbox: "none" as const };
|
|
179
|
+
const strong = { ...ZCODE_CAPS, conversation: "native" as const, maxTurns: true, sandbox: "emulated" as const };
|
|
180
|
+
// 应答强于 manifest:引擎兑现 manifest 全部声明,无多声明
|
|
181
|
+
expect(() => assertGateCapabilitiesMatched("fake", weak, strong)).not.toThrow();
|
|
182
|
+
// 同值对齐:无差异
|
|
183
|
+
expect(() => assertGateCapabilitiesMatched("fake", strong, strong)).not.toThrow();
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it("非 gate 位不一致 → 不判定不抛(无论强弱一律 warn 留痕,归 EngineClient 诊断面)", () => {
|
|
187
|
+
const manifest = { ...ZCODE_CAPS, personaInjection: "file" as const, eventGranularity: "stream" as const, sessionRead: "full" as const, resume: "native" as const, interrupt: "native" as const, permissionMode: "native" as const, schemaEnforcement: "native" as const };
|
|
188
|
+
const weaker = { ...ZCODE_CAPS, personaInjection: "prompt" as const, eventGranularity: "coarse" as const, sessionRead: "outcome-only" as const, resume: "unsupported" as const, interrupt: "kill-only" as const, permissionMode: "fixed" as const, schemaEnforcement: "emulated" as const };
|
|
189
|
+
expect(() => assertGateCapabilitiesMatched("fake", manifest, weaker)).not.toThrow();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// errors.test.ts —— 引擎层错误 SSOT 的结构锁定。
|
|
2
2
|
//
|
|
3
|
-
// 三视角:①构建者——
|
|
4
|
-
//
|
|
3
|
+
// 三视角:①构建者——12 条 code 与设计错误规格全表一致([W3] 协议化增
|
|
4
|
+
// engine_capability_mismatch——manifest 多声明的 run 期握手阻断面,与 SDK 协议错误码
|
|
5
|
+
// 词表同源);②使用者——错误消息 code 前缀格式可被字符串匹配分流;③观察者——每条
|
|
6
|
+
// 错误必有非空恢复指引(可操作)。
|
|
5
7
|
|
|
6
8
|
import { describe, expect, it } from "vitest";
|
|
7
9
|
|
|
@@ -12,14 +14,12 @@ import {
|
|
|
12
14
|
engineRunFailedDetail,
|
|
13
15
|
engineTimeoutDetail,
|
|
14
16
|
isEngineErrorCode,
|
|
15
|
-
nestedSpawnRejectedError,
|
|
16
17
|
promptTooLargeError,
|
|
17
|
-
schemaEmulationFailedDetail,
|
|
18
18
|
STDOUT_TAIL_ECHO_CHARS,
|
|
19
19
|
} from "../../common/errors.ts";
|
|
20
20
|
|
|
21
21
|
describe("ENGINE_ERROR_CODES(§3.3.3 全表)", () => {
|
|
22
|
-
it("
|
|
22
|
+
it("12 条错误码与设计文档错误规格表逐条一致([W3] 协议化增 engine_capability_mismatch)", () => {
|
|
23
23
|
expect([...ENGINE_ERROR_CODES]).toEqual([
|
|
24
24
|
"engine_not_found",
|
|
25
25
|
"engine_probe_failed",
|
|
@@ -28,6 +28,7 @@ describe("ENGINE_ERROR_CODES(§3.3.3 全表)", () => {
|
|
|
28
28
|
"schema_emulation_failed",
|
|
29
29
|
"engine_timeout",
|
|
30
30
|
"engine_capability_unsupported",
|
|
31
|
+
"engine_capability_mismatch",
|
|
31
32
|
"engine_session_not_resumable",
|
|
32
33
|
"model_not_available",
|
|
33
34
|
"prompt_too_large",
|
|
@@ -90,13 +91,6 @@ describe("具名构造器", () => {
|
|
|
90
91
|
expect(err.recovery).toMatch(/stdin/);
|
|
91
92
|
});
|
|
92
93
|
|
|
93
|
-
it("nestedSpawnRejectedError:说明防护规则 + 指向 task 内自行完成", () => {
|
|
94
|
-
const err = nestedSpawnRejectedError();
|
|
95
|
-
expect(err.code).toBe("nested_spawn_rejected");
|
|
96
|
-
expect(err.message).toContain("XYZ_AGENT_SUBAGENT");
|
|
97
|
-
expect(err.recovery).toMatch(/inside the current task/);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
94
|
it("engineTimeoutDetail:含 stdout 尾部 + engine: pi 重跑建议", () => {
|
|
101
95
|
const detail = engineTimeoutDetail("partial stdout output");
|
|
102
96
|
expect(detail).toContain("partial stdout output");
|
|
@@ -123,10 +117,9 @@ describe("具名构造器", () => {
|
|
|
123
117
|
expect(engineRunFailedDetail("crash", null, "t")).toContain("killed by signal");
|
|
124
118
|
});
|
|
125
119
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
});
|
|
120
|
+
// nestedSpawnRejectedError 用例已随构造器删除(nesting-guard 收编 SDK 后死导出,
|
|
121
|
+
// 活体单源 SDK nesting-guard.ts NestedSpawnRejectedError,其行为由 SDK
|
|
122
|
+
// __tests__/primitives.test.ts + 本目录 nesting-guard.test.ts 覆盖)。
|
|
123
|
+
// schemaEmulationFailedDetail 用例已随函数删除(test-only 死镜像收口,活体单源
|
|
124
|
+
// SDK error-codes.ts,其行为由 SDK __tests__/primitives.test.ts 覆盖)。
|
|
132
125
|
});
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
// kill-chain.test.ts —— 杀链两分支 + 超时终态合成 + abort 两级编排(fake timers)。
|
|
2
2
|
//
|
|
3
|
+
// 实现体已收编 @zhushanwen/subagent-engine-sdk(common/kill-chain.ts 为 re-export
|
|
4
|
+
// shim,s4-reuse 簇 1):SDK 侧 __tests__/kill-chain.test.ts 是超集演进版(+
|
|
5
|
+
// LoggerSink 捕获 + kill 抛错幂等用例),本文件保留 core 侧独有断言——engine: pi
|
|
6
|
+
// 重跑建议文案、stdout 尾部 2000 字截断、signalCode 形态退出、grace 贴边不升级。
|
|
7
|
+
// SDK 版 synthesizeTimeoutOutcome 的 engineId 必填(core 原缺省 "pi" 已删),用例显式传。
|
|
8
|
+
//
|
|
3
9
|
// 三视角:①构建者——SIGTERM 优雅 / 超时 SIGKILL 两分支的信号序列正确;②使用者——
|
|
4
10
|
// abortWithFallback 对 CLI-only 与 native-interrupt 引擎都收敛不悬挂;③观察者——
|
|
5
11
|
// 合成终态的 error 含 stdout 尾部与 exitCode=null(被信号杀死判据)。
|
|
@@ -120,6 +126,7 @@ describe("synthesizeTimeoutOutcome", () => {
|
|
|
120
126
|
const outcome = synthesizeTimeoutOutcome(
|
|
121
127
|
{ prompt: "review files", description: "review-files" },
|
|
122
128
|
"last stdout lines...",
|
|
129
|
+
"pi",
|
|
123
130
|
);
|
|
124
131
|
expect(outcome.error!).toContain("engine_timeout");
|
|
125
132
|
expect(outcome.error).toContain("review-files");
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
// nesting-guard.test.ts —— 嵌套标记注入与原生标记剥离(D8 双层防护)。
|
|
2
2
|
//
|
|
3
|
+
// 实现体已收编 @zhushanwen/subagent-engine-sdk(common/nesting-guard.ts 为
|
|
4
|
+
// re-export shim,s4-reuse 簇 2):SDK 侧 __tests__/primitives.test.ts 已有同语义
|
|
5
|
+
// 断言,本文件保留 core 侧独有细粒度断言——精确名 vs 前缀剥离边界(CLAUDE_UNRELATED)、
|
|
6
|
+
// 非 '1' 值不抛、空白 env 最小产出。错误形态随收编改 NestedSpawnRejectedError
|
|
7
|
+
//(code/recovery 文案与 core 词表逐字一致)。
|
|
8
|
+
//
|
|
3
9
|
// 三视角:①构建者——三引擎原生标记(PI_SUBAGENT_* / CLAUDECODE / ZSW_NESTED)全部
|
|
4
10
|
// 剥离且其余 env 保留;②使用者——子代理进程内 assertNotNestedSpawn 同步拒绝且文案
|
|
5
11
|
// 可操作;③观察者——产出的 env 是新对象(不污染入参)。
|
|
@@ -9,9 +15,9 @@ import { describe, expect, it } from "vitest";
|
|
|
9
15
|
import {
|
|
10
16
|
assertNotNestedSpawn,
|
|
11
17
|
buildNestedSpawnEnv,
|
|
18
|
+
NestedSpawnRejectedError,
|
|
12
19
|
NESTED_SPAWN_ENV,
|
|
13
20
|
} from "../../common/nesting-guard.ts";
|
|
14
|
-
import { EngineError } from "../../common/errors.ts";
|
|
15
21
|
|
|
16
22
|
describe("buildNestedSpawnEnv", () => {
|
|
17
23
|
it("注入统一标记 XYZ_AGENT_SUBAGENT=1", () => {
|
|
@@ -60,12 +66,12 @@ describe("buildNestedSpawnEnv", () => {
|
|
|
60
66
|
|
|
61
67
|
describe("assertNotNestedSpawn", () => {
|
|
62
68
|
it("检测到统一标记(本进程已是 subagent)→ 抛 nested_spawn_rejected", () => {
|
|
63
|
-
expect(() => assertNotNestedSpawn({ [NESTED_SPAWN_ENV]: "1" })).toThrowError(
|
|
69
|
+
expect(() => assertNotNestedSpawn({ [NESTED_SPAWN_ENV]: "1" })).toThrowError(NestedSpawnRejectedError);
|
|
64
70
|
try {
|
|
65
71
|
assertNotNestedSpawn({ [NESTED_SPAWN_ENV]: "1" });
|
|
66
72
|
expect.unreachable("should throw");
|
|
67
73
|
} catch (err) {
|
|
68
|
-
const e = err as
|
|
74
|
+
const e = err as NestedSpawnRejectedError;
|
|
69
75
|
expect(e.code).toBe("nested_spawn_rejected");
|
|
70
76
|
// 文案说明防护规则(标记名)+ 指向 task 内自行完成
|
|
71
77
|
expect(e.message).toContain("XYZ_AGENT_SUBAGENT");
|
|
@@ -34,7 +34,7 @@ beforeEach(() => {
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
afterEach(() => {
|
|
37
|
-
rmSync(dataDir, { recursive: true, force: true });
|
|
37
|
+
rmSync(dataDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
38
38
|
// reader registry 是进程级状态——重置回内置集,防 fake 注入跨用例泄漏
|
|
39
39
|
resetNativeSessionReaders();
|
|
40
40
|
});
|
|
@@ -163,7 +163,13 @@ describe("降级链编排", () => {
|
|
|
163
163
|
});
|
|
164
164
|
});
|
|
165
165
|
|
|
166
|
-
it("①级
|
|
166
|
+
it("[W11/H1] ①级 reader 不可达(协议 read 失败降级形态)→ ②级 journal 命中", async () => {
|
|
167
|
+
// W11 后①级 reader 全经注入(生产 = runtime 协议 read,失败在其内部 catch 后
|
|
168
|
+
// 返回 undefined):注入一个恒 undefined 的 reader 复现「协议失败降②级」语义
|
|
169
|
+
// (原「真 zcode reader 对不存在 db 内部 catch 降级」分支随 H1 内建 reader
|
|
170
|
+
// 删除,sqlite 侧行为由 zcode 包 e2e 接替;NativeSessionReader 契约 = 不抛,
|
|
171
|
+
// 失败以 undefined 表达)。
|
|
172
|
+
registerNativeSessionReader("zcode", async () => undefined);
|
|
167
173
|
const journalPath = join(dataDir, "engines", "zcode", "shared", "journal-sub-1.jsonl");
|
|
168
174
|
await writeJournal(journalPath, [
|
|
169
175
|
{ type: "text_delta", delta: "part one. " },
|
|
@@ -190,7 +196,7 @@ describe("降级链编排", () => {
|
|
|
190
196
|
});
|
|
191
197
|
|
|
192
198
|
it("②级也不可达(无 journalPath)→ ③级 outcome-only,永不返回空数组", async () => {
|
|
193
|
-
//
|
|
199
|
+
// ①级无注册 reader(W11 后注册表初始为空)→ 直落②级;handle 无 journalPath → ③级
|
|
194
200
|
const messages = await readSubagentHistoryMessages(
|
|
195
201
|
makeRecord({ result: "final answer", endedAt: 2_000 }),
|
|
196
202
|
dataDir,
|
|
@@ -228,6 +234,87 @@ describe("降级链编排", () => {
|
|
|
228
234
|
expect(messages).toHaveLength(2);
|
|
229
235
|
expect(messages[1]).toMatchObject({ content: "r" });
|
|
230
236
|
});
|
|
237
|
+
|
|
238
|
+
// ============================================================
|
|
239
|
+
// ①级判空降级矩阵(设计 D3:turns 无实质内容 = 本级不可用,与②级同语义)
|
|
240
|
+
// ============================================================
|
|
241
|
+
|
|
242
|
+
it("①级 defined 空 turns({turns:[], source:'native'})→ 降②级,journal 内容命中(不返回 [task] 空壳)", async () => {
|
|
243
|
+
const journalPath = join(dataDir, "engines", "zcode", "shared", "journal-sub-1.jsonl");
|
|
244
|
+
await writeJournal(journalPath, [
|
|
245
|
+
{ type: "text_delta", delta: "journal answer" },
|
|
246
|
+
{ type: "turn_end" },
|
|
247
|
+
]);
|
|
248
|
+
registerNativeSessionReader("zcode", async () => ({
|
|
249
|
+
engineId: "zcode",
|
|
250
|
+
sessionId: "sess-1",
|
|
251
|
+
turns: [],
|
|
252
|
+
source: "native",
|
|
253
|
+
}));
|
|
254
|
+
const record = makeRecord({
|
|
255
|
+
engineHandle: {
|
|
256
|
+
sessionRef: { sessionId: "sess-1", dbPath: ".zcode/cli/db/db.sqlite" },
|
|
257
|
+
poolKey: "shared",
|
|
258
|
+
journalPath,
|
|
259
|
+
},
|
|
260
|
+
});
|
|
261
|
+
const messages = await readSubagentHistoryMessages(record, dataDir);
|
|
262
|
+
expect(messages).toHaveLength(2);
|
|
263
|
+
expect(messages[0]).toMatchObject({ role: "user", content: "do the thing" });
|
|
264
|
+
expect(messages[1]).toMatchObject({ role: "assistant", content: "journal answer" });
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it("①级非空数组但全空 turn(截断/被杀残留形态)→ 同样降级:无 journalPath 落③级 outcome-only", async () => {
|
|
268
|
+
registerNativeSessionReader("zcode", async () => ({
|
|
269
|
+
engineId: "zcode",
|
|
270
|
+
sessionId: "sess-1",
|
|
271
|
+
// closeTurn 对 step-finish 无条件 push + applyPartToTurn 空 acc 创建——形态代码级可达
|
|
272
|
+
turns: [{ text: "", thinking: "", toolCalls: [], closed: true }],
|
|
273
|
+
source: "native",
|
|
274
|
+
}));
|
|
275
|
+
const messages = await readSubagentHistoryMessages(
|
|
276
|
+
makeRecord({ result: "outcome text" }),
|
|
277
|
+
dataDir,
|
|
278
|
+
);
|
|
279
|
+
// 不是「仅 task」空壳:①级空 turn 被判不可用 → ③级占位投影
|
|
280
|
+
expect(messages).toHaveLength(2);
|
|
281
|
+
expect(messages[1]).toMatchObject({ role: "assistant", content: "outcome text" });
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it("①级混合 turn(含空 turn 但任一有实质内容)→ 不降级,真实内容原样投影", async () => {
|
|
285
|
+
registerNativeSessionReader("zcode", async () => ({
|
|
286
|
+
engineId: "zcode",
|
|
287
|
+
sessionId: "sess-1",
|
|
288
|
+
turns: [
|
|
289
|
+
{ text: "", thinking: "", toolCalls: [], closed: true },
|
|
290
|
+
{ text: "real answer", thinking: "", toolCalls: [], closed: true },
|
|
291
|
+
],
|
|
292
|
+
source: "native",
|
|
293
|
+
}));
|
|
294
|
+
const messages = await readSubagentHistoryMessages(makeRecord(), dataDir);
|
|
295
|
+
// task + 两个 turn(空 turn 也随①级放行原样投影)
|
|
296
|
+
expect(messages).toHaveLength(3);
|
|
297
|
+
expect(messages[2]).toMatchObject({ role: "assistant", content: "real answer" });
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it("①空(defined 空 turns)②亦不可达(无 journalPath)→ 落③级 outcome-only 占位", async () => {
|
|
301
|
+
registerNativeSessionReader("zcode", async () => ({
|
|
302
|
+
engineId: "zcode",
|
|
303
|
+
sessionId: "sess-1",
|
|
304
|
+
turns: [],
|
|
305
|
+
source: "native",
|
|
306
|
+
}));
|
|
307
|
+
const messages = await readSubagentHistoryMessages(
|
|
308
|
+
makeRecord({ result: undefined, error: undefined }),
|
|
309
|
+
dataDir,
|
|
310
|
+
);
|
|
311
|
+
expect(messages).toHaveLength(2);
|
|
312
|
+
expect(messages[1]).toMatchObject({
|
|
313
|
+
role: "assistant",
|
|
314
|
+
content: "(no outcome recorded)",
|
|
315
|
+
status: "complete",
|
|
316
|
+
});
|
|
317
|
+
});
|
|
231
318
|
});
|
|
232
319
|
|
|
233
320
|
// ============================================================
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# W10 H9 测试面处置表(core 深路径测试三选一)
|
|
2
|
+
|
|
3
|
+
> 实施计划 §2.10「core 测试逐文件三选一处置清单」的执行记录(W10,2026-09-09)。
|
|
4
|
+
> 处置依据 = 文件 import 实测 + W5/W7 已迁件核对。处置后 core test 全绿
|
|
5
|
+
> (2999 passed | 7 skipped;删除 48 文件 / 改写 5 文件 / 保留待 W11 同批改写 4 文件——保留的 4 文件已随 W3 收口(1 删 3 改写),见 §② 节尾回写注记)。
|
|
6
|
+
|
|
7
|
+
## ① 已随引擎包迁移 —— 删除 core 重复副本(11 文件)
|
|
8
|
+
|
|
9
|
+
W5/W7 已把自包含件迁入引擎包(pi-subagent-cli / zcode-subagent-cli `__tests__/`,
|
|
10
|
+
两包 test 全绿),core 侧同名副本属重复实现测试,删除:
|
|
11
|
+
|
|
12
|
+
| core 副本(已删) | 引擎包权威副本 |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `src/__tests__/fr4-get-state-handshake.test.ts` | pi-subagent-cli `__tests__/get-state-handshake.test.ts` |
|
|
15
|
+
| `execution/__tests__/get-state-handshake.test.ts` | 同上 |
|
|
16
|
+
| `execution/__tests__/output-collector.test.ts` | pi `__tests__/output-collector.test.ts` |
|
|
17
|
+
| `execution/__tests__/pi-invocation.test.ts` | pi `__tests__/pi-invocation.test.ts` |
|
|
18
|
+
| `execution/__tests__/temp-prompt.test.ts` | pi `__tests__/temp-prompt.test.ts` |
|
|
19
|
+
| `execution/__tests__/stdin-writer.test.ts` | pi `__tests__/stdin-writer.test.ts` |
|
|
20
|
+
| `execution/__tests__/spawn-event-adapter.test.ts` | pi `__tests__/spawn-event-adapter.test.ts` |
|
|
21
|
+
| `execution/__tests__/spawn-event-adapter-rpc.test.ts` | pi `__tests__/spawn-event-adapter-rpc.test.ts` |
|
|
22
|
+
| `execution/__tests__/turn-limiter.test.ts` | pi `__tests__/turn-limiter.test.ts` |
|
|
23
|
+
| `execution/__tests__/turn-limiter-semantics.test.ts` | pi `__tests__/turn-limiter-semantics.test.ts` |
|
|
24
|
+
| `execution/__tests__/spawn-args.test.ts` | pi `__tests__/spawn-args.test.ts`(core 副本的 `MAX_FORK_DEPTH` 断言面由 `recursive-visibility-baseline`/`nested-visibility` 族承接) |
|
|
25
|
+
|
|
26
|
+
## ① 随 SDK 原语迁移(1 文件)
|
|
27
|
+
|
|
28
|
+
| core(已删) | 迁移落点 |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `execution/engine/__tests__/paths.test.ts` | `subagent-engine-sdk/src/__tests__/paths.test.ts`(import 改 SDK 包内相对路径,5 用例全绿) |
|
|
31
|
+
|
|
32
|
+
## ② 改写为镜像/协议等价断言 —— 已完成(5 文件)
|
|
33
|
+
|
|
34
|
+
| 文件 | 改写内容 |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `src/orchestration/__tests__/execute-agent-call.test.ts` | output-collector 深路径 import → `@zhushanwen/pi-subagent-cli` 公共导出面(25 用例绿) |
|
|
37
|
+
| `execution/__tests__/subprocess-agent-runner-routing.test.ts` | `getChildByRecord` 深路径 → core 侧镜像 `host/spawned-children.ts coreSpawnedChildrenMirror().getChildByRecord`(pid 同构判据);「退出后按句移除」断言移至 protocol-blackbox childStateChanged 用例(inproc 双模不回灌该通道,文件内已注记) |
|
|
38
|
+
| `execution/__tests__/chat-engine-routing.test.ts` | 同上(镜像面改写) |
|
|
39
|
+
| `execution/engine/__tests__/common/capability-gate.test.ts` | PiEngine/ZcodeEngine 内建构造 → 读两引擎包 package.json manifest `xyz-agent.subagentEngine.capabilities`(同步成员唯一源;11 用例绿) |
|
|
40
|
+
| `execution/engine/__tests__/conformance/contract.{probe,abort,read-degradation,agent-events}.test.ts` + `golden-replay.{pi,zcode}.test.ts` + `engine-conformance.live.test.ts` | conformance 契约套件整体协议黑盒化:RemoteEngine × fake 引擎 CLI / golden 语料改引擎包 `__golden__/` + 公共导出面 / live 门改「协议客户端 × 引擎包 CLI」形态(A2 真机形态本身) |
|
|
41
|
+
|
|
42
|
+
## ② 改写被阻塞 —— 保留 + W10 处置注记,W11 同批改写(4 文件)[v1.x W3 已收口,见节尾回写注记]
|
|
43
|
+
|
|
44
|
+
`src/__tests__/append-system-prompt-assembly.test.ts`、`execution/__tests__/explicit-agent-ref-guard.test.ts`、`execution/__tests__/delivery-methods.test.ts`、`execution/__tests__/gc-timer.test.ts`。
|
|
45
|
+
|
|
46
|
+
阻塞原因(同根):这些文件 `vi.mock("…engines/pi/session-runner.ts")` 拦截的**是 core 生产代码的 inproc 深路径 import**(subagent-service / lifecycle 谓词等消费点在生产侧)——mock 目标改指引擎包或镜像需生产 import 先改线,而 W6 已把改线收敛到 W11 收口(`subagent-service.ts` W7 注 + `lifecycle-predicates.test.ts` 仍深 import spawnedChildren 同证)。W11 删内建当轮必须同批改写这 4 个文件(每文件头部已留 `[W10 处置注记]`)。
|
|
47
|
+
|
|
48
|
+
> **[v1.x W3 已收口 —— 回写注记(2026-09-09)]** 上方 4 文件已随 commit `0df9ef8b3`(W3 删 inproc pi 引擎 + chat 协议化改线)处理完毕:`append-system-prompt-assembly.test.ts` 删除,其余 3 文件改写为协议等价断言(`explicit-agent-ref-guard.test.ts` / `delivery-methods.test.ts` / `gc-timer.test.ts`,现头注 `[W3 改写]` 可核)。原 `[W10 处置注记]` 已被 `[W3 改写]` 头注取代,W11 对这 4 文件无剩余改写面。本节标题、阻塞原因与文首统计行保留作 W10 时点历史([HISTORICAL] 纪律),现行状态以本注记为准。
|
|
49
|
+
|
|
50
|
+
## ③ 声明废弃 —— 删除(34 文件 + 1 helper)
|
|
51
|
+
|
|
52
|
+
统一理由(按文件另有侧重):**被测行为 = 内建 pi/zcode inproc 编排实现**,协议化终态下该实现归引擎进程(W11 删除 core `engines/pi|zcode`);行为面承接:
|
|
53
|
+
|
|
54
|
+
- **引擎内部行为**(spawn 参数/dispatch/LRU/心跳/EPIPE/收敛)→ `@zhushanwen/pi-subagent-cli` / `zcode-subagent-cli` 包内测试(W5/W7 迁移件,两包全绿);
|
|
55
|
+
- **协议契约面**(run/cancel/read/反向通道/错误帧/结构等价)→ W10 新协议黑盒套件 `conformance/protocol-blackbox.test.ts` + `client/__tests__/*`(W2);
|
|
56
|
+
- **收割/杀链语义**(R9-1 口径:一代子进程 + 组内后代)→ SDK kill-chain 单测 + A3 真机门;
|
|
57
|
+
- **inproc 双模过渡态**(XYZ_SUBAGENT_ENGINE_MODE)本身 = DoD#5 删除对象,不保留锚定测试。
|
|
58
|
+
|
|
59
|
+
| 已删文件 | 侧重理由 |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `src/__tests__/session-runner.test.ts` | 引擎内部(pi spawn-runner) |
|
|
62
|
+
| ask-user-transit-e2e / ui-request-handler | ui 请求链引擎内部面(pi 包 ui-channels/ui-request-queue 测试 + W10 反向通道用例) |
|
|
63
|
+
| chatmode-first-round-closure-spawn / run-and-finalize-chatmode / run-spawn-chatmode-settled | chat 轮次收敛编排(pi 包 spawn-runner;chat 域 HostBridge 编排 W7 已登记 stage-3 gap) |
|
|
64
|
+
| descendant-sweep / descendant-sweep-guards / kill-all-escalation / service-kill-escalation / spawned-children | 收割/杀链(SDK kill-chain + A3 真机门;镜像面 = protocol-blackbox) |
|
|
65
|
+
| epipe-fallback / session-runner-epipe | EPIPE 兜底(pi 包 stdin-writer/spawn-runner 测试) |
|
|
66
|
+
| keep-alive-no-progress / settled-watchdog / timeout-integration | 进度/超时判据(ADR-0047 域)。**处置改写(2026-09-09,Gate B 后纠正)**:原「pi 包 + A8 真机门」承接声称不成立——pi 包内无等价测试(grep keep-alive/no-progress/settled-watchdog/timeout-integration 零命中),Gate B 时点 A8 真机门为 blocked/manual、不构成承接证据;该三测试的行为面**随 keep-alive 协议化偏差登记**(impl-plan §5 2026-09-09 行:workflow 域单次 run 口径 agent_end 即终结,后台后代保活编排未随迁移),**不声称已承接** |
|
|
67
|
+
| recursive-visibility-env / start-sync-model-guard / session-runner-schema-env | 引擎内 env 注入面(pi 包 spawn-args/relay-env 测试;W12 env 契约单测) |
|
|
68
|
+
| rpc-mode / run-spawn-rpc-mode / run-spawn-integration / run-spawn-resume / run-spawn-edges / run-and-finalize-anchoring / run-spawn-stdout-callback-throw / spawn-worktree-guidance | run 全链编排(pi 包 spawn-runner/protocol-e2e;协议面 = W10 黑盒套件) |
|
|
69
|
+
| session-runner-branch-cache-lru / session-runner-close-prune / session-runner-dispatch / session-runner-heartbeat-idle-fallback / session-runner-lifecycle-helpers | session-runner 内部机制(pi 包) |
|
|
70
|
+
| max-turns-to-watchdog-ms | turn limiter 换算(pi 包 turn-limiter 测试) |
|
|
71
|
+
| subagent-service-message-close | message-close 编排(chat 域 stage-3 gap 承接) |
|
|
72
|
+
| worktree-pid-registration.integration | pid 注册集成(镜像面承接;worktree 面归 W12 回归) |
|
|
73
|
+
| execution-runtime-face / engine-model-validation / session-view-service-zcode-dbpath | zcode 引擎内部(zcode 包 zcode-engine-* / reader / zcode-session-db-isolation 测试) |
|
|
74
|
+
| `helpers/session-runner-mocks.ts` | 消费者全部随上表删除(spawn-mock.ts 保留——3 个存活壳侧行为测试仍消费) |
|
|
75
|
+
|
|
76
|
+
## 未入清单的既有深路径引用(W11 处置面,W10 显式登记)[v1.x W3 已收口,见节尾回写注记]
|
|
77
|
+
|
|
78
|
+
以下文件经 `vi.mock` 字符串路径引用 `engines/pi|zcode`(非值 import,grep 字符串命中),
|
|
79
|
+
不在 §2.10 三选一清单内、本次未动,W11 删内建时同批核处:
|
|
80
|
+
`recursive-visibility-baseline` / `nested-visibility-env-propagation` / `execute-nesting` / `execute-and-await-worktree` / `collect-coordinator-service` / `collect-mixed-dispatch` / `get-record-for-action-restart` / `stream-sink-retirement` / `subagent-agent-runner.test` / `subagent-service-{multiproc-guard,notify-gate,parent-guard,recovery-bounds}` / `sync-collect-recovery` / `helpers/{spawn-mock,subagent-service-mocks}` / `lifecycle-predicates.test`(归 W6/W11)。
|
|
81
|
+
|
|
82
|
+
> **[v1.x W3 已收口 —— 回写注记(2026-09-09)]** 上节登记的 17 项(14 测试 + 2 helper + `lifecycle-predicates.test`)已全部随 commit `0df9ef8b3`(W3 删 inproc pi 引擎 + chat 协议化改线)处理完毕:节内所列文件在该 commit 全部为改写(M),无一保留原深路径 mock;其中 `subagent-agent-runner.test` 系 `subprocess-agent-runner.test.ts` 的简写登记,同在该 commit 改写。`vi.mock(…engines/pi|zcode)` 深路径命中现全 core 树清零(grep 实测:残留仅注释/用例描述文本,无模块路径引用);`[W3]`/`[W3 改写]` 标记 17 项中 14 项可核(标记散布文件头部注记与用例旁注,非全在文件头),余 3 项(`execute-and-await-worktree` / `subagent-service-multiproc-guard` / `subagent-service-parent-guard`)无标记但同 commit 已删深路径 mock(diff 可核)。W11(commit `6d5f6747d`)对该面无剩余核处义务。原节登记保留作 W10 时点历史([HISTORICAL] 纪律),现行状态以本注记为准。
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
## 主会话修正(2026-09-09,W10 修复轮)
|
|
86
|
+
|
|
87
|
+
- `engine/__tests__/common/session-view-service-zcode-dbpath.test.ts` 原列 §2.10 清单①(随 zcode 包迁移/W5),但 W5 未迁(它测的是 core 壳侧 session-view-service 白名单分支,非引擎内部行为)、W10 批次误删——已按原样恢复(8 用例绿)。该文件深路径 import(engines/zcode/{reader,constants,db-path})在 **W11 H1 改写当轮**随 session-view-service 协议化同批改写为协议等价断言(或由 zcode 包 e2e 接替后删除);在此之前保留为 A plan(zcode-session-db-isolation)生产链验收证据。
|
|
88
|
+
- ①类清单中「测 core 壳侧模块」的文件(本件与 execution-runtime-face / engine-model-validation)处置归属应为「W11 H1/H2 同批」而非「随引擎包迁移」——后续处置以本节为准。
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
## W6 承接回写(2026-09-09,chat-domain v1.x 轮次活性治理)
|
|
92
|
+
|
|
93
|
+
> 设计权威源:`docs/design/chat-domain-v1x-liveness-governance.md` §3.2 D2/D5 + §5 W6 行。
|
|
94
|
+
> 本节回写 §③ 行「keep-alive-no-progress / settled-watchdog / timeout-integration」的
|
|
95
|
+
> 处置改写注记(该行「不声称已承接」状态自本节起 supersede)——三测试行为面已随
|
|
96
|
+
> W4/W6 落地,承接落点如下。原注记保留作历史,不删([HISTORICAL] 纪律)。
|
|
97
|
+
|
|
98
|
+
| 原测试 | 承接落点 | 状态 |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| keep-alive-no-progress | **W4 轮次活性监督器**(keep-alive 编排归属裁决 A:core 编排层持有「轮次活性权威」,`execution/round-supervisor/`——no-progress 判定域按设计 D2 域分类收窄:run 域 resumable 无驱动任务归监督器三态;chat 域 idle 稳态豁免归 settled-watchdog/idle 机制)+ conformance 协议黑盒场景链 `conformance/round-liveness-supervisor.test.ts`(SIGTERM crash → 纳管 → 该唤醒 → 该放弃全链 / boot 分区 / 通知对账 / 重建不解管)+ W4 判定矩阵单测 `execution/__tests__/round-supervisor.test.ts` | 已承接(W6 回写) |
|
|
101
|
+
| settled-watchdog | **含生产接线归属**:两段守护行为面 = 既有 core 原语套件(`execution/__tests__/subagent-service-recovery-bounds.test.ts`:armSettledWatchdog / mid-round no-progress / settled 硬顶 / 双 disarm 回收面)。**生产接线归属(D5「删件不同批重接 = 失守」约束)**:W4 已立协议事件 API 三入口——`execution/settled-watchdog.ts` 的 `refreshFromProtocolEvent`(协议事件行到达刷新中段)/ `noteRoundSettledFromProtocol`(settled 相位中段让位收尾段)/ `disarmRoundFromProtocol`(idle 相位/close/终态两段一并清),零新语义薄委托、与存量原语幂等并存;**W3 删 `engines/pi/session-runner.ts` 时必须同批把存量 arm/refresh/kill 接线(arm 点 = 轮开始;refresh 源 = host/streamDelta + host/roundLifecycle;kill/终态 = 既有杀链)换到这三个入口**——接线未重接完成前 W3 不得删件 | 已承接(协议事件面已立 + W3 重接认领) |
|
|
102
|
+
| timeout-integration | live conformance 门(`conformance/engine-conformance.live.test.ts`,`ENGINE_CONFORMANCE_LIVE=1 PI_LIVE_MODEL=<模型>`;设计验收 A7)——超时/abort/收敛行为在真机引擎 + 真实进程生命周期下验证;单测不再锚定 inproc 实现(原 timeout-integration 的「abort 超时强杀集成」语义由 W7 runtime 三级阶梯测试 + 本 live 门共同承载) | 已承接(live 门) |
|
|
103
|
+
|
|
104
|
+
**W6 同批新增语义钉住**(conformance 领地,均绿于 `pnpm --filter @zhushanwen/subagent-core test`):
|
|
105
|
+
|
|
106
|
+
- 引擎中途 SIGTERM → run 终态 failed(**D5 前置闸:本用例先于 W3 删 `engines/pi/session-runner.ts` 旧 143 误分类器存在并保持绿**,P2 探针的 conformance 承载)→ `conformance/engine-crash.test.ts`;
|
|
107
|
+
- chat 轮次协议 v1.x(host/roundLifecycle 三相位 × runId|recordId 关联键回执链 + recordId 键 delta 分路 + conversation gate 负向 A6)→ `conformance/chat-round-protocol.test.ts`;
|
|
108
|
+
- 翻档事实(三类型全 process 档、跨时长无 TTL 清理)+ fork 读侧过滤①③两口径 + **bash 跨 session 可见性显式断言**(R4 一刀钉成显式选择)+ 偏差 #4 探针(goal 守卫口径实测)→ `conformance/registry-fork-filter.test.ts`。
|
|
109
|
+
|
|
110
|
+
**goal 熔断(W5)处置**:**由 extension 侧单测承载,不重复造**——`extensions/universal/goal` 393 例已覆盖双维度熔断(circuit-breaker 6 + liveness 17:50 次封顶必停发、第 5 轮起间隔 ×2、恢复清零退避不重置总数、defer 通知去重);设计验收 A10(实机熔断场景)仍归 Gate B 真机剧本,不在 conformance 重复。
|
|
111
|
+
|
|
112
|
+
## 一致性审查批 2 修复回写(2026-09-09,F-2 首轮 arm 重接)
|
|
113
|
+
|
|
114
|
+
上方 W6 承接回写节「settled-watchdog」行声称的「W3 重接」**当时失实**(一致性审查批 2 F-2 证实):W3 实际只重接了热路径续聊轮(`deliverChatMessage` 的 arm 调用点),`kickOffChatRound`(spawn 首轮 + 冷续 resume 轮)内无任何 arm 调用——:1382 注释声称「首轮调用点在 kickOffChatRound 的 run 派发后」不存在,被删的 inproc stdout-pump 是首轮唯一中段守护,协议化后引擎侧 spawn-runner 仅 turn 计数无墙钟 → **首轮 wedged 无熔断**(LC-1 场景①重新敞开)。H9 行「已承接」按当时状态属过度声称。
|
|
115
|
+
|
|
116
|
+
**修复后真实状态**(本行 supersede 上方 W6 行的承接声明):`kickOffChatRound` 在 run 派发前(pool acquire 成功后)补 `armMidRoundNoProgress`,与热路径 arm 复用同一守护实例语义(同一 `onHotPathSettledWatchdogTimeout` 处置闭包);refresh 源核实齐备——首轮 runId 键 `ctx.onEvent` 协议事件行(含 text_delta,引擎侧 spawn-runner 对 text_delta 同时走 onEvent/onDelta 两通道)+ `ctx.onRoundLifecycle` settled 相位交棒(`noteRoundSettledFromProtocol`,首轮 runId 键经同一 handleChatRoundPhase 收敛,本批测试核实生效)。承接测试:`execution/__tests__/chat-round-first-round-watchdog.test.ts`(首轮 arm / 冷续轮静默 30min 熔断 / 中段事件行刷新 / settled 交棒不继承中段计时)。
|