@zhushanwen/subagent-core 0.4.0 → 0.6.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/dist/{chunk-4KN4TTG7.js → chunk-43ONBFZX.js} +1 -1
- package/dist/{chunk-X7SZ5HLQ.js → chunk-V3VHZ2VX.js} +20 -27
- package/dist/execution/engine/engines/zcode/constants.cjs +29 -41
- package/dist/execution/engine/engines/zcode/constants.d.cts +65 -53
- package/dist/execution/engine/engines/zcode/constants.d.ts +65 -53
- package/dist/execution/engine/engines/zcode/constants.js +17 -27
- package/dist/execution/engine/engines/zcode/reader.d.cts +2 -1
- package/dist/execution/engine/engines/zcode/reader.d.ts +2 -1
- package/dist/execution/engine/engines/zcode/reader.js +2 -2
- package/dist/index.cjs +17100 -14082
- package/dist/index.d.cts +5336 -4033
- package/dist/index.d.ts +5336 -4033
- package/dist/index.js +17020 -14055
- package/dist/{types-DpUO16pj.d.cts → types-C3fE3R9x.d.cts} +280 -112
- package/dist/{types-DpUO16pj.d.ts → types-C3fE3R9x.d.ts} +280 -112
- package/dist.bundle/index.cjs +34933 -0
- package/package.json +3 -3
- package/src/__tests__/agent-opts-resolver-schema-prompt.test.ts +0 -1
- package/src/__tests__/append-system-prompt-assembly.test.ts +8 -7
- package/src/__tests__/fr4-get-state-handshake.test.ts +2 -2
- package/src/__tests__/m2-append-content-probe.test.ts +0 -1
- package/src/__tests__/manifest-store.test.ts +10 -9
- package/src/__tests__/record-store-cache.test.ts +0 -2
- package/src/__tests__/record-store-index.test.ts +1 -2
- package/src/__tests__/review-fix-loop-script.test.ts +4 -2
- package/src/__tests__/review-fix-loop-utils.test.ts +10 -10
- package/src/__tests__/robustness-low-batch1.test.ts +6 -5
- package/src/__tests__/robustness-medium-batch1.test.ts +2 -2
- package/src/__tests__/robustness-medium-batch2.test.ts +17 -6
- package/src/__tests__/robustness-medium-batch4.test.ts +2 -2
- package/src/__tests__/session-runner.test.ts +1 -1
- package/src/core/__tests__/host-services.test.ts +2 -2
- package/src/core/__tests__/logger.test.ts +1 -1
- package/src/core/error-message.ts +9 -0
- package/src/core/host-services.ts +21 -5
- package/src/core/notify-ports.ts +18 -5
- package/src/execution/__tests__/agent-profile.test.ts +4 -4
- package/src/execution/__tests__/agent-registry.test.ts +370 -0
- package/src/execution/__tests__/agent-result-mapper.test.ts +18 -2
- package/src/execution/__tests__/agents-assembly.test.ts +2 -2
- package/src/execution/__tests__/alive-store.test.ts +1 -1
- package/src/execution/__tests__/ask-user-transit-e2e.test.ts +6 -6
- package/src/execution/__tests__/chat-engine-routing.test.ts +68 -33
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +4 -4
- package/src/execution/__tests__/cold-resurrect.test.ts +283 -0
- package/src/execution/__tests__/collect-budget.test.ts +291 -0
- package/src/execution/__tests__/collect-coordinator-service.test.ts +327 -0
- package/src/execution/__tests__/collect-coordinator.test.ts +371 -0
- package/src/execution/__tests__/collect-mixed-dispatch.test.ts +262 -0
- package/src/execution/__tests__/config-collect-sync.test.ts +120 -0
- package/src/execution/__tests__/config.test.ts +1 -1
- package/src/execution/__tests__/delivery-methods.test.ts +75 -62
- package/src/execution/__tests__/descendant-sweep-guards.test.ts +220 -0
- package/src/execution/__tests__/descendant-sweep.test.ts +6 -6
- package/src/execution/__tests__/dialog-queue.test.ts +2 -2
- package/src/execution/__tests__/engine-model-validation.test.ts +741 -0
- package/src/execution/__tests__/epipe-fallback.test.ts +29 -24
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +21 -91
- package/src/execution/__tests__/execute-nesting.test.ts +34 -188
- package/src/execution/__tests__/execution-record.test.ts +217 -60
- package/src/execution/__tests__/execution-runtime-face.test.ts +5 -5
- package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +4 -4
- package/src/execution/__tests__/finalize-record.test.ts +173 -17
- package/src/execution/__tests__/finalized-marker.test.ts +1 -1
- package/src/execution/__tests__/gc-timer.test.ts +56 -3
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +12 -12
- package/src/execution/__tests__/get-state-handshake.test.ts +1 -1
- package/src/execution/__tests__/helpers/mock-extension-api.ts +1 -1
- package/src/execution/__tests__/helpers/session-runner-mocks.ts +113 -0
- package/src/execution/__tests__/helpers/spawn-mock.ts +150 -3
- package/src/execution/__tests__/helpers/subagent-service-mocks.ts +137 -0
- package/src/execution/__tests__/keep-alive-no-progress.test.ts +50 -148
- package/src/execution/__tests__/kill-all-escalation.test.ts +2 -2
- package/src/execution/__tests__/lifecycle-predicates.test.ts +1 -2
- package/src/execution/__tests__/manifest-parentid.test.ts +4 -4
- package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +1 -1
- package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +1 -1
- package/src/execution/__tests__/model-resolver.test.ts +2 -2
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +23 -121
- package/src/execution/__tests__/nested-visibility.test.ts +2 -0
- package/src/execution/__tests__/notify-batch.test.ts +500 -0
- package/src/execution/__tests__/notify-ledger.test.ts +1000 -18
- package/src/execution/__tests__/output-collector.test.ts +117 -6
- package/src/execution/__tests__/pi-invocation.test.ts +36 -4
- package/src/execution/__tests__/record-entry-collect.test.ts +102 -0
- package/src/execution/__tests__/record-store.test.ts +10 -9
- package/src/execution/__tests__/records-cwd-isolation.test.ts +2 -2
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +29 -132
- package/src/execution/__tests__/recursive-visibility-env.test.ts +55 -179
- package/src/execution/__tests__/relay-env.test.ts +12 -1
- package/src/execution/__tests__/rpc-mode.test.ts +2 -2
- package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +387 -0
- package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +15 -9
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +4 -4
- package/src/execution/__tests__/run-spawn-edges.test.ts +17 -15
- package/src/execution/__tests__/run-spawn-integration.test.ts +2 -2
- package/src/execution/__tests__/run-spawn-resume.test.ts +2 -2
- package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +2 -2
- package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +4 -4
- package/src/execution/__tests__/service-kill-escalation.test.ts +7 -5
- package/src/execution/__tests__/session-context-resolver.test.ts +0 -2
- package/src/execution/__tests__/session-file-gc.test.ts +36 -1
- package/src/execution/__tests__/session-pending.test.ts +257 -14
- package/src/execution/__tests__/session-reconstructor.test.ts +366 -15
- package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +1 -1
- package/src/execution/__tests__/session-runner-close-prune.test.ts +2 -2
- package/src/execution/__tests__/session-runner-dispatch.test.ts +489 -0
- package/src/execution/__tests__/session-runner-epipe.test.ts +3 -3
- package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +5 -4
- package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +290 -0
- package/src/execution/__tests__/session-runner-schema-env.test.ts +7 -5
- package/src/execution/__tests__/settled-watchdog.test.ts +282 -47
- package/src/execution/__tests__/spawn-args.test.ts +11 -10
- package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +26 -23
- package/src/execution/__tests__/spawn-event-adapter.test.ts +3 -3
- package/src/execution/__tests__/spawn-worktree-guidance.test.ts +5 -4
- package/src/execution/__tests__/spawned-children.test.ts +2 -1
- package/src/execution/__tests__/start-collect-guard.test.ts +255 -0
- package/src/execution/__tests__/start-sync-model-guard.test.ts +5 -5
- package/src/execution/__tests__/stdin-writer.test.ts +6 -4
- package/src/execution/__tests__/stream-sink-retirement.test.ts +6 -6
- package/src/execution/__tests__/subagent-actions-core.test.ts +48 -22
- package/src/execution/__tests__/subagent-service-message-close.test.ts +29 -26
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +21 -8
- package/src/execution/__tests__/subagent-service-notify-gate.test.ts +27 -22
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +30 -29
- package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +45 -20
- package/src/execution/__tests__/subagent-service.test.ts +37 -30
- package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +88 -12
- package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +75 -0
- package/src/execution/__tests__/subprocess-agent-runner.test.ts +22 -20
- package/src/execution/__tests__/sync-collect-recovery.test.ts +1117 -0
- package/src/execution/__tests__/temp-prompt.test.ts +1 -1
- package/src/execution/__tests__/timeout-integration.test.ts +6 -5
- package/src/execution/__tests__/tombstone-store.test.ts +1 -1
- package/src/execution/__tests__/turn-limiter-semantics.test.ts +1 -1
- package/src/execution/__tests__/turn-limiter.test.ts +1 -1
- package/src/execution/__tests__/ui-request-handler-factory.test.ts +12 -6
- package/src/execution/__tests__/ui-request-handler.test.ts +4 -3
- package/src/execution/__tests__/ui-request-queue.test.ts +142 -2
- package/src/execution/__tests__/worktree-git-ops.test.ts +1 -1
- package/src/execution/__tests__/worktree-manager.test.ts +14 -5
- package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +4 -3
- package/src/execution/__tests__/worktree-reconcile-aging.test.ts +2 -2
- package/src/execution/__tests__/worktree-reconcile.integration.test.ts +1 -1
- package/src/execution/__tests__/worktree-registry.test.ts +1 -1
- package/src/execution/agent-registry.ts +74 -30
- package/src/execution/agent-result-mapper.ts +3 -0
- package/src/execution/cold-resurrect.ts +199 -0
- package/src/execution/collect-coordinator.ts +200 -0
- package/src/execution/config.ts +77 -5
- package/src/execution/engine/__tests__/common/capability-gate.test.ts +91 -0
- package/src/execution/engine/__tests__/common/data-dir.test.ts +1 -1
- package/src/execution/engine/__tests__/common/event-journal.test.ts +1 -1
- package/src/execution/engine/__tests__/common/journal-wiring.test.ts +84 -0
- package/src/execution/engine/__tests__/common/kill-chain.test.ts +34 -7
- package/src/execution/engine/__tests__/common/persona-router.test.ts +4 -5
- package/src/execution/engine/__tests__/common/pool-manager.test.ts +213 -53
- package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +149 -0
- package/src/execution/engine/__tests__/common/session-view-service.test.ts +499 -0
- package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +22 -112
- package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +15 -28
- package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +1 -1
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +12 -12
- package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +2 -2
- package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +21 -82
- package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +4 -7
- package/src/execution/engine/__tests__/engine-discovery.test.ts +15 -3
- package/src/execution/engine/__tests__/model-prompt.test.ts +15 -3
- package/src/execution/engine/__tests__/registry.test.ts +4 -2
- package/src/execution/engine/__tests__/routing.test.ts +115 -6
- package/src/execution/engine/common/capability-gate.ts +92 -0
- package/src/execution/engine/common/journal-wiring.ts +97 -0
- package/src/execution/engine/common/kill-chain.ts +42 -10
- package/src/execution/engine/common/nesting-guard.ts +66 -0
- package/src/execution/engine/common/persona-router.ts +18 -8
- package/src/execution/engine/common/pool-manager.ts +332 -78
- package/src/execution/engine/common/session-view-service.ts +506 -0
- package/src/execution/engine/common/session-view-types.ts +125 -0
- package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +174 -28
- package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +257 -0
- package/src/execution/{argv-mirror.ts → engine/engines/pi/argv-mirror.ts} +43 -21
- package/src/execution/{get-state-handshake.ts → engine/engines/pi/get-state-handshake.ts} +1 -1
- package/src/execution/{output-collector.ts → engine/engines/pi/output-collector.ts} +108 -19
- package/src/execution/engine/engines/pi/pi-engine.ts +434 -38
- package/src/execution/{pi-invocation.ts → engine/engines/pi/pi-invocation.ts} +2 -2
- package/src/execution/engine/engines/pi/reader.ts +11 -0
- package/src/execution/engine/engines/pi/registration.ts +4 -2
- package/src/execution/{session-runner.ts → engine/engines/pi/session-runner.ts} +617 -412
- package/src/execution/{spawn-event-adapter.ts → engine/engines/pi/spawn-event-adapter.ts} +75 -34
- package/src/execution/{stdin-writer.ts → engine/engines/pi/stdin-writer.ts} +10 -9
- package/src/execution/{temp-prompt.ts → engine/engines/pi/temp-prompt.ts} +2 -2
- package/src/execution/{turn-limiter.ts → engine/engines/pi/turn-limiter.ts} +1 -1
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +54 -27
- package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +321 -0
- package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +13 -12
- package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +7 -210
- package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +6 -110
- package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +247 -0
- package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +451 -0
- package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +20 -8
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +77 -110
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +26 -320
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +210 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +353 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +282 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +372 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +48 -148
- package/src/execution/engine/engines/zcode/appserver-launcher.ts +167 -0
- package/src/execution/engine/engines/zcode/connection.ts +24 -11
- package/src/execution/engine/engines/zcode/constants.ts +75 -71
- package/src/execution/engine/engines/zcode/golden-sample.ts +8 -46
- package/src/execution/engine/engines/zcode/parser.ts +12 -346
- package/src/execution/engine/engines/zcode/preparer.ts +12 -143
- package/src/execution/engine/engines/zcode/session-channel.ts +351 -39
- package/src/execution/engine/engines/zcode/zcode-engine.ts +665 -760
- package/src/execution/engine/host-task-spec.ts +32 -36
- package/src/execution/engine/model-validation.ts +177 -0
- package/src/execution/engine/port.ts +24 -6
- package/src/execution/engine/routing.ts +75 -1
- package/src/execution/engine/types.ts +30 -103
- package/src/execution/execution-record.ts +229 -144
- package/src/execution/finalize-record.ts +141 -99
- package/src/execution/idle-gc.ts +28 -0
- package/src/execution/lifecycle-predicates.ts +1 -1
- package/src/execution/notifier.ts +234 -25
- package/src/execution/notify-host.ts +232 -0
- package/src/execution/record-entry.ts +16 -0
- package/src/execution/record-store.ts +280 -103
- package/src/execution/round-settlement.ts +93 -0
- package/src/execution/session-file-gc.ts +96 -62
- package/src/execution/session-reconstructor.ts +256 -143
- package/src/execution/sessions-index.ts +117 -47
- package/src/execution/settled-watchdog.ts +264 -52
- package/src/execution/subagent-actions-core.ts +84 -28
- package/src/execution/subagent-service.ts +1225 -964
- package/src/execution/subprocess-agent-runner.ts +144 -97
- package/src/execution/sync-rebuild.ts +87 -0
- package/src/execution/types.ts +72 -0
- package/src/execution/ui-request-handler-factory.ts +102 -74
- package/src/execution/ui-request-queue.ts +50 -19
- package/src/index.ts +442 -316
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +1 -1
- package/src/orchestration/__tests__/agent-call-stream.test.ts +2 -2
- package/src/orchestration/__tests__/args-validator.test.ts +14 -0
- package/src/orchestration/__tests__/config-loader.test.ts +1 -1
- package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +1 -1
- package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +11 -9
- package/src/orchestration/__tests__/execute-agent-call.test.ts +151 -11
- package/src/orchestration/__tests__/file-run-store-prune.test.ts +1 -1
- package/src/orchestration/__tests__/file-run-store-throttle.test.ts +1 -1
- package/src/orchestration/__tests__/file-run-store.test.ts +7 -6
- package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +2 -2
- package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +1 -1
- package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +3 -3
- package/src/orchestration/__tests__/lifecycle.test.ts +7 -5
- package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +1 -1
- package/src/orchestration/__tests__/review-fix-loop-scriptpath-failfast.test.ts +1 -1
- package/src/orchestration/__tests__/run-snapshot.test.ts +8 -5
- package/src/orchestration/__tests__/script-generate.test.ts +5 -5
- package/src/orchestration/__tests__/script-lint.test.ts +17 -0
- package/src/orchestration/__tests__/skill-discovery.test.ts +2 -2
- package/src/orchestration/__tests__/test-mocks.ts +2 -0
- package/src/orchestration/__tests__/worker-exit-without-result.test.ts +7 -6
- package/src/orchestration/__tests__/worker-message-pump-finalize-run.test.ts +229 -0
- package/src/orchestration/__tests__/{error-recovery-handlers.test.ts → worker-message-pump-handlers.test.ts} +27 -19
- package/src/orchestration/__tests__/{error-recovery-postmessage-defense.test.ts → worker-message-pump-postmessage-defense.test.ts} +8 -8
- package/src/orchestration/__tests__/{error-recovery-serialize-failed-result.test.ts → worker-message-pump-serialize-failed-result.test.ts} +2 -2
- package/src/orchestration/__tests__/{error-recovery-workflow-call.test.ts → worker-message-pump-workflow-call.test.ts} +1 -1
- package/src/orchestration/__tests__/worker-pending-timeout-abort.test.ts +1 -1
- package/src/orchestration/__tests__/worker-script-builder.test.ts +1 -1
- package/src/orchestration/__tests__/workflow-files.test.ts +10 -10
- package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +1 -1
- package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +1 -1
- package/src/orchestration/agent-opts-resolver.ts +1 -1
- package/src/orchestration/args-validator.ts +53 -31
- package/src/orchestration/execute-agent-call.ts +19 -73
- package/src/orchestration/launcher.ts +128 -81
- package/src/orchestration/lifecycle.ts +43 -45
- package/src/orchestration/models/ports.ts +4 -4
- package/src/orchestration/models/run-runtime.ts +2 -2
- package/src/orchestration/models/trace.ts +1 -1
- package/src/orchestration/models/types.ts +111 -22
- package/src/orchestration/models/workflow-run.ts +1 -1
- package/src/orchestration/script-lint.ts +91 -58
- package/src/orchestration/{error-recovery.ts → worker-message-pump.ts} +157 -150
- package/src/shared/__tests__/atomic-write.test.ts +1 -1
- package/src/shared/__tests__/meta-parser.test.ts +151 -0
- package/src/shared/__tests__/resource-discovery-host-roots.test.ts +5 -5
- package/src/shared/__tests__/resource-discovery.test.ts +258 -215
- package/src/shared/atomic-write.ts +12 -9
- package/src/shared/meta-parser.ts +158 -84
- package/src/shared/model-ref.ts +15 -2
- package/src/shared/resource-discovery.ts +9 -183
- package/src/shared/schema-jsonify.ts +1 -1
- package/workflows/review-fix-loop-utils.cjs +151 -89
- package/workflows/review-fix-loop-utils.d.cts +287 -0
- package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
- package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
- package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
- package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
- package/src/execution/engine/engines/zcode/__tests__/preparer-appserver.test.ts +0 -387
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -710
- package/src/execution/engine/engines/zcode/appserver-home.ts +0 -442
- package/src/execution/engine/engines/zcode/appserver-probe.ts +0 -141
- package/src/execution/engine/engines/zcode/launcher.ts +0 -161
- package/src/execution/execute-options-mapper.ts +0 -115
- package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -288
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { describe, expect, it, vi } from "vitest";
|
|
14
14
|
|
|
15
|
-
import { handleWorkerMessage } from "../
|
|
15
|
+
import { handleWorkerMessage } from "../worker-message-pump.ts";
|
|
16
16
|
import type { LifecycleDeps, WorkerHandlers } from "../models/ports.ts";
|
|
17
17
|
import { Trace } from "../models/trace.ts";
|
|
18
18
|
import type { WorkflowRun } from "../models/workflow-run.ts";
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { describe, expect, it, vi } from "vitest";
|
|
10
10
|
|
|
11
|
-
import { handleWorkerMessage } from "../
|
|
11
|
+
import { handleWorkerMessage } from "../worker-message-pump.ts";
|
|
12
12
|
import type { LifecycleDeps, WorkerHandlers } from "../models/ports.ts";
|
|
13
13
|
import { Trace } from "../models/trace.ts";
|
|
14
14
|
import type { WorkflowRun } from "../models/workflow-run.ts";
|
|
@@ -122,7 +122,7 @@ describe("U5: widgetKey 格式", () => {
|
|
|
122
122
|
expect(setWidget.mock.calls.length).toBeGreaterThanOrEqual(1);
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
const widgetKey = setWidget.mock.calls[0][0] as string;
|
|
125
|
+
const widgetKey = setWidget.mock.calls[0]![0] as string;
|
|
126
126
|
expect(widgetKey).toBe("subagent-stream-wf-test-123-2");
|
|
127
127
|
});
|
|
128
128
|
});
|
|
@@ -123,6 +123,20 @@ describe("validateRunArgs — 校验语义", () => {
|
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
+
it("TC6c: parameters 非 object(数组)→ ArgsValidationError「expected object」", () => {
|
|
127
|
+
// 锚定 schema 形状守卫分支:数组 parameters 在 null-scan/compile 之前 fail-fast
|
|
128
|
+
const spec = makeSpec([{ target: "string" }] as unknown as Record<string, unknown>, { a: 1 });
|
|
129
|
+
try {
|
|
130
|
+
validateRunArgs(spec);
|
|
131
|
+
expect.unreachable("should throw");
|
|
132
|
+
} catch (err) {
|
|
133
|
+
expect(err).toBeInstanceOf(ArgsValidationError);
|
|
134
|
+
expect((err as ArgsValidationError).message).toContain(
|
|
135
|
+
"invalid parameter schema (expected object)",
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
126
140
|
it("TC6b: strictSchema:false 容忍自定义关键字与 format(design-review major-3 回归)", () => {
|
|
127
141
|
const spec = makeSpec(
|
|
128
142
|
{ type: "object", properties: { target: { type: "string", format: "uri" } }, required: ["target"], "x-custom": true },
|
|
@@ -102,7 +102,7 @@ beforeEach(async () => {
|
|
|
102
102
|
|
|
103
103
|
afterEach(async () => {
|
|
104
104
|
vi.useRealTimers();
|
|
105
|
-
if (ws) await rm(ws.root, { recursive: true, force: true });
|
|
105
|
+
if (ws) await rm(ws.root, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
/** 过滤掉可能从真实 homedir 泄漏进来的 user-agents 文件,只保留临时工作区内结果。 */
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import {
|
|
20
20
|
handleWorkerError,
|
|
21
21
|
resetRebuildFailureInjectionForTest,
|
|
22
|
-
} from "../
|
|
22
|
+
} from "../worker-message-pump.ts";
|
|
23
23
|
import { Budget } from "../models/budget.ts";
|
|
24
24
|
import { RunRuntime } from "../models/run-runtime.ts";
|
|
25
25
|
import { Trace } from "../models/trace.ts";
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
handleWorkerError,
|
|
23
23
|
handleWorkerExit,
|
|
24
24
|
handleWorkerMessage,
|
|
25
|
-
} from "../
|
|
25
|
+
} from "../worker-message-pump.ts";
|
|
26
26
|
import { Budget } from "../models/budget.ts";
|
|
27
27
|
import { RunRuntime } from "../models/run-runtime.ts";
|
|
28
28
|
import { toRunSnapshot } from "../run-snapshot.ts";
|
|
@@ -69,12 +69,14 @@ function makeDeps(opts: {
|
|
|
69
69
|
emitThrows?: boolean;
|
|
70
70
|
/** onRunDone 同步抛错(模拟 evictDoneRunsBeyondCap 等收尾异常)。 */
|
|
71
71
|
onRunDoneThrows?: boolean;
|
|
72
|
-
} = {}): LifecycleDeps & {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
} = {}): Omit<LifecycleDeps, "store" | "workerHost" | "runner" | "eventBus" | "onRunDone" | "log"> & {
|
|
73
|
+
// 真实类型整体保留(接口成员完整),仅 mock 方法交叉 vi.fn 能力
|
|
74
|
+
store: LifecycleDeps["store"] & { save: LifecycleDeps["store"]["save"] & ReturnType<typeof vi.fn> };
|
|
75
|
+
workerHost: LifecycleDeps["workerHost"] & { start: LifecycleDeps["workerHost"]["start"] & ReturnType<typeof vi.fn> };
|
|
76
|
+
runner: LifecycleDeps["runner"] & { run: LifecycleDeps["runner"]["run"] & ReturnType<typeof vi.fn> };
|
|
77
|
+
eventBus: NonNullable<LifecycleDeps["eventBus"]> & { emit: NonNullable<LifecycleDeps["eventBus"]>["emit"] & ReturnType<typeof vi.fn> };
|
|
78
|
+
onRunDone: LifecycleDeps["onRunDone"] & ReturnType<typeof vi.fn>;
|
|
79
|
+
log: LifecycleDeps["log"] & ReturnType<typeof vi.fn>;
|
|
78
80
|
} {
|
|
79
81
|
return {
|
|
80
82
|
store: { save: vi.fn(async () => {}) },
|
|
@@ -239,7 +241,7 @@ describe("[OR-6] log 消息消费 + 未知类型 default 留痕", () => {
|
|
|
239
241
|
expect(run.state.errorLogs).toEqual([{ level: "log", message: "step 1 done" }]);
|
|
240
242
|
expect(run.state.status).toBe("running"); // 不触发终态
|
|
241
243
|
expect(deps.store.save).not.toHaveBeenCalled();
|
|
242
|
-
expect(deps.log).toHaveBeenCalledWith("debug", "workflow:
|
|
244
|
+
expect(deps.log).toHaveBeenCalledWith("debug", "workflow:worker-message-pump", "worker log", {
|
|
243
245
|
runId: "wf-log-1",
|
|
244
246
|
phase: "build",
|
|
245
247
|
message: "step 1 done",
|
|
@@ -289,7 +291,7 @@ describe("[OR-6] log 消息消费 + 未知类型 default 留痕", () => {
|
|
|
289
291
|
await handleWorkerMessage(run, { type: "future-unknown-type", payload: 1 }, deps, makeHandlers());
|
|
290
292
|
|
|
291
293
|
expect(warnSpy.mock.calls.map((c) => String(c[0])).some((m) => m.includes("unknown worker message type") && m.includes("future-unknown-type"))).toBe(true);
|
|
292
|
-
expect(deps.log).toHaveBeenCalledWith("warn", "workflow:
|
|
294
|
+
expect(deps.log).toHaveBeenCalledWith("warn", "workflow:worker-message-pump", "unknown worker message type", {
|
|
293
295
|
runId: "wf-log-3",
|
|
294
296
|
type: "future-unknown-type",
|
|
295
297
|
});
|
|
@@ -6,16 +6,17 @@
|
|
|
6
6
|
import { describe, expect, it, vi } from "vitest";
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
|
+
classifyFailureKind,
|
|
10
|
+
describeMissingParsedOutput,
|
|
9
11
|
DETERMINISTIC_SCHEMA_FAILURE_PREFIX,
|
|
10
|
-
executeAgentCall,
|
|
11
12
|
isDeterministicSchemaFailureMsg,
|
|
12
13
|
isStaleContextErrorMsg,
|
|
13
14
|
STALE_CONTEXT_PATTERNS,
|
|
14
|
-
} from "
|
|
15
|
+
} from "../../execution/engine/engines/pi/output-collector.ts";
|
|
16
|
+
import { executeAgentCall } from "../execute-agent-call.ts";
|
|
15
17
|
import { AgentCall } from "../models/agent-call.ts";
|
|
16
18
|
import { Budget } from "../models/budget.ts";
|
|
17
19
|
import type { AgentRunner } from "../models/ports.ts";
|
|
18
|
-
import { describeMissingParsedOutput } from "../../execution/output-collector.ts";
|
|
19
20
|
import type { ToolCall } from "../../execution/types.ts";
|
|
20
21
|
import { Trace } from "../models/trace.ts";
|
|
21
22
|
import type { ExecutionTraceNode } from "../models/types.ts";
|
|
@@ -67,6 +68,15 @@ function createMockRunner(impl?: ReturnType<typeof vi.fn>): AgentRunner & { run:
|
|
|
67
68
|
return { run } as unknown as AgentRunner & { run: ReturnType<typeof vi.fn> };
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
/**
|
|
72
|
+
* [D5-③] 构造带真实分诊的失败 result——failureKind 经产出侧 classifyFailureKind
|
|
73
|
+
* 分类(复刻 collectResult → mapper 透传后的消费侧视角),避免手写字面量与
|
|
74
|
+
* 产出侧词表脱钩。
|
|
75
|
+
*/
|
|
76
|
+
function makeFailedResult(error: string): AgentResult {
|
|
77
|
+
return makeMockResult({ error, failureKind: classifyFailureKind(error) });
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
// ── U2: executeAgentCall 透传 stream 给 runner.run ──
|
|
71
81
|
|
|
72
82
|
describe("U2: executeAgentCall 透传 stream", () => {
|
|
@@ -201,8 +211,9 @@ describe("isOrphaned 守卫", () => {
|
|
|
201
211
|
it("U2: 谓词 true + stale-context 失败路径 → trace.update 0 次,markDone 保留(覆盖 stale finalize 调用点)", async () => {
|
|
202
212
|
const { call, trace } = makeAgentCallAndTrace();
|
|
203
213
|
const updateSpy = vi.spyOn(trace, "update");
|
|
214
|
+
// "context canceled" 经产出侧词表分类为 stale_context(D5-③ 后消费侧读字段)
|
|
204
215
|
const runner = createMockRunner(
|
|
205
|
-
vi.fn().mockResolvedValue(
|
|
216
|
+
vi.fn().mockResolvedValue(makeFailedResult("context canceled")),
|
|
206
217
|
);
|
|
207
218
|
const budget = new Budget();
|
|
208
219
|
|
|
@@ -297,9 +308,11 @@ describe("W4b: stale 分诊对齐 pi 真实文案", () => {
|
|
|
297
308
|
});
|
|
298
309
|
|
|
299
310
|
it("真实文案 → executeAgentCall 不重试(runner.run 恰 1 次)+ markDone failed", async () => {
|
|
311
|
+
// [D5-③] 全链路锁:产出侧 classifyFailureKind(真实文案 → stale_context)→
|
|
312
|
+
// 消费侧读 failureKind 字段分诊(不扫文案)
|
|
300
313
|
const { call, trace } = makeAgentCallAndTrace();
|
|
301
314
|
const runner = createMockRunner(
|
|
302
|
-
vi.fn().mockResolvedValue(
|
|
315
|
+
vi.fn().mockResolvedValue(makeFailedResult(PI_REAL_STALE_MESSAGE)),
|
|
303
316
|
);
|
|
304
317
|
const budget = new Budget();
|
|
305
318
|
|
|
@@ -351,7 +364,7 @@ describe("MF-1: 确定性 schema 失败不重试", () => {
|
|
|
351
364
|
|
|
352
365
|
const { call, trace } = makeAgentCallAndTrace();
|
|
353
366
|
const runner = createMockRunner(
|
|
354
|
-
vi.fn().mockResolvedValue(
|
|
367
|
+
vi.fn().mockResolvedValue(makeFailedResult(attribution)),
|
|
355
368
|
);
|
|
356
369
|
const budget = new Budget();
|
|
357
370
|
|
|
@@ -368,7 +381,7 @@ describe("MF-1: 确定性 schema 失败不重试", () => {
|
|
|
368
381
|
const attribution = describeMissingParsedOutput([])!;
|
|
369
382
|
const { call, trace } = makeAgentCallAndTrace();
|
|
370
383
|
const runner = createMockRunner(
|
|
371
|
-
vi.fn().mockResolvedValue(
|
|
384
|
+
vi.fn().mockResolvedValue(makeFailedResult(attribution)),
|
|
372
385
|
);
|
|
373
386
|
const budget = new Budget();
|
|
374
387
|
|
|
@@ -384,7 +397,11 @@ describe("MF-1: 确定性 schema 失败不重试", () => {
|
|
|
384
397
|
const { call, trace } = makeAgentCallAndTrace();
|
|
385
398
|
const runner = createMockRunner(
|
|
386
399
|
vi.fn().mockResolvedValue(
|
|
387
|
-
makeMockResult({
|
|
400
|
+
makeMockResult({
|
|
401
|
+
error: attribution,
|
|
402
|
+
failureKind: "schema_deterministic",
|
|
403
|
+
usage: { input: 100, output: 50, cacheRead: 0, cacheWrite: 0, cost: 0.01, contextTokens: 0, turns: 0 },
|
|
404
|
+
}),
|
|
388
405
|
),
|
|
389
406
|
);
|
|
390
407
|
const budget = new Budget();
|
|
@@ -402,7 +419,7 @@ describe("MF-1: 确定性 schema 失败不重试", () => {
|
|
|
402
419
|
const attribution = state2Attribution();
|
|
403
420
|
const { call, trace } = makeAgentCallAndTrace();
|
|
404
421
|
const runner = createMockRunner(
|
|
405
|
-
vi.fn().mockResolvedValue(
|
|
422
|
+
vi.fn().mockResolvedValue(makeFailedResult(attribution)),
|
|
406
423
|
);
|
|
407
424
|
const budget = new Budget();
|
|
408
425
|
|
|
@@ -414,7 +431,7 @@ describe("MF-1: 确定性 schema 失败不重试", () => {
|
|
|
414
431
|
it("态③(no details,无标记)→ 照常重试(可重试语义保留)", async () => {
|
|
415
432
|
vi.useFakeTimers();
|
|
416
433
|
try {
|
|
417
|
-
// 态③真实文案(不带确定性标记)——矩阵执行面锁定:无标记 = 可重试
|
|
434
|
+
// 态③真实文案(不带确定性标记)——矩阵执行面锁定:无标记 = unknown = 可重试
|
|
418
435
|
const msg = describeMissingParsedOutput([
|
|
419
436
|
{ toolName: "structured-output", result: { content: [] } },
|
|
420
437
|
])!;
|
|
@@ -423,7 +440,7 @@ describe("MF-1: 确定性 schema 失败不重试", () => {
|
|
|
423
440
|
const { call, trace } = makeAgentCallAndTrace();
|
|
424
441
|
const runner = createMockRunner(
|
|
425
442
|
vi.fn()
|
|
426
|
-
.mockResolvedValueOnce(
|
|
443
|
+
.mockResolvedValueOnce(makeFailedResult(msg))
|
|
427
444
|
.mockResolvedValueOnce(makeMockResult()),
|
|
428
445
|
);
|
|
429
446
|
const budget = new Budget();
|
|
@@ -449,3 +466,126 @@ describe("MF-1: 确定性 schema 失败不重试", () => {
|
|
|
449
466
|
expect(isDeterministicSchemaFailureMsg(DETERMINISTIC_SCHEMA_FAILURE_PREFIX)).toBe(true);
|
|
450
467
|
});
|
|
451
468
|
});
|
|
469
|
+
|
|
470
|
+
// ── D5-③: failureKind 三态结构化分诊(V5③④ 验收的执行面锁定) ──
|
|
471
|
+
//
|
|
472
|
+
// 语义守恒(r1 MF4 钉正,最高优先约束):unknown(含字段缺省)= 可重试——保持
|
|
473
|
+
// 收敛前(子串分诊时代)的默认重试语义;仅 stale_context(不重试、换参重发由
|
|
474
|
+
// 上层编排)与 schema_deterministic 维持特判。词表识别已收敛到产出侧
|
|
475
|
+
// output-collector.classifyFailureKind(消费侧只读字段)。
|
|
476
|
+
|
|
477
|
+
describe("D5-③: failureKind 三态分诊", () => {
|
|
478
|
+
it("stale_context → 不退避不重试:runner.run 恰 1 次 + 终态 failed(V5③)", async () => {
|
|
479
|
+
const { call, trace } = makeAgentCallAndTrace();
|
|
480
|
+
const runner = createMockRunner(
|
|
481
|
+
vi.fn().mockResolvedValue(makeMockResult({
|
|
482
|
+
error: PI_REAL_STALE_MESSAGE,
|
|
483
|
+
failureKind: "stale_context",
|
|
484
|
+
})),
|
|
485
|
+
);
|
|
486
|
+
const budget = new Budget();
|
|
487
|
+
|
|
488
|
+
await executeAgentCall(call, runner, budget, new AbortController().signal, trace);
|
|
489
|
+
|
|
490
|
+
expect(runner.run).toHaveBeenCalledTimes(1);
|
|
491
|
+
expect(call.attempts).toBe(1);
|
|
492
|
+
expect(call.status).toBe("done");
|
|
493
|
+
expect(call.result?.error).toBe(PI_REAL_STALE_MESSAGE);
|
|
494
|
+
expect(trace.find(0)?.status).toBe("failed");
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it("schema_deterministic → 不重试特判维持:runner.run 恰 1 次(V5③ 同族)", async () => {
|
|
498
|
+
const attribution = state2Attribution();
|
|
499
|
+
const { call, trace } = makeAgentCallAndTrace();
|
|
500
|
+
const runner = createMockRunner(
|
|
501
|
+
vi.fn().mockResolvedValue(makeMockResult({
|
|
502
|
+
error: attribution,
|
|
503
|
+
failureKind: "schema_deterministic",
|
|
504
|
+
})),
|
|
505
|
+
);
|
|
506
|
+
const budget = new Budget();
|
|
507
|
+
|
|
508
|
+
await executeAgentCall(call, runner, budget, new AbortController().signal, trace);
|
|
509
|
+
|
|
510
|
+
expect(runner.run).toHaveBeenCalledTimes(1);
|
|
511
|
+
expect(trace.find(0)?.status).toBe("failed");
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it("unknown → 默认退避重试:瞬态错误(模拟 provider 5xx)退避后第二次成功(V5④ 正向)", async () => {
|
|
515
|
+
vi.useFakeTimers();
|
|
516
|
+
try {
|
|
517
|
+
const { call, trace } = makeAgentCallAndTrace();
|
|
518
|
+
const runner = createMockRunner(
|
|
519
|
+
vi.fn()
|
|
520
|
+
.mockResolvedValueOnce(makeMockResult({
|
|
521
|
+
error: "provider 503 service unavailable",
|
|
522
|
+
failureKind: "unknown",
|
|
523
|
+
}))
|
|
524
|
+
.mockResolvedValueOnce(makeMockResult()),
|
|
525
|
+
);
|
|
526
|
+
const budget = new Budget();
|
|
527
|
+
|
|
528
|
+
const promise = executeAgentCall(call, runner, budget, new AbortController().signal, trace);
|
|
529
|
+
await vi.advanceTimersByTimeAsync(2000);
|
|
530
|
+
await promise;
|
|
531
|
+
|
|
532
|
+
expect(runner.run).toHaveBeenCalledTimes(2);
|
|
533
|
+
expect(call.status).toBe("done");
|
|
534
|
+
expect(call.result?.error).toBeUndefined();
|
|
535
|
+
expect(trace.find(0)?.status).toBe("completed");
|
|
536
|
+
} finally {
|
|
537
|
+
vi.useRealTimers();
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
it("failureKind 缺省(旧链路/上游未写)→ 等同 unknown 默认退避重试(V5④ 语义守恒核心断言)", async () => {
|
|
542
|
+
vi.useFakeTimers();
|
|
543
|
+
try {
|
|
544
|
+
// 字段缺省是可重试而非「保守不重试」——反转会把一切未标注路径(瞬态 provider
|
|
545
|
+
// 错误、spawn 失败)静默丢进不重试(r1 MF4 击穿反例)
|
|
546
|
+
const { call, trace } = makeAgentCallAndTrace();
|
|
547
|
+
const runner = createMockRunner(
|
|
548
|
+
vi.fn()
|
|
549
|
+
.mockResolvedValueOnce(makeMockResult({ error: "spawn EAGAIN transient" }))
|
|
550
|
+
.mockResolvedValueOnce(makeMockResult()),
|
|
551
|
+
);
|
|
552
|
+
const budget = new Budget();
|
|
553
|
+
|
|
554
|
+
const promise = executeAgentCall(call, runner, budget, new AbortController().signal, trace);
|
|
555
|
+
await vi.advanceTimersByTimeAsync(2000);
|
|
556
|
+
await promise;
|
|
557
|
+
|
|
558
|
+
expect(runner.run).toHaveBeenCalledTimes(2);
|
|
559
|
+
expect(call.status).toBe("done");
|
|
560
|
+
} finally {
|
|
561
|
+
vi.useRealTimers();
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
it("词表漂移失效模式:未知错误文案 → classifyFailureKind=unknown → 走退避重试(安全默认)", async () => {
|
|
566
|
+
vi.useFakeTimers();
|
|
567
|
+
try {
|
|
568
|
+
// pi 升级改写 stale 文案后,旧词表对新文案零命中——分诊降级 unknown、
|
|
569
|
+
// 保守重试(可能多耗一次调用),而不是静默漏诊挂死在不重试
|
|
570
|
+
const futurePiError = "extension runtime was superseded by a newer orchestration epoch";
|
|
571
|
+
expect(classifyFailureKind(futurePiError)).toBe("unknown");
|
|
572
|
+
|
|
573
|
+
const { call, trace } = makeAgentCallAndTrace();
|
|
574
|
+
const runner = createMockRunner(
|
|
575
|
+
vi.fn()
|
|
576
|
+
.mockResolvedValueOnce(makeFailedResult(futurePiError))
|
|
577
|
+
.mockResolvedValueOnce(makeMockResult()),
|
|
578
|
+
);
|
|
579
|
+
const budget = new Budget();
|
|
580
|
+
|
|
581
|
+
const promise = executeAgentCall(call, runner, budget, new AbortController().signal, trace);
|
|
582
|
+
await vi.advanceTimersByTimeAsync(2000);
|
|
583
|
+
await promise;
|
|
584
|
+
|
|
585
|
+
expect(runner.run).toHaveBeenCalledTimes(2);
|
|
586
|
+
expect(call.status).toBe("done");
|
|
587
|
+
} finally {
|
|
588
|
+
vi.useRealTimers();
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
});
|
|
@@ -39,7 +39,7 @@ beforeEach(() => {
|
|
|
39
39
|
afterEach(() => {
|
|
40
40
|
vi.useRealTimers();
|
|
41
41
|
resetCoreForTests();
|
|
42
|
-
rmSync(dataRoot, { recursive: true, force: true });
|
|
42
|
+
rmSync(dataRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
/** 构造可持久化的 WorkflowRun(对齐 file-run-store.test.ts makeRun 模式)。 */
|
|
@@ -24,13 +24,13 @@ import { WorkflowRun } from "../models/workflow-run.ts";
|
|
|
24
24
|
import { FileRunStore } from "../file-run-store.ts";
|
|
25
25
|
|
|
26
26
|
let dataRoot: string;
|
|
27
|
-
let logSpy: ReturnType<typeof vi.fn
|
|
27
|
+
let logSpy: ReturnType<typeof vi.fn<(level: import("../../core/logger.ts").LogLevel, component: string, message: string, data?: unknown) => void>>;
|
|
28
28
|
let store: FileRunStore;
|
|
29
29
|
|
|
30
30
|
beforeEach(() => {
|
|
31
31
|
resetCoreForTests();
|
|
32
32
|
dataRoot = mkdtempSync(join(tmpdir(), "file-run-store-"));
|
|
33
|
-
logSpy = vi.fn();
|
|
33
|
+
logSpy = vi.fn((_level: import("../../core/logger.ts").LogLevel, _component: string, _message: string, _data?: unknown) => {});
|
|
34
34
|
const host: HostServices = {
|
|
35
35
|
dataRoot: () => dataRoot,
|
|
36
36
|
log: logSpy,
|
|
@@ -41,7 +41,7 @@ beforeEach(() => {
|
|
|
41
41
|
|
|
42
42
|
afterEach(() => {
|
|
43
43
|
resetCoreForTests();
|
|
44
|
-
rmSync(dataRoot, { recursive: true, force: true });
|
|
44
|
+
rmSync(dataRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
/** 构造可持久化的 WorkflowRun(对齐 lifecycle.test.ts makeEvictableRun 模式)。 */
|
|
@@ -328,12 +328,13 @@ describe("FileRunStore — 版本衔接与 live-strip(U8 / ⛔5,D4 裁决)
|
|
|
328
328
|
|
|
329
329
|
it("⛔5 live 字段 strip 后落盘(落盘行无 live 键,内存 run 不受影响)", async () => {
|
|
330
330
|
const run = makeRun("wf-livestrip-1");
|
|
331
|
-
const node = {
|
|
331
|
+
const node: import("../models/types.ts").ExecutionTraceNode = {
|
|
332
332
|
stepIndex: 0,
|
|
333
333
|
agent: "coder",
|
|
334
334
|
task: "do work",
|
|
335
335
|
model: "test-model",
|
|
336
|
-
status: "running"
|
|
336
|
+
status: "running",
|
|
337
|
+
live: undefined,
|
|
337
338
|
};
|
|
338
339
|
run.state.trace.append(node);
|
|
339
340
|
const AgentCallMod = await import("../models/agent-call.ts");
|
|
@@ -378,7 +379,7 @@ describe("FileRunStore — stateFilePath / 端口语义", () => {
|
|
|
378
379
|
join(altRoot, "workflow-state", "wf-x-2.jsonl"),
|
|
379
380
|
);
|
|
380
381
|
} finally {
|
|
381
|
-
rmSync(altRoot, { recursive: true, force: true });
|
|
382
|
+
rmSync(altRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
382
383
|
}
|
|
383
384
|
});
|
|
384
385
|
|
|
@@ -618,7 +618,7 @@ describe("runAndWait model 透传", () => {
|
|
|
618
618
|
);
|
|
619
619
|
expect(result.reason).toBe("completed");
|
|
620
620
|
expect(vi.mocked(runWorkflow)).toHaveBeenCalledTimes(1);
|
|
621
|
-
const spec = vi.mocked(runWorkflow).mock.calls[0][0] as RunSpec;
|
|
621
|
+
const spec = vi.mocked(runWorkflow).mock.calls[0]![0] as RunSpec;
|
|
622
622
|
expect(spec.model).toBe("zai-coding-cn/glm-5.3-flash");
|
|
623
623
|
});
|
|
624
624
|
|
|
@@ -628,7 +628,7 @@ describe("runAndWait model 透传", () => {
|
|
|
628
628
|
setupRunWorkflow(childRun);
|
|
629
629
|
|
|
630
630
|
await runAndWait("child-wf", {}, deps);
|
|
631
|
-
const spec = vi.mocked(runWorkflow).mock.calls[0][0] as RunSpec;
|
|
631
|
+
const spec = vi.mocked(runWorkflow).mock.calls[0]![0] as RunSpec;
|
|
632
632
|
expect(spec.model).toBeUndefined();
|
|
633
633
|
});
|
|
634
634
|
});
|
|
@@ -324,7 +324,7 @@ describe("[OR-7] signal abort listener run 终态移除", () => {
|
|
|
324
324
|
describe("[B-2] runWorkflow fail-fast throw 路径不泄漏 signal abort listener", () => {
|
|
325
325
|
/** signal 上当前真实挂载的 abort listener 数(EventTarget 权威查询,非 spy 计数)。 */
|
|
326
326
|
function liveListenerCount(signal: AbortSignal): number {
|
|
327
|
-
return getEventListeners(signal).length;
|
|
327
|
+
return getEventListeners(signal, "abort").length;
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
it("budgetTimeMs 越界 fail-fast 重试 12 次 → 每次拒绝后 listener 计数归零(无 MaxListeners 累积)", async () => {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { describe, expect, it, vi } from "vitest";
|
|
11
11
|
|
|
12
|
-
import { rebuildRuntime } from "../
|
|
12
|
+
import { rebuildRuntime } from "../worker-message-pump.ts";
|
|
13
13
|
import { runWorkflow } from "../lifecycle.ts";
|
|
14
14
|
import type { RunSpec } from "../models/run-spec.ts";
|
|
15
15
|
import type { LifecycleDeps } from "../models/ports.ts";
|
|
@@ -73,11 +73,11 @@ describe("A4 rebuild 后 _runId 稳定(tier-1 §7.1)", () => {
|
|
|
73
73
|
const runId = await runWorkflow(spec, deps);
|
|
74
74
|
expect(deps.startCalls.length).toBe(1);
|
|
75
75
|
|
|
76
|
-
const run = deps.runs.get(runId)
|
|
76
|
+
const run = deps.runs.get(runId)!;
|
|
77
77
|
expect(run).toBeTruthy();
|
|
78
78
|
expect(run.state.status).toBe("running");
|
|
79
79
|
|
|
80
|
-
// 触发 rebuild(对齐
|
|
80
|
+
// 触发 rebuild(对齐 worker-message-pump handleWorkerError 的恢复路径)
|
|
81
81
|
rebuildRuntime(run, deps, {
|
|
82
82
|
onMessage: vi.fn(),
|
|
83
83
|
onError: vi.fn(),
|
|
@@ -87,7 +87,7 @@ function makeRunningRealRun(
|
|
|
87
87
|
const terminate = vi.fn(async () => {});
|
|
88
88
|
const controller = new AbortController();
|
|
89
89
|
const abort = vi.spyOn(controller, "abort");
|
|
90
|
-
const worker = { terminate, postMessage: vi.fn() } as unknown as
|
|
90
|
+
const worker = { terminate, postMessage: vi.fn() } as unknown as ConstructorParameters<typeof RunRuntime>[0];
|
|
91
91
|
const runtime = new RunRuntime(
|
|
92
92
|
worker as never,
|
|
93
93
|
controller,
|
|
@@ -217,7 +217,7 @@ describe("runWorkflow", () => {
|
|
|
217
217
|
const deps = makeDeps();
|
|
218
218
|
// worker.start 被调时探测 runs 注册状态——证明 runs.set 在 assignRuntime 之后
|
|
219
219
|
let runsSizeAtWorkerStart = -1;
|
|
220
|
-
deps.workerHost
|
|
220
|
+
vi.spyOn(deps.workerHost, "start").mockImplementation(() => {
|
|
221
221
|
runsSizeAtWorkerStart = deps.runs.size;
|
|
222
222
|
return { postMessage: vi.fn(), terminate: vi.fn(async () => {}) };
|
|
223
223
|
});
|
|
@@ -513,7 +513,7 @@ describe("terminateRunningRuns", () => {
|
|
|
513
513
|
expect(terminateB).toHaveBeenCalledTimes(1);
|
|
514
514
|
});
|
|
515
515
|
|
|
516
|
-
it("单 run save
|
|
516
|
+
it("单 run save 抛错不中断其余(save best-effort:unregister 仍发 + 其余 run 照常落盘)", async () => {
|
|
517
517
|
const { run: bad } = makeRunningRealRun("wf-term-err");
|
|
518
518
|
const { run: good } = makeRunningRealRun("wf-term-ok");
|
|
519
519
|
const deps = makeDeps();
|
|
@@ -525,10 +525,12 @@ describe("terminateRunningRuns", () => {
|
|
|
525
525
|
|
|
526
526
|
await terminateRunningRuns(deps, "Session shutdown: run terminated");
|
|
527
527
|
|
|
528
|
-
//
|
|
528
|
+
// [D5-② finalizeRun 收敛] save 失败 best-effort(SW-DATA-3 统一):transition 先于
|
|
529
|
+
// save,状态已转 done;与收敛前不同,unregister 不再被 save 失败短路——否则
|
|
530
|
+
// pending 通知幽灵注销(列表残留永不清理的 running 条目)
|
|
529
531
|
expect(bad.state.status).toBe("done");
|
|
530
532
|
expect(bad.state.reason).toBe("failed");
|
|
531
|
-
expect(deps.eventBus.emit).
|
|
533
|
+
expect(deps.eventBus.emit).toHaveBeenCalledWith("pending:unregister", {
|
|
532
534
|
id: "wf-term-err",
|
|
533
535
|
reason: "failed",
|
|
534
536
|
});
|
|
@@ -80,7 +80,7 @@ describe("[F1] 不可克隆 return → run failed(非悬挂)— e2e", () =>
|
|
|
80
80
|
// worker 侧 fallback 消息经 handleScriptError 超限路径写入归因
|
|
81
81
|
expect(run.state.error).toContain("structured-clone failed");
|
|
82
82
|
// 终态副作用齐全(对比 SW-DATA-3/F1 前的幽灵悬挂:无 unregister / 无 onRunDone)
|
|
83
|
-
expect(deps.eventBus
|
|
83
|
+
expect(deps.eventBus!.emit).toHaveBeenCalledWith(
|
|
84
84
|
"pending:unregister",
|
|
85
85
|
expect.objectContaining({ id: runId, reason: "failed" }),
|
|
86
86
|
);
|
|
@@ -67,7 +67,7 @@ beforeEach(() => {
|
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
afterEach(() => {
|
|
70
|
-
rmSync(sandboxDir, { recursive: true, force: true });
|
|
70
|
+
rmSync(sandboxDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
/** cwd 植入件:若任一脚本回退 process.cwd() 加载依赖,本文件被 require 即抛标记错误。 */
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { describe, expect, it } from "vitest";
|
|
15
15
|
|
|
16
16
|
import type { ExecutionRecord } from "../../execution/types.ts";
|
|
17
|
+
import type { ExecutionTraceNode } from "../models/types.ts";
|
|
17
18
|
import { AgentCall } from "../models/agent-call.ts";
|
|
18
19
|
import { Budget } from "../models/budget.ts";
|
|
19
20
|
import { Trace } from "../models/trace.ts";
|
|
@@ -54,7 +55,7 @@ function makeLiveRecord(id: string): ExecutionRecord {
|
|
|
54
55
|
agent: "coder",
|
|
55
56
|
model: "test-model",
|
|
56
57
|
thinkingLevel: undefined,
|
|
57
|
-
mode: "
|
|
58
|
+
mode: "background",
|
|
58
59
|
task: "do work",
|
|
59
60
|
slug: "do-work",
|
|
60
61
|
startedAt: 0,
|
|
@@ -206,12 +207,13 @@ describe("run-snapshot — toRunSnapshot/fromRunSnapshot 往返等值", () => {
|
|
|
206
207
|
describe("run-snapshot — live-strip 防御内聚", () => {
|
|
207
208
|
it("trace 节点与 calls[].traceNode 带 live → 序列化输出无 live 键", () => {
|
|
208
209
|
const run = makeRun("wf-live-1");
|
|
209
|
-
const node = {
|
|
210
|
+
const node: ExecutionTraceNode = {
|
|
210
211
|
stepIndex: 0,
|
|
211
212
|
agent: "coder",
|
|
212
213
|
task: "do work",
|
|
213
214
|
model: "test-model",
|
|
214
|
-
status: "running"
|
|
215
|
+
status: "running",
|
|
216
|
+
live: undefined,
|
|
215
217
|
};
|
|
216
218
|
run.state.trace.append(node);
|
|
217
219
|
const call = new AgentCall(0, { prompt: "do work" }, node);
|
|
@@ -229,12 +231,13 @@ describe("run-snapshot — live-strip 防御内聚", () => {
|
|
|
229
231
|
|
|
230
232
|
it("strip 产出新对象,不 mutate 内存 run(save 后 run 可继续跑)", () => {
|
|
231
233
|
const run = makeRun("wf-live-2");
|
|
232
|
-
const node = {
|
|
234
|
+
const node: ExecutionTraceNode = {
|
|
233
235
|
stepIndex: 0,
|
|
234
236
|
agent: "coder",
|
|
235
237
|
task: "do work",
|
|
236
238
|
model: "test-model",
|
|
237
|
-
status: "running"
|
|
239
|
+
status: "running",
|
|
240
|
+
live: undefined,
|
|
238
241
|
};
|
|
239
242
|
run.state.trace.append(node);
|
|
240
243
|
node.live = makeLiveRecord("run-0");
|
|
@@ -168,7 +168,7 @@ describe("generateWorkflowScript 校验闸(文案逐字对齐 pi 现版)", (
|
|
|
168
168
|
);
|
|
169
169
|
expect(existsSync(join(tmpRoot, "esm-wf.js"))).toBe(false);
|
|
170
170
|
} finally {
|
|
171
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
171
|
+
rmSync(tmpRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
172
172
|
}
|
|
173
173
|
});
|
|
174
174
|
|
|
@@ -216,7 +216,7 @@ describe("generateWorkflowScript 校验闸(文案逐字对齐 pi 现版)", (
|
|
|
216
216
|
}
|
|
217
217
|
expect(existsSync(join(tmpRoot, "bad-wf.js"))).toBe(false);
|
|
218
218
|
} finally {
|
|
219
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
219
|
+
rmSync(tmpRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
220
220
|
}
|
|
221
221
|
});
|
|
222
222
|
|
|
@@ -247,7 +247,7 @@ describe("generateWorkflowScript 合法样本落 tmp", () => {
|
|
|
247
247
|
expect(existsSync(r.path)).toBe(true);
|
|
248
248
|
expect(readFileSync(r.path, "utf-8")).toBe(PI_META_VALID);
|
|
249
249
|
} finally {
|
|
250
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
250
|
+
rmSync(tmpRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
251
251
|
}
|
|
252
252
|
});
|
|
253
253
|
|
|
@@ -259,7 +259,7 @@ describe("generateWorkflowScript 合法样本落 tmp", () => {
|
|
|
259
259
|
if (!r.ok) throw new Error(r.error);
|
|
260
260
|
expect(existsSync(r.path)).toBe(true);
|
|
261
261
|
} finally {
|
|
262
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
262
|
+
rmSync(tmpRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
263
263
|
}
|
|
264
264
|
});
|
|
265
265
|
|
|
@@ -274,7 +274,7 @@ describe("generateWorkflowScript 合法样本落 tmp", () => {
|
|
|
274
274
|
expect(existsSync(r.path)).toBe(true);
|
|
275
275
|
} finally {
|
|
276
276
|
cwdSpy.mockRestore();
|
|
277
|
-
rmSync(fakeCwd, { recursive: true, force: true });
|
|
277
|
+
rmSync(fakeCwd, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
|
|
278
278
|
}
|
|
279
279
|
});
|
|
280
280
|
});
|