@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
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* agent ref 处理(systemPrompt/model/thinkingLevel)已移交 resolveIdentity(execution 层,
|
|
11
11
|
* 经 getAgentConfig + resolveModel 完整覆盖),消除双重注入与 model 层级混乱。
|
|
12
12
|
*
|
|
13
|
-
* 调用方:engine/
|
|
13
|
+
* 调用方:engine/worker-message-pump.ts dispatchAgentCall(每次 agent-call 消息)。
|
|
14
14
|
* - skill → resolveSkillPath → skillPath(--skill)
|
|
15
15
|
* - schema → 结构化输出指令内容直传 appendSystemPrompt(--append-system-prompt)+ schemaEnv(PI_WORKFLOW_SCHEMA)
|
|
16
16
|
*
|
|
@@ -58,6 +58,57 @@ function formatMessage(name: string, errors: readonly unknown[]): string {
|
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
// ── validateRunArgs 阶段 helper(按 预处理/编译 提取,主函数只留编排) ────
|
|
62
|
+
|
|
63
|
+
/** schema.properties 提取(畸形/缺失 → {},null-scan 在空 properties 上安全退化)。 */
|
|
64
|
+
function extractSchemaProperties(schema: Record<string, unknown>): Record<string, unknown> {
|
|
65
|
+
return schema.properties !== null && typeof schema.properties === "object"
|
|
66
|
+
? (schema.properties as Record<string, unknown>)
|
|
67
|
+
: {};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** 单个 property 声明是否 nullable(type 含 "null" 或 type === "null")。 */
|
|
71
|
+
function isNullableProp(prop: unknown): boolean {
|
|
72
|
+
if (prop === null || typeof prop !== "object") return false;
|
|
73
|
+
const propType = (prop as Record<string, unknown>).type;
|
|
74
|
+
return Array.isArray(propType)
|
|
75
|
+
? (propType as unknown[]).includes("null")
|
|
76
|
+
: propType === "null";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* null-scan:null 值视为缺失(coerceTypes 会把 null→"" 放行 required,绕过 fail-fast)。
|
|
81
|
+
* 只删 schema 未声明 nullable 的键——type 含 "null"(如 ["string","null"])的合法 null
|
|
82
|
+
* 输入保留(m3 exec-review M1 探针实证:全键删除会拒掉 nullable required 的合法值)。
|
|
83
|
+
*/
|
|
84
|
+
function deleteNonNullableNullArgs(
|
|
85
|
+
args: Record<string, unknown>,
|
|
86
|
+
schema: Record<string, unknown>,
|
|
87
|
+
): void {
|
|
88
|
+
const properties = extractSchemaProperties(schema);
|
|
89
|
+
for (const key of Object.keys(args)) {
|
|
90
|
+
if (args[key] !== null) continue;
|
|
91
|
+
if (!isNullableProp(properties[key])) delete args[key];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** ajv 编译(畸形 schema → 结构化 ArgsValidationError,不泄漏原始 throw)。 */
|
|
96
|
+
function compileSchema(
|
|
97
|
+
parameters: Record<string, unknown>,
|
|
98
|
+
scriptName: string,
|
|
99
|
+
): ReturnType<Ajv["compile"]> {
|
|
100
|
+
try {
|
|
101
|
+
return ajv.compile(parameters);
|
|
102
|
+
} catch (err) {
|
|
103
|
+
// 真畸形 schema(如 type:'not-a-type')→ 结构化 ArgsValidationError,不泄漏原始 throw
|
|
104
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
105
|
+
throw new ArgsValidationError(
|
|
106
|
+
scriptName,
|
|
107
|
+
`Workflow '${scriptName}' has an invalid parameter schema: ${detail}. Read the workflow script file (location from <available_workflows>) to inspect it.`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
61
112
|
/**
|
|
62
113
|
* 校验 spec.parameters(JSON Schema draft-07)对 spec.args 的约束。
|
|
63
114
|
*
|
|
@@ -79,38 +130,9 @@ export function validateRunArgs(spec: RunSpec): void {
|
|
|
79
130
|
);
|
|
80
131
|
}
|
|
81
132
|
|
|
82
|
-
|
|
83
|
-
// 只删 schema 未声明 nullable 的键——type 含 "null"(如 ["string","null"])的合法 null
|
|
84
|
-
// 输入保留(m3 exec-review M1 探针实证:全键删除会拒掉 nullable required 的合法值)。
|
|
85
|
-
const schema = parameters as Record<string, unknown>;
|
|
86
|
-
const properties =
|
|
87
|
-
schema.properties !== null && typeof schema.properties === "object"
|
|
88
|
-
? (schema.properties as Record<string, unknown>)
|
|
89
|
-
: {};
|
|
90
|
-
for (const key of Object.keys(args)) {
|
|
91
|
-
if (args[key] !== null) continue;
|
|
92
|
-
const prop = properties[key];
|
|
93
|
-
let isNullable = false;
|
|
94
|
-
if (prop !== null && typeof prop === "object") {
|
|
95
|
-
const propType = (prop as Record<string, unknown>).type;
|
|
96
|
-
isNullable = Array.isArray(propType)
|
|
97
|
-
? (propType as unknown[]).includes("null")
|
|
98
|
-
: propType === "null";
|
|
99
|
-
}
|
|
100
|
-
if (!isNullable) delete args[key];
|
|
101
|
-
}
|
|
133
|
+
deleteNonNullableNullArgs(args, parameters);
|
|
102
134
|
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
validate = ajv.compile(parameters);
|
|
106
|
-
} catch (err) {
|
|
107
|
-
// 真畸形 schema(如 type:'not-a-type')→ 结构化 ArgsValidationError,不泄漏原始 throw
|
|
108
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
109
|
-
throw new ArgsValidationError(
|
|
110
|
-
scriptName,
|
|
111
|
-
`Workflow '${scriptName}' has an invalid parameter schema: ${detail}. Read the workflow script file (location from <available_workflows>) to inspect it.`,
|
|
112
|
-
);
|
|
113
|
-
}
|
|
135
|
+
const validate = compileSchema(parameters, scriptName);
|
|
114
136
|
|
|
115
137
|
if (!validate(args)) {
|
|
116
138
|
throw new ArgsValidationError(
|
|
@@ -8,16 +8,23 @@
|
|
|
8
8
|
* 职责:
|
|
9
9
|
* - 重试:3 次 + 指数退避(BACKOFF_MS = [1000, 2000, 4000])
|
|
10
10
|
* - 预算:超限不重试(直接 markDone failed)
|
|
11
|
-
* - stale-context
|
|
12
|
-
* - [MF-1] 确定性 schema
|
|
11
|
+
* - stale-context(result.failureKind="stale_context"):不重试(直接 markDone failed)
|
|
12
|
+
* - [MF-1] 确定性 schema 失败(result.failureKind="schema_deterministic"):不重试
|
|
13
|
+
* (直接 markDone failed)
|
|
13
14
|
* - 成功:consume usage + incrementCallCount + markDone + trace.update(completed)
|
|
14
15
|
*
|
|
16
|
+
* [D5-③ 结构化分诊] 失败分诊读 AgentResult.failureKind 字段(产出侧唯一识别点 =
|
|
17
|
+
* execution/engine/engines/pi/output-collector.ts 的 classifyFailureKind,词表归属
|
|
18
|
+
* 见其文件头)。本模块不再扫 error 文案子串——**语义守恒(r1 MF4)**:unknown
|
|
19
|
+
* (含字段缺省)= 可重试,保持收敛前的默认重试语义;仅 stale_context(不重试、
|
|
20
|
+
* 换参重发场景由调用方编排)与 schema_deterministic 维持特判。
|
|
21
|
+
*
|
|
15
22
|
* 关键设计:
|
|
16
23
|
* - **usage 透传**:result.usage 直接交给 budget.consume,加权由 Budget 内部的权重常量
|
|
17
|
-
*
|
|
24
|
+
* 处理(见 budget.ts)。此函数不再做 usage 形状的改写。
|
|
18
25
|
* - **参数显式化**:runner 直接传入(而非 ctx.getRun(runId).pool),无 runId 查找 / pool 守卫。
|
|
19
26
|
* - **stale-state 检查**:signal.aborted 时早返回。WorkflowRun 状态由调用方 lifecycle
|
|
20
|
-
*
|
|
27
|
+
* 持有,executeAgentCall 只关心单次 call 生命周期。
|
|
21
28
|
*
|
|
22
29
|
* 层归属:Engine。零 infra 依赖(runner 是 AgentRunner port,budget/trace/call 是 Engine 模型)。
|
|
23
30
|
*
|
|
@@ -41,69 +48,6 @@ const BACKOFF_EXPONENT_BASE = 2;
|
|
|
41
48
|
/** 最大尝试次数(含首次):initial + 2 retries = 3。 */
|
|
42
49
|
const MAX_ATTEMPTS = 3;
|
|
43
50
|
|
|
44
|
-
/**
|
|
45
|
-
* Stale context 检测模式(P1-5;W4b 对齐 pi 0.84.x 真实文案)。
|
|
46
|
-
*
|
|
47
|
-
* pi session context 被 compact/cancel 时报告的模式。这种情况下重试无意义——
|
|
48
|
-
* 同样的 call 会再次失败。直接 markDone failed 终止单次调用。
|
|
49
|
-
*
|
|
50
|
-
* W4b:原 "stale context"/"stalecontext" 与 pi 真实文案零匹配(真实文案为
|
|
51
|
-
* "This extension ctx is stale after session replacement or reload. ..."——
|
|
52
|
-
* runner.ts:544(dist runner.js:352),词序是 "ctx is stale" 而非 "stale context"),stale 分诊对
|
|
53
|
-
* 真实文案失效。现对齐:
|
|
54
|
-
* - "ctx is stale":真实文案核心子串(词序修正)
|
|
55
|
-
* - "stale after session replacement":scheduler 已验证 marker(runtime.ts
|
|
56
|
-
* STALE_CTX_MARKER,同文案锚定)
|
|
57
|
-
* - "context canceled"/"aborted":保留——abort 族错误同样不重试(signal.aborted
|
|
58
|
-
* 分支的先行分诊,防边界竞态漏网),删除会放宽重试语义。
|
|
59
|
-
*/
|
|
60
|
-
export const STALE_CONTEXT_PATTERNS = [
|
|
61
|
-
"ctx is stale",
|
|
62
|
-
"stale after session replacement",
|
|
63
|
-
"context canceled",
|
|
64
|
-
"aborted",
|
|
65
|
-
] as const;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* 判断错误信息是否表示 stale/canceled pi session context。
|
|
69
|
-
* 命中时不重试——重试只会再次失败(P1-5)。
|
|
70
|
-
*/
|
|
71
|
-
export function isStaleContextErrorMsg(msg: string | undefined): boolean {
|
|
72
|
-
if (!msg) return false;
|
|
73
|
-
const lower = msg.toLowerCase();
|
|
74
|
-
return STALE_CONTEXT_PATTERNS.some((p) => lower.includes(p));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* [MF-1] 确定性 schema 失败标记(error 文本前缀,产出方 = output-collector 的
|
|
79
|
-
* describeMissingParsedOutput)。
|
|
80
|
-
*
|
|
81
|
-
* 标记 SSOT 放本模块(与 STALE_CONTEXT_PATTERNS 同布局:orchestration 持表、
|
|
82
|
-
* execution 值引用;反向引用会形成 execute-agent-call → output-collector →
|
|
83
|
-
* execute-agent-call 运行时循环)。
|
|
84
|
-
*
|
|
85
|
-
* 标记词逐字核对不命中 STALE_CONTEXT_PATTERNS 任一 pattern 与
|
|
86
|
-
* isStaleContextErrorMsg 的子串匹配(否则归因 error 被误诊 stale-context,
|
|
87
|
-
* 虽然同样不重试但归因语义被污染;output-collector.test 有交叉锁定)。
|
|
88
|
-
*
|
|
89
|
-
* 三态可重试性矩阵(F-1 归因):
|
|
90
|
-
* | 归因态 | 带本标记 | 可重试性 | 理由 |
|
|
91
|
-
* |----------------------------|---------|---------|------|
|
|
92
|
-
* | ① 从未调用 SO tool | 是 | 不可重试 | 缺 extension 是环境确定性(C1 安装盲区),同环境重试必同结果 |
|
|
93
|
-
* | ② SO 调用 isError(gate 终止/不可满足 schema) | 是 | 不可重试 | 同 schema 重试必同结果(第五轮实测:3 attempts/4 子进程/235s 纯烧钱) |
|
|
94
|
-
* | ③ 调用过但无 details | 否 | 可重试 | 可能瞬态(details 提取/序列化异常),保留既有重试语义 |
|
|
95
|
-
*/
|
|
96
|
-
export const DETERMINISTIC_SCHEMA_FAILURE_PREFIX = "Structured output failed deterministically:";
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* [MF-1] 判断错误信息是否为确定性 schema 失败(命中标记前缀)。
|
|
100
|
-
* 命中时不重试——同 schema 重试必同结果(矩阵见 DETERMINISTIC_SCHEMA_FAILURE_PREFIX)。
|
|
101
|
-
*/
|
|
102
|
-
export function isDeterministicSchemaFailureMsg(msg: string | undefined): boolean {
|
|
103
|
-
if (!msg) return false;
|
|
104
|
-
return msg.includes(DETERMINISTIC_SCHEMA_FAILURE_PREFIX);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
51
|
// ── 内部 helper ──────────────────────────────────────────────
|
|
108
52
|
|
|
109
53
|
/**
|
|
@@ -124,7 +68,7 @@ function backoffDelay(retryIndex: number): number {
|
|
|
124
68
|
* rebuild 竞态窗口中,重跑 dispatch 已 append 同 stepIndex 新节点,旧代际
|
|
125
69
|
* finalize 的 update 会命中新节点,TUI/中间快照短暂可见错误终态。正确性论证:
|
|
126
70
|
* 运行期 calls Map 写点仅 discardInFlightCalls 的 delete 与 dispatchAgentCall 的
|
|
127
|
-
* set 两族(
|
|
71
|
+
* set 两族(worker-message-pump.ts isOrphanedCall 文档注释既定),故实例不等 ⟺ 本
|
|
128
72
|
* finalize 属于被丢弃/被替换的旧代际——与 dispatch 层 .then/.catch 守卫
|
|
129
73
|
* (S7-second 修复,8353f6b60)同一判定语义,本守卫只是把它前移到 trace.update
|
|
130
74
|
* 之前。markDone 与 sessionId/sessionFile 同步保留(markDone 在孤儿实例上无害,
|
|
@@ -208,16 +152,18 @@ export async function executeAgentCall(
|
|
|
208
152
|
budget.consume(result.usage);
|
|
209
153
|
}
|
|
210
154
|
|
|
211
|
-
// stale-context
|
|
212
|
-
|
|
155
|
+
// stale-context(D5-③ 结构化分诊:读 failureKind 字段,词表识别在产出侧
|
|
156
|
+
// output-collector):不重试(P1-5)
|
|
157
|
+
if (result.error !== undefined && result.failureKind === "stale_context") {
|
|
213
158
|
finalizeCall(call, result, trace, isOrphaned);
|
|
214
159
|
budget.incrementCallCount();
|
|
215
160
|
return;
|
|
216
161
|
}
|
|
217
162
|
|
|
218
|
-
// [MF-1] 确定性 schema
|
|
219
|
-
//
|
|
220
|
-
|
|
163
|
+
// [MF-1] 确定性 schema 失败(failureKind="schema_deterministic"):不重试
|
|
164
|
+
// (gate 终止/不可满足 schema 同 schema 重试必同结果——重试纯烧钱;三态矩阵
|
|
165
|
+
// 见产出侧 output-collector 的确定性失败标记注释)
|
|
166
|
+
if (result.error !== undefined && result.failureKind === "schema_deterministic") {
|
|
221
167
|
finalizeCall(call, result, trace, isOrphaned);
|
|
222
168
|
budget.incrementCallCount();
|
|
223
169
|
return;
|
|
@@ -31,7 +31,9 @@ import type { LifecycleDeps } from "./models/ports.ts";
|
|
|
31
31
|
import type { RunSpec } from "./models/run-spec.ts";
|
|
32
32
|
import type { DoneReason } from "./models/types.ts";
|
|
33
33
|
import type { WorkflowRun } from "./models/workflow-run.ts";
|
|
34
|
+
import type { WorkflowScript } from "./models/workflow-script.ts";
|
|
34
35
|
import type { WorkflowScriptRegistry } from "./models/workflow-script-registry.ts";
|
|
36
|
+
import type { LintResult } from "./script-lint.ts";
|
|
35
37
|
import { assertSafeTimerDelay } from "../shared/timer-delay.ts";
|
|
36
38
|
|
|
37
39
|
// ── 常量 ─────────────────────────────────────────────────────
|
|
@@ -106,6 +108,14 @@ function pollInterval(): Promise<void> {
|
|
|
106
108
|
});
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
/** lint findings 摘要串(runAndWait / executeNestedWorkflow 共用同一错误文案格式)。 */
|
|
112
|
+
function formatLintErrorSummary(lintResult: LintResult): string {
|
|
113
|
+
return lintResult.findings
|
|
114
|
+
.filter((f) => f.severity === "error")
|
|
115
|
+
.map((f) => `L${f.line}: ${f.message}`)
|
|
116
|
+
.join("; ");
|
|
117
|
+
}
|
|
118
|
+
|
|
109
119
|
/**
|
|
110
120
|
* 从 WorkflowRun 构建 WorkflowRunResult(D-8)。
|
|
111
121
|
*
|
|
@@ -243,11 +253,9 @@ export async function runAndWait(
|
|
|
243
253
|
// 2. lint 校验(失败抛错——脚本本身有问题,不应静默吞)
|
|
244
254
|
const lintResult = script.validate();
|
|
245
255
|
if (!lintResult.valid) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
.join("; ");
|
|
250
|
-
throw new Error(`Workflow script '${name}' has lint errors: ${errors}`);
|
|
256
|
+
throw new Error(
|
|
257
|
+
`Workflow script '${name}' has lint errors: ${formatLintErrorSummary(lintResult)}`,
|
|
258
|
+
);
|
|
251
259
|
}
|
|
252
260
|
|
|
253
261
|
// 3. 构建 RunSpec
|
|
@@ -312,19 +320,118 @@ async function safeAbort(
|
|
|
312
320
|
|
|
313
321
|
// ── executeNestedWorkflow(workflow() 嵌套调用实现) ────────
|
|
314
322
|
|
|
323
|
+
/** 父 run 的循环检测链:[...parentChain, parentScriptName](顶层 run 无 chain 时前段为空)。 */
|
|
324
|
+
function buildParentChain(parentRun: WorkflowRun): string[] {
|
|
325
|
+
return [...(parentRun.spec.parentWorkflowChain ?? []), parentRun.spec.scriptName];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** Step 2 的 signal 继承产物(childController + 父 signal/回调——finally 移除 listener 用)。 */
|
|
329
|
+
interface InheritedSignal {
|
|
330
|
+
childController: AbortController;
|
|
331
|
+
parentSignal: AbortSignal | undefined;
|
|
332
|
+
onParentAbort: () => void;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Step 2: signal 继承——子 run 响应父 run abort(parentController → childController)。
|
|
337
|
+
*
|
|
338
|
+
* [L-2] onParentAbort 提取为命名函数以便 finally removeEventListener,防子 run 完成后
|
|
339
|
+
* parentSignal 上残留 listener(多次嵌套调用会累积)。
|
|
340
|
+
*/
|
|
341
|
+
function inheritParentSignal(parentRun: WorkflowRun): InheritedSignal {
|
|
342
|
+
const childController = new AbortController();
|
|
343
|
+
const parentSignal = parentRun.runtime?.controller.signal;
|
|
344
|
+
const onParentAbort = (): void => childController.abort();
|
|
345
|
+
if (parentSignal) {
|
|
346
|
+
if (parentSignal.aborted) {
|
|
347
|
+
childController.abort();
|
|
348
|
+
} else {
|
|
349
|
+
parentSignal.addEventListener("abort", onParentAbort, { once: true });
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return { childController, parentSignal, onParentAbort };
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Step 4: 构建 RunSpec(共享父 Budget + 循环链)。
|
|
357
|
+
*
|
|
358
|
+
* budget 共享(F-7 方案 B):子 run 直接复用父 Budget 引用(budgetRef),consume 实时
|
|
359
|
+
* 累加到父 Budget,消除并行嵌套下的超支窗口,无需 sync-back。
|
|
360
|
+
*/
|
|
361
|
+
function buildNestedSpec(
|
|
362
|
+
args: Record<string, unknown>,
|
|
363
|
+
parentRun: WorkflowRun,
|
|
364
|
+
script: WorkflowScript,
|
|
365
|
+
chain: string[],
|
|
366
|
+
): RunSpec {
|
|
367
|
+
return {
|
|
368
|
+
scriptSource: script.toExecutable(),
|
|
369
|
+
args,
|
|
370
|
+
budgetRef: parentRun.state.budget,
|
|
371
|
+
// Run-level override 传播(与父 run 对齐):子 run 继承父 run 的 model/thinkingLevel,
|
|
372
|
+
// 否则嵌套 workflow 丢失父 run 的模型指定,回落主 agent 模型。
|
|
373
|
+
model: parentRun.spec.model,
|
|
374
|
+
thinkingLevel: parentRun.spec.thinkingLevel,
|
|
375
|
+
scriptName: script.name,
|
|
376
|
+
scriptPath: script.path,
|
|
377
|
+
description: script.meta.description,
|
|
378
|
+
parameters: script.meta.parameters,
|
|
379
|
+
parentWorkflowChain: chain,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* 嵌套 workflow timeout 从父 run 完整传导:父 spec.budgetTimeMs 显式设定时原样作为子 run
|
|
385
|
+
* 轮询 deadline(不 min(DEFAULT) 封顶——旧实现把父 time:2h 截断到 10min,违背「显式传参
|
|
386
|
+
* 完整生效」语义);父未设 → undefined,无 deadline(不限)。
|
|
387
|
+
* [U2] 预算语义统一:父 budgetTimeMs <=0(含 0/负)与 undefined 同义 = 不限——与
|
|
388
|
+
* lifecycle.runWorkflow 的 budgetTimeMs 判定(>0 才挂 scheduleTimeBudget)对齐。
|
|
389
|
+
*/
|
|
390
|
+
function resolveNestedTimeoutMs(parentRun: WorkflowRun): number | undefined {
|
|
391
|
+
const raw = parentRun.spec.budgetTimeMs;
|
|
392
|
+
return raw !== undefined && raw > 0 ? raw : undefined;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Step 6: 结果转换(budget 已通过共享 budgetRef 实时同步,无需 sync-back)。
|
|
397
|
+
* completed → content = 字符串原样 / 其余 JSON.stringify;非 completed → error result。
|
|
398
|
+
*/
|
|
399
|
+
function toNestedCallResult(
|
|
400
|
+
name: string,
|
|
401
|
+
result: WorkflowRunResult,
|
|
402
|
+
): { content: string; parsedOutput?: unknown; error?: string } {
|
|
403
|
+
if (result.reason === "completed") {
|
|
404
|
+
const scriptResult = result.scriptResult;
|
|
405
|
+
return {
|
|
406
|
+
content:
|
|
407
|
+
typeof scriptResult === "string"
|
|
408
|
+
? scriptResult
|
|
409
|
+
: JSON.stringify(scriptResult ?? ""),
|
|
410
|
+
parsedOutput:
|
|
411
|
+
typeof scriptResult === "object" && scriptResult !== null
|
|
412
|
+
? scriptResult
|
|
413
|
+
: undefined,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
return {
|
|
417
|
+
content: "",
|
|
418
|
+
error: result.error ?? `Workflow '${name}' ended: ${result.reason}`,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
|
|
315
422
|
/**
|
|
316
423
|
* workflow() 嵌套调用的 Engine 实现。
|
|
317
424
|
*
|
|
318
|
-
* Worker 脚本内调 workflow(name, args) 时,
|
|
425
|
+
* Worker 脚本内调 workflow(name, args) 时,worker-message-pump.dispatchWorkflowCall 路由
|
|
319
426
|
* 到 deps.onWorkflowCall,后者(Interface 层 makeDeps 注入)委托本函数。
|
|
320
427
|
*
|
|
321
|
-
* 流程(6
|
|
428
|
+
* 流程(6 步,Step 2-6 的机制细节见各 helper):
|
|
322
429
|
* 1. 循环检测——name 已在 parentWorkflowChain 中则拒绝(防 A→B→A 死循环)
|
|
323
|
-
* 2. signal 继承——子 run 响应父 run abort(
|
|
430
|
+
* 2. signal 继承——子 run 响应父 run abort(inheritParentSignal)
|
|
324
431
|
* 3. registry.get + lint——失败返回 error result(不抛错,让脚本 soft-fail)
|
|
325
432
|
* 4. 构建 RunSpec(共享父 Budget 引用 + parentWorkflowChain 延长)+ runWorkflow
|
|
326
433
|
* 5. pollRunToResult 轮询至 done(复用 runAndWait 的轮询逻辑)
|
|
327
|
-
* 6. 结果转换(
|
|
434
|
+
* 6. 结果转换(toNestedCallResult)
|
|
328
435
|
*
|
|
329
436
|
* 不走 runAndWait:runAndWait 内部构建 RunSpec 不支持 parentWorkflowChain 与 budget
|
|
330
437
|
* 共享引用,故直接构建 spec + runWorkflow + pollRunToResult。
|
|
@@ -342,10 +449,7 @@ export async function executeNestedWorkflow(
|
|
|
342
449
|
deps: LauncherDeps,
|
|
343
450
|
): Promise<{ content: string; parsedOutput?: unknown; error?: string }> {
|
|
344
451
|
// Step 1: 循环检测——parentWorkflowChain 不存在时为 [](顶层 run)
|
|
345
|
-
const chain =
|
|
346
|
-
...(parentRun.spec.parentWorkflowChain ?? []),
|
|
347
|
-
parentRun.spec.scriptName,
|
|
348
|
-
];
|
|
452
|
+
const chain = buildParentChain(parentRun);
|
|
349
453
|
if (chain.includes(name)) {
|
|
350
454
|
return {
|
|
351
455
|
content: "",
|
|
@@ -354,21 +458,10 @@ export async function executeNestedWorkflow(
|
|
|
354
458
|
}
|
|
355
459
|
|
|
356
460
|
// Step 2: signal 继承——子 run 响应父 run abort
|
|
357
|
-
|
|
358
|
-
// parentSignal 上残留 listener(多次嵌套调用会累积)。
|
|
359
|
-
const childController = new AbortController();
|
|
360
|
-
const parentSignal = parentRun.runtime?.controller.signal;
|
|
361
|
-
const onParentAbort = (): void => childController.abort();
|
|
362
|
-
if (parentSignal) {
|
|
363
|
-
if (parentSignal.aborted) {
|
|
364
|
-
childController.abort();
|
|
365
|
-
} else {
|
|
366
|
-
parentSignal.addEventListener("abort", onParentAbort, { once: true });
|
|
367
|
-
}
|
|
368
|
-
}
|
|
461
|
+
const { childController, parentSignal, onParentAbort } = inheritParentSignal(parentRun);
|
|
369
462
|
|
|
370
463
|
// Step 3+:registry 查找 + lint + RunSpec + runWorkflow + poll 全程 try(m3 E8——
|
|
371
|
-
// try
|
|
464
|
+
// try 起点在 Step 2 的 listener 注册之后,覆盖 Step 3-6。runWorkflow throw
|
|
372
465
|
// (含 chokepoint ArgsValidationError)与 not found/lint 早返回均走 finally 移除
|
|
373
466
|
// parentSignal listener——修复原 try 外 runWorkflow 的泄漏路径)。
|
|
374
467
|
try {
|
|
@@ -379,76 +472,30 @@ export async function executeNestedWorkflow(
|
|
|
379
472
|
}
|
|
380
473
|
const lintResult = script.validate();
|
|
381
474
|
if (!lintResult.valid) {
|
|
382
|
-
const errors = lintResult.findings
|
|
383
|
-
.filter((f) => f.severity === "error")
|
|
384
|
-
.map((f) => `L${f.line}: ${f.message}`)
|
|
385
|
-
.join("; ");
|
|
386
475
|
return {
|
|
387
476
|
content: "",
|
|
388
|
-
error: `Workflow script '${name}' has lint errors: ${
|
|
477
|
+
error: `Workflow script '${name}' has lint errors: ${formatLintErrorSummary(lintResult)}`,
|
|
389
478
|
};
|
|
390
479
|
}
|
|
391
480
|
|
|
392
|
-
// Step 4: 构建 RunSpec
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
args,
|
|
398
|
-
budgetRef: parentRun.state.budget,
|
|
399
|
-
// Run-level override 传播(与父 run 对齐):子 run 继承父 run 的 model/thinkingLevel,
|
|
400
|
-
// 否则嵌套 workflow 丢失父 run 的模型指定,回落主 agent 模型。
|
|
401
|
-
model: parentRun.spec.model,
|
|
402
|
-
thinkingLevel: parentRun.spec.thinkingLevel,
|
|
403
|
-
scriptName: script.name,
|
|
404
|
-
scriptPath: script.path,
|
|
405
|
-
description: script.meta.description,
|
|
406
|
-
parameters: script.meta.parameters,
|
|
407
|
-
parentWorkflowChain: chain,
|
|
408
|
-
};
|
|
481
|
+
// Step 4: 构建 RunSpec + 启动子 workflow
|
|
482
|
+
// budgetRef(共享 Budget)已在 spec 透传给子 run 处理 token/cost 预算,
|
|
483
|
+
// resolveNestedTimeoutMs 的 budgetTimeMs 只服务 pollRunToResult 的轮询 deadline
|
|
484
|
+
// (wall-clock 兜底)。
|
|
485
|
+
const spec = buildNestedSpec(args, parentRun, script, chain);
|
|
409
486
|
const runId = await runWorkflow(spec, deps, childController.signal);
|
|
410
487
|
|
|
411
488
|
// Step 5: 轮询至 done(复用 runAndWait 的轮询逻辑)
|
|
412
|
-
// [H-1] 嵌套 workflow timeout 从父 run 完整传导:父 spec.budgetTimeMs 显式设定时
|
|
413
|
-
// 原样作为子 run 轮询 deadline(不 min(DEFAULT) 封顶——旧实现把父 time:2h 截断到
|
|
414
|
-
// 10min,违背「显式传参完整生效」语义);父未设 → undefined,无 deadline(不限)。
|
|
415
|
-
// budgetRef(共享 Budget)已在 Step 4 透传给子 run 处理 token/cost 预算,
|
|
416
|
-
// 此处的 budgetTimeMs 只服务 pollRunToResult 的轮询 deadline(wall-clock 兜底)。
|
|
417
|
-
// [U2] 预算语义统一:父 budgetTimeMs <=0(含 0/负)与 undefined 同义 = 不限——
|
|
418
|
-
// 与 lifecycle.runWorkflow 的 budgetTimeMs 判定(>0 才挂 scheduleTimeBudget)对齐。
|
|
419
|
-
// 旧实现 0 传导给子 run 后 deadline=now 立即超时("timed out after 0ms"),与
|
|
420
|
-
// lifecycle 的 0=不限 语义分裂。pollRunToResult 内亦对非正值兜底归一(双写防漂移),
|
|
421
|
-
// 此处显式归一是传导语义的文档化表达。
|
|
422
|
-
const rawNestedTimeoutMs = parentRun.spec.budgetTimeMs;
|
|
423
|
-
const nestedTimeoutMs =
|
|
424
|
-
rawNestedTimeoutMs !== undefined && rawNestedTimeoutMs > 0 ? rawNestedTimeoutMs : undefined;
|
|
425
|
-
|
|
426
489
|
const result = await pollRunToResult(
|
|
427
490
|
runId,
|
|
428
491
|
deps,
|
|
429
492
|
childController.signal,
|
|
430
|
-
|
|
493
|
+
resolveNestedTimeoutMs(parentRun),
|
|
431
494
|
"Aborted by parent signal",
|
|
432
495
|
);
|
|
433
496
|
|
|
434
|
-
// Step 6:
|
|
435
|
-
|
|
436
|
-
const scriptResult = result.scriptResult;
|
|
437
|
-
return {
|
|
438
|
-
content:
|
|
439
|
-
typeof scriptResult === "string"
|
|
440
|
-
? scriptResult
|
|
441
|
-
: JSON.stringify(scriptResult ?? ""),
|
|
442
|
-
parsedOutput:
|
|
443
|
-
typeof scriptResult === "object" && scriptResult !== null
|
|
444
|
-
? scriptResult
|
|
445
|
-
: undefined,
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
return {
|
|
449
|
-
content: "",
|
|
450
|
-
error: result.error ?? `Workflow '${name}' ended: ${result.reason}`,
|
|
451
|
-
};
|
|
497
|
+
// Step 6: 结果转换
|
|
498
|
+
return toNestedCallResult(name, result);
|
|
452
499
|
} catch (err) {
|
|
453
500
|
// m3:chokepoint 校验失败 → {error}(§5.3 指引文案),非 ArgsValidationError 保持传播
|
|
454
501
|
// (dispatchWorkflowCall 的 .catch 兜底转 postResult,worker 不崩)。
|