@zhushanwen/subagent-core 0.2.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -2
- package/agents/analyst.md +60 -0
- package/agents/coder.md +69 -0
- package/agents/debugger.md +66 -0
- package/agents/doc-reviewer.md +49 -0
- package/agents/explorer.md +63 -0
- package/agents/general-purpose.md +32 -0
- package/agents/orchestrator.md +61 -0
- package/agents/planner.md +53 -0
- package/agents/researcher.md +67 -0
- package/agents/reviewer.md +73 -0
- package/dist/chunk-43ONBFZX.js +240 -0
- package/dist/chunk-APZY4IME.js +27 -0
- package/dist/chunk-V3VHZ2VX.js +59 -0
- package/dist/execution/engine/engines/zcode/constants.cjs +62 -9
- package/dist/execution/engine/engines/zcode/constants.d.cts +116 -12
- package/dist/execution/engine/engines/zcode/constants.d.ts +116 -12
- package/dist/execution/engine/engines/zcode/constants.js +39 -7
- 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 +4 -234
- package/dist/execution/engine/paths.js +7 -19
- package/dist/index.cjs +18234 -1277
- package/dist/index.d.cts +5646 -673
- package/dist/index.d.ts +5646 -673
- package/dist/index.js +17828 -1277
- package/dist/{types-BxyAidGf.d.cts → types-Dv4QhSJ_.d.cts} +678 -112
- package/dist/{types-BxyAidGf.d.ts → types-Dv4QhSJ_.d.ts} +678 -112
- package/package.json +7 -4
- 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 +93 -3
- package/src/__tests__/review-fix-loop-utils.test.ts +31 -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/__tests__/smoke.test.ts +9 -2
- 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 +232 -0
- 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 +219 -0
- package/src/execution/__tests__/ask-user-transit-e2e.test.ts +6 -6
- package/src/execution/__tests__/chat-engine-routing.test.ts +136 -30
- package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +5 -4
- package/src/execution/__tests__/cold-resurrect.test.ts +283 -0
- package/src/execution/__tests__/create-concurrency-pool.test.ts +194 -0
- package/src/execution/__tests__/delivery-methods.test.ts +77 -62
- package/src/execution/__tests__/descendant-sweep-guards.test.ts +220 -0
- package/src/execution/__tests__/descendant-sweep.test.ts +269 -0
- package/src/execution/__tests__/dialog-queue.test.ts +199 -1
- package/src/execution/__tests__/engine-model-validation.test.ts +741 -0
- package/src/execution/__tests__/epipe-fallback.test.ts +31 -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 +272 -0
- package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +3 -3
- package/src/execution/__tests__/finalize-record.test.ts +278 -16
- package/src/execution/__tests__/gc-timer.test.ts +57 -2
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +14 -12
- package/src/execution/__tests__/get-state-handshake.test.ts +127 -0
- 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 +280 -0
- package/src/execution/__tests__/kill-all-escalation.test.ts +196 -0
- package/src/execution/__tests__/lifecycle-manager-idle-timer-identity.test.ts +117 -0
- package/src/execution/__tests__/lifecycle-manager.test.ts +39 -0
- 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 +99 -0
- package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +113 -0
- 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-ledger.test.ts +1249 -0
- package/src/execution/__tests__/output-collector.test.ts +117 -6
- package/src/execution/__tests__/pi-invocation.test.ts +1 -1
- package/src/execution/__tests__/record-store-orphan-revive.test.ts +159 -0
- package/src/execution/__tests__/record-store.test.ts +89 -5
- 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__/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 +19 -9
- package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +5 -4
- package/src/execution/__tests__/run-spawn-edges.test.ts +418 -26
- package/src/execution/__tests__/run-spawn-integration.test.ts +3 -3
- 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 +16 -8
- package/src/execution/__tests__/service-kill-escalation.test.ts +91 -0
- package/src/execution/__tests__/session-context-resolver.test.ts +0 -2
- package/src/execution/__tests__/session-file-gc.test.ts +35 -0
- package/src/execution/__tests__/session-pending.test.ts +471 -0
- package/src/execution/__tests__/session-reconstructor.test.ts +366 -15
- package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +110 -0
- package/src/execution/__tests__/session-runner-close-prune.test.ts +181 -0
- package/src/execution/__tests__/session-runner-dispatch.test.ts +489 -0
- package/src/execution/__tests__/session-runner-epipe.test.ts +4 -3
- package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +227 -0
- 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 +524 -0
- 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 +1 -1
- package/src/execution/__tests__/spawn-worktree-guidance.test.ts +5 -4
- package/src/execution/__tests__/spawned-children.test.ts +155 -11
- package/src/execution/__tests__/start-sync-model-guard.test.ts +4 -4
- 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 +1017 -0
- package/src/execution/__tests__/subagent-service-message-close.test.ts +99 -35
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +174 -0
- package/src/execution/__tests__/subagent-service-notify-gate.test.ts +271 -0
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +33 -29
- package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +341 -0
- 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__/temp-prompt.test.ts +1 -1
- package/src/execution/__tests__/timeout-integration.test.ts +13 -12
- 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 +107 -7
- package/src/execution/__tests__/ui-request-handler.test.ts +4 -3
- package/src/execution/__tests__/ui-request-queue.test.ts +167 -2
- package/src/execution/__tests__/worktree-git-ops.test.ts +571 -0
- 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 +204 -0
- package/src/execution/agent-registry.ts +298 -30
- package/src/execution/agent-result-mapper.ts +3 -0
- package/src/execution/agents-assembly.ts +88 -0
- package/src/execution/cold-resurrect.ts +199 -0
- package/src/execution/concurrency-pool.ts +71 -9
- package/src/execution/dialog-queue.ts +101 -3
- 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/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 +211 -51
- 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 +56 -99
- package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +88 -15
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +33 -7
- package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +1 -1
- package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +75 -54
- package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +128 -0
- 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 +94 -3
- 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/engine-discovery.ts +12 -16
- 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} +86 -11
- 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/engine/engines/pi/session-runner.ts +2840 -0
- 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 +301 -0
- package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +36 -0
- package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +321 -0
- package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +473 -0
- 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 +792 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +782 -0
- package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +168 -0
- 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 +65 -47
- package/src/execution/engine/engines/zcode/appserver-launcher.ts +167 -0
- package/src/execution/engine/engines/zcode/connection.ts +598 -0
- package/src/execution/engine/engines/zcode/constants.ts +147 -14
- package/src/execution/engine/engines/zcode/golden-sample.ts +42 -34
- package/src/execution/engine/engines/zcode/parser.ts +12 -346
- package/src/execution/engine/engines/zcode/preparer.ts +22 -150
- package/src/execution/engine/engines/zcode/session-channel.ts +968 -0
- package/src/execution/engine/engines/zcode/zcode-engine.ts +1023 -250
- 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 +65 -7
- package/src/execution/engine/registry.ts +53 -0
- package/src/execution/engine/routing.ts +75 -1
- package/src/execution/engine/types.ts +30 -103
- package/src/execution/execution-record.ts +222 -144
- package/src/execution/finalize-record.ts +181 -85
- package/src/execution/idle-gc.ts +28 -0
- package/src/execution/lifecycle-manager.ts +27 -3
- package/src/execution/lifecycle-predicates.ts +1 -1
- package/src/execution/manifest-store.ts +53 -62
- package/src/execution/notifier.ts +10 -10
- package/src/execution/notify-host.ts +212 -0
- package/src/execution/notify-ledger.ts +117 -16
- package/src/execution/record-entry.ts +8 -2
- package/src/execution/record-store.ts +148 -88
- package/src/execution/round-settlement.ts +93 -0
- package/src/execution/session-file-gc.ts +96 -62
- package/src/execution/session-pending.ts +213 -62
- package/src/execution/session-reconstructor.ts +256 -143
- package/src/execution/sessions-index.ts +127 -102
- package/src/execution/settled-watchdog.ts +311 -0
- package/src/execution/subagent-actions-core.ts +686 -0
- package/src/execution/subagent-service.ts +1106 -907
- package/src/execution/subprocess-agent-runner.ts +144 -97
- package/src/execution/types.ts +9 -0
- package/src/execution/ui-request-handler-factory.ts +126 -75
- package/src/execution/ui-request-queue.ts +50 -19
- package/src/execution/worktree-git-ops.ts +397 -0
- package/src/execution/worktree-manager.ts +72 -10
- package/src/execution/worktree-registry.ts +6 -12
- package/src/index.ts +542 -9
- package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +42 -3
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +3 -5
- package/src/orchestration/__tests__/agent-call-stream.test.ts +2 -2
- package/src/orchestration/__tests__/args-meta.test.ts +358 -0
- package/src/orchestration/__tests__/args-validator.test.ts +14 -0
- package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +312 -0
- package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +384 -0
- package/src/orchestration/__tests__/execute-agent-call.test.ts +151 -11
- package/src/orchestration/__tests__/file-run-store-prune.test.ts +168 -0
- package/src/orchestration/__tests__/file-run-store-throttle.test.ts +168 -0
- package/src/orchestration/__tests__/file-run-store.test.ts +390 -0
- package/src/orchestration/__tests__/helpers/flush-microtasks.ts +13 -0
- package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +34 -0
- package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +357 -0
- package/src/orchestration/__tests__/lifecycle-recover-crashed.test.ts +289 -0
- package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +3 -3
- package/src/orchestration/__tests__/lifecycle.test.ts +84 -5
- package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +1 -1
- package/src/orchestration/__tests__/run-snapshot.test.ts +356 -0
- package/src/orchestration/__tests__/script-generate.test.ts +314 -0
- package/src/orchestration/__tests__/script-lint.test.ts +17 -0
- 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} +28 -27
- 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 +275 -0
- package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +78 -1
- package/src/orchestration/__tests__/worker-script-builder.test.ts +1 -1
- package/src/orchestration/__tests__/workflow-files.test.ts +186 -0
- package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +1 -1
- package/src/orchestration/__tests__/workflow-run-summary.test.ts +119 -0
- package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +124 -0
- package/src/orchestration/agent-opts-resolver.ts +8 -8
- package/src/orchestration/args-meta.ts +198 -0
- package/src/orchestration/args-validator.ts +53 -31
- package/src/orchestration/execute-agent-call.ts +25 -79
- package/src/orchestration/file-run-store.ts +327 -0
- package/src/orchestration/launcher.ts +160 -104
- package/src/orchestration/lifecycle.ts +371 -97
- package/src/orchestration/models/agent-call.ts +7 -7
- package/src/orchestration/models/budget.ts +5 -5
- package/src/orchestration/models/ports.ts +4 -4
- package/src/orchestration/models/run-runtime.ts +15 -15
- package/src/orchestration/models/trace.ts +9 -9
- package/src/orchestration/models/types.ts +111 -22
- package/src/orchestration/models/workflow-run.ts +28 -28
- package/src/orchestration/models/workflow-script.ts +4 -4
- package/src/orchestration/run-snapshot.ts +266 -0
- package/src/orchestration/script-generate.ts +154 -0
- package/src/orchestration/script-lint.ts +123 -90
- package/src/orchestration/worker-handle.ts +10 -10
- package/src/orchestration/worker-host.ts +10 -10
- package/src/orchestration/{error-recovery.ts → worker-message-pump.ts} +498 -221
- package/src/orchestration/worker-script-builder.ts +401 -346
- package/src/orchestration/workflow-files.ts +37 -11
- package/src/orchestration/workflow-run-summary.ts +69 -0
- package/src/orchestration/workflow-script-registry-impl.ts +31 -9
- package/src/shared/__tests__/agent-ref.test.ts +209 -2
- package/src/shared/__tests__/atomic-write.test.ts +267 -0
- package/src/shared/__tests__/bounded-serialize.test.ts +236 -0
- package/src/shared/__tests__/injection-render.test.ts +518 -0
- package/src/shared/__tests__/meta-parser.test.ts +151 -0
- package/src/shared/__tests__/resource-discovery-host-roots.test.ts +474 -0
- package/src/shared/__tests__/resource-discovery.test.ts +261 -217
- package/src/shared/agent-ref.ts +143 -2
- package/src/shared/atomic-write.ts +323 -0
- package/src/shared/bounded-serialize.ts +154 -0
- package/src/shared/injection-render.ts +279 -0
- package/src/shared/meta-parser.ts +182 -68
- package/src/shared/model-ref.ts +15 -2
- package/src/shared/resource-discovery.ts +97 -204
- package/src/shared/resource-meta.ts +14 -0
- package/src/shared/schema-jsonify.ts +1 -1
- package/src/shared/xml-injection.ts +9 -9
- package/workflows/README.md +9 -9
- package/workflows/chain.js +4 -2
- package/workflows/map-reduce.js +5 -3
- package/workflows/parallel.js +5 -3
- package/workflows/review-fix-loop-utils.cjs +165 -92
- package/workflows/review-fix-loop-utils.d.cts +287 -0
- package/workflows/review-fix-loop.js +18 -7
- package/workflows/scatter-gather.js +4 -2
- package/dist/chunk-3VOERJPJ.js +0 -22
- 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__/zcode-engine.test.ts +0 -580
- package/src/execution/engine/engines/zcode/launcher.ts +0 -161
- package/src/execution/execute-options-mapper.ts +0 -115
- package/src/execution/session-runner.ts +0 -1789
- package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -288
|
@@ -5,37 +5,44 @@
|
|
|
5
5
|
// 从"自己 spawn pi"改为"委托 SubagentService.executeAndAwait"。
|
|
6
6
|
// MF-3: 从 orchestration/infra 迁入 execution,同层委托 SubagentService。
|
|
7
7
|
//
|
|
8
|
+
// [D6 任务形状合流] AgentCallOpts 已是 EnginePort.run 的单一任务形状——本类直传 opts
|
|
9
|
+
// 给 engine.run(无 ExecuteOptions/AgentTaskSpec 中间态映射);pi 边界的一次直出在
|
|
10
|
+
// PiEngine.agentCallToExecuteOptions。mergeTimeoutSignal(原 execute-options-mapper
|
|
11
|
+
// 的运行期件,D-A9)随 mapper 删除迁入本文件(唯一消费点)。
|
|
12
|
+
//
|
|
8
13
|
// 接线层级:
|
|
9
14
|
// [跨模块 port] implements AgentRunner(orchestration/models/ports.ts)
|
|
10
|
-
// [模块内直调]
|
|
11
|
-
// [P4 路由层] engine/routing.ts
|
|
15
|
+
// [模块内直调] mergeTimeoutSignal(本文件,D-A9)
|
|
16
|
+
// [P4 路由层] engine/routing.ts routeEngineForHost(D3-② 路由单点:三层优先级 +
|
|
17
|
+
// pi 同步短路 + probe + fallback 三守卫,D9)
|
|
18
|
+
// [公共预检] engine/common/capability-gate(D3-④:capabilities 驱动的调用前拒绝)
|
|
12
19
|
// [引擎层] EnginePort.run(pi = 本地 DI 绑定实例;非 pi = registry.getEngine 动态获取)
|
|
20
|
+
// [公共 journal] engine/common/journal-wiring(D3-③:writer + retarget + 回填单实现)
|
|
13
21
|
// [模块内直调] this.subagentService.executeAndAwait(PiEngine 内部委托目标)
|
|
14
22
|
//
|
|
15
23
|
// 设计基线:
|
|
16
|
-
// D-
|
|
24
|
+
// D-A8(onEvent 桥接)/ D-A9(timeoutMs 合并 signal)/
|
|
17
25
|
// D-008(model 填底,不调 resolveModel)/ BC-9(timeoutMs 行为)/ BC-10(live-record 进度)
|
|
18
26
|
|
|
19
27
|
import type { AgentRunner } from "../orchestration/models/ports.ts";
|
|
20
28
|
import type { AgentCallOpts, AgentResult } from "../orchestration/models/types.ts";
|
|
21
29
|
import type { AgentEvent } from "../shared/agent-event.ts";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { resolveJournalPath } from "./engine/paths.ts";
|
|
30
|
+
import { assertTaskShapeSupported } from "./engine/common/capability-gate.ts";
|
|
31
|
+
import { HOST_TIMEOUT_ABORT_REASON } from "./engine/common/kill-chain.ts";
|
|
32
|
+
import { JOURNAL_INITIAL_POOL_KEY, wireEventJournal } from "./engine/common/journal-wiring.ts";
|
|
33
|
+
import { createPiEngine } from "./engine/engines/pi/registration.ts";
|
|
27
34
|
import type { EnginePort, RunContext } from "./engine/port.ts";
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import
|
|
31
|
-
import {
|
|
35
|
+
import { validateModelForEngine } from "./engine/model-validation.ts";
|
|
36
|
+
import { routeEngineForHost, type EngineRouteResult, type EngineRoutingInput } from "./engine/routing.ts";
|
|
37
|
+
import { getEngine } from "./engine/registry.ts";
|
|
38
|
+
import type { AgentOutcome } from "./engine/types.ts";
|
|
32
39
|
import { getModelConfigService } from "./model-config-service.ts";
|
|
33
40
|
import type { ModelInfo } from "./model-resolver.ts";
|
|
34
41
|
import { modelRefFromVerified } from "../shared/model-ref";
|
|
35
|
-
import { registerSpawnedChildForRecord } from "./session-runner.ts";
|
|
42
|
+
import { registerSpawnedChildForRecord } from "./engine/engines/pi/session-runner.ts";
|
|
36
43
|
import type { SubagentStream } from "./stream-sink.ts";
|
|
37
44
|
import type { SubagentService } from "./subagent-service.ts";
|
|
38
|
-
import
|
|
45
|
+
import { toErrorMessage } from "../core/error-message.ts";
|
|
39
46
|
|
|
40
47
|
// ── 构造依赖(per-session 注入)──
|
|
41
48
|
|
|
@@ -71,10 +78,12 @@ export interface SubprocessAgentRunnerDeps {
|
|
|
71
78
|
* 非 pi 引擎(P4 路由可达:frontmatter/调用参数/全局默认指定)经 registry.getEngine
|
|
72
79
|
* 动态获取——「引擎身份」的归属边界在注册表,SAR 不感知具体引擎实现。
|
|
73
80
|
*
|
|
74
|
-
* [P4 配置路由] 每次运行经 engine/routing.ts
|
|
75
|
-
* agent frontmatter engine > 全局默认
|
|
76
|
-
*
|
|
77
|
-
*
|
|
81
|
+
* [P4 配置路由] 每次运行经 engine/routing.ts 的 routeEngineForHost(D3-② 路由单点:
|
|
82
|
+
* 唯一实现承载三层优先级(调用参数 opts.engine > agent frontmatter engine > 全局默认
|
|
83
|
+
* 'pi')+ pi 同步短路 + registry 注入 + probe/fallback 三守卫,D9;本类与
|
|
84
|
+
* SubagentService.execute 是其仅有的两调用点)。路由失败(engine_not_found /
|
|
85
|
+
* engine_probe_failed / model_not_available)与预检命中(engine_capability_unsupported,
|
|
86
|
+
* D3-④)不 reject,入 result.error——与 executeAgentCall 契约一致。
|
|
78
87
|
*/
|
|
79
88
|
export class SubprocessAgentRunner implements AgentRunner {
|
|
80
89
|
private readonly subagentService: SubagentService;
|
|
@@ -85,7 +94,8 @@ export class SubprocessAgentRunner implements AgentRunner {
|
|
|
85
94
|
constructor(deps: SubprocessAgentRunnerDeps) {
|
|
86
95
|
this.subagentService = deps.subagentService;
|
|
87
96
|
this.ctxModel = deps.ctxModel;
|
|
88
|
-
|
|
97
|
+
// [D4 聚合连带] 经 asEngineService 显式视图适配(原结构化直绑依赖查询面 public)。
|
|
98
|
+
this.piEngine = createPiEngine(() => this.subagentService.asEngineService);
|
|
89
99
|
}
|
|
90
100
|
|
|
91
101
|
/**
|
|
@@ -99,16 +109,21 @@ export class SubprocessAgentRunner implements AgentRunner {
|
|
|
99
109
|
}
|
|
100
110
|
|
|
101
111
|
/**
|
|
102
|
-
* 执行单次 agent 调用:路由(P4)→ EnginePort.run → PiEngine 委托
|
|
112
|
+
* 执行单次 agent 调用:路由(P4)→ 预检(D3-④)→ EnginePort.run → PiEngine 委托
|
|
103
113
|
* SubagentService.executeAndAwait。
|
|
104
114
|
*
|
|
105
115
|
* 接线链路:
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
116
|
+
* routeEngineForHost(D3-② 路由单点:三层 + pi 同步短路 + probe + 守卫)→
|
|
117
|
+
* assertTaskShapeSupported(D3-④ 预检 capabilities 化)→ mergeTimeoutSignal →
|
|
118
|
+
* engine.run(opts 直传——D6 合流:AgentCallOpts 即 EnginePort 任务形状,零映射;
|
|
119
|
+
* PiEngine 内一次直出 ExecuteOptions + engine 留痕) → executeAndAwait →
|
|
120
|
+
* AgentOutcome → AgentResult
|
|
109
121
|
*
|
|
110
122
|
* 错误处理:不 reject。
|
|
111
123
|
* - 路由失败(未注册 id / probe 失败 + 守卫或 strict)→ AgentResult.error(错误码前缀)
|
|
124
|
+
* - 预检命中(capabilities 不支持的任务形状参数)→ AgentResult.error
|
|
125
|
+
* (engine_capability_unsupported——[D3-④] workflow 域 zcode+worktree 由漏拦变
|
|
126
|
+
* 拦截,本单元唯一有意行为变化;拒绝在 journal/run 之前,无进程无 journal 产物)
|
|
112
127
|
* - executeAndAwait 内部失败 → 返回 AgentResult(success:false) → 已映射 error 字段
|
|
113
128
|
* - executeAndAwait throw(嵌套超限 BC-12)→ catch → AgentResult.error
|
|
114
129
|
* - spawn 级失败已由 runSpawn 内部收口为 failed AgentResult(不逃逸)
|
|
@@ -121,69 +136,57 @@ export class SubprocessAgentRunner implements AgentRunner {
|
|
|
121
136
|
): Promise<AgentResult> {
|
|
122
137
|
const startedAt = Date.now();
|
|
123
138
|
|
|
124
|
-
// ── P4
|
|
125
|
-
// 路由在最前——引擎身份决定 journal
|
|
126
|
-
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
let routingInput: EngineRoutingInput;
|
|
139
|
+
// ── P4 路由(D3-② 单点:routeEngineForHost)+ D3-④ 预检 ──
|
|
140
|
+
// 路由在最前——引擎身份决定 journal 路径与后续一切执行面。pi 快路径同步短路
|
|
141
|
+
//(routed 非 Promise,零微任务——缺省路径时序与 P1 接线前完全一致,下游依赖
|
|
142
|
+
// 「run 内首个 await 前已触达 executeAndAwait」的时序契约)。路由失败(未注册
|
|
143
|
+
// id / probe 失败 + strict/守卫)与预检命中(capabilities 驱动,含 worktree——
|
|
144
|
+
// workflow 域漏拦缺口修复)一并按「不 reject」契约转 result.error。
|
|
131
145
|
let route: EngineRouteResult;
|
|
132
146
|
try {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
147
|
+
const routed = routeEngineForHost({
|
|
148
|
+
routing: this.buildRoutingInput(opts),
|
|
149
|
+
taskModel: opts.model,
|
|
150
|
+
strict: getModelConfigService()?.getGlobalConfig().engineRouting?.strict === true,
|
|
151
|
+
probe: (engineId) => this.engineFor(engineId).probe(),
|
|
152
|
+
piEngine: this.piEngine,
|
|
153
|
+
});
|
|
154
|
+
route = routed instanceof Promise ? await routed : routed;
|
|
155
|
+
// [D3-④] SAR 路径预检调用点(run 前同模块调用;唯一实现 = common/capability-gate)。
|
|
156
|
+
// pi 全参数放行(V4⑤ 反向守护);zcode 拦 fork/conversation/maxTurns/worktree。
|
|
157
|
+
// [D6 合流] opts(AgentCallOpts)直传预检——TaskShapeForGate 是结构子集,
|
|
158
|
+
// conversation/fork/worktree/maxTurns 均在合流形状字段表内。
|
|
159
|
+
assertTaskShapeSupported(route.engineId, route.engine.capabilities(), opts);
|
|
160
|
+
// [u-h2 D2-2 调用点②] workflow 域非 pi 引擎的派发同步期 model 校验——与 chat
|
|
161
|
+
// 路径(subagent-service.executeViaEngine)共享同一入口 validateModelForEngine
|
|
162
|
+
// 与同一错误文案(V2-4④:agent({engine:'zcode', model:<pi id>}) 同步期报
|
|
163
|
+
// 「引擎与模型不配套」,不再落 engine.run 的 prepare 期晚炸)。校验对象是显式
|
|
164
|
+
// opts.model(frontmatter model 的解析归 pi 链,workflow 域非 pi 路径现状不消费
|
|
165
|
+
// ——维持现状语义不扩散)。「不 reject」契约:throw 由本 try 的 catch 收口
|
|
166
|
+
// errorResult,不进入 journal 创建与 engine.run(零 record/spawn 副作用)。
|
|
167
|
+
if (route.engineId !== "pi") {
|
|
168
|
+
validateModelForEngine(route.engine, opts.model);
|
|
154
169
|
}
|
|
155
170
|
} catch (err) {
|
|
156
|
-
// buildRoutingInput 的 agent 解析期校验(未注册 frontmatter engine
|
|
157
|
-
|
|
171
|
+
// buildRoutingInput 的 agent 解析期校验(未注册 frontmatter engine)、路由失败
|
|
172
|
+
//(probe + strict/守卫)与预检拒绝(engine_capability_unsupported)一并在此
|
|
173
|
+
// 收口——「不 reject」契约
|
|
158
174
|
return errorResult(err, startedAt);
|
|
159
175
|
}
|
|
160
176
|
|
|
161
177
|
// ── P2 event journal 接线(设计 D6 第②级;对齐点③:路径权威 = 引擎池 key)──
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
// RunContext.onPoolResolved 声明实际池 key →
|
|
165
|
-
//
|
|
178
|
+
// [D3-③] writer + retarget + 回填收敛 common/journal-wiring(与 chat 域同一实现):
|
|
179
|
+
// 初始 poolKey 占位 'shared'(pi 恒终值);非池化稳定引擎(zcode)在 prepare 期经
|
|
180
|
+
// RunContext.onPoolResolved 声明实际池 key → retarget——保证 journal 落盘路径与
|
|
181
|
+
// handle.poolKey 同源(handle.journalPath 由本方法 run 返回后回填)。
|
|
166
182
|
//
|
|
167
183
|
// taskId 为宿主侧任务标识(journal 文件名与池引用计数 key)——executeAndAwait
|
|
168
184
|
// 不外露内部 record id(取真实 id 需 hook record store 且改 createRecordForMode
|
|
169
185
|
// 签名,影响面大;P4 决策:保留占位,`sa-` 前缀与 record id 同构。影响面:record
|
|
170
|
-
// GC 时无法按 taskId 联动删 journal(journal 依赖
|
|
171
|
-
//
|
|
186
|
+
// GC 时无法按 taskId 联动删 journal(journal 依赖 TTL 兜底回收,见 D8 分域裁决),
|
|
187
|
+
// read ②级经 handle.journalPath 自描述定位不受影响)。
|
|
172
188
|
const taskId = `sa-${crypto.randomUUID()}`;
|
|
173
|
-
const journal =
|
|
174
|
-
path: resolveJournalPath(getEngineDataDir(), route.engineId, PI_POOL_KEY, taskId),
|
|
175
|
-
taskId,
|
|
176
|
-
engineId: route.engineId,
|
|
177
|
-
});
|
|
178
|
-
const retargetJournal = (poolKey: string): void => {
|
|
179
|
-
journal.retarget(resolveJournalPath(getEngineDataDir(), route.engineId, poolKey, taskId));
|
|
180
|
-
};
|
|
181
|
-
// 包装:先写 journal 再转发原 onEvent(原 onEvent 未传时也恒传包装版——
|
|
182
|
-
// 下游 onEvent 通道是事件生成后的纯转发,无行为分支,仅多一次入队)
|
|
183
|
-
const journalingOnEvent = (event: AgentEvent): void => {
|
|
184
|
-
journal.append(event);
|
|
185
|
-
onEvent?.(event);
|
|
186
|
-
};
|
|
189
|
+
const journal = wireEventJournal({ engineId: route.engineId, taskId, forwardEvents: onEvent });
|
|
187
190
|
|
|
188
191
|
try {
|
|
189
192
|
// ── [U1 D2] RunContext.modelRef 接入:ctxModel 继承路径的孪生守卫 ──
|
|
@@ -202,40 +205,39 @@ export class SubprocessAgentRunner implements AgentRunner {
|
|
|
202
205
|
// ── D-A9: timeoutMs 合并 signal(超时 abort 带 HOST_TIMEOUT_ABORT_REASON 标记)──
|
|
203
206
|
const mergedSignal = mergeTimeoutSignal(signal, opts.timeoutMs);
|
|
204
207
|
|
|
205
|
-
// ── D-A2 + D-008: AgentCallOpts → ExecuteOptions 映射 ──
|
|
206
|
-
const mappedOpts: ExecuteOptions = mapToExecuteOptions(opts, this.ctxModel);
|
|
207
|
-
|
|
208
208
|
// ── P1/P4 引擎接线:EnginePort.run ──
|
|
209
209
|
const runCtx: RunContext = {
|
|
210
210
|
taskId,
|
|
211
|
-
poolKey:
|
|
211
|
+
poolKey: JOURNAL_INITIAL_POOL_KEY,
|
|
212
212
|
signal: mergedSignal,
|
|
213
|
-
onEvent:
|
|
213
|
+
onEvent: journal.onEvent,
|
|
214
214
|
ctxModel: this.ctxModel,
|
|
215
215
|
...(route.engineFallback !== undefined ? { engineFallback: route.engineFallback } : {}),
|
|
216
|
-
onPoolResolved:
|
|
216
|
+
onPoolResolved: journal.onPoolResolved,
|
|
217
217
|
// [U0 D10] 终止链路径①:引擎 spawn 的子进程注册进 session-runner 的
|
|
218
218
|
// spawnedChildren 记账(dispose killAll 收割兜底对 workflow 域引擎任务生效);
|
|
219
219
|
// taskId('sa-' 前缀)即记账 key,与 chat 域 kickOffEngineRun 的 record.id 同构
|
|
220
220
|
onChildSpawned: (child) => registerSpawnedChildForRecord(taskId, child),
|
|
221
221
|
...(stream !== undefined ? { stream } : {}),
|
|
222
|
-
// 解耦形态(有 schemaEnv 无 schema
|
|
223
|
-
//
|
|
224
|
-
|
|
222
|
+
// [D6 合流] 解耦形态(有 schemaEnv 无 schema)不再经 RunContext.schemaEnv
|
|
223
|
+
// 兜底通道——schemaEnv 已在合流形状 AgentCallOpts.schemaEnv 内,pi 直出
|
|
224
|
+
// (agentCallToExecuteOptions)以「schema 派生优先、schemaEnv 兜底」取值,
|
|
225
|
+
// 与原 ctx 兜底链路逐字节等值。
|
|
225
226
|
};
|
|
226
227
|
const { handle, outcome } = await route.engine.run(
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
|
|
228
|
+
// [D6 合流] opts 直传——AgentCallOpts 即 EnginePort 任务形状(缺省路径零映射;
|
|
229
|
+
// pi 边界一次直出由 PiEngine.agentCallToExecuteOptions 承担,逐字段等值由
|
|
230
|
+
// engines/pi/__tests__/spawn-opts-direct.test.ts 对照表锁定)
|
|
231
|
+
opts,
|
|
230
232
|
runCtx,
|
|
231
233
|
);
|
|
232
234
|
// handle.journalPath 回填(§3.3.6:read ②级的自描述定位符——运行期落盘路径
|
|
233
235
|
// 权威在 writer,handle 记录最终路径供跨重启 read 消费)
|
|
234
|
-
|
|
236
|
+
journal.backfillHandle(handle);
|
|
235
237
|
return outcomeToRunnerResult(outcome);
|
|
236
238
|
} catch (err) {
|
|
237
239
|
// executeAndAwait throw(嵌套超限 ForkDepthExceededError,BC-12)或未预期异常 → 不 reject,入 error。
|
|
238
|
-
const message =
|
|
240
|
+
const message = toErrorMessage(err);
|
|
239
241
|
return {
|
|
240
242
|
content: "",
|
|
241
243
|
durationMs: Date.now() - startedAt,
|
|
@@ -252,9 +254,11 @@ export class SubprocessAgentRunner implements AgentRunner {
|
|
|
252
254
|
// ── 内部 ──
|
|
253
255
|
|
|
254
256
|
/**
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
* EngineNotFoundError
|
|
257
|
+
* 引擎获取(routeEngineForHost 的 probe 注入体):pi 走 per-session DI 绑定(mock
|
|
258
|
+
* 语义 + 生产同单例,P1 行为零变化);非 pi 经 registry.getEngine 动态获取(P4:
|
|
259
|
+
* 引擎身份归属注册表,未注册 id 抛 EngineNotFoundError——路由期已前置校验,这里
|
|
260
|
+
* 是防御性兜底)。[D3-②] get/has/list 的路由期注入已由 routeEngineForHost 内部
|
|
261
|
+
* 承载(本地 pi 恒可用口径),本方法只剩 probe 一个消费点(pi 请求同步短路恒免探)。
|
|
258
262
|
*/
|
|
259
263
|
private engineFor(engineId: string): EnginePort {
|
|
260
264
|
if (engineId === "pi") return this.piEngine;
|
|
@@ -280,21 +284,16 @@ export class SubprocessAgentRunner implements AgentRunner {
|
|
|
280
284
|
}
|
|
281
285
|
}
|
|
282
286
|
|
|
283
|
-
/**
|
|
287
|
+
/** 路由期/预检错误 → AgentResult.error(错误码前缀格式保留——engine_not_found 等)。 */
|
|
284
288
|
function errorResult(err: unknown, startedAt: number): AgentResult {
|
|
285
289
|
return {
|
|
286
290
|
content: "",
|
|
287
291
|
durationMs: Date.now() - startedAt,
|
|
288
|
-
error:
|
|
292
|
+
error: toErrorMessage(err),
|
|
289
293
|
toolCalls: [],
|
|
290
294
|
};
|
|
291
295
|
}
|
|
292
296
|
|
|
293
|
-
/** handle.journalPath 回填(一次写者:SAR 是 handle 的首个消费者)。 */
|
|
294
|
-
function backfillJournalPath(handle: EngineHandle, journalPath: string): void {
|
|
295
|
-
handle.data.journalPath = journalPath;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
297
|
/**
|
|
299
298
|
* AgentOutcome → workflow AgentResult:剥离引擎层新增字段(engineId/engineFallback/
|
|
300
299
|
* exitCode——engineFallback 经 record(pi 路径)/outcome(zcode 路径)留痕,GUI 投影
|
|
@@ -305,6 +304,9 @@ function backfillJournalPath(handle: EngineHandle, journalPath: string): void {
|
|
|
305
304
|
function outcomeToRunnerResult(outcome: AgentOutcome): AgentResult {
|
|
306
305
|
return {
|
|
307
306
|
content: outcome.content,
|
|
307
|
+
// [D5-③] 失败分诊标签透传(pi 引擎产出;zcode 不产 failureKind,缺省 =
|
|
308
|
+
// unknown = 可重试)。成功路径 undefined 不落键。
|
|
309
|
+
...(outcome.failureKind !== undefined ? { failureKind: outcome.failureKind } : {}),
|
|
308
310
|
parsedOutput: outcome.parsedOutput,
|
|
309
311
|
usage: outcome.usage,
|
|
310
312
|
durationMs: outcome.durationMs,
|
|
@@ -315,3 +317,48 @@ function outcomeToRunnerResult(outcome: AgentOutcome): AgentResult {
|
|
|
315
317
|
toolCalls: outcome.toolCalls,
|
|
316
318
|
};
|
|
317
319
|
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* D-A9: per-call timeoutMs 合并进 AbortSignal([D6 合流迁入]——原定义在已删除的
|
|
323
|
+
* execution/execute-options-mapper.ts,本类是唯一消费点,运行期件随消费方落位)。
|
|
324
|
+
*
|
|
325
|
+
* 墙钟 timeoutMs(per-call)+ 外部 signal(run 级 abort)都生效。
|
|
326
|
+
* 缺此合并则 agent({timeoutMs:5000}) 静默无效(BC-9)。
|
|
327
|
+
*
|
|
328
|
+
* @param signal 外部 signal(workflow run 级 controller.signal)
|
|
329
|
+
* @param timeoutMs per-call 墙钟超时;undefined/<=0 → 不设超时,原样返回 signal
|
|
330
|
+
* @returns 合并后的 signal(timeoutMs 或外部 signal 任一 abort 都触发)
|
|
331
|
+
*/
|
|
332
|
+
export function mergeTimeoutSignal(
|
|
333
|
+
signal: AbortSignal,
|
|
334
|
+
timeoutMs?: number,
|
|
335
|
+
): AbortSignal {
|
|
336
|
+
if (!timeoutMs || timeoutMs <= 0) {
|
|
337
|
+
return signal;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const controller = new AbortController();
|
|
341
|
+
// 超时 abort 带 reason 标记(对齐点④):引擎合成终态时判别「宿主超时」
|
|
342
|
+
// (engine_timeout 公共合成)vs「外部 cancel」(中止标记)——pi 链路不读 reason,
|
|
343
|
+
// 行为不变。外部 signal abort 不带标记(用户/编排层 cancel 语义)。
|
|
344
|
+
const timer = setTimeout(() => controller.abort(HOST_TIMEOUT_ABORT_REASON), timeoutMs);
|
|
345
|
+
timer.unref();
|
|
346
|
+
|
|
347
|
+
const onExternalAbort = (): void => controller.abort();
|
|
348
|
+
if (signal.aborted) {
|
|
349
|
+
controller.abort();
|
|
350
|
+
} else {
|
|
351
|
+
signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
controller.signal.addEventListener(
|
|
355
|
+
"abort",
|
|
356
|
+
() => {
|
|
357
|
+
clearTimeout(timer);
|
|
358
|
+
if (!signal.aborted) signal.removeEventListener("abort", onExternalAbort);
|
|
359
|
+
},
|
|
360
|
+
{ once: true },
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
return controller.signal;
|
|
364
|
+
}
|
package/src/execution/types.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import type { GuiRenderResult } from "@xyz-agent/extension-protocol";
|
|
11
11
|
|
|
12
|
+
import type { AgentFailureKind } from "../orchestration/models/types.ts";
|
|
12
13
|
import type { ModelInfo, ModelRegistryLike } from "./model-resolver.ts";
|
|
13
14
|
|
|
14
15
|
// ============================================================
|
|
@@ -318,6 +319,12 @@ export interface AgentResult {
|
|
|
318
319
|
durationMs: number;
|
|
319
320
|
success: boolean;
|
|
320
321
|
error?: string;
|
|
322
|
+
/**
|
|
323
|
+
* [D5-③] 失败分诊结构化标签(类型 SSOT 在 orchestration/models/types.ts 的
|
|
324
|
+
* AgentFailureKind——消费语义「unknown=可重试」与其文档同源)。collectResult 对
|
|
325
|
+
* 最终 error 分类后写入;缺省 = unknown(可重试)。type-only 引用零运行时依赖。
|
|
326
|
+
*/
|
|
327
|
+
failureKind?: AgentFailureKind;
|
|
321
328
|
sessionId: string;
|
|
322
329
|
toolCalls: ToolCall[];
|
|
323
330
|
usage?: AgentUsageTotal;
|
|
@@ -831,6 +838,8 @@ export interface SubagentRecord {
|
|
|
831
838
|
status: ExecutionStatus;
|
|
832
839
|
/** L2 关闭原因子枚举(仅 status="closed" 时有意义)。SP-1 新增。 */
|
|
833
840
|
closedReason?: ClosedReason;
|
|
841
|
+
/** 终态三态对外语义(U3 C-outcome)。磁盘重建源一等直读;无字段的存量兜底走 projectOutcome。 */
|
|
842
|
+
outcome?: ExecutionOutcome;
|
|
834
843
|
mode: ExecutionMode;
|
|
835
844
|
startedAt: number;
|
|
836
845
|
/** 根 Pi session ID(session 隔离过滤用)。递归链上所有层 record 同值。 */
|
|
@@ -20,7 +20,13 @@
|
|
|
20
20
|
|
|
21
21
|
import { getLogger } from "../core/logger.ts";
|
|
22
22
|
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
DialogGlobalQueue,
|
|
25
|
+
isValidDialogTimeout,
|
|
26
|
+
type UiRequest,
|
|
27
|
+
type UiRequestHandler,
|
|
28
|
+
type UiResponse,
|
|
29
|
+
} from "./dialog-queue.ts";
|
|
24
30
|
import { type HostMode, resolveHostMode } from "./host-mode.ts";
|
|
25
31
|
import type { UiChannelRegistry } from "./ui-channels.ts";
|
|
26
32
|
import { isDialogMethod } from "./ui-interaction-model.ts";
|
|
@@ -157,87 +163,132 @@ function coerceUiResponse(raw: unknown, reqId: string): UiResponse {
|
|
|
157
163
|
* input(title: string, placeholder?: string, opts?): Promise<string | undefined>
|
|
158
164
|
* editor(title: string, prefill?: string): Promise<string | undefined>
|
|
159
165
|
* 注意:SDK 是位置参数(非对象参数);返回 undefined 表示用户取消。
|
|
166
|
+
* opts 为 ExtensionUIDialogOptions(signal?/timeout?,timeout 毫秒,SDK auto-dismiss
|
|
167
|
+
* 带倒计时展示)——LC-3/T2⑦ 协同:请求方显式传 timeout 时透传给 SDK,SDK 层超时
|
|
168
|
+
* (正常路径,用户可见倒计时)先于队列级兜底 settle;队列级上界(dialog-queue,
|
|
169
|
+
* 未传挂 30min 默认)兜住 SDK timeout 未生效的形态(host 实现不完整 / channel handler
|
|
170
|
+
* 路径不经 SDK)。两层取先到,settle 恰一次由 DialogGlobalQueue 的 settled 标志保证。
|
|
171
|
+
* editor 的 SDK 签名无 opts,不透传(其上界只由队列级兜底承担)。
|
|
160
172
|
*
|
|
161
173
|
* Stage 4 风险点:TUI 下 ask_user channel 未注册时,select 会以普通列表渲染
|
|
162
174
|
* (title 可能含 marker)。channel 注册后由 createRealHandler 优先走 channel handler,
|
|
163
175
|
* 不进这里。editor 不可用/抛错时降级 cancelled + warn,不卡队列。 */
|
|
176
|
+
/** select/confirm/input 的 SDK 第三参(opts):请求方传了**合法** timeout(>0 且有限,
|
|
177
|
+
* 判定源 = dialog-queue 的 isValidDialogTimeout,与队列层上界同一权威)才透传——
|
|
178
|
+
* 未传或非法(0/负数/NaN/±Infinity)时不加第三参,参数个数与旧调用完全一致(严格
|
|
179
|
+
* additive)。非法值透传会让 SDK 收到语义反转的 opts(<=0 可能立即 auto-dismiss),
|
|
180
|
+
* 且与队列层「非法回落默认上界」的判定不一致(A2-3);不透传时数组为空,SDK 无界
|
|
181
|
+
* 由队列层默认上界(30min)兜底。
|
|
182
|
+
* 返回元组联合以支持 spread 到固定签名(TS2556)。 */
|
|
183
|
+
function sdkTimeoutArg(req: UiRequest): [] | [{ timeout: number }] {
|
|
184
|
+
return isValidDialogTimeout(req.timeout) ? [{ timeout: req.timeout }] : [];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** 各 method 的默认转发器(表驱动分发;dialog 类 await SDK,fire-and-forget 类同步调用后回 ack)。
|
|
188
|
+
* 落空(未知 method)语义留在 defaultDialogForward,与原 default 分支逐字节一致。 */
|
|
189
|
+
type DialogMethodForwarder = (req: UiRequest, ui: HostUIChannel) => Promise<UiResponse>;
|
|
190
|
+
|
|
191
|
+
async function forwardSelect(req: UiRequest, ui: HostUIChannel): Promise<UiResponse> {
|
|
192
|
+
const selected = await ui.select(req.title ?? "", req.options ?? [], ...sdkTimeoutArg(req));
|
|
193
|
+
return selected === undefined ? { cancelled: true } : { value: selected };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async function forwardConfirm(req: UiRequest, ui: HostUIChannel): Promise<UiResponse> {
|
|
197
|
+
// SDK confirm 必传 message(req.message 缺失时降级空串,不报错阻塞)
|
|
198
|
+
const confirmed = await ui.confirm(req.title ?? "", req.message ?? "", ...sdkTimeoutArg(req));
|
|
199
|
+
return { confirmed };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async function forwardInput(req: UiRequest, ui: HostUIChannel): Promise<UiResponse> {
|
|
203
|
+
const text = await ui.input(req.title ?? "", req.placeholder, ...sdkTimeoutArg(req));
|
|
204
|
+
return text === undefined ? { cancelled: true } : { value: text };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async function forwardEditor(req: UiRequest, ui: HostUIChannel): Promise<UiResponse> {
|
|
208
|
+
// SDK editor 必填,但部分 host 运行时未实现——try/catch 降级 cancelled + warn(不卡队列)。
|
|
209
|
+
// 不用 typeof 守卫:editor 在类型上必填,typeof 检查会被 TS2367 拒(条件永假)。
|
|
210
|
+
try {
|
|
211
|
+
const text = await ui.editor(req.title ?? "", req.prefill);
|
|
212
|
+
return text === undefined ? { cancelled: true } : { value: text };
|
|
213
|
+
} catch (err) {
|
|
214
|
+
logger.warn(
|
|
215
|
+
"[subagents] ctx.ui.editor unavailable/threw, returning cancelled",
|
|
216
|
+
{ detail: { id: req.id, error: err instanceof Error ? err.message : String(err) } },
|
|
217
|
+
);
|
|
218
|
+
return { cancelled: true };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ── fire-and-forget 类(§3.2 映射表:GUI 模式下由 createUiRequestHandlerForMode 直接转发)
|
|
223
|
+
// 子进程 rpc-mode 发出的 fire-and-forget method,channel miss 后落到此处。
|
|
224
|
+
// 全部回 {ack:true}(fire-and-forget 语义:子进程不等响应)。
|
|
225
|
+
|
|
226
|
+
async function forwardNotify(req: UiRequest, ui: HostUIChannel): Promise<UiResponse> {
|
|
227
|
+
// notifyType 运行时收窄:UiRequest.notifyType 是宽 string,ctx.ui.notify 要字面量联合。
|
|
228
|
+
// 非法值 fallback "info"(pi 侧也会静默降级 info,此处显式 fallback 避免类型不安全)。
|
|
229
|
+
const rawType = req.notifyType;
|
|
230
|
+
const notifyType = rawType === "info" || rawType === "warning" || rawType === "error"
|
|
231
|
+
? rawType
|
|
232
|
+
: "info";
|
|
233
|
+
ui.notify(req.message ?? "", notifyType);
|
|
234
|
+
return { ack: true };
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async function forwardSetStatus(req: UiRequest, ui: HostUIChannel): Promise<UiResponse> {
|
|
238
|
+
ui.setStatus(req.statusKey ?? "", req.statusText);
|
|
239
|
+
return { ack: true };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async function forwardSetWidget(req: UiRequest, ui: HostUIChannel): Promise<UiResponse> {
|
|
243
|
+
// setWidget channel-miss 语义(§3.2 D1):
|
|
244
|
+
// req.channel === "gui_widget"(带 marker 但 channel 未注册)→ 不转发(marker 行无渲染意义)
|
|
245
|
+
// req.channel === undefined(普通 widget)→ 转发文本行到主 agent
|
|
246
|
+
// channel 命中 registry 时由 createRealHandler 优先走 channel handler,不进这里。
|
|
247
|
+
if (req.channel === "gui_widget") {
|
|
248
|
+
return { ack: true };
|
|
249
|
+
}
|
|
250
|
+
ui.setWidget(req.widgetKey ?? "", req.widgetLines, { placement: req.widgetPlacement });
|
|
251
|
+
return { ack: true };
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async function forwardSetTitle(req: UiRequest, ui: HostUIChannel): Promise<UiResponse> {
|
|
255
|
+
ui.setTitle(req.title ?? "");
|
|
256
|
+
return { ack: true };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async function forwardSetEditorText(req: UiRequest, ui: HostUIChannel): Promise<UiResponse> {
|
|
260
|
+
ui.setEditorText(req.text ?? "");
|
|
261
|
+
return { ack: true };
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** method → 转发器路由表(key 与原 switch case 标签一一对应;值可选表达落空语义)。 */
|
|
265
|
+
const DIALOG_METHOD_FORWARDERS: Readonly<
|
|
266
|
+
Record<string, DialogMethodForwarder | undefined>
|
|
267
|
+
> = {
|
|
268
|
+
select: forwardSelect,
|
|
269
|
+
confirm: forwardConfirm,
|
|
270
|
+
input: forwardInput,
|
|
271
|
+
editor: forwardEditor,
|
|
272
|
+
notify: forwardNotify,
|
|
273
|
+
setStatus: forwardSetStatus,
|
|
274
|
+
setWidget: forwardSetWidget,
|
|
275
|
+
setTitle: forwardSetTitle,
|
|
276
|
+
set_editor_text: forwardSetEditorText,
|
|
277
|
+
};
|
|
278
|
+
|
|
164
279
|
async function defaultDialogForward(
|
|
165
280
|
req: UiRequest,
|
|
166
281
|
ctx: HostUIContext,
|
|
167
282
|
): Promise<UiResponse> {
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return { confirmed };
|
|
178
|
-
}
|
|
179
|
-
case "input": {
|
|
180
|
-
const text = await ui.input(req.title ?? "", req.placeholder);
|
|
181
|
-
return text === undefined ? { cancelled: true } : { value: text };
|
|
182
|
-
}
|
|
183
|
-
case "editor": {
|
|
184
|
-
// SDK editor 必填,但部分 host 运行时未实现——try/catch 降级 cancelled + warn(不卡队列)。
|
|
185
|
-
// 不用 typeof 守卫:editor 在类型上必填,typeof 检查会被 TS2367 拒(条件永假)。
|
|
186
|
-
try {
|
|
187
|
-
const text = await ui.editor(req.title ?? "", req.prefill);
|
|
188
|
-
return text === undefined ? { cancelled: true } : { value: text };
|
|
189
|
-
} catch (err) {
|
|
190
|
-
logger.warn(
|
|
191
|
-
"[subagents] ctx.ui.editor unavailable/threw, returning cancelled",
|
|
192
|
-
{ detail: { id: req.id, error: err instanceof Error ? err.message : String(err) } },
|
|
193
|
-
);
|
|
194
|
-
return { cancelled: true };
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
// ── fire-and-forget 类(§3.2 映射表:GUI 模式下由 createUiRequestHandlerForMode 直接转发)
|
|
198
|
-
// 子进程 rpc-mode 发出的 fire-and-forget method,channel miss 后落到此处。
|
|
199
|
-
// 全部回 {ack:true}(fire-and-forget 语义:子进程不等响应)。
|
|
200
|
-
case "notify": {
|
|
201
|
-
// notifyType 运行时收窄:UiRequest.notifyType 是宽 string,ctx.ui.notify 要字面量联合。
|
|
202
|
-
// 非法值 fallback "info"(pi 侧也会静默降级 info,此处显式 fallback 避免类型不安全)。
|
|
203
|
-
const rawType = req.notifyType;
|
|
204
|
-
const notifyType = rawType === "info" || rawType === "warning" || rawType === "error"
|
|
205
|
-
? rawType
|
|
206
|
-
: "info";
|
|
207
|
-
ui.notify(req.message ?? "", notifyType);
|
|
208
|
-
return { ack: true };
|
|
209
|
-
}
|
|
210
|
-
case "setStatus": {
|
|
211
|
-
ui.setStatus(req.statusKey ?? "", req.statusText);
|
|
212
|
-
return { ack: true };
|
|
213
|
-
}
|
|
214
|
-
case "setWidget": {
|
|
215
|
-
// setWidget channel-miss 语义(§3.2 D1):
|
|
216
|
-
// req.channel === "gui_widget"(带 marker 但 channel 未注册)→ 不转发(marker 行无渲染意义)
|
|
217
|
-
// req.channel === undefined(普通 widget)→ 转发文本行到主 agent
|
|
218
|
-
// channel 命中 registry 时由 createRealHandler 优先走 channel handler,不进这里。
|
|
219
|
-
if (req.channel === "gui_widget") {
|
|
220
|
-
return { ack: true };
|
|
221
|
-
}
|
|
222
|
-
ui.setWidget(req.widgetKey ?? "", req.widgetLines, { placement: req.widgetPlacement });
|
|
223
|
-
return { ack: true };
|
|
224
|
-
}
|
|
225
|
-
case "setTitle": {
|
|
226
|
-
ui.setTitle(req.title ?? "");
|
|
227
|
-
return { ack: true };
|
|
228
|
-
}
|
|
229
|
-
case "set_editor_text": {
|
|
230
|
-
ui.setEditorText(req.text ?? "");
|
|
231
|
-
return { ack: true };
|
|
232
|
-
}
|
|
233
|
-
default: {
|
|
234
|
-
// 未知 method(非 dialog 非 fire-and-forget)——保留 warn(协议演进信号,P3 限流兜底),
|
|
235
|
-
// 回 ack(落到 default 的一定不是 dialog,fire-and-forget 正确应答是 ack,与 TUI 分支先例一致)。
|
|
236
|
-
logger.warn(
|
|
237
|
-
"[subagents] defaultDialogForward: unknown method",
|
|
238
|
-
{ detail: { method: req.method, id: req.id } },
|
|
239
|
-
);
|
|
240
|
-
return { ack: true };
|
|
241
|
-
}
|
|
283
|
+
const forwarder = DIALOG_METHOD_FORWARDERS[req.method];
|
|
284
|
+
if (!forwarder) {
|
|
285
|
+
// 未知 method(非 dialog 非 fire-and-forget)——保留 warn(协议演进信号,P3 限流兜底),
|
|
286
|
+
// 回 ack(落到 default 的一定不是 dialog,fire-and-forget 正确应答是 ack,与 TUI 分支先例一致)。
|
|
287
|
+
logger.warn(
|
|
288
|
+
"[subagents] defaultDialogForward: unknown method",
|
|
289
|
+
{ detail: { method: req.method, id: req.id } },
|
|
290
|
+
);
|
|
291
|
+
return { ack: true };
|
|
242
292
|
}
|
|
293
|
+
return forwarder(req, ctx.ui);
|
|
243
294
|
}
|