@duckmind/dm-linux-x64 0.65.5 → 0.65.7
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 +0 -8
- package/dm +2 -2
- package/extensions/.dm-extensions.json +677 -44
- package/extensions/dm-lens/clients/actionable-warnings-logger.js +0 -6
- package/extensions/dm-lens/clients/actionable-warnings.js +42 -13
- package/extensions/dm-lens/clients/advisory-provenance.js +129 -41
- package/extensions/dm-lens/clients/agent-behavior-client.js +1 -0
- package/extensions/dm-lens/clients/analysed-root.js +0 -0
- package/extensions/dm-lens/clients/ast-grep-client.js +38 -3
- package/extensions/dm-lens/clients/ast-grep-rule-manager.js +37 -5
- package/extensions/dm-lens/clients/ast-grep-tool-logger.js +1 -7
- package/extensions/dm-lens/clients/bash-file-access.js +138 -1
- package/extensions/dm-lens/clients/biome-client.js +9 -2
- package/extensions/dm-lens/clients/blocker-freshness.js +171 -21
- package/extensions/dm-lens/clients/bootstrap.js +9 -5
- package/extensions/dm-lens/clients/bounded-pid-file-lock.js +1 -1
- package/extensions/dm-lens/clients/bounded-telemetry.js +1 -4
- package/extensions/dm-lens/clients/bundled-resource-health.js +43 -0
- package/extensions/dm-lens/clients/bus-events-logger.js +0 -6
- package/extensions/dm-lens/clients/cache/rule-cache.js +11 -3
- package/extensions/dm-lens/clients/cache-manager.js +29 -5
- package/extensions/dm-lens/clients/cache-observability.js +104 -4
- package/extensions/dm-lens/clients/cargo-manifest.js +6 -3
- package/extensions/dm-lens/clients/cascade-format.js +87 -5
- package/extensions/dm-lens/clients/cascade-logger.js +0 -6
- package/extensions/dm-lens/clients/child-unref.js +5 -9
- package/extensions/dm-lens/clients/code-quality-warnings.js +4 -2
- package/extensions/dm-lens/clients/complexity-client.js +5 -1
- package/extensions/dm-lens/clients/config-core/index.js +2 -68
- package/extensions/dm-lens/clients/config-core/process-spec.js +1 -1
- package/extensions/dm-lens/clients/config-core/provenance.js +1 -2
- package/extensions/dm-lens/clients/config-core/records.js +1 -1
- package/extensions/dm-lens/clients/config-core/schema.js +3 -6
- package/extensions/dm-lens/clients/config-diagnostic-codes.js +5 -3
- package/extensions/dm-lens/clients/config-locations.js +125 -5
- package/extensions/dm-lens/clients/config-resolve.js +12 -6
- package/extensions/dm-lens/clients/config-schema.js +56 -3
- package/extensions/dm-lens/clients/config-warn.js +3 -2
- package/extensions/dm-lens/clients/dead-code-client.js +4 -1
- package/extensions/dm-lens/clients/dead-code-logger.js +0 -3
- package/extensions/dm-lens/clients/degradation-ledger.js +29 -4
- package/extensions/dm-lens/clients/dependency-checker.js +29 -50
- package/extensions/dm-lens/clients/diagnostic-dispositions.js +23 -4
- package/extensions/dm-lens/clients/diagnostic-logger.js +1 -1
- package/extensions/dm-lens/clients/dispatch/ast-grep-catalog.js +19 -0
- package/extensions/dm-lens/clients/dispatch/auxiliary-lsp.js +9 -0
- package/extensions/dm-lens/clients/dispatch/collect-later-tier.js +0 -3
- package/extensions/dm-lens/clients/dispatch/dispatcher.js +30 -27
- package/extensions/dm-lens/clients/dispatch/facts/function-facts.js +1 -1
- package/extensions/dm-lens/clients/dispatch/facts/import-facts.js +4 -1
- package/extensions/dm-lens/clients/dispatch/finding-policy.js +163 -0
- package/extensions/dm-lens/clients/dispatch/indent-detect.js +213 -13
- package/extensions/dm-lens/clients/dispatch/inline-suppressions.js +20 -1
- package/extensions/dm-lens/clients/dispatch/integration.js +77 -13
- package/extensions/dm-lens/clients/dispatch/lazy.js +0 -3
- package/extensions/dm-lens/clients/dispatch/pending-runner-findings.js +1 -1
- package/extensions/dm-lens/clients/dispatch/plan.js +0 -3
- package/extensions/dm-lens/clients/dispatch/rule-ignores.js +21 -0
- package/extensions/dm-lens/clients/dispatch/rules/high-complexity.js +2 -2
- package/extensions/dm-lens/clients/dispatch/rules/high-fan-out.js +1 -1
- package/extensions/dm-lens/clients/dispatch/runners/actionlint.js +25 -29
- package/extensions/dm-lens/clients/dispatch/runners/ast-grep-napi.js +8 -32
- package/extensions/dm-lens/clients/dispatch/runners/biome-check.js +39 -23
- package/extensions/dm-lens/clients/dispatch/runners/cpp-check.js +29 -48
- package/extensions/dm-lens/clients/dispatch/runners/credo.js +17 -14
- package/extensions/dm-lens/clients/dispatch/runners/cue-vet.js +9 -7
- package/extensions/dm-lens/clients/dispatch/runners/dart-analyze.js +21 -43
- package/extensions/dm-lens/clients/dispatch/runners/detekt.js +11 -5
- package/extensions/dm-lens/clients/dispatch/runners/dotnet-build.js +27 -23
- package/extensions/dm-lens/clients/dispatch/runners/elixir-check.js +23 -38
- package/extensions/dm-lens/clients/dispatch/runners/eslint.js +22 -35
- package/extensions/dm-lens/clients/dispatch/runners/fish-indent.js +2 -1
- package/extensions/dm-lens/clients/dispatch/runners/gleam-check.js +35 -12
- package/extensions/dm-lens/clients/dispatch/runners/go-vet.js +5 -3
- package/extensions/dm-lens/clients/dispatch/runners/golangci-lint.js +21 -22
- package/extensions/dm-lens/clients/dispatch/runners/hadolint.js +26 -16
- package/extensions/dm-lens/clients/dispatch/runners/helm-lint.js +3 -1
- package/extensions/dm-lens/clients/dispatch/runners/helm-render.js +3 -2
- package/extensions/dm-lens/clients/dispatch/runners/htmlhint.js +18 -9
- package/extensions/dm-lens/clients/dispatch/runners/javac.js +24 -23
- package/extensions/dm-lens/clients/dispatch/runners/ktlint.js +23 -54
- package/extensions/dm-lens/clients/dispatch/runners/lsp.js +17 -7
- package/extensions/dm-lens/clients/dispatch/runners/markdownlint.js +12 -6
- package/extensions/dm-lens/clients/dispatch/runners/mypy.js +2 -1
- package/extensions/dm-lens/clients/dispatch/runners/oxlint.js +24 -7
- package/extensions/dm-lens/clients/dispatch/runners/php-lint.js +26 -17
- package/extensions/dm-lens/clients/dispatch/runners/phpstan.js +2 -1
- package/extensions/dm-lens/clients/dispatch/runners/prisma-validate.js +2 -1
- package/extensions/dm-lens/clients/dispatch/runners/psscriptanalyzer.js +10 -11
- package/extensions/dm-lens/clients/dispatch/runners/pyright.js +2 -1
- package/extensions/dm-lens/clients/dispatch/runners/rubocop.js +22 -18
- package/extensions/dm-lens/clients/dispatch/runners/ruff.js +17 -22
- package/extensions/dm-lens/clients/dispatch/runners/rust-clippy.js +8 -11
- package/extensions/dm-lens/clients/dispatch/runners/shellcheck.js +9 -4
- package/extensions/dm-lens/clients/dispatch/runners/shfmt.js +4 -13
- package/extensions/dm-lens/clients/dispatch/runners/spellcheck.js +15 -5
- package/extensions/dm-lens/clients/dispatch/runners/spotbugs.js +2 -1
- package/extensions/dm-lens/clients/dispatch/runners/sqlfluff.js +10 -4
- package/extensions/dm-lens/clients/dispatch/runners/stylelint.js +9 -4
- package/extensions/dm-lens/clients/dispatch/runners/swiftlint.js +11 -3
- package/extensions/dm-lens/clients/dispatch/runners/taplo.js +13 -7
- package/extensions/dm-lens/clients/dispatch/runners/terragrunt.js +2 -1
- package/extensions/dm-lens/clients/dispatch/runners/tflint.js +26 -16
- package/extensions/dm-lens/clients/dispatch/runners/tree-sitter.js +12 -13
- package/extensions/dm-lens/clients/dispatch/runners/trivy-config.js +9 -3
- package/extensions/dm-lens/clients/dispatch/runners/utils/availability-policy.js +5 -0
- package/extensions/dm-lens/clients/dispatch/runners/utils/candidate-probe.js +2 -2
- package/extensions/dm-lens/clients/dispatch/runners/utils/diagnostic-parsers.js +8 -52
- package/extensions/dm-lens/clients/dispatch/runners/utils/runner-helpers.js +35 -3
- package/extensions/dm-lens/clients/dispatch/runners/utils.js +0 -17
- package/extensions/dm-lens/clients/dispatch/runners/vale.js +12 -4
- package/extensions/dm-lens/clients/dispatch/runners/yaml-rule-parser.js +2 -20
- package/extensions/dm-lens/clients/dispatch/runners/yamllint.js +16 -4
- package/extensions/dm-lens/clients/dispatch/runners/zig-check.js +26 -38
- package/extensions/dm-lens/clients/dispatch/suppress-writer.js +13 -3
- package/extensions/dm-lens/clients/dispatch/types.js +4 -1
- package/extensions/dm-lens/clients/dispatch/utils/format-utils.js +2 -2
- package/extensions/dm-lens/clients/disposition-logger.js +0 -6
- package/extensions/dm-lens/clients/disposition-publish.js +2 -1
- package/extensions/dm-lens/clients/effective-config.js +14 -4
- package/extensions/dm-lens/clients/event-loop-hold.js +123 -0
- package/extensions/dm-lens/clients/event-loop-monitor.js +2 -2
- package/extensions/dm-lens/clients/extension-log.js +6 -1
- package/extensions/dm-lens/clients/feature-hints.js +2 -1
- package/extensions/dm-lens/clients/file-kinds.js +17 -21
- package/extensions/dm-lens/clients/file-role.js +11 -2
- package/extensions/dm-lens/clients/file-time.js +1 -1
- package/extensions/dm-lens/clients/file-utils.js +93 -6
- package/extensions/dm-lens/clients/finding-delivery-gate.js +22 -26
- package/extensions/dm-lens/clients/format-service.js +33 -16
- package/extensions/dm-lens/clients/formatters.js +129 -92
- package/extensions/dm-lens/clients/generated-artifacts.js +2 -2
- package/extensions/dm-lens/clients/generation-guard.js +4 -0
- package/extensions/dm-lens/clients/git-guard.js +80 -26
- package/extensions/dm-lens/clients/gitleaks-client.js +26 -0
- package/extensions/dm-lens/clients/govulncheck-client.js +34 -6
- package/extensions/dm-lens/clients/gradle-ktfmt-style.js +96 -13
- package/extensions/dm-lens/clients/grammar-source.js +3 -3
- package/extensions/dm-lens/clients/host-edit-normalize.js +1 -1
- package/extensions/dm-lens/clients/indent-retarget.js +35 -5
- package/extensions/dm-lens/clients/inline-blocker-dispositions.js +107 -0
- package/extensions/dm-lens/clients/install-diagnostics.js +8 -6
- package/extensions/dm-lens/clients/installer/index.js +695 -183
- package/extensions/dm-lens/clients/installer/managed-tool-refresh.js +85 -25
- package/extensions/dm-lens/clients/instance-reaper-state.js +3 -0
- package/extensions/dm-lens/clients/instance-reaper.js +23 -16
- package/extensions/dm-lens/clients/instance-registry.js +34 -2
- package/extensions/dm-lens/clients/jscpd-client.js +11 -1
- package/extensions/dm-lens/clients/knip-client.js +2 -1
- package/extensions/dm-lens/clients/language-profile.js +18 -12
- package/extensions/dm-lens/clients/language-registry.js +3 -1
- package/extensions/dm-lens/clients/latency-logger.js +14 -4
- package/extensions/dm-lens/clients/ledger-bounds.js +13 -1
- package/extensions/dm-lens/clients/lens-config.js +74 -7
- package/extensions/dm-lens/clients/lens-engine.js +9 -10
- package/extensions/dm-lens/clients/lens-events.js +1 -1
- package/extensions/dm-lens/clients/lens-flag-registry.js +47 -2
- package/extensions/dm-lens/clients/lens-map.js +1 -1
- package/extensions/dm-lens/clients/log-cleanup.js +0 -28
- package/extensions/dm-lens/clients/lsp/cascade-tier.js +2 -1
- package/extensions/dm-lens/clients/lsp/client.js +70 -30
- package/extensions/dm-lens/clients/lsp/config.js +41 -15
- package/extensions/dm-lens/clients/lsp/content-limits.js +21 -0
- package/extensions/dm-lens/clients/lsp/diagnostic-binding.js +8 -0
- package/extensions/dm-lens/clients/lsp/document-drift.js +72 -1
- package/extensions/dm-lens/clients/lsp/edits.js +3 -3
- package/extensions/dm-lens/clients/lsp/index.js +435 -62
- package/extensions/dm-lens/clients/lsp/inferred-project.js +1 -1
- package/extensions/dm-lens/clients/lsp/language.js +0 -3
- package/extensions/dm-lens/clients/lsp/launch.js +12 -5
- package/extensions/dm-lens/clients/lsp/path-utils.js +0 -2
- package/extensions/dm-lens/clients/lsp/pending-aux-coverage.js +0 -1
- package/extensions/dm-lens/clients/lsp/server.js +125 -60
- package/extensions/dm-lens/clients/lsp/session-roots.js +26 -5
- package/extensions/dm-lens/clients/lsp/sync-kind.js +14 -1
- package/extensions/dm-lens/clients/lsp/tsserver-sync.js +5 -7
- package/extensions/dm-lens/clients/lsp/wait-policy/classification.js +3 -0
- package/extensions/dm-lens/clients/lsp/wait-policy/strategies.js +31 -2
- package/extensions/dm-lens/clients/lsp/workspace-diagnostics-cache.js +26 -4
- package/extensions/dm-lens/clients/lsp-document-symbols.js +1 -1
- package/extensions/dm-lens/clients/map-with-concurrency.js +7 -3
- package/extensions/dm-lens/clients/mcp/analyze.js +1 -1
- package/extensions/dm-lens/clients/mcp/ipc.js +104 -40
- package/extensions/dm-lens/clients/mcp/review.js +39 -7
- package/extensions/dm-lens/clients/mcp/session.js +38 -4
- package/extensions/dm-lens/clients/metrics-history.js +19 -84
- package/extensions/dm-lens/clients/middle-man-analysis.js +2 -4
- package/extensions/dm-lens/clients/module-report.js +1 -1
- package/extensions/dm-lens/clients/mutating-tool.js +3 -3
- package/extensions/dm-lens/clients/mutation-attribution.js +3 -3
- package/extensions/dm-lens/clients/ndjson-logger.js +17 -9
- package/extensions/dm-lens/clients/observed-mutation.js +42 -11
- package/extensions/dm-lens/clients/opaque-mutation-scan.js +17 -7
- package/extensions/dm-lens/clients/opengrep-client.js +92 -10
- package/extensions/dm-lens/clients/opengrep-config.js +1 -1
- package/extensions/dm-lens/clients/package-manager.js +2 -1
- package/extensions/dm-lens/clients/path-utils.js +199 -3
- package/extensions/dm-lens/clients/performance-report.js +3 -3
- package/extensions/dm-lens/clients/persistent-reverify.js +167 -0
- package/extensions/dm-lens/clients/php-cs-fixer-config.js +9 -4
- package/extensions/dm-lens/clients/pipeline.js +124 -68
- package/extensions/dm-lens/clients/project-changes.js +1 -1
- package/extensions/dm-lens/clients/project-diagnostics/cache.js +19 -5
- package/extensions/dm-lens/clients/project-diagnostics/extractors.js +1 -1
- package/extensions/dm-lens/clients/project-diagnostics/fresh-fetch.js +150 -18
- package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
- package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -3
- package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/jscpd.js +1 -1
- package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/knip.js +1 -1
- package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/madge.js +1 -1
- package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/opengrep.js +1 -1
- package/extensions/dm-lens/clients/project-diagnostics/runner-adapters/runner-findings.js +19 -2
- package/extensions/dm-lens/clients/project-diagnostics/scanner.js +35 -4
- package/extensions/dm-lens/clients/project-lens-config.js +58 -4
- package/extensions/dm-lens/clients/project-scan-policy.js +0 -46
- package/extensions/dm-lens/clients/python-environment.js +80 -4
- package/extensions/dm-lens/clients/python-provenance.js +551 -0
- package/extensions/dm-lens/clients/read-guard-logger.js +3 -1
- package/extensions/dm-lens/clients/read-guard.js +29 -6
- package/extensions/dm-lens/clients/recent-touches.js +2 -2
- package/extensions/dm-lens/clients/resource-sampler.js +59 -9
- package/extensions/dm-lens/clients/review-graph/builder.js +39 -34
- package/extensions/dm-lens/clients/review-graph/git-identity.js +11 -7
- package/extensions/dm-lens/clients/review-graph/import-resolvers.js +1 -1
- package/extensions/dm-lens/clients/review-graph-logger.js +3 -1
- package/extensions/dm-lens/clients/ruff-client.js +11 -10
- package/extensions/dm-lens/clients/runtime-agent-end.js +41 -5
- package/extensions/dm-lens/clients/runtime-context.js +5 -2
- package/extensions/dm-lens/clients/runtime-coordinator.js +60 -6
- package/extensions/dm-lens/clients/runtime-session.js +52 -8
- package/extensions/dm-lens/clients/runtime-tool-call.js +27 -15
- package/extensions/dm-lens/clients/runtime-tool-result.js +279 -63
- package/extensions/dm-lens/clients/runtime-turn.js +453 -185
- package/extensions/dm-lens/clients/safe-spawn.js +248 -62
- package/extensions/dm-lens/clients/sanitize.js +0 -4
- package/extensions/dm-lens/clients/scan-utils.js +1 -39
- package/extensions/dm-lens/clients/scratch-tree-policy.js +2 -3
- package/extensions/dm-lens/clients/security-scan-client.js +2 -2
- package/extensions/dm-lens/clients/session-event-guard.js +59 -2
- package/extensions/dm-lens/clients/session-summary.js +0 -25
- package/extensions/dm-lens/clients/sg-runner.js +24 -12
- package/extensions/dm-lens/clients/sgconfig.js +58 -6
- package/extensions/dm-lens/clients/shared-checkout-guard.js +1 -1
- package/extensions/dm-lens/clients/situational-tool-telemetry.js +85 -0
- package/extensions/dm-lens/clients/skills-resolver.js +42 -0
- package/extensions/dm-lens/clients/smells-rollup.js +2 -2
- package/extensions/dm-lens/clients/spawn-output-cap.js +29 -0
- package/extensions/dm-lens/clients/startup-scan.js +1 -2
- package/extensions/dm-lens/clients/string-utils.js +3 -0
- package/extensions/dm-lens/clients/test-runner-client.js +118 -57
- package/extensions/dm-lens/clients/test-runner-delivery.js +118 -66
- package/extensions/dm-lens/clients/tool-agreement.js +403 -0
- package/extensions/dm-lens/clients/tool-config.js +218 -0
- package/extensions/dm-lens/clients/tool-cwd.js +248 -0
- package/extensions/dm-lens/clients/tool-definition.js +18 -1
- package/extensions/dm-lens/clients/tool-policy.js +138 -10
- package/extensions/dm-lens/clients/tool-probe.js +5 -0
- package/extensions/dm-lens/clients/tool-set-policy.js +35 -0
- package/extensions/dm-lens/clients/tree-sitter-client.js +201 -80
- package/extensions/dm-lens/clients/tree-sitter-query-loader.js +78 -130
- package/extensions/dm-lens/clients/trivy-client.js +8 -1
- package/extensions/dm-lens/clients/tui-fit.js +0 -3
- package/extensions/dm-lens/clients/turn-context.js +48 -0
- package/extensions/dm-lens/clients/turn-end/lane.js +0 -0
- package/extensions/dm-lens/clients/turn-end/lanes/govulncheck.js +54 -0
- package/extensions/dm-lens/clients/turn-end/lanes/secrets.js +140 -0
- package/extensions/dm-lens/clients/user-notify.js +0 -3
- package/extensions/dm-lens/clients/warm-attach.js +25 -0
- package/extensions/dm-lens/clients/widget-state.js +203 -13
- package/extensions/dm-lens/clients/word-index-logger.js +0 -6
- package/extensions/dm-lens/clients/word-index-store.js +1 -4
- package/extensions/dm-lens/clients/word-index.js +9 -5
- package/extensions/dm-lens/clients/workspace-topology.js +20 -3
- package/extensions/dm-lens/clients/write-ordering-guard.js +6 -0
- package/extensions/dm-lens/clients/zizmor-config.js +15 -11
- package/extensions/dm-lens/config/dependency-cruiser-eager-allowlist.json +8 -2
- package/extensions/dm-lens/dist/clients/actionable-warnings-logger.js +24 -0
- package/extensions/dm-lens/dist/clients/actionable-warnings.js +1014 -0
- package/extensions/dm-lens/dist/clients/advisory-provenance.js +385 -0
- package/extensions/dm-lens/dist/clients/agent-behavior-client.js +94 -0
- package/extensions/dm-lens/dist/clients/agent-nudge.js +151 -0
- package/extensions/dm-lens/dist/clients/analysed-root.js +1 -0
- package/extensions/dm-lens/dist/clients/ast-grep-client.js +576 -0
- package/extensions/dm-lens/dist/clients/ast-grep-rule-manager.js +114 -0
- package/extensions/dm-lens/dist/clients/ast-grep-tool-logger.js +85 -0
- package/extensions/dm-lens/dist/clients/ast-grep-types.js +1 -0
- package/extensions/dm-lens/dist/clients/ast-grep-yaml-synth.js +109 -0
- package/extensions/dm-lens/dist/clients/atomic-write-staging.js +66 -0
- package/extensions/dm-lens/dist/clients/atomic-write.js +37 -0
- package/extensions/dm-lens/dist/clients/availability-probe-flight.js +11 -0
- package/extensions/dm-lens/dist/clients/bash-file-access.js +830 -0
- package/extensions/dm-lens/dist/clients/biome-client.js +221 -0
- package/extensions/dm-lens/dist/clients/blocker-freshness.js +385 -0
- package/extensions/dm-lens/dist/clients/blocker-past-eof.js +49 -0
- package/extensions/dm-lens/dist/clients/bootstrap.js +246 -0
- package/extensions/dm-lens/dist/clients/bounded-cache.js +105 -0
- package/extensions/dm-lens/dist/clients/bounded-pid-file-lock.js +173 -0
- package/extensions/dm-lens/dist/clients/bounded-telemetry.js +104 -0
- package/extensions/dm-lens/dist/clients/build-identity.js +45 -0
- package/extensions/dm-lens/dist/clients/bundled-resource-health.js +41 -0
- package/extensions/dm-lens/dist/clients/bus-events-logger.js +48 -0
- package/extensions/dm-lens/dist/clients/bus-publish.js +117 -0
- package/extensions/dm-lens/dist/clients/cache/rule-cache.js +103 -0
- package/extensions/dm-lens/dist/clients/cache-manager.js +340 -0
- package/extensions/dm-lens/dist/clients/cache-observability.js +847 -0
- package/extensions/dm-lens/dist/clients/call-graph.js +628 -0
- package/extensions/dm-lens/dist/clients/cargo-manifest.js +151 -0
- package/extensions/dm-lens/dist/clients/cascade-budget.js +52 -0
- package/extensions/dm-lens/dist/clients/cascade-format.js +160 -0
- package/extensions/dm-lens/dist/clients/cascade-logger.js +22 -0
- package/extensions/dm-lens/dist/clients/cascade-types.js +1 -0
- package/extensions/dm-lens/dist/clients/child-unref.js +59 -0
- package/extensions/dm-lens/dist/clients/code-quality-warnings.js +192 -0
- package/extensions/dm-lens/dist/clients/codebase-model.js +110 -0
- package/extensions/dm-lens/dist/clients/collateral-test-role.js +8 -0
- package/extensions/dm-lens/dist/clients/complexity-client.js +398 -0
- package/extensions/dm-lens/dist/clients/config-core/deny.js +117 -0
- package/extensions/dm-lens/dist/clients/config-core/index.js +2 -0
- package/extensions/dm-lens/dist/clients/config-core/merge.js +228 -0
- package/extensions/dm-lens/dist/clients/config-core/normalize.js +217 -0
- package/extensions/dm-lens/dist/clients/config-core/process-spec.js +147 -0
- package/extensions/dm-lens/dist/clients/config-core/provenance.js +54 -0
- package/extensions/dm-lens/dist/clients/config-core/records.js +79 -0
- package/extensions/dm-lens/dist/clients/config-core/resolve.js +48 -0
- package/extensions/dm-lens/dist/clients/config-core/safe-object.js +22 -0
- package/extensions/dm-lens/dist/clients/config-core/schema.js +90 -0
- package/extensions/dm-lens/dist/clients/config-diagnostic-codes.js +90 -0
- package/extensions/dm-lens/dist/clients/config-locations.js +175 -0
- package/extensions/dm-lens/dist/clients/config-resolve.js +359 -0
- package/extensions/dm-lens/dist/clients/config-schema.js +128 -0
- package/extensions/dm-lens/dist/clients/config-warn.js +146 -0
- package/extensions/dm-lens/dist/clients/console-guard-install.js +4 -0
- package/extensions/dm-lens/dist/clients/cooperative-budget.js +36 -0
- package/extensions/dm-lens/dist/clients/dead-code-client.js +342 -0
- package/extensions/dm-lens/dist/clients/dead-code-logger.js +18 -0
- package/extensions/dm-lens/dist/clients/deadline-utils.js +117 -0
- package/extensions/dm-lens/dist/clients/debug-handles.js +121 -0
- package/extensions/dm-lens/dist/clients/debug-heap.js +80 -0
- package/extensions/dm-lens/dist/clients/deferred-lsp-work.js +33 -0
- package/extensions/dm-lens/dist/clients/degradation-ledger.js +272 -0
- package/extensions/dm-lens/dist/clients/demoted-finding-render.js +61 -0
- package/extensions/dm-lens/dist/clients/dependency-checker.js +525 -0
- package/extensions/dm-lens/dist/clients/deps/ast-grep-napi.js +17 -0
- package/extensions/dm-lens/dist/clients/deps/dm-host-deps.js +10 -0
- package/extensions/dm-lens/dist/clients/deps/dm-tui-compat.js +58 -0
- package/extensions/dm-lens/dist/clients/deps/js-yaml.js +7 -0
- package/extensions/dm-lens/dist/clients/deps/minimatch.js +6 -0
- package/extensions/dm-lens/dist/clients/deps/pidusage.js +5 -0
- package/extensions/dm-lens/dist/clients/deps/typebox.js +5 -0
- package/extensions/dm-lens/dist/clients/deps/vscode-jsonrpc.js +8 -0
- package/extensions/dm-lens/dist/clients/deps/web-tree-sitter.js +11 -0
- package/extensions/dm-lens/dist/clients/diagnostic-dispositions.js +318 -0
- package/extensions/dm-lens/dist/clients/diagnostic-line-freshness.js +144 -0
- package/extensions/dm-lens/dist/clients/diagnostic-logger.js +60 -0
- package/extensions/dm-lens/dist/clients/diagnostic-tracker.js +89 -0
- package/extensions/dm-lens/dist/clients/diagnostics-publish.js +134 -0
- package/extensions/dm-lens/dist/clients/dispatch/ast-grep-catalog.js +16 -0
- package/extensions/dm-lens/dist/clients/dispatch/auxiliary-lsp.js +158 -0
- package/extensions/dm-lens/dist/clients/dispatch/collect-later-tier.js +25 -0
- package/extensions/dm-lens/dist/clients/dispatch/diagnostic-taxonomy.js +58 -0
- package/extensions/dm-lens/dist/clients/dispatch/dispatcher.js +953 -0
- package/extensions/dm-lens/dist/clients/dispatch/fact-provider-types.js +1 -0
- package/extensions/dm-lens/dist/clients/dispatch/fact-rule-runner.js +17 -0
- package/extensions/dm-lens/dist/clients/dispatch/fact-runner.js +18 -0
- package/extensions/dm-lens/dist/clients/dispatch/fact-scheduler.js +52 -0
- package/extensions/dm-lens/dist/clients/dispatch/fact-store.js +199 -0
- package/extensions/dm-lens/dist/clients/dispatch/facts/comment-facts.js +20 -0
- package/extensions/dm-lens/dist/clients/dispatch/facts/file-content.js +18 -0
- package/extensions/dm-lens/dist/clients/dispatch/facts/function-facts.js +281 -0
- package/extensions/dm-lens/dist/clients/dispatch/facts/import-facts.js +169 -0
- package/extensions/dm-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +19 -0
- package/extensions/dm-lens/dist/clients/dispatch/facts/try-catch-facts.js +95 -0
- package/extensions/dm-lens/dist/clients/dispatch/finding-policy.js +159 -0
- package/extensions/dm-lens/dist/clients/dispatch/indent-detect.js +227 -0
- package/extensions/dm-lens/dist/clients/dispatch/inline-suppressions.js +52 -0
- package/extensions/dm-lens/dist/clients/dispatch/integration.js +1463 -0
- package/extensions/dm-lens/dist/clients/dispatch/lazy.js +8 -0
- package/extensions/dm-lens/dist/clients/dispatch/pending-runner-findings.js +75 -0
- package/extensions/dm-lens/dist/clients/dispatch/plan.js +278 -0
- package/extensions/dm-lens/dist/clients/dispatch/priorities.js +14 -0
- package/extensions/dm-lens/dist/clients/dispatch/rule-id-normalize.js +42 -0
- package/extensions/dm-lens/dist/clients/dispatch/rule-ignores.js +21 -0
- package/extensions/dm-lens/dist/clients/dispatch/rule-policy.js +73 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/async-noise.js +31 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +27 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/cors-wildcard.js +35 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/error-obscuring.js +29 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/error-swallowing.js +29 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/framework-call-noise.js +31 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/high-complexity.js +56 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/high-fan-out.js +45 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/high-import-coupling.js +31 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/missing-error-propagation.js +45 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/no-commented-credentials.js +46 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +38 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/placeholder-comments.js +40 -0
- package/extensions/dm-lens/dist/clients/dispatch/rules/unsafe-boundary.js +101 -0
- package/extensions/dm-lens/dist/clients/dispatch/runner-context.js +46 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/actionlint.js +98 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/ast-grep-napi.js +690 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/biome-check.js +202 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/cpp-check.js +190 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/credo.js +66 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/cue-vet.js +167 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/dart-analyze.js +151 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/detekt.js +157 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/dotnet-build.js +157 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/elixir-check.js +153 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/eslint.js +99 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/fact-rules.js +20 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/fish-indent.js +65 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/gleam-check.js +107 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/go-vet.js +51 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/golangci-lint.js +89 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/hadolint.js +83 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/helm-lint.js +144 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/helm-render.js +593 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/htmlhint.js +103 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/index.js +100 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/javac.js +82 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/ktlint.js +93 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/lsp.js +206 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/markdownlint.js +129 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/mypy.js +70 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/oxlint.js +305 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/php-lint.js +70 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/phpstan.js +90 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/prisma-validate.js +56 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +307 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/pyright.js +118 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/rubocop.js +79 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/ruff.js +69 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/rust-clippy.js +147 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/shellcheck.js +111 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/shfmt.js +81 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/spellcheck.js +74 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/spotbugs.js +208 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/sqlfluff.js +136 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/stylelint.js +118 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/swiftlint.js +143 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/taplo.js +97 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/terragrunt.js +110 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/tflint.js +104 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/tree-sitter.js +516 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/trivy-config.js +155 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/availability-policy.js +285 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +61 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +61 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +130 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +1067 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +40 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/tool-failure.js +117 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +88 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils.js +8 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/vale.js +106 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +163 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/yamllint.js +83 -0
- package/extensions/dm-lens/dist/clients/dispatch/runners/zig-check.js +72 -0
- package/extensions/dm-lens/dist/clients/dispatch/suppress-writer.js +57 -0
- package/extensions/dm-lens/dist/clients/dispatch/tool-profile.js +30 -0
- package/extensions/dm-lens/dist/clients/dispatch/types.js +7 -0
- package/extensions/dm-lens/dist/clients/dispatch/utils/format-utils.js +45 -0
- package/extensions/dm-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +31 -0
- package/extensions/dm-lens/dist/clients/disposition-logger.js +19 -0
- package/extensions/dm-lens/dist/clients/disposition-publish.js +88 -0
- package/extensions/dm-lens/dist/clients/durable-store.js +77 -0
- package/extensions/dm-lens/dist/clients/effective-config.js +160 -0
- package/extensions/dm-lens/dist/clients/env-utils.js +26 -0
- package/extensions/dm-lens/dist/clients/error-class.js +3 -0
- package/extensions/dm-lens/dist/clients/eval-timestamp.js +2 -0
- package/extensions/dm-lens/dist/clients/event-loop-hold.js +119 -0
- package/extensions/dm-lens/dist/clients/event-loop-monitor.js +84 -0
- package/extensions/dm-lens/dist/clients/extension-log.js +230 -0
- package/extensions/dm-lens/dist/clients/extension-mode.js +20 -0
- package/extensions/dm-lens/dist/clients/feature-hints.js +88 -0
- package/extensions/dm-lens/dist/clients/file-kinds.js +304 -0
- package/extensions/dm-lens/dist/clients/file-role.js +50 -0
- package/extensions/dm-lens/dist/clients/file-time.js +112 -0
- package/extensions/dm-lens/dist/clients/file-utils.js +630 -0
- package/extensions/dm-lens/dist/clients/finding-delivery-gate.js +129 -0
- package/extensions/dm-lens/dist/clients/finding-identity.js +23 -0
- package/extensions/dm-lens/dist/clients/fix-worklog.js +75 -0
- package/extensions/dm-lens/dist/clients/format-events-publish.js +230 -0
- package/extensions/dm-lens/dist/clients/format-service.js +154 -0
- package/extensions/dm-lens/dist/clients/formatters-lazy.js +8 -0
- package/extensions/dm-lens/dist/clients/formatters.js +1351 -0
- package/extensions/dm-lens/dist/clients/freshness-cadence.js +1 -0
- package/extensions/dm-lens/dist/clients/freshness.js +8 -0
- package/extensions/dm-lens/dist/clients/generated-artifacts.js +209 -0
- package/extensions/dm-lens/dist/clients/generation-guard.js +105 -0
- package/extensions/dm-lens/dist/clients/git-guard.js +770 -0
- package/extensions/dm-lens/dist/clients/git-tracked-ignore.js +120 -0
- package/extensions/dm-lens/dist/clients/gitleaks-client.js +282 -0
- package/extensions/dm-lens/dist/clients/go-client.js +47 -0
- package/extensions/dm-lens/dist/clients/govulncheck-client.js +411 -0
- package/extensions/dm-lens/dist/clients/gradle-ktfmt-style.js +177 -0
- package/extensions/dm-lens/dist/clients/grammar-source.js +224 -0
- package/extensions/dm-lens/dist/clients/gzip-stage-write.js +85 -0
- package/extensions/dm-lens/dist/clients/hashline-anchor.js +222 -0
- package/extensions/dm-lens/dist/clients/hook-budgets.js +16 -0
- package/extensions/dm-lens/dist/clients/host-edit-normalize.js +87 -0
- package/extensions/dm-lens/dist/clients/host-ports.js +35 -0
- package/extensions/dm-lens/dist/clients/indent-retarget.js +102 -0
- package/extensions/dm-lens/dist/clients/inline-blocker-dispositions.js +103 -0
- package/extensions/dm-lens/dist/clients/install-diagnostics.js +123 -0
- package/extensions/dm-lens/dist/clients/installer/index.js +3770 -0
- package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh-session.js +17 -0
- package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh.js +522 -0
- package/extensions/dm-lens/dist/clients/instance-reaper-state.js +3 -0
- package/extensions/dm-lens/dist/clients/instance-reaper.js +577 -0
- package/extensions/dm-lens/dist/clients/instance-registry-lock.js +131 -0
- package/extensions/dm-lens/dist/clients/instance-registry.js +452 -0
- package/extensions/dm-lens/dist/clients/jscpd-client.js +252 -0
- package/extensions/dm-lens/dist/clients/json-cache-read.js +25 -0
- package/extensions/dm-lens/dist/clients/knip-client.js +472 -0
- package/extensions/dm-lens/dist/clients/language-policy.js +242 -0
- package/extensions/dm-lens/dist/clients/language-profile.js +261 -0
- package/extensions/dm-lens/dist/clients/language-registry.js +424 -0
- package/extensions/dm-lens/dist/clients/latency-logger.js +192 -0
- package/extensions/dm-lens/dist/clients/lazy-import.js +14 -0
- package/extensions/dm-lens/dist/clients/ledger-bounds.js +21 -0
- package/extensions/dm-lens/dist/clients/lens-config.js +237 -0
- package/extensions/dm-lens/dist/clients/lens-engine.js +181 -0
- package/extensions/dm-lens/dist/clients/lens-events.js +105 -0
- package/extensions/dm-lens/dist/clients/lens-flag-registry.js +302 -0
- package/extensions/dm-lens/dist/clients/lens-map.js +980 -0
- package/extensions/dm-lens/dist/clients/live-bus-emitter.js +53 -0
- package/extensions/dm-lens/dist/clients/log-cleanup.js +138 -0
- package/extensions/dm-lens/dist/clients/lsp/aggregation.js +88 -0
- package/extensions/dm-lens/dist/clients/lsp/cascade-tier.js +203 -0
- package/extensions/dm-lens/dist/clients/lsp/client.js +2709 -0
- package/extensions/dm-lens/dist/clients/lsp/config.js +252 -0
- package/extensions/dm-lens/dist/clients/lsp/content-limits.js +21 -0
- package/extensions/dm-lens/dist/clients/lsp/diagnostic-binding.js +79 -0
- package/extensions/dm-lens/dist/clients/lsp/document-drift.js +312 -0
- package/extensions/dm-lens/dist/clients/lsp/edits.js +930 -0
- package/extensions/dm-lens/dist/clients/lsp/index.js +4448 -0
- package/extensions/dm-lens/dist/clients/lsp/inferred-project.js +121 -0
- package/extensions/dm-lens/dist/clients/lsp/jvm-runtime.js +194 -0
- package/extensions/dm-lens/dist/clients/lsp/language.js +23 -0
- package/extensions/dm-lens/dist/clients/lsp/launch.js +468 -0
- package/extensions/dm-lens/dist/clients/lsp/lombok.js +146 -0
- package/extensions/dm-lens/dist/clients/lsp/path-utils.js +1 -0
- package/extensions/dm-lens/dist/clients/lsp/pending-aux-coverage.js +90 -0
- package/extensions/dm-lens/dist/clients/lsp/position-encoding.js +28 -0
- package/extensions/dm-lens/dist/clients/lsp/ruby-drive-dirs.js +42 -0
- package/extensions/dm-lens/dist/clients/lsp/server.js +2422 -0
- package/extensions/dm-lens/dist/clients/lsp/session-roots.js +52 -0
- package/extensions/dm-lens/dist/clients/lsp/spawn-history.js +15 -0
- package/extensions/dm-lens/dist/clients/lsp/sync-kind.js +30 -0
- package/extensions/dm-lens/dist/clients/lsp/tsserver-sync.js +156 -0
- package/extensions/dm-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +1 -0
- package/extensions/dm-lens/dist/clients/lsp/wait-policy/classification.js +36 -0
- package/extensions/dm-lens/dist/clients/lsp/wait-policy/index.js +3 -0
- package/extensions/dm-lens/dist/clients/lsp/wait-policy/strategies.js +175 -0
- package/extensions/dm-lens/dist/clients/lsp/watch-queue.js +40 -0
- package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-cache.js +267 -0
- package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-session.js +7 -0
- package/extensions/dm-lens/dist/clients/lsp/workspace-sweep-hold.js +93 -0
- package/extensions/dm-lens/dist/clients/lsp-budget.js +83 -0
- package/extensions/dm-lens/dist/clients/lsp-document-symbols.js +93 -0
- package/extensions/dm-lens/dist/clients/lsp-lazy.js +8 -0
- package/extensions/dm-lens/dist/clients/lsp-mutation.js +273 -0
- package/extensions/dm-lens/dist/clients/lsp-status.js +37 -0
- package/extensions/dm-lens/dist/clients/map-with-concurrency.js +20 -0
- package/extensions/dm-lens/dist/clients/mcp/analyze.js +251 -0
- package/extensions/dm-lens/dist/clients/mcp/host-shim.js +14 -0
- package/extensions/dm-lens/dist/clients/mcp/ipc.js +302 -0
- package/extensions/dm-lens/dist/clients/mcp/review.js +137 -0
- package/extensions/dm-lens/dist/clients/mcp/session.js +305 -0
- package/extensions/dm-lens/dist/clients/memory-sampler.js +107 -0
- package/extensions/dm-lens/dist/clients/message-end-attribution.js +18 -0
- package/extensions/dm-lens/dist/clients/metrics-client.js +80 -0
- package/extensions/dm-lens/dist/clients/metrics-history.js +255 -0
- package/extensions/dm-lens/dist/clients/middle-man-analysis.js +161 -0
- package/extensions/dm-lens/dist/clients/model-provider.js +31 -0
- package/extensions/dm-lens/dist/clients/module-report-lsp.js +140 -0
- package/extensions/dm-lens/dist/clients/module-report.js +1642 -0
- package/extensions/dm-lens/dist/clients/mutating-tool.js +377 -0
- package/extensions/dm-lens/dist/clients/mutation-attribution.js +168 -0
- package/extensions/dm-lens/dist/clients/mutation-bridge.js +102 -0
- package/extensions/dm-lens/dist/clients/ndjson-logger.js +471 -0
- package/extensions/dm-lens/dist/clients/observed-mutation-sources.js +43 -0
- package/extensions/dm-lens/dist/clients/observed-mutation.js +709 -0
- package/extensions/dm-lens/dist/clients/oldtext-autopatch.js +100 -0
- package/extensions/dm-lens/dist/clients/opaque-mutation-scan.js +313 -0
- package/extensions/dm-lens/dist/clients/opengrep-client.js +216 -0
- package/extensions/dm-lens/dist/clients/opengrep-config.js +52 -0
- package/extensions/dm-lens/dist/clients/package-manager.js +303 -0
- package/extensions/dm-lens/dist/clients/package-root.js +25 -0
- package/extensions/dm-lens/dist/clients/partial-edit-apply.js +337 -0
- package/extensions/dm-lens/dist/clients/path-attribution-telemetry.js +31 -0
- package/extensions/dm-lens/dist/clients/path-keyed-map.js +57 -0
- package/extensions/dm-lens/dist/clients/path-utils.js +476 -0
- package/extensions/dm-lens/dist/clients/performance-report.js +291 -0
- package/extensions/dm-lens/dist/clients/persist-debounce.js +37 -0
- package/extensions/dm-lens/dist/clients/persistent-reverify.js +165 -0
- package/extensions/dm-lens/dist/clients/php-cs-fixer-config.js +15 -0
- package/extensions/dm-lens/dist/clients/pipeline.js +1091 -0
- package/extensions/dm-lens/dist/clients/post-autofix-notice.js +19 -0
- package/extensions/dm-lens/dist/clients/print-mode.js +3 -0
- package/extensions/dm-lens/dist/clients/probe-home-state.js +62 -0
- package/extensions/dm-lens/dist/clients/process-bridge.js +20 -0
- package/extensions/dm-lens/dist/clients/process-singletons.js +69 -0
- package/extensions/dm-lens/dist/clients/process-snapshot.js +22 -0
- package/extensions/dm-lens/dist/clients/project-changes.js +112 -0
- package/extensions/dm-lens/dist/clients/project-conventions.js +152 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/cache.js +91 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/extractors.js +53 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/fresh-fetch.js +408 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +64 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +38 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +21 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +23 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +28 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +45 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +34 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +32 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +79 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +41 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/scanner.js +349 -0
- package/extensions/dm-lens/dist/clients/project-diagnostics/types.js +1 -0
- package/extensions/dm-lens/dist/clients/project-lens-config.js +437 -0
- package/extensions/dm-lens/dist/clients/project-report.js +527 -0
- package/extensions/dm-lens/dist/clients/project-scale.js +60 -0
- package/extensions/dm-lens/dist/clients/project-scan-policy.js +4 -0
- package/extensions/dm-lens/dist/clients/project-snapshot-fingerprint.js +39 -0
- package/extensions/dm-lens/dist/clients/project-snapshot-persist-worker.js +14 -0
- package/extensions/dm-lens/dist/clients/project-snapshot.js +1178 -0
- package/extensions/dm-lens/dist/clients/project-trust.js +104 -0
- package/extensions/dm-lens/dist/clients/python-environment.js +120 -0
- package/extensions/dm-lens/dist/clients/python-provenance.js +551 -0
- package/extensions/dm-lens/dist/clients/quiet-window-config.js +16 -0
- package/extensions/dm-lens/dist/clients/quiet-window.js +126 -0
- package/extensions/dm-lens/dist/clients/read-bridge.js +46 -0
- package/extensions/dm-lens/dist/clients/read-expansion.js +218 -0
- package/extensions/dm-lens/dist/clients/read-guard-logger.js +178 -0
- package/extensions/dm-lens/dist/clients/read-guard-tool-lines.js +1042 -0
- package/extensions/dm-lens/dist/clients/read-guard.js +1096 -0
- package/extensions/dm-lens/dist/clients/recent-touches.js +126 -0
- package/extensions/dm-lens/dist/clients/redact/secrets.js +386 -0
- package/extensions/dm-lens/dist/clients/resource-sampler.js +344 -0
- package/extensions/dm-lens/dist/clients/reverse-deps.js +227 -0
- package/extensions/dm-lens/dist/clients/review-graph/builder.js +3635 -0
- package/extensions/dm-lens/dist/clients/review-graph/format.js +30 -0
- package/extensions/dm-lens/dist/clients/review-graph/git-identity.js +115 -0
- package/extensions/dm-lens/dist/clients/review-graph/import-resolvers.js +325 -0
- package/extensions/dm-lens/dist/clients/review-graph/persist-worker.js +8 -0
- package/extensions/dm-lens/dist/clients/review-graph/query.js +195 -0
- package/extensions/dm-lens/dist/clients/review-graph/revision-drift.js +3 -0
- package/extensions/dm-lens/dist/clients/review-graph/service.js +60 -0
- package/extensions/dm-lens/dist/clients/review-graph/shared-extraction-ir.js +54 -0
- package/extensions/dm-lens/dist/clients/review-graph/symbol-id.js +29 -0
- package/extensions/dm-lens/dist/clients/review-graph/tsconfig-paths.js +253 -0
- package/extensions/dm-lens/dist/clients/review-graph/types.js +1 -0
- package/extensions/dm-lens/dist/clients/review-graph/workspace-modules.js +374 -0
- package/extensions/dm-lens/dist/clients/review-graph-logger.js +51 -0
- package/extensions/dm-lens/dist/clients/ruff-client.js +109 -0
- package/extensions/dm-lens/dist/clients/rules-scanner.js +113 -0
- package/extensions/dm-lens/dist/clients/run-duration.js +9 -0
- package/extensions/dm-lens/dist/clients/runtime-agent-end.js +608 -0
- package/extensions/dm-lens/dist/clients/runtime-config.js +39 -0
- package/extensions/dm-lens/dist/clients/runtime-context.js +155 -0
- package/extensions/dm-lens/dist/clients/runtime-coordinator.js +817 -0
- package/extensions/dm-lens/dist/clients/runtime-session.js +1625 -0
- package/extensions/dm-lens/dist/clients/runtime-tool-call.js +868 -0
- package/extensions/dm-lens/dist/clients/runtime-tool-result.js +1317 -0
- package/extensions/dm-lens/dist/clients/runtime-turn.js +2333 -0
- package/extensions/dm-lens/dist/clients/rust-client.js +48 -0
- package/extensions/dm-lens/dist/clients/safe-spawn.js +1267 -0
- package/extensions/dm-lens/dist/clients/sanitize.js +174 -0
- package/extensions/dm-lens/dist/clients/scan-utils.js +7 -0
- package/extensions/dm-lens/dist/clients/scratch-tree-policy.js +57 -0
- package/extensions/dm-lens/dist/clients/search-read-registration.js +59 -0
- package/extensions/dm-lens/dist/clients/secret-findings.js +69 -0
- package/extensions/dm-lens/dist/clients/security-scan-client.js +208 -0
- package/extensions/dm-lens/dist/clients/session-event-guard.js +111 -0
- package/extensions/dm-lens/dist/clients/session-lifecycle.js +173 -0
- package/extensions/dm-lens/dist/clients/session-start-observability.js +47 -0
- package/extensions/dm-lens/dist/clients/session-state-store.js +63 -0
- package/extensions/dm-lens/dist/clients/session-summary.js +8 -0
- package/extensions/dm-lens/dist/clients/sessionstart-logger.js +22 -0
- package/extensions/dm-lens/dist/clients/sg-runner.js +627 -0
- package/extensions/dm-lens/dist/clients/sgconfig.js +280 -0
- package/extensions/dm-lens/dist/clients/shared-checkout-guard.js +177 -0
- package/extensions/dm-lens/dist/clients/single-flight.js +52 -0
- package/extensions/dm-lens/dist/clients/situational-tool-telemetry.js +85 -0
- package/extensions/dm-lens/dist/clients/skills-resolver.js +38 -0
- package/extensions/dm-lens/dist/clients/slow-fs.js +77 -0
- package/extensions/dm-lens/dist/clients/smells-rollup.js +118 -0
- package/extensions/dm-lens/dist/clients/source-filter.js +320 -0
- package/extensions/dm-lens/dist/clients/source-walker.js +96 -0
- package/extensions/dm-lens/dist/clients/spawn-output-cap.js +35 -0
- package/extensions/dm-lens/dist/clients/spawn-timeout-cooldown.js +51 -0
- package/extensions/dm-lens/dist/clients/stale-marker.js +1 -0
- package/extensions/dm-lens/dist/clients/startup-scan.js +222 -0
- package/extensions/dm-lens/dist/clients/startup-timing.js +67 -0
- package/extensions/dm-lens/dist/clients/string-utils.js +6 -0
- package/extensions/dm-lens/dist/clients/subagent-mode.js +40 -0
- package/extensions/dm-lens/dist/clients/symbol-containment.js +16 -0
- package/extensions/dm-lens/dist/clients/symbol-types.js +1 -0
- package/extensions/dm-lens/dist/clients/test-runner-client.js +1504 -0
- package/extensions/dm-lens/dist/clients/test-runner-delivery.js +260 -0
- package/extensions/dm-lens/dist/clients/todo-scanner.js +164 -0
- package/extensions/dm-lens/dist/clients/tool-agreement.js +377 -0
- package/extensions/dm-lens/dist/clients/tool-config.js +218 -0
- package/extensions/dm-lens/dist/clients/tool-cwd.js +235 -0
- package/extensions/dm-lens/dist/clients/tool-definition.js +22 -0
- package/extensions/dm-lens/dist/clients/tool-event.js +18 -0
- package/extensions/dm-lens/dist/clients/tool-policy.js +2393 -0
- package/extensions/dm-lens/dist/clients/tool-probe.js +5 -0
- package/extensions/dm-lens/dist/clients/tool-render.js +79 -0
- package/extensions/dm-lens/dist/clients/tool-set-policy.js +70 -0
- package/extensions/dm-lens/dist/clients/tree-sitter-cache.js +206 -0
- package/extensions/dm-lens/dist/clients/tree-sitter-client.js +2787 -0
- package/extensions/dm-lens/dist/clients/tree-sitter-logger.js +77 -0
- package/extensions/dm-lens/dist/clients/tree-sitter-navigator.js +198 -0
- package/extensions/dm-lens/dist/clients/tree-sitter-query-loader.js +318 -0
- package/extensions/dm-lens/dist/clients/tree-sitter-shared.js +87 -0
- package/extensions/dm-lens/dist/clients/tree-sitter-symbol-extractor.js +957 -0
- package/extensions/dm-lens/dist/clients/trivy-client.js +305 -0
- package/extensions/dm-lens/dist/clients/tui-fit.js +26 -0
- package/extensions/dm-lens/dist/clients/turn-context.js +48 -0
- package/extensions/dm-lens/dist/clients/turn-end/lane.js +1 -0
- package/extensions/dm-lens/dist/clients/turn-end/lanes/govulncheck.js +54 -0
- package/extensions/dm-lens/dist/clients/turn-end/lanes/secrets.js +131 -0
- package/extensions/dm-lens/dist/clients/turn-summary-render.js +56 -0
- package/extensions/dm-lens/dist/clients/turn-summary.js +84 -0
- package/extensions/dm-lens/dist/clients/typos-config.js +9 -0
- package/extensions/dm-lens/dist/clients/user-notify.js +15 -0
- package/extensions/dm-lens/dist/clients/vanished-instance-marker.js +18 -0
- package/extensions/dm-lens/dist/clients/warm-attach.js +210 -0
- package/extensions/dm-lens/dist/clients/widget-state.js +963 -0
- package/extensions/dm-lens/dist/clients/word-index-logger.js +21 -0
- package/extensions/dm-lens/dist/clients/word-index-store.js +222 -0
- package/extensions/dm-lens/dist/clients/word-index.js +1426 -0
- package/extensions/dm-lens/dist/clients/workspace-topology.js +261 -0
- package/extensions/dm-lens/dist/clients/write-ordering-guard.js +24 -0
- package/extensions/dm-lens/dist/clients/zizmor-config.js +160 -0
- package/extensions/dm-lens/dist/i18n.js +67 -0
- package/extensions/dm-lens/dist/index.js +1782 -0
- package/extensions/dm-lens/dist/mcp/analyze-cli.js +178 -0
- package/extensions/dm-lens/dist/mcp/build-staleness.js +55 -0
- package/extensions/dm-lens/dist/mcp/cli.js +78 -0
- package/extensions/dm-lens/dist/mcp/server.js +1208 -0
- package/extensions/dm-lens/dist/mcp/worker.js +33 -0
- package/extensions/dm-lens/dist/scripts/lib/process-scan.mjs +256 -0
- package/extensions/dm-lens/dist/scripts/lib/skills-predicate.mjs +53 -0
- package/extensions/dm-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +45 -0
- package/extensions/dm-lens/dist/tools/activate-tools.js +61 -0
- package/extensions/dm-lens/dist/tools/ast-grep-outline.js +127 -0
- package/extensions/dm-lens/dist/tools/ast-grep-replace.js +226 -0
- package/extensions/dm-lens/dist/tools/ast-grep-search.js +687 -0
- package/extensions/dm-lens/dist/tools/effective-config.js +59 -0
- package/extensions/dm-lens/dist/tools/lens-diagnostic-mark.js +240 -0
- package/extensions/dm-lens/dist/tools/lens-diagnostics.js +1484 -0
- package/extensions/dm-lens/dist/tools/lsp-diagnostics.js +1088 -0
- package/extensions/dm-lens/dist/tools/lsp-navigation.js +1194 -0
- package/extensions/dm-lens/dist/tools/lsp-structured-output.js +277 -0
- package/extensions/dm-lens/dist/tools/module-report.js +332 -0
- package/extensions/dm-lens/dist/tools/project-report.js +72 -0
- package/extensions/dm-lens/dist/tools/render-compact.js +272 -0
- package/extensions/dm-lens/dist/tools/scan-progress.js +31 -0
- package/extensions/dm-lens/dist/tools/shared.js +26 -0
- package/extensions/dm-lens/dist/tools/symbol-search.js +133 -0
- package/extensions/dm-lens/index.js +278 -101
- package/extensions/dm-lens/mcp/analyze-cli.js +3 -2
- package/extensions/dm-lens/mcp/build-staleness.js +1 -1
- package/extensions/dm-lens/mcp/server.js +144 -73
- package/extensions/dm-lens/package.json +4 -4
- package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-assert-tuple-test.yml +13 -0
- package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-boolean-in-except-test.yml +26 -0
- package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/no-http-headers-bracket-access-test.yml +10 -0
- package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/unchecked-numeric-parse-python-test.yml +18 -0
- package/extensions/dm-lens/rules/ast-grep-rules/rule-tests/unchecked-throwing-call-python-test.yml +4 -3
- package/extensions/dm-lens/rules/ast-grep-rules/rules/go-no-fmt-println.yml +2 -2
- package/extensions/dm-lens/rules/ast-grep-rules/rules/no-assert-tuple.yml +23 -13
- package/extensions/dm-lens/rules/ast-grep-rules/rules/no-boolean-in-except.yml +7 -3
- package/extensions/dm-lens/rules/ast-grep-rules/rules/no-console-except-error-js.yml +2 -2
- package/extensions/dm-lens/rules/ast-grep-rules/rules/no-console-except-error.yml +2 -2
- package/extensions/dm-lens/rules/ast-grep-rules/rules/no-http-headers-bracket-access.yml +12 -7
- package/extensions/dm-lens/rules/ast-grep-rules/rules/unchecked-numeric-parse-python.yml +44 -0
- package/extensions/dm-lens/rules/ast-grep-rules/rules/unchecked-throwing-call-python.yml +5 -3
- package/extensions/dm-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
- package/extensions/dm-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
- package/extensions/dm-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
- package/extensions/dm-lens/rules/tree-sitter-queries/typescript/console-statement.yml +2 -2
- package/extensions/dm-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +23 -7
- package/extensions/dm-lens/rules/typos/_typos.toml +4 -2
- package/extensions/dm-lens/scripts/lib/process-scan.mjs +1 -1
- package/extensions/dm-lens/scripts/lib/skills-predicate.mjs +53 -0
- package/extensions/dm-lens/scripts/lib/web-tree-sitter-dir.mjs +45 -0
- package/extensions/dm-lens/skills/pi-lens-ast-grep/SKILL.md +23 -6
- package/extensions/dm-lens/skills/pi-lens-lsp-navigation/SKILL.md +26 -9
- package/extensions/dm-lens/tools/activate-tools.js +10 -7
- package/extensions/dm-lens/tools/ast-grep-outline.js +2 -6
- package/extensions/dm-lens/tools/ast-grep-replace.js +5 -16
- package/extensions/dm-lens/tools/ast-grep-search.js +83 -38
- package/extensions/dm-lens/tools/effective-config.js +5 -4
- package/extensions/dm-lens/tools/lens-diagnostic-mark.js +5 -3
- package/extensions/dm-lens/tools/lens-diagnostics.js +478 -106
- package/extensions/dm-lens/tools/lsp-diagnostics.js +317 -172
- package/extensions/dm-lens/tools/lsp-navigation.js +26 -56
- package/extensions/dm-lens/tools/lsp-structured-output.js +3 -3
- package/extensions/dm-lens/tools/module-report.js +5 -5
- package/extensions/dm-lens/tools/project-report.js +9 -15
- package/extensions/dm-lens/tools/render-compact.js +220 -1
- package/extensions/dm-lens/tools/symbol-search.js +3 -5
- package/extensions/dm-mcp-adapter/OAUTH.md +368 -2
- package/extensions/dm-mcp-adapter/THIRD_PARTY_NOTICES.md +1 -1
- package/extensions/dm-mcp-adapter/agent-plugin-loader.js +73 -30
- package/extensions/dm-mcp-adapter/agent-plugin-provenance.js +26 -0
- package/extensions/dm-mcp-adapter/bearer-command-resolver.js +182 -0
- package/extensions/dm-mcp-adapter/claude-plugin-loader.js +350 -0
- package/extensions/dm-mcp-adapter/cli.js +82 -5
- package/extensions/dm-mcp-adapter/commands.js +89 -15
- package/extensions/dm-mcp-adapter/config.js +283 -33
- package/extensions/dm-mcp-adapter/consent-manager.js +32 -8
- package/extensions/dm-mcp-adapter/direct-tool-surface.js +223 -0
- package/extensions/dm-mcp-adapter/direct-tools.js +21 -216
- package/extensions/dm-mcp-adapter/dist/abort.js +35 -0
- package/extensions/dm-mcp-adapter/dist/agent-plugin-loader.js +73 -30
- package/extensions/dm-mcp-adapter/dist/agent-plugin-provenance.js +26 -0
- package/extensions/dm-mcp-adapter/dist/bearer-command-resolver.js +182 -0
- package/extensions/dm-mcp-adapter/dist/claude-plugin-loader.js +350 -0
- package/extensions/dm-mcp-adapter/dist/config.js +283 -33
- package/extensions/dm-mcp-adapter/dist/consent-manager.js +84 -0
- package/extensions/dm-mcp-adapter/dist/elicitation-handler.js +308 -0
- package/extensions/dm-mcp-adapter/dist/errors.js +225 -0
- package/extensions/dm-mcp-adapter/dist/http-ca.js +71 -0
- package/extensions/dm-mcp-adapter/dist/jev-client.js +359 -0
- package/extensions/dm-mcp-adapter/dist/jev-contracts.js +1 -0
- package/extensions/dm-mcp-adapter/dist/jev-key-store.js +176 -0
- package/extensions/dm-mcp-adapter/dist/json-schema-validator.js +70 -0
- package/extensions/dm-mcp-adapter/dist/lifecycle.js +387 -0
- package/extensions/dm-mcp-adapter/dist/logger.js +115 -0
- package/extensions/dm-mcp-adapter/dist/mcp-auth-fetch.js +86 -0
- package/extensions/dm-mcp-adapter/dist/mcp-auth-flow.js +949 -0
- package/extensions/dm-mcp-adapter/dist/mcp-auth.js +997 -0
- package/extensions/dm-mcp-adapter/dist/mcp-bearer-store.js +7 -136
- package/extensions/dm-mcp-adapter/dist/mcp-callback-server.js +381 -0
- package/extensions/dm-mcp-adapter/dist/mcp-oauth-provider.js +524 -0
- package/extensions/dm-mcp-adapter/dist/mcp-probe.js +151 -0
- package/extensions/dm-mcp-adapter/dist/mcp-tasks.js +300 -0
- package/extensions/dm-mcp-adapter/dist/mcp-trace.js +215 -0
- package/extensions/dm-mcp-adapter/dist/metadata-cache.js +10 -28
- package/extensions/dm-mcp-adapter/dist/npx-resolver.js +465 -0
- package/extensions/dm-mcp-adapter/dist/package-mcp-loader.js +5 -16
- package/extensions/dm-mcp-adapter/dist/request-headers-command.js +294 -0
- package/extensions/dm-mcp-adapter/dist/runtime-owner.js +94 -0
- package/extensions/dm-mcp-adapter/dist/sampling-handler.js +213 -0
- package/extensions/dm-mcp-adapter/dist/secure-keyring.js +191 -0
- package/extensions/dm-mcp-adapter/dist/server-manager.js +1514 -0
- package/extensions/dm-mcp-adapter/dist/session-approvals.js +127 -0
- package/extensions/dm-mcp-adapter/dist/session-recovery.js +82 -0
- package/extensions/dm-mcp-adapter/dist/state.js +1 -0
- package/extensions/dm-mcp-adapter/dist/types.js +39 -0
- package/extensions/dm-mcp-adapter/dist/ui-resource-handler.js +204 -0
- package/extensions/dm-mcp-adapter/dist/unix-socket-transport.js +83 -0
- package/extensions/dm-mcp-adapter/dist/utils.js +84 -9
- package/extensions/dm-mcp-adapter/elicitation-handler.js +27 -22
- package/extensions/dm-mcp-adapter/host-html-template.js +17 -18
- package/extensions/dm-mcp-adapter/http-ca.js +71 -0
- package/extensions/dm-mcp-adapter/index.js +904 -167
- package/extensions/dm-mcp-adapter/init.js +53 -42
- package/extensions/dm-mcp-adapter/jev-client.js +359 -0
- package/extensions/dm-mcp-adapter/jev-contracts.js +0 -0
- package/extensions/dm-mcp-adapter/jev-key-store.js +176 -0
- package/extensions/dm-mcp-adapter/json-schema-validator.js +19 -2
- package/extensions/dm-mcp-adapter/lazy-loader.js +7 -0
- package/extensions/dm-mcp-adapter/lifecycle.js +8 -3
- package/extensions/dm-mcp-adapter/mcp-auth-fetch.js +86 -0
- package/extensions/dm-mcp-adapter/mcp-auth-flow.js +228 -75
- package/extensions/dm-mcp-adapter/mcp-auth.js +312 -47
- package/extensions/dm-mcp-adapter/mcp-bearer-store.js +7 -136
- package/extensions/dm-mcp-adapter/mcp-code.js +151 -20
- package/extensions/dm-mcp-adapter/mcp-install.js +40 -0
- package/extensions/dm-mcp-adapter/mcp-oauth-provider.js +52 -8
- package/extensions/dm-mcp-adapter/mcp-output-guard.js +42 -43
- package/extensions/dm-mcp-adapter/mcp-panel-theme.js +79 -0
- package/extensions/dm-mcp-adapter/mcp-panel.js +294 -286
- package/extensions/dm-mcp-adapter/mcp-references.js +13 -18
- package/extensions/dm-mcp-adapter/mcp-script-worker.mjs +5 -1
- package/extensions/dm-mcp-adapter/mcp-setup-panel.js +317 -282
- package/extensions/dm-mcp-adapter/mcp-status.js +2 -0
- package/extensions/dm-mcp-adapter/mcp-tasks.js +309 -0
- package/extensions/dm-mcp-adapter/metadata-cache.js +11 -28
- package/extensions/dm-mcp-adapter/namespace-tools.js +43 -7
- package/extensions/dm-mcp-adapter/oauth.js +1 -1
- package/extensions/dm-mcp-adapter/package-mcp-loader.js +5 -16
- package/extensions/dm-mcp-adapter/package.json +4 -1
- package/extensions/dm-mcp-adapter/prompts.js +31 -4
- package/extensions/dm-mcp-adapter/proxy-modes.js +394 -199
- package/extensions/dm-mcp-adapter/request-headers-command.js +3 -2
- package/extensions/dm-mcp-adapter/runtime-owner.js +16 -1
- package/extensions/dm-mcp-adapter/sampling-handler.js +16 -25
- package/extensions/dm-mcp-adapter/sandbox-proxy-template.js +14 -90
- package/extensions/dm-mcp-adapter/search-ranking.js +31 -6
- package/extensions/dm-mcp-adapter/secure-keyring.js +191 -0
- package/extensions/dm-mcp-adapter/semantic-search.js +160 -0
- package/extensions/dm-mcp-adapter/server-manager.js +406 -117
- package/extensions/dm-mcp-adapter/session-approvals.js +127 -0
- package/extensions/dm-mcp-adapter/skills/mcp-scripting/SKILL.md +11 -1
- package/extensions/dm-mcp-adapter/test-runner.mjs +3 -4
- package/extensions/dm-mcp-adapter/tool-approval.js +32 -22
- package/extensions/dm-mcp-adapter/tool-metadata.js +18 -11
- package/extensions/dm-mcp-adapter/tool-registrar.js +7 -4
- package/extensions/dm-mcp-adapter/tool-result-renderer.js +4 -2
- package/extensions/dm-mcp-adapter/types.js +39 -0
- package/extensions/dm-mcp-adapter/ui-server.js +51 -36
- package/extensions/dm-mcp-adapter/ui-session.js +57 -25
- package/extensions/dm-mcp-adapter/utils.js +84 -9
- package/extensions/dm-ponytail/hooks/cursor-hooks.json +17 -0
- package/extensions/dm-ponytail/hooks/ponytail-activate.js +14 -2
- package/extensions/dm-ponytail/hooks/ponytail-mode-tracker.js +21 -2
- package/extensions/dm-ponytail/hooks/ponytail-runtime.js +23 -0
- package/extensions/dm-ponytail/package.json +1 -1
- package/extensions/dm-subagents/agents/claude-code-writer.md +1 -0
- package/extensions/dm-subagents/agents/codex-exec-writer.md +1 -0
- package/extensions/dm-subagents/agents/cursor-agent-writer.md +1 -0
- package/extensions/dm-subagents/agents/evidence-auditor.md +34 -0
- package/extensions/dm-subagents/agents/researcher.md +23 -13
- package/extensions/dm-subagents/agents/reviewer.md +6 -4
- package/extensions/dm-subagents/agents/scout.md +1 -1
- package/extensions/dm-subagents/agents/worker.md +3 -2
- package/extensions/dm-subagents/index.js +3 -2
- package/extensions/dm-subagents/inspector-runner.mjs +2 -2
- package/extensions/dm-subagents/install.mjs +1 -2
- package/extensions/dm-subagents/package.json +35 -1
- package/extensions/dm-subagents/prompts/council.md +6 -3
- package/extensions/dm-subagents/prompts/parallel-review.md +1 -1
- package/extensions/dm-subagents/runner-peer-loader.mjs +18 -0
- package/extensions/dm-subagents/runner-peer-preload.mjs +29 -0
- package/extensions/dm-subagents/skills/dm-subagents/SKILL.md +35 -22
- package/extensions/dm-subagents/skills/dm-subagents/references/constraints-and-recipes.md +9 -5
- package/extensions/dm-subagents/skills/dm-subagents/references/execution-controls.md +40 -19
- package/extensions/dm-subagents/skills/dm-subagents/references/management-authoring-rpc.md +6 -6
- package/extensions/dm-subagents/skills/dm-subagents/references/multi-lane-orchestration.md +11 -1
- package/extensions/dm-subagents/skills/dm-subagents/references/prompting-and-roles.md +35 -30
- package/extensions/dm-subagents/skills/dm-subagents/references/review-and-validation.md +3 -3
- package/extensions/dm-subagents/src/agents/advertised-agent-prompt.js +70 -0
- package/extensions/dm-subagents/src/agents/agent-management.js +276 -172
- package/extensions/dm-subagents/src/agents/agent-memory.js +92 -3
- package/extensions/dm-subagents/src/agents/agent-serializer.js +17 -8
- package/extensions/dm-subagents/src/agents/agents.js +389 -207
- package/extensions/dm-subagents/src/agents/builtin-names.js +1 -0
- package/extensions/dm-subagents/src/agents/chain-serializer.js +7 -0
- package/extensions/dm-subagents/src/agents/global-npm-root.js +47 -0
- package/extensions/dm-subagents/src/agents/proactive-skills.js +1 -1
- package/extensions/dm-subagents/src/agents/runtime-agent-registry.js +17 -13
- package/extensions/dm-subagents/src/agents/skills.js +36 -10
- package/extensions/dm-subagents/src/api/capability-ceiling.js +0 -1
- package/extensions/dm-subagents/src/api/child-tool-plan.js +3 -0
- package/extensions/dm-subagents/src/api/preflight.js +75 -64
- package/extensions/dm-subagents/src/api/required-child-extensions.js +3 -0
- package/extensions/dm-subagents/src/api/workflow-resources.js +1 -0
- package/extensions/dm-subagents/src/extension/config.js +27 -18
- package/extensions/dm-subagents/src/extension/doctor.js +10 -13
- package/extensions/dm-subagents/src/extension/fanout-child.js +91 -14
- package/extensions/dm-subagents/src/extension/herdr-dm-bridge.js +258 -0
- package/extensions/dm-subagents/src/extension/index.js +202 -66
- package/extensions/dm-subagents/src/extension/public-execution.js +55 -4
- package/extensions/dm-subagents/src/extension/rpc.js +18 -27
- package/extensions/dm-subagents/src/extension/schemas.js +99 -84
- package/extensions/dm-subagents/src/extension/subagent-guide.js +14 -3
- package/extensions/dm-subagents/src/extension/tool-activation.js +157 -0
- package/extensions/dm-subagents/src/extension/tool-description.js +30 -78
- package/extensions/dm-subagents/src/inspectors/actions.js +145 -0
- package/extensions/dm-subagents/src/inspectors/ghostty/actions.js +60 -0
- package/extensions/dm-subagents/src/inspectors/ghostty/plugin.js +17 -0
- package/extensions/dm-subagents/src/inspectors/herdr/actions.js +94 -179
- package/extensions/dm-subagents/src/inspectors/herdr/plugin.js +13 -0
- package/extensions/dm-subagents/src/inspectors/herdr/project-panes.js +1 -1
- package/extensions/dm-subagents/src/inspectors/{herdr/inspector-runner.js → inspector-runner.js} +31 -25
- package/extensions/dm-subagents/src/inspectors/plugins.js +5 -0
- package/extensions/dm-subagents/src/inspectors/{herdr/session-roots-codec.js → session-roots-codec.js} +1 -6
- package/extensions/dm-subagents/src/inspectors/types.js +1 -0
- package/extensions/dm-subagents/src/integrations/dm-web-session-liveness.js +50 -0
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +39 -5
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +256 -151
- package/extensions/dm-subagents/src/intercom/result-intercom.js +6 -0
- package/extensions/dm-subagents/src/intercom/supervisor-ui.js +199 -0
- package/extensions/dm-subagents/src/missions/workflow-state.js +30 -17
- package/extensions/dm-subagents/src/policy/authority.js +6 -2
- package/extensions/dm-subagents/src/profiles/profiles.js +10 -5
- package/extensions/dm-subagents/src/runs/background/active-async-capacity.js +28 -35
- package/extensions/dm-subagents/src/runs/background/active-run-index.js +17 -0
- package/extensions/dm-subagents/src/runs/background/async-execution.js +580 -389
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +71 -47
- package/extensions/dm-subagents/src/runs/background/async-resume.js +61 -26
- package/extensions/dm-subagents/src/runs/background/async-retention.js +8 -0
- package/extensions/dm-subagents/src/runs/background/async-status-snapshot.js +3 -4
- package/extensions/dm-subagents/src/runs/background/async-status.js +90 -13
- package/extensions/dm-subagents/src/runs/background/auto-drain.js +57 -33
- package/extensions/dm-subagents/src/runs/background/binary-bootstrap.js +54 -0
- package/extensions/dm-subagents/src/runs/background/chain-append.js +1 -1
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +11 -27
- package/extensions/dm-subagents/src/runs/background/control-channel.js +105 -256
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +67 -10
- package/extensions/dm-subagents/src/runs/background/notify.js +252 -17
- package/extensions/dm-subagents/src/runs/background/owned-process-tree.js +33 -2
- package/extensions/dm-subagents/src/runs/background/process-terminal-candidate.js +88 -0
- package/extensions/dm-subagents/src/runs/background/process-terminal.js +29 -87
- package/extensions/dm-subagents/src/runs/background/result-files.js +8 -4
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +15 -3
- package/extensions/dm-subagents/src/runs/background/retained-children.js +3 -2
- package/extensions/dm-subagents/src/runs/background/retained-nested-route-tracker.js +86 -0
- package/extensions/dm-subagents/src/runs/background/run-child-session.js +574 -0
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +9 -5
- package/extensions/dm-subagents/src/runs/background/run-status.js +114 -11
- package/extensions/dm-subagents/src/runs/background/runner-aliases.js +129 -0
- package/extensions/dm-subagents/src/runs/background/runner-child-launch.js +62 -0
- package/extensions/dm-subagents/src/runs/background/runner-child-sessions.js +16 -0
- package/extensions/dm-subagents/src/runs/background/runner-http-dispatcher.js +84 -0
- package/extensions/dm-subagents/src/runs/background/runner-startup-failure.js +43 -0
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +119 -20
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +33 -10
- package/extensions/dm-subagents/src/runs/background/steering.js +24 -3
- package/extensions/dm-subagents/src/runs/background/subagent-runner-bootstrap.js +238 -0
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +1008 -1344
- package/extensions/dm-subagents/src/runs/background/subagent-wait.js +156 -26
- package/extensions/dm-subagents/src/runs/background/wait-completions.js +91 -23
- package/extensions/dm-subagents/src/runs/background/wait-subscriptions.js +10 -3
- package/extensions/dm-subagents/src/runs/background/wait-tool.js +8 -12
- package/extensions/dm-subagents/src/runs/background/workflow-terminal-proof.js +60 -0
- package/extensions/dm-subagents/src/runs/foreground/async-steering-action.js +29 -26
- package/extensions/dm-subagents/src/runs/foreground/async-stop-action.js +94 -2
- package/extensions/dm-subagents/src/runs/foreground/execution.js +446 -648
- package/extensions/dm-subagents/src/runs/foreground/foreground-control.js +4 -0
- package/extensions/dm-subagents/src/runs/foreground/foreground-history.js +5 -2
- package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +8 -4
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +1337 -445
- package/extensions/dm-subagents/src/runs/foreground/workflow-detach-reconcile.js +10 -5
- package/extensions/dm-subagents/src/runs/foreground/workflow-foreground-steering.js +65 -90
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +265 -68
- package/extensions/dm-subagents/src/runs/shared/agent-contract.js +1 -1
- package/extensions/dm-subagents/src/runs/shared/async-status-projection.js +133 -76
- package/extensions/dm-subagents/src/runs/shared/capability-ceiling.js +4 -2
- package/extensions/dm-subagents/src/runs/shared/child-hooks.js +166 -0
- package/extensions/dm-subagents/src/runs/shared/child-identity.js +10 -2
- package/extensions/dm-subagents/src/runs/shared/child-launch-plan.js +19 -2
- package/extensions/dm-subagents/src/runs/shared/child-launch.js +212 -0
- package/extensions/dm-subagents/src/runs/shared/child-lifecycle.js +22 -0
- package/extensions/dm-subagents/src/runs/shared/child-runtime-config.js +31 -0
- package/extensions/dm-subagents/src/runs/shared/child-session.js +378 -0
- package/extensions/dm-subagents/src/runs/shared/child-tool-plan.js +299 -0
- package/extensions/dm-subagents/src/runs/shared/claude-code-adapter.js +1 -1
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +148 -32
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +6 -4
- package/extensions/dm-subagents/src/runs/shared/effective-system-prompt.js +19 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-contract.js +6 -1
- package/extensions/dm-subagents/src/runs/shared/external-cli-preflight.js +14 -2
- package/extensions/dm-subagents/src/runs/shared/external-cli-runner.js +6 -7
- package/extensions/dm-subagents/src/runs/shared/external-job-bridge.js +60 -0
- package/extensions/dm-subagents/src/runs/shared/git-environment.js +25 -0
- package/extensions/dm-subagents/src/runs/shared/herdr-connection.js +341 -0
- package/extensions/dm-subagents/src/runs/shared/herdr-dm-protocol.js +60 -0
- package/extensions/dm-subagents/src/runs/shared/herdr-external-adapters.js +555 -0
- package/extensions/dm-subagents/src/runs/shared/herdr-machine.js +239 -0
- package/extensions/dm-subagents/src/runs/shared/herdr-placed-run.js +987 -0
- package/extensions/dm-subagents/src/runs/shared/host-step-status.js +2 -0
- package/extensions/dm-subagents/src/runs/shared/lane-metadata.js +23 -3
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +4 -3
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-grant.js +15 -5
- package/extensions/dm-subagents/src/runs/shared/model-resolution-diagnostic.js +43 -0
- package/extensions/dm-subagents/src/runs/shared/{model-fallback.js → model-resolution.js} +44 -128
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +39 -49
- package/extensions/dm-subagents/src/runs/shared/nested-path.js +0 -13
- package/extensions/dm-subagents/src/runs/shared/orca-progress-tabs.js +22 -12
- package/extensions/dm-subagents/src/runs/shared/parallel-handoff.js +78 -2
- package/extensions/dm-subagents/src/runs/shared/permissions.js +1 -16
- package/extensions/dm-subagents/src/runs/shared/process-signal.js +3 -0
- package/extensions/dm-subagents/src/runs/shared/readonly-drain-observation.js +51 -0
- package/extensions/dm-subagents/src/runs/shared/run-fanout-budget.js +0 -13
- package/extensions/dm-subagents/src/runs/shared/runtime-acknowledged-extensions.js +0 -26
- package/extensions/dm-subagents/src/runs/shared/single-output.js +20 -2
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +263 -10
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +6 -14
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +117 -370
- package/extensions/dm-subagents/src/runs/shared/tool-availability.js +12 -50
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +10 -13
- package/extensions/dm-subagents/src/runs/shared/tool-timeout.js +1 -1
- package/extensions/dm-subagents/src/runs/shared/usage-reconciliation.js +69 -0
- package/extensions/dm-subagents/src/runs/shared/workflow-async-child-guidance.js +11 -0
- package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-plan.js +30 -10
- package/extensions/dm-subagents/src/runs/shared/worktree-setup-command.js +195 -0
- package/extensions/dm-subagents/src/runs/shared/worktree.js +814 -141
- package/extensions/dm-subagents/src/shared/atomic-json.js +2 -1
- package/extensions/dm-subagents/src/shared/child-cache-retention.js +19 -0
- package/extensions/dm-subagents/src/shared/fork-context.js +40 -77
- package/extensions/dm-subagents/src/shared/fork-session-cwd.js +24 -0
- package/extensions/dm-subagents/src/shared/jsonl-writer.js +8 -0
- package/extensions/dm-subagents/src/shared/launch-contract.js +37 -6
- package/extensions/dm-subagents/src/shared/model-response-aliases.js +15 -0
- package/extensions/dm-subagents/src/shared/opencode-session-headers.js +15 -0
- package/extensions/dm-subagents/src/shared/pruned-fork.js +83 -76
- package/extensions/dm-subagents/src/shared/required-child-extensions.js +72 -0
- package/extensions/dm-subagents/src/shared/shortcuts.js +0 -2
- package/extensions/dm-subagents/src/shared/thinking-ceiling.js +0 -6
- package/extensions/dm-subagents/src/shared/types.js +16 -12
- package/extensions/dm-subagents/src/shared/utils.js +22 -7
- package/extensions/dm-subagents/src/shared/watch-strategy.js +2 -0
- package/extensions/dm-subagents/src/shared/workflow-child-permit.js +70 -0
- package/extensions/dm-subagents/src/slash/delegation-adapters.js +15 -1
- package/extensions/dm-subagents/src/slash/delegation-request.js +13 -0
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +28 -1
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +15 -2
- package/extensions/dm-subagents/src/slash/slash-commands.js +12 -269
- package/extensions/dm-subagents/src/slash/subagent-cost.js +255 -0
- package/extensions/dm-subagents/src/slash/subagents-admin.js +49 -25
- package/extensions/dm-subagents/src/tui/fleet-status.js +224 -23
- package/extensions/dm-subagents/src/tui/fleet.js +38 -25
- package/extensions/dm-subagents/src/tui/render.js +636 -63
- package/extensions/dm-subagents/src/watchdog/child-status.js +42 -23
- package/extensions/dm-subagents/src/watchdog/diff-tool.js +86 -0
- package/extensions/dm-subagents/src/watchdog/emission-guard.js +4 -3
- package/extensions/dm-subagents/src/watchdog/guidance.js +19 -0
- package/extensions/dm-subagents/src/watchdog/lsp-diagnostics.js +1 -1
- package/extensions/dm-subagents/src/watchdog/model-selection.js +18 -1
- package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +16 -10
- package/extensions/dm-subagents/src/watchdog/register-child.js +39 -26
- package/extensions/dm-subagents/src/watchdog/register-main.js +51 -43
- package/extensions/dm-subagents/src/watchdog/render.js +5 -7
- package/extensions/dm-subagents/src/watchdog/review.js +142 -67
- package/extensions/dm-subagents/src/watchdog/rules.js +55 -0
- package/extensions/dm-subagents/src/watchdog/runtime.js +167 -109
- package/extensions/dm-subagents/src/watchdog/scope.js +1 -9
- package/extensions/dm-subagents/src/watchdog/settings.js +55 -99
- package/extensions/dm-subagents/src/watchdog/tool-actions.js +11 -12
- package/extensions/dm-subagents/src/watchdog/turn-delta.js +30 -5
- package/extensions/dm-subagents/src/watchdog/types.js +2 -4
- package/extensions/dm-subagents/src/watchdog/warning-format.js +2 -3
- package/extensions/dm-subagents/src/workflows/chat-progress.js +4 -4
- package/extensions/dm-subagents/src/workflows/scripted-workflow.js +482 -36
- package/extensions/dm-subagents/src/workflows/workflow-checklist.js +303 -0
- package/extensions/dm-subagents/src/workflows/workflow-child-summary.js +57 -5
- package/extensions/dm-subagents/src/workflows/workflow-preflight.js +27 -1
- package/extensions/dm-subagents/src/workflows/workflow-receipt.js +51 -3
- package/extensions/dm-subagents/src/workflows/workflow-resources.js +226 -0
- package/extensions/dm-subagents/src/workflows/workflow-settlement.js +5 -0
- package/extensions/dm-web-access/abortable.js +19 -0
- package/extensions/dm-web-access/anysearch.js +4 -13
- package/extensions/dm-web-access/baizhi.js +123 -0
- package/extensions/dm-web-access/bocha.js +3 -24
- package/extensions/dm-web-access/brave.js +3 -23
- package/extensions/dm-web-access/brightdata.js +5 -30
- package/extensions/dm-web-access/content-find.js +181 -47
- package/extensions/dm-web-access/crawl4ai.js +166 -0
- package/extensions/dm-web-access/credential-source.js +1 -0
- package/extensions/dm-web-access/curator-page.js +27 -2
- package/extensions/dm-web-access/curator-run.js +36 -0
- package/extensions/dm-web-access/curator-server.js +11 -2
- package/extensions/dm-web-access/domain-filter-normalization.js +17 -0
- package/extensions/dm-web-access/duckduckgo.js +4 -24
- package/extensions/dm-web-access/extract.js +54 -12
- package/extensions/dm-web-access/fetch-params.js +1 -1
- package/extensions/dm-web-access/firecrawl.js +7 -45
- package/extensions/dm-web-access/gemini-search.js +101 -46
- package/extensions/dm-web-access/github-extract.js +2 -11
- package/extensions/dm-web-access/index.js +382 -247
- package/extensions/dm-web-access/jina-search.js +4 -13
- package/extensions/dm-web-access/kagi.js +4 -13
- package/extensions/dm-web-access/kimi-search.js +5 -30
- package/extensions/dm-web-access/mistral-search.js +251 -0
- package/extensions/dm-web-access/ollama.js +2 -7
- package/extensions/dm-web-access/openai-search.js +204 -46
- package/extensions/dm-web-access/opencode-session-headers.js +15 -0
- package/extensions/dm-web-access/package.json +1 -1
- package/extensions/dm-web-access/page-query.js +14 -4
- package/extensions/dm-web-access/parallel.js +1 -17
- package/extensions/dm-web-access/pdf-extract.js +1 -0
- package/extensions/dm-web-access/perplexity.js +10 -1
- package/extensions/dm-web-access/querit.js +5 -34
- package/extensions/dm-web-access/query-rewrite.js +6 -2
- package/extensions/dm-web-access/search-answer-formatting.js +6 -0
- package/extensions/dm-web-access/search-result-count-normalization.js +5 -0
- package/extensions/dm-web-access/search1api.js +5 -34
- package/extensions/dm-web-access/searchinfinity.js +5 -34
- package/extensions/dm-web-access/searxng.js +3 -23
- package/extensions/dm-web-access/serpapi.js +183 -0
- package/extensions/dm-web-access/serpbase.js +3 -24
- package/extensions/dm-web-access/serpdive.js +3 -23
- package/extensions/dm-web-access/serper.js +5 -30
- package/extensions/dm-web-access/serply.js +184 -0
- package/extensions/dm-web-access/source-check.js +10 -46
- package/extensions/dm-web-access/ssrf-protection.js +3 -1
- package/extensions/dm-web-access/storage.js +9 -0
- package/extensions/dm-web-access/summary-review.js +36 -25
- package/extensions/dm-web-access/tavily.js +3 -23
- package/extensions/dm-web-access/tinyfish.js +5 -34
- package/extensions/dm-web-access/tool-activation.js +112 -0
- package/extensions/dm-web-access/utils.js +27 -10
- package/extensions/dm-web-access/valyu.js +5 -30
- package/extensions/dm-web-access/xai-search.js +78 -42
- package/extensions/dm-web-access/xcrawl.js +5 -30
- package/package.json +7 -4
- package/extensions/dm-lens/tools/ast-dump.js +0 -101
- package/extensions/dm-subagents/src/api/dm-args.js +0 -3
- package/extensions/dm-subagents/src/runs/shared/child-protocol.js +0 -447
- package/extensions/dm-subagents/src/runs/shared/completion-evidence.js +0 -40
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +0 -173
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +0 -581
- package/extensions/dm-subagents/src/runs/shared/llm-intent-arbiter.js +0 -190
- package/extensions/dm-subagents/src/runs/shared/model-exclusions.js +0 -207
- package/extensions/dm-subagents/src/runs/shared/subagent-startup-retry.js +0 -50
- package/extensions/dm-subagents/src/runs/shared/task-intent.js +0 -130
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +0 -68
- /package/extensions/dm-subagents/src/inspectors/{herdr/shell-command.js → shell-command.js} +0 -0
|
@@ -21,10 +21,13 @@ import { handleManagementAction } from "../../agents/agent-management.js";
|
|
|
21
21
|
import { handleRefinementAction } from "../../agents/agent-refinements.js";
|
|
22
22
|
import { buildDoctorReport } from "../../extension/doctor.js";
|
|
23
23
|
import { readSubagentGuide } from "../../extension/subagent-guide.js";
|
|
24
|
-
import { normalizePublicSubagentExecution } from "../../extension/public-execution.js";
|
|
24
|
+
import { normalizePublicSubagentExecution, validateWorkflowCapacityOverrides } from "../../extension/public-execution.js";
|
|
25
25
|
import { runSync } from "./execution.js";
|
|
26
26
|
import { handleWatchdogToolAction, WATCHDOG_TOOL_ACTIONS } from "../../watchdog/tool-actions.js";
|
|
27
|
-
import {
|
|
27
|
+
import { applyWatchdogLaunchRules } from "../../watchdog/rules.js";
|
|
28
|
+
import { childWatchdogProgressForModel } from "../../watchdog/child-status.js";
|
|
29
|
+
import { normalizeParentModel, resolveEffectiveSubagentModel, resolveModelOrigin } from "../shared/model-resolution.js";
|
|
30
|
+
import { projectChainOutputSchemas, resolveEffectiveOutputSchema } from "../shared/child-launch-plan.js";
|
|
28
31
|
import { formatRetainedChildren, listRetainedChildren } from "../background/retained-children.js";
|
|
29
32
|
import { resolveModelScopesForAgent } from "../shared/model-scope.js";
|
|
30
33
|
import { recordRun } from "../shared/run-history.js";
|
|
@@ -40,27 +43,30 @@ import { updateActiveRunIndex } from "../background/active-run-index.js";
|
|
|
40
43
|
import { steeringReceipt } from "../background/steering.js";
|
|
41
44
|
import { acquireActiveAsyncCapacity, ActiveAsyncCapacityError, getActiveAsyncCapacitySnapshot, resolveAbandonedSlotReleaseAfterMs, resolveMaxActiveAsyncRunsPerSession, transferActiveAsyncCapacity } from "../background/active-async-capacity.js";
|
|
42
45
|
import { isScheduledRunAction } from "../background/scheduled-runs.js";
|
|
46
|
+
import { encodeIndexSegment } from "../background/index-segment.js";
|
|
43
47
|
import { enqueueChainAppendRequest, readPendingChainAppendRequests, runnerStepOutputNames } from "../background/chain-append.js";
|
|
44
48
|
import { ChainOutputValidationError, validateChainOutputBindingsWithContext } from "../shared/chain-outputs.js";
|
|
45
|
-
import { normalizeGateAcceptance, validateExecutionAcceptance } from "../shared/acceptance.js";
|
|
46
|
-
import { canPreferFork, createForkContextResolver,
|
|
49
|
+
import { acceptanceHasTypedVerify, normalizeGateAcceptance, resolveAcceptanceReportMode, TYPED_VERIFY_OUTPUT_SCHEMA_CONFLICT, validateAcceptanceInput, validateExecutionAcceptance, validateExecutionAcceptancePolicy } from "../shared/acceptance.js";
|
|
50
|
+
import { canPreferFork, createForkContextResolver, resolveSubagentLaunchContext } from "../../shared/fork-context.js";
|
|
47
51
|
import { createPrunedForkSessionWriter } from "../../shared/pruned-fork.js";
|
|
48
52
|
import { resolveCurrentSessionId } from "../../shared/session-identity.js";
|
|
49
53
|
import { currentCompletionOwnerId } from "../../shared/completion-owner.js";
|
|
54
|
+
import { SUBAGENT_ASYNC_COMPLETE_EVENT } from "../../shared/types.js";
|
|
50
55
|
import { applyIntercomBridgeToAgent, INTERCOM_BRIDGE_MARKER, resolveIntercomBridge, resolveIntercomSessionTarget, resolveSubagentIntercomTarget } from "../../intercom/intercom-bridge.js";
|
|
51
56
|
import { formatControlIntercomMessage, formatControlNoticeMessage, resolveControlConfig, shouldNotifyControlEvent } from "../shared/subagent-control.js";
|
|
52
57
|
import { formatSpawnBudget, getSpawnBudgetSnapshot, grantSpawnBudget, preflightSpawnBudget, preflightSpawnBudgetGrant, reserveSpawnBudget } from "../shared/spawn-budget.js";
|
|
53
|
-
import { claimRunFanoutBatch, claimRunFanoutBatchWithCommit, createRunFanoutBudget,
|
|
58
|
+
import { claimRunFanoutBatch, claimRunFanoutBatchWithCommit, createRunFanoutBudget, formatRunFanoutBudget, getRunFanoutBudgetSnapshot, readRunFanoutBudgetDescriptor, RunFanoutLimitError, writeRunFanoutBudgetDescriptor } from "../shared/run-fanout-budget.js";
|
|
59
|
+
import { retainLiveForegroundNestedRoute } from "../../integrations/dm-web-session-liveness.js";
|
|
54
60
|
import { validateToolBudgetConfig } from "../shared/tool-budget.js";
|
|
55
61
|
import { usageBudgetExceededMessage, usageBudgetState, validateUsageBudgetConfig } from "../shared/usage-budget.js";
|
|
56
62
|
import { intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling } from "../shared/capability-ceiling.js";
|
|
57
|
-
import {
|
|
63
|
+
import { isAgentContract } from "../shared/agent-contract.js";
|
|
58
64
|
import { normalizeExtensionBindings } from "../shared/extension-bindings.js";
|
|
65
|
+
import { resolveRequiredChildExtensions } from "../../shared/required-child-extensions.js";
|
|
59
66
|
import { finalizeSingleOutput, injectSingleOutputInstruction, normalizeSingleOutputOverride, outputPathMappingFromTask, resolveSingleOutputPath, validateFileOnlyOutputMode } from "../shared/single-output.js";
|
|
60
67
|
import { assertJsonSchemaObject, cleanupStructuredOutputRuntime, createStructuredOutputRuntime } from "../shared/structured-output.js";
|
|
61
|
-
import { compactForegroundDetails, getSingleResultOutput, readStatus, resolveChildCwd, sumResultsCost, sumResultsUsage } from "../../shared/utils.js";
|
|
62
|
-
import {
|
|
63
|
-
import { discardPreservedWorktrees, formatParallelHandoffError, formatParallelHandoffReference, formatStoredParallelHandoffCleanup, parallelHandoffPath, readParallelHandoffManifest, recordParallelHandoffMerge, recordParallelHandoffSupersession, writeParallelHandoffGroup, writePendingParallelHandoff } from "../shared/parallel-handoff.js";
|
|
68
|
+
import { compactForegroundDetails, getSingleResultOutput, PROMPT_REDACTED, readStatus, resolveChildCwd, sumResultsCost, sumResultsUsage } from "../../shared/utils.js";
|
|
69
|
+
import { discardPreservedWorktrees, formatParallelHandoffError, formatParallelHandoffReference, formatStoredParallelHandoffCleanup, parallelHandoffPath, readParallelHandoffManifest, recordParallelHandoffMerge, recordParallelHandoffSupersession, writeParallelHandoffGroup, writeWorktreeSetupHandoff } from "../shared/parallel-handoff.js";
|
|
64
70
|
import { summarizeContextModes } from "../shared/context-mode.js";
|
|
65
71
|
import {
|
|
66
72
|
attachNestedChildrenToResultChildren,
|
|
@@ -71,50 +77,60 @@ import {
|
|
|
71
77
|
stripDetailsOutputsForIntercomReceipt
|
|
72
78
|
} from "../../intercom/result-intercom.js";
|
|
73
79
|
import { applySteeringRecoveryAgentConfig, asyncReviveRequiresRecoveryDescriptor, buildRevivedAsyncTask, readAsyncRecoveryDescriptor, resolveAsyncResumeTarget, resolveAsyncRunLocation } from "../background/async-resume.js";
|
|
74
|
-
import { deliverInterruptRequest, readRevivalBriefs, requestAsyncSteer } from "../background/control-channel.js";
|
|
75
|
-
import { updateSteeringTarget, waitForSteeringAction } from "../background/steering.js";
|
|
80
|
+
import { closeSteerInbox, consumeSteerRequests, deliverInterruptRequest, readRevivalBriefs, requestAsyncSteer, watchAsyncControlInbox } from "../background/control-channel.js";
|
|
81
|
+
import { createSteeringStatus, recordSteeringRequest, steeringStatus, updateSteeringTarget, waitForSteeringAction } from "../background/steering.js";
|
|
76
82
|
import { canQueueRetainedAsyncFollowUp, steerAsyncRun } from "./async-steering-action.js";
|
|
77
83
|
import {
|
|
78
|
-
removeWorkflowForegroundSteeringRoute,
|
|
79
84
|
resolveWorkflowForegroundSteeringTarget,
|
|
80
85
|
steerWorkflowForegroundTarget,
|
|
81
|
-
|
|
82
|
-
workflowForegroundSteeringLaunchOptions
|
|
86
|
+
steerWorkflowRun
|
|
83
87
|
} from "./workflow-foreground-steering.js";
|
|
84
88
|
import { stopAsyncRun } from "./async-stop-action.js";
|
|
85
89
|
import { dismissRecoveredWorkflow } from "./async-dismiss-action.js";
|
|
86
90
|
import { promotePausedWorkflowIfSettled, reconcileDetachedWorkflowChildCompletion } from "./workflow-detach-reconcile.js";
|
|
87
91
|
import { reconcileAsyncRun } from "../background/stale-run-reconciler.js";
|
|
88
92
|
import { resolveAsyncRootResultPath, waitForImportedAsyncRoot } from "../background/chain-root-attachment.js";
|
|
89
|
-
import { resultFilePath, writeAsyncResultFile } from "../background/result-files.js";
|
|
90
|
-
import { attachRootChildrenToSteps, createNestedRoute, findNestedControlResult,
|
|
93
|
+
import { fallbackResultPayloadPathForSessionRun, removeResultIndex, resultFilePath, writeAsyncResultFile } from "../background/result-files.js";
|
|
94
|
+
import { attachRootChildrenToSteps, createNestedRoute, findNestedControlResult, inheritedNestedParentAddressOf, inheritedNestedRouteOf, nestedRunScope, resolveNestedAsyncDir, retainNestedLookupRoute, snapshotNestedEventFiles, updateForegroundNestedProjection, writeNestedControlRequest, writeNestedEvent } from "../shared/nested-events.js";
|
|
91
95
|
import { resolveSubagentRunId } from "../background/run-id-resolver.js";
|
|
92
96
|
import { formatNestedRunStatusLines } from "../shared/nested-render.js";
|
|
93
|
-
import { isStoppableAsyncStatusStep, resolveAsyncStatusChild } from "../shared/child-identity.js";
|
|
97
|
+
import { isStoppableAsyncStatusStep, resolveAsyncStatusChild, stopStoppableAsyncStatusChildren } from "../shared/child-identity.js";
|
|
94
98
|
import { inspectSubagentStatus } from "../background/run-status.js";
|
|
95
99
|
import { getExternalJobProvider } from "../../api/external-job-provider.js";
|
|
96
100
|
import { externalJobFollowUpRequestDigest, externalJobFollowUpRequestId, externalJobFollowUpRunId, externalJobPromptDigest, externalJobStableJson } from "../shared/external-job-runner.js";
|
|
97
101
|
import { externalCliReceiptMetadata, normalizeExternalCliRunnerStatus } from "../shared/external-cli-contract.js";
|
|
102
|
+
import { formatHerdrMachineRunnerUnsupported, resolveHerdrMachinePlacement } from "../shared/herdr-machine.js";
|
|
98
103
|
import { applyForceTopLevelAsyncOverride } from "../background/top-level-async.js";
|
|
99
104
|
import { handleMissionAction, MISSION_ACTIONS } from "../../missions/actions.js";
|
|
100
105
|
import { attachMissionToLaunchResult, prepareMissionLaunch, writeMissionAsyncBinding } from "../../missions/lifecycle.js";
|
|
101
106
|
import { MissionNotFoundError, updateMission } from "../../missions/store.js";
|
|
102
107
|
import { createMissionWorkflowState } from "../../missions/workflow-state.js";
|
|
103
108
|
import { resolveAuthorityDecision } from "../../policy/authority.js";
|
|
104
|
-
import {
|
|
109
|
+
import { handleInspectorAction, INSPECTOR_ACTIONS } from "../../inspectors/actions.js";
|
|
110
|
+
import { createBuiltinInspectorPlugins } from "../../inspectors/plugins.js";
|
|
105
111
|
import { handleHerdrProjectPaneAction, HERDR_PROJECT_PANE_ACTIONS } from "../../inspectors/herdr/project-panes.js";
|
|
106
112
|
import { previewSimpleWorkflowRun, runWorkflowScript, validateWorkflowScript, WorkflowScriptError } from "../../workflows/scripted-workflow.js";
|
|
113
|
+
import { formatIncrementalChildCompletion, incrementalChildCompletionTriggersTurn } from "../background/notify.js";
|
|
107
114
|
import { executeWorkflowHostCommand, resolveWorkflowHostOutputClaimPath } from "../../workflows/host-command.js";
|
|
108
|
-
import { buildWorkflowReceipt, resolveWorkflowReceiptResumeEntry, writeWorkflowReceipt } from "../../workflows/workflow-receipt.js";
|
|
115
|
+
import { buildWorkflowReceipt, readWorkflowReceipt, workflowReceiptPath, resolveWorkflowReceiptResumeEntry, writeWorkflowReceipt } from "../../workflows/workflow-receipt.js";
|
|
109
116
|
import { upsertHostStep, validHostStepNodes } from "../shared/host-step-status.js";
|
|
110
117
|
import { assertWorkflowLaneKey, normalizeWorkflowLaneMetadata } from "../shared/lane-metadata.js";
|
|
111
|
-
import { parseWorkflowChildSummary, workflowChildSummary } from "../../workflows/workflow-child-summary.js";
|
|
118
|
+
import { parseWorkflowChildSummary, workflowChildProgress, workflowChildSummary } from "../../workflows/workflow-child-summary.js";
|
|
112
119
|
import { resolveWorkflowChatProgress } from "../../workflows/chat-progress.js";
|
|
113
120
|
import { annotateWorkflowPreflightTrace, formatWorkflowPreflight, formatWorkflowPreflightWarnings, normalizeWorkflowPreflight, workflowPreflightWarnings } from "../../workflows/workflow-preflight.js";
|
|
114
|
-
import {
|
|
121
|
+
import {
|
|
122
|
+
authorizeWorkflowResourceHost,
|
|
123
|
+
claimWorkflowChildPermit,
|
|
124
|
+
consumeWorkflowResourcePermit,
|
|
125
|
+
validateWorkflowChildPermitRoot
|
|
126
|
+
} from "../../shared/workflow-child-permit.js";
|
|
127
|
+
import { deepFreezeWorkflowArgs, normalizeWorkflowArgs, resolveWorkflowResource } from "../../workflows/workflow-resources.js";
|
|
128
|
+
import { stableJsonDigest } from "../../shared/launch-contract.js";
|
|
115
129
|
import {
|
|
116
130
|
cleanupWorktrees,
|
|
117
131
|
createWorktrees,
|
|
132
|
+
preflightWorktreeSource,
|
|
133
|
+
withWorktreeTransaction,
|
|
118
134
|
diffWorktrees,
|
|
119
135
|
formatWorktreeDiffSummary
|
|
120
136
|
} from "../shared/worktree.js";
|
|
@@ -124,9 +140,12 @@ import {
|
|
|
124
140
|
DEFAULT_ARTIFACT_CONFIG,
|
|
125
141
|
DEFAULT_FORK_PREAMBLE,
|
|
126
142
|
SUBAGENT_ACTIONS,
|
|
143
|
+
SUBAGENT_ASYNC_STARTED_EVENT,
|
|
144
|
+
SUBAGENT_CHILD_STATUS_EVENT,
|
|
127
145
|
SUBAGENT_CONTROL_EVENT,
|
|
128
146
|
SUBAGENT_CONTROL_INTERCOM_EVENT,
|
|
129
147
|
SUBAGENT_FOREGROUND_COMPLETE_EVENT,
|
|
148
|
+
SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
130
149
|
checkSubagentDepth,
|
|
131
150
|
resolveChildMaxSubagentDepth,
|
|
132
151
|
resolveCurrentMaxSubagentDepth,
|
|
@@ -196,6 +215,15 @@ function rememberParentModel(state, sessionId, model) {
|
|
|
196
215
|
state.lastParentModel = parentModel;
|
|
197
216
|
return parentModel ?? state.lastParentModel;
|
|
198
217
|
}
|
|
218
|
+
function inheritedNestedRoute(deps) {
|
|
219
|
+
return inheritedNestedRouteOf(deps.childRuntime);
|
|
220
|
+
}
|
|
221
|
+
function inheritedNestedParentAddress(deps) {
|
|
222
|
+
return inheritedNestedParentAddressOf(deps.childRuntime);
|
|
223
|
+
}
|
|
224
|
+
function inheritedRunFanoutBudget(deps) {
|
|
225
|
+
return deps.childRuntime?.runFanoutBudget;
|
|
226
|
+
}
|
|
199
227
|
function resolveRequestedCwd(runtimeCwd, requestedCwd) {
|
|
200
228
|
return requestedCwd ? path.resolve(runtimeCwd, requestedCwd) : runtimeCwd;
|
|
201
229
|
}
|
|
@@ -214,12 +242,19 @@ function loadWorkflowScriptPath(params, runtimeCwd) {
|
|
|
214
242
|
const { workflowScriptPath: _workflowScriptPath, ...rest } = params;
|
|
215
243
|
return { params: { ...rest, workflowScript } };
|
|
216
244
|
}
|
|
217
|
-
function removeForegroundControlIfIdle(state, runId) {
|
|
245
|
+
export function removeForegroundControlIfIdle(state, runId, trackRetainedNestedRoute) {
|
|
218
246
|
const control = state.foregroundControls.get(runId);
|
|
219
247
|
if (control && (!foregroundSchedulingSettled(control) || (control.activeChildren?.size ?? 0) > 0))
|
|
220
248
|
return false;
|
|
221
|
-
if (control)
|
|
222
|
-
|
|
249
|
+
if (control?.nestedRoute && trackRetainedNestedRoute) {
|
|
250
|
+
try {
|
|
251
|
+
if (retainLiveForegroundNestedRoute(state, control.nestedRoute))
|
|
252
|
+
trackRetainedNestedRoute(runId);
|
|
253
|
+
} catch (error) {
|
|
254
|
+
console.error(`Failed to retain live nested descendants for foreground run '${runId}':`, error);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
retainNestedLookupRoute(state, control?.nestedRoute, control?.sessionId);
|
|
223
258
|
state.foregroundControls.delete(runId);
|
|
224
259
|
if (state.lastForegroundControlId === runId)
|
|
225
260
|
state.lastForegroundControlId = null;
|
|
@@ -285,8 +320,8 @@ function formatForegroundActivity(control) {
|
|
|
285
320
|
function nestedResolutionScopeForExecutor(deps) {
|
|
286
321
|
if (deps.allowMutatingManagementActions !== false)
|
|
287
322
|
return;
|
|
288
|
-
const route =
|
|
289
|
-
const address = route ?
|
|
323
|
+
const route = inheritedNestedRoute(deps);
|
|
324
|
+
const address = route ? inheritedNestedParentAddress(deps) : undefined;
|
|
290
325
|
return {
|
|
291
326
|
routes: route ? [route] : [],
|
|
292
327
|
...address ? { descendantOf: { parentRunId: address.parentRunId, ...address.parentStepIndex !== undefined ? { parentStepIndex: address.parentStepIndex } : {} } } : {}
|
|
@@ -428,6 +463,7 @@ function rememberForegroundRun(state, input) {
|
|
|
428
463
|
updatedAt,
|
|
429
464
|
children: input.results.map((result, index) => {
|
|
430
465
|
const resumeContract = omitUndefinedProperties({
|
|
466
|
+
modelResponseAliases: input.modelResponseAliases,
|
|
431
467
|
outputSchema: input.params.outputSchema,
|
|
432
468
|
agentContract: input.params.agentContract,
|
|
433
469
|
acceptance: input.params.acceptance,
|
|
@@ -468,6 +504,7 @@ function rememberForegroundRun(state, input) {
|
|
|
468
504
|
...Object.keys(resumeContract).length ? { resumeContract } : {},
|
|
469
505
|
...result.launchContractDigest ? { launchContractDigest: result.launchContractDigest } : {},
|
|
470
506
|
...input.extensionBindings ? { extensionBindings: input.extensionBindings } : {},
|
|
507
|
+
...input.requiredExtensions?.length ? { requiredExtensions: input.requiredExtensions } : {},
|
|
471
508
|
...result.launchResolvedExtensions ? { launchResolvedExtensions: result.launchResolvedExtensions } : {},
|
|
472
509
|
...result.runtimeAcknowledgedExtensions ? { runtimeAcknowledgedExtensions: result.runtimeAcknowledgedExtensions } : {},
|
|
473
510
|
...result.capabilityCeiling ? { capabilityCeiling: result.capabilityCeiling } : {},
|
|
@@ -627,6 +664,7 @@ function resolveForegroundResumeTarget(params, state, options = {}) {
|
|
|
627
664
|
...child.launchContractDigest ? { launchContractDigest: child.launchContractDigest } : {},
|
|
628
665
|
...child.resumeContract ? { resumeContract: child.resumeContract } : {},
|
|
629
666
|
...child.extensionBindings ? { extensionBindings: normalizeExtensionBindings(child.extensionBindings).value } : {},
|
|
667
|
+
...child.requiredExtensions ? { requiredExtensions: child.requiredExtensions } : {},
|
|
630
668
|
...child.capabilityCeiling ? { capabilityCeiling: child.capabilityCeiling } : {}
|
|
631
669
|
};
|
|
632
670
|
}
|
|
@@ -868,10 +906,15 @@ function appendStepToAsyncChain(input) {
|
|
|
868
906
|
};
|
|
869
907
|
}
|
|
870
908
|
const chain = [input.params.step];
|
|
871
|
-
const
|
|
872
|
-
|
|
909
|
+
const validationParams = { ...input.params, chain };
|
|
910
|
+
const acceptancePolicyErrors = validateExecutionAcceptancePolicy(validationParams);
|
|
911
|
+
const outputSchemaError = validateLaunchOutputSchemaOverrides(validationParams);
|
|
912
|
+
const earlyErrors = [...acceptancePolicyErrors];
|
|
913
|
+
if (outputSchemaError)
|
|
914
|
+
earlyErrors.push(outputSchemaError);
|
|
915
|
+
if (earlyErrors.length > 0) {
|
|
873
916
|
return {
|
|
874
|
-
content: [{ type: "text", text: `Cannot append step: ${
|
|
917
|
+
content: [{ type: "text", text: `Cannot append step: ${earlyErrors.join(" ")}` }],
|
|
875
918
|
isError: true,
|
|
876
919
|
details: { mode: "management", results: [] }
|
|
877
920
|
};
|
|
@@ -950,6 +993,14 @@ function appendStepToAsyncChain(input) {
|
|
|
950
993
|
const scope = resolveExecutionAgentScope(input.params.agentScope);
|
|
951
994
|
const discoveredForAppend = input.deps.discoverAgents(input.requestCwd, scope, input.parentModel?.provider);
|
|
952
995
|
const agents = discoveredForAppend.agents;
|
|
996
|
+
const acceptanceErrors = validateExecutionAcceptance(projectEffectiveAcceptanceSchemas(validationParams, agents));
|
|
997
|
+
if (acceptanceErrors.length > 0) {
|
|
998
|
+
return {
|
|
999
|
+
content: [{ type: "text", text: `Cannot append step: ${acceptanceErrors.join(" ")}` }],
|
|
1000
|
+
isError: true,
|
|
1001
|
+
details: { mode: "management", results: [] }
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
953
1004
|
const contextPolicy = resolveExplicitContextPolicy(input.params);
|
|
954
1005
|
const chainSkillInput = normalizeSkillInput(input.params.skill);
|
|
955
1006
|
const chainSkills = chainSkillInput === false ? [] : chainSkillInput ?? [];
|
|
@@ -962,8 +1013,10 @@ function appendStepToAsyncChain(input) {
|
|
|
962
1013
|
currentModelProvider: parentModel?.provider,
|
|
963
1014
|
currentModel: parentModel,
|
|
964
1015
|
modelScope: discoveredForAppend.modelScope,
|
|
1016
|
+
modelResponseAliases: input.deps.config.modelResponseAliases,
|
|
965
1017
|
interactive: input.ctx.hasUI,
|
|
966
|
-
permissions: input.deps.config.permissions
|
|
1018
|
+
permissions: input.deps.config.permissions,
|
|
1019
|
+
childRuntime: input.deps.childRuntime
|
|
967
1020
|
});
|
|
968
1021
|
const built = buildAsyncRunnerSteps(resolved.id, compactOptional({
|
|
969
1022
|
chain: wrapChainTasksForFork(chain, contextPolicy),
|
|
@@ -976,10 +1029,13 @@ function appendStepToAsyncChain(input) {
|
|
|
976
1029
|
cwd: status.cwd ?? input.requestCwd,
|
|
977
1030
|
chainSkills,
|
|
978
1031
|
dynamicFanoutMaxItems: input.deps.config.chain?.dynamicFanout?.maxItems,
|
|
979
|
-
maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
|
|
1032
|
+
maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime),
|
|
980
1033
|
waitToolEnabled: input.deps.waitToolEnabled,
|
|
981
1034
|
waitToolDefaultTimeoutMs: input.deps.waitToolDefaultTimeoutMs,
|
|
982
1035
|
contextForAgent: contextPolicy.contextForAgent,
|
|
1036
|
+
worktreeBaseDir: input.deps.config.worktreeBaseDir,
|
|
1037
|
+
worktreeProvider: input.deps.config.worktreeProvider,
|
|
1038
|
+
worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
|
|
983
1039
|
asyncDir: resolved.location.asyncDir,
|
|
984
1040
|
validateOutputBindings: false,
|
|
985
1041
|
capabilityCeiling: intersectSubagentCapabilityCeilings(status.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(asyncCtx.currentSessionId))
|
|
@@ -1118,6 +1174,49 @@ function resolveNestedResumeTarget(match, trustedSessionRoots) {
|
|
|
1118
1174
|
...recoveryDescriptor ? { recoveryDescriptor } : {}
|
|
1119
1175
|
});
|
|
1120
1176
|
}
|
|
1177
|
+
function resolveNestedExternalJobResumeTarget(match, params, deps) {
|
|
1178
|
+
const run = match.match.run;
|
|
1179
|
+
if (run.state === "stopped")
|
|
1180
|
+
return;
|
|
1181
|
+
const asyncDir = resolveNestedAsyncDir(match.match.rootRunId, run);
|
|
1182
|
+
if (!asyncDir)
|
|
1183
|
+
return;
|
|
1184
|
+
const status = readNestedRunStatus(asyncDir, run);
|
|
1185
|
+
const steps = status?.steps ?? [];
|
|
1186
|
+
const step = steps[params.index ?? 0];
|
|
1187
|
+
if (!step) {
|
|
1188
|
+
if (params.index === undefined || !steps.some((candidate) => candidate.runner?.type === "external-job"))
|
|
1189
|
+
return;
|
|
1190
|
+
} else if (!step.runner) {
|
|
1191
|
+
if (nestedRunSessionFile(run))
|
|
1192
|
+
return;
|
|
1193
|
+
const agent = deps.discoverAgents(status?.cwd ?? deps.state.baseCwd, resolveExecutionAgentScope(params.agentScope)).agents.find((candidate) => candidate.name === step.agent);
|
|
1194
|
+
if (agent?.runner?.type === "external-job")
|
|
1195
|
+
throw new Error(externalJobWithoutMetadataMessage(run.id));
|
|
1196
|
+
return;
|
|
1197
|
+
} else if (step.runner.type !== "external-job") {
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
const target = resolveAsyncResumeTarget(compactOptional({ dir: asyncDir, index: params.index }), nestedRunScope(match.match.rootRunId), { requireSessionFile: false });
|
|
1201
|
+
if (target.kind === "live")
|
|
1202
|
+
throw new Error(externalJobStillRunningMessage(target.runId));
|
|
1203
|
+
return { source: "async", ...target };
|
|
1204
|
+
}
|
|
1205
|
+
function readNestedRunStatus(asyncDir, run) {
|
|
1206
|
+
try {
|
|
1207
|
+
return readStatus(asyncDir);
|
|
1208
|
+
} catch (error) {
|
|
1209
|
+
if (nestedRunSessionFile(run))
|
|
1210
|
+
return null;
|
|
1211
|
+
throw error;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
function externalJobStillRunningMessage(runId) {
|
|
1215
|
+
return `External-job run '${runId}' is still running. Wait for completion, then use subagent({ action: "resume", id: "${runId}", message: "..." }).`;
|
|
1216
|
+
}
|
|
1217
|
+
function externalJobWithoutMetadataMessage(runId) {
|
|
1218
|
+
return `External-job run '${runId}' has no persisted provider metadata. Cannot follow up without the parent provider job id.`;
|
|
1219
|
+
}
|
|
1121
1220
|
async function waitForNestedControlResult(target, requestId, ignoredFiles, timeoutMs = 1000) {
|
|
1122
1221
|
const deadline = Date.now() + timeoutMs;
|
|
1123
1222
|
while (Date.now() < deadline) {
|
|
@@ -1268,14 +1367,14 @@ function externalRunnerControlError(asyncDir, action) {
|
|
|
1268
1367
|
}
|
|
1269
1368
|
async function resumeExternalJobFollowUp(input) {
|
|
1270
1369
|
if (input.target.kind === "live" || input.target.state === "running" || input.target.state === "queued") {
|
|
1271
|
-
return { content: [{ type: "text", text:
|
|
1370
|
+
return { content: [{ type: "text", text: externalJobStillRunningMessage(input.target.runId) }], isError: true, details: { mode: "management", results: [] } };
|
|
1272
1371
|
}
|
|
1273
1372
|
const runner = input.target.runner;
|
|
1274
1373
|
const externalJob = input.target.externalJob;
|
|
1275
1374
|
if (runner?.type !== "external-job")
|
|
1276
1375
|
return { content: [{ type: "text", text: "Internal error: external-job follow-up was requested for a non-external-job runner." }], isError: true, details: { mode: "management", results: [] } };
|
|
1277
1376
|
if (!externalJob)
|
|
1278
|
-
return { content: [{ type: "text", text:
|
|
1377
|
+
return { content: [{ type: "text", text: externalJobWithoutMetadataMessage(input.target.runId) }], isError: true, details: { mode: "management", results: [] } };
|
|
1279
1378
|
if (externalJob.provider !== runner.provider)
|
|
1280
1379
|
return { content: [{ type: "text", text: `External-job run '${input.target.runId}' has mismatched provider metadata. Refusing to follow up.` }], isError: true, details: { mode: "management", results: [] } };
|
|
1281
1380
|
if (!externalJobOptionsEqual(externalJob.options, runner.options))
|
|
@@ -1291,18 +1390,20 @@ async function resumeExternalJobFollowUp(input) {
|
|
|
1291
1390
|
const requestDigest = externalJobFollowUpRequestDigest({ provider: runner.provider, parentProviderJobId: externalJob.providerJobId, promptDigest, options: runner.options });
|
|
1292
1391
|
const requestId = externalJobFollowUpRequestId(requestDigest);
|
|
1293
1392
|
const runId = externalJobFollowUpRunId(requestDigest);
|
|
1294
|
-
const
|
|
1393
|
+
const nestedRoute = inheritedNestedRoute(input.deps);
|
|
1394
|
+
const runRoots = nestedRoute ? nestedRunScope(nestedRoute.rootRunId) : { asyncDirRoot: DIRS.async, resultsDir: DIRS.results };
|
|
1395
|
+
const asyncDir = path.join(runRoots.asyncDirRoot, runId);
|
|
1295
1396
|
const currentSessionId = input.deps.state.currentSessionId;
|
|
1296
1397
|
if (!currentSessionId)
|
|
1297
1398
|
return { content: [{ type: "text", text: "External-job follow-up requires an active parent session." }], isError: true, details: { mode: "management", results: [] } };
|
|
1298
|
-
if (fs.existsSync(asyncDir) || fs.existsSync(resultFilePath(
|
|
1399
|
+
if (fs.existsSync(asyncDir) || fs.existsSync(resultFilePath(runRoots.resultsDir, runId))) {
|
|
1299
1400
|
return externalJobFollowUpStarted({ sourceRunId: input.target.runId, runId, asyncDir, duplicate: true, interactive: input.ctx.hasUI });
|
|
1300
1401
|
}
|
|
1301
|
-
const depthState = checkSubagentDepth(input.deps.config.maxSubagentDepth);
|
|
1402
|
+
const depthState = checkSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime);
|
|
1302
1403
|
if (depthState.blocked) {
|
|
1303
1404
|
return { content: [{ type: "text", text: `Nested subagent resume blocked (depth=${depthState.depth}, max=${depthState.maxDepth}). Complete the follow-up directly instead.` }], isError: true, details: { mode: "management", results: [] } };
|
|
1304
1405
|
}
|
|
1305
|
-
const topLevelResume = depthState.depth === 0 && !
|
|
1406
|
+
const topLevelResume = depthState.depth === 0 && !inheritedNestedRoute(input.deps) && !input.deps.state.workflowControllers?.has(input.target.runId);
|
|
1306
1407
|
let activeAsyncCapacity;
|
|
1307
1408
|
try {
|
|
1308
1409
|
activeAsyncCapacity = topLevelResume ? acquireActiveAsyncCapacity({
|
|
@@ -1324,7 +1425,7 @@ async function resumeExternalJobFollowUp(input) {
|
|
|
1324
1425
|
...input.baseAgentConfig,
|
|
1325
1426
|
runner: { type: "external-job", provider: runner.provider, options: runner.options }
|
|
1326
1427
|
};
|
|
1327
|
-
const result = executeAsyncSingle(runId, compactOptional({
|
|
1428
|
+
const result = await executeAsyncSingle(runId, compactOptional({
|
|
1328
1429
|
agent: input.target.agent,
|
|
1329
1430
|
task: input.followUp,
|
|
1330
1431
|
goal: input.followUp,
|
|
@@ -1338,20 +1439,24 @@ async function resumeExternalJobFollowUp(input) {
|
|
|
1338
1439
|
currentModelProvider: parentModel?.provider,
|
|
1339
1440
|
currentModel: parentModel,
|
|
1340
1441
|
modelScope: input.modelScope,
|
|
1442
|
+
modelResponseAliases: input.deps.config.modelResponseAliases,
|
|
1341
1443
|
interactive: input.ctx.hasUI,
|
|
1342
|
-
permissions: input.deps.config.permissions
|
|
1444
|
+
permissions: input.deps.config.permissions,
|
|
1445
|
+
childRuntime: input.deps.childRuntime
|
|
1343
1446
|
}),
|
|
1344
1447
|
cwd: input.effectiveCwd,
|
|
1345
1448
|
artifactsDir,
|
|
1346
1449
|
artifactConfig,
|
|
1347
1450
|
shareEnabled: false,
|
|
1348
1451
|
...input.parentSessionFile ? { sessionRoot: input.deps.getSubagentSessionRoot(input.parentSessionFile) } : {},
|
|
1349
|
-
maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
|
|
1452
|
+
maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime),
|
|
1350
1453
|
waitToolEnabled: input.deps.waitToolEnabled,
|
|
1351
1454
|
waitToolDefaultTimeoutMs: input.deps.waitToolDefaultTimeoutMs,
|
|
1352
1455
|
worktreeSetupHook: input.deps.config.worktreeSetupHook,
|
|
1353
1456
|
worktreeSetupHookTimeoutMs: input.deps.config.worktreeSetupHookTimeoutMs,
|
|
1354
1457
|
worktreeBaseDir: input.deps.config.worktreeBaseDir,
|
|
1458
|
+
worktreeProvider: input.deps.config.worktreeProvider,
|
|
1459
|
+
worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
|
|
1355
1460
|
controlConfig: resolveControlConfig(input.deps.config.control, undefined),
|
|
1356
1461
|
controlIntercomTarget: input.intercomBridge.active ? input.intercomBridge.orchestratorTarget : undefined,
|
|
1357
1462
|
childIntercomTarget: input.intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(runId, agent, index) : undefined,
|
|
@@ -1369,6 +1474,33 @@ async function resumeExternalJobFollowUp(input) {
|
|
|
1369
1474
|
}
|
|
1370
1475
|
return externalJobFollowUpStarted({ sourceRunId: input.target.runId, runId: result.details.asyncId ?? runId, asyncDir: result.details.asyncDir ?? asyncDir, interactive: input.ctx.hasUI });
|
|
1371
1476
|
}
|
|
1477
|
+
function resolveRequestedResumeTarget(params, deps, parentSessionFile) {
|
|
1478
|
+
const requestedId = params.id ?? params.runId;
|
|
1479
|
+
let resolved;
|
|
1480
|
+
try {
|
|
1481
|
+
resolved = requestedId ? resolveSubagentRunId(requestedId, omitUndefinedProperties({ state: deps.state, nested: nestedResolutionScopeForExecutor(deps) })) : undefined;
|
|
1482
|
+
} catch (error) {
|
|
1483
|
+
const message = error instanceof Error ? error.message : "";
|
|
1484
|
+
const asyncMatches = message.match(/async:/g)?.length ?? 0;
|
|
1485
|
+
if (!isResumeAmbiguity(error) || !message.includes("foreground:") || asyncMatches !== 1)
|
|
1486
|
+
throw error;
|
|
1487
|
+
}
|
|
1488
|
+
if (resolved?.kind === "nested") {
|
|
1489
|
+
if (params.chain?.length)
|
|
1490
|
+
throw new Error("Attaching a running subagent as a chain root is currently available for top-level async runs only.");
|
|
1491
|
+
if (resolved.match.run.state === "running" || resolved.match.run.state === "queued")
|
|
1492
|
+
return { kind: "live-nested", target: resolved };
|
|
1493
|
+
const externalJobTarget = resolveNestedExternalJobResumeTarget(resolved, params, deps);
|
|
1494
|
+
if (externalJobTarget)
|
|
1495
|
+
return externalJobTarget;
|
|
1496
|
+
const trustedSessionRoots = [
|
|
1497
|
+
...deps.config.defaultSessionDir ? [path.resolve(deps.expandTilde(deps.config.defaultSessionDir))] : [],
|
|
1498
|
+
...parentSessionFile ? [deps.getSubagentSessionRoot(parentSessionFile)] : []
|
|
1499
|
+
];
|
|
1500
|
+
return resolveNestedResumeTarget(resolved, trustedSessionRoots);
|
|
1501
|
+
}
|
|
1502
|
+
return resolveResumeTarget(params, deps.state, { asyncRequireSessionFile: false });
|
|
1503
|
+
}
|
|
1372
1504
|
async function resumeAsyncRun(input) {
|
|
1373
1505
|
const followUp = (input.params.message ?? input.params.task ?? "").trim();
|
|
1374
1506
|
const attachChain = (input.params.chain?.length ?? 0) > 0 ? input.params.chain : undefined;
|
|
@@ -1386,47 +1518,22 @@ async function resumeAsyncRun(input) {
|
|
|
1386
1518
|
details: { mode: "management", results: [] }
|
|
1387
1519
|
};
|
|
1388
1520
|
}
|
|
1389
|
-
const
|
|
1390
|
-
if (
|
|
1391
|
-
return {
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
};
|
|
1521
|
+
const acceptancePolicyErrors = validateExecutionAcceptancePolicy(input.params);
|
|
1522
|
+
if (acceptancePolicyErrors.length > 0) {
|
|
1523
|
+
return { content: [{ type: "text", text: `Cannot resume: ${acceptancePolicyErrors.join(" ")}` }], isError: true, details: { mode: "management", results: [] } };
|
|
1524
|
+
}
|
|
1525
|
+
const outputSchemaError = validateLaunchOutputSchemaOverrides(input.params);
|
|
1526
|
+
if (outputSchemaError) {
|
|
1527
|
+
return { content: [{ type: "text", text: `Cannot resume: ${outputSchemaError}` }], isError: true, details: { mode: "management", results: [] } };
|
|
1396
1528
|
}
|
|
1397
1529
|
input.deps.state.currentSessionId = resolveCurrentSessionId(input.ctx.sessionManager);
|
|
1398
1530
|
let target;
|
|
1399
1531
|
const parentSessionFile = input.ctx.sessionManager.getSessionFile() ?? null;
|
|
1400
1532
|
try {
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
} catch (error) {
|
|
1406
|
-
const message = error instanceof Error ? error.message : "";
|
|
1407
|
-
const asyncMatches = message.match(/async:/g)?.length ?? 0;
|
|
1408
|
-
if (!isResumeAmbiguity(error) || !message.includes("foreground:") || asyncMatches !== 1)
|
|
1409
|
-
throw error;
|
|
1410
|
-
}
|
|
1411
|
-
if (resolved?.kind === "nested") {
|
|
1412
|
-
if (attachChain) {
|
|
1413
|
-
return {
|
|
1414
|
-
content: [{ type: "text", text: "Attaching a running subagent as a chain root is currently available for top-level async runs only." }],
|
|
1415
|
-
isError: true,
|
|
1416
|
-
details: { mode: "management", results: [] }
|
|
1417
|
-
};
|
|
1418
|
-
}
|
|
1419
|
-
if (resolved.match.run.state === "running" || resolved.match.run.state === "queued") {
|
|
1420
|
-
return resumeLiveNestedRun({ target: resolved, message: followUp });
|
|
1421
|
-
}
|
|
1422
|
-
const trustedSessionRoots = [
|
|
1423
|
-
...input.deps.config.defaultSessionDir ? [path.resolve(input.deps.expandTilde(input.deps.config.defaultSessionDir))] : [],
|
|
1424
|
-
...parentSessionFile ? [input.deps.getSubagentSessionRoot(parentSessionFile)] : []
|
|
1425
|
-
];
|
|
1426
|
-
target = resolveNestedResumeTarget(resolved, trustedSessionRoots);
|
|
1427
|
-
} else {
|
|
1428
|
-
target = resolveResumeTarget(input.params, input.deps.state, { asyncRequireSessionFile: false });
|
|
1429
|
-
}
|
|
1533
|
+
const resolved = resolveRequestedResumeTarget(input.params, input.deps, parentSessionFile);
|
|
1534
|
+
if (resolved.kind === "live-nested")
|
|
1535
|
+
return resumeLiveNestedRun({ target: resolved.target, message: followUp });
|
|
1536
|
+
target = resolved;
|
|
1430
1537
|
} catch (error) {
|
|
1431
1538
|
const message = error instanceof Error ? error.message : String(error);
|
|
1432
1539
|
return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
|
|
@@ -1445,7 +1552,7 @@ async function resumeAsyncRun(input) {
|
|
|
1445
1552
|
details: { mode: "management", results: [] }
|
|
1446
1553
|
};
|
|
1447
1554
|
}
|
|
1448
|
-
const { blocked, depth, maxDepth } = checkSubagentDepth(input.deps.config.maxSubagentDepth);
|
|
1555
|
+
const { blocked, depth, maxDepth } = checkSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime);
|
|
1449
1556
|
if (blocked) {
|
|
1450
1557
|
return {
|
|
1451
1558
|
content: [{ type: "text", text: `Nested subagent resume blocked (depth=${depth}, max=${maxDepth}). Complete the follow-up directly instead.` }],
|
|
@@ -1460,7 +1567,7 @@ async function resumeAsyncRun(input) {
|
|
|
1460
1567
|
const discoveredAgents = discovered.agents;
|
|
1461
1568
|
const unknownAgentDiagnosticContext = diagnosticContextFromDiscovery(discovered, effectiveCwd, scope);
|
|
1462
1569
|
const modelScope = discovered.modelScope;
|
|
1463
|
-
const sessionName = resolveIntercomSessionTarget(input.deps.dm.getSessionName(), input.ctx.sessionManager.getSessionId());
|
|
1570
|
+
const sessionName = resolveIntercomSessionTarget(input.deps.childRuntime?.intercomSessionName ?? input.deps.dm.getSessionName(), input.ctx.sessionManager.getSessionId());
|
|
1464
1571
|
const recoveryDescriptor = "recoveryDescriptor" in target ? target.recoveryDescriptor : undefined;
|
|
1465
1572
|
const recoveryContext = recoveryDescriptor?.context ?? (input.params.context === "profile" ? undefined : input.params.context);
|
|
1466
1573
|
const intercomBridge = resolveIntercomBridge({
|
|
@@ -1498,7 +1605,7 @@ async function resumeAsyncRun(input) {
|
|
|
1498
1605
|
if (target.source === "async" && target.runner?.type === "external-job") {
|
|
1499
1606
|
if (attachChain)
|
|
1500
1607
|
return { content: [{ type: "text", text: "External-job follow-up does not support chain attachment. Use action='resume' with message instead." }], isError: true, details: { mode: "management", results: [] } };
|
|
1501
|
-
|
|
1608
|
+
const resumed = await resumeExternalJobFollowUp({
|
|
1502
1609
|
target,
|
|
1503
1610
|
followUp,
|
|
1504
1611
|
baseAgentConfig,
|
|
@@ -1512,6 +1619,10 @@ async function resumeAsyncRun(input) {
|
|
|
1512
1619
|
parentSessionFile,
|
|
1513
1620
|
absoluteDeadlineAt: input.absoluteDeadlineAt
|
|
1514
1621
|
});
|
|
1622
|
+
const resumedRunId = resumed.details.runId ?? resumed.details.asyncId;
|
|
1623
|
+
if (!resumed.isError && resumedRunId)
|
|
1624
|
+
input.onLaunch?.({ agent: target.agent, async: true, runId: resumedRunId });
|
|
1625
|
+
return resumed;
|
|
1515
1626
|
}
|
|
1516
1627
|
if (attachChain) {
|
|
1517
1628
|
if (target.source !== "async") {
|
|
@@ -1528,8 +1639,12 @@ async function resumeAsyncRun(input) {
|
|
|
1528
1639
|
details: { mode: "chain", results: [] }
|
|
1529
1640
|
};
|
|
1530
1641
|
}
|
|
1642
|
+
const acceptanceErrors = validateExecutionAcceptance(projectEffectiveAcceptanceSchemas(input.params, agents));
|
|
1643
|
+
if (acceptanceErrors.length > 0) {
|
|
1644
|
+
return { content: [{ type: "text", text: `Cannot resume: ${acceptanceErrors.join(" ")}` }], isError: true, details: { mode: "chain", results: [] } };
|
|
1645
|
+
}
|
|
1531
1646
|
const runId = randomUUID();
|
|
1532
|
-
const topLevelResume = depth === 0 && !
|
|
1647
|
+
const topLevelResume = depth === 0 && !inheritedNestedRoute(input.deps) && !input.params.workflowParentRunId;
|
|
1533
1648
|
let activeAsyncCapacity;
|
|
1534
1649
|
try {
|
|
1535
1650
|
activeAsyncCapacity = topLevelResume ? acquireActiveAsyncCapacity({
|
|
@@ -1574,8 +1689,10 @@ async function resumeAsyncRun(input) {
|
|
|
1574
1689
|
currentModelProvider: parentModel?.provider,
|
|
1575
1690
|
currentModel: parentModel,
|
|
1576
1691
|
modelScope,
|
|
1692
|
+
modelResponseAliases: input.deps.config.modelResponseAliases,
|
|
1577
1693
|
interactive: input.ctx.hasUI,
|
|
1578
|
-
permissions: input.deps.config.permissions
|
|
1694
|
+
permissions: input.deps.config.permissions,
|
|
1695
|
+
childRuntime: input.deps.childRuntime
|
|
1579
1696
|
}),
|
|
1580
1697
|
availableModels,
|
|
1581
1698
|
cwd: effectiveCwd,
|
|
@@ -1588,12 +1705,16 @@ async function resumeAsyncRun(input) {
|
|
|
1588
1705
|
agentContract: input.params.agentContract,
|
|
1589
1706
|
fast: input.params.fast,
|
|
1590
1707
|
dynamicFanoutMaxItems: input.deps.config.chain?.dynamicFanout?.maxItems,
|
|
1591
|
-
maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
|
|
1708
|
+
maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime),
|
|
1592
1709
|
waitToolEnabled: input.deps.waitToolEnabled,
|
|
1593
1710
|
waitToolDefaultTimeoutMs: input.deps.waitToolDefaultTimeoutMs,
|
|
1594
1711
|
worktreeSetupHook: input.deps.config.worktreeSetupHook,
|
|
1595
1712
|
worktreeSetupHookTimeoutMs: input.deps.config.worktreeSetupHookTimeoutMs,
|
|
1596
1713
|
worktreeBaseDir: input.deps.config.worktreeBaseDir,
|
|
1714
|
+
baseRef: input.params.baseRef ?? target.recoveryDescriptor?.baseRef,
|
|
1715
|
+
...recoveryDescriptor?.requiredExtensions ? { requiredExtensions: recoveryDescriptor.requiredExtensions } : {},
|
|
1716
|
+
worktreeProvider: input.deps.config.worktreeProvider,
|
|
1717
|
+
worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
|
|
1597
1718
|
controlConfig: resolveControlConfig(input.deps.config.control, input.params.control),
|
|
1598
1719
|
controlIntercomTarget: intercomBridge.active ? intercomBridge.orchestratorTarget : undefined,
|
|
1599
1720
|
childIntercomTarget: intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(runId, agent, index) : undefined,
|
|
@@ -1608,6 +1729,7 @@ async function resumeAsyncRun(input) {
|
|
|
1608
1729
|
return result;
|
|
1609
1730
|
}
|
|
1610
1731
|
const attachedId = result.details.asyncId ?? runId;
|
|
1732
|
+
input.onLaunch?.({ agent: target.agent, ...target.sessionFile ? { sessionFile: target.sessionFile } : {}, async: true, runId: attachedId });
|
|
1611
1733
|
const lines = [
|
|
1612
1734
|
`Attached async subagent ${target.runId} as the first step of a new chain.`,
|
|
1613
1735
|
`Chain run: ${attachedId}`,
|
|
@@ -1627,11 +1749,26 @@ async function resumeAsyncRun(input) {
|
|
|
1627
1749
|
if (!revivalSessionFile) {
|
|
1628
1750
|
return { content: [{ type: "text", text: `Async run '${target.runId}' child ${target.index} does not have a persisted session file to resume from.` }], isError: true, details: { mode: "management", results: [] } };
|
|
1629
1751
|
}
|
|
1752
|
+
if (input.params.baseRef !== undefined && "managedWorktree" in target && target.managedWorktree === true) {
|
|
1753
|
+
return { content: [{ type: "text", text: "Cannot resume with baseRef: retained managed-worktree children continue in their existing worktree. Start a new worktree run from that base ref instead." }], isError: true, details: { mode: "management", results: [] } };
|
|
1754
|
+
}
|
|
1630
1755
|
if (target.source === "async" && asyncReviveRequiresRecoveryDescriptor(target)) {
|
|
1631
1756
|
return { content: [{ type: "text", text: `Async child '${target.runId}' is missing its required run fan-out recovery identity. Start a new run instead.` }], isError: true, details: { mode: "management", results: [] } };
|
|
1632
1757
|
}
|
|
1758
|
+
if (target.source === "nested" && !target.recoveryDescriptor) {
|
|
1759
|
+
return { content: [{ type: "text", text: `Nested child '${target.runId}' is missing its required recovery identity. Start a new run instead.` }], isError: true, details: { mode: "management", results: [] } };
|
|
1760
|
+
}
|
|
1761
|
+
const recoveryAgentConfig = recoveryDescriptor ? applySteeringRecoveryAgentConfig(baseAgentConfig, recoveryDescriptor) : baseAgentConfig;
|
|
1762
|
+
const agentConfig = intercomBridge.active ? applyIntercomBridgeToAgent(recoveryAgentConfig, intercomBridge) : recoveryAgentConfig;
|
|
1763
|
+
const foregroundContract = target.source === "foreground" ? target.resumeContract : undefined;
|
|
1764
|
+
const outputSchema = Object.hasOwn(input.params, "outputSchema") ? input.params.outputSchema : Object.hasOwn(foregroundContract ?? {}, "outputSchema") ? foregroundContract?.outputSchema : recoveryDescriptor?.structuredOutputSchema;
|
|
1765
|
+
const acceptance = input.params.acceptance !== undefined ? input.params.acceptance : foregroundContract?.acceptance !== undefined ? foregroundContract.acceptance : recoveryDescriptor?.acceptance;
|
|
1766
|
+
const acceptanceErrors = validateExecutionAcceptance({ ...input.params, acceptance, outputSchema });
|
|
1767
|
+
if (acceptanceErrors.length > 0) {
|
|
1768
|
+
return { content: [{ type: "text", text: `Cannot resume: ${acceptanceErrors.join(" ")}` }], isError: true, details: { mode: "management", results: [] } };
|
|
1769
|
+
}
|
|
1633
1770
|
const runId = randomUUID();
|
|
1634
|
-
const topLevelResume = depth === 0 && !
|
|
1771
|
+
const topLevelResume = depth === 0 && !inheritedNestedRoute(input.deps) && !input.params.workflowParentRunId;
|
|
1635
1772
|
let activeAsyncCapacity;
|
|
1636
1773
|
try {
|
|
1637
1774
|
activeAsyncCapacity = !topLevelResume ? undefined : target.source === "async" ? transferActiveAsyncCapacity({
|
|
@@ -1652,17 +1789,13 @@ async function resumeAsyncRun(input) {
|
|
|
1652
1789
|
return { content: [{ type: "text", text: error.message }], isError: true, details: { mode: "single", results: [], activeAsyncCapacity: error.snapshot } };
|
|
1653
1790
|
return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "single", results: [] } };
|
|
1654
1791
|
}
|
|
1655
|
-
const recoveryAgentConfig = recoveryDescriptor ? applySteeringRecoveryAgentConfig(baseAgentConfig, recoveryDescriptor) : baseAgentConfig;
|
|
1656
|
-
const agentConfig = intercomBridge.active ? applyIntercomBridgeToAgent(recoveryAgentConfig, intercomBridge) : recoveryAgentConfig;
|
|
1657
|
-
const foregroundContract = target.source === "foreground" ? target.resumeContract : undefined;
|
|
1658
|
-
const outputSchema = input.params.outputSchema ?? foregroundContract?.outputSchema ?? recoveryDescriptor?.structuredOutputSchema;
|
|
1659
1792
|
const agentContract = input.params.agentContract ?? foregroundContract?.agentContract ?? recoveryDescriptor?.agentContract;
|
|
1660
1793
|
const artifactConfig = recoveryDescriptor?.artifactConfig ?? omitUndefinedProperties({ ...DEFAULT_ARTIFACT_CONFIG, enabled: input.params.artifacts !== false, dir: input.deps.config.artifactDir ?? DEFAULT_ARTIFACT_CONFIG.dir });
|
|
1661
1794
|
const artifactsDir = recoveryDescriptor?.artifactsDir ?? getArtifactsDir(parentSessionFile, effectiveCwd, artifactConfig.dir);
|
|
1662
1795
|
const availableModels = input.ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
1663
1796
|
const parentModel = input.parentModel;
|
|
1664
1797
|
const revivalAsyncDir = path.join(DIRS.async, runId);
|
|
1665
|
-
const result = executeAsyncSingle(runId, compactOptional({
|
|
1798
|
+
const result = await executeAsyncSingle(runId, compactOptional({
|
|
1666
1799
|
agent: target.agent,
|
|
1667
1800
|
task: buildRevivedAsyncTask(target, effectiveFollowUp),
|
|
1668
1801
|
goal: effectiveFollowUp,
|
|
@@ -1676,8 +1809,10 @@ async function resumeAsyncRun(input) {
|
|
|
1676
1809
|
currentModelProvider: parentModel?.provider,
|
|
1677
1810
|
currentModel: parentModel,
|
|
1678
1811
|
modelScope,
|
|
1812
|
+
modelResponseAliases: recoveryDescriptor ? recoveryDescriptor.modelResponseAliases : foregroundContract?.modelResponseAliases,
|
|
1679
1813
|
interactive: input.ctx.hasUI,
|
|
1680
|
-
permissions: input.deps.config.permissions
|
|
1814
|
+
permissions: input.deps.config.permissions,
|
|
1815
|
+
childRuntime: input.deps.childRuntime
|
|
1681
1816
|
}),
|
|
1682
1817
|
cwd: effectiveCwd,
|
|
1683
1818
|
maxOutput: input.params.maxOutput ?? recoveryDescriptor?.maxOutput,
|
|
@@ -1697,41 +1832,49 @@ async function resumeAsyncRun(input) {
|
|
|
1697
1832
|
modelOverride: recoveryDescriptor?.model ?? target.model,
|
|
1698
1833
|
fast: recoveryDescriptor?.fast,
|
|
1699
1834
|
modelOverrideFromParent: recoveryDescriptor?.modelOverrideFromParent,
|
|
1835
|
+
modelOrigin: recoveryDescriptor?.modelOrigin ?? (recoveryDescriptor?.modelOverrideFromParent ? "inherited" : undefined),
|
|
1700
1836
|
thinkingOverride: recoveryDescriptor?.thinking ?? target.thinking,
|
|
1701
1837
|
thinkingCeiling: recoveryDescriptor?.thinkingCeiling ?? ("thinkingCeiling" in target ? target.thinkingCeiling : undefined),
|
|
1702
1838
|
extensionBindings: recoveryDescriptor?.extensionBindings ?? ("extensionBindings" in target ? target.extensionBindings : undefined),
|
|
1839
|
+
requiredExtensions: recoveryDescriptor?.requiredExtensions ?? target.requiredExtensions,
|
|
1703
1840
|
outputBaseDir: resolveSingleRunOutputBaseDir(input.deps, artifactsDir, runId),
|
|
1704
|
-
maxSubagentDepth: recoveryDescriptor?.maxSubagentDepth ?? resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
|
|
1841
|
+
maxSubagentDepth: recoveryDescriptor?.maxSubagentDepth ?? resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth, input.deps.childRuntime),
|
|
1705
1842
|
waitToolEnabled: input.deps.waitToolEnabled,
|
|
1706
1843
|
waitToolDefaultTimeoutMs: input.deps.waitToolDefaultTimeoutMs,
|
|
1707
1844
|
worktreeSetupHook: input.deps.config.worktreeSetupHook,
|
|
1708
1845
|
worktreeSetupHookTimeoutMs: input.deps.config.worktreeSetupHookTimeoutMs,
|
|
1709
1846
|
worktreeBaseDir: input.deps.config.worktreeBaseDir,
|
|
1710
|
-
|
|
1847
|
+
baseRef: input.params.baseRef ?? recoveryDescriptor?.baseRef,
|
|
1848
|
+
worktreeProvider: input.deps.config.worktreeProvider,
|
|
1849
|
+
worktreeBranchPrefix: input.deps.config.worktreeBranchPrefix,
|
|
1850
|
+
worktree: input.params.worktree === true && !(("managedWorktree" in target) && target.managedWorktree === true),
|
|
1711
1851
|
lane: input.params.lane ?? recoveryDescriptor?.lane,
|
|
1712
|
-
controlConfig:
|
|
1852
|
+
controlConfig: resolveRevivalControlConfig({ globalConfig: input.deps.config.control, requestedControl: input.params.control, recoveryControlConfig: recoveryDescriptor?.controlConfig }),
|
|
1713
1853
|
intercomBridge: input.params.intercomBridge ?? recoveryDescriptor?.intercomBridge,
|
|
1714
1854
|
controlIntercomTarget: intercomBridge.active ? intercomBridge.orchestratorTarget : undefined,
|
|
1715
1855
|
childIntercomTarget: intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(runId, agent, index) : undefined,
|
|
1716
1856
|
availableModels,
|
|
1717
1857
|
output: input.params.output !== undefined ? input.params.output : foregroundContract?.output ?? recoveryDescriptor?.outputPath,
|
|
1718
1858
|
outputMode: input.params.outputMode ?? foregroundContract?.outputMode ?? recoveryDescriptor?.outputMode,
|
|
1859
|
+
outputClaimPath: input.params.workflowOutputClaimPath,
|
|
1719
1860
|
...agentContract ? { agentContract } : {},
|
|
1720
1861
|
...outputSchema ? { structuredOutputSchema: outputSchema } : {},
|
|
1721
1862
|
...recoveryDescriptor?.skills ? { skills: [...recoveryDescriptor.skills] } : {},
|
|
1722
|
-
...
|
|
1863
|
+
...acceptance !== undefined ? { acceptance } : {},
|
|
1723
1864
|
...input.params.timeoutMs !== undefined ? { timeoutMs: input.params.timeoutMs } : {},
|
|
1724
1865
|
...input.absoluteDeadlineAt !== undefined ? { absoluteDeadlineAt: input.absoluteDeadlineAt } : {},
|
|
1725
1866
|
...input.params.toolBudget !== undefined ? { toolBudget: input.params.toolBudget } : {},
|
|
1726
|
-
capabilityCeiling: intersectSubagentCapabilityCeilings(
|
|
1867
|
+
capabilityCeiling: intersectSubagentCapabilityCeilings(recoveryDescriptor?.capabilityCeiling ?? (target.source === "foreground" || target.source === "async" && target.mode === "workflow" ? target.capabilityCeiling : undefined), resolveCurrentSubagentCapabilityCeiling(input.deps.state.currentSessionId)),
|
|
1727
1868
|
runFanoutBudget: input.params.runFanoutBudget ?? recoveryDescriptor?.runFanoutBudget ?? createRunFanoutBudget(runId, resolveMaxSubagentSpawnsPerRun(input.deps.config.maxSubagentSpawnsPerRun)),
|
|
1728
1869
|
parentWorkflowRunId: input.params.workflowParentRunId,
|
|
1729
1870
|
workflowKey: input.params.workflowKey,
|
|
1730
1871
|
activeAsyncCapacity
|
|
1731
1872
|
}));
|
|
1873
|
+
const notifyLaunch = () => input.onLaunch?.({ agent: target.agent, sessionFile: revivalSessionFile, async: true, runId });
|
|
1732
1874
|
if (result.isError) {
|
|
1733
1875
|
const startedStatus = readStatus(revivalAsyncDir);
|
|
1734
1876
|
if (input.params.workflowParentRunId !== undefined && startedStatus?.runId === runId && startedStatus.processTerminal?.runnerProcessInstanceId) {
|
|
1877
|
+
notifyLaunch();
|
|
1735
1878
|
return {
|
|
1736
1879
|
...result,
|
|
1737
1880
|
details: {
|
|
@@ -1746,6 +1889,7 @@ async function resumeAsyncRun(input) {
|
|
|
1746
1889
|
activeAsyncCapacity?.rollback();
|
|
1747
1890
|
return result;
|
|
1748
1891
|
}
|
|
1892
|
+
notifyLaunch();
|
|
1749
1893
|
for (const brief of queuedBriefs)
|
|
1750
1894
|
fs.rmSync(brief.path, { force: true });
|
|
1751
1895
|
if (queuedBriefs.length > 0 && sourceAsyncDir) {
|
|
@@ -1773,7 +1917,9 @@ async function resumeAsyncRun(input) {
|
|
|
1773
1917
|
} finally {
|
|
1774
1918
|
input.signal?.removeEventListener("abort", stopOnAbort);
|
|
1775
1919
|
}
|
|
1776
|
-
|
|
1920
|
+
if (completed.importedPublication)
|
|
1921
|
+
removeWorkflowAwaitedResult(asyncDir, resultPath, revivedId, completed.importedPublication);
|
|
1922
|
+
emitWorkflowAwaitedChildComplete(input.deps.dm, input.deps.state, revivedId, asyncDir, input.params.workflowParentRunId, completed);
|
|
1777
1923
|
const usage = importedAsyncRootUsage(completed);
|
|
1778
1924
|
const childResult = {
|
|
1779
1925
|
index: 0,
|
|
@@ -1789,14 +1935,14 @@ async function resumeAsyncRun(input) {
|
|
|
1789
1935
|
...completed.stopped ? { stopped: true } : {},
|
|
1790
1936
|
...completed.sessionFile ? { sessionFile: completed.sessionFile } : {},
|
|
1791
1937
|
...completed.model ? { model: completed.model } : {},
|
|
1792
|
-
...completed.
|
|
1793
|
-
...completed.modelAttempts ? { modelAttempts: completed.modelAttempts } : {},
|
|
1938
|
+
...completed.requestedModel ? { requestedModel: completed.requestedModel } : {},
|
|
1794
1939
|
...completed.contextOverflow ? { contextOverflow: true } : {},
|
|
1795
1940
|
...completed.structuredOutput !== undefined ? { structuredOutput: completed.structuredOutput } : {},
|
|
1796
1941
|
...completed.structuredOutputPath ? { structuredOutputPath: completed.structuredOutputPath } : {},
|
|
1797
1942
|
...completed.structuredOutputSchemaPath ? { structuredOutputSchemaPath: completed.structuredOutputSchemaPath } : {},
|
|
1798
1943
|
...completed.acceptance ? { acceptance: completed.acceptance } : {},
|
|
1799
1944
|
...completed.artifactPaths ? { artifactPaths: completed.artifactPaths } : {},
|
|
1945
|
+
...completed.savedOutputPath ? { savedOutputPath: completed.savedOutputPath } : {},
|
|
1800
1946
|
...completed.outputSaveError ? { outputSaveError: completed.outputSaveError } : {},
|
|
1801
1947
|
...completed.transcriptPath ? { transcriptPath: completed.transcriptPath } : {},
|
|
1802
1948
|
...completed.transcriptError ? { transcriptError: completed.transcriptError } : {}
|
|
@@ -1974,6 +2120,9 @@ function canonicalizeExecutionParams(params, agents, diagnostics, context) {
|
|
|
1974
2120
|
const agent = agents.find((candidate) => candidate.name === result.name);
|
|
1975
2121
|
if (params.extensionBindings !== undefined && (agent?.runner?.type === "external-cli" || agent?.runner?.type === "external-job"))
|
|
1976
2122
|
return { error: `extensionBindings is not supported for runner.type='${agent.runner.type}'.` };
|
|
2123
|
+
const machineError = agent ? formatHerdrMachineRunnerUnsupported({ machine: params.machine ?? agent.machine, agentName: agent.name, runnerType: agent.runner?.type, adapter: agent.runner?.type === "external-cli" ? agent.runner.adapter : undefined, worktree: params.worktree }) : undefined;
|
|
2124
|
+
if (machineError)
|
|
2125
|
+
return { error: machineError };
|
|
1977
2126
|
}
|
|
1978
2127
|
if (params.extensionBindings !== undefined) {
|
|
1979
2128
|
try {
|
|
@@ -2029,20 +2178,33 @@ function canonicalizeExecutionParams(params, agents, diagnostics, context) {
|
|
|
2029
2178
|
}
|
|
2030
2179
|
return { params };
|
|
2031
2180
|
}
|
|
2181
|
+
function projectEffectiveAcceptanceSchemas(params, agents) {
|
|
2182
|
+
const withEffectiveSchema = (step) => {
|
|
2183
|
+
const agent = agents.find((candidate) => candidate.name === step.agent);
|
|
2184
|
+
return agent ? { ...step, outputSchema: resolveEffectiveOutputSchema(agent, step.outputSchema) } : step;
|
|
2185
|
+
};
|
|
2186
|
+
return {
|
|
2187
|
+
...params,
|
|
2188
|
+
...params.tasks ? { tasks: params.tasks.map(withEffectiveSchema) } : {},
|
|
2189
|
+
...params.chain ? { chain: projectChainOutputSchemas(params.chain, agents) } : {}
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2032
2192
|
function validateExecutionInput(params, agents, hasChain, hasTasks, hasSingle, allowClarifyTaskPrompt, context) {
|
|
2033
2193
|
if (Number(hasChain) + Number(hasTasks) + Number(hasSingle) !== 1) {
|
|
2194
|
+
const agentList = agents.map((a) => a.name).join(", ") || "none";
|
|
2195
|
+
const noMode = !hasChain && !hasTasks && !hasSingle;
|
|
2034
2196
|
return {
|
|
2035
2197
|
content: [
|
|
2036
2198
|
{
|
|
2037
2199
|
type: "text",
|
|
2038
|
-
text:
|
|
2200
|
+
text: noMode && typeof params.workflowKey === "string" ? `Workflow child '${params.workflowKey}' has no agent. Pass { key, agent, task }. Agents: ${agentList}` : `Provide exactly one mode. Agents: ${agentList}`
|
|
2039
2201
|
}
|
|
2040
2202
|
],
|
|
2041
2203
|
isError: true,
|
|
2042
2204
|
details: { mode: "single", results: [] }
|
|
2043
2205
|
};
|
|
2044
2206
|
}
|
|
2045
|
-
const acceptanceErrors = validateExecutionAcceptance(params);
|
|
2207
|
+
const acceptanceErrors = validateExecutionAcceptance(projectEffectiveAcceptanceSchemas(params, agents));
|
|
2046
2208
|
if (acceptanceErrors.length > 0) {
|
|
2047
2209
|
return {
|
|
2048
2210
|
content: [{ type: "text", text: acceptanceErrors.join(" ") }],
|
|
@@ -2263,6 +2425,14 @@ function buildRequestedModeError(params, message) {
|
|
|
2263
2425
|
details: { mode: getRequestedModeLabel(params), results: [] }
|
|
2264
2426
|
}, params.context === "profile" ? undefined : params.context);
|
|
2265
2427
|
}
|
|
2428
|
+
function buildWorkflowValidationResult(validation, mode, preflight) {
|
|
2429
|
+
const payload = preflight ? { ...validation, preflight } : validation;
|
|
2430
|
+
return {
|
|
2431
|
+
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
2432
|
+
...validation.ok ? {} : { isError: true },
|
|
2433
|
+
details: { mode, results: [] }
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2266
2436
|
function applySingleAgentLaunchDefaults(params, agents) {
|
|
2267
2437
|
if ((params.chain?.length ?? 0) > 0 || (params.tasks?.length ?? 0) > 0 || !params.agent)
|
|
2268
2438
|
return params;
|
|
@@ -2270,14 +2440,37 @@ function applySingleAgentLaunchDefaults(params, agents) {
|
|
|
2270
2440
|
if (!agent)
|
|
2271
2441
|
return params;
|
|
2272
2442
|
const parentTimeoutMs = params.timeoutMs === undefined && params.maxRuntimeMs === undefined && agent.defaultTimeoutMs === undefined && params.workflowParentDeadlineAt !== undefined ? Math.max(1, params.workflowParentDeadlineAt - Date.now()) : undefined;
|
|
2443
|
+
const outputSchema = params.outputSchema === false ? false : resolveEffectiveOutputSchema(agent, params.outputSchema);
|
|
2273
2444
|
return {
|
|
2274
2445
|
...params,
|
|
2275
2446
|
...params.async === undefined && agent.defaultAsync !== undefined ? { async: agent.defaultAsync } : {},
|
|
2276
2447
|
...params.timeoutMs === undefined && params.maxRuntimeMs === undefined && agent.defaultTimeoutMs !== undefined ? { timeoutMs: agent.defaultTimeoutMs } : {},
|
|
2277
2448
|
...parentTimeoutMs !== undefined ? { timeoutMs: parentTimeoutMs } : {},
|
|
2278
|
-
...params.acceptance === undefined && agent.defaultAcceptance !== undefined ? { acceptance: agent.defaultAcceptance } : {}
|
|
2449
|
+
...params.acceptance === undefined && agent.defaultAcceptance !== undefined ? { acceptance: agent.defaultAcceptance } : {},
|
|
2450
|
+
...outputSchema !== undefined ? { outputSchema } : {}
|
|
2279
2451
|
};
|
|
2280
2452
|
}
|
|
2453
|
+
function validateLaunchOutputSchemaOverrides(params) {
|
|
2454
|
+
const values = [params.outputSchema, ...(params.tasks ?? []).map((task) => task.outputSchema)];
|
|
2455
|
+
for (const step of params.chain ?? []) {
|
|
2456
|
+
if (isParallelStep(step))
|
|
2457
|
+
values.push(...step.parallel.map((task) => task.outputSchema));
|
|
2458
|
+
else if (isDynamicParallelStep(step))
|
|
2459
|
+
values.push(step.parallel.outputSchema);
|
|
2460
|
+
else
|
|
2461
|
+
values.push(step.outputSchema);
|
|
2462
|
+
}
|
|
2463
|
+
for (const value of values) {
|
|
2464
|
+
if (value === undefined || value === false)
|
|
2465
|
+
continue;
|
|
2466
|
+
try {
|
|
2467
|
+
assertJsonSchemaObject(value, "outputSchema");
|
|
2468
|
+
} catch (error) {
|
|
2469
|
+
return error instanceof Error ? error.message : String(error);
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
return;
|
|
2473
|
+
}
|
|
2281
2474
|
export const DEFAULT_FOREGROUND_TIMEOUT_MS = 30 * 60 * 1000;
|
|
2282
2475
|
|
|
2283
2476
|
export { DEFAULT_ASYNC_TIMEOUT_MS };
|
|
@@ -2397,17 +2590,22 @@ function withResolvedContext(result, fallback) {
|
|
|
2397
2590
|
};
|
|
2398
2591
|
}
|
|
2399
2592
|
function withAggregatedToolUsage(result) {
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
}
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2593
|
+
const highWarnings = result.details.results.flatMap((child) => child.watchdog?.warnings?.filter((warning) => warning.importance === "high") ?? []);
|
|
2594
|
+
const projected = {
|
|
2595
|
+
...result,
|
|
2596
|
+
...highWarnings.length ? { content: [...result.content, { type: "text", text: ["High-importance watchdog findings:", ...highWarnings.map((warning) => `- ${warning.severity}: ${warning.summary}
|
|
2597
|
+
Evidence: ${warning.evidence}
|
|
2598
|
+
Recommended action: ${warning.recommendedAction}`)].join(`
|
|
2599
|
+
`) }] } : {},
|
|
2600
|
+
details: {
|
|
2601
|
+
...result.details,
|
|
2602
|
+
results: result.details.results.map((child) => ({ ...child, ...child.watchdog ? { watchdog: childWatchdogProgressForModel(child.watchdog) } : {} }))
|
|
2603
|
+
}
|
|
2604
|
+
};
|
|
2605
|
+
if (projected.details.results.length === 0)
|
|
2606
|
+
return projected;
|
|
2607
|
+
const usage = sumResultsUsage(projected.details.results);
|
|
2608
|
+
return usage.input !== 0 || usage.output !== 0 || usage.cacheRead !== 0 || usage.cacheWrite !== 0 || usage.cost !== 0 || usage.turns !== 0 ? { ...projected, details: { ...projected.details, totalChildUsage: usage } } : projected;
|
|
2411
2609
|
}
|
|
2412
2610
|
function toExecutionErrorResult(params, error, contextSummary) {
|
|
2413
2611
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -2422,7 +2620,7 @@ function resolveStaticLaunchSummary(input) {
|
|
|
2422
2620
|
const externalRunner = agentConfig?.runner?.type === "external-cli" || agentConfig?.runner?.type === "external-job";
|
|
2423
2621
|
const modelScopes = resolveModelScopesForAgent(input.modelScope, input.agent, input.parentModel);
|
|
2424
2622
|
const model = externalRunner ? undefined : resolveEffectiveSubagentModel(input.explicitModel, agentConfig?.model, input.parentModel, input.availableModels, agentConfig?.modelProvider ?? input.currentProvider, modelScopes.length === 0 ? {} : { scope: modelScopes });
|
|
2425
|
-
const thinkingOverride = externalRunner ? undefined : input.thinkingOverrideForTask(
|
|
2623
|
+
const thinkingOverride = externalRunner ? undefined : input.thinkingOverrideForTask();
|
|
2426
2624
|
const thinking = externalRunner ? undefined : resolveEffectiveThinking(model, thinkingOverride ?? agentConfig?.thinking);
|
|
2427
2625
|
return {
|
|
2428
2626
|
agent: input.agent,
|
|
@@ -2524,8 +2722,9 @@ async function preflightForkSessionsForStaticTasks(params, contextPolicy, prepar
|
|
|
2524
2722
|
if (!contextPolicy.usesFork)
|
|
2525
2723
|
return;
|
|
2526
2724
|
if (params.agent) {
|
|
2527
|
-
if (shouldForkAgent(contextPolicy, params.agent))
|
|
2528
|
-
await prepareSessionForTask(params.agent, 0, params.model);
|
|
2725
|
+
if (shouldForkAgent(contextPolicy, params.agent)) {
|
|
2726
|
+
await prepareSessionForTask(params.agent, 0, params.model, params.modelOrigin === "inherited", params.modelOrigin);
|
|
2727
|
+
}
|
|
2529
2728
|
return;
|
|
2530
2729
|
}
|
|
2531
2730
|
if (params.tasks) {
|
|
@@ -2573,6 +2772,35 @@ function importedAsyncRootUsage(completed) {
|
|
|
2573
2772
|
turns: 0
|
|
2574
2773
|
};
|
|
2575
2774
|
}
|
|
2775
|
+
function removeWorkflowAwaitedResult(asyncDir, resultPath, runId, publication) {
|
|
2776
|
+
try {
|
|
2777
|
+
fs.rmSync(resultPath, { force: true });
|
|
2778
|
+
} catch {}
|
|
2779
|
+
removeResultIndex(asyncDir, publication.sessionId, runId, publication.toolCallId);
|
|
2780
|
+
}
|
|
2781
|
+
function emitWorkflowAwaitedChildComplete(dm, state, runId, asyncDir, parentWorkflowRunId, completed) {
|
|
2782
|
+
let status;
|
|
2783
|
+
try {
|
|
2784
|
+
status = readStatus(asyncDir);
|
|
2785
|
+
} catch (error) {
|
|
2786
|
+
console.error(`Failed to read awaited workflow child status for ${runId}; emitting completion with fallback metadata:`, error);
|
|
2787
|
+
}
|
|
2788
|
+
dm.events.emit(SUBAGENT_ASYNC_COMPLETE_EVENT, {
|
|
2789
|
+
id: runId,
|
|
2790
|
+
runId,
|
|
2791
|
+
sessionId: status?.sessionId ?? completed.importedPublication?.sessionId ?? state.currentSessionId,
|
|
2792
|
+
completionOwnerId: status?.completionOwnerId ?? state.completionOwnerId ?? currentCompletionOwnerId(),
|
|
2793
|
+
asyncDir,
|
|
2794
|
+
agent: completed.agent,
|
|
2795
|
+
mode: "single",
|
|
2796
|
+
state: completed.stopped ? "stopped" : completed.success ? "complete" : "failed",
|
|
2797
|
+
success: completed.success,
|
|
2798
|
+
timestamp: Date.now(),
|
|
2799
|
+
triggerTurn: false,
|
|
2800
|
+
awaitedByWorkflow: true,
|
|
2801
|
+
parentWorkflowRunId
|
|
2802
|
+
});
|
|
2803
|
+
}
|
|
2576
2804
|
async function waitForWorkflowAsyncSingleResult(params, launchResult, options) {
|
|
2577
2805
|
if (params.workflowAwaitAsync !== true || !launchResult.details.asyncDir)
|
|
2578
2806
|
return launchResult;
|
|
@@ -2594,7 +2822,9 @@ async function waitForWorkflowAsyncSingleResult(params, launchResult, options) {
|
|
|
2594
2822
|
} finally {
|
|
2595
2823
|
options.signal?.removeEventListener("abort", stopOnAbort);
|
|
2596
2824
|
}
|
|
2597
|
-
|
|
2825
|
+
if (completed.importedPublication)
|
|
2826
|
+
removeWorkflowAwaitedResult(asyncDir, resultPath, options.runId, completed.importedPublication);
|
|
2827
|
+
emitWorkflowAwaitedChildComplete(options.dm, options.state, options.runId, asyncDir, params.workflowParentRunId, completed);
|
|
2598
2828
|
const usage = importedAsyncRootUsage(completed);
|
|
2599
2829
|
const childResult = omitUndefinedProperties({
|
|
2600
2830
|
index: 0,
|
|
@@ -2610,14 +2840,14 @@ async function waitForWorkflowAsyncSingleResult(params, launchResult, options) {
|
|
|
2610
2840
|
...completed.stopped ? { stopped: true } : {},
|
|
2611
2841
|
...completed.sessionFile ? { sessionFile: completed.sessionFile } : {},
|
|
2612
2842
|
...completed.model ? { model: completed.model } : {},
|
|
2613
|
-
...completed.
|
|
2614
|
-
...completed.modelAttempts ? { modelAttempts: completed.modelAttempts } : {},
|
|
2843
|
+
...completed.requestedModel ? { requestedModel: completed.requestedModel } : {},
|
|
2615
2844
|
...completed.contextOverflow ? { contextOverflow: true } : {},
|
|
2616
2845
|
...completed.structuredOutput !== undefined ? { structuredOutput: completed.structuredOutput } : {},
|
|
2617
2846
|
...completed.structuredOutputPath ? { structuredOutputPath: completed.structuredOutputPath } : {},
|
|
2618
2847
|
...completed.structuredOutputSchemaPath ? { structuredOutputSchemaPath: completed.structuredOutputSchemaPath } : {},
|
|
2619
2848
|
...completed.acceptance ? { acceptance: completed.acceptance } : {},
|
|
2620
2849
|
...completed.artifactPaths ? { artifactPaths: completed.artifactPaths } : {},
|
|
2850
|
+
...completed.savedOutputPath ? { savedOutputPath: completed.savedOutputPath } : {},
|
|
2621
2851
|
...completed.outputSaveError ? { outputSaveError: completed.outputSaveError } : {},
|
|
2622
2852
|
...completed.transcriptPath ? { transcriptPath: completed.transcriptPath } : {},
|
|
2623
2853
|
...completed.transcriptError ? { transcriptError: completed.transcriptError } : {}
|
|
@@ -2673,11 +2903,13 @@ async function runAsyncPath(data, deps) {
|
|
|
2673
2903
|
currentModelProvider: parentModel?.provider,
|
|
2674
2904
|
currentModel: parentModel,
|
|
2675
2905
|
modelScope: data.modelScope,
|
|
2906
|
+
modelResponseAliases: deps.config.modelResponseAliases,
|
|
2676
2907
|
interactive: ctx.hasUI,
|
|
2677
|
-
permissions: deps.config.permissions
|
|
2908
|
+
permissions: deps.config.permissions,
|
|
2909
|
+
childRuntime: deps.childRuntime
|
|
2678
2910
|
});
|
|
2679
2911
|
const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
2680
|
-
const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth);
|
|
2912
|
+
const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime);
|
|
2681
2913
|
const currentProvider = parentModel?.provider;
|
|
2682
2914
|
const controlIntercomTarget = resolveRunLevelIntercomTarget(intercomBridge, contextPolicy);
|
|
2683
2915
|
const childIntercomTarget = resolveChildIntercomTargetFactory(intercomBridge, contextPolicy, id);
|
|
@@ -2701,9 +2933,21 @@ async function runAsyncPath(data, deps) {
|
|
|
2701
2933
|
return buildRequestedModeError(params, `Agent '${a.name}' uses runner.type='${a.runner.type}' and does not support fast mode.`);
|
|
2702
2934
|
}
|
|
2703
2935
|
const modelScopes = resolveModelScopesForAgent(data.modelScope, a.name, parentModel);
|
|
2704
|
-
const
|
|
2705
|
-
|
|
2706
|
-
|
|
2936
|
+
const modelOrigin = resolveModelOrigin({
|
|
2937
|
+
storedOrigin: params.modelOrigin,
|
|
2938
|
+
explicitModel: params.model,
|
|
2939
|
+
agentModel: a.model,
|
|
2940
|
+
parentModel
|
|
2941
|
+
});
|
|
2942
|
+
const modelOverride = a.runner?.type === "external-cli" || a.runner?.type === "external-job" ? params.model ?? (externalRunnerWithoutExplicitModel ? undefined : a.model) : resolveEffectiveSubagentModel(params.model, a.model, parentModel, availableModels, a.modelProvider ?? currentProvider, {
|
|
2943
|
+
...modelScopes.length === 0 ? {} : { scope: modelScopes },
|
|
2944
|
+
source: modelOrigin === "explicit" ? "explicit" : "inherited"
|
|
2945
|
+
});
|
|
2946
|
+
const modelOverrideFromParent = modelOrigin === "inherited";
|
|
2947
|
+
const launchRuleError = applyWatchdogLaunchRules({ cwd: effectiveCwd, agent: a.name, model: modelOverride ?? (parentModel && `${parentModel.provider}/${parentModel.id}`), warn: (violation) => deps.watchdog?.displayRuleWarning(violation) });
|
|
2948
|
+
if (launchRuleError)
|
|
2949
|
+
return toExecutionErrorResult(params, new Error(launchRuleError), data.contextPolicy.contextSummary);
|
|
2950
|
+
const asyncResult = await executeAsyncSingle(id, compactOptional({
|
|
2707
2951
|
agent: params.agent,
|
|
2708
2952
|
task: shouldForkAgent(contextPolicy, params.agent) ? wrapForkTask(params.task ?? "") : params.task ?? "",
|
|
2709
2953
|
goal: params.task ?? "",
|
|
@@ -2713,13 +2957,15 @@ async function runAsyncPath(data, deps) {
|
|
|
2713
2957
|
availableModels,
|
|
2714
2958
|
cwd: effectiveCwd,
|
|
2715
2959
|
requestedCwd: data.requestedCwd,
|
|
2960
|
+
machine: params.machine,
|
|
2961
|
+
machineCwd: params.machineCwd,
|
|
2716
2962
|
maxOutput: params.maxOutput,
|
|
2717
2963
|
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
2718
2964
|
artifactConfig,
|
|
2719
2965
|
shareEnabled,
|
|
2720
2966
|
activeAsyncCapacity: data.activeAsyncCapacity,
|
|
2721
2967
|
sessionRoot,
|
|
2722
|
-
sessionFile: sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent),
|
|
2968
|
+
sessionFile: sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent, modelOrigin),
|
|
2723
2969
|
context: contextPolicy.contextForAgent(params.agent),
|
|
2724
2970
|
skills,
|
|
2725
2971
|
output: effectiveOutput,
|
|
@@ -2730,7 +2976,8 @@ async function runAsyncPath(data, deps) {
|
|
|
2730
2976
|
modelOverride,
|
|
2731
2977
|
fast: params.fast,
|
|
2732
2978
|
modelOverrideFromParent,
|
|
2733
|
-
|
|
2979
|
+
modelOrigin,
|
|
2980
|
+
thinkingOverride: externalRunnerWithoutExplicitModel ? undefined : thinkingOverrideForTask(),
|
|
2734
2981
|
thinkingCeiling: a.maxThinking,
|
|
2735
2982
|
maxSubagentDepth,
|
|
2736
2983
|
waitToolEnabled: deps.waitToolEnabled,
|
|
@@ -2739,13 +2986,16 @@ async function runAsyncPath(data, deps) {
|
|
|
2739
2986
|
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
2740
2987
|
worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
|
|
2741
2988
|
worktreeBaseDir: deps.config.worktreeBaseDir,
|
|
2989
|
+
baseRef: params.baseRef,
|
|
2990
|
+
worktreeProvider: deps.config.worktreeProvider,
|
|
2991
|
+
worktreeBranchPrefix: deps.config.worktreeBranchPrefix,
|
|
2742
2992
|
controlConfig,
|
|
2743
2993
|
intercomBridge: params.intercomBridge,
|
|
2744
2994
|
controlIntercomTarget,
|
|
2745
2995
|
childIntercomTarget: childIntercomTarget ? (agent, index) => childIntercomTarget(agent, index) : undefined,
|
|
2746
2996
|
nestedRoute,
|
|
2747
2997
|
agentContract: params.agentContract,
|
|
2748
|
-
structuredOutputSchema: params.outputSchema,
|
|
2998
|
+
structuredOutputSchema: params.outputSchema || undefined,
|
|
2749
2999
|
extensionBindings: params.extensionBindings,
|
|
2750
3000
|
acceptance: params.acceptance,
|
|
2751
3001
|
timeoutMs: data.timeoutMs,
|
|
@@ -2753,6 +3003,7 @@ async function runAsyncPath(data, deps) {
|
|
|
2753
3003
|
usageBudget: data.usageBudget,
|
|
2754
3004
|
configToolBudget: data.configToolBudget,
|
|
2755
3005
|
toolTimeoutMs: data.params?.toolTimeoutMs,
|
|
3006
|
+
checkpointBeforeDeadlineMs: data.params?.checkpointBeforeDeadlineMs ?? deps.config.checkpointBeforeDeadlineMs,
|
|
2756
3007
|
configToolTimeoutMs: data.configToolTimeoutMs,
|
|
2757
3008
|
capabilityCeiling: data.capabilityCeiling,
|
|
2758
3009
|
runFanoutBudget: data.runFanoutBudget,
|
|
@@ -2761,20 +3012,25 @@ async function runAsyncPath(data, deps) {
|
|
|
2761
3012
|
lane: params.lane,
|
|
2762
3013
|
workflowAwaitAsync: params.workflowAwaitAsync
|
|
2763
3014
|
}));
|
|
2764
|
-
return waitForWorkflowAsyncSingleResult(params, asyncResult, { runId: id, task: params.task ?? "", signal: data.signal, state: deps.state, kill: deps.kill });
|
|
3015
|
+
return waitForWorkflowAsyncSingleResult(params, asyncResult, { runId: id, task: params.task ?? "", signal: data.signal, state: deps.state, dm: deps.dm, kill: deps.kill });
|
|
2765
3016
|
}
|
|
2766
3017
|
return null;
|
|
2767
3018
|
}
|
|
2768
|
-
function createSingleWorktreeSetup(
|
|
2769
|
-
if (!enabled)
|
|
2770
|
-
return {};
|
|
3019
|
+
async function createSingleWorktreeSetup(cwd, runId, agent, setupHook, setupHookTimeoutMs, baseDir, baseRef, provider, branchPrefix, label, task, onProgress, signal, deadlineAt) {
|
|
2771
3020
|
try {
|
|
2772
3021
|
return {
|
|
2773
|
-
setup: createWorktrees(cwd, runId, 1, omitUndefinedProperties({
|
|
3022
|
+
setup: await createWorktrees(cwd, runId, 1, omitUndefinedProperties({
|
|
2774
3023
|
agents: [agent],
|
|
2775
3024
|
setupHook: setupHook ? { hookPath: setupHook, ...setupHookTimeoutMs === undefined ? {} : { timeoutMs: setupHookTimeoutMs } } : undefined,
|
|
2776
3025
|
baseDir,
|
|
2777
|
-
|
|
3026
|
+
baseRef,
|
|
3027
|
+
provider,
|
|
3028
|
+
branchPrefix,
|
|
3029
|
+
labels: [label],
|
|
3030
|
+
tasks: [task],
|
|
3031
|
+
onProgress,
|
|
3032
|
+
signal,
|
|
3033
|
+
deadlineAt
|
|
2778
3034
|
}))
|
|
2779
3035
|
};
|
|
2780
3036
|
} catch (error) {
|
|
@@ -2796,9 +3052,6 @@ export function sanitizeRunPathSegment(value, maxBytes = 120) {
|
|
|
2796
3052
|
function resolveSingleRunOutputBaseDir(deps, artifactsDir, runId) {
|
|
2797
3053
|
return resolveConfiguredSingleRunOutputBaseDir(deps) ?? path.join(artifactsDir, "outputs", sanitizeRunPathSegment(runId));
|
|
2798
3054
|
}
|
|
2799
|
-
function resolveWorkflowAggregateOutputPath(output, ctxCwd, workflowCwd, outputBaseDir) {
|
|
2800
|
-
return resolveSingleOutputPath(output, ctxCwd, workflowCwd, outputBaseDir);
|
|
2801
|
-
}
|
|
2802
3055
|
function workflowChildDefaultOutput(aggregateOutputPath, artifactsDir, workflowRunId, workflowKey) {
|
|
2803
3056
|
if (aggregateOutputPath) {
|
|
2804
3057
|
const parsed = path.parse(aggregateOutputPath);
|
|
@@ -2808,6 +3061,9 @@ function workflowChildDefaultOutput(aggregateOutputPath, artifactsDir, workflowR
|
|
|
2808
3061
|
}
|
|
2809
3062
|
function workflowHostCommandRunner(input) {
|
|
2810
3063
|
return async (key, params, signal) => {
|
|
3064
|
+
const authorizationError = input.authorize?.(key, params);
|
|
3065
|
+
if (authorizationError)
|
|
3066
|
+
throw new Error(authorizationError);
|
|
2811
3067
|
const defaultOutputPath = path.join(input.artifactsDir, "outputs", sanitizeRunPathSegment(input.workflowRunId), "host", `${sanitizeRunPathSegment(key)}.log`);
|
|
2812
3068
|
const outputPath = params.output ? path.resolve(input.workflowCwd, params.output) : defaultOutputPath;
|
|
2813
3069
|
const claimPath = resolveWorkflowHostOutputClaimPath(outputPath);
|
|
@@ -2839,8 +3095,22 @@ function appendWorkflowOutputWarning(text, warning) {
|
|
|
2839
3095
|
|
|
2840
3096
|
${warning}` : text;
|
|
2841
3097
|
}
|
|
3098
|
+
export function resolveWorkflowChildLocalCwd(input) {
|
|
3099
|
+
if (input.params.machine !== undefined)
|
|
3100
|
+
return input.workflowCwd;
|
|
3101
|
+
if (typeof input.params.agent === "string") {
|
|
3102
|
+
const agentScope = resolveExecutionAgentScope(input.params.agentScope ?? input.workflowAgentScope);
|
|
3103
|
+
const workflowAgents = input.discoverAgents(input.workflowCwd, agentScope).agents;
|
|
3104
|
+
const agent = resolveAgentName(input.params.agent, workflowAgents).agent ?? resolveAgentName(input.params.agent, input.agents).agent;
|
|
3105
|
+
if (agent?.machine !== undefined)
|
|
3106
|
+
return input.workflowCwd;
|
|
3107
|
+
}
|
|
3108
|
+
return typeof input.params.cwd === "string" ? resolveChildCwd(input.workflowCwd, input.params.cwd) : input.workflowCwd;
|
|
3109
|
+
}
|
|
2842
3110
|
function resolveWorkflowChildOutputPath(input) {
|
|
2843
|
-
|
|
3111
|
+
const rawOutput = input.params.output;
|
|
3112
|
+
const hasExplicitOutput = typeof rawOutput === "string" || typeof rawOutput === "boolean";
|
|
3113
|
+
if (typeof input.params.resume === "string" && (!hasExplicitOutput || rawOutput === true || rawOutput === "true")) {
|
|
2844
3114
|
if (!input.state)
|
|
2845
3115
|
return { path: undefined, inherited: false };
|
|
2846
3116
|
const index = input.params.index;
|
|
@@ -2850,13 +3120,14 @@ function resolveWorkflowChildOutputPath(input) {
|
|
|
2850
3120
|
}, input.state);
|
|
2851
3121
|
return { path: "recoveryDescriptor" in target ? target.recoveryDescriptor?.outputPath : undefined, inherited: false };
|
|
2852
3122
|
}
|
|
2853
|
-
const
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
3123
|
+
const childCwd = resolveWorkflowChildLocalCwd(input);
|
|
3124
|
+
let agentOutput;
|
|
3125
|
+
if (rawOutput === true || rawOutput === "true" || !hasExplicitOutput && !input.aggregateOutputPath) {
|
|
3126
|
+
const agentScope = resolveExecutionAgentScope(input.params.agentScope ?? input.workflowAgentScope);
|
|
3127
|
+
const discoveredAgents = input.discoverAgents(childCwd, agentScope).agents;
|
|
3128
|
+
const agent = typeof input.params.agent === "string" ? resolveAgentName(input.params.agent, discoveredAgents).agent ?? resolveAgentName(input.params.agent, input.agents).agent : undefined;
|
|
3129
|
+
agentOutput = typeof agent?.output === "string" ? agent.output : undefined;
|
|
3130
|
+
}
|
|
2860
3131
|
const output = rawOutput === true || rawOutput === "true" ? agentOutput : hasExplicitOutput ? rawOutput : input.aggregateOutputPath ? workflowChildDefaultOutput(input.aggregateOutputPath, input.artifactsDir, input.workflowRunId, input.key) : agentOutput;
|
|
2861
3132
|
return {
|
|
2862
3133
|
path: resolveSingleOutputPath(output, input.ctxCwd, childCwd, input.configuredOutputBaseDir ?? path.join(input.artifactsDir, "outputs", sanitizeRunPathSegment(input.workflowRunId))),
|
|
@@ -2911,25 +3182,89 @@ function prepareWorkflowChildLaunchParams(input) {
|
|
|
2911
3182
|
childParams = { ...input.childParams, output: input.outputOverride };
|
|
2912
3183
|
} else if (usesDefaultOutput && input.aggregateOutputPath !== undefined) {
|
|
2913
3184
|
childParams = { ...input.childParams, output: workflowChildDefaultOutput(input.aggregateOutputPath, input.artifactsDir, input.parentWorkflowRunId, input.workflowKey) };
|
|
2914
|
-
} else if (input.childParams.resume === undefined) {
|
|
3185
|
+
} else if (input.childParams.resume === undefined || input.childParams.output !== undefined) {
|
|
2915
3186
|
const resolvedOutput = resolveWorkflowChildOutputPath({ ctxCwd: input.ctxCwd, workflowCwd: input.workflowCwd, artifactsDir: input.artifactsDir, workflowRunId: input.parentWorkflowRunId, aggregateOutputPath: input.aggregateOutputPath, configuredOutputBaseDir: input.configuredOutputBaseDir, discoverAgents: input.discoverAgents, agents: input.agents, workflowAgentScope: input.workflowAgentScope, key: input.workflowKey, params: input.childParams });
|
|
2916
3187
|
if (resolvedOutput.path)
|
|
2917
3188
|
childParams = { ...input.childParams, output: resolvedOutput.path };
|
|
2918
3189
|
}
|
|
2919
|
-
const childCwd =
|
|
3190
|
+
const childCwd = resolveWorkflowChildLocalCwd({ ...input, params: childParams });
|
|
2920
3191
|
const agentScope = resolveExecutionAgentScope(childParams.agentScope ?? input.workflowAgentScope);
|
|
2921
3192
|
const discoveredAgents = input.discoverAgents(childCwd, agentScope).agents;
|
|
2922
3193
|
const agent = typeof childParams.agent === "string" ? resolveAgentName(childParams.agent, discoveredAgents).agent ?? resolveAgentName(childParams.agent, input.agents).agent : undefined;
|
|
2923
3194
|
const externalAsyncRequired = agent?.runner?.type === "external-cli" || agent?.runner?.type === "external-job";
|
|
2924
3195
|
return prepareWorkflowLaunchParams(input.workflowDefaults, childParams, input.parentWorkflowRunId, input.workflowKey, { ...input.options, externalAsyncRequired, outputClaimPath: input.outputClaimPath });
|
|
2925
3196
|
}
|
|
2926
|
-
function finalizeSingleWorktreeHandoff(input) {
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
3197
|
+
async function finalizeSingleWorktreeHandoff(input) {
|
|
3198
|
+
let admitted = false;
|
|
3199
|
+
try {
|
|
3200
|
+
return await withWorktreeTransaction(() => {
|
|
3201
|
+
admitted = true;
|
|
3202
|
+
const diffsDir = path.join(input.artifactsDir, "worktree-diffs", input.runId);
|
|
3203
|
+
const diffs = diffWorktrees(input.worktreeSetup, [input.agent], diffsDir);
|
|
3204
|
+
const diffSummary = formatWorktreeDiffSummary(diffs);
|
|
3205
|
+
const manifestPath = parallelHandoffPath(input.artifactsDir, input.runId);
|
|
3206
|
+
const handoff = {
|
|
3207
|
+
manifestPath,
|
|
3208
|
+
runId: input.runId,
|
|
3209
|
+
mode: "single",
|
|
3210
|
+
source: "foreground",
|
|
3211
|
+
cwd: input.cwd,
|
|
3212
|
+
stepIndex: 0,
|
|
3213
|
+
flatStartIndex: 0,
|
|
3214
|
+
setup: input.worktreeSetup,
|
|
3215
|
+
laneBindings: input.workflowKey || input.lane ? [{ index: 0, taskIndex: 0, ...input.workflowKey ? { workflowKey: input.workflowKey } : {}, runId: input.workflowKey ? input.runId : undefined, ...input.lane ? { lane: input.lane } : {} }] : undefined,
|
|
3216
|
+
diffs,
|
|
3217
|
+
results: [{
|
|
3218
|
+
agent: input.result.agent,
|
|
3219
|
+
...input.workflowKey ? { workflowKey: input.workflowKey } : {},
|
|
3220
|
+
...input.workflowKey ? { runId: input.runId } : {},
|
|
3221
|
+
...input.lane ? { lane: input.lane } : {},
|
|
3222
|
+
status: resolveSubagentResultStatus(omitUndefinedProperties({
|
|
3223
|
+
exitCode: input.result.exitCode,
|
|
3224
|
+
interrupted: input.result.interrupted,
|
|
3225
|
+
detached: input.result.detached,
|
|
3226
|
+
state: input.result.stopped ? "stopped" : undefined,
|
|
3227
|
+
processSignal: input.result.processSignal,
|
|
3228
|
+
timedOut: input.result.timedOut,
|
|
3229
|
+
stopped: input.result.stopped,
|
|
3230
|
+
turnBudgetExceeded: input.result.turnBudgetExceeded
|
|
3231
|
+
})),
|
|
3232
|
+
summary: resultSummaryForIntercom(input.result),
|
|
3233
|
+
...input.result.artifactPaths?.outputPath ? { outputPath: input.result.artifactPaths.outputPath } : {},
|
|
3234
|
+
...input.result.structuredOutput !== undefined ? { structuredOutput: input.result.structuredOutput } : {},
|
|
3235
|
+
...input.result.structuredOutputPath ? { structuredOutputPath: input.result.structuredOutputPath } : {},
|
|
3236
|
+
...input.result.sessionFile ? { sessionPath: input.result.sessionFile } : {}
|
|
3237
|
+
}]
|
|
3238
|
+
};
|
|
3239
|
+
try {
|
|
3240
|
+
writeParallelHandoffGroup(handoff);
|
|
3241
|
+
const cleanup = cleanupWorktrees(input.worktreeSetup, { kind: "preserve", capturedDiffs: diffs, handoffManifestPath: manifestPath });
|
|
3242
|
+
const reference = writeParallelHandoffGroup({ ...handoff, cleanup });
|
|
3243
|
+
return {
|
|
3244
|
+
suffix: [diffSummary, formatParallelHandoffReference(reference)].filter(Boolean).join(`
|
|
3245
|
+
|
|
3246
|
+
`),
|
|
3247
|
+
reference
|
|
3248
|
+
};
|
|
3249
|
+
} catch (error) {
|
|
3250
|
+
return { suffix: [diffSummary, formatParallelHandoffError(error)].filter(Boolean).join(`
|
|
3251
|
+
|
|
3252
|
+
`) };
|
|
3253
|
+
}
|
|
3254
|
+
});
|
|
3255
|
+
} catch (error) {
|
|
3256
|
+
if (admitted)
|
|
3257
|
+
throw error;
|
|
3258
|
+
const reference = retainSingleWorktreeHandoff(input, error);
|
|
3259
|
+
return { suffix: `${formatParallelHandoffError(error)}
|
|
3260
|
+
|
|
3261
|
+
${formatParallelHandoffReference(reference)}`, reference };
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
function retainSingleWorktreeHandoff(input, error) {
|
|
3265
|
+
const reason = `Worktree finalization retained; manual reconciliation required: ${error instanceof Error ? error.message : String(error)}`;
|
|
3266
|
+
return writeParallelHandoffGroup({
|
|
3267
|
+
manifestPath: parallelHandoffPath(input.artifactsDir, input.runId),
|
|
2933
3268
|
runId: input.runId,
|
|
2934
3269
|
mode: "single",
|
|
2935
3270
|
source: "foreground",
|
|
@@ -2937,45 +3272,20 @@ function finalizeSingleWorktreeHandoff(input) {
|
|
|
2937
3272
|
stepIndex: 0,
|
|
2938
3273
|
flatStartIndex: 0,
|
|
2939
3274
|
setup: input.worktreeSetup,
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
stopped: input.result.stopped,
|
|
2955
|
-
turnBudgetExceeded: input.result.turnBudgetExceeded
|
|
2956
|
-
})),
|
|
2957
|
-
summary: resultSummaryForIntercom(input.result),
|
|
2958
|
-
...input.result.artifactPaths?.outputPath ? { outputPath: input.result.artifactPaths.outputPath } : {},
|
|
2959
|
-
...input.result.structuredOutput !== undefined ? { structuredOutput: input.result.structuredOutput } : {},
|
|
2960
|
-
...input.result.structuredOutputPath ? { structuredOutputPath: input.result.structuredOutputPath } : {},
|
|
2961
|
-
...input.result.sessionFile ? { sessionPath: input.result.sessionFile } : {}
|
|
2962
|
-
}]
|
|
2963
|
-
};
|
|
2964
|
-
try {
|
|
2965
|
-
writeParallelHandoffGroup(handoff);
|
|
2966
|
-
const cleanup = cleanupWorktrees(input.worktreeSetup, { kind: "preserve", capturedDiffs: diffs, handoffManifestPath: manifestPath });
|
|
2967
|
-
const reference = writeParallelHandoffGroup({ ...handoff, cleanup });
|
|
2968
|
-
return {
|
|
2969
|
-
suffix: [diffSummary, formatParallelHandoffReference(reference)].filter(Boolean).join(`
|
|
2970
|
-
|
|
2971
|
-
`),
|
|
2972
|
-
reference
|
|
2973
|
-
};
|
|
2974
|
-
} catch (error) {
|
|
2975
|
-
return { suffix: [diffSummary, formatParallelHandoffError(error)].filter(Boolean).join(`
|
|
2976
|
-
|
|
2977
|
-
`) };
|
|
2978
|
-
}
|
|
3275
|
+
diffs: [],
|
|
3276
|
+
results: [],
|
|
3277
|
+
cleanup: { state: "partial", pruned: false, errors: [reason], tasks: input.worktreeSetup.worktrees.map((worktree) => ({
|
|
3278
|
+
index: worktree.index,
|
|
3279
|
+
path: worktree.path,
|
|
3280
|
+
branch: worktree.branch,
|
|
3281
|
+
provider: worktree.provider,
|
|
3282
|
+
naming: worktree.naming,
|
|
3283
|
+
worktreeRemoved: false,
|
|
3284
|
+
branchRemoved: false,
|
|
3285
|
+
preserved: true,
|
|
3286
|
+
reason
|
|
3287
|
+
})) }
|
|
3288
|
+
});
|
|
2979
3289
|
}
|
|
2980
3290
|
async function runSinglePath(data, deps) {
|
|
2981
3291
|
const {
|
|
@@ -2993,7 +3303,8 @@ async function runSinglePath(data, deps) {
|
|
|
2993
3303
|
artifactsDir,
|
|
2994
3304
|
onUpdate,
|
|
2995
3305
|
controlConfig,
|
|
2996
|
-
contextPolicy
|
|
3306
|
+
contextPolicy,
|
|
3307
|
+
suppressUnchangedDelegationUpdates
|
|
2997
3308
|
} = data;
|
|
2998
3309
|
let lane;
|
|
2999
3310
|
try {
|
|
@@ -3015,6 +3326,15 @@ async function runSinglePath(data, deps) {
|
|
|
3015
3326
|
details: { mode: "single", results: [] }
|
|
3016
3327
|
};
|
|
3017
3328
|
}
|
|
3329
|
+
let foregroundMachine;
|
|
3330
|
+
const requestedMachine = params.machine ?? agentConfig.machine;
|
|
3331
|
+
if (requestedMachine) {
|
|
3332
|
+
try {
|
|
3333
|
+
foregroundMachine = resolveHerdrMachinePlacement({ machine: requestedMachine, cwd: ctx.cwd, stepCwd: params.machineCwd }).machine;
|
|
3334
|
+
} catch (error) {
|
|
3335
|
+
return toExecutionErrorResult(params, error instanceof Error ? error : new Error(String(error)), data.contextPolicy.contextSummary);
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3018
3338
|
const effectiveToolBudget = resolveEffectiveToolBudget(omitUndefinedProperties({ runBudget: data.toolBudget, agentBudget: agentConfig.toolBudget, configBudget: data.configToolBudget }));
|
|
3019
3339
|
if (effectiveToolBudget.error)
|
|
3020
3340
|
return toExecutionErrorResult(params, new Error(effectiveToolBudget.error), data.contextPolicy.contextSummary);
|
|
@@ -3023,19 +3343,31 @@ async function runSinglePath(data, deps) {
|
|
|
3023
3343
|
const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
3024
3344
|
const modelScopes = resolveModelScopesForAgent(data.modelScope, agentConfig.name, parentModel);
|
|
3025
3345
|
let task = typeof params.task === "string" ? params.task : "";
|
|
3026
|
-
|
|
3027
|
-
|
|
3346
|
+
const modelOrigin = resolveModelOrigin({
|
|
3347
|
+
storedOrigin: params.modelOrigin,
|
|
3348
|
+
explicitModel: params.model,
|
|
3349
|
+
agentModel: agentConfig.model,
|
|
3350
|
+
parentModel
|
|
3351
|
+
});
|
|
3352
|
+
let modelOverride = resolveEffectiveSubagentModel(params.model, agentConfig.model, parentModel, availableModels, agentConfig.modelProvider ?? currentProvider, {
|
|
3353
|
+
...modelScopes.length === 0 ? {} : { scope: modelScopes },
|
|
3354
|
+
source: modelOrigin === "explicit" ? "explicit" : "inherited"
|
|
3355
|
+
});
|
|
3356
|
+
const modelOverrideFromParent = modelOrigin === "inherited";
|
|
3357
|
+
const launchRuleError = applyWatchdogLaunchRules({ cwd: effectiveCwd, agent: agentConfig.name, model: modelOverride ?? (parentModel && `${parentModel.provider}/${parentModel.id}`), warn: (violation) => deps.watchdog?.displayRuleWarning(violation) });
|
|
3358
|
+
if (launchRuleError)
|
|
3359
|
+
return toExecutionErrorResult(params, new Error(launchRuleError), data.contextPolicy.contextSummary);
|
|
3028
3360
|
let skillOverride = normalizeSkillInput(params.skill);
|
|
3029
3361
|
let readsOverride = params.reads;
|
|
3030
3362
|
const rawOutput = params.output !== undefined ? params.output : agentConfig.output;
|
|
3031
3363
|
let effectiveOutput = normalizeSingleOutputOverride(rawOutput, agentConfig.output);
|
|
3032
3364
|
const effectiveOutputMode = params.outputMode ?? agentConfig.outputMode ?? "inline";
|
|
3033
|
-
const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth);
|
|
3365
|
+
const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime);
|
|
3034
3366
|
const maxSubagentDepth = resolveChildMaxSubagentDepth(currentMaxSubagentDepth, agentConfig.maxSubagentDepth);
|
|
3035
|
-
const sourceCwd = effectiveCwd;
|
|
3367
|
+
const sourceCwd = foregroundMachine?.cwd ?? effectiveCwd;
|
|
3036
3368
|
let pendingHandoff;
|
|
3037
|
-
const { setup: worktreeSetup, errorResult: worktreeSetupError } =
|
|
3038
|
-
pendingHandoff =
|
|
3369
|
+
const { setup: worktreeSetup, errorResult: worktreeSetupError } = params.worktree ? await createSingleWorktreeSetup(sourceCwd, runId, params.agent, deps.config.worktreeSetupHook, deps.config.worktreeSetupHookTimeoutMs, deps.config.worktreeBaseDir, params.baseRef, deps.config.worktreeProvider, deps.config.worktreeBranchPrefix, params.lane?.key ?? params.workflowKey, task, (progress) => {
|
|
3370
|
+
pendingHandoff = writeWorktreeSetupHandoff({
|
|
3039
3371
|
manifestPath: parallelHandoffPath(artifactsDir, runId),
|
|
3040
3372
|
runId,
|
|
3041
3373
|
mode: "single",
|
|
@@ -3043,13 +3375,52 @@ async function runSinglePath(data, deps) {
|
|
|
3043
3375
|
cwd: sourceCwd,
|
|
3044
3376
|
stepIndex: 0,
|
|
3045
3377
|
flatStartIndex: 0,
|
|
3046
|
-
|
|
3378
|
+
progress,
|
|
3047
3379
|
laneBindings: params.workflowKey || lane ? [{ index: 0, taskIndex: 0, ...params.workflowKey ? { workflowKey: params.workflowKey, runId } : {}, ...lane ? { lane } : {} }] : undefined
|
|
3048
3380
|
});
|
|
3049
|
-
});
|
|
3050
|
-
if (worktreeSetupError)
|
|
3381
|
+
}, signal, data.deadlineAt) : {};
|
|
3382
|
+
if (worktreeSetupError) {
|
|
3383
|
+
if (pendingHandoff) {
|
|
3384
|
+
worktreeSetupError.details.parallelHandoff = pendingHandoff;
|
|
3385
|
+
worktreeSetupError.content.push({ type: "text", text: formatParallelHandoffReference(pendingHandoff) });
|
|
3386
|
+
}
|
|
3051
3387
|
return worktreeSetupError;
|
|
3388
|
+
}
|
|
3052
3389
|
const singleCwd = worktreeSetup?.worktrees[0]?.agentCwd ?? sourceCwd;
|
|
3390
|
+
const cleanupSingleWorktree = async () => {
|
|
3391
|
+
if (!worktreeSetup)
|
|
3392
|
+
return;
|
|
3393
|
+
let admitted = false;
|
|
3394
|
+
try {
|
|
3395
|
+
await withWorktreeTransaction(() => {
|
|
3396
|
+
if (data.deadlineAt !== undefined && Date.now() >= data.deadlineAt)
|
|
3397
|
+
throw new Error("Run deadline expired before unlaunched worktree cleanup");
|
|
3398
|
+
admitted = true;
|
|
3399
|
+
const cleanup = cleanupWorktrees(worktreeSetup);
|
|
3400
|
+
pendingHandoff = writeParallelHandoffGroup({
|
|
3401
|
+
manifestPath: parallelHandoffPath(artifactsDir, runId),
|
|
3402
|
+
runId,
|
|
3403
|
+
mode: "single",
|
|
3404
|
+
source: "foreground",
|
|
3405
|
+
cwd: sourceCwd,
|
|
3406
|
+
stepIndex: 0,
|
|
3407
|
+
flatStartIndex: 0,
|
|
3408
|
+
setup: worktreeSetup,
|
|
3409
|
+
diffs: [],
|
|
3410
|
+
results: [],
|
|
3411
|
+
cleanup
|
|
3412
|
+
});
|
|
3413
|
+
});
|
|
3414
|
+
} catch (error) {
|
|
3415
|
+
if (admitted)
|
|
3416
|
+
throw error;
|
|
3417
|
+
pendingHandoff = retainSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd }, error);
|
|
3418
|
+
}
|
|
3419
|
+
};
|
|
3420
|
+
if (worktreeSetup && (signal?.aborted || data.deadlineAt !== undefined && Date.now() >= data.deadlineAt)) {
|
|
3421
|
+
await cleanupSingleWorktree();
|
|
3422
|
+
return { content: [{ type: "text", text: "Subagent setup canceled before child launch." }], isError: true, details: { mode: "single", results: [], parallelHandoff: pendingHandoff } };
|
|
3423
|
+
}
|
|
3053
3424
|
const authoredTask = task;
|
|
3054
3425
|
if (shouldForkAgent(contextPolicy, params.agent)) {
|
|
3055
3426
|
task = wrapForkTask(task);
|
|
@@ -3058,13 +3429,12 @@ async function runSinglePath(data, deps) {
|
|
|
3058
3429
|
const outputPath = resolveSingleOutputPath(effectiveOutput, ctx.cwd, singleCwd, resolveSingleRunOutputBaseDir(deps, artifactsDir, runId));
|
|
3059
3430
|
const validationError = validateFileOnlyOutputMode(effectiveOutputMode, outputPath, `Single run (${params.agent})`);
|
|
3060
3431
|
if (validationError) {
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
return { content: [{ type: "text", text: validationError }], isError: true, details: { mode: "single", results: [] } };
|
|
3432
|
+
await cleanupSingleWorktree();
|
|
3433
|
+
return { content: [{ type: "text", text: validationError }], isError: true, details: { mode: "single", results: [], parallelHandoff: pendingHandoff } };
|
|
3064
3434
|
}
|
|
3065
|
-
const structuredRuntime = params.outputSchema ? createStructuredOutputRuntime(params.outputSchema, artifactConfig.enabled ? path.join(artifactsDir, "structured-output", runId) : undefined, {
|
|
3435
|
+
const structuredRuntime = params.outputSchema ? createStructuredOutputRuntime(params.outputSchema, artifactConfig.enabled ? path.join(artifactsDir, "structured-output", runId) : undefined, { acceptanceReport: resolveAcceptanceReportMode(params.acceptance) }) : undefined;
|
|
3066
3436
|
const reads = readsOverride !== undefined ? readsOverride : agentConfig.defaultReads ?? false;
|
|
3067
|
-
const readPaths = Array.isArray(reads) ? resolveExistingReadPaths(reads, singleCwd) : [];
|
|
3437
|
+
const readPaths = !foregroundMachine && Array.isArray(reads) ? resolveExistingReadPaths(reads, singleCwd) : [];
|
|
3068
3438
|
const readsInstruction = readPaths.length > 0 ? `[Read from: ${readPaths.join(", ")}]
|
|
3069
3439
|
|
|
3070
3440
|
` : "";
|
|
@@ -3078,9 +3448,10 @@ async function runSinglePath(data, deps) {
|
|
|
3078
3448
|
}
|
|
3079
3449
|
const interruptController = new AbortController;
|
|
3080
3450
|
let detachForeground;
|
|
3451
|
+
let childSessionControls;
|
|
3081
3452
|
const foregroundControl = deps.state.foregroundControls.get(runId);
|
|
3082
3453
|
if (foregroundControl) {
|
|
3083
|
-
const thinking = resolveEffectiveThinking(modelOverride, thinkingOverrideForTask(
|
|
3454
|
+
const thinking = resolveEffectiveThinking(modelOverride, thinkingOverrideForTask());
|
|
3084
3455
|
beginForegroundChild(foregroundControl, omitUndefinedProperties({
|
|
3085
3456
|
index: 0,
|
|
3086
3457
|
agent: params.agent,
|
|
@@ -3098,15 +3469,33 @@ async function runSinglePath(data, deps) {
|
|
|
3098
3469
|
interruptController.abort();
|
|
3099
3470
|
return true;
|
|
3100
3471
|
},
|
|
3101
|
-
detach: () => detachForeground?.("user request") === true
|
|
3472
|
+
detach: () => detachForeground?.("user request") === true,
|
|
3473
|
+
steer: async (input) => {
|
|
3474
|
+
if (!childSessionControls)
|
|
3475
|
+
return { state: "failed", reason: CHILD_SESSION_NOT_RUNNING_YET };
|
|
3476
|
+
try {
|
|
3477
|
+
if (input.mode === "follow_up") {
|
|
3478
|
+
await childSessionControls.followUp(input.message);
|
|
3479
|
+
return { state: "queued" };
|
|
3480
|
+
}
|
|
3481
|
+
await childSessionControls.steer(input.message);
|
|
3482
|
+
return { state: "delivered" };
|
|
3483
|
+
} catch (error) {
|
|
3484
|
+
return { state: "failed", reason: error instanceof Error ? error.message : String(error) };
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3102
3487
|
}));
|
|
3488
|
+
if (deps.childRuntime?.fanoutChild)
|
|
3489
|
+
deps.activateSupervisorTransport?.();
|
|
3103
3490
|
}
|
|
3491
|
+
const modelResponseAliases = deps.config.modelResponseAliases === undefined ? undefined : structuredClone(deps.config.modelResponseAliases);
|
|
3104
3492
|
const forwardSingleUpdate = onUpdate ? (update) => {
|
|
3105
3493
|
if (foregroundControl)
|
|
3106
3494
|
updateForegroundChild(foregroundControl, 0, update.details?.progress?.[0]);
|
|
3107
3495
|
onUpdate(update);
|
|
3108
3496
|
} : undefined;
|
|
3109
3497
|
const deadlineAt = data.deadlineAt ?? (data.timeoutMs !== undefined ? Date.now() + data.timeoutMs : undefined);
|
|
3498
|
+
const requiredExtensions = deps.childRuntime?.requiredExtensions ?? resolveRequiredChildExtensions(data.parentPiSessionId);
|
|
3110
3499
|
let r;
|
|
3111
3500
|
let resolveDetachedWorkflowChild;
|
|
3112
3501
|
const detachedWorkflowChild = params.workflowAwaitDetached === true ? new Promise((resolve) => {
|
|
@@ -3114,11 +3503,17 @@ async function runSinglePath(data, deps) {
|
|
|
3114
3503
|
}) : undefined;
|
|
3115
3504
|
try {
|
|
3116
3505
|
const launched = await runSync(ctx.cwd, agents, params.agent, task, compactOptional({
|
|
3506
|
+
machine: foregroundMachine,
|
|
3507
|
+
parentProviderRegistry: ctx.modelRegistry,
|
|
3508
|
+
remoteReads: foregroundMachine ? readsOverride : undefined,
|
|
3117
3509
|
permissions: deps.config.permissions,
|
|
3118
3510
|
runtimeSnapshotHost: deps.dm,
|
|
3119
3511
|
parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
|
|
3120
|
-
|
|
3121
|
-
|
|
3512
|
+
requiredExtensions,
|
|
3513
|
+
childRuntime: deps.childRuntime,
|
|
3514
|
+
onChildSession: (controls) => {
|
|
3515
|
+
childSessionControls = controls;
|
|
3516
|
+
},
|
|
3122
3517
|
context: data.contextPolicy.contextForAgent(params.agent),
|
|
3123
3518
|
unknownAgentDiagnosticContext: data.unknownAgentDiagnosticContext,
|
|
3124
3519
|
runFanoutBudget: params.runFanoutAdmitted ? data.runFanoutBudget : { ...data.runFanoutBudget, parentPath: `${data.runFanoutBudget.parentPath ? `${data.runFanoutBudget.parentPath}/` : ""}single` },
|
|
@@ -3130,7 +3525,7 @@ async function runSinglePath(data, deps) {
|
|
|
3130
3525
|
intercomEvents: deps.dm.events,
|
|
3131
3526
|
runId,
|
|
3132
3527
|
sessionDir: sessionDirForIndex(0),
|
|
3133
|
-
sessionFile: sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent),
|
|
3528
|
+
sessionFile: sessionFileForTask(params.agent, 0, modelOverride, modelOverrideFromParent, modelOrigin),
|
|
3134
3529
|
share: shareEnabled,
|
|
3135
3530
|
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
3136
3531
|
artifactConfig,
|
|
@@ -3142,6 +3537,7 @@ async function runSinglePath(data, deps) {
|
|
|
3142
3537
|
waitToolEnabled: deps.waitToolEnabled,
|
|
3143
3538
|
waitToolDefaultTimeoutMs: deps.waitToolDefaultTimeoutMs,
|
|
3144
3539
|
onUpdate: forwardSingleUpdate,
|
|
3540
|
+
suppressUnchangedDelegationUpdates,
|
|
3145
3541
|
controlConfig,
|
|
3146
3542
|
onControlEvent,
|
|
3147
3543
|
intercomSessionName: childIntercomTarget,
|
|
@@ -3151,10 +3547,12 @@ async function runSinglePath(data, deps) {
|
|
|
3151
3547
|
modelOverride,
|
|
3152
3548
|
fast: params.fast,
|
|
3153
3549
|
modelOverrideFromParent,
|
|
3154
|
-
|
|
3550
|
+
modelOrigin,
|
|
3551
|
+
thinkingOverride: thinkingOverrideForTask(),
|
|
3155
3552
|
thinkingCeiling: agentConfig.maxThinking,
|
|
3156
3553
|
extensionBindings: params.extensionBindings,
|
|
3157
3554
|
availableModels,
|
|
3555
|
+
modelResponseAliases,
|
|
3158
3556
|
preferredModelProvider: currentProvider,
|
|
3159
3557
|
modelScope: modelScopes,
|
|
3160
3558
|
skills: effectiveSkills,
|
|
@@ -3167,14 +3565,14 @@ async function runSinglePath(data, deps) {
|
|
|
3167
3565
|
onDetachReady: (detach) => {
|
|
3168
3566
|
detachForeground = detach;
|
|
3169
3567
|
},
|
|
3170
|
-
onDetachedExit: (result) => {
|
|
3568
|
+
onDetachedExit: async (result) => {
|
|
3171
3569
|
if (resolveDetachedWorkflowChild) {
|
|
3172
3570
|
resolveDetachedWorkflowChild(result);
|
|
3173
3571
|
return;
|
|
3174
3572
|
}
|
|
3175
3573
|
try {
|
|
3176
3574
|
if (worktreeSetup) {
|
|
3177
|
-
finalizeSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd, agent: params.agent, result, workflowKey: params.workflowKey, lane });
|
|
3575
|
+
await finalizeSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd, agent: params.agent, result, workflowKey: params.workflowKey, lane });
|
|
3178
3576
|
}
|
|
3179
3577
|
try {
|
|
3180
3578
|
updateRememberedForegroundChild(deps.state, { runId, mode: "single", cwd: singleCwd, sessionId: data.parentSessionId, index: 0, result, events: deps.dm.events, notify: true });
|
|
@@ -3199,7 +3597,7 @@ async function runSinglePath(data, deps) {
|
|
|
3199
3597
|
if (foregroundControl)
|
|
3200
3598
|
finishForegroundChild(foregroundControl, 0);
|
|
3201
3599
|
} finally {
|
|
3202
|
-
removeForegroundControlIfIdle(deps.state, runId);
|
|
3600
|
+
removeForegroundControlIfIdle(deps.state, runId, deps.trackRetainedNestedRoute);
|
|
3203
3601
|
}
|
|
3204
3602
|
}
|
|
3205
3603
|
}
|
|
@@ -3210,13 +3608,13 @@ async function runSinglePath(data, deps) {
|
|
|
3210
3608
|
toolTimeoutMs: params.toolTimeoutMs,
|
|
3211
3609
|
configToolTimeoutMs: data.configToolTimeoutMs,
|
|
3212
3610
|
toolBudget: effectiveToolBudget.toolBudget,
|
|
3611
|
+
usageBudget: data.usageBudget ?? data.inheritedUsageBudget,
|
|
3213
3612
|
capabilityCeiling: data.capabilityCeiling,
|
|
3214
3613
|
allowZeroToolBudget: data.allowZeroToolBudget && effectiveToolBudget.toolBudget === data.toolBudget
|
|
3215
3614
|
}));
|
|
3216
3615
|
r = launched.detached && detachedWorkflowChild ? await detachedWorkflowChild : launched;
|
|
3217
3616
|
} catch (error) {
|
|
3218
|
-
|
|
3219
|
-
cleanupWorktrees(worktreeSetup);
|
|
3617
|
+
await cleanupSingleWorktree();
|
|
3220
3618
|
throw error;
|
|
3221
3619
|
} finally {
|
|
3222
3620
|
if (!r?.detached) {
|
|
@@ -3231,7 +3629,7 @@ async function runSinglePath(data, deps) {
|
|
|
3231
3629
|
}
|
|
3232
3630
|
let worktreeHandoff;
|
|
3233
3631
|
if (worktreeSetup) {
|
|
3234
|
-
worktreeHandoff = r.detached ? { suffix: pendingHandoff ? formatParallelHandoffReference(pendingHandoff) : "", reference: pendingHandoff } : finalizeSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd, agent: params.agent, result: r, workflowKey: params.workflowKey, lane });
|
|
3632
|
+
worktreeHandoff = r.detached ? { suffix: pendingHandoff ? formatParallelHandoffReference(pendingHandoff) : "", reference: pendingHandoff } : await finalizeSingleWorktreeHandoff({ worktreeSetup, artifactsDir, runId, cwd: sourceCwd, agent: params.agent, result: r, workflowKey: params.workflowKey, lane });
|
|
3235
3633
|
}
|
|
3236
3634
|
if (r.progress)
|
|
3237
3635
|
allProgress.push(r.progress);
|
|
@@ -3269,7 +3667,7 @@ async function runSinglePath(data, deps) {
|
|
|
3269
3667
|
usageBudget: usageBudgetState(data.usageBudget, totalCost),
|
|
3270
3668
|
...worktreeHandoff?.reference ? { parallelHandoff: worktreeHandoff.reference } : {}
|
|
3271
3669
|
}));
|
|
3272
|
-
rememberForegroundRun(deps.state, { runId, mode: "single", cwd: singleCwd, sessionId: data.parentSessionId, results: details.results, params, effectiveOutput, effectiveOutputMode, extensionBindings: params.extensionBindings });
|
|
3670
|
+
rememberForegroundRun(deps.state, { modelResponseAliases, runId, mode: "single", cwd: singleCwd, sessionId: data.parentSessionId, results: details.results, params, effectiveOutput, effectiveOutputMode, extensionBindings: params.extensionBindings, requiredExtensions });
|
|
3273
3671
|
const suppressRoutineResultIntercom = shouldSuppressRoutineResultIntercom({ suppressRoutineResultIntercom: params.suppressRoutineResultIntercom, results: [r] });
|
|
3274
3672
|
if (!r.detached && !r.interrupted && !suppressRoutineResultIntercom) {
|
|
3275
3673
|
if (foregroundControl)
|
|
@@ -3340,6 +3738,7 @@ function duplicateSubagentCallResult(params) {
|
|
|
3340
3738
|
};
|
|
3341
3739
|
}
|
|
3342
3740
|
const workflowLaunchObservers = new WeakMap;
|
|
3741
|
+
const workflowOwnedUsageBudgets = new WeakMap;
|
|
3343
3742
|
const missionsMissingFromStore = new Set;
|
|
3344
3743
|
function recordMissionWorkflowChild(binding, workflowRunId, key, update) {
|
|
3345
3744
|
if (!binding || missionsMissingFromStore.has(binding.missionId))
|
|
@@ -3378,30 +3777,34 @@ export async function runMissionWorkflowChild(binding, workflowRunId, key, phase
|
|
|
3378
3777
|
throw error;
|
|
3379
3778
|
}
|
|
3380
3779
|
}
|
|
3381
|
-
export function bindMissionWorkflowChildAsyncLaunch(params, binding, asyncByDefault, asyncId = randomUUID()) {
|
|
3780
|
+
export function bindMissionWorkflowChildAsyncLaunch(params, binding, asyncByDefault, asyncId = randomUUID(), nestedRootRunId) {
|
|
3382
3781
|
const requestedAsync = params.async ?? asyncByDefault;
|
|
3383
3782
|
if (!binding || !requestedAsync || params.clarify === true)
|
|
3384
3783
|
return params;
|
|
3385
3784
|
const id = asyncId.trim();
|
|
3386
3785
|
if (!id || path.basename(id) !== id)
|
|
3387
3786
|
throw new Error("workflow child async id must be a single path segment");
|
|
3388
|
-
writeMissionAsyncBinding(path.join(DIRS.async, id), binding);
|
|
3787
|
+
writeMissionAsyncBinding(path.join(nestedRootRunId ? nestedRunScope(nestedRootRunId).asyncDirRoot : DIRS.async, id), binding);
|
|
3389
3788
|
return { ...params, workflowChildAsyncId: id };
|
|
3390
3789
|
}
|
|
3391
3790
|
function workflowChildResult(key, result, childParams = {}, resumeState, forcedTerminalOutcome) {
|
|
3791
|
+
const running = missionWorkflowChildStatus(result) === "running";
|
|
3392
3792
|
const receiptOutput = result.content.map((part) => part.type === "text" ? part.text : "").filter(Boolean).join(`
|
|
3393
3793
|
`);
|
|
3394
|
-
const output = result.details.results.length === 1 && result.details.results[0]?.finalOutput !== undefined ? result.details.results[0].finalOutput : receiptOutput;
|
|
3794
|
+
const output = running ? "" : result.details.results.length === 1 && result.details.results[0]?.finalOutput !== undefined ? result.details.results[0].finalOutput : receiptOutput;
|
|
3395
3795
|
const childError = result.details.results.map((child) => child.error).find((error) => Boolean(error));
|
|
3396
|
-
const
|
|
3796
|
+
const failureErrorBase = childError && receiptOutput ? receiptOutput.includes(childError) ? receiptOutput : `${childError}
|
|
3397
3797
|
|
|
3398
3798
|
${receiptOutput}` : childError || receiptOutput || output || "Child run failed.";
|
|
3799
|
+
const savedOutputEvidence = [...new Set(result.details.results.map((child) => child.savedOutputPath).filter((value) => Boolean(value)))].filter((savedOutputPath) => !failureErrorBase.includes(savedOutputPath)).map((savedOutputPath) => `Saved output: ${savedOutputPath}`);
|
|
3800
|
+
const failureError = [failureErrorBase, ...savedOutputEvidence].join(`
|
|
3801
|
+
`);
|
|
3399
3802
|
const detached = result.details.results.some((child) => child.detached);
|
|
3400
3803
|
const interrupted = result.details.results.some((child) => child.interrupted);
|
|
3401
3804
|
const stopped = result.details.results.some((child) => child.stopped);
|
|
3402
3805
|
const terminalOutcome = forcedTerminalOutcome ?? (result.details.results.some((child) => child.timedOut) ? { state: "partial", reason: "timeout" } : result.details.usageBudget?.exhausted || result.details.results.some((child) => child.turnBudgetExceeded || child.toolBudgetBlocked) ? { state: "partial", reason: "budget_exhausted" } : undefined);
|
|
3403
3806
|
const acceptanceRecovery = result.details.results.find((child) => child.acceptance?.recovery)?.acceptance?.recovery;
|
|
3404
|
-
const ok = result.isError !== true && !detached && !interrupted && !stopped && acceptanceRecovery === undefined;
|
|
3807
|
+
const ok = result.isError !== true && !running && !detached && !interrupted && !stopped && acceptanceRecovery === undefined;
|
|
3405
3808
|
const artifactPaths = new Set;
|
|
3406
3809
|
if (result.details.asyncDir)
|
|
3407
3810
|
artifactPaths.add(result.details.asyncDir);
|
|
@@ -3432,9 +3835,8 @@ ${receiptOutput}` : childError || receiptOutput || output || "Child run failed."
|
|
|
3432
3835
|
}
|
|
3433
3836
|
const requestedContext = childParams.context === "fresh" || childParams.context === "fork" ? childParams.context : undefined;
|
|
3434
3837
|
const resolvedContext = result.details.context ?? (resolvedContexts.length === 1 ? resolvedContexts[0] : resolvedContexts.length > 1 ? "mixed" : undefined);
|
|
3435
|
-
const resumeSourceRunId = typeof childParams.resume === "string" && childParams.resume.trim() ? childParams.resume.trim() : undefined;
|
|
3436
|
-
const continuationRunIds = [...new Set([resumeSourceRunId, runId].filter((value) => Boolean(value)))];
|
|
3437
3838
|
const outputReference = result.details.results.find((child) => child.savedOutputPath)?.savedOutputPath ?? result.details.results.find((child) => child.outputReference?.path)?.outputReference?.path;
|
|
3839
|
+
const outputArtifactPath = running ? undefined : result.details.parallelHandoff?.path ?? result.details.results.find((child) => child.artifactPaths?.outputPath)?.artifactPaths?.outputPath;
|
|
3438
3840
|
const outputPathMapping = typeof childParams.task === "string" ? outputPathMappingFromTask(childParams.task, outputReference) : undefined;
|
|
3439
3841
|
const externalResult = result.details.results.length === 1 && result.details.results[0]?.runner?.type === "external-cli" ? result.details.results[0] : undefined;
|
|
3440
3842
|
const externalStatus = result.details.asyncDir ? readStatus(result.details.asyncDir) : undefined;
|
|
@@ -3449,12 +3851,14 @@ ${receiptOutput}` : childError || receiptOutput || output || "Child run failed."
|
|
|
3449
3851
|
return {
|
|
3450
3852
|
key,
|
|
3451
3853
|
ok,
|
|
3854
|
+
...running ? { state: "running" } : {},
|
|
3855
|
+
...result.details.asyncDir ? { asyncDir: result.details.asyncDir } : {},
|
|
3452
3856
|
...lane ? { lane } : {},
|
|
3453
3857
|
...terminalOutcome ? { terminalOutcome } : {},
|
|
3454
3858
|
...resolvedAgents.length === 1 ? { agent: resolvedAgents[0] } : {},
|
|
3455
3859
|
...runId ? { runId } : {},
|
|
3456
3860
|
output,
|
|
3457
|
-
...!ok ? { error: failureError } : {},
|
|
3861
|
+
...!ok && !running ? { error: failureError } : {},
|
|
3458
3862
|
...detached ? { detached: true } : {},
|
|
3459
3863
|
...interrupted ? { interrupted: true } : {},
|
|
3460
3864
|
...stopped ? { stopped: true } : {},
|
|
@@ -3462,11 +3866,12 @@ ${receiptOutput}` : childError || receiptOutput || output || "Child run failed."
|
|
|
3462
3866
|
...requestedContext ? { requestedContext } : {},
|
|
3463
3867
|
...resolvedContext ? { resolvedContext } : {},
|
|
3464
3868
|
...outputReference ? { outputReference } : {},
|
|
3869
|
+
...outputArtifactPath ? { outputArtifactPath } : {},
|
|
3465
3870
|
...acceptanceRecovery ? { recovery: acceptanceRecovery } : {},
|
|
3466
3871
|
...outputPathMapping ? { outputPathMapping } : {},
|
|
3467
3872
|
...externalAdapter ? { externalAdapter } : {},
|
|
3468
3873
|
resumability,
|
|
3469
|
-
continuation: { runIds:
|
|
3874
|
+
continuation: { runIds: runId ? [runId] : [] },
|
|
3470
3875
|
artifactPaths: [...artifactPaths],
|
|
3471
3876
|
results: result.details.results
|
|
3472
3877
|
};
|
|
@@ -3482,10 +3887,23 @@ function workflowChildAccountingFields(child) {
|
|
|
3482
3887
|
...child.recovery ? { recovery: child.recovery } : {}
|
|
3483
3888
|
};
|
|
3484
3889
|
}
|
|
3890
|
+
function workflowRunningChildrenSummary(children) {
|
|
3891
|
+
const running = children.filter((child) => child.state === "running");
|
|
3892
|
+
return running.length ? `${running.length} child ${running.length === 1 ? "run remains" : "runs remain"} running or uncollected: ${running.map((child) => `${child.key}=${child.runId}`).join(", ")}. These launch receipts contain no final child results.` : "";
|
|
3893
|
+
}
|
|
3894
|
+
function workflowResultChildren(children, status, includeFailureFields) {
|
|
3895
|
+
return children.map((child) => {
|
|
3896
|
+
const sessionName = status.steps?.find((step) => step.workflowKey === child.key)?.sessionName;
|
|
3897
|
+
return { workflowKey: child.key, ...child.agent ? { agent: child.agent } : {}, ...child.runId ? { runId: child.runId } : {}, ...sessionName ? { sessionName } : {}, ...workflowChildAccountingFields(child), output: child.output, outputState: child.output.trim() || child.structuredOutput !== undefined ? "present" : "absent", structuredOutput: child.structuredOutput, ...child.state === "running" ? { state: "running" } : { success: child.ok }, ...child.asyncDir ? { asyncDir: child.asyncDir } : {}, ...child.outputReference ? { outputReference: child.outputReference } : {}, ...includeFailureFields && child.terminalOutcome ? { terminalOutcome: child.terminalOutcome } : {}, ...child.outputPathMapping ? { outputPathMapping: child.outputPathMapping } : {}, ...child.stopped ? { stopped: true } : {}, ...child.interrupted ? { interrupted: true } : {}, ...includeFailureFields && child.detached && status.state !== "complete" ? { detached: true } : {}, ...child.outputArtifactPath || child.outputReference ? { artifactPaths: { outputPath: child.outputArtifactPath ?? child.outputReference } } : {} };
|
|
3898
|
+
});
|
|
3899
|
+
}
|
|
3485
3900
|
function workflowOutputPathMappingSummary(children) {
|
|
3486
3901
|
const mappings = children.flatMap((child) => child.outputPathMapping ? [`'${child.key}': requested ${child.outputPathMapping.requestedPath} -> saved ${child.outputPathMapping.savedPath}`] : []);
|
|
3487
3902
|
return mappings.length > 0 ? ` Output path mappings: ${mappings.join("; ")}.` : "";
|
|
3488
3903
|
}
|
|
3904
|
+
function workflowDetailsResults(children) {
|
|
3905
|
+
return children.flatMap((child) => (child.results ?? []).map((result) => result.workflowKey ? result : { ...result, workflowKey: child.key }));
|
|
3906
|
+
}
|
|
3489
3907
|
function workflowSteerReceipt(key, result) {
|
|
3490
3908
|
const steering = result.details.steering;
|
|
3491
3909
|
const error = result.content.map((part) => part.type === "text" ? part.text : "").filter(Boolean).join(`
|
|
@@ -3502,6 +3920,7 @@ function workflowSteerReceipt(key, result) {
|
|
|
3502
3920
|
...state === "failed" && error ? { error } : {}
|
|
3503
3921
|
};
|
|
3504
3922
|
}
|
|
3923
|
+
const CHILD_SESSION_NOT_RUNNING_YET = "Child session is not running yet.";
|
|
3505
3924
|
const MAX_WORKFLOW_RESUME_HINT_BYTES = 1024;
|
|
3506
3925
|
const MAX_WORKFLOW_CHILD_RUN_ID_BYTES = 256;
|
|
3507
3926
|
const WORKFLOW_RESUME_HINT_PARENT_STATES = new Set(["complete", "failed", "partial"]);
|
|
@@ -3553,7 +3972,29 @@ function missingWorkflowReceiptResumeHint(reference, state) {
|
|
|
3553
3972
|
return;
|
|
3554
3973
|
}
|
|
3555
3974
|
}
|
|
3556
|
-
function
|
|
3975
|
+
function resolveWorkflowResume(reference, deps, parentSessionFile, index) {
|
|
3976
|
+
const state = deps.state;
|
|
3977
|
+
if (typeof reference === "string") {
|
|
3978
|
+
const target = resolveRequestedResumeTarget({ id: reference.trim(), ...index !== undefined ? { index } : {} }, deps, parentSessionFile);
|
|
3979
|
+
if (target.kind !== "revive")
|
|
3980
|
+
return reference.trim();
|
|
3981
|
+
const runId = target.runId;
|
|
3982
|
+
const status = target.source === "async" && target.asyncDir ? readStatus(target.asyncDir) : undefined;
|
|
3983
|
+
if (status?.runId === runId && status.parentWorkflowRunId && status.workflowKey) {
|
|
3984
|
+
const receiptPath = workflowReceiptPath(DIRS.async, status.parentWorkflowRunId);
|
|
3985
|
+
try {
|
|
3986
|
+
fs.statSync(receiptPath);
|
|
3987
|
+
} catch (error) {
|
|
3988
|
+
if (error.code === "ENOENT")
|
|
3989
|
+
return { runId, runIds: [runId] };
|
|
3990
|
+
throw error;
|
|
3991
|
+
}
|
|
3992
|
+
const entry = readWorkflowReceipt(DIRS.async, status.parentWorkflowRunId).entries[status.workflowKey];
|
|
3993
|
+
if (entry?.latestRunId === runId)
|
|
3994
|
+
return { runId, runIds: entry.continuation.runIds };
|
|
3995
|
+
}
|
|
3996
|
+
return { runId, runIds: [runId] };
|
|
3997
|
+
}
|
|
3557
3998
|
try {
|
|
3558
3999
|
const entry = resolveWorkflowReceiptResumeEntry({
|
|
3559
4000
|
reference,
|
|
@@ -3564,10 +4005,7 @@ function resolveKeyedWorkflowResume(reference, state) {
|
|
|
3564
4005
|
throw new Error(`Workflow receipt child '${reference.key}' latest run '${runId}' is still running.`);
|
|
3565
4006
|
}
|
|
3566
4007
|
});
|
|
3567
|
-
|
|
3568
|
-
if (!runId)
|
|
3569
|
-
throw new Error(`Workflow receipt child '${reference.key}' has no retained run id.`);
|
|
3570
|
-
return { runId, runIds: entry.continuation.runIds };
|
|
4008
|
+
return { runId: entry.latestRunId, runIds: entry.continuation.runIds };
|
|
3571
4009
|
} catch (error) {
|
|
3572
4010
|
const workflowRunId = reference.workflowRunId.trim();
|
|
3573
4011
|
if (isMissingWorkflowReceiptDiagnostic(error, workflowRunId)) {
|
|
@@ -3578,8 +4016,8 @@ function resolveKeyedWorkflowResume(reference, state) {
|
|
|
3578
4016
|
throw error;
|
|
3579
4017
|
}
|
|
3580
4018
|
}
|
|
3581
|
-
function terminalWorkflowReceipt(workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps) {
|
|
3582
|
-
return buildWorkflowReceipt({ workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps });
|
|
4019
|
+
function terminalWorkflowReceipt(workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps, resource, argsDigest) {
|
|
4020
|
+
return buildWorkflowReceipt({ workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps, resource, ...argsDigest ? { argsDigest } : {} });
|
|
3583
4021
|
}
|
|
3584
4022
|
function workflowFailureTerminalOutcome(error, _children, usageBudget) {
|
|
3585
4023
|
if (usageBudget?.exhausted)
|
|
@@ -3592,24 +4030,23 @@ function workflowFailureMessage(error, workflowRunId, children) {
|
|
|
3592
4030
|
if (children.length === 0 && text.includes(validationPrefix)) {
|
|
3593
4031
|
return `Workflow '${workflowRunId}' validation failed before child launch; no children launched.${text.slice(text.indexOf(validationPrefix) + validationPrefix.length)}`;
|
|
3594
4032
|
}
|
|
3595
|
-
return text;
|
|
4033
|
+
return [text, workflowRunningChildrenSummary(children)].filter(Boolean).join(" ");
|
|
3596
4034
|
}
|
|
3597
4035
|
export async function steerWorkflowChildByKey(input) {
|
|
3598
4036
|
const asyncDirRoot = input.asyncDirRoot ?? DIRS.async;
|
|
3599
4037
|
const ackTimeoutMs = input.options.ackTimeoutMs ?? 3000;
|
|
3600
4038
|
const deadline = Date.now() + ackTimeoutMs;
|
|
3601
4039
|
while (true) {
|
|
3602
|
-
const control = [...input.state.foregroundControls.values()].find((candidate) => candidate.parentWorkflowRunId === input.workflowRunId && candidate.workflowKey === input.key &&
|
|
4040
|
+
const control = [...input.state.foregroundControls.values()].find((candidate) => candidate.parentWorkflowRunId === input.workflowRunId && candidate.workflowKey === input.key && (candidate.activeChildren?.size ?? 0) > 0);
|
|
3603
4041
|
if (control) {
|
|
3604
4042
|
const result = await steerWorkflowForegroundTarget({
|
|
3605
4043
|
target: { control, workflowRunId: input.workflowRunId, sourceRunId: control.runId },
|
|
3606
4044
|
message: input.message,
|
|
3607
4045
|
mode: input.options.mode,
|
|
3608
|
-
index: input.options.index
|
|
3609
|
-
ackTimeoutMs: Math.max(1, deadline - Date.now()),
|
|
3610
|
-
signal: input.signal
|
|
4046
|
+
index: input.options.index
|
|
3611
4047
|
});
|
|
3612
|
-
|
|
4048
|
+
if (!result.details.steering?.targets.some((target) => target.reason === CHILD_SESSION_NOT_RUNNING_YET) || Date.now() >= deadline)
|
|
4049
|
+
return workflowSteerReceipt(input.key, result);
|
|
3613
4050
|
}
|
|
3614
4051
|
const workflowStatus = readStatus(path.join(asyncDirRoot, input.workflowRunId));
|
|
3615
4052
|
const step = workflowStatus?.steps?.find((candidate) => candidate.workflowKey === input.key);
|
|
@@ -3649,7 +4086,33 @@ export async function steerWorkflowChildByKey(input) {
|
|
|
3649
4086
|
await new Promise((resolve) => setTimeout(resolve, Math.min(10, Math.max(1, deadline - Date.now()))));
|
|
3650
4087
|
}
|
|
3651
4088
|
}
|
|
4089
|
+
export async function preflightWorkflowWorktrees(input) {
|
|
4090
|
+
const sources = new Map;
|
|
4091
|
+
for (const { key, params } of input.calls) {
|
|
4092
|
+
if (params.resume !== undefined)
|
|
4093
|
+
continue;
|
|
4094
|
+
const effective = prepareWorkflowLaunchParams(input.workflowDefaults, params, "preflight", key);
|
|
4095
|
+
if ((effective.worktree ?? input.defaultWorktree) !== true)
|
|
4096
|
+
continue;
|
|
4097
|
+
const cwd = resolveRequestedCwd(input.ctxCwd, effective.cwd);
|
|
4098
|
+
const keys = sources.get(cwd) ?? [];
|
|
4099
|
+
keys.push(key);
|
|
4100
|
+
sources.set(cwd, keys);
|
|
4101
|
+
}
|
|
4102
|
+
for (const [cwd, keys] of sources) {
|
|
4103
|
+
try {
|
|
4104
|
+
await preflightWorktreeSource(cwd, { signal: input.signal, deadlineAt: input.deadlineAt });
|
|
4105
|
+
} catch (error) {
|
|
4106
|
+
throw new Error(`Worktree admission failed for ${keys.map((key) => `'${key}'`).join(", ")} at ${cwd}: ${error instanceof Error ? error.message : String(error)} Select the correct cwd or arrange an operator-approved commit/stash.`, { cause: error });
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
4109
|
+
input.signal.throwIfAborted();
|
|
4110
|
+
}
|
|
3652
4111
|
export function prepareWorkflowLaunchParams(workflowDefaults, childParams, parentWorkflowRunId, workflowKey, options = {}) {
|
|
4112
|
+
const { globalConcurrencyLimit: _globalConcurrencyLimit, maxSubagentSpawnsPerRun: _maxSubagentSpawnsPerRun, ...workflowDefaultsWithoutCapacity } = workflowDefaults;
|
|
4113
|
+
const { globalConcurrencyLimit: _childGlobalConcurrencyLimit, maxSubagentSpawnsPerRun: _childMaxSubagentSpawnsPerRun, ...childParamsWithoutCapacity } = childParams;
|
|
4114
|
+
workflowDefaults = workflowDefaultsWithoutCapacity;
|
|
4115
|
+
childParams = childParamsWithoutCapacity;
|
|
3653
4116
|
const capabilityCeiling = intersectSubagentCapabilityCeilings(workflowDefaults.capabilityCeiling, options.capabilityCeiling);
|
|
3654
4117
|
const lane = normalizeWorkflowLaneMetadata(Object.hasOwn(childParams, "lane") ? childParams.lane : workflowDefaults.lane, `workflow child '${workflowKey}'.lane`);
|
|
3655
4118
|
assertWorkflowLaneKey(lane, workflowKey, `workflow child '${workflowKey}'.lane`);
|
|
@@ -3665,11 +4128,12 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
|
|
|
3665
4128
|
const toolBudget = childParams.toolBudget ?? workflowDefaults.toolBudget;
|
|
3666
4129
|
const intercomBridge = childParams.intercomBridge ?? workflowDefaults.intercomBridge;
|
|
3667
4130
|
const worktree = childParams.worktree ?? workflowDefaults.worktree;
|
|
4131
|
+
const baseRef = Object.hasOwn(childParams, "baseRef") ? childParams.baseRef : undefined;
|
|
3668
4132
|
const outputSchema = Object.hasOwn(childParams, "outputSchema") ? childParams.outputSchema : workflowDefaults.outputSchema;
|
|
3669
|
-
if (outputSchema !== undefined)
|
|
4133
|
+
if (outputSchema !== undefined && outputSchema !== false)
|
|
3670
4134
|
assertJsonSchemaObject(outputSchema, "outputSchema");
|
|
3671
4135
|
const agentContract = Object.hasOwn(childParams, "agentContract") ? childParams.agentContract : workflowDefaults.agentContract;
|
|
3672
|
-
if (agentContract !== undefined && !
|
|
4136
|
+
if (agentContract !== undefined && !isAgentContract(agentContract))
|
|
3673
4137
|
throw new Error("agentContract must be { version: 1 }.");
|
|
3674
4138
|
const acceptance = Object.hasOwn(childParams, "acceptance") ? childParams.acceptance : workflowDefaults.acceptance;
|
|
3675
4139
|
const output = Object.hasOwn(childParams, "output") ? childParams.output : workflowDefaults.output;
|
|
@@ -3678,6 +4142,7 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
|
|
|
3678
4142
|
const outputMode = Object.hasOwn(childParams, "outputMode") ? childParams.outputMode : workflowDefaults.outputMode;
|
|
3679
4143
|
if (outputMode !== undefined && outputMode !== "inline" && outputMode !== "file-only")
|
|
3680
4144
|
throw new Error("outputMode must be 'inline' or 'file-only'.");
|
|
4145
|
+
const control = mergeWorkflowControlOverrides(workflowDefaults.control, childParams.control);
|
|
3681
4146
|
return {
|
|
3682
4147
|
action: "resume",
|
|
3683
4148
|
id: childParams.resume.trim(),
|
|
@@ -3685,8 +4150,10 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
|
|
|
3685
4150
|
message: typeof childParams.task === "string" ? childParams.task.trim() : "",
|
|
3686
4151
|
workflowParentRunId: parentWorkflowRunId,
|
|
3687
4152
|
workflowKey,
|
|
4153
|
+
...options.outputClaimPath ? { workflowOutputClaimPath: options.outputClaimPath } : {},
|
|
3688
4154
|
...lane ? { lane } : {},
|
|
3689
4155
|
...worktree !== undefined ? { worktree } : {},
|
|
4156
|
+
...baseRef !== undefined ? { baseRef } : {},
|
|
3690
4157
|
...outputSchema !== undefined ? { outputSchema } : {},
|
|
3691
4158
|
...agentContract !== undefined ? { agentContract } : {},
|
|
3692
4159
|
...acceptance !== undefined ? { acceptance } : {},
|
|
@@ -3696,15 +4163,19 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
|
|
|
3696
4163
|
...options.missionDetached ? { mission: false } : {},
|
|
3697
4164
|
...timeoutMs !== undefined ? { timeoutMs } : {},
|
|
3698
4165
|
...toolBudget !== undefined ? { toolBudget } : {},
|
|
4166
|
+
...control !== undefined ? { control } : {},
|
|
3699
4167
|
...intercomBridge !== undefined ? { intercomBridge } : {},
|
|
3700
4168
|
...capabilityCeiling ? { capabilityCeiling } : {}
|
|
3701
4169
|
};
|
|
3702
4170
|
}
|
|
4171
|
+
const control = mergeWorkflowControlOverrides(workflowDefaults.control, childParams.control);
|
|
4172
|
+
const asyncOmitted = childParams.async === undefined && workflowDefaults.async === undefined;
|
|
3703
4173
|
const launchParams = {
|
|
3704
4174
|
...workflowDefaults,
|
|
3705
|
-
|
|
4175
|
+
...options.externalAsyncRequired === true && asyncOmitted ? { async: true } : {},
|
|
3706
4176
|
...childParams,
|
|
3707
|
-
...
|
|
4177
|
+
...control !== undefined ? { control } : {},
|
|
4178
|
+
...asyncOmitted ? { workflowAwaitAsync: true } : {},
|
|
3708
4179
|
...options.missionDetached ? { mission: false } : {},
|
|
3709
4180
|
workflowParentRunId: parentWorkflowRunId,
|
|
3710
4181
|
workflowKey,
|
|
@@ -3723,6 +4194,18 @@ export function prepareWorkflowLaunchParams(workflowDefaults, childParams, paren
|
|
|
3723
4194
|
throw new Error(normalizedGate.error);
|
|
3724
4195
|
return normalizedGate.params;
|
|
3725
4196
|
}
|
|
4197
|
+
function mergeWorkflowControlOverrides(workflowControl, childControl) {
|
|
4198
|
+
if (childControl === undefined)
|
|
4199
|
+
return workflowControl;
|
|
4200
|
+
if (workflowControl === undefined)
|
|
4201
|
+
return childControl;
|
|
4202
|
+
return { ...workflowControl, ...childControl };
|
|
4203
|
+
}
|
|
4204
|
+
export function resolveRevivalControlConfig(input) {
|
|
4205
|
+
if (input.requestedControl === undefined)
|
|
4206
|
+
return input.recoveryControlConfig ?? resolveControlConfig(input.globalConfig, undefined);
|
|
4207
|
+
return resolveControlConfig(input.recoveryControlConfig ?? input.globalConfig, input.requestedControl);
|
|
4208
|
+
}
|
|
3726
4209
|
function normalizeGateParams(params) {
|
|
3727
4210
|
if (params.gate !== undefined && params.action === "resume") {
|
|
3728
4211
|
return { ok: false, error: "gate is not supported with action='resume'; resume uses the retained child contract." };
|
|
@@ -3735,6 +4218,16 @@ function normalizeGateParams(params) {
|
|
|
3735
4218
|
const { gate: _gate, ...rest } = params;
|
|
3736
4219
|
return { ok: true, params: { ...rest, ...normalized.acceptance !== undefined ? { acceptance: normalized.acceptance } : {} } };
|
|
3737
4220
|
}
|
|
4221
|
+
function describeTypedVerifyOutputSchemaConflict(effective, requested) {
|
|
4222
|
+
if (!acceptanceHasTypedVerify(effective.acceptance))
|
|
4223
|
+
return;
|
|
4224
|
+
if (effective.outputSchema === undefined || effective.outputSchema === false)
|
|
4225
|
+
return;
|
|
4226
|
+
const agent = effective.agent ?? "?";
|
|
4227
|
+
const schemaSource = requested.outputSchema !== undefined && requested.outputSchema !== false ? "outputSchema" : `agent '${agent}' outputSchema`;
|
|
4228
|
+
const verifySource = requested.gate !== undefined ? "gate.output" : requested.acceptance !== undefined ? "acceptance.verify" : `agent '${agent}' defaultAcceptance`;
|
|
4229
|
+
return `${verifySource}: ${TYPED_VERIFY_OUTPUT_SCHEMA_CONFLICT.replace("with outputSchema", `with ${schemaSource}`)}`;
|
|
4230
|
+
}
|
|
3738
4231
|
function formatWorkflowValue(value) {
|
|
3739
4232
|
if (value === undefined)
|
|
3740
4233
|
return "(undefined)";
|
|
@@ -3842,9 +4335,7 @@ function applyWorkflowLaneTrace(graph, trace) {
|
|
|
3842
4335
|
else
|
|
3843
4336
|
delete graph.currentNodeId;
|
|
3844
4337
|
}
|
|
3845
|
-
function
|
|
3846
|
-
if (chatProgress.mode !== "live-card")
|
|
3847
|
-
return;
|
|
4338
|
+
function workflowProgressUpdate(runId, chatProgress, workflow, workflowChildren, preflight) {
|
|
3848
4339
|
return {
|
|
3849
4340
|
content: [{ type: "text", text: "Workflow running." }],
|
|
3850
4341
|
details: { mode: "workflow", runId, results: [], workflow, ...preflight ? { preflight } : {}, ...workflowChildren ? { workflowChildren } : {}, chatProgress }
|
|
@@ -3885,14 +4376,19 @@ export function createSubagentExecutor(deps) {
|
|
|
3885
4376
|
const delegatedThinkingOverrides = new WeakMap;
|
|
3886
4377
|
const delegatedZeroToolBudgets = new WeakSet;
|
|
3887
4378
|
const delegatedExecutions = new WeakSet;
|
|
4379
|
+
const publicExecutions = new WeakSet;
|
|
4380
|
+
const workflowResourcePermits = new WeakMap;
|
|
3888
4381
|
const workflowPermitContexts = new WeakMap;
|
|
3889
4382
|
const warnedArtifactPackageDirs = new Set;
|
|
3890
4383
|
const scheduledOwnerExecutors = new Map;
|
|
3891
4384
|
const execute = async (_id, params, signal, onUpdate, ctx, preserveActiveSession = false, parentModelOverride) => {
|
|
3892
4385
|
const workflowLaunchObserver = workflowLaunchObservers.get(params);
|
|
4386
|
+
const inheritedUsageBudget = workflowOwnedUsageBudgets.get(params);
|
|
3893
4387
|
const delegatedThinkingOverride = delegatedThinkingOverrides.get(params);
|
|
3894
4388
|
const allowZeroToolBudget = delegatedZeroToolBudgets.has(params);
|
|
3895
4389
|
const delegatedExecution = delegatedExecutions.has(params);
|
|
4390
|
+
const publicExecution = publicExecutions.has(params);
|
|
4391
|
+
const workflowResourcePermit = workflowResourcePermits.get(params);
|
|
3896
4392
|
const workflowPermitContext = workflowPermitContexts.get(params);
|
|
3897
4393
|
const delegatedWorkflowPermit = workflowPermitContext && "root" in workflowPermitContext ? workflowPermitContext.root : undefined;
|
|
3898
4394
|
const workflowChildPermitLaunch = workflowPermitContext && "child" in workflowPermitContext ? workflowPermitContext.child : undefined;
|
|
@@ -3905,6 +4401,9 @@ export function createSubagentExecutor(deps) {
|
|
|
3905
4401
|
if (!normalizedGate.ok)
|
|
3906
4402
|
return buildRequestedModeError(params, normalizedGate.error);
|
|
3907
4403
|
let requestParams = normalizedGate.params;
|
|
4404
|
+
const capacityOverrideError = validateWorkflowCapacityOverrides(requestParams);
|
|
4405
|
+
if (capacityOverrideError)
|
|
4406
|
+
return buildRequestedModeError(requestParams, capacityOverrideError);
|
|
3908
4407
|
let workflowPreflight;
|
|
3909
4408
|
try {
|
|
3910
4409
|
if (requestParams.preflight !== undefined && requestParams.workflowScript === undefined && requestParams.workflowScriptPath === undefined) {
|
|
@@ -3916,7 +4415,9 @@ export function createSubagentExecutor(deps) {
|
|
|
3916
4415
|
} catch (error) {
|
|
3917
4416
|
const message = error instanceof Error ? error.message : String(error);
|
|
3918
4417
|
if (requestParams.action?.trim() === "validate") {
|
|
3919
|
-
const validation = validateWorkflowScript(requestParams.workflowScript ?? ""
|
|
4418
|
+
const validation = validateWorkflowScript(requestParams.workflowScript ?? "", {
|
|
4419
|
+
maxSubagentSpawnsPerRun: requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun)
|
|
4420
|
+
});
|
|
3920
4421
|
const invalidValidation = { ...validation, ok: false, errors: [...validation.errors, { message }] };
|
|
3921
4422
|
return {
|
|
3922
4423
|
content: [{ type: "text", text: JSON.stringify(invalidValidation) }],
|
|
@@ -3927,20 +4428,44 @@ export function createSubagentExecutor(deps) {
|
|
|
3927
4428
|
return buildRequestedModeError(requestParams, message);
|
|
3928
4429
|
}
|
|
3929
4430
|
if (requestParams.action?.trim() === "validate") {
|
|
3930
|
-
const validation = validateWorkflowScript(requestParams.workflowScript ?? ""
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
...validation.ok ? {} : { isError: true },
|
|
3935
|
-
details: { mode: "management", results: [] }
|
|
3936
|
-
};
|
|
4431
|
+
const validation = validateWorkflowScript(requestParams.workflowScript ?? "", {
|
|
4432
|
+
maxSubagentSpawnsPerRun: requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun)
|
|
4433
|
+
});
|
|
4434
|
+
return buildWorkflowValidationResult(validation, "management", workflowPreflight);
|
|
3937
4435
|
}
|
|
3938
4436
|
const normalizedAction = typeof requestParams.action === "string" ? requestParams.action.trim() : requestParams.action;
|
|
3939
4437
|
if (normalizedAction === "resume" && requestParams.extensionBindings !== undefined)
|
|
3940
4438
|
return buildRequestedModeError(requestParams, "extensionBindings is not supported with action='resume'; resume uses the original retained child binding.");
|
|
4439
|
+
let workflowResource;
|
|
4440
|
+
if (workflowResourcePermit) {
|
|
4441
|
+
if (typeof requestParams.workflowScript !== "string")
|
|
4442
|
+
return buildRequestedModeError(requestParams, "Resolved workflow resource is missing its workflow script.");
|
|
4443
|
+
const consumed = consumeWorkflowResourcePermit(workflowResourcePermit, requestParams.workflowScript);
|
|
4444
|
+
if (typeof consumed === "string")
|
|
4445
|
+
return buildRequestedModeError(requestParams, consumed);
|
|
4446
|
+
workflowResource = { permit: workflowResourcePermit, ...consumed };
|
|
4447
|
+
}
|
|
3941
4448
|
if (requestParams.workflowScript !== undefined && normalizedAction === undefined) {
|
|
4449
|
+
const workflowArgsEvidence = requestParams.args === undefined ? undefined : { args: requestParams.args, argsDigest: stableJsonDigest(requestParams.args) };
|
|
4450
|
+
const workflowArgs = workflowArgsEvidence?.args;
|
|
4451
|
+
const workflowArgsDigest = workflowArgsEvidence?.argsDigest;
|
|
4452
|
+
const workflowValidation = validateWorkflowScript(requestParams.workflowScript, {
|
|
4453
|
+
maxSubagentSpawnsPerRun: requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun)
|
|
4454
|
+
});
|
|
4455
|
+
if (!workflowValidation.ok && publicExecution)
|
|
4456
|
+
return buildWorkflowValidationResult(workflowValidation, "workflow", workflowPreflight);
|
|
4457
|
+
const spawnBudgetErrors = workflowValidation.errors.filter((error) => error.kind === "spawn-budget");
|
|
4458
|
+
if (spawnBudgetErrors.length > 0) {
|
|
4459
|
+
return buildRequestedModeError(requestParams, `Workflow '${_id}' validation failed before child launch; no children launched. ${spawnBudgetErrors.map((error) => error.message).join(" ")}`);
|
|
4460
|
+
}
|
|
4461
|
+
for (const warning of workflowValidation.warnings ?? [])
|
|
4462
|
+
console.warn(`[dm-subagents] ${warning.message}`);
|
|
4463
|
+
const acceptanceErrors = validateAcceptanceInput(requestParams.acceptance);
|
|
4464
|
+
if (acceptanceErrors.length > 0)
|
|
4465
|
+
return buildRequestedModeError(requestParams, acceptanceErrors.join(" "));
|
|
4466
|
+
const foregroundWorkflowRunId = encodeIndexSegment(_id);
|
|
3942
4467
|
if (delegatedWorkflowPermit) {
|
|
3943
|
-
const permitError = validateWorkflowChildPermitRoot(delegatedWorkflowPermit,
|
|
4468
|
+
const permitError = validateWorkflowChildPermitRoot(delegatedWorkflowPermit, foregroundWorkflowRunId);
|
|
3944
4469
|
if (permitError)
|
|
3945
4470
|
return buildRequestedModeError(requestParams, permitError);
|
|
3946
4471
|
if (requestParams.async !== false)
|
|
@@ -3988,9 +4513,9 @@ export function createSubagentExecutor(deps) {
|
|
|
3988
4513
|
const scriptFirstLine = requestParams.workflowScript.split(/\r?\n/).map((line) => line.trim()).find(Boolean) || "Workflow";
|
|
3989
4514
|
const boundedScriptPreview = scriptFirstLine.length > 100 ? `${scriptFirstLine.slice(0, 97)}...` : scriptFirstLine;
|
|
3990
4515
|
const derivedObjective = previewAgent ? `Workflow: ${previewAgent}` : boundedScriptPreview;
|
|
3991
|
-
const workflowDepth = checkSubagentDepth(deps.config.maxSubagentDepth).depth;
|
|
4516
|
+
const workflowDepth = checkSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime).depth;
|
|
3992
4517
|
const asyncWorkflow = requestParams.async !== false;
|
|
3993
|
-
const topLevelAsyncWorkflow = asyncWorkflow && workflowDepth === 0 && !
|
|
4518
|
+
const topLevelAsyncWorkflow = asyncWorkflow && workflowDepth === 0 && !inheritedNestedRoute(deps) && !requestParams.workflowParentRunId;
|
|
3994
4519
|
const workflowRunId = asyncWorkflow ? randomUUID() : undefined;
|
|
3995
4520
|
let workflowCapacity;
|
|
3996
4521
|
if (workflowRunId && topLevelAsyncWorkflow) {
|
|
@@ -4013,7 +4538,7 @@ export function createSubagentExecutor(deps) {
|
|
|
4013
4538
|
}
|
|
4014
4539
|
let workflowFanoutBudget;
|
|
4015
4540
|
try {
|
|
4016
|
-
workflowFanoutBudget = requestParams.runFanoutBudget ??
|
|
4541
|
+
workflowFanoutBudget = requestParams.runFanoutBudget ?? inheritedRunFanoutBudget(deps) ?? createRunFanoutBudget(_id, requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun));
|
|
4017
4542
|
} catch (error) {
|
|
4018
4543
|
workflowCapacity?.rollback();
|
|
4019
4544
|
return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "workflow", results: [] } };
|
|
@@ -4087,9 +4612,10 @@ export function createSubagentExecutor(deps) {
|
|
|
4087
4612
|
...workflowSessionRoot ? { sessionRoot: workflowSessionRoot } : {},
|
|
4088
4613
|
...requestParams.scheduleOrigin ? { scheduleOrigin: requestParams.scheduleOrigin } : {},
|
|
4089
4614
|
pid: process.pid,
|
|
4615
|
+
...workflowCapabilityCeiling ? { admissionCapabilityCeiling: workflowCapabilityCeiling } : {},
|
|
4090
4616
|
steps: [],
|
|
4091
4617
|
...workflowPreflight ? { preflight: workflowPreflight } : {},
|
|
4092
|
-
workflow: { trace: [], emits: [], console: [] },
|
|
4618
|
+
workflow: { trace: [], emits: [], console: [], ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {} },
|
|
4093
4619
|
workflowChildren: workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState: "running", inventoryComplete: false }),
|
|
4094
4620
|
runFanoutBudget: getRunFanoutBudgetSnapshot(workflowFanoutBudget)
|
|
4095
4621
|
};
|
|
@@ -4109,22 +4635,63 @@ export function createSubagentExecutor(deps) {
|
|
|
4109
4635
|
},
|
|
4110
4636
|
onError: (error, filePath) => console.error(`Failed to update async workflow index '${filePath}':`, error)
|
|
4111
4637
|
});
|
|
4112
|
-
const queueActiveRunIndex = () => {
|
|
4113
|
-
const state =
|
|
4638
|
+
const queueActiveRunIndex = (snapshot = status) => {
|
|
4639
|
+
const state = snapshot.state;
|
|
4114
4640
|
if (indexedState === state && indexPersistence.pendingCount() === 0)
|
|
4115
4641
|
return;
|
|
4116
|
-
indexPersistence.write(asyncDir, { state, toolCallId:
|
|
4642
|
+
indexPersistence.write(asyncDir, { state, toolCallId: snapshot.toolCallId }, (_filePath, payload) => {
|
|
4117
4643
|
const indexPayload = payload;
|
|
4118
4644
|
updateActiveRunIndex(asyncDir, indexPayload.state, indexPayload.toolCallId, { retryCapacityErrors: true });
|
|
4119
4645
|
});
|
|
4120
4646
|
};
|
|
4647
|
+
let pendingResultPublication;
|
|
4648
|
+
let settleResultPublication;
|
|
4649
|
+
let resultWriteFailureWakeDelivered = false;
|
|
4650
|
+
const reportResultWriteFailure = (error) => {
|
|
4651
|
+
const message = `Failed to write async workflow result ${resultPath}: ${error instanceof Error ? error.message : String(error)}`;
|
|
4652
|
+
console.error(message, error);
|
|
4653
|
+
try {
|
|
4654
|
+
if (currentSessionId && fallbackResultPayloadPathForSessionRun(path.dirname(resultPath), currentSessionId, workflowRunId))
|
|
4655
|
+
return true;
|
|
4656
|
+
} catch (pendingError) {
|
|
4657
|
+
console.error(`Failed to verify pending async workflow result '${workflowRunId}':`, pendingError);
|
|
4658
|
+
}
|
|
4659
|
+
appendWorkflowEvent({ type: "subagent.workflow.result_write_failed", error: message });
|
|
4660
|
+
if (resultWriteFailureWakeDelivered)
|
|
4661
|
+
return false;
|
|
4662
|
+
if (deps.state.currentSessionId !== currentSessionId || deps.state.completionOwnerId !== completionOwnerId)
|
|
4663
|
+
return false;
|
|
4664
|
+
try {
|
|
4665
|
+
deps.dm.sendMessage({
|
|
4666
|
+
customType: "subagent-workflow-result-write-failed",
|
|
4667
|
+
content: message,
|
|
4668
|
+
display: true
|
|
4669
|
+
}, { triggerTurn: true });
|
|
4670
|
+
resultWriteFailureWakeDelivered = true;
|
|
4671
|
+
} catch (sendError) {
|
|
4672
|
+
console.error(`Failed to send workflow result write failure notification for '${workflowRunId}':`, sendError);
|
|
4673
|
+
}
|
|
4674
|
+
deps.refreshResultDelivery?.();
|
|
4675
|
+
return false;
|
|
4676
|
+
};
|
|
4677
|
+
const pendingWorkflowChildAnnouncements = new Map;
|
|
4678
|
+
let announcePersistedWorkflowChildren = () => {};
|
|
4121
4679
|
const runPersistence = createCapacityResilientJsonWriter({
|
|
4122
4680
|
keepAlive: true,
|
|
4123
|
-
onSuccess: (filePath) => {
|
|
4124
|
-
if (filePath === statusPath)
|
|
4125
|
-
|
|
4681
|
+
onSuccess: (filePath, payload) => {
|
|
4682
|
+
if (filePath === statusPath) {
|
|
4683
|
+
announcePersistedWorkflowChildren();
|
|
4684
|
+
queueActiveRunIndex(payload);
|
|
4685
|
+
}
|
|
4686
|
+
if (filePath === resultPath)
|
|
4687
|
+
settleResultPublication?.(true);
|
|
4688
|
+
},
|
|
4689
|
+
onError: (error, filePath) => {
|
|
4690
|
+
if (filePath === resultPath)
|
|
4691
|
+
settleResultPublication?.(reportResultWriteFailure(error));
|
|
4692
|
+
else
|
|
4693
|
+
console.error(`Failed to persist async workflow state '${filePath}':`, error);
|
|
4126
4694
|
},
|
|
4127
|
-
onError: (error, filePath) => console.error(`Failed to persist async workflow state '${filePath}':`, error),
|
|
4128
4695
|
write: (filePath, payload) => filePath === resultPath ? writeAsyncResultFile(filePath, payload) : writeAtomicJson(filePath, payload)
|
|
4129
4696
|
});
|
|
4130
4697
|
let initialPersistenceComplete = false;
|
|
@@ -4145,8 +4712,9 @@ export function createSubagentExecutor(deps) {
|
|
|
4145
4712
|
queueActiveRunIndex();
|
|
4146
4713
|
} else if (options.tolerateStatusWriteFailure) {
|
|
4147
4714
|
try {
|
|
4148
|
-
runPersistence.write(statusPath, status);
|
|
4149
|
-
|
|
4715
|
+
runPersistence.write(statusPath, { ...status });
|
|
4716
|
+
if (runPersistence.pendingCount() === 0)
|
|
4717
|
+
statusPersistenceDegraded = false;
|
|
4150
4718
|
} catch (error) {
|
|
4151
4719
|
const message = `Failed to persist async workflow state ${statusPath}: ${error instanceof Error ? error.message : String(error)}`;
|
|
4152
4720
|
console.error(message, error);
|
|
@@ -4160,7 +4728,7 @@ export function createSubagentExecutor(deps) {
|
|
|
4160
4728
|
}
|
|
4161
4729
|
}
|
|
4162
4730
|
} else {
|
|
4163
|
-
runPersistence.write(statusPath, status);
|
|
4731
|
+
runPersistence.write(statusPath, { ...status });
|
|
4164
4732
|
}
|
|
4165
4733
|
if (liveJob) {
|
|
4166
4734
|
liveJob.status = status.state;
|
|
@@ -4188,13 +4756,19 @@ export function createSubagentExecutor(deps) {
|
|
|
4188
4756
|
};
|
|
4189
4757
|
const writeWorkflowResult = (payload) => {
|
|
4190
4758
|
try {
|
|
4759
|
+
let resultPublished = false;
|
|
4760
|
+
settleResultPublication = (published) => {
|
|
4761
|
+
resultPublished = published;
|
|
4762
|
+
};
|
|
4763
|
+
pendingResultPublication = undefined;
|
|
4191
4764
|
runPersistence.write(resultPath, payload);
|
|
4765
|
+
if (!resultPublished)
|
|
4766
|
+
pendingResultPublication = new Promise((resolve) => {
|
|
4767
|
+
settleResultPublication = resolve;
|
|
4768
|
+
});
|
|
4192
4769
|
return true;
|
|
4193
4770
|
} catch (error) {
|
|
4194
|
-
|
|
4195
|
-
console.error(message, error);
|
|
4196
|
-
appendWorkflowEvent({ type: "subagent.workflow.result_write_failed", error: message });
|
|
4197
|
-
return false;
|
|
4771
|
+
return reportResultWriteFailure(error);
|
|
4198
4772
|
}
|
|
4199
4773
|
};
|
|
4200
4774
|
const projectWorkflowActivity = () => {
|
|
@@ -4227,22 +4801,221 @@ export function createSubagentExecutor(deps) {
|
|
|
4227
4801
|
indexPersistence.dispose();
|
|
4228
4802
|
return { content: [{ type: "text", text: `Failed to create async workflow storage: ${error instanceof Error ? error.message : String(error)}` }], isError: true, details: { mode: "workflow", results: [] } };
|
|
4229
4803
|
}
|
|
4230
|
-
appendWorkflowEvent({ type: "subagent.workflow.started" });
|
|
4804
|
+
appendWorkflowEvent({ type: "subagent.workflow.started", ...workflowArgsDigest ? { argsDigest: workflowArgsDigest } : {} });
|
|
4805
|
+
try {
|
|
4806
|
+
deps.dm.events.emit(SUBAGENT_ASYNC_STARTED_EVENT, {
|
|
4807
|
+
lifecycleArtifactVersion: SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
4808
|
+
id: workflowRunId,
|
|
4809
|
+
asyncDir,
|
|
4810
|
+
cwd: workflowCwd,
|
|
4811
|
+
...workflowSessionRoot ? { sessionRoot: workflowSessionRoot } : {},
|
|
4812
|
+
pid: process.pid,
|
|
4813
|
+
sessionId: currentSessionId ?? undefined,
|
|
4814
|
+
completionOwnerId,
|
|
4815
|
+
mode: "workflow",
|
|
4816
|
+
agent: "workflow",
|
|
4817
|
+
goal: derivedObjective.trim() ? PROMPT_REDACTED : undefined,
|
|
4818
|
+
...timeout !== undefined ? { timeoutMs: timeout, deadlineAt: startedAt + timeout } : {}
|
|
4819
|
+
});
|
|
4820
|
+
} catch (error) {
|
|
4821
|
+
console.error("Failed to emit async workflow start event:", error);
|
|
4822
|
+
}
|
|
4823
|
+
const emitWorkflowSteerEvent = (type, requestId, index, extra = {}) => {
|
|
4824
|
+
appendWorkflowEvent({ type, requestId, ...index !== undefined ? { index } : {}, ...extra });
|
|
4825
|
+
};
|
|
4826
|
+
const recordWorkflowSteerTargets = (request, targets) => {
|
|
4827
|
+
status.steering ??= createSteeringStatus();
|
|
4828
|
+
recordSteeringRequest(steeringStatus(status), {
|
|
4829
|
+
id: request.id,
|
|
4830
|
+
requestedAt: request.ts,
|
|
4831
|
+
...request.source ? { source: request.source } : {},
|
|
4832
|
+
message: request.message,
|
|
4833
|
+
targets
|
|
4834
|
+
});
|
|
4835
|
+
};
|
|
4836
|
+
const explicitWorkflowSteerIndexes = (request) => request.targetIndex !== undefined ? [request.targetIndex] : request.targetIndexes;
|
|
4837
|
+
const failWorkflowSteer = (request, indexes, reason) => {
|
|
4838
|
+
const targets = indexes.map((index) => ({ index, state: "failed", reason }));
|
|
4839
|
+
recordWorkflowSteerTargets(request, targets);
|
|
4840
|
+
emitWorkflowSteerEvent("subagent.steer.requested", request.id, undefined, { targets });
|
|
4841
|
+
for (const index of indexes)
|
|
4842
|
+
emitWorkflowSteerEvent("subagent.steer.failed", request.id, index, { reason });
|
|
4843
|
+
persist({ tolerateStatusWriteFailure: true });
|
|
4844
|
+
};
|
|
4845
|
+
const pendingWorkflowSteers = new Set;
|
|
4846
|
+
const deliverWorkflowSteerRequest = (request) => {
|
|
4847
|
+
let indexes = explicitWorkflowSteerIndexes(request);
|
|
4848
|
+
if (status.state !== "running") {
|
|
4849
|
+
failWorkflowSteer(request, indexes ?? [0], `run became ${status.state} before steering request was consumed`);
|
|
4850
|
+
return;
|
|
4851
|
+
}
|
|
4852
|
+
const liveControls = [...deps.state.foregroundControls.values()].filter((candidate) => candidate.parentWorkflowRunId === workflowRunId && (candidate.activeChildren?.size ?? 0) > 0);
|
|
4853
|
+
if (indexes === undefined) {
|
|
4854
|
+
if (liveControls.length !== 1) {
|
|
4855
|
+
failWorkflowSteer(request, [0], liveControls.length > 1 ? `workflow has ${liveControls.length} live children; steer a child run id instead` : "workflow child is not live in this process");
|
|
4856
|
+
return;
|
|
4857
|
+
}
|
|
4858
|
+
const index = status.steps?.findIndex((step) => !!step.workflowKey && step.workflowKey === liveControls[0].workflowKey) ?? -1;
|
|
4859
|
+
if (index < 0) {
|
|
4860
|
+
failWorkflowSteer(request, [0], "live workflow child has no projected step");
|
|
4861
|
+
return;
|
|
4862
|
+
}
|
|
4863
|
+
indexes = [index];
|
|
4864
|
+
}
|
|
4865
|
+
const resolved = indexes.map((index) => {
|
|
4866
|
+
const step = status.steps?.[index];
|
|
4867
|
+
const control = step?.workflowKey ? liveControls.find((candidate) => candidate.workflowKey === step.workflowKey) : undefined;
|
|
4868
|
+
return { index, control, reason: !step ? "child index out of range" : !control ? "workflow child is not live in this process" : undefined };
|
|
4869
|
+
});
|
|
4870
|
+
const targets = resolved.map(({ index, reason }) => ({ index, state: reason ? "failed" : "routed", ...reason ? { reason } : {} }));
|
|
4871
|
+
recordWorkflowSteerTargets(request, targets);
|
|
4872
|
+
emitWorkflowSteerEvent("subagent.steer.requested", request.id, undefined, { targets });
|
|
4873
|
+
persist({ tolerateStatusWriteFailure: true });
|
|
4874
|
+
for (const { index, control, reason } of resolved) {
|
|
4875
|
+
if (!control) {
|
|
4876
|
+
emitWorkflowSteerEvent("subagent.steer.failed", request.id, index, { reason });
|
|
4877
|
+
continue;
|
|
4878
|
+
}
|
|
4879
|
+
emitWorkflowSteerEvent("subagent.steer.routed", request.id, index);
|
|
4880
|
+
const applyWorkflowSteerDelivery = (state, reason) => {
|
|
4881
|
+
if (!pendingWorkflowSteers.has(applyWorkflowSteerDelivery))
|
|
4882
|
+
return;
|
|
4883
|
+
if (state !== "queued")
|
|
4884
|
+
pendingWorkflowSteers.delete(applyWorkflowSteerDelivery);
|
|
4885
|
+
const now = Date.now();
|
|
4886
|
+
const steering = steeringStatus(status);
|
|
4887
|
+
if (state !== "queued")
|
|
4888
|
+
steering.pending = Math.max(0, steering.pending - 1);
|
|
4889
|
+
if (state === "delivered") {
|
|
4890
|
+
steering.delivered++;
|
|
4891
|
+
steering.lastDeliveredAt = now;
|
|
4892
|
+
} else if (state === "failed")
|
|
4893
|
+
steering.failed++;
|
|
4894
|
+
const receipt = steering.recent.find((candidate) => candidate.id === request.id)?.targets.find((target) => target.index === index);
|
|
4895
|
+
if (receipt) {
|
|
4896
|
+
receipt.state = state;
|
|
4897
|
+
if (state === "delivered")
|
|
4898
|
+
receipt.deliveredAt = now;
|
|
4899
|
+
if (state === "failed")
|
|
4900
|
+
receipt.failedAt = now;
|
|
4901
|
+
if (reason)
|
|
4902
|
+
receipt.reason = reason;
|
|
4903
|
+
}
|
|
4904
|
+
if (state === "failed") {
|
|
4905
|
+
const failedStep = status.steps?.[index];
|
|
4906
|
+
if (failedStep)
|
|
4907
|
+
failedStep.activityState = "needs_attention";
|
|
4908
|
+
status.activityState = "needs_attention";
|
|
4909
|
+
}
|
|
4910
|
+
emitWorkflowSteerEvent(`subagent.steer.${state}`, request.id, index, state === "failed" ? { reason } : { deliveryStatus: state, message: request.message });
|
|
4911
|
+
persist({ tolerateStatusWriteFailure: true });
|
|
4912
|
+
};
|
|
4913
|
+
pendingWorkflowSteers.add(applyWorkflowSteerDelivery);
|
|
4914
|
+
steerWorkflowForegroundTarget({
|
|
4915
|
+
target: { control, workflowRunId, sourceRunId: workflowRunId },
|
|
4916
|
+
message: request.message,
|
|
4917
|
+
...request.mode ? { mode: request.mode } : {}
|
|
4918
|
+
}).then((result) => {
|
|
4919
|
+
const target = result.details.steering?.targets[0];
|
|
4920
|
+
applyWorkflowSteerDelivery(target?.state === "delivered" ? "delivered" : target?.state === "queued" ? "queued" : "failed", target?.reason ?? (target ? undefined : "steering produced no target receipt"));
|
|
4921
|
+
}, (error) => applyWorkflowSteerDelivery("failed", error instanceof Error ? error.message : String(error)));
|
|
4922
|
+
}
|
|
4923
|
+
};
|
|
4924
|
+
let disposeWorkflowSteerInbox;
|
|
4925
|
+
try {
|
|
4926
|
+
disposeWorkflowSteerInbox = watchAsyncControlInbox(asyncDir, {
|
|
4927
|
+
onSteer: deliverWorkflowSteerRequest,
|
|
4928
|
+
onError: (error, phase, request) => {
|
|
4929
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
4930
|
+
appendWorkflowEvent({ type: "subagent.workflow.steer_inbox_unavailable", phase, error: reason });
|
|
4931
|
+
if (request)
|
|
4932
|
+
failWorkflowSteer(request, explicitWorkflowSteerIndexes(request) ?? [0], `steer consumer failed: ${reason}`);
|
|
4933
|
+
}
|
|
4934
|
+
});
|
|
4935
|
+
} catch (error) {
|
|
4936
|
+
appendWorkflowEvent({ type: "subagent.workflow.steer_inbox_unavailable", error: error instanceof Error ? error.message : String(error) });
|
|
4937
|
+
}
|
|
4938
|
+
deps.activateSupervisorTransport?.();
|
|
4231
4939
|
const { workflowScript, async: _workflowAsync, chatProgress: _chatProgress, ...workflowRequest } = requestParams;
|
|
4940
|
+
let workflowSteerInboxClosed = false;
|
|
4941
|
+
const settleWorkflowSteerInbox = (outcome = status.state) => {
|
|
4942
|
+
if (workflowSteerInboxClosed)
|
|
4943
|
+
return;
|
|
4944
|
+
workflowSteerInboxClosed = true;
|
|
4945
|
+
disposeWorkflowSteerInbox?.();
|
|
4946
|
+
for (const settle of pendingWorkflowSteers)
|
|
4947
|
+
settle("failed", `run became ${outcome} before steering delivery settled; delivery unconfirmed`);
|
|
4948
|
+
try {
|
|
4949
|
+
closeSteerInbox(asyncDir, outcome);
|
|
4950
|
+
const undelivered = consumeSteerRequests(asyncDir, undefined, (error) => {
|
|
4951
|
+
appendWorkflowEvent({ type: "subagent.workflow.steer_inbox_unavailable", phase: "drain", error: error instanceof Error ? error.message : String(error) });
|
|
4952
|
+
});
|
|
4953
|
+
for (const request of undelivered)
|
|
4954
|
+
failWorkflowSteer(request, explicitWorkflowSteerIndexes(request) ?? [0], `run became ${outcome} before steering request was consumed`);
|
|
4955
|
+
} catch (error) {
|
|
4956
|
+
appendWorkflowEvent({ type: "subagent.workflow.steer_inbox_unavailable", phase: "close", error: error instanceof Error ? error.message : String(error) });
|
|
4957
|
+
}
|
|
4958
|
+
persist();
|
|
4959
|
+
};
|
|
4232
4960
|
Promise.resolve().then(async () => {
|
|
4233
4961
|
const workflowDeadlineAt = timeout === undefined ? undefined : Date.now() + timeout;
|
|
4234
4962
|
const workflowResults = [];
|
|
4235
4963
|
const workflowChildRunIds = new Map;
|
|
4236
|
-
const { action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, missionId: _missionId, mission: _mission, preflight: _preflight, ...workflowChildDefaults } = workflowRequest;
|
|
4964
|
+
const { args: _args, action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, missionId: _missionId, mission: _mission, preflight: _preflight, globalConcurrencyLimit: _globalConcurrencyLimit, maxSubagentSpawnsPerRun: _maxSubagentSpawnsPerRun, ...workflowChildDefaults } = workflowRequest;
|
|
4237
4965
|
const workflowOutput = typeof workflowChildDefaults.output === "string" || typeof workflowChildDefaults.output === "boolean" ? workflowChildDefaults.output : undefined;
|
|
4238
4966
|
const configuredOutputBaseDir = resolveConfiguredSingleRunOutputBaseDir(deps);
|
|
4239
|
-
const workflowAggregateOutputPath =
|
|
4967
|
+
const workflowAggregateOutputPath = resolveSingleOutputPath(workflowOutput, parentCwd, workflowCwd, resolveSingleRunOutputBaseDir(deps, workflowArtifactsDir, workflowRunId));
|
|
4240
4968
|
const claimedOutputPaths = new Map;
|
|
4241
4969
|
const childOutputOverrides = new Map;
|
|
4242
4970
|
const childOutputClaimPaths = new Map;
|
|
4243
4971
|
const producedChildOutputPaths = new Set;
|
|
4244
4972
|
const workflowSteps = new Map;
|
|
4245
|
-
const
|
|
4973
|
+
const announcedWorkflowChildren = new Set;
|
|
4974
|
+
const announceWorkflowChild = (key, step) => {
|
|
4975
|
+
if (announcedWorkflowChildren.has(key))
|
|
4976
|
+
return;
|
|
4977
|
+
announcedWorkflowChildren.add(key);
|
|
4978
|
+
const stepIndex = status.steps?.indexOf(step);
|
|
4979
|
+
const childEvent = {
|
|
4980
|
+
type: "subagent.child-status",
|
|
4981
|
+
version: 1,
|
|
4982
|
+
runId: workflowRunId,
|
|
4983
|
+
childId: key,
|
|
4984
|
+
status: "started",
|
|
4985
|
+
ts: Date.now(),
|
|
4986
|
+
source: "async",
|
|
4987
|
+
asyncDir,
|
|
4988
|
+
...stepIndex !== undefined ? { stepIndex } : {},
|
|
4989
|
+
agent: step.agent,
|
|
4990
|
+
...step.runId ? { childRunId: step.runId } : {},
|
|
4991
|
+
workflowKey: key,
|
|
4992
|
+
...step.phase ? { phase: step.phase } : {},
|
|
4993
|
+
...step.label ? { label: step.label } : {}
|
|
4994
|
+
};
|
|
4995
|
+
appendWorkflowEvent({ ...childEvent });
|
|
4996
|
+
try {
|
|
4997
|
+
deps.dm.events.emit(SUBAGENT_CHILD_STATUS_EVENT, childEvent);
|
|
4998
|
+
} catch (error) {
|
|
4999
|
+
console.error("Failed to emit workflow child status event:", error);
|
|
5000
|
+
}
|
|
5001
|
+
};
|
|
5002
|
+
announcePersistedWorkflowChildren = () => {
|
|
5003
|
+
for (const [key, step] of pendingWorkflowChildAnnouncements) {
|
|
5004
|
+
if (!step.runId)
|
|
5005
|
+
continue;
|
|
5006
|
+
announceWorkflowChild(key, step);
|
|
5007
|
+
pendingWorkflowChildAnnouncements.delete(key);
|
|
5008
|
+
}
|
|
5009
|
+
};
|
|
5010
|
+
const runHostCommand = workflowHostCommandRunner({
|
|
5011
|
+
workflowCwd,
|
|
5012
|
+
artifactsDir: workflowArtifactsDir,
|
|
5013
|
+
workflowRunId,
|
|
5014
|
+
claimedOutputPaths,
|
|
5015
|
+
producedOutputPaths: producedChildOutputPaths,
|
|
5016
|
+
...workflowResource ? { authorize: (key, params) => authorizeWorkflowResourceHost(workflowResource.permit, key, params.command) } : {}
|
|
5017
|
+
});
|
|
5018
|
+
const workflowHost = workflowResource ? workflowResource.authority.host ? runHostCommand : undefined : publicExecution ? undefined : runHostCommand;
|
|
4246
5019
|
let projectedTraceLength = 0;
|
|
4247
5020
|
let projectedTraceTail;
|
|
4248
5021
|
const updateTrace = (trace) => {
|
|
@@ -4352,9 +5125,19 @@ export function createSubagentExecutor(deps) {
|
|
|
4352
5125
|
try {
|
|
4353
5126
|
const workflow = await runWorkflowScript({
|
|
4354
5127
|
script: workflowScript,
|
|
4355
|
-
|
|
5128
|
+
...workflowArgs ? { args: workflowArgs } : {},
|
|
5129
|
+
workflowRunId,
|
|
5130
|
+
processCwd: ctx.cwd,
|
|
5131
|
+
globalConcurrencyLimit: requestParams.globalConcurrencyLimit ?? deps.config.globalConcurrencyLimit,
|
|
4356
5132
|
timeoutMs: timeout,
|
|
4357
5133
|
signal: controller.signal,
|
|
5134
|
+
continueAfterAbortWhenChildrenSettled: (abortError) => {
|
|
5135
|
+
if (abortError.message !== "Workflow stopped because the extension session was replaced or reloaded.")
|
|
5136
|
+
return false;
|
|
5137
|
+
const activeAsyncChild = [...deps.state.asyncJobs?.values() ?? []].some((job) => job.parentWorkflowRunId === workflowRunId && (job.status === "queued" || job.status === "running"));
|
|
5138
|
+
const activeForegroundChild = [...deps.state.foregroundControls.values()].some((control) => control.parentWorkflowRunId === workflowRunId && (control.activeChildren?.size ?? 0) > 0);
|
|
5139
|
+
return !activeAsyncChild && !activeForegroundChild;
|
|
5140
|
+
},
|
|
4358
5141
|
registerStopChild: (stop) => {
|
|
4359
5142
|
if (stop)
|
|
4360
5143
|
deps.state.workflowChildStops?.set(workflowRunId, stop);
|
|
@@ -4363,19 +5146,39 @@ export function createSubagentExecutor(deps) {
|
|
|
4363
5146
|
},
|
|
4364
5147
|
...workflowState ? { state: workflowState } : {},
|
|
4365
5148
|
onTrace: updateTrace,
|
|
5149
|
+
onChildSettled: (notification) => {
|
|
5150
|
+
appendWorkflowEvent({
|
|
5151
|
+
type: "subagent.workflow.child_settled",
|
|
5152
|
+
childKey: notification.childKey,
|
|
5153
|
+
...notification.childRunId ? { childRunId: notification.childRunId } : {},
|
|
5154
|
+
outcome: notification.outcome,
|
|
5155
|
+
workflowRunning: notification.workflowRunning
|
|
5156
|
+
});
|
|
5157
|
+
try {
|
|
5158
|
+
deps.dm.sendMessage({
|
|
5159
|
+
customType: "subagent-incremental-child-notify",
|
|
5160
|
+
content: formatIncrementalChildCompletion(notification),
|
|
5161
|
+
display: notification.outcome !== "completed"
|
|
5162
|
+
}, { triggerTurn: incrementalChildCompletionTriggersTurn(notification, requestParams.scheduleOrigin) });
|
|
5163
|
+
} catch (sendError) {
|
|
5164
|
+
console.error(`Failed to send incremental child completion notification for '${notification.childKey}':`, sendError);
|
|
5165
|
+
}
|
|
5166
|
+
deps.refreshResultDelivery?.();
|
|
5167
|
+
},
|
|
4366
5168
|
onLanePlan: (lanes) => {
|
|
4367
5169
|
status.workflowGraph = buildWorkflowLaneGraph(workflowRunId, lanes, status.workflowGraph);
|
|
4368
5170
|
applyWorkflowLaneTrace(status.workflowGraph, status.workflow?.trace ?? []);
|
|
4369
5171
|
persist({ tolerateStatusWriteFailure: true });
|
|
4370
5172
|
},
|
|
4371
|
-
host:
|
|
5173
|
+
...workflowHost ? { host: workflowHost } : {},
|
|
4372
5174
|
onHostStep: (hostStep) => {
|
|
4373
5175
|
status = upsertHostStep({ status, hostStep, persist: (nextStatus) => {
|
|
4374
5176
|
status = nextStatus;
|
|
4375
5177
|
persist({ tolerateStatusWriteFailure: true });
|
|
4376
5178
|
} });
|
|
4377
5179
|
},
|
|
4378
|
-
admit: (calls) => {
|
|
5180
|
+
admit: async (calls, admissionSignal) => {
|
|
5181
|
+
await preflightWorkflowWorktrees({ workflowDefaults: workflowChildDefaults, defaultWorktree: deps.config.worktree, calls, ctxCwd: parentCwd, signal: admissionSignal, deadlineAt: workflowDeadlineAt });
|
|
4379
5182
|
const outputClaims = workflowChildOutputClaims({ ctxCwd: parentCwd, workflowCwd, artifactsDir: workflowArtifactsDir, workflowRunId, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, state: deps.state, claimedOutputPaths, entries: calls });
|
|
4380
5183
|
if (outputClaims.error)
|
|
4381
5184
|
throw new Error(outputClaims.error);
|
|
@@ -4412,8 +5215,10 @@ export function createSubagentExecutor(deps) {
|
|
|
4412
5215
|
});
|
|
4413
5216
|
let preparedChildParams;
|
|
4414
5217
|
const result = await runMissionWorkflowChild(missionBinding, workflowRunId, key, childPhase, () => {
|
|
4415
|
-
const childRequest = bindMissionWorkflowChildAsyncLaunch({ ...prepareWorkflowChildLaunchParams({ workflowDefaults: workflowChildDefaults, childParams, parentWorkflowRunId: workflowRunId, workflowKey: key, ctxCwd: parentCwd, workflowCwd, artifactsDir: workflowArtifactsDir, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, outputOverride: childOutputOverrides.get(key), outputClaimPath: childOutputClaimPaths.get(key), options: { missionDetached: detachWorkflowChildMissions, awaitDetachedChild: true, runFanoutBudget: workflowFanoutBudget, parentDeadlineAt: workflowDeadlineAt, capabilityCeiling: workflowCapabilityCeiling } }), runFanoutAdmitted: admission.admitted }, missionBinding, deps.asyncByDefault);
|
|
5218
|
+
const childRequest = bindMissionWorkflowChildAsyncLaunch({ ...prepareWorkflowChildLaunchParams({ workflowDefaults: workflowChildDefaults, childParams, parentWorkflowRunId: workflowRunId, workflowKey: key, ctxCwd: parentCwd, workflowCwd, artifactsDir: workflowArtifactsDir, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, outputOverride: childOutputOverrides.get(key), outputClaimPath: childOutputClaimPaths.get(key), options: { missionDetached: detachWorkflowChildMissions, awaitDetachedChild: true, runFanoutBudget: workflowFanoutBudget, parentDeadlineAt: workflowDeadlineAt, capabilityCeiling: workflowCapabilityCeiling } }), runFanoutAdmitted: admission.admitted }, missionBinding, deps.asyncByDefault, undefined, inheritedNestedRoute(deps)?.rootRunId);
|
|
4416
5219
|
preparedChildParams = childRequest;
|
|
5220
|
+
if (workflowUsageBudget.budget)
|
|
5221
|
+
workflowOwnedUsageBudgets.set(childRequest, workflowUsageBudget.budget);
|
|
4417
5222
|
workflowLaunchObservers.set(childRequest, (launch) => {
|
|
4418
5223
|
const step = status.steps?.find((candidate) => candidate.workflowKey === key);
|
|
4419
5224
|
if (step) {
|
|
@@ -4426,6 +5231,8 @@ export function createSubagentExecutor(deps) {
|
|
|
4426
5231
|
step.runId = launch.runId;
|
|
4427
5232
|
if (childRequest.lane)
|
|
4428
5233
|
step.lane = childRequest.lane;
|
|
5234
|
+
if (step.runId)
|
|
5235
|
+
pendingWorkflowChildAnnouncements.set(key, step);
|
|
4429
5236
|
persist({ tolerateStatusWriteFailure: true });
|
|
4430
5237
|
}
|
|
4431
5238
|
recordMissionWorkflowChild(missionBinding, workflowRunId, key, { status: "running", agent: launch.agent, ...launch.sessionFile ? { sessionPath: launch.sessionFile } : {} });
|
|
@@ -4469,7 +5276,7 @@ export function createSubagentExecutor(deps) {
|
|
|
4469
5276
|
workflowChildRunIds.set(key, child.runId);
|
|
4470
5277
|
const step = status.steps?.find((candidate) => candidate.workflowKey === key);
|
|
4471
5278
|
if (step) {
|
|
4472
|
-
step.async = Boolean(result.details.asyncId || result.details.asyncDir);
|
|
5279
|
+
step.async = step.async === true || Boolean(result.details.asyncId || result.details.asyncDir);
|
|
4473
5280
|
if (child.runId)
|
|
4474
5281
|
step.runId = child.runId;
|
|
4475
5282
|
if (child.lane)
|
|
@@ -4497,37 +5304,43 @@ export function createSubagentExecutor(deps) {
|
|
|
4497
5304
|
return child;
|
|
4498
5305
|
},
|
|
4499
5306
|
status: async (keyOrRunId, workflowSignal) => workflowChildResult(keyOrRunId, await execute(randomUUID(), { action: "status", id: keyOrRunId }, workflowSignal, undefined, ctx, preserveActiveSession, workflowParentModel)),
|
|
4500
|
-
resolveResume: (reference) =>
|
|
5307
|
+
resolveResume: (reference, _signal, index) => resolveWorkflowResume(reference, deps, ctx.sessionManager.getSessionFile() ?? null, index),
|
|
4501
5308
|
steer: (key, message, options, workflowSignal) => steerWorkflowChildByKey({ state: deps.state, workflowRunId, key, message, options, signal: workflowSignal, resolveRunId: () => workflowChildRunIds.get(key) })
|
|
4502
5309
|
});
|
|
4503
5310
|
const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, workflow.trace, { settled: true });
|
|
4504
5311
|
const finalPreflightTrace = annotateWorkflowPreflightTrace(workflow.trace, workflowPreflight);
|
|
4505
5312
|
const returnPreview = formatWorkflowValue(workflow.value).slice(0, 1000);
|
|
4506
5313
|
const emitPreview = workflow.emits.length > 0 ? ` Emitted: ${workflow.emits.map(formatWorkflowValue).join(", ").slice(0, 1000)}` : "";
|
|
4507
|
-
const
|
|
5314
|
+
const runningSummary = workflowRunningChildrenSummary(workflow.children);
|
|
5315
|
+
const summary = `${runningSummary ? `Workflow dispatch completed; ${runningSummary}` : `Workflow completed with ${workflow.children.length} child run(s).`} Return: ${returnPreview}${emitPreview} Trace: ${workflow.trace.length} event(s).${workflowOutputPathMappingSummary(workflow.children)}${finalPreflightWarnings.length ? ` ${finalPreflightWarnings.join(" ")}` : ""}`;
|
|
4508
5316
|
const outputWarning = writeWorkflowAggregateOutput(workflowAggregateOutputPath, summary, producedChildOutputPaths);
|
|
4509
5317
|
const resultSummary = appendWorkflowOutputWarning(summary, outputWarning);
|
|
4510
5318
|
const workflowUsage = sumResultsUsage(workflowResults);
|
|
5319
|
+
settleWorkflowSteerInbox("complete");
|
|
4511
5320
|
const workflowChildren = workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState: "completed", inventoryComplete: true, trace: workflow.trace, children: workflow.children, steps: status.steps });
|
|
4512
|
-
status = { ...status, state: "complete", endedAt: Date.now(), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren, totalTokens: { input: workflowUsage.input, output: workflowUsage.output, total: workflowUsage.input + workflowUsage.output }, totalCost: sumResultsCost(workflowResults) };
|
|
4513
|
-
const receipt = terminalWorkflowReceipt(workflowRunId, "complete", workflow.children, workflowChildren, undefined, validHostStepNodes(status.workflowGraph));
|
|
5321
|
+
status = { ...status, state: "complete", endedAt: Date.now(), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren, totalTokens: { input: workflowUsage.input, output: workflowUsage.output, total: workflowUsage.input + workflowUsage.output }, totalCost: sumResultsCost(workflowResults) };
|
|
5322
|
+
const receipt = terminalWorkflowReceipt(workflowRunId, "complete", workflow.children, workflowChildren, undefined, validHostStepNodes(status.workflowGraph), workflowResource?.provenance, workflowArgsDigest);
|
|
5323
|
+
delete status.workflowReceiptPath;
|
|
4514
5324
|
let workflowReceipt;
|
|
4515
5325
|
try {
|
|
4516
5326
|
workflowReceipt = { path: writeWorkflowReceipt(asyncDir, receipt), receipt };
|
|
5327
|
+
status.workflowReceiptPath = workflowReceipt.path;
|
|
4517
5328
|
} catch (receiptError) {
|
|
4518
5329
|
appendWorkflowEvent({ type: "subagent.workflow.receipt_write_failed", error: `Failed to persist async workflow receipt: ${receiptError instanceof Error ? receiptError.message : String(receiptError)}` });
|
|
4519
5330
|
}
|
|
4520
|
-
if (!writeWorkflowResult({ id: workflowRunId, runId: workflowRunId, toolCallId, agent: "workflow", mode: "workflow", success: true, state: "complete", summary: resultSummary, output: resultSummary, workflowChildren, results: workflow.children
|
|
5331
|
+
if (!writeWorkflowResult({ id: workflowRunId, runId: workflowRunId, toolCallId, agent: "workflow", mode: "workflow", success: true, state: "complete", summary: resultSummary, output: resultSummary, workflowChildren, results: workflowResultChildren(workflow.children, status, false), workflow: status.workflow, ...workflowCapabilityCeiling ? { admissionCapabilityCeiling: workflowCapabilityCeiling } : {}, ...workflowReceipt ? { workflowReceipt } : {}, asyncDir, cwd: workflowCwd, sessionId: currentSessionId, completionOwnerId, ...requestParams.scheduleOrigin ? { scheduleOrigin: requestParams.scheduleOrigin } : {}, timestamp: Date.now(), durationMs: Date.now() - startedAt }))
|
|
5332
|
+
return;
|
|
5333
|
+
if (pendingResultPublication && !await pendingResultPublication)
|
|
4521
5334
|
return;
|
|
4522
5335
|
persist();
|
|
4523
5336
|
deps.refreshResultDelivery?.();
|
|
4524
5337
|
persistClosed = true;
|
|
4525
|
-
appendWorkflowEvent({ type: "subagent.workflow.completed", state: status.state, ...status.error ? { error: status.error } : {} });
|
|
5338
|
+
appendWorkflowEvent({ type: "subagent.workflow.completed", state: status.state, ...workflowArgsDigest ? { argsDigest: workflowArgsDigest } : {}, ...status.error ? { error: status.error } : {} });
|
|
4526
5339
|
} catch (error) {
|
|
4527
5340
|
const partial = error instanceof WorkflowScriptError ? error.partial : { trace: [], emits: [], console: [], children: [] };
|
|
4528
5341
|
const stopped = controller.signal.aborted;
|
|
4529
5342
|
const detachedChildKeys = new Set(partial.children.filter((child) => child.detached).map((child) => child.key));
|
|
4530
|
-
const hasRealFailedChild = partial.children.some((child) => !child.ok && !child.detached);
|
|
5343
|
+
const hasRealFailedChild = partial.children.some((child) => !child.ok && child.state !== "running" && !child.detached);
|
|
4531
5344
|
const pauseForDetached = !stopped && error instanceof WorkflowScriptError && error.errorKind === "detached-child" && detachedChildKeys.size > 0 && !hasRealFailedChild;
|
|
4532
5345
|
const state = stopped ? "stopped" : pauseForDetached ? "paused" : "failed";
|
|
4533
5346
|
for (const step of status.steps ?? []) {
|
|
@@ -4543,10 +5356,11 @@ export function createSubagentExecutor(deps) {
|
|
|
4543
5356
|
}
|
|
4544
5357
|
}
|
|
4545
5358
|
const workflowState = state === "paused" ? "paused" : state === "stopped" ? "stopped" : "failed";
|
|
5359
|
+
settleWorkflowSteerInbox(state);
|
|
4546
5360
|
const workflowChildren = workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState, inventoryComplete: true, trace: partial.trace, children: partial.children, steps: status.steps });
|
|
4547
5361
|
const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, partial.trace, { settled: true });
|
|
4548
5362
|
const finalPreflightTrace = annotateWorkflowPreflightTrace(partial.trace, workflowPreflight);
|
|
4549
|
-
status = compactOptional({ ...status, state, stopped: stopped || undefined, activityState: pauseForDetached ? "needs_attention" : undefined, error: workflowFailureMessage(error, workflowRunId, partial.children), endedAt: Date.now(), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren });
|
|
5363
|
+
status = compactOptional({ ...status, state, stopped: stopped || undefined, activityState: pauseForDetached || status.activityState === "needs_attention" ? "needs_attention" : undefined, error: workflowFailureMessage(error, workflowRunId, partial.children), endedAt: Date.now(), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {} }, workflowChildren });
|
|
4550
5364
|
if (pauseForDetached) {
|
|
4551
5365
|
const promoted = promotePausedWorkflowIfSettled(status);
|
|
4552
5366
|
if (promoted)
|
|
@@ -4557,20 +5371,29 @@ export function createSubagentExecutor(deps) {
|
|
|
4557
5371
|
const resultSummary = appendWorkflowOutputWarning(terminalSummary, outputWarning);
|
|
4558
5372
|
const receiptState = status.state === "complete" ? "complete" : status.state === "paused" ? "paused" : status.state === "stopped" ? "stopped" : "failed";
|
|
4559
5373
|
const terminalOutcome = workflowFailureTerminalOutcome(error, partial.children, usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)));
|
|
4560
|
-
const receipt = terminalWorkflowReceipt(workflowRunId, receiptState, partial.children, workflowChildren, terminalOutcome, validHostStepNodes(status.workflowGraph));
|
|
5374
|
+
const receipt = terminalWorkflowReceipt(workflowRunId, receiptState, partial.children, workflowChildren, terminalOutcome, validHostStepNodes(status.workflowGraph), workflowResource?.provenance, workflowArgsDigest);
|
|
5375
|
+
delete status.workflowReceiptPath;
|
|
4561
5376
|
let workflowReceipt;
|
|
4562
5377
|
try {
|
|
4563
5378
|
workflowReceipt = { path: writeWorkflowReceipt(asyncDir, receipt), receipt };
|
|
5379
|
+
status.workflowReceiptPath = workflowReceipt.path;
|
|
4564
5380
|
} catch (receiptError) {
|
|
4565
5381
|
appendWorkflowEvent({ type: "subagent.workflow.receipt_write_failed", error: `Failed to persist async workflow receipt: ${receiptError instanceof Error ? receiptError.message : String(receiptError)}` });
|
|
4566
5382
|
}
|
|
4567
|
-
if (!writeWorkflowResult({ id: workflowRunId, runId: workflowRunId, toolCallId, agent: "workflow", mode: "workflow", success: status.state === "complete", state: status.state, summary: resultSummary, error: status.state === "complete" ? undefined : status.error, stopped: status.stopped, activityState: status.activityState, workflowChildren, ...terminalOutcome ? { terminalOutcome } : {}, results: partial.children
|
|
5383
|
+
if (!writeWorkflowResult({ id: workflowRunId, runId: workflowRunId, toolCallId, agent: "workflow", mode: "workflow", success: status.state === "complete", state: status.state, summary: resultSummary, error: status.state === "complete" ? undefined : status.error, stopped: status.stopped, activityState: status.activityState, workflowChildren, ...terminalOutcome ? { terminalOutcome } : {}, results: workflowResultChildren(partial.children, status, true), workflow: status.workflow, ...workflowCapabilityCeiling ? { admissionCapabilityCeiling: workflowCapabilityCeiling } : {}, ...workflowReceipt ? { workflowReceipt } : {}, asyncDir, cwd: workflowCwd, sessionId: currentSessionId, completionOwnerId, ...requestParams.scheduleOrigin ? { scheduleOrigin: requestParams.scheduleOrigin } : {}, timestamp: Date.now(), durationMs: Date.now() - startedAt }))
|
|
5384
|
+
return;
|
|
5385
|
+
if (pendingResultPublication && !await pendingResultPublication)
|
|
4568
5386
|
return;
|
|
4569
5387
|
persist();
|
|
4570
5388
|
deps.refreshResultDelivery?.();
|
|
4571
5389
|
persistClosed = true;
|
|
4572
|
-
appendWorkflowEvent({ type: "subagent.workflow.completed", state: status.state, ...terminalOutcome ? { terminalOutcome } : {}, ...status.error ? { error: status.error } : {}, ...status.activityState ? { activityState: status.activityState } : {} });
|
|
5390
|
+
appendWorkflowEvent({ type: "subagent.workflow.completed", state: status.state, ...workflowArgsDigest ? { argsDigest: workflowArgsDigest } : {}, ...terminalOutcome ? { terminalOutcome } : {}, ...status.error ? { error: status.error } : {}, ...status.activityState ? { activityState: status.activityState } : {} });
|
|
4573
5391
|
} finally {
|
|
5392
|
+
try {
|
|
5393
|
+
settleWorkflowSteerInbox();
|
|
5394
|
+
} catch (error) {
|
|
5395
|
+
console.error(`Failed to close async workflow steer inbox '${asyncDir}':`, error);
|
|
5396
|
+
}
|
|
4574
5397
|
persistClosed = true;
|
|
4575
5398
|
deps.state.workflowControllers?.delete(workflowRunId);
|
|
4576
5399
|
deps.state.workflowChildStops?.delete(workflowRunId);
|
|
@@ -4581,39 +5404,58 @@ export function createSubagentExecutor(deps) {
|
|
|
4581
5404
|
content: [{ type: "text", text: `${workflowPreflight ? `${formatWorkflowPreflight(workflowPreflight)}
|
|
4582
5405
|
|
|
4583
5406
|
` : ""}${formatAsyncStartedMessage(`Async workflow [${workflowRunId}]`, ctx.hasUI === true)}` }],
|
|
4584
|
-
details: { mode: "workflow", runId: workflowRunId, toolCallId, asyncId: workflowRunId, asyncDir, results: [], ...workflowPreflight ? { preflight: workflowPreflight } : {}, workflowChildren: status.workflowChildren, chatProgress, ...deps.state.activeAsyncCapacity ? { activeAsyncCapacity: deps.state.activeAsyncCapacity } : {} }
|
|
5407
|
+
details: { mode: "workflow", runId: workflowRunId, toolCallId, asyncId: workflowRunId, asyncDir, results: [], ...workflowPreflight ? { preflight: workflowPreflight } : {}, workflow: status.workflow, workflowChildren: status.workflowChildren, chatProgress, ...deps.state.activeAsyncCapacity ? { activeAsyncCapacity: deps.state.activeAsyncCapacity } : {} }
|
|
4585
5408
|
}, workflowFanoutBudget));
|
|
4586
5409
|
}
|
|
4587
|
-
const { workflowScript: _workflowScript, action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, async: _async, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, chatProgress: _chatProgress, missionId: _missionId, mission: _mission, preflight: _preflight, ...workflowChildDefaults } = requestParams;
|
|
5410
|
+
const { workflowScript: _workflowScript, args: _args, action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, async: _async, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, chatProgress: _chatProgress, missionId: _missionId, mission: _mission, preflight: _preflight, globalConcurrencyLimit: _globalConcurrencyLimit, maxSubagentSpawnsPerRun: _maxSubagentSpawnsPerRun, ...workflowChildDefaults } = requestParams;
|
|
4588
5411
|
const workflowOutput = typeof workflowChildDefaults.output === "string" || typeof workflowChildDefaults.output === "boolean" ? workflowChildDefaults.output : undefined;
|
|
4589
5412
|
const configuredOutputBaseDir = resolveConfiguredSingleRunOutputBaseDir(deps);
|
|
4590
|
-
const workflowAggregateOutputPath =
|
|
5413
|
+
const workflowAggregateOutputPath = resolveSingleOutputPath(workflowOutput, ctx.cwd, workflowCwd, resolveSingleRunOutputBaseDir(deps, workflowArtifactsDir, foregroundWorkflowRunId));
|
|
4591
5414
|
const claimedOutputPaths = new Map;
|
|
4592
5415
|
const childOutputOverrides = new Map;
|
|
4593
5416
|
const childOutputClaimPaths = new Map;
|
|
4594
5417
|
const producedChildOutputPaths = new Set;
|
|
4595
5418
|
const workflowResults = [];
|
|
4596
5419
|
const workflowChildRunIds = new Map;
|
|
4597
|
-
const runHostCommand = workflowHostCommandRunner({
|
|
5420
|
+
const runHostCommand = workflowHostCommandRunner({
|
|
5421
|
+
workflowCwd,
|
|
5422
|
+
artifactsDir: workflowArtifactsDir,
|
|
5423
|
+
workflowRunId: foregroundWorkflowRunId,
|
|
5424
|
+
claimedOutputPaths,
|
|
5425
|
+
producedOutputPaths: producedChildOutputPaths,
|
|
5426
|
+
...workflowResource ? { authorize: (key, params) => authorizeWorkflowResourceHost(workflowResource.permit, key, params.command) } : {}
|
|
5427
|
+
});
|
|
5428
|
+
const workflowHost = delegatedWorkflowPermit ? undefined : workflowResource ? workflowResource.authority.host ? runHostCommand : undefined : publicExecution ? undefined : runHostCommand;
|
|
4598
5429
|
const workflowHostSteps = new Map;
|
|
4599
|
-
let liveWorkflow = { trace: [], emits: [], console: [] };
|
|
4600
|
-
|
|
5430
|
+
let liveWorkflow = { trace: [], emits: [], console: [], ...workflowResource ? { resource: workflowResource.provenance } : {} };
|
|
5431
|
+
const childProgress = new Map;
|
|
5432
|
+
let activityTimer;
|
|
5433
|
+
let lastProgressAt = 0;
|
|
5434
|
+
let workflowProgressClosed = false;
|
|
4601
5435
|
const workflowDeadlineAt = timeout === undefined ? undefined : Date.now() + timeout;
|
|
4602
5436
|
const workflowCapabilityCeiling = intersectSubagentCapabilityCeilings(requestParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(resolveCurrentSessionId(ctx.sessionManager)));
|
|
4603
5437
|
const sendWorkflowProgress = () => {
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
5438
|
+
if (workflowProgressClosed)
|
|
5439
|
+
return;
|
|
5440
|
+
if (activityTimer)
|
|
5441
|
+
clearTimeout(activityTimer);
|
|
5442
|
+
activityTimer = undefined;
|
|
5443
|
+
lastProgressAt = Date.now();
|
|
5444
|
+
const liveWorkflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: foregroundWorkflowRunId, workflowState: "running", inventoryComplete: false, trace: liveWorkflow.trace, progress: childProgress });
|
|
5445
|
+
onUpdate?.(workflowProgressUpdate(foregroundWorkflowRunId, chatProgress, liveWorkflow, liveWorkflowChildren, workflowPreflight));
|
|
4607
5446
|
};
|
|
4608
5447
|
try {
|
|
4609
5448
|
const workflow = await runWorkflowScript({
|
|
4610
5449
|
script: requestParams.workflowScript,
|
|
4611
|
-
...
|
|
4612
|
-
|
|
5450
|
+
...workflowArgs ? { args: workflowArgs } : {},
|
|
5451
|
+
workflowRunId: foregroundWorkflowRunId,
|
|
5452
|
+
processCwd: ctx.cwd,
|
|
5453
|
+
...delegatedWorkflowPermit ? { oneUsePermit: { claim: (key) => claimWorkflowChildPermit(delegatedWorkflowPermit, foregroundWorkflowRunId, key) } } : {},
|
|
5454
|
+
globalConcurrencyLimit: requestParams.globalConcurrencyLimit ?? deps.config.globalConcurrencyLimit,
|
|
4613
5455
|
timeoutMs: timeout,
|
|
4614
5456
|
signal,
|
|
4615
5457
|
...workflowState ? { state: workflowState } : {},
|
|
4616
|
-
|
|
5458
|
+
...workflowHost ? { host: workflowHost } : {},
|
|
4617
5459
|
onHostStep: (hostStep) => {
|
|
4618
5460
|
workflowHostSteps.set(hostStep.id, { ...hostStep, ...hostStep.freshness ? { freshness: { ...hostStep.freshness } } : {} });
|
|
4619
5461
|
},
|
|
@@ -4621,11 +5463,15 @@ export function createSubagentExecutor(deps) {
|
|
|
4621
5463
|
const projectedTrace = annotateWorkflowPreflightTrace(trace, workflowPreflight);
|
|
4622
5464
|
const preflightWarnings = workflowPreflightWarnings(workflowPreflight, trace);
|
|
4623
5465
|
liveWorkflow = { ...liveWorkflow, trace: projectedTrace, ...preflightWarnings.length ? { preflightWarnings } : {} };
|
|
4624
|
-
|
|
5466
|
+
for (const entry of trace) {
|
|
5467
|
+
if (entry.operation === "run" && ["completed", "failed", "stopped", "detached"].includes(entry.state))
|
|
5468
|
+
childProgress.delete(entry.key);
|
|
5469
|
+
}
|
|
4625
5470
|
sendWorkflowProgress();
|
|
4626
5471
|
},
|
|
4627
|
-
admit: (calls) => {
|
|
4628
|
-
|
|
5472
|
+
admit: async (calls, admissionSignal) => {
|
|
5473
|
+
await preflightWorkflowWorktrees({ workflowDefaults: workflowChildDefaults, defaultWorktree: deps.config.worktree, calls, ctxCwd: ctx.cwd, signal: admissionSignal, deadlineAt: workflowDeadlineAt });
|
|
5474
|
+
const outputClaims = workflowChildOutputClaims({ ctxCwd: ctx.cwd, workflowCwd, artifactsDir: workflowArtifactsDir, workflowRunId: foregroundWorkflowRunId, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, state: deps.state, claimedOutputPaths, entries: calls });
|
|
4629
5475
|
if (outputClaims.error)
|
|
4630
5476
|
throw new Error(outputClaims.error);
|
|
4631
5477
|
claimRunFanoutBatch(workflowFanoutBudget, calls.map(({ key }) => `workflow[${key}]`));
|
|
@@ -4656,7 +5502,7 @@ export function createSubagentExecutor(deps) {
|
|
|
4656
5502
|
return workflowChildResult(key, buildRequestedModeError(childParams, usageBudgetExceededMessage(budgetState)), childParams, deps.state, { state: "partial", reason: "budget_exhausted" });
|
|
4657
5503
|
const childPhase = typeof childParams.phase === "string" && childParams.phase.trim() ? childParams.phase.trim() : undefined;
|
|
4658
5504
|
const childLabel = typeof childParams.label === "string" && childParams.label.trim() ? childParams.label.trim() : undefined;
|
|
4659
|
-
recordMissionWorkflowChild(missionBinding,
|
|
5505
|
+
recordMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, {
|
|
4660
5506
|
status: "running",
|
|
4661
5507
|
...typeof childParams.agent === "string" && childParams.agent.trim() ? { agent: childParams.agent.trim() } : {},
|
|
4662
5508
|
...childLabel ? { label: childLabel } : {},
|
|
@@ -4664,9 +5510,11 @@ export function createSubagentExecutor(deps) {
|
|
|
4664
5510
|
heartbeat: { status: "running", ...childPhase ? { phase: childPhase } : {} }
|
|
4665
5511
|
});
|
|
4666
5512
|
let preparedChildParams;
|
|
4667
|
-
const result = await runMissionWorkflowChild(missionBinding,
|
|
4668
|
-
const childRequest = bindMissionWorkflowChildAsyncLaunch({ ...prepareWorkflowChildLaunchParams({ workflowDefaults: workflowChildDefaults, childParams, parentWorkflowRunId:
|
|
5513
|
+
const result = await runMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, childPhase, () => {
|
|
5514
|
+
const childRequest = bindMissionWorkflowChildAsyncLaunch({ ...prepareWorkflowChildLaunchParams({ workflowDefaults: workflowChildDefaults, childParams: delegatedWorkflowPermit ? { ...childParams, async: false } : childParams, parentWorkflowRunId: foregroundWorkflowRunId, workflowKey: key, ctxCwd: ctx.cwd, workflowCwd, artifactsDir: workflowArtifactsDir, aggregateOutputPath: workflowAggregateOutputPath, configuredOutputBaseDir, discoverAgents: discoverWorkflowAgents, agents: workflowAgents, workflowAgentScope: workflowChildDefaults.agentScope, outputOverride: childOutputOverrides.get(key), outputClaimPath: childOutputClaimPaths.get(key), options: { missionDetached: detachWorkflowChildMissions, suppressRoutineResultIntercom: chatProgress.mode === "live-card", runFanoutBudget: workflowFanoutBudget, parentDeadlineAt: workflowDeadlineAt, capabilityCeiling: workflowCapabilityCeiling } }), runFanoutAdmitted: admission.admitted }, missionBinding, deps.asyncByDefault, undefined, inheritedNestedRoute(deps)?.rootRunId);
|
|
4669
5515
|
preparedChildParams = childRequest;
|
|
5516
|
+
if (workflowUsageBudget.budget)
|
|
5517
|
+
workflowOwnedUsageBudgets.set(childRequest, workflowUsageBudget.budget);
|
|
4670
5518
|
if (delegatedWorkflowPermit) {
|
|
4671
5519
|
if (childRequest.async !== false)
|
|
4672
5520
|
throw new Error("Workflow child permit supports one foreground child only.");
|
|
@@ -4674,9 +5522,9 @@ export function createSubagentExecutor(deps) {
|
|
|
4674
5522
|
const childAgent = typeof childRequest.agent === "string" ? resolveAgentName(childRequest.agent, discoverWorkflowAgents(childCwd, resolveExecutionAgentScope(childRequest.agentScope)).agents).agent : undefined;
|
|
4675
5523
|
if (childAgent?.runner?.type === "external-cli" || childAgent?.runner?.type === "external-job")
|
|
4676
5524
|
throw new Error("Workflow child permit supports native DM children only.");
|
|
4677
|
-
workflowPermitContexts.set(childRequest, { child: { permit: delegatedWorkflowPermit, workflowRunId:
|
|
5525
|
+
workflowPermitContexts.set(childRequest, { child: { permit: delegatedWorkflowPermit, workflowRunId: foregroundWorkflowRunId, childKey: key } });
|
|
4678
5526
|
}
|
|
4679
|
-
workflowLaunchObservers.set(childRequest, (launch) => recordMissionWorkflowChild(missionBinding,
|
|
5527
|
+
workflowLaunchObservers.set(childRequest, (launch) => recordMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, {
|
|
4680
5528
|
status: "running",
|
|
4681
5529
|
agent: launch.agent,
|
|
4682
5530
|
...launch.sessionFile ? { sessionPath: launch.sessionFile } : {}
|
|
@@ -4685,8 +5533,21 @@ export function createSubagentExecutor(deps) {
|
|
|
4685
5533
|
const progress = update.details.progress?.[0];
|
|
4686
5534
|
if (!progress)
|
|
4687
5535
|
return;
|
|
5536
|
+
if (onUpdate && !workflowProgressClosed) {
|
|
5537
|
+
if (progress.status === "running")
|
|
5538
|
+
childProgress.set(key, workflowChildProgress(progress));
|
|
5539
|
+
else
|
|
5540
|
+
childProgress.delete(key);
|
|
5541
|
+
if (!activityTimer) {
|
|
5542
|
+
const delay = 100 - (Date.now() - lastProgressAt);
|
|
5543
|
+
if (delay <= 0)
|
|
5544
|
+
sendWorkflowProgress();
|
|
5545
|
+
else
|
|
5546
|
+
activityTimer = setTimeout(sendWorkflowProgress, delay);
|
|
5547
|
+
}
|
|
5548
|
+
}
|
|
4688
5549
|
const progressStatus = progress.status === "completed" ? "completed" : progress.status === "failed" ? "failed" : "running";
|
|
4689
|
-
recordMissionWorkflowChild(missionBinding,
|
|
5550
|
+
recordMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, {
|
|
4690
5551
|
status: progressStatus,
|
|
4691
5552
|
heartbeat: { status: progressStatus, ...childPhase ? { phase: childPhase } : {} }
|
|
4692
5553
|
});
|
|
@@ -4703,7 +5564,7 @@ export function createSubagentExecutor(deps) {
|
|
|
4703
5564
|
if (child.runId)
|
|
4704
5565
|
workflowChildRunIds.set(key, child.runId);
|
|
4705
5566
|
const childStatus = missionWorkflowChildStatus(result);
|
|
4706
|
-
recordMissionWorkflowChild(missionBinding,
|
|
5567
|
+
recordMissionWorkflowChild(missionBinding, foregroundWorkflowRunId, key, {
|
|
4707
5568
|
status: childStatus,
|
|
4708
5569
|
...child.runId ? { runId: child.runId } : {},
|
|
4709
5570
|
...result.details.results[0]?.agent ? { agent: result.details.results[0].agent } : {},
|
|
@@ -4715,17 +5576,18 @@ export function createSubagentExecutor(deps) {
|
|
|
4715
5576
|
return child;
|
|
4716
5577
|
},
|
|
4717
5578
|
status: async (keyOrRunId, workflowSignal) => workflowChildResult(keyOrRunId, await execute(randomUUID(), { action: "status", id: keyOrRunId }, workflowSignal, undefined, ctx, preserveActiveSession, workflowParentModel)),
|
|
4718
|
-
resolveResume: (reference) =>
|
|
4719
|
-
steer: (key, message, options, workflowSignal) => steerWorkflowChildByKey({ state: deps.state, workflowRunId:
|
|
5579
|
+
resolveResume: (reference, _signal, index) => resolveWorkflowResume(reference, deps, ctx.sessionManager.getSessionFile() ?? null, index),
|
|
5580
|
+
steer: (key, message, options, workflowSignal) => steerWorkflowChildByKey({ state: deps.state, workflowRunId: foregroundWorkflowRunId, key, message, options, signal: workflowSignal, resolveRunId: () => workflowChildRunIds.get(key) })
|
|
4720
5581
|
});
|
|
4721
5582
|
const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, workflow.trace, { settled: true });
|
|
4722
5583
|
const finalPreflightTrace = annotateWorkflowPreflightTrace(workflow.trace, workflowPreflight);
|
|
4723
|
-
const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId:
|
|
4724
|
-
const receipt = terminalWorkflowReceipt(
|
|
5584
|
+
const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: foregroundWorkflowRunId, workflowState: "completed", inventoryComplete: true, trace: workflow.trace, children: workflow.children });
|
|
5585
|
+
const receipt = terminalWorkflowReceipt(foregroundWorkflowRunId, "complete", workflow.children, workflowChildren, undefined, [...workflowHostSteps.values()], workflowResource?.provenance, workflowArgsDigest);
|
|
4725
5586
|
const traceLines = finalPreflightTrace.map((entry) => `- ${entry.operation} ${entry.key}: ${entry.state}${entry.runId ? ` (${entry.runId})` : ""}${entry.durationMs !== undefined ? ` in ${entry.durationMs}ms` : ""}${entry.warning ? ` — ${entry.warning}` : ""}${entry.error ? ` — ${entry.error}` : ""}`);
|
|
5587
|
+
const runningSummary = workflowRunningChildrenSummary(workflow.children);
|
|
4726
5588
|
const sections = [
|
|
4727
5589
|
...workflowPreflight ? [formatWorkflowPreflight(workflowPreflight)] : [],
|
|
4728
|
-
"Workflow completed.",
|
|
5590
|
+
runningSummary ? `Workflow dispatch completed; ${runningSummary}` : "Workflow completed.",
|
|
4729
5591
|
`Return:
|
|
4730
5592
|
${formatWorkflowValue(workflow.value)}`
|
|
4731
5593
|
];
|
|
@@ -4753,11 +5615,11 @@ ${traceLines.join(`
|
|
|
4753
5615
|
const displayText = appendWorkflowOutputWarning(workflowText, outputWarning);
|
|
4754
5616
|
return attachWorkflowMission(withRunFanoutBudget({
|
|
4755
5617
|
content: [{ type: "text", text: displayText }],
|
|
4756
|
-
details: compactOptional({ mode: "workflow", runId:
|
|
5618
|
+
details: compactOptional({ mode: "workflow", runId: foregroundWorkflowRunId, results: workflowDetailsResults(workflow.children), ...workflowPreflight ? { preflight: workflowPreflight } : {}, workflowChildren, totalChildUsage: sumResultsUsage(workflowResults), totalCost: sumResultsCost(workflowResults), usageBudget: usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}, receipt }, chatProgress })
|
|
4757
5619
|
}, workflowFanoutBudget));
|
|
4758
5620
|
} catch (error) {
|
|
4759
5621
|
const partial = error instanceof WorkflowScriptError ? error.partial : { trace: [], emits: [], console: [], children: [] };
|
|
4760
|
-
const text = workflowFailureMessage(error,
|
|
5622
|
+
const text = workflowFailureMessage(error, foregroundWorkflowRunId, partial.children);
|
|
4761
5623
|
const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, partial.trace, { settled: true });
|
|
4762
5624
|
const finalPreflightTrace = annotateWorkflowPreflightTrace(partial.trace, workflowPreflight);
|
|
4763
5625
|
const traceLines = finalPreflightTrace.map((entry) => `- ${entry.operation} ${entry.key}: ${entry.state}${entry.runId ? ` (${entry.runId})` : ""}${entry.warning ? ` — ${entry.warning}` : ""}${entry.error ? ` — ${entry.error}` : ""}`);
|
|
@@ -4787,20 +5649,35 @@ ${traceLines.join(`
|
|
|
4787
5649
|
`);
|
|
4788
5650
|
const outputWarning = writeWorkflowAggregateOutput(workflowAggregateOutputPath, workflowText, producedChildOutputPaths);
|
|
4789
5651
|
const displayText = appendWorkflowOutputWarning(workflowText, outputWarning);
|
|
4790
|
-
const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId:
|
|
5652
|
+
const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: foregroundWorkflowRunId, workflowState: "failed", inventoryComplete: true, trace: partial.trace, children: partial.children });
|
|
4791
5653
|
const terminalOutcome = workflowFailureTerminalOutcome(error, partial.children, usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)));
|
|
4792
|
-
const receipt = terminalWorkflowReceipt(
|
|
5654
|
+
const receipt = terminalWorkflowReceipt(foregroundWorkflowRunId, "failed", partial.children, workflowChildren, terminalOutcome, [...workflowHostSteps.values()], workflowResource?.provenance, workflowArgsDigest);
|
|
4793
5655
|
return attachWorkflowMission(withRunFanoutBudget({
|
|
4794
5656
|
content: [{ type: "text", text: displayText }],
|
|
4795
5657
|
isError: true,
|
|
4796
|
-
details: compactOptional({ mode: "workflow", runId:
|
|
5658
|
+
details: compactOptional({ mode: "workflow", runId: foregroundWorkflowRunId, results: workflowDetailsResults(partial.children), ...workflowPreflight ? { preflight: workflowPreflight } : {}, workflowChildren, totalChildUsage: sumResultsUsage(workflowResults), totalCost: sumResultsCost(workflowResults), usageBudget: usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...workflowArgsEvidence ?? {}, ...workflowResource ? { resource: workflowResource.provenance } : {}, ...finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}, receipt }, chatProgress })
|
|
4797
5659
|
}, workflowFanoutBudget));
|
|
5660
|
+
} finally {
|
|
5661
|
+
workflowProgressClosed = true;
|
|
5662
|
+
if (activityTimer)
|
|
5663
|
+
clearTimeout(activityTimer);
|
|
5664
|
+
childProgress.clear();
|
|
4798
5665
|
}
|
|
4799
5666
|
}
|
|
4800
5667
|
const directParams = requestParams;
|
|
4801
|
-
const
|
|
4802
|
-
|
|
4803
|
-
|
|
5668
|
+
const placedByAgent = () => {
|
|
5669
|
+
if (directParams.machine !== undefined || directParams.cwd === undefined || typeof directParams.agent !== "string")
|
|
5670
|
+
return false;
|
|
5671
|
+
try {
|
|
5672
|
+
return resolveAgentName(directParams.agent, deps.discoverAgents(ctx.cwd, resolveExecutionAgentScope(directParams.agentScope)).agents).agent?.machine !== undefined;
|
|
5673
|
+
} catch {
|
|
5674
|
+
return false;
|
|
5675
|
+
}
|
|
5676
|
+
};
|
|
5677
|
+
const remotePlacement = directParams.action === undefined && (directParams.machine !== undefined || placedByAgent());
|
|
5678
|
+
const requestedCwd = remotePlacement ? undefined : directParams.cwd;
|
|
5679
|
+
const requestCwd = remotePlacement ? ctx.cwd : resolveRequestedCwd(ctx.cwd, directParams.cwd);
|
|
5680
|
+
const paramsWithResolvedCwd = directParams.cwd === undefined ? directParams : remotePlacement ? omitUndefinedProperties({ ...directParams, cwd: undefined, machineCwd: directParams.cwd }) : { ...directParams, cwd: requestCwd };
|
|
4804
5681
|
const action = paramsWithResolvedCwd.action;
|
|
4805
5682
|
let requestSessionId = "";
|
|
4806
5683
|
let requestPiSessionId;
|
|
@@ -4865,7 +5742,8 @@ ${paramsWithResolvedCwd.handoffPath}`);
|
|
|
4865
5742
|
if (!confirmed)
|
|
4866
5743
|
return { content: [{ type: "text", text: "Worktree discard canceled; preserved worktrees were not changed." }], details: { mode: "management", results: [] } };
|
|
4867
5744
|
try {
|
|
4868
|
-
const
|
|
5745
|
+
const manifestPath = path.isAbsolute(paramsWithResolvedCwd.handoffPath) ? paramsWithResolvedCwd.handoffPath : path.resolve(requestCwd, paramsWithResolvedCwd.handoffPath);
|
|
5746
|
+
const discarded = await withWorktreeTransaction(() => discardPreservedWorktrees(manifestPath, { kind: decision === "confirm" ? "confirmed" : "policy", ...deps.config.authorityPolicy ? { policy: deps.config.authorityPolicy } : {} }));
|
|
4869
5747
|
return { content: [{ type: "text", text: discarded.text }], details: { mode: "management", results: [] } };
|
|
4870
5748
|
} catch (error) {
|
|
4871
5749
|
return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
|
|
@@ -4900,6 +5778,23 @@ ${paramsWithResolvedCwd.handoffPath}`);
|
|
|
4900
5778
|
return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
|
|
4901
5779
|
}
|
|
4902
5780
|
}
|
|
5781
|
+
const policyAction = action === "stop" ? "stopRun" : action === "steer" ? "steerRun" : action === "schedule.create" ? "scheduleCreate" : action === "inspector.open" ? "inspectorOpen" : action === "project.open" ? "projectOpen" : undefined;
|
|
5782
|
+
if (policyAction) {
|
|
5783
|
+
if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
|
|
5784
|
+
return { content: [{ type: "text", text: `Action '${action}' is not available from child-safe subagent fanout mode.` }], isError: true, details: { mode: "management", results: [] } };
|
|
5785
|
+
}
|
|
5786
|
+
const decision = resolveAuthorityDecision({ action: policyAction, ...deps.config.authorityPolicy === undefined ? {} : { policy: deps.config.authorityPolicy } });
|
|
5787
|
+
if (decision === "forbid") {
|
|
5788
|
+
return { content: [{ type: "text", text: `Authority policy forbids action '${action}'.` }], isError: true, details: { mode: "management", results: [] } };
|
|
5789
|
+
}
|
|
5790
|
+
if (decision === "confirm") {
|
|
5791
|
+
if (!ctx.hasUI)
|
|
5792
|
+
return { content: [{ type: "text", text: `Authority policy requires user confirmation for action '${action}', but this session has no interactive UI.` }], isError: true, details: { mode: "management", results: [] } };
|
|
5793
|
+
const confirmed = await ctx.ui.confirm(`Authorize subagent ${action}?`, `Authority policy requires confirmation before '${action}'.`);
|
|
5794
|
+
if (!confirmed)
|
|
5795
|
+
return { content: [{ type: "text", text: `Action '${action}' canceled; authority was not granted.` }], details: { mode: "management", results: [] } };
|
|
5796
|
+
}
|
|
5797
|
+
}
|
|
4903
5798
|
if (HERDR_PROJECT_PANE_ACTIONS.includes(action)) {
|
|
4904
5799
|
if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
|
|
4905
5800
|
return { content: [{ type: "text", text: `Action '${action}' is not available from child-safe subagent fanout mode.` }], isError: true, details: { mode: "management", results: [] } };
|
|
@@ -4907,16 +5802,17 @@ ${paramsWithResolvedCwd.handoffPath}`);
|
|
|
4907
5802
|
deps.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
|
|
4908
5803
|
return handleHerdrProjectPaneAction(action, paramsWithResolvedCwd, { cwd: requestCwd, state: deps.state, signal });
|
|
4909
5804
|
}
|
|
4910
|
-
if (
|
|
5805
|
+
if (INSPECTOR_ACTIONS.includes(action)) {
|
|
4911
5806
|
if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
|
|
4912
5807
|
return { content: [{ type: "text", text: `Action '${action}' is not available from child-safe subagent fanout mode.` }], isError: true, details: { mode: "management", results: [] } };
|
|
4913
5808
|
}
|
|
4914
5809
|
deps.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
|
|
4915
|
-
return
|
|
5810
|
+
return handleInspectorAction(action, paramsWithResolvedCwd, {
|
|
4916
5811
|
state: deps.state,
|
|
4917
5812
|
cwd: requestCwd,
|
|
4918
5813
|
...deps.config.missions ? { missions: deps.config.missions } : {},
|
|
4919
5814
|
...deps.config.authorityPolicy ? { authorityPolicy: deps.config.authorityPolicy } : {},
|
|
5815
|
+
plugins: createBuiltinInspectorPlugins(),
|
|
4920
5816
|
signal
|
|
4921
5817
|
});
|
|
4922
5818
|
}
|
|
@@ -4935,20 +5831,6 @@ ${paramsWithResolvedCwd.handoffPath}`);
|
|
|
4935
5831
|
...currentSessionId ? { currentSessionId } : {}
|
|
4936
5832
|
});
|
|
4937
5833
|
}
|
|
4938
|
-
const policyAction = action === "stop" ? "stopRun" : action === "steer" ? "steerRun" : action === "schedule.create" ? "scheduleCreate" : undefined;
|
|
4939
|
-
if (policyAction) {
|
|
4940
|
-
const decision = resolveAuthorityDecision({ action: policyAction, ...deps.config.authorityPolicy === undefined ? {} : { policy: deps.config.authorityPolicy } });
|
|
4941
|
-
if (decision === "forbid") {
|
|
4942
|
-
return { content: [{ type: "text", text: `Authority policy forbids action '${action}'.` }], isError: true, details: { mode: "management", results: [] } };
|
|
4943
|
-
}
|
|
4944
|
-
if (decision === "confirm") {
|
|
4945
|
-
if (!ctx.hasUI)
|
|
4946
|
-
return { content: [{ type: "text", text: `Authority policy requires user confirmation for action '${action}', but this session has no interactive UI.` }], isError: true, details: { mode: "management", results: [] } };
|
|
4947
|
-
const confirmed = await ctx.ui.confirm(`Authorize subagent ${action}?`, `Authority policy requires confirmation before '${action}'.`);
|
|
4948
|
-
if (!confirmed)
|
|
4949
|
-
return { content: [{ type: "text", text: `Action '${action}' canceled; authority was not granted.` }], details: { mode: "management", results: [] } };
|
|
4950
|
-
}
|
|
4951
|
-
}
|
|
4952
5834
|
if (WATCHDOG_TOOL_ACTIONS.includes(action)) {
|
|
4953
5835
|
if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
|
|
4954
5836
|
return {
|
|
@@ -5084,7 +5966,7 @@ Usage is not reset. Compaction keeps the same budget; a new parent session start
|
|
|
5084
5966
|
}
|
|
5085
5967
|
let orchestratorTarget;
|
|
5086
5968
|
try {
|
|
5087
|
-
orchestratorTarget = resolveIntercomSessionTarget(deps.dm.getSessionName(), ctx.sessionManager.getSessionId());
|
|
5969
|
+
orchestratorTarget = resolveIntercomSessionTarget(deps.childRuntime?.intercomSessionName ?? deps.dm.getSessionName(), ctx.sessionManager.getSessionId());
|
|
5088
5970
|
} catch (error) {
|
|
5089
5971
|
if (!sessionError)
|
|
5090
5972
|
sessionError = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
@@ -5136,7 +6018,7 @@ ${item.text}` } : item)
|
|
|
5136
6018
|
}
|
|
5137
6019
|
return withBudget(inspectSubagentStatus(paramsWithResolvedCwd, omitUndefinedProperties({ state: deps.state, nested: nestedScope, sessionRoots, abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps.config.capacity?.abandonedSlotReleaseAfterMs) })));
|
|
5138
6020
|
}
|
|
5139
|
-
if (paramsWithResolvedCwd.view === "fleet") {
|
|
6021
|
+
if (paramsWithResolvedCwd.view === "fleet" || paramsWithResolvedCwd.view === "transcript") {
|
|
5140
6022
|
return withBudget(inspectSubagentStatus(paramsWithResolvedCwd, omitUndefinedProperties({ state: deps.state, nested: nestedScope, sessionRoots, abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps.config.capacity?.abandonedSlotReleaseAfterMs) })));
|
|
5141
6023
|
}
|
|
5142
6024
|
if (targetRunId) {
|
|
@@ -5145,12 +6027,6 @@ ${item.text}` } : item)
|
|
|
5145
6027
|
if (resolved?.kind === "foreground") {
|
|
5146
6028
|
const foreground = getForegroundControl(deps.state, resolved.id);
|
|
5147
6029
|
if (foreground) {
|
|
5148
|
-
if (paramsWithResolvedCwd.view === "transcript") {
|
|
5149
|
-
return withBudget({
|
|
5150
|
-
content: [{ type: "text", text: "Live foreground transcript is already visible in the expanded running subagent result. Persisted session transcript becomes inspectable after the foreground run completes when sessions are enabled." }],
|
|
5151
|
-
details: { mode: "management", results: [] }
|
|
5152
|
-
});
|
|
5153
|
-
}
|
|
5154
6030
|
return withBudget(foregroundStatusResult(foreground));
|
|
5155
6031
|
}
|
|
5156
6032
|
}
|
|
@@ -5160,19 +6036,24 @@ ${item.text}` } : item)
|
|
|
5160
6036
|
}
|
|
5161
6037
|
} else if (!hasDirectoryTarget) {
|
|
5162
6038
|
const foreground = getForegroundControl(deps.state, undefined);
|
|
5163
|
-
if (foreground
|
|
6039
|
+
if (foreground)
|
|
5164
6040
|
return withBudget(foregroundStatusResult(foreground));
|
|
5165
|
-
if (foreground && paramsWithResolvedCwd.view === "transcript") {
|
|
5166
|
-
return withBudget({
|
|
5167
|
-
content: [{ type: "text", text: "Live foreground transcript is already visible in the expanded running subagent result. Pass an async run id to inspect a background transcript." }],
|
|
5168
|
-
details: { mode: "management", results: [] }
|
|
5169
|
-
});
|
|
5170
|
-
}
|
|
5171
6041
|
}
|
|
5172
6042
|
return withBudget(inspectSubagentStatus(paramsWithResolvedCwd, omitUndefinedProperties({ state: deps.state, nested: nestedScope, sessionRoots, abandonedSlotReleaseAfterMs: resolveAbandonedSlotReleaseAfterMs(deps.config.capacity?.abandonedSlotReleaseAfterMs) })));
|
|
5173
6043
|
}
|
|
5174
6044
|
if (action === "resume") {
|
|
5175
|
-
return resumeAsyncRun(omitUndefinedProperties({
|
|
6045
|
+
return resumeAsyncRun(omitUndefinedProperties({
|
|
6046
|
+
params: paramsWithResolvedCwd,
|
|
6047
|
+
requestCwd,
|
|
6048
|
+
ctx,
|
|
6049
|
+
deps,
|
|
6050
|
+
parentModel: requestParentModel,
|
|
6051
|
+
signal,
|
|
6052
|
+
...workflowLaunchObserver ? { onLaunch: (launch) => {
|
|
6053
|
+
workflowLaunchObservers.delete(params);
|
|
6054
|
+
workflowLaunchObserver(launch);
|
|
6055
|
+
} } : {}
|
|
6056
|
+
}));
|
|
5176
6057
|
}
|
|
5177
6058
|
if (action === "steer") {
|
|
5178
6059
|
if (paramsWithResolvedCwd.mode !== undefined && resolveSteerDeliveryMode(paramsWithResolvedCwd.mode) === undefined) {
|
|
@@ -5189,10 +6070,7 @@ ${item.text}` } : item)
|
|
|
5189
6070
|
const runId = location.resolvedId ?? targetRunId ?? path.basename(location.asyncDir ?? paramsWithResolvedCwd.dir);
|
|
5190
6071
|
const directoryStatus = location.asyncDir ? readStatus(location.asyncDir) : null;
|
|
5191
6072
|
if (directoryStatus?.mode === "workflow") {
|
|
5192
|
-
|
|
5193
|
-
if (!route.ok)
|
|
5194
|
-
return { content: [{ type: "text", text: route.message }], isError: true, details: { mode: "management", results: [] } };
|
|
5195
|
-
return steerWorkflowForegroundTarget({ target: route.target, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
|
|
6073
|
+
return steerWorkflowRun({ state: deps.state, runId, asyncDir: location.asyncDir, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
|
|
5196
6074
|
}
|
|
5197
6075
|
if (location.asyncDir) {
|
|
5198
6076
|
const unsupported = externalRunnerControlError(location.asyncDir, "steer");
|
|
@@ -5201,6 +6079,7 @@ ${item.text}` } : item)
|
|
|
5201
6079
|
}
|
|
5202
6080
|
return steerAsyncRun(compactOptional({
|
|
5203
6081
|
state: deps.state,
|
|
6082
|
+
findPendingAsks: deps.findPendingAsks,
|
|
5204
6083
|
runId,
|
|
5205
6084
|
message,
|
|
5206
6085
|
mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode),
|
|
@@ -5232,16 +6111,13 @@ ${item.text}` } : item)
|
|
|
5232
6111
|
const route = resolveWorkflowForegroundSteeringTarget({ state: deps.state, childRunId: resolved.id, asyncDirRoot: DIRS.async });
|
|
5233
6112
|
if (!route.ok)
|
|
5234
6113
|
return { content: [{ type: "text", text: route.message }], isError: true, details: { mode: "management", results: [] } };
|
|
5235
|
-
return steerWorkflowForegroundTarget({ target: route.target, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index
|
|
6114
|
+
return steerWorkflowForegroundTarget({ target: route.target, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index });
|
|
5236
6115
|
}
|
|
5237
6116
|
if (resolved?.kind !== "async")
|
|
5238
6117
|
return { content: [{ type: "text", text: `No async run found for '${targetRunId}'.` }], isError: true, details: { mode: "management", results: [] } };
|
|
5239
6118
|
const resolvedStatus = resolved.location.asyncDir ? readStatus(resolved.location.asyncDir) : null;
|
|
5240
6119
|
if (resolvedStatus?.mode === "workflow") {
|
|
5241
|
-
|
|
5242
|
-
if (!route.ok)
|
|
5243
|
-
return { content: [{ type: "text", text: route.message }], isError: true, details: { mode: "management", results: [] } };
|
|
5244
|
-
return steerWorkflowForegroundTarget({ target: route.target, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
|
|
6120
|
+
return steerWorkflowRun({ state: deps.state, runId: resolved.id, asyncDir: resolved.location.asyncDir, message, mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode), index: paramsWithResolvedCwd.index, signal });
|
|
5245
6121
|
}
|
|
5246
6122
|
if (resolved.location.asyncDir) {
|
|
5247
6123
|
const unsupported = externalRunnerControlError(resolved.location.asyncDir, "steer");
|
|
@@ -5250,6 +6126,7 @@ ${item.text}` } : item)
|
|
|
5250
6126
|
}
|
|
5251
6127
|
return steerAsyncRun(compactOptional({
|
|
5252
6128
|
state: deps.state,
|
|
6129
|
+
findPendingAsks: deps.findPendingAsks,
|
|
5253
6130
|
runId: resolved.id,
|
|
5254
6131
|
message,
|
|
5255
6132
|
mode: resolveSteerDeliveryMode(paramsWithResolvedCwd.mode),
|
|
@@ -5318,7 +6195,8 @@ ${item.text}` } : item)
|
|
|
5318
6195
|
if (action === "stop") {
|
|
5319
6196
|
const targetRunId = paramsWithResolvedCwd.runId ?? paramsWithResolvedCwd.id;
|
|
5320
6197
|
const workflowController = targetRunId ? deps.state.workflowControllers?.get(targetRunId) : undefined;
|
|
5321
|
-
if (workflowController) {
|
|
6198
|
+
if (workflowController && targetRunId) {
|
|
6199
|
+
const stopChild = deps.state.workflowChildStops?.get(targetRunId);
|
|
5322
6200
|
if (paramsWithResolvedCwd.childId !== undefined) {
|
|
5323
6201
|
const workflowRunId = targetRunId;
|
|
5324
6202
|
const asyncJob = deps.state.asyncJobs.get(workflowRunId);
|
|
@@ -5332,7 +6210,6 @@ ${item.text}` } : item)
|
|
|
5332
6210
|
return { content: [{ type: "text", text: resolution.message }], isError: true, details: { mode: "management", results: [] } };
|
|
5333
6211
|
if (!isStoppableAsyncStatusStep(resolution.child.step))
|
|
5334
6212
|
return { content: [{ type: "text", text: `Child '${paramsWithResolvedCwd.childId}' in async run '${targetRunId}' is ${resolution.child.step.status}; stop only supports pending or running children.` }], isError: true, details: { mode: "management", results: [] } };
|
|
5335
|
-
const stopChild = deps.state.workflowChildStops?.get(targetRunId);
|
|
5336
6213
|
if (!stopChild)
|
|
5337
6214
|
return { content: [{ type: "text", text: `Workflow ${targetRunId} child stop is unavailable in this extension runtime.` }], isError: true, details: { mode: "management", results: [] } };
|
|
5338
6215
|
if (!stopChild(resolution.child.id, `Workflow child '${resolution.child.id}' stopped.`))
|
|
@@ -5360,6 +6237,10 @@ ${item.text}` } : item)
|
|
|
5360
6237
|
}
|
|
5361
6238
|
return { content: [{ type: "text", text: `Stop requested for child ${resolution.child.id} in async workflow ${workflowRunId}.` }], details: { mode: "management", results: [] } };
|
|
5362
6239
|
}
|
|
6240
|
+
const asyncJob = deps.state.asyncJobs.get(targetRunId);
|
|
6241
|
+
const status = asyncJob?.asyncDir ? readStatus(asyncJob.asyncDir) : undefined;
|
|
6242
|
+
if (status)
|
|
6243
|
+
stopStoppableAsyncStatusChildren(status, stopChild, "Workflow stopped.");
|
|
5363
6244
|
workflowController.abort(new Error("Workflow stopped."));
|
|
5364
6245
|
return { content: [{ type: "text", text: `Stop requested for async workflow ${targetRunId}.` }], details: { mode: "management", results: [] } };
|
|
5365
6246
|
}
|
|
@@ -5446,10 +6327,12 @@ ${item.text}` } : item)
|
|
|
5446
6327
|
cwd: requestCwd,
|
|
5447
6328
|
config: deps.config,
|
|
5448
6329
|
currentSessionId: deps.state.currentSessionId ?? ctx.sessionManager.getSessionId() ?? undefined,
|
|
5449
|
-
|
|
6330
|
+
discoverAgentsAll: deps.discoverAgentsAll,
|
|
6331
|
+
runtimeAgentOwner: deps.dm,
|
|
6332
|
+
onAgentsChanged: deps.onAgentsChanged
|
|
5450
6333
|
});
|
|
5451
6334
|
}
|
|
5452
|
-
const { blocked, depth, maxDepth } = checkSubagentDepth(deps.config.maxSubagentDepth);
|
|
6335
|
+
const { blocked, depth, maxDepth } = checkSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime);
|
|
5453
6336
|
if (blocked) {
|
|
5454
6337
|
return {
|
|
5455
6338
|
content: [
|
|
@@ -5466,6 +6349,9 @@ ${item.text}` } : item)
|
|
|
5466
6349
|
if (normalized.error)
|
|
5467
6350
|
return normalized.error;
|
|
5468
6351
|
const normalizedParams = normalized.params;
|
|
6352
|
+
const outputSchemaError = validateLaunchOutputSchemaOverrides(normalizedParams);
|
|
6353
|
+
if (outputSchemaError)
|
|
6354
|
+
return buildRequestedModeError(normalizedParams, outputSchemaError);
|
|
5469
6355
|
let effectiveParams = applyForceTopLevelAsyncOverride(normalizedParams, depth, deps.config.forceTopLevelAsync === true);
|
|
5470
6356
|
const runToolBudget = resolveToolBudget(effectiveParams.toolBudget, "toolBudget", allowZeroToolBudget ? { minimumHard: 0 } : undefined);
|
|
5471
6357
|
if (runToolBudget.error)
|
|
@@ -5486,14 +6372,20 @@ ${item.text}` } : item)
|
|
|
5486
6372
|
if (canonicalParams.error)
|
|
5487
6373
|
return buildRequestedModeError(effectiveParams, canonicalParams.error);
|
|
5488
6374
|
effectiveParams = canonicalParams.params;
|
|
6375
|
+
if (effectiveParams.worktree === undefined && deps.config.worktree !== undefined) {
|
|
6376
|
+
effectiveParams = { ...effectiveParams, worktree: deps.config.worktree };
|
|
6377
|
+
}
|
|
5489
6378
|
const modelScope = discovered.modelScope;
|
|
5490
6379
|
effectiveParams = applySingleAgentLaunchDefaults(effectiveParams, discoveredAgents);
|
|
6380
|
+
const typedVerifyConflict = describeTypedVerifyOutputSchemaConflict(effectiveParams, params);
|
|
6381
|
+
if (typedVerifyConflict)
|
|
6382
|
+
return buildRequestedModeError(effectiveParams, typedVerifyConflict);
|
|
5491
6383
|
const contextPolicyResult = resolveAgentDefaultContextPolicy(effectiveParams, discoveredAgents, deps.config.defaultSubagentContext, canPreferFork(ctx.sessionManager));
|
|
5492
6384
|
if ("error" in contextPolicyResult)
|
|
5493
6385
|
return buildRequestedModeError(effectiveParams, contextPolicyResult.error);
|
|
5494
6386
|
const contextPolicy = contextPolicyResult;
|
|
5495
6387
|
effectiveParams = contextPolicy.params;
|
|
5496
|
-
const sessionName = resolveIntercomSessionTarget(deps.dm.getSessionName(), ctx.sessionManager.getSessionId());
|
|
6388
|
+
const sessionName = resolveIntercomSessionTarget(deps.childRuntime?.intercomSessionName ?? deps.dm.getSessionName(), ctx.sessionManager.getSessionId());
|
|
5497
6389
|
const intercomBridge = resolveIntercomBridge({
|
|
5498
6390
|
config: deps.config.intercomBridge,
|
|
5499
6391
|
override: effectiveParams.intercomBridge,
|
|
@@ -5501,9 +6393,8 @@ ${item.text}` } : item)
|
|
|
5501
6393
|
orchestratorTarget: sessionName
|
|
5502
6394
|
});
|
|
5503
6395
|
const agents = applyScopedIntercomBridgeToAgents(discoveredAgents, intercomBridge, contextPolicy);
|
|
5504
|
-
const
|
|
5505
|
-
const
|
|
5506
|
-
const nestedParentAddress = inheritedNestedRoute ? resolveNestedParentAddressFromEnv() : undefined;
|
|
6396
|
+
const inheritedNestedRouteValue = inheritedNestedRoute(deps);
|
|
6397
|
+
const nestedParentAddress = inheritedNestedRouteValue ? inheritedNestedParentAddress(deps) : undefined;
|
|
5507
6398
|
const shareEnabled = effectiveParams.share === true;
|
|
5508
6399
|
const hasChain = (effectiveParams.chain?.length ?? 0) > 0;
|
|
5509
6400
|
const hasTasks = (effectiveParams.tasks?.length ?? 0) > 0;
|
|
@@ -5521,33 +6412,11 @@ ${item.text}` } : item)
|
|
|
5521
6412
|
return;
|
|
5522
6413
|
};
|
|
5523
6414
|
let prepareForkSessionForIndex = async () => {};
|
|
5524
|
-
let forkThinkingOverrideForIndex = () => {
|
|
5525
|
-
return;
|
|
5526
|
-
};
|
|
5527
|
-
let prepareForkThinking = (_agentName, _index, _modelOverride, _modelOverrideFromParent) => {};
|
|
5528
|
-
const forkThinkingRequirements = new Map;
|
|
5529
|
-
const forkThinkingDowngrades = new Map;
|
|
5530
6415
|
try {
|
|
5531
|
-
const forkAvailableModels = contextPolicy.usesFork ? ctx.modelRegistry.getAvailable().map(toModelInfo) : [];
|
|
5532
|
-
const parentModel = requestParentModel;
|
|
5533
|
-
prepareForkThinking = (agentName, index, modelOverride, modelOverrideFromParent) => {
|
|
5534
|
-
const agentConfig = agents.find((agent) => agent.name === agentName);
|
|
5535
|
-
if (agentConfig?.runner?.type === "external-cli" || agentConfig?.runner?.type === "external-job") {
|
|
5536
|
-
forkThinkingRequirements.set(index, true);
|
|
5537
|
-
return;
|
|
5538
|
-
}
|
|
5539
|
-
const primaryModel = modelOverrideFromParent ? modelOverride : resolveEffectiveSubagentModel(modelOverride, agentConfig?.model, parentModel, forkAvailableModels, agentConfig?.modelProvider ?? parentModel?.provider, { source: "inherited" });
|
|
5540
|
-
const candidates = buildModelCandidates(primaryModel, agentConfig?.fallbackModels, forkAvailableModels, agentConfig?.modelProvider ?? parentModel?.provider, { primaryModelFromParent: modelOverrideFromParent ?? inheritsParentModel(modelOverride, agentConfig?.model, parentModel) });
|
|
5541
|
-
forkThinkingRequirements.set(index, candidates.length === 0 || candidates.some((candidate) => forkedChildRequiresThinkingOff(candidate, forkAvailableModels, parentModel?.provider)));
|
|
5542
|
-
};
|
|
5543
6416
|
const pruneSession = contextPolicy.usesFork && deps.config.forkContext?.mode === "pruned" ? await createPrunedForkSessionWriter(ctx, deps.config.forkContext, signal) : undefined;
|
|
5544
|
-
const forkContextResolver = createForkContextResolver(ctx.sessionManager, contextPolicy.usesFork ? "fork" : undefined, {
|
|
5545
|
-
forceThinkingOffForIndex: (index) => forkThinkingRequirements.get(index) ?? true,
|
|
5546
|
-
...pruneSession ? { pruneSession } : {}
|
|
5547
|
-
});
|
|
6417
|
+
const forkContextResolver = createForkContextResolver(ctx.sessionManager, contextPolicy.usesFork ? "fork" : undefined, pruneSession ? { pruneSession } : {});
|
|
5548
6418
|
prepareForkSessionForIndex = forkContextResolver.prepareSessionForIndex;
|
|
5549
6419
|
forkSessionFileForIndex = forkContextResolver.sessionFileForIndex;
|
|
5550
|
-
forkThinkingOverrideForIndex = forkContextResolver.thinkingOverrideForIndex;
|
|
5551
6420
|
} catch (error) {
|
|
5552
6421
|
return toExecutionErrorResult(effectiveParams, error, contextPolicy.contextSummary);
|
|
5553
6422
|
}
|
|
@@ -5560,13 +6429,21 @@ ${item.text}` } : item)
|
|
|
5560
6429
|
if (externalAgent && (!effectiveAsync || effectiveParams.foregroundOnly === true)) {
|
|
5561
6430
|
return buildRequestedModeError(effectiveParams, `Agent '${externalAgent.name}' uses runner.type='${externalAgent.runner?.type}', which currently supports async/background execution only. Omit async or pass async:true; clarify and foregroundOnly are unsupported.`);
|
|
5562
6431
|
}
|
|
6432
|
+
if (effectiveAsync && hasSingle && effectiveParams.resume === undefined && effectiveParams.worktree === true) {
|
|
6433
|
+
try {
|
|
6434
|
+
await preflightWorktreeSource(effectiveCwd, { signal });
|
|
6435
|
+
} catch (error) {
|
|
6436
|
+
return toExecutionErrorResult(effectiveParams, error, contextPolicy.contextSummary);
|
|
6437
|
+
}
|
|
6438
|
+
}
|
|
6439
|
+
const runId = randomUUID();
|
|
5563
6440
|
const foregroundTimeout = resolveSingleAgentLaunchTimeout(effectiveParams, effectiveAsync, resolveConfigDefaultTimeoutMs(deps.config.timeoutMs));
|
|
5564
6441
|
if (foregroundTimeout.error)
|
|
5565
6442
|
return buildRequestedModeError(effectiveParams, foregroundTimeout.error);
|
|
5566
6443
|
const controlConfig = resolveControlConfig(deps.config.control, effectiveParams.control);
|
|
5567
6444
|
const requestedWorkflowChildAsyncId = typeof effectiveParams.workflowChildAsyncId === "string" ? effectiveParams.workflowChildAsyncId.trim() : "";
|
|
5568
6445
|
const asyncRunId = requestedWorkflowChildAsyncId && path.basename(requestedWorkflowChildAsyncId) === requestedWorkflowChildAsyncId ? requestedWorkflowChildAsyncId : randomUUID();
|
|
5569
|
-
const topLevelAsyncCapacityEligible = depth === 0 && !
|
|
6446
|
+
const topLevelAsyncCapacityEligible = depth === 0 && !inheritedNestedRouteValue && !effectiveParams.workflowParentRunId;
|
|
5570
6447
|
const topLevelAsync = effectiveAsync && topLevelAsyncCapacityEligible;
|
|
5571
6448
|
let activeAsyncCapacity;
|
|
5572
6449
|
if (topLevelAsync) {
|
|
@@ -5590,8 +6467,8 @@ ${item.text}` } : item)
|
|
|
5590
6467
|
}
|
|
5591
6468
|
let runFanoutBudget;
|
|
5592
6469
|
try {
|
|
5593
|
-
const
|
|
5594
|
-
runFanoutBudget = effectiveParams.runFanoutBudget ?? (
|
|
6470
|
+
const inheritedRunFanoutBudgetValue = effectiveParams.runFanoutBudget ? undefined : inheritedRunFanoutBudget(deps);
|
|
6471
|
+
runFanoutBudget = effectiveParams.runFanoutBudget ?? (inheritedRunFanoutBudgetValue ? { ...inheritedRunFanoutBudgetValue, parentPath: `${inheritedRunFanoutBudgetValue.parentPath ? `${inheritedRunFanoutBudgetValue.parentPath}/` : ""}${runId}` } : undefined) ?? createRunFanoutBudget(runId, resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun));
|
|
5595
6472
|
if (!effectiveParams.runFanoutAdmitted)
|
|
5596
6473
|
claimRunFanoutBatch(runFanoutBudget, staticRunFanoutPaths(effectiveParams));
|
|
5597
6474
|
} catch (error) {
|
|
@@ -5600,7 +6477,7 @@ ${item.text}` } : item)
|
|
|
5600
6477
|
return runFanoutErrorResult(error, foregroundMode);
|
|
5601
6478
|
return buildRequestedModeError(effectiveParams, error instanceof Error ? error.message : String(error));
|
|
5602
6479
|
}
|
|
5603
|
-
const nestedRoute =
|
|
6480
|
+
const nestedRoute = inheritedNestedRouteValue ?? createNestedRoute(runId);
|
|
5604
6481
|
const artifactConfig = omitUndefinedProperties({
|
|
5605
6482
|
...DEFAULT_ARTIFACT_CONFIG,
|
|
5606
6483
|
enabled: effectiveParams.artifacts !== false,
|
|
@@ -5615,7 +6492,7 @@ ${item.text}` } : item)
|
|
|
5615
6492
|
}
|
|
5616
6493
|
let sessionRoot;
|
|
5617
6494
|
if (effectiveParams.sessionDir) {
|
|
5618
|
-
sessionRoot = path.resolve(deps.expandTilde(effectiveParams.sessionDir));
|
|
6495
|
+
sessionRoot = path.join(path.resolve(deps.expandTilde(effectiveParams.sessionDir)), runId);
|
|
5619
6496
|
} else {
|
|
5620
6497
|
const baseSessionRoot = deps.config.defaultSessionDir ? path.resolve(deps.expandTilde(deps.config.defaultSessionDir)) : deps.getSubagentSessionRoot(parentSessionFile);
|
|
5621
6498
|
sessionRoot = path.join(baseSessionRoot, runId);
|
|
@@ -5628,28 +6505,18 @@ ${item.text}` } : item)
|
|
|
5628
6505
|
return toExecutionErrorResult(effectiveParams, new Error(`Failed to create session directory '${sessionRoot}': ${message}`), contextPolicy.contextSummary);
|
|
5629
6506
|
}
|
|
5630
6507
|
const sessionDirForIndex = (idx) => path.join(sessionRoot, `run-${idx ?? 0}`);
|
|
5631
|
-
const forkSessionFileForTask = (agentName, idx = 0
|
|
6508
|
+
const forkSessionFileForTask = (agentName, idx = 0) => {
|
|
5632
6509
|
if (!shouldForkAgent(contextPolicy, agentName))
|
|
5633
6510
|
return;
|
|
5634
|
-
prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent);
|
|
5635
6511
|
return forkSessionFileForIndex(idx);
|
|
5636
6512
|
};
|
|
5637
|
-
const prepareForkSessionForTask = async (agentName, idx = 0
|
|
6513
|
+
const prepareForkSessionForTask = async (agentName, idx = 0) => {
|
|
5638
6514
|
if (!shouldForkAgent(contextPolicy, agentName))
|
|
5639
6515
|
return;
|
|
5640
|
-
prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent);
|
|
5641
6516
|
await prepareForkSessionForIndex(idx);
|
|
5642
6517
|
};
|
|
5643
|
-
const
|
|
5644
|
-
|
|
5645
|
-
return delegatedThinkingOverride;
|
|
5646
|
-
prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent);
|
|
5647
|
-
const override = forkThinkingOverrideForIndex(idx);
|
|
5648
|
-
if (override === "off")
|
|
5649
|
-
forkThinkingDowngrades.set(idx, agentName);
|
|
5650
|
-
return override ?? delegatedThinkingOverride;
|
|
5651
|
-
};
|
|
5652
|
-
const childSessionFileForTask = (agentName, idx, modelOverride, modelOverrideFromParent) => forkSessionFileForTask(agentName, idx, modelOverride, modelOverrideFromParent) ?? path.join(sessionDirForIndex(idx), "session.jsonl");
|
|
6518
|
+
const thinkingOverrideForTask = () => delegatedThinkingOverride;
|
|
6519
|
+
const childSessionFileForTask = (agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) => forkSessionFileForTask(agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) ?? path.join(sessionDirForIndex(idx), "session.jsonl");
|
|
5653
6520
|
const childSessionFileForIndex = (idx) => path.join(sessionDirForIndex(idx), "session.jsonl");
|
|
5654
6521
|
try {
|
|
5655
6522
|
if (!(effectiveParams.clarify === true && ctx.hasUI) || deps.config.forkContext?.mode === "pruned") {
|
|
@@ -5724,18 +6591,20 @@ ${item.text}` } : item)
|
|
|
5724
6591
|
sessionDirForIndex,
|
|
5725
6592
|
sessionFileForIndex: childSessionFileForIndex,
|
|
5726
6593
|
sessionFileForTask: childSessionFileForTask,
|
|
5727
|
-
thinkingOverrideForTask
|
|
6594
|
+
thinkingOverrideForTask,
|
|
5728
6595
|
artifactConfig,
|
|
5729
6596
|
artifactsDir,
|
|
5730
6597
|
backgroundRequestedWhileClarifying,
|
|
5731
6598
|
effectiveAsync,
|
|
5732
6599
|
asyncRunId,
|
|
5733
6600
|
controlConfig,
|
|
6601
|
+
...delegatedExecution ? { suppressUnchangedDelegationUpdates: true } : {},
|
|
5734
6602
|
intercomBridge,
|
|
5735
6603
|
nestedRoute,
|
|
5736
6604
|
timeoutMs: foregroundTimeout.timeoutMs,
|
|
5737
6605
|
toolBudget: runToolBudget.toolBudget,
|
|
5738
6606
|
usageBudget: usageBudget.budget,
|
|
6607
|
+
inheritedUsageBudget,
|
|
5739
6608
|
allowZeroToolBudget,
|
|
5740
6609
|
configToolBudget: configToolBudget.toolBudget,
|
|
5741
6610
|
configToolTimeoutMs: deps.config.toolTimeoutMs,
|
|
@@ -5751,15 +6620,12 @@ ${item.text}` } : item)
|
|
|
5751
6620
|
workflowChildPermitLaunch
|
|
5752
6621
|
});
|
|
5753
6622
|
const foregroundDescription = selectedAgentNames.length === 1 ? `${selectedAgentNames[0]} child` : `${selectedAgentNames.length} live children`;
|
|
5754
|
-
const parentWorkflowStatus = effectiveParams.workflowParentRunId ? readStatus(path.join(DIRS.async, effectiveParams.workflowParentRunId)) : null;
|
|
5755
|
-
const workflowSteeringDir = effectiveParams.workflowParentRunId && requestSessionId && deps.state.workflowControllers?.has(effectiveParams.workflowParentRunId) && parentWorkflowStatus?.mode === "workflow" && (parentWorkflowStatus.state === "running" || parentWorkflowStatus.state === "queued") && parentWorkflowStatus.sessionId === requestSessionId ? workflowForegroundSteeringDir(DIRS.async, effectiveParams.workflowParentRunId, runId) : undefined;
|
|
5756
6623
|
const foregroundControl = effectiveAsync ? undefined : compactOptional({
|
|
5757
6624
|
runId,
|
|
5758
6625
|
sessionId: requestSessionId,
|
|
5759
6626
|
mode: foregroundMode,
|
|
5760
6627
|
...effectiveParams.workflowParentRunId ? { parentWorkflowRunId: effectiveParams.workflowParentRunId } : {},
|
|
5761
6628
|
...effectiveParams.workflowKey ? { workflowKey: effectiveParams.workflowKey } : {},
|
|
5762
|
-
workflowSteeringDir,
|
|
5763
6629
|
startedAt: Date.now(),
|
|
5764
6630
|
updatedAt: Date.now(),
|
|
5765
6631
|
cwd: effectiveCwd,
|
|
@@ -5811,7 +6677,7 @@ ${item.text}` } : item)
|
|
|
5811
6677
|
deps.refreshResultDelivery?.();
|
|
5812
6678
|
}
|
|
5813
6679
|
const writeNestedForegroundEvent = (type, result) => {
|
|
5814
|
-
if (!
|
|
6680
|
+
if (!inheritedNestedRouteValue || !nestedParentAddress)
|
|
5815
6681
|
return;
|
|
5816
6682
|
const now = Date.now();
|
|
5817
6683
|
const details = result?.details;
|
|
@@ -5826,7 +6692,7 @@ ${item.text}` } : item)
|
|
|
5826
6692
|
availableModels: ctx.modelRegistry.getAvailable().map(toModelInfo),
|
|
5827
6693
|
currentProvider: requestParentModel?.provider,
|
|
5828
6694
|
modelScope,
|
|
5829
|
-
thinkingOverrideForTask
|
|
6695
|
+
thinkingOverrideForTask,
|
|
5830
6696
|
dynamicFanoutMaxItems: deps.config.chain?.dynamicFanout?.maxItems
|
|
5831
6697
|
});
|
|
5832
6698
|
} catch (error) {
|
|
@@ -5836,7 +6702,7 @@ ${item.text}` } : item)
|
|
|
5836
6702
|
const agentsForSummary = startedLaunches.map((launch) => launch.agent);
|
|
5837
6703
|
const leafIntercomTarget = agentsForSummary[0] && intercomBridgeAppliesToAgent(intercomBridge, contextPolicy, agentsForSummary[0]) ? resolveSubagentIntercomTarget(runId, agentsForSummary[0], 0) : undefined;
|
|
5838
6704
|
try {
|
|
5839
|
-
writeNestedEvent(
|
|
6705
|
+
writeNestedEvent(inheritedNestedRouteValue, compactOptional({
|
|
5840
6706
|
type,
|
|
5841
6707
|
ts: now,
|
|
5842
6708
|
parentRunId: nestedParentAddress.parentRunId,
|
|
@@ -5847,7 +6713,7 @@ ${item.text}` } : item)
|
|
|
5847
6713
|
parentStepIndex: nestedParentAddress.parentStepIndex,
|
|
5848
6714
|
depth: nestedParentAddress.depth,
|
|
5849
6715
|
path: nestedParentAddress.path,
|
|
5850
|
-
ownerIntercomTarget:
|
|
6716
|
+
ownerIntercomTarget: deps.childRuntime?.intercomSessionName,
|
|
5851
6717
|
leafIntercomTarget,
|
|
5852
6718
|
intercomTarget: leafIntercomTarget,
|
|
5853
6719
|
ownerState: state === "running" ? "live" : "gone",
|
|
@@ -5902,7 +6768,7 @@ ${item.text}` } : item)
|
|
|
5902
6768
|
const asyncResult = await runAsyncPath(execData, deps);
|
|
5903
6769
|
if (asyncResult) {
|
|
5904
6770
|
asyncLaunchFailed = asyncResult.isError === true;
|
|
5905
|
-
return attachMission(withRunFanoutBudget(withResolvedContext(
|
|
6771
|
+
return attachMission(withRunFanoutBudget(withResolvedContext(asyncResult, contextPolicy.contextSummary), runFanoutBudget));
|
|
5906
6772
|
}
|
|
5907
6773
|
if (foregroundControl) {
|
|
5908
6774
|
writeNestedForegroundEvent("subagent.nested.started");
|
|
@@ -5912,11 +6778,11 @@ ${item.text}` } : item)
|
|
|
5912
6778
|
if (hasSingle) {
|
|
5913
6779
|
const result = await runSinglePath(execData, deps);
|
|
5914
6780
|
writeNestedForegroundEvent("subagent.nested.completed", result);
|
|
5915
|
-
return attachMission(withRunFanoutBudget(withResolvedContext(
|
|
6781
|
+
return attachMission(withRunFanoutBudget(withResolvedContext(result, contextPolicy.contextSummary), runFanoutBudget, { annotateContent: runFanoutAnnotateContent }));
|
|
5916
6782
|
}
|
|
5917
6783
|
} catch (error) {
|
|
5918
6784
|
asyncLaunchFailed = effectiveAsync;
|
|
5919
|
-
const errorResult =
|
|
6785
|
+
const errorResult = toExecutionErrorResult(effectiveParams, error, contextPolicy.contextSummary);
|
|
5920
6786
|
if (nestedForegroundStarted)
|
|
5921
6787
|
writeNestedForegroundEvent("subagent.nested.completed", errorResult);
|
|
5922
6788
|
return attachMission(errorResult);
|
|
@@ -5927,7 +6793,7 @@ ${item.text}` } : item)
|
|
|
5927
6793
|
activeAsyncCapacity.rollback();
|
|
5928
6794
|
if (foregroundControl) {
|
|
5929
6795
|
settleForegroundSchedulingOwner(foregroundControl);
|
|
5930
|
-
removeForegroundControlIfIdle(deps.state, runId);
|
|
6796
|
+
removeForegroundControlIfIdle(deps.state, runId, deps.trackRetainedNestedRoute);
|
|
5931
6797
|
}
|
|
5932
6798
|
}
|
|
5933
6799
|
return withResolvedContext({
|
|
@@ -5941,7 +6807,7 @@ ${item.text}` } : item)
|
|
|
5941
6807
|
const requestParams = normalizedAction ? { ...params, action: normalizedAction } : params;
|
|
5942
6808
|
if (normalizedAction)
|
|
5943
6809
|
return execute(id, requestParams, signal, onUpdate, ctx).then(withAggregatedToolUsage);
|
|
5944
|
-
const { depth } = checkSubagentDepth(deps.config.maxSubagentDepth);
|
|
6810
|
+
const { depth } = checkSubagentDepth(deps.config.maxSubagentDepth, deps.childRuntime);
|
|
5945
6811
|
const dispatchParams = applyForceTopLevelAsyncOverride(requestParams, depth, deps.config.forceTopLevelAsync === true);
|
|
5946
6812
|
const runsForeground = dispatchParams.clarify === true || (dispatchParams.async ?? deps.asyncByDefault) !== true;
|
|
5947
6813
|
if (!runsForeground)
|
|
@@ -5960,10 +6826,25 @@ ${item.text}` } : item)
|
|
|
5960
6826
|
if (!normalized.ok) {
|
|
5961
6827
|
return Promise.resolve({ content: [{ type: "text", text: normalized.error }], isError: true, details: { mode: normalized.mode, results: [] } });
|
|
5962
6828
|
}
|
|
5963
|
-
|
|
6829
|
+
let publicParams = normalized.params;
|
|
6830
|
+
if (publicParams.workflow !== undefined) {
|
|
6831
|
+
const resolved = resolveWorkflowResource(publicParams.workflow, publicParams.args, ctx.sessionManager.getSessionId() ?? undefined);
|
|
6832
|
+
if (!resolved.ok)
|
|
6833
|
+
return Promise.resolve({ content: [{ type: "text", text: resolved.error }], isError: true, details: { mode: "workflow", results: [] } });
|
|
6834
|
+
const { workflow: _workflow, args: _args, ...withoutResourceInput } = publicParams;
|
|
6835
|
+
publicParams = { ...withoutResourceInput, workflowScript: resolved.resource.script };
|
|
6836
|
+
workflowResourcePermits.set(publicParams, resolved.resource.permit);
|
|
6837
|
+
} else if (publicParams.workflowScript !== undefined || publicParams.workflowScriptPath !== undefined) {
|
|
6838
|
+
const normalizedArgs = normalizeWorkflowArgs(publicParams.args);
|
|
6839
|
+
if ("error" in normalizedArgs)
|
|
6840
|
+
return Promise.resolve({ content: [{ type: "text", text: normalizedArgs.error }], isError: true, details: { mode: publicParams.action ? "management" : "workflow", results: [] } });
|
|
6841
|
+
publicParams = { ...publicParams, args: deepFreezeWorkflowArgs(normalizedArgs.args) };
|
|
6842
|
+
}
|
|
6843
|
+
const loaded = loadWorkflowScriptPath(publicParams, ctx.cwd);
|
|
5964
6844
|
if (loaded.error) {
|
|
5965
|
-
return Promise.resolve({ content: [{ type: "text", text: loaded.error }], isError: true, details: { mode:
|
|
6845
|
+
return Promise.resolve({ content: [{ type: "text", text: loaded.error }], isError: true, details: { mode: publicParams.action ? "management" : "workflow", results: [] } });
|
|
5966
6846
|
}
|
|
6847
|
+
publicExecutions.add(loaded.params);
|
|
5967
6848
|
return executeWithSingleDispatchGuard(id, loaded.params, signal, onUpdate, ctx);
|
|
5968
6849
|
};
|
|
5969
6850
|
const executeDelegated = async (id, params, signal, onUpdate, ctx) => {
|
|
@@ -5986,15 +6867,26 @@ ${item.text}` } : item)
|
|
|
5986
6867
|
};
|
|
5987
6868
|
const executeScheduled = (id, params, signal, ctx) => {
|
|
5988
6869
|
const ownerSessionId = resolveCurrentSessionId(ctx.sessionManager);
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
6870
|
+
const runtimeOwnerId = ctx.sessionManager.getSessionId() || null;
|
|
6871
|
+
let ownerExecutors = scheduledOwnerExecutors.get(runtimeOwnerId);
|
|
6872
|
+
if (!ownerExecutors) {
|
|
6873
|
+
ownerExecutors = new Map;
|
|
6874
|
+
scheduledOwnerExecutors.set(runtimeOwnerId, ownerExecutors);
|
|
6875
|
+
}
|
|
6876
|
+
let owner = ownerExecutors.get(ownerSessionId);
|
|
6877
|
+
if (!owner) {
|
|
6878
|
+
const state = createScheduledOwnerState(deps.state, ownerSessionId, ctx);
|
|
6879
|
+
owner = { state, executor: createSubagentExecutor({ ...deps, state }) };
|
|
6880
|
+
ownerExecutors.set(ownerSessionId, owner);
|
|
5996
6881
|
}
|
|
5997
|
-
return
|
|
6882
|
+
return owner.executor.executePublic(id, params, signal, undefined, ctx);
|
|
5998
6883
|
};
|
|
5999
|
-
|
|
6884
|
+
function* getCurrentSupervisorOwnerStates() {
|
|
6885
|
+
const ownerId = deps.state.supervisorOwnerSessionId;
|
|
6886
|
+
if (!ownerId)
|
|
6887
|
+
return;
|
|
6888
|
+
for (const owner of scheduledOwnerExecutors.get(ownerId)?.values() ?? [])
|
|
6889
|
+
yield owner.state;
|
|
6890
|
+
}
|
|
6891
|
+
return { execute: executeWithSingleDispatchGuard, executePublic, executeDelegated, executeScheduled, getCurrentSupervisorOwnerStates };
|
|
6000
6892
|
}
|