@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
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
3
2
|
import * as fs from "node:fs";
|
|
4
3
|
import * as path from "node:path";
|
|
4
|
+
import { performance } from "node:perf_hooks";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { installRunnerHttpDispatcher } from "./runner-http-dispatcher.js";
|
|
6
7
|
import { writeAtomicJson } from "../../shared/atomic-json.js";
|
|
7
8
|
import { writeAsyncResultFile, writePendingAsyncResultFile } from "./result-files.js";
|
|
8
9
|
import { createFileCoalescer } from "../../shared/file-coalescer.js";
|
|
@@ -10,16 +11,16 @@ import { createCapacityResilientJsonWriter } from "../../shared/capacity-resilie
|
|
|
10
11
|
import { isStorageCapacityError } from "../../shared/file-system-retry.js";
|
|
11
12
|
import { updateActiveRunIndex } from "./active-run-index.js";
|
|
12
13
|
import { createChildTranscriptWriter } from "../../shared/child-transcript.js";
|
|
13
|
-
import { closeSteerInbox, consumeInterruptRequest, consumeSteerRequests, deliverInterruptRequest, deliverStopRequest, deliverTimeoutRequest,
|
|
14
|
+
import { closeSteerInbox, consumeInterruptRequest, consumeSteerRequests, consumeStopRequestPayloads, deliverInterruptRequest, deliverStopRequest, deliverTimeoutRequest, watchAsyncControlInbox } from "./control-channel.js";
|
|
14
15
|
import { appendJsonl as appendRawJsonl, formatOutputArtifactContent, getArtifactPaths, writeArtifact, writeMetadata } from "../../shared/artifacts.js";
|
|
15
|
-
import { DM_CODING_AGENT_PACKAGE,
|
|
16
|
+
import { DM_CODING_AGENT_PACKAGE, resolveInstalledPiPackageRoot } from "../shared/dm-spawn.js";
|
|
16
17
|
import { preflightLaunchCwd } from "../shared/launch-cwd.js";
|
|
17
18
|
import { captureSingleOutputSnapshot, extractChildWrittenOutput, finalizeSingleOutput, formatSavedOutputReference, injectOutputPathSystemPrompt, injectSingleOutputInstruction, resolveSingleOutput } from "../shared/single-output.js";
|
|
19
|
+
import { runSetupCommand } from "../shared/worktree-setup-command.js";
|
|
18
20
|
import {
|
|
19
21
|
DEFAULT_MAX_OUTPUT,
|
|
20
22
|
SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
21
|
-
truncateOutput
|
|
22
|
-
getSubagentDepthEnv
|
|
23
|
+
truncateOutput
|
|
23
24
|
} from "../../shared/types.js";
|
|
24
25
|
import {
|
|
25
26
|
DEFAULT_CONTROL_CONFIG,
|
|
@@ -40,33 +41,27 @@ import {
|
|
|
40
41
|
DEFAULT_GLOBAL_CONCURRENCY_LIMIT,
|
|
41
42
|
Semaphore
|
|
42
43
|
} from "../shared/parallel-utils.js";
|
|
43
|
-
import { applyThinkingSuffix,
|
|
44
|
+
import { applyThinkingSuffix, projectLaunchResolvedChildExtensions, resolvePiLaunchToolPlan } from "../shared/child-tool-plan.js";
|
|
45
|
+
import { buildRunnerChildLaunch } from "./runner-child-launch.js";
|
|
46
|
+
import { normalizeExtensionBindings } from "../shared/extension-bindings.js";
|
|
47
|
+
import { runChildSession } from "./run-child-session.js";
|
|
48
|
+
import { loadRunnerChildSessionFactory } from "./runner-child-sessions.js";
|
|
49
|
+
import { SUBAGENT_CHILD_ENV } from "../shared/child-runtime-config.js";
|
|
44
50
|
import { deriveChildSessionName } from "../../shared/child-session-name.js";
|
|
45
|
-
import {
|
|
51
|
+
import { alignForkedSessionCwd } from "../../shared/fork-session-cwd.js";
|
|
46
52
|
import { outputEntryFromAsyncResult, resolveOutputReferences } from "../shared/chain-outputs.js";
|
|
47
|
-
import { createStructuredOutputRuntime, MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput, readStructuredOutputAcceptanceReport } from "../shared/structured-output.js";
|
|
48
|
-
import { formatMidToolExitError,
|
|
49
|
-
import {
|
|
53
|
+
import { clearStructuredOutputCaptures, createStructuredOutputFileCapture, createStructuredOutputRuntime, formatStructuredOutputRejectionError, MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput, readStructuredOutputAcceptanceReport } from "../shared/structured-output.js";
|
|
54
|
+
import { formatMidToolExitError, isOrdinaryToolForMidToolExit, isUnexplainedProcessSignal } from "../shared/process-signal.js";
|
|
55
|
+
import { formatChildToolDiagnostic } from "../shared/tool-availability.js";
|
|
50
56
|
import { buildTimeoutRecoverySummary, collectTrackedMutationEvidence, snapshotTrackedMutations } from "../shared/mutation-evidence.js";
|
|
51
57
|
import { collectDynamicResults, DynamicFanoutError, materializeDynamicParallelStep, validateDynamicCollection } from "../shared/dynamic-fanout.js";
|
|
52
58
|
import { claimRunFanoutBatch, getRunFanoutBudgetSnapshot } from "../shared/run-fanout-budget.js";
|
|
53
59
|
import { nestedSummaryFromAsyncStatus, projectNestedEvents, resolveNestedAsyncDir, writeNestedEvent } from "../shared/nested-events.js";
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
formatSubagentStartupRetryNote,
|
|
60
|
-
isRetryableSubagentStartupFailure,
|
|
61
|
-
waitForSubagentStartupRetry
|
|
62
|
-
} from "../shared/subagent-startup-retry.js";
|
|
63
|
-
import { markProcessTerminalCandidateLeaseRelease, writeProcessTerminalCandidate } from "./process-terminal.js";
|
|
64
|
-
import { createOwnedProcessTreeController } from "./owned-process-tree.js";
|
|
65
|
-
import { createSteeringStatus, recordSteeringRequest, steeringStatus, terminalSteeringNoticeState, updateSteeringTarget } from "./steering.js";
|
|
66
|
-
import { attachPostExitStdioGuard, trySignalChild } from "../../shared/post-exit-stdio-guard.js";
|
|
67
|
-
import { PROMPT_REDACTED, detectSubagentError, extractTextFromContent, extractToolArgsPreview, formatEmptyTerminalAssistantResponseError, getFinalOutput, hasEmptyTerminalAssistantResponse, readStatus } from "../../shared/utils.js";
|
|
68
|
-
import { evaluateCompletionMutationGuard, expectsImplementationMutation, hasMutationToolCapability, validateImplementationToolContract } from "../shared/completion-guard.js";
|
|
69
|
-
import { planCompletionEvidence, projectSettlementDiagnostic } from "../shared/completion-evidence.js";
|
|
60
|
+
import { isContextOverflow } from "../shared/model-resolution.js";
|
|
61
|
+
import { processTerminalPath, writeProcessTerminalCandidate } from "./process-terminal.js";
|
|
62
|
+
import { persistRunnerStartupFailure } from "./runner-startup-failure.js";
|
|
63
|
+
import { createSteeringStatus, recordSteeringRequest, steeringStatus, terminalSteeringNoticeState, unconsumedSteerReason, updateSteeringTarget } from "./steering.js";
|
|
64
|
+
import { PROMPT_REDACTED, detectSubagentError, extractTextFromContent, extractToolArgsPreview, formatEmptyTerminalAssistantResponseError, getAgentDir, hasEmptyTerminalAssistantResponse, readStatus } from "../../shared/utils.js";
|
|
70
65
|
import { planAbortRecovery } from "../shared/abort-recovery.js";
|
|
71
66
|
import {
|
|
72
67
|
createMutatingFailureState,
|
|
@@ -83,46 +78,46 @@ import { parseSessionTokens } from "../../shared/session-tokens.js";
|
|
|
83
78
|
import {
|
|
84
79
|
cleanupWorktrees,
|
|
85
80
|
createWorktrees,
|
|
81
|
+
withWorktreeTransaction,
|
|
82
|
+
WorktreeSetupError,
|
|
86
83
|
diffWorktrees,
|
|
87
84
|
findWorktreeTaskCwdConflict,
|
|
88
85
|
formatWorktreeDiffSummary,
|
|
89
|
-
formatWorktreeTaskCwdConflict
|
|
86
|
+
formatWorktreeTaskCwdConflict,
|
|
87
|
+
WORKTREE_AGENT_CWD_PLACEHOLDER
|
|
90
88
|
} from "../shared/worktree.js";
|
|
91
89
|
import { findModelInfo, resolveEffectiveThinking } from "../../shared/model-info.js";
|
|
92
|
-
import { assertThinkingWithinCeiling
|
|
93
|
-
import {
|
|
90
|
+
import { assertThinkingWithinCeiling } from "../../shared/thinking-ceiling.js";
|
|
91
|
+
import { resolveLaunchBinding } from "../../shared/launch-contract.js";
|
|
94
92
|
import { writeInitialProgressFile } from "../../shared/settings.js";
|
|
95
93
|
import { resolveSubagentIntercomTarget } from "../../intercom/intercom-bridge.js";
|
|
96
|
-
import { acceptanceFailureMessage, aggregateAcceptanceReport, buildSkippedAcceptanceLedger, evaluateAcceptance, formatAcceptancePrompt, resolveEffectiveAcceptance, stripAcceptanceReport } from "../shared/acceptance.js";
|
|
97
|
-
import { attachContractProjections,
|
|
94
|
+
import { acceptanceFailureMessage, aggregateAcceptanceReport, buildSkippedAcceptanceLedger, captureStagedIndexBaseline, evaluateAcceptance, formatAcceptancePrompt, resolveAcceptanceReportMode, resolveEffectiveAcceptance, stripAcceptanceReport, typedVerifyOutput } from "../shared/acceptance.js";
|
|
95
|
+
import { attachContractProjections, isAgentContract } from "../shared/agent-contract.js";
|
|
98
96
|
import { waitForImportedAsyncRoot } from "./chain-root-attachment.js";
|
|
99
|
-
import { normalizeExtensionBindings } from "../shared/extension-bindings.js";
|
|
100
97
|
import { appendRunnerStepsToStatus, consumeChainAppendRequests, countPendingChainAppendRequests, statusStepDescription } from "./chain-append.js";
|
|
101
98
|
import { asyncStatusChildIdentity } from "../shared/child-identity.js";
|
|
102
99
|
import { initialToolBudgetState, toolBudgetState } from "../shared/tool-budget.js";
|
|
103
|
-
import {
|
|
100
|
+
import { toolTimeoutCallKey } from "../shared/tool-timeout.js";
|
|
104
101
|
import { usageBudgetExceededMessage, usageBudgetState } from "../shared/usage-budget.js";
|
|
105
|
-
import { formatParallelHandoffError, formatParallelHandoffReference, parallelHandoffPath, writeParallelHandoffGroup,
|
|
102
|
+
import { formatParallelHandoffError, formatParallelHandoffReference, parallelHandoffPath, writeParallelHandoffGroup, writeWorktreeSetupHandoff } from "../shared/parallel-handoff.js";
|
|
106
103
|
import { resolveWatchdogConfig } from "../../watchdog/settings.js";
|
|
107
|
-
import { createBoundedByteTail, createBoundedLineReader, formatProtocolOutputLimit, MAX_CHILD_STDERR_BYTES, PI_AGGREGATE_EVENT_PROJECTOR, projectChildLifecycle } from "../shared/child-protocol.js";
|
|
108
|
-
import { acquireSessionLease } from "../shared/session-lease.js";
|
|
109
104
|
import { buildExternalCliPrompt, runExternalCli } from "../shared/external-cli-runner.js";
|
|
110
105
|
import { resolveClaudeCodeLaunch } from "../shared/claude-code-adapter.js";
|
|
111
106
|
import { resolveCodexExecLaunch } from "../shared/codex-exec-adapter.js";
|
|
112
107
|
import { resolveCursorAgentLaunch } from "../shared/cursor-agent-adapter.js";
|
|
113
108
|
import { resolveExternalCliRunnerStatus } from "../shared/external-cli-contract.js";
|
|
109
|
+
import { formatHerdrMachineHint, prepareHerdrMachineExternalCliRun } from "../shared/herdr-machine.js";
|
|
110
|
+
import { HerdrExternalNeedsAttentionError, createHerdrExternalAdapter, prepareInternalHerdrExternalAdapter } from "../shared/herdr-external-adapters.js";
|
|
114
111
|
import { runExternalJob } from "../shared/external-job-runner.js";
|
|
115
112
|
import { createOrcaProgressTab } from "../shared/orca-progress-tabs.js";
|
|
116
|
-
import { decodeSubagentCapabilityCeiling, SUBAGENT_CAPABILITY_CEILING_ENV } from "../shared/capability-ceiling.js";
|
|
117
113
|
import {
|
|
118
|
-
CHILD_WATCHDOG_CONFIG_ENV,
|
|
119
114
|
acceptChildWatchdogEvent,
|
|
120
|
-
|
|
121
|
-
decodeChildWatchdogConfig,
|
|
115
|
+
applyChildWatchdogMessage,
|
|
122
116
|
isChildWatchdogStatusEvent,
|
|
123
117
|
resolveChildWatchdogConfig
|
|
124
118
|
} from "../../watchdog/child-status.js";
|
|
125
119
|
const INTERCOM_DETACH_RECEIPT = "Detached for intercom coordination before task completion.";
|
|
120
|
+
process.env[SUBAGENT_CHILD_ENV] = "1";
|
|
126
121
|
function persistStepArtifacts(input) {
|
|
127
122
|
const errors = {};
|
|
128
123
|
if (input.artifactConfig?.includeOutput !== false) {
|
|
@@ -205,9 +200,6 @@ function appendDiagnosticJsonl(filePath, line, droppedEventType) {
|
|
|
205
200
|
}
|
|
206
201
|
state.diagnosticsTruncated = true;
|
|
207
202
|
}
|
|
208
|
-
function shouldPersistChildEvent(event) {
|
|
209
|
-
return event.type !== "message_update";
|
|
210
|
-
}
|
|
211
203
|
function isBlockingSupervisorTool(toolName, args) {
|
|
212
204
|
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
213
205
|
return false;
|
|
@@ -231,47 +223,18 @@ function findLatestSessionFile(sessionDir) {
|
|
|
231
223
|
function emptyUsage() {
|
|
232
224
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
|
|
233
225
|
}
|
|
234
|
-
function
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
let input = 0;
|
|
238
|
-
let output = 0;
|
|
239
|
-
for (const attempt of attempts) {
|
|
240
|
-
input += attempt.usage?.input ?? 0;
|
|
241
|
-
output += attempt.usage?.output ?? 0;
|
|
242
|
-
}
|
|
226
|
+
function tokenUsageFromUsage(usage) {
|
|
227
|
+
const input = usage?.input ?? 0;
|
|
228
|
+
const output = usage?.output ?? 0;
|
|
243
229
|
const total = input + output;
|
|
244
230
|
return total > 0 ? { input, output, total } : null;
|
|
245
231
|
}
|
|
246
|
-
function
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
let outputTokens = 0;
|
|
251
|
-
let costUsd = 0;
|
|
252
|
-
for (const attempt of attempts) {
|
|
253
|
-
inputTokens += attempt.usage?.input ?? 0;
|
|
254
|
-
outputTokens += attempt.usage?.output ?? 0;
|
|
255
|
-
costUsd += attempt.usage?.cost ?? 0;
|
|
256
|
-
}
|
|
232
|
+
function costSummaryFromUsage(usage) {
|
|
233
|
+
const inputTokens = usage?.input ?? 0;
|
|
234
|
+
const outputTokens = usage?.output ?? 0;
|
|
235
|
+
const costUsd = usage?.cost ?? 0;
|
|
257
236
|
return inputTokens > 0 || outputTokens > 0 || costUsd > 0 ? { inputTokens, outputTokens, costUsd } : undefined;
|
|
258
237
|
}
|
|
259
|
-
function usageFromAttempts(attempts) {
|
|
260
|
-
if (!attempts || attempts.length === 0)
|
|
261
|
-
return;
|
|
262
|
-
const usage = emptyUsage();
|
|
263
|
-
for (const attempt of attempts) {
|
|
264
|
-
if (!attempt.usage)
|
|
265
|
-
continue;
|
|
266
|
-
usage.input += attempt.usage.input;
|
|
267
|
-
usage.output += attempt.usage.output;
|
|
268
|
-
usage.cacheRead += attempt.usage.cacheRead;
|
|
269
|
-
usage.cacheWrite += attempt.usage.cacheWrite;
|
|
270
|
-
usage.cost += attempt.usage.cost;
|
|
271
|
-
usage.turns += attempt.usage.turns;
|
|
272
|
-
}
|
|
273
|
-
return usage.input !== 0 || usage.output !== 0 || usage.cacheRead !== 0 || usage.cacheWrite !== 0 || usage.cost !== 0 || usage.turns !== 0 ? usage : undefined;
|
|
274
|
-
}
|
|
275
238
|
function appendRecentStepOutput(step, lines) {
|
|
276
239
|
const nonEmpty = lines.filter((line) => line.trim());
|
|
277
240
|
if (nonEmpty.length === 0)
|
|
@@ -282,12 +245,6 @@ function appendRecentStepOutput(step, lines) {
|
|
|
282
245
|
step.recentOutput.splice(0, step.recentOutput.length - 50);
|
|
283
246
|
}
|
|
284
247
|
}
|
|
285
|
-
function assistantStartsToolCall(message) {
|
|
286
|
-
return Array.isArray(message.content) && message.content.some((part) => part.type === "toolCall");
|
|
287
|
-
}
|
|
288
|
-
function isTerminalAssistantStop(message) {
|
|
289
|
-
return message.stopReason === "stop" && !assistantStartsToolCall(message);
|
|
290
|
-
}
|
|
291
248
|
function omitUndefinedProperties(value) {
|
|
292
249
|
for (const key in value) {
|
|
293
250
|
if (value[key] === undefined)
|
|
@@ -338,549 +295,6 @@ function formatChildFailureDiagnostic(input) {
|
|
|
338
295
|
return `${baseError.slice(0, Math.max(0, errorLimit))}${context ? `
|
|
339
296
|
${context}` : ""}`;
|
|
340
297
|
}
|
|
341
|
-
function runPiStreaming(args, cwd, outputFile, env, piPackageRoot, piArgv1, maxSubagentDepth, childEventContext, registerInterrupt, onChildEvent, transcriptWriter, registerTimeout, timeoutMessage, registerStop, stopMessage, onWriterProcess, toolTimeoutMs, runDeadlineAt, orcaProgressTab, expectedModelForVerification, modelVerificationRegistry, mutationTools) {
|
|
342
|
-
return new Promise((resolve) => {
|
|
343
|
-
const startedAt = Date.now();
|
|
344
|
-
const processInstanceId = randomUUID();
|
|
345
|
-
onWriterProcess?.({ state: "spawning" });
|
|
346
|
-
const outputStream = fs.createWriteStream(outputFile, { flags: "w" });
|
|
347
|
-
const spawnEnv = { ...process.env, ...env ?? {}, ...getSubagentDepthEnv(maxSubagentDepth) };
|
|
348
|
-
const spawnSpec = getPiSpawnCommand(args, {
|
|
349
|
-
...piPackageRoot ? { piPackageRoot } : {},
|
|
350
|
-
...piArgv1 ? { argv1: piArgv1 } : {}
|
|
351
|
-
});
|
|
352
|
-
const child = spawn(spawnSpec.command, spawnSpec.args, {
|
|
353
|
-
cwd,
|
|
354
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
355
|
-
env: spawnEnv,
|
|
356
|
-
windowsHide: true,
|
|
357
|
-
detached: process.platform !== "win32"
|
|
358
|
-
});
|
|
359
|
-
let processTreeController;
|
|
360
|
-
const stderrTail = createBoundedByteTail();
|
|
361
|
-
const rawStdoutTail = createBoundedByteTail();
|
|
362
|
-
const messages = [];
|
|
363
|
-
const usage = emptyUsage();
|
|
364
|
-
let model;
|
|
365
|
-
let writerRegistrationError;
|
|
366
|
-
if (typeof child.pid === "number") {
|
|
367
|
-
processTreeController = createOwnedProcessTreeController(child.pid);
|
|
368
|
-
try {
|
|
369
|
-
onWriterProcess?.({ state: "running", pid: child.pid });
|
|
370
|
-
} catch (writerError) {
|
|
371
|
-
writerRegistrationError = `Failed to record revived DM writer ownership: ${writerError instanceof Error ? writerError.message : String(writerError)}`;
|
|
372
|
-
trySignalChild(child, "SIGKILL");
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
let error = writerRegistrationError;
|
|
376
|
-
let assistantError;
|
|
377
|
-
let interrupted = false;
|
|
378
|
-
let timedOut = false;
|
|
379
|
-
let stopped = false;
|
|
380
|
-
let observedMutationAttempt = false;
|
|
381
|
-
let structuredOutputToolInvoked = false;
|
|
382
|
-
let structuredOutputMessageStartIndex;
|
|
383
|
-
let currentTool;
|
|
384
|
-
let currentToolArgs;
|
|
385
|
-
let currentPath;
|
|
386
|
-
let toolCount = 0;
|
|
387
|
-
let activeToolSequence = 0;
|
|
388
|
-
const activeToolCalls = new Map;
|
|
389
|
-
const activeToolKeysByName = new Map;
|
|
390
|
-
const refreshCurrentTool = () => {
|
|
391
|
-
const active = [...activeToolCalls.values()].at(-1);
|
|
392
|
-
currentTool = active?.tool;
|
|
393
|
-
currentToolArgs = active?.args;
|
|
394
|
-
currentPath = active?.path;
|
|
395
|
-
};
|
|
396
|
-
const recordActiveToolCall = (event) => {
|
|
397
|
-
const key = toolTimeoutCallKey(event, ++activeToolSequence);
|
|
398
|
-
const active = omitUndefinedProperties({
|
|
399
|
-
key,
|
|
400
|
-
tool: event.toolName,
|
|
401
|
-
args: extractToolArgsPreview(event.args ?? {}),
|
|
402
|
-
path: resolveCurrentPath(event.toolName, event.args)
|
|
403
|
-
});
|
|
404
|
-
activeToolCalls.set(key, active);
|
|
405
|
-
const keys = activeToolKeysByName.get(active.tool) ?? [];
|
|
406
|
-
keys.push(key);
|
|
407
|
-
activeToolKeysByName.set(active.tool, keys);
|
|
408
|
-
refreshCurrentTool();
|
|
409
|
-
};
|
|
410
|
-
const removeActiveToolCall = (event) => {
|
|
411
|
-
const key = typeof event.toolCallId === "string" && event.toolCallId.length > 0 ? `id:${event.toolCallId}` : typeof event.toolName === "string" ? activeToolKeysByName.get(event.toolName)?.[0] : activeToolCalls.size === 1 ? [...activeToolCalls.keys()][0] : undefined;
|
|
412
|
-
if (!key)
|
|
413
|
-
return;
|
|
414
|
-
const active = activeToolCalls.get(key);
|
|
415
|
-
if (!active)
|
|
416
|
-
return;
|
|
417
|
-
activeToolCalls.delete(key);
|
|
418
|
-
const keys = activeToolKeysByName.get(active.tool)?.filter((candidate) => candidate !== key) ?? [];
|
|
419
|
-
if (keys.length > 0)
|
|
420
|
-
activeToolKeysByName.set(active.tool, keys);
|
|
421
|
-
else
|
|
422
|
-
activeToolKeysByName.delete(active.tool);
|
|
423
|
-
refreshCurrentTool();
|
|
424
|
-
};
|
|
425
|
-
const childWatchdogConfig = decodeChildWatchdogConfig(env?.[CHILD_WATCHDOG_CONFIG_ENV]);
|
|
426
|
-
let childWatchdogState;
|
|
427
|
-
const childLifecycleState = { compactionRetryActive: false };
|
|
428
|
-
let applyChildLifecycle = (_action) => {};
|
|
429
|
-
const updateChildWatchdogState = (snapshot) => {
|
|
430
|
-
childWatchdogState = snapshot;
|
|
431
|
-
};
|
|
432
|
-
const writeOutputLine = (line) => {
|
|
433
|
-
if (!line.trim())
|
|
434
|
-
return;
|
|
435
|
-
outputStream.write(`${line}
|
|
436
|
-
`);
|
|
437
|
-
orcaProgressTab?.append(`${line}
|
|
438
|
-
`);
|
|
439
|
-
};
|
|
440
|
-
const writeOutputText = (text) => {
|
|
441
|
-
for (const line of text.split(`
|
|
442
|
-
`)) {
|
|
443
|
-
writeOutputLine(line);
|
|
444
|
-
}
|
|
445
|
-
};
|
|
446
|
-
const appendChildEvent = (event) => {
|
|
447
|
-
if (!childEventContext)
|
|
448
|
-
return;
|
|
449
|
-
if (!shouldPersistChildEvent(event))
|
|
450
|
-
return;
|
|
451
|
-
appendDiagnosticJsonl(childEventContext.eventsPath, JSON.stringify({
|
|
452
|
-
...event,
|
|
453
|
-
subagentSource: "child",
|
|
454
|
-
subagentRunId: childEventContext.runId,
|
|
455
|
-
subagentStepIndex: childEventContext.stepIndex,
|
|
456
|
-
subagentAgent: childEventContext.agent,
|
|
457
|
-
observedAt: Date.now()
|
|
458
|
-
}), typeof event.type === "string" ? event.type : undefined);
|
|
459
|
-
};
|
|
460
|
-
const appendChildLine = (type, line) => {
|
|
461
|
-
appendChildEvent({ type, line });
|
|
462
|
-
if (type === "subagent.child.stdout")
|
|
463
|
-
transcriptWriter?.writeStdoutLine(line);
|
|
464
|
-
else
|
|
465
|
-
transcriptWriter?.writeStderrLine(line);
|
|
466
|
-
};
|
|
467
|
-
const processStdoutLine = (line) => {
|
|
468
|
-
if (!line.trim())
|
|
469
|
-
return;
|
|
470
|
-
let event;
|
|
471
|
-
try {
|
|
472
|
-
event = JSON.parse(line);
|
|
473
|
-
} catch {
|
|
474
|
-
rawStdoutTail.push(`${line}
|
|
475
|
-
`);
|
|
476
|
-
writeOutputLine(line);
|
|
477
|
-
appendChildLine("subagent.child.stdout", line);
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
appendChildEvent(event);
|
|
481
|
-
transcriptWriter?.writeChildEvent(event);
|
|
482
|
-
if (event.type === "compaction_start")
|
|
483
|
-
compactionStartedReceived = true;
|
|
484
|
-
if (event.type === "compaction_end" && event.willRetry === true) {
|
|
485
|
-
compactionStartedReceived = false;
|
|
486
|
-
afterCompactionSettlement = false;
|
|
487
|
-
}
|
|
488
|
-
if (event.type === "agent_start" || event.type === "auto_retry_start") {
|
|
489
|
-
compactionStartedReceived = false;
|
|
490
|
-
afterCompactionSettlement = false;
|
|
491
|
-
}
|
|
492
|
-
const lifecycleAction = projectChildLifecycle(event, false, childLifecycleState);
|
|
493
|
-
if (event.type === "agent_settled" && lifecycleAction === "start-drain") {
|
|
494
|
-
agentSettledReceived = true;
|
|
495
|
-
afterCompactionSettlement = compactionStartedReceived;
|
|
496
|
-
}
|
|
497
|
-
applyChildLifecycle(lifecycleAction);
|
|
498
|
-
if (isChildWatchdogStatusEvent(event)) {
|
|
499
|
-
if (!childWatchdogConfig)
|
|
500
|
-
return;
|
|
501
|
-
const next = acceptChildWatchdogEvent({
|
|
502
|
-
current: childWatchdogState,
|
|
503
|
-
event,
|
|
504
|
-
...childEventContext ? {
|
|
505
|
-
runId: childEventContext.runId,
|
|
506
|
-
agent: childEventContext.agent,
|
|
507
|
-
childIndex: childEventContext.stepIndex
|
|
508
|
-
} : {}
|
|
509
|
-
});
|
|
510
|
-
if (!next)
|
|
511
|
-
return;
|
|
512
|
-
updateChildWatchdogState(next);
|
|
513
|
-
onChildEvent?.(event);
|
|
514
|
-
if (childWatchdogIsActive(next)) {
|
|
515
|
-
if (finalDrainTimer) {
|
|
516
|
-
clearTimeout(finalDrainTimer);
|
|
517
|
-
finalDrainTimer = undefined;
|
|
518
|
-
}
|
|
519
|
-
if (finalHardKillTimer) {
|
|
520
|
-
clearTimeout(finalHardKillTimer);
|
|
521
|
-
finalHardKillTimer = undefined;
|
|
522
|
-
}
|
|
523
|
-
armWatchdogTail();
|
|
524
|
-
} else {
|
|
525
|
-
clearWatchdogTailTimer();
|
|
526
|
-
if (cleanTerminalAssistantStopReceived || agentSettledReceived)
|
|
527
|
-
startFinalDrain();
|
|
528
|
-
}
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
onChildEvent?.(event);
|
|
532
|
-
if (event.type === "tool_execution_end") {
|
|
533
|
-
clearActiveToolTimeout(event);
|
|
534
|
-
removeActiveToolCall(event);
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
if (event.type === "tool_execution_start" && event.toolName) {
|
|
538
|
-
toolCount += 1;
|
|
539
|
-
armToolTimeout({ toolCallId: event.toolCallId, toolName: event.toolName });
|
|
540
|
-
recordActiveToolCall({ toolCallId: event.toolCallId, toolName: event.toolName, args: event.args });
|
|
541
|
-
if (event.toolName === "structured_output") {
|
|
542
|
-
structuredOutputToolInvoked = true;
|
|
543
|
-
structuredOutputMessageStartIndex = messages.length;
|
|
544
|
-
}
|
|
545
|
-
observedMutationAttempt = observedMutationAttempt || isMutatingTool(event.toolName, event.args, mutationTools);
|
|
546
|
-
const toolArgs = extractToolArgsPreview(event.args ?? {});
|
|
547
|
-
writeOutputLine(toolArgs ? `${event.toolName}: ${toolArgs}` : event.toolName);
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
if ((event.type === "message_end" || event.type === "tool_result_end") && event.message) {
|
|
551
|
-
if (event.type === "tool_result_end") {
|
|
552
|
-
clearActiveToolTimeout(event);
|
|
553
|
-
removeActiveToolCall({
|
|
554
|
-
toolCallId: event.message.toolCallId ?? event.toolCallId,
|
|
555
|
-
toolName: event.message.toolName ?? event.toolName
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
messages.push(event.message);
|
|
559
|
-
const text = extractTextFromContent(event.message.content);
|
|
560
|
-
if (text)
|
|
561
|
-
writeOutputText(text);
|
|
562
|
-
if (event.type !== "message_end" || event.message.role !== "assistant")
|
|
563
|
-
return;
|
|
564
|
-
const hasToolCall = assistantStartsToolCall(event.message);
|
|
565
|
-
if (event.message.model) {
|
|
566
|
-
model = event.message.model;
|
|
567
|
-
if (expectedModelForVerification && !hasToolCall) {
|
|
568
|
-
const modelVerificationError = formatSubagentModelVerificationError(expectedModelForVerification, event.message.model, modelVerificationRegistry);
|
|
569
|
-
if (modelVerificationError && !error)
|
|
570
|
-
error = modelVerificationError;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
if (event.message.errorMessage)
|
|
574
|
-
assistantError = event.message.errorMessage;
|
|
575
|
-
const eventUsage = event.message.usage;
|
|
576
|
-
if (eventUsage) {
|
|
577
|
-
usage.turns++;
|
|
578
|
-
usage.input += eventUsage.input ?? eventUsage.inputTokens ?? 0;
|
|
579
|
-
usage.output += eventUsage.output ?? eventUsage.outputTokens ?? 0;
|
|
580
|
-
usage.cacheRead += eventUsage.cacheRead ?? 0;
|
|
581
|
-
usage.cacheWrite += eventUsage.cacheWrite ?? 0;
|
|
582
|
-
usage.cost += eventUsage.cost?.total ?? 0;
|
|
583
|
-
}
|
|
584
|
-
if (isTerminalAssistantStop(event.message)) {
|
|
585
|
-
if (!event.message.errorMessage && extractTextFromContent(event.message.content).trim())
|
|
586
|
-
assistantError = undefined;
|
|
587
|
-
cleanTerminalAssistantStopReceived ||= !event.message.errorMessage;
|
|
588
|
-
clearAllToolTimeouts();
|
|
589
|
-
activeToolCalls.clear();
|
|
590
|
-
activeToolKeysByName.clear();
|
|
591
|
-
refreshCurrentTool();
|
|
592
|
-
applyChildLifecycle(projectChildLifecycle(event, true, childLifecycleState));
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
};
|
|
596
|
-
const FINAL_STOP_GRACE_MS = 1000;
|
|
597
|
-
const HARD_KILL_MS = 3000;
|
|
598
|
-
let childExited = false;
|
|
599
|
-
let forcedTerminationSignal = false;
|
|
600
|
-
let cleanTerminalAssistantStopReceived = false;
|
|
601
|
-
let agentSettledReceived = false;
|
|
602
|
-
let compactionStartedReceived = false;
|
|
603
|
-
let afterCompactionSettlement = false;
|
|
604
|
-
let finalDrainTimer;
|
|
605
|
-
let finalHardKillTimer;
|
|
606
|
-
let watchdogTailTimer;
|
|
607
|
-
let protocolHardKillTimer;
|
|
608
|
-
let protocolError;
|
|
609
|
-
let settled = false;
|
|
610
|
-
applyChildLifecycle = (action) => {
|
|
611
|
-
if (action === "cancel-drain") {
|
|
612
|
-
if (finalDrainTimer) {
|
|
613
|
-
clearTimeout(finalDrainTimer);
|
|
614
|
-
finalDrainTimer = undefined;
|
|
615
|
-
}
|
|
616
|
-
if (finalHardKillTimer) {
|
|
617
|
-
clearTimeout(finalHardKillTimer);
|
|
618
|
-
finalHardKillTimer = undefined;
|
|
619
|
-
}
|
|
620
|
-
clearWatchdogTailTimer();
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
if (action === "start-drain")
|
|
624
|
-
startFinalDrain();
|
|
625
|
-
};
|
|
626
|
-
const failProtocol = (limit) => {
|
|
627
|
-
if (protocolError)
|
|
628
|
-
return;
|
|
629
|
-
protocolError = limit;
|
|
630
|
-
error = formatProtocolOutputLimit(limit);
|
|
631
|
-
if (!childExited) {
|
|
632
|
-
trySignalChild(child, "SIGTERM");
|
|
633
|
-
protocolHardKillTimer = setTimeout(() => {
|
|
634
|
-
if (!settled)
|
|
635
|
-
trySignalChild(child, "SIGKILL");
|
|
636
|
-
}, 3000);
|
|
637
|
-
protocolHardKillTimer.unref?.();
|
|
638
|
-
}
|
|
639
|
-
};
|
|
640
|
-
const stdoutReader = createBoundedLineReader({
|
|
641
|
-
oversizedLineProjector: PI_AGGREGATE_EVENT_PROJECTOR,
|
|
642
|
-
onLine: processStdoutLine,
|
|
643
|
-
onLimit: failProtocol
|
|
644
|
-
});
|
|
645
|
-
const stderrReader = createBoundedLineReader({
|
|
646
|
-
stream: "stderr",
|
|
647
|
-
maxPendingLineBytes: MAX_CHILD_STDERR_BYTES,
|
|
648
|
-
onLine: (line) => appendChildLine("subagent.child.stderr", line),
|
|
649
|
-
onLimit: (limit) => appendChildLine("subagent.child.stderr", formatProtocolOutputLimit(limit))
|
|
650
|
-
});
|
|
651
|
-
const clearStdioGuard = attachPostExitStdioGuard(child, { idleMs: 2000, hardMs: 8000 });
|
|
652
|
-
child.stdout.on("data", (chunk) => stdoutReader.push(chunk));
|
|
653
|
-
child.stderr.on("data", (chunk) => {
|
|
654
|
-
stderrTail.push(chunk);
|
|
655
|
-
stderrReader.push(chunk);
|
|
656
|
-
outputStream.write(chunk);
|
|
657
|
-
orcaProgressTab?.append(chunk.toString("utf-8"));
|
|
658
|
-
});
|
|
659
|
-
registerInterrupt?.(() => {
|
|
660
|
-
if (settled || timedOut || stopped)
|
|
661
|
-
return;
|
|
662
|
-
interrupted = true;
|
|
663
|
-
if (!error)
|
|
664
|
-
error = "Interrupted. Waiting for explicit next action.";
|
|
665
|
-
trySignalChild(child, "SIGINT");
|
|
666
|
-
setTimeout(() => {
|
|
667
|
-
if (!settled && !timedOut && !stopped)
|
|
668
|
-
trySignalChild(child, "SIGTERM");
|
|
669
|
-
}, 1000).unref?.();
|
|
670
|
-
});
|
|
671
|
-
const terminateForTimeout = (message) => {
|
|
672
|
-
if (settled || timedOut || stopped)
|
|
673
|
-
return;
|
|
674
|
-
timedOut = true;
|
|
675
|
-
timeoutMessage = message;
|
|
676
|
-
interrupted = false;
|
|
677
|
-
error = message;
|
|
678
|
-
if (processTreeController)
|
|
679
|
-
processTreeController.terminate();
|
|
680
|
-
else
|
|
681
|
-
trySignalChild(child, "SIGTERM");
|
|
682
|
-
};
|
|
683
|
-
let toolTimeoutSequence = 0;
|
|
684
|
-
const activeToolTimeouts = new Map;
|
|
685
|
-
const activeToolTimeoutKeysByName = new Map;
|
|
686
|
-
const removeToolTimeoutKey = (key) => {
|
|
687
|
-
const active = activeToolTimeouts.get(key);
|
|
688
|
-
if (!active)
|
|
689
|
-
return;
|
|
690
|
-
clearTimeout(active.timer);
|
|
691
|
-
activeToolTimeouts.delete(key);
|
|
692
|
-
const keys = activeToolTimeoutKeysByName.get(active.toolName)?.filter((candidate) => candidate !== key) ?? [];
|
|
693
|
-
if (keys.length > 0)
|
|
694
|
-
activeToolTimeoutKeysByName.set(active.toolName, keys);
|
|
695
|
-
else
|
|
696
|
-
activeToolTimeoutKeysByName.delete(active.toolName);
|
|
697
|
-
};
|
|
698
|
-
const clearActiveToolTimeout = (event) => {
|
|
699
|
-
const key = typeof event.toolCallId === "string" && event.toolCallId.length > 0 ? `id:${event.toolCallId}` : typeof event.toolName === "string" ? activeToolTimeoutKeysByName.get(event.toolName)?.[0] : activeToolTimeouts.size === 1 ? [...activeToolTimeouts.keys()][0] : undefined;
|
|
700
|
-
if (key)
|
|
701
|
-
removeToolTimeoutKey(key);
|
|
702
|
-
};
|
|
703
|
-
const clearAllToolTimeouts = () => {
|
|
704
|
-
for (const key of [...activeToolTimeouts.keys()])
|
|
705
|
-
removeToolTimeoutKey(key);
|
|
706
|
-
};
|
|
707
|
-
const armToolTimeout = (event) => {
|
|
708
|
-
const timeoutForTool = effectiveToolTimeoutMs(event.toolName, toolTimeoutMs);
|
|
709
|
-
if (timeoutForTool === undefined)
|
|
710
|
-
return;
|
|
711
|
-
const runRemaining = runDeadlineAt === undefined ? undefined : Math.max(0, runDeadlineAt - Date.now());
|
|
712
|
-
if (runRemaining !== undefined && timeoutForTool >= runRemaining)
|
|
713
|
-
return;
|
|
714
|
-
const key = toolTimeoutCallKey(event, ++toolTimeoutSequence);
|
|
715
|
-
const toolName = event.toolName;
|
|
716
|
-
const timer = setTimeout(() => {
|
|
717
|
-
removeToolTimeoutKey(key);
|
|
718
|
-
terminateForTimeout(formatToolTimeoutMessage(toolName, timeoutForTool));
|
|
719
|
-
}, timeoutForTool);
|
|
720
|
-
timer.unref?.();
|
|
721
|
-
activeToolTimeouts.set(key, { toolName, timer });
|
|
722
|
-
const keys = activeToolTimeoutKeysByName.get(toolName) ?? [];
|
|
723
|
-
keys.push(key);
|
|
724
|
-
activeToolTimeoutKeysByName.set(toolName, keys);
|
|
725
|
-
};
|
|
726
|
-
registerTimeout?.(() => terminateForTimeout(timeoutMessage ?? "Subagent timed out."));
|
|
727
|
-
registerStop?.(() => {
|
|
728
|
-
if (settled || timedOut || stopped)
|
|
729
|
-
return;
|
|
730
|
-
stopped = true;
|
|
731
|
-
interrupted = false;
|
|
732
|
-
error = stopMessage ?? "Subagent stopped by user.";
|
|
733
|
-
if (processTreeController)
|
|
734
|
-
processTreeController.terminate();
|
|
735
|
-
else
|
|
736
|
-
trySignalChild(child, "SIGTERM");
|
|
737
|
-
});
|
|
738
|
-
const clearDrainTimers = () => {
|
|
739
|
-
clearAllToolTimeouts();
|
|
740
|
-
if (finalDrainTimer) {
|
|
741
|
-
clearTimeout(finalDrainTimer);
|
|
742
|
-
finalDrainTimer = undefined;
|
|
743
|
-
}
|
|
744
|
-
if (finalHardKillTimer) {
|
|
745
|
-
clearTimeout(finalHardKillTimer);
|
|
746
|
-
finalHardKillTimer = undefined;
|
|
747
|
-
}
|
|
748
|
-
clearWatchdogTailTimer();
|
|
749
|
-
if (protocolHardKillTimer) {
|
|
750
|
-
clearTimeout(protocolHardKillTimer);
|
|
751
|
-
protocolHardKillTimer = undefined;
|
|
752
|
-
}
|
|
753
|
-
};
|
|
754
|
-
function startFinalDrain() {
|
|
755
|
-
if (childWatchdogIsActive(childWatchdogState)) {
|
|
756
|
-
armWatchdogTail();
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
if (childExited || finalDrainTimer || settled)
|
|
760
|
-
return;
|
|
761
|
-
finalDrainTimer = setTimeout(() => {
|
|
762
|
-
if (settled)
|
|
763
|
-
return;
|
|
764
|
-
const termSent = trySignalChild(child, "SIGTERM");
|
|
765
|
-
if (!termSent)
|
|
766
|
-
return;
|
|
767
|
-
forcedTerminationSignal = true;
|
|
768
|
-
if (!cleanTerminalAssistantStopReceived && !agentSettledReceived && !error && !assistantError) {
|
|
769
|
-
error = `Subagent process did not exit within ${FINAL_STOP_GRACE_MS}ms after its terminal event. Forcing termination.`;
|
|
770
|
-
}
|
|
771
|
-
finalHardKillTimer = setTimeout(() => {
|
|
772
|
-
if (settled)
|
|
773
|
-
return;
|
|
774
|
-
forcedTerminationSignal = trySignalChild(child, "SIGKILL") || forcedTerminationSignal;
|
|
775
|
-
}, HARD_KILL_MS);
|
|
776
|
-
finalHardKillTimer.unref?.();
|
|
777
|
-
}, FINAL_STOP_GRACE_MS);
|
|
778
|
-
finalDrainTimer.unref?.();
|
|
779
|
-
}
|
|
780
|
-
function clearWatchdogTailTimer() {
|
|
781
|
-
if (watchdogTailTimer) {
|
|
782
|
-
clearTimeout(watchdogTailTimer);
|
|
783
|
-
watchdogTailTimer = undefined;
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
function armWatchdogTail() {
|
|
787
|
-
if (!cleanTerminalAssistantStopReceived && !agentSettledReceived || watchdogTailTimer || settled)
|
|
788
|
-
return;
|
|
789
|
-
watchdogTailTimer = setTimeout(() => {
|
|
790
|
-
watchdogTailTimer = undefined;
|
|
791
|
-
updateChildWatchdogState({
|
|
792
|
-
phase: "stale",
|
|
793
|
-
seq: (childWatchdogState?.seq ?? 0) + 1,
|
|
794
|
-
lastUpdate: Date.now(),
|
|
795
|
-
followUpPending: false,
|
|
796
|
-
reason: "child watchdog tail timeout",
|
|
797
|
-
timedOut: true
|
|
798
|
-
});
|
|
799
|
-
startFinalDrain();
|
|
800
|
-
}, childWatchdogConfig?.watchdogTailTimeoutMs ?? 120000);
|
|
801
|
-
watchdogTailTimer.unref?.();
|
|
802
|
-
}
|
|
803
|
-
child.on("exit", () => {
|
|
804
|
-
childExited = true;
|
|
805
|
-
clearDrainTimers();
|
|
806
|
-
});
|
|
807
|
-
child.on("close", async (exitCode, signal) => {
|
|
808
|
-
settled = true;
|
|
809
|
-
const processCloseObservedAt = Date.now();
|
|
810
|
-
const processTree = processTreeController ? await processTreeController.finishAfterWriterClose() : { state: "unknown", reason: "verification-failed", diagnostic: "Writer PID was unavailable." };
|
|
811
|
-
try {
|
|
812
|
-
onWriterProcess?.({ state: "none" });
|
|
813
|
-
} catch {}
|
|
814
|
-
registerInterrupt?.(undefined);
|
|
815
|
-
registerTimeout?.(undefined);
|
|
816
|
-
registerStop?.(undefined);
|
|
817
|
-
clearDrainTimers();
|
|
818
|
-
clearStdioGuard();
|
|
819
|
-
stdoutReader.end();
|
|
820
|
-
stderrReader.end();
|
|
821
|
-
outputStream.end();
|
|
822
|
-
const stderr = stderrTail.text();
|
|
823
|
-
const finalOutput = getFinalOutput(messages) || rawStdoutTail.text().trim();
|
|
824
|
-
const finalError = error ?? assistantError;
|
|
825
|
-
const forcedDrainAfterFinalSuccess = Boolean(forcedTerminationSignal || signal) && (cleanTerminalAssistantStopReceived || agentSettledReceived) && !finalError;
|
|
826
|
-
const forcedDrainAfterEmptyTerminal = forcedDrainAfterFinalSuccess && hasEmptyTerminalAssistantResponse(messages);
|
|
827
|
-
const forcedDrainError = forcedDrainAfterEmptyTerminal && stderr.trim() ? stderr.trim() : undefined;
|
|
828
|
-
const signalError = isUnexplainedProcessSignal({
|
|
829
|
-
processSignal: signal,
|
|
830
|
-
interrupted,
|
|
831
|
-
timedOut,
|
|
832
|
-
stopped,
|
|
833
|
-
forcedDrainAfterFinalSuccess: forcedDrainAfterFinalSuccess && !forcedDrainAfterEmptyTerminal
|
|
834
|
-
}) ? formatProcessSignalError(signal) : undefined;
|
|
835
|
-
resolve(omitUndefinedProperties({
|
|
836
|
-
stderr,
|
|
837
|
-
exitCode: timedOut || stopped ? 1 : interrupted || forcedDrainAfterFinalSuccess && !forcedDrainAfterEmptyTerminal ? 0 : forcedTerminationSignal || signal ? exitCode ?? 1 : exitCode,
|
|
838
|
-
messages,
|
|
839
|
-
usage,
|
|
840
|
-
toolCount,
|
|
841
|
-
durationMs: Date.now() - startedAt,
|
|
842
|
-
model,
|
|
843
|
-
error: stopped ? stopMessage ?? "Subagent stopped by user." : timedOut ? timeoutMessage ?? "Subagent timed out." : interrupted || forcedDrainAfterFinalSuccess && !forcedDrainAfterEmptyTerminal ? undefined : finalError ?? forcedDrainError ?? signalError,
|
|
844
|
-
protocolError,
|
|
845
|
-
finalOutput: (timedOut || stopped) && !finalOutput.trim() ? stopped ? stopMessage ?? "Subagent stopped by user." : timeoutMessage ?? "Subagent timed out." : finalOutput,
|
|
846
|
-
outputState: finalOutput.trim() ? "present" : "absent",
|
|
847
|
-
interrupted,
|
|
848
|
-
timedOut,
|
|
849
|
-
stopped,
|
|
850
|
-
observedMutationAttempt,
|
|
851
|
-
structuredOutputToolInvoked,
|
|
852
|
-
structuredOutputMessageStartIndex,
|
|
853
|
-
watchdog: childWatchdogState,
|
|
854
|
-
processInstanceId,
|
|
855
|
-
processCloseObservedAt,
|
|
856
|
-
processSignal: signal,
|
|
857
|
-
processTree,
|
|
858
|
-
currentTool,
|
|
859
|
-
currentToolArgs,
|
|
860
|
-
currentPath,
|
|
861
|
-
afterCompactionSettlement: afterCompactionSettlement || undefined
|
|
862
|
-
}));
|
|
863
|
-
});
|
|
864
|
-
child.on("error", (spawnError) => {
|
|
865
|
-
settled = true;
|
|
866
|
-
try {
|
|
867
|
-
onWriterProcess?.({ state: "none" });
|
|
868
|
-
} catch {}
|
|
869
|
-
registerInterrupt?.(undefined);
|
|
870
|
-
registerTimeout?.(undefined);
|
|
871
|
-
registerStop?.(undefined);
|
|
872
|
-
clearDrainTimers();
|
|
873
|
-
clearStdioGuard();
|
|
874
|
-
stdoutReader.end();
|
|
875
|
-
stderrReader.end();
|
|
876
|
-
outputStream.end();
|
|
877
|
-
const stderr = stderrTail.text();
|
|
878
|
-
const finalOutput = getFinalOutput(messages) || rawStdoutTail.text().trim();
|
|
879
|
-
const spawnErrorMessage = spawnError instanceof Error ? spawnError.message : String(spawnError);
|
|
880
|
-
resolve(omitUndefinedProperties({ stderr, exitCode: 1, messages, usage, toolCount, durationMs: Date.now() - startedAt, model, error: stopped ? stopMessage ?? "Subagent stopped by user." : timedOut ? timeoutMessage ?? "Subagent timed out." : error ?? assistantError ?? spawnErrorMessage, protocolError, finalOutput: (timedOut || stopped) && !finalOutput.trim() ? stopped ? stopMessage ?? "Subagent stopped by user." : timeoutMessage ?? "Subagent timed out." : finalOutput, outputState: finalOutput.trim() ? "present" : "absent", timedOut, stopped, observedMutationAttempt, structuredOutputToolInvoked, structuredOutputMessageStartIndex, watchdog: childWatchdogState, processInstanceId, processTree: { state: "unknown", reason: "verification-failed", diagnostic: spawnErrorMessage } }));
|
|
881
|
-
});
|
|
882
|
-
});
|
|
883
|
-
}
|
|
884
298
|
function resolvePiPackageRootFallback() {
|
|
885
299
|
const root = resolveInstalledPiPackageRoot();
|
|
886
300
|
if (root)
|
|
@@ -969,7 +383,68 @@ function writeRunLog(logPath, input, write = (filePath, content) => fs.writeFile
|
|
|
969
383
|
write(logPath, lines.join(`
|
|
970
384
|
`));
|
|
971
385
|
}
|
|
972
|
-
|
|
386
|
+
function expectedMissingGitEvidence(error) {
|
|
387
|
+
if (typeof error?.code !== "number")
|
|
388
|
+
return false;
|
|
389
|
+
const stderr = error.stderr;
|
|
390
|
+
const detail = Buffer.isBuffer(stderr) ? stderr.toString("utf-8") : String(stderr ?? "");
|
|
391
|
+
return /not a git repository|Needed a single revision/i.test(detail);
|
|
392
|
+
}
|
|
393
|
+
async function readGitFingerprint(cwd, signal, onError) {
|
|
394
|
+
try {
|
|
395
|
+
const runGit = async (args) => {
|
|
396
|
+
const result = await runSetupCommand("git", args, {
|
|
397
|
+
cwd,
|
|
398
|
+
signal,
|
|
399
|
+
maxBuffer: 16777216,
|
|
400
|
+
deadlineAt: Date.now() + 30000,
|
|
401
|
+
acceptedExitCodes: Array.from({ length: 256 }, (_, code) => code)
|
|
402
|
+
});
|
|
403
|
+
if (result.error)
|
|
404
|
+
throw result.error;
|
|
405
|
+
if (result.status !== 0) {
|
|
406
|
+
throw Object.assign(new Error(result.stderr || `git exited with ${result.status}`), { code: result.status, stderr: result.stderr });
|
|
407
|
+
}
|
|
408
|
+
return result.stdoutBuffer;
|
|
409
|
+
};
|
|
410
|
+
const headOutput = await runGit(["rev-parse", "--verify", "HEAD"]);
|
|
411
|
+
const head = headOutput.toString("utf-8").trim();
|
|
412
|
+
if (!head)
|
|
413
|
+
return;
|
|
414
|
+
const status = await runGit(["status", "--porcelain=v1", "-z", "--untracked-files=normal"]);
|
|
415
|
+
return `${head}\x00${status.toString("base64")}`;
|
|
416
|
+
} catch (error) {
|
|
417
|
+
if (error?.code === "PROCESS_TREE_UNVERIFIED")
|
|
418
|
+
throw error;
|
|
419
|
+
if (!signal.aborted && !expectedMissingGitEvidence(error))
|
|
420
|
+
onError(error);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
function decorateHerdrMachineResult(result, machine, adapter) {
|
|
425
|
+
let stderrTail = "";
|
|
426
|
+
try {
|
|
427
|
+
const stderr = fs.readFileSync(result.externalProcess.stderrPath, "utf-8");
|
|
428
|
+
stderrTail = stderr.slice(-4096);
|
|
429
|
+
} catch {}
|
|
430
|
+
const hint = result.exitCode === 0 ? undefined : formatHerdrMachineHint(machine, `${result.error ?? ""}
|
|
431
|
+
${stderrTail}
|
|
432
|
+
exit code ${result.exitCode}`);
|
|
433
|
+
const error = hint ? `${result.error ?? `Remote command exited with code ${result.exitCode}.`}
|
|
434
|
+
${hint}` : result.error;
|
|
435
|
+
const note = result.exitCode === 0 && adapter?.endsWith("-writer") ? `Changes made by this run live on ${machine.label ?? machine.id} at ${machine.cwd}; the local checkout is unchanged.` : undefined;
|
|
436
|
+
const output = note ? result.output.trim() ? `${result.output.trimEnd()}
|
|
437
|
+
|
|
438
|
+
${note}` : note : result.output;
|
|
439
|
+
return { ...result, output, ...error !== undefined ? { error } : {} };
|
|
440
|
+
}
|
|
441
|
+
export async function settleHerdrExternalRunnerError(error, adapter, evidence, retain) {
|
|
442
|
+
await retain();
|
|
443
|
+
if (!(error instanceof HerdrExternalNeedsAttentionError))
|
|
444
|
+
throw error;
|
|
445
|
+
return createHerdrExternalAdapter(adapter).normalize(evidence, error.message);
|
|
446
|
+
}
|
|
447
|
+
export async function runSingleStepInner(step, ctx) {
|
|
973
448
|
if (step.importAsyncRoot) {
|
|
974
449
|
let importTimedOut = false;
|
|
975
450
|
let importStopped = false;
|
|
@@ -1018,8 +493,7 @@ async function runSingleStepInner(step, ctx) {
|
|
|
1018
493
|
sessionFile: imported.sessionFile,
|
|
1019
494
|
intercomTarget: imported.intercomTarget,
|
|
1020
495
|
model: imported.model,
|
|
1021
|
-
|
|
1022
|
-
modelAttempts: imported.modelAttempts,
|
|
496
|
+
requestedModel: imported.requestedModel,
|
|
1023
497
|
contextOverflow: imported.contextOverflow,
|
|
1024
498
|
totalCost: imported.totalCost,
|
|
1025
499
|
usage: imported.usage,
|
|
@@ -1035,58 +509,34 @@ async function runSingleStepInner(step, ctx) {
|
|
|
1035
509
|
ctx.registerStop?.(undefined);
|
|
1036
510
|
}
|
|
1037
511
|
}
|
|
1038
|
-
const effectiveStructuredOutput = step.structuredOutput ?? (step.structuredOutputSchema ? createStructuredOutputRuntime(step.structuredOutputSchema, path.join(path.dirname(ctx.outputFile), "structured-output")) : undefined);
|
|
512
|
+
const effectiveStructuredOutput = step.structuredOutput ?? (step.structuredOutputSchema ? createStructuredOutputRuntime(step.structuredOutputSchema, path.join(path.dirname(ctx.outputFile), "structured-output"), { acceptanceReport: resolveAcceptanceReportMode(step.acceptanceInput) }) : undefined);
|
|
1039
513
|
const placeholderRegex = new RegExp(ctx.placeholder.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g");
|
|
1040
514
|
let task = step.task.replace(placeholderRegex, () => ctx.previousOutput);
|
|
1041
515
|
if (ctx.outputs)
|
|
1042
516
|
task = resolveOutputReferences(task, ctx.outputs);
|
|
1043
|
-
const taskForCompletionGuard = task;
|
|
1044
517
|
let resolvedTaskToolPlan;
|
|
1045
518
|
if (!step.runner) {
|
|
1046
519
|
resolvedTaskToolPlan = resolvePiLaunchToolPlan(omitUndefinedProperties({
|
|
1047
520
|
tools: step.tools,
|
|
521
|
+
excludeTools: step.excludeTools,
|
|
1048
522
|
allowNestedSubagents: step.allowNestedSubagents,
|
|
1049
523
|
extensions: step.extensions,
|
|
1050
524
|
subagentOnlyExtensions: step.subagentOnlyExtensions,
|
|
1051
525
|
fast: step.fast,
|
|
1052
526
|
model: step.model,
|
|
1053
|
-
modelCandidates: step.modelCandidates,
|
|
1054
527
|
mcpDirectTools: step.mcpDirectTools,
|
|
1055
|
-
mcpConfig: step.mcpConfig,
|
|
1056
|
-
runtimeServerNames: step.runtimeServerNames,
|
|
1057
528
|
cwd: step.cwd ?? ctx.cwd,
|
|
1058
529
|
requireReadTool: Boolean(step.skills?.length),
|
|
1059
530
|
structuredOutput: Boolean(effectiveStructuredOutput),
|
|
1060
531
|
capabilityCeiling: step.capabilityCeiling ?? ctx.capabilityCeiling,
|
|
1061
|
-
inheritedCapabilityCeiling:
|
|
532
|
+
inheritedCapabilityCeiling: ctx.inheritedChildRuntime?.capabilityCeiling,
|
|
533
|
+
requiredExtensions: step.requiredExtensions ?? ctx.inheritedChildRuntime?.requiredExtensions,
|
|
1062
534
|
permissionRules: step.permissionRules
|
|
1063
535
|
}));
|
|
1064
|
-
const contractTools = resolvedTaskToolPlan.explicitToolAllowlist ? resolvedTaskToolPlan.effectiveToolAllowlist : undefined;
|
|
1065
|
-
const contractError = validateImplementationToolContract({
|
|
1066
|
-
agent: step.agent,
|
|
1067
|
-
task: taskForCompletionGuard,
|
|
1068
|
-
tools: contractTools,
|
|
1069
|
-
mcpDirectTools: resolvedTaskToolPlan.effectiveMcpTools,
|
|
1070
|
-
configuredExtensions: resolvedTaskToolPlan.configuredExtensions,
|
|
1071
|
-
requestedTools: resolvedTaskToolPlan.requestedBuiltinTools,
|
|
1072
|
-
acceptanceRole: step.acceptanceRole,
|
|
1073
|
-
completionGuard: step.completionGuard
|
|
1074
|
-
});
|
|
1075
|
-
if (contractError) {
|
|
1076
|
-
return omitUndefinedProperties({
|
|
1077
|
-
agent: step.agent,
|
|
1078
|
-
context: step.context,
|
|
1079
|
-
output: contractError,
|
|
1080
|
-
error: contractError,
|
|
1081
|
-
exitCode: 1,
|
|
1082
|
-
capabilityCeiling: resolvedTaskToolPlan.capabilityCeiling,
|
|
1083
|
-
capabilityAudit: resolvedTaskToolPlan.capabilityAudit
|
|
1084
|
-
});
|
|
1085
|
-
}
|
|
1086
536
|
}
|
|
1087
537
|
const childSessionName = step.sessionName ?? deriveChildSessionName({ agent: step.agent, task, label: step.label });
|
|
1088
|
-
if (step.effectiveAcceptance) {
|
|
1089
|
-
const acceptancePrompt = formatAcceptancePrompt(step.effectiveAcceptance, { reportOptional:
|
|
538
|
+
if (step.effectiveAcceptance && (step.runner?.type === "external-cli" || step.runner?.type === "external-job")) {
|
|
539
|
+
const acceptancePrompt = formatAcceptancePrompt(step.effectiveAcceptance, { reportOptional: isAgentContract(step.agentContract), structuredOutput: Boolean(step.structuredOutput?.acceptanceReportPath) });
|
|
1090
540
|
if (acceptancePrompt)
|
|
1091
541
|
task = `${task}
|
|
1092
542
|
${acceptancePrompt}`;
|
|
@@ -1118,11 +568,81 @@ ${PROMPT_REDACTED}; live Prompt Audit only.
|
|
|
1118
568
|
}
|
|
1119
569
|
transcriptWriter?.writeInitialUserMessage(`${PROMPT_REDACTED}; live Prompt Audit only.`);
|
|
1120
570
|
if (step.runner?.type === "external-cli") {
|
|
1121
|
-
const externalCwd = step.cwd ?? ctx.cwd;
|
|
571
|
+
const externalCwd = step.machine?.cwd ?? step.cwd ?? ctx.cwd;
|
|
572
|
+
const externalAbortSignal = combinedAbortSignal([ctx.timeoutSignal, ctx.stopSignal]);
|
|
573
|
+
if (!step.machine && externalAbortSignal)
|
|
574
|
+
await ctx.prepareExternalActivity?.(externalCwd, externalAbortSignal);
|
|
575
|
+
if (externalAbortSignal?.aborted) {
|
|
576
|
+
const stopped = ctx.stopSignal?.aborted === true;
|
|
577
|
+
const message = stopped ? ctx.stopMessage ?? "Subagent stopped by user." : ctx.timeoutMessage ?? "Subagent timed out.";
|
|
578
|
+
return omitUndefinedProperties({ agent: step.agent, context: step.context, output: message, error: message, exitCode: 1, stopped: stopped || undefined, timedOut: stopped ? undefined : true });
|
|
579
|
+
}
|
|
580
|
+
if (step.machine) {
|
|
581
|
+
const runner = resolveExternalCliRunnerStatus({ ...step.runner, machine: step.machine });
|
|
582
|
+
const outputSnapshot = captureSingleOutputSnapshot(step.outputPath);
|
|
583
|
+
const placedRunId = `${ctx.id}-${ctx.flatIndex}`;
|
|
584
|
+
const session = await prepareInternalHerdrExternalAdapter({ adapter: step.runner.adapter, machine: step.machine, runId: placedRunId }, {});
|
|
585
|
+
let timedOut = false, stopped = false, retain = false;
|
|
586
|
+
const evidenceInput = { runId: placedRunId, requestId: `prompt-${ctx.flatIndex}`, task: buildExternalCliPrompt(step.systemPrompt ?? "", task), cwd: externalCwd, nativeSessionId: session.launch.nativeSessionId };
|
|
587
|
+
let resolveInterruption, rejectInterruption;
|
|
588
|
+
const interruption = new Promise((resolve, reject) => {
|
|
589
|
+
resolveInterruption = resolve;
|
|
590
|
+
rejectInterruption = reject;
|
|
591
|
+
});
|
|
592
|
+
ctx.registerTimeout?.(() => {
|
|
593
|
+
timedOut = true;
|
|
594
|
+
retain = true;
|
|
595
|
+
resolveInterruption("timeout");
|
|
596
|
+
});
|
|
597
|
+
ctx.registerStop?.(() => {
|
|
598
|
+
stopped = true;
|
|
599
|
+
session.abort().then(() => resolveInterruption("stop"), rejectInterruption);
|
|
600
|
+
});
|
|
601
|
+
try {
|
|
602
|
+
let settled;
|
|
603
|
+
try {
|
|
604
|
+
const raced = await Promise.race([session.promptAndSettle(evidenceInput).then((value) => ({ kind: "settled", value })), interruption.then((kind) => ({ kind }))]);
|
|
605
|
+
if (raced.kind === "settled")
|
|
606
|
+
settled = raced.value;
|
|
607
|
+
else if (raced.kind === "timeout")
|
|
608
|
+
settled = createHerdrExternalAdapter(step.runner.adapter).normalize(evidenceInput, "Placed external run timed out; truthful pane retained for inspection.");
|
|
609
|
+
else
|
|
610
|
+
return { agent: step.agent, context: step.context, output: "Placed external run stopped by user.", outputState: "present", exitCode: 1, stopped: true, runner, execution: { status: "stopped", success: false, exitCode: 1, stopped: true } };
|
|
611
|
+
} catch (error) {
|
|
612
|
+
retain = true;
|
|
613
|
+
settled = await settleHerdrExternalRunnerError(error, step.runner.adapter, evidenceInput, () => session.retain());
|
|
614
|
+
}
|
|
615
|
+
const output = settled.output;
|
|
616
|
+
try {
|
|
617
|
+
fs.writeFileSync(ctx.outputFile, output, "utf-8");
|
|
618
|
+
} catch {}
|
|
619
|
+
const resolvedOutput = step.outputPath ? resolveSingleOutput(step.outputPath, output, outputSnapshot, step.outputClaimPath) : { fullOutput: output };
|
|
620
|
+
const outputReference = resolvedOutput.savedPath ? formatSavedOutputReference(resolvedOutput.savedPath, resolvedOutput.fullOutput) : undefined;
|
|
621
|
+
const finalizedOutput = finalizeSingleOutput(omitUndefinedProperties({ fullOutput: resolvedOutput.fullOutput, outputPath: step.outputPath, outputMode: step.outputMode, exitCode: 1, preserveSavedOutput: true, savedPath: resolvedOutput.savedPath, outputReference, saveError: resolvedOutput.saveError }));
|
|
622
|
+
const artifactErrors = artifactPaths && ctx.artifactConfig?.enabled !== false ? persistStepArtifacts({ artifactPaths, artifactConfig: ctx.artifactConfig, output: formatOutputArtifactContent(omitUndefinedProperties({ output: resolvedOutput.fullOutput, metadataPath: ctx.artifactConfig?.includeMetadata === false ? undefined : artifactPaths.metadataPath })), metadata: { runId: ctx.id, agent: step.agent, task: PROMPT_REDACTED, runner, placement: session.owner.identity, settlement: settled.settlement, outcome: settled.outcome, timestamp: Date.now() } }) : {};
|
|
623
|
+
return omitUndefinedProperties({ agent: step.agent, ...childSessionName ? { sessionName: childSessionName } : {}, context: step.context, output: finalizedOutput.displayOutput, outputState: output.trim() ? "present" : "absent", exitCode: 1, error: resolvedOutput.fatalError ? resolvedOutput.saveError : undefined, timedOut, stopped, artifactPaths, outputSaveError: [resolvedOutput.saveError, artifactErrors.outputSaveError].filter(Boolean).join(`
|
|
624
|
+
`) || undefined, metadataSaveError: artifactErrors.metadataSaveError, runner, execution: { status: "partial", success: false, exitCode: 1 } });
|
|
625
|
+
} catch (error) {
|
|
626
|
+
retain = true;
|
|
627
|
+
throw error;
|
|
628
|
+
} finally {
|
|
629
|
+
ctx.registerTimeout?.(undefined);
|
|
630
|
+
ctx.registerStop?.(undefined);
|
|
631
|
+
if (retain)
|
|
632
|
+
await session.retain();
|
|
633
|
+
else
|
|
634
|
+
await session.dispose();
|
|
635
|
+
}
|
|
636
|
+
}
|
|
1122
637
|
const adapterLaunch = step.runner.adapter === "codex-exec" || step.runner.adapter === "codex-exec-writer" ? resolveCodexExecLaunch({ adapter: step.runner.adapter, command: step.runner.command, asyncDir: path.dirname(ctx.outputFile), stepIndex: ctx.flatIndex }) : step.runner.adapter === "claude-code" || step.runner.adapter === "claude-code-writer" ? resolveClaudeCodeLaunch({ adapter: step.runner.adapter, command: step.runner.command }) : step.runner.adapter === "cursor-agent" || step.runner.adapter === "cursor-agent-writer" ? resolveCursorAgentLaunch({ adapter: step.runner.adapter, command: step.runner.command, cwd: externalCwd, asyncDir: path.dirname(ctx.outputFile), stepIndex: ctx.flatIndex }) : undefined;
|
|
1123
|
-
const runner = resolveExternalCliRunnerStatus({ ...step.runner, ...adapterLaunch ? { args: adapterLaunch.args } : {} });
|
|
638
|
+
const runner = resolveExternalCliRunnerStatus({ ...step.runner, ...adapterLaunch ? { args: adapterLaunch.args } : {}, ...step.machine ? { machine: step.machine } : {} });
|
|
1124
639
|
const outputSnapshot = captureSingleOutputSnapshot(step.outputPath);
|
|
1125
|
-
const
|
|
640
|
+
const onExternalOutput = (chunk) => {
|
|
641
|
+
if (chunk.length > 0)
|
|
642
|
+
ctx.onExternalStreamActivity?.();
|
|
643
|
+
ctx.orcaProgressTab?.append(chunk.toString("utf-8"));
|
|
644
|
+
};
|
|
645
|
+
const externalInput = omitUndefinedProperties({
|
|
1126
646
|
command: adapterLaunch?.command ?? runner.command,
|
|
1127
647
|
args: adapterLaunch?.args ?? runner.args,
|
|
1128
648
|
cwd: externalCwd,
|
|
@@ -1140,9 +660,13 @@ ${PROMPT_REDACTED}; live Prompt Audit only.
|
|
|
1140
660
|
timeoutMessage: ctx.timeoutMessage,
|
|
1141
661
|
stopMessage: ctx.stopMessage,
|
|
1142
662
|
onProcess: ctx.onExternalProcess,
|
|
1143
|
-
onStdout:
|
|
1144
|
-
onStderr:
|
|
1145
|
-
})
|
|
663
|
+
onStdout: onExternalOutput,
|
|
664
|
+
onStderr: onExternalOutput
|
|
665
|
+
});
|
|
666
|
+
const preparedExternal = prepareHerdrMachineExternalCliRun(externalInput, step.machine ? { machine: step.machine, ...step.machineEnv ? { env: step.machineEnv } : {} } : undefined, { localCwd: ctx.cwd });
|
|
667
|
+
const ran = await runExternalCli(preparedExternal.input);
|
|
668
|
+
const externalProcess = preparedExternal.decorateProcess(ran.externalProcess);
|
|
669
|
+
const external = step.machine ? decorateHerdrMachineResult(ran, step.machine, step.runner.adapter) : ran;
|
|
1146
670
|
try {
|
|
1147
671
|
fs.writeFileSync(ctx.outputFile, external.output, "utf-8");
|
|
1148
672
|
} catch {}
|
|
@@ -1164,7 +688,7 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError : external.error;
|
|
|
1164
688
|
artifactPaths,
|
|
1165
689
|
artifactConfig: ctx.artifactConfig,
|
|
1166
690
|
output: formatOutputArtifactContent(omitUndefinedProperties({ output: resolvedOutput.fullOutput, error: external.error, metadataPath: ctx.artifactConfig?.includeMetadata === false ? undefined : artifactPaths.metadataPath })),
|
|
1167
|
-
metadata: { runId: ctx.id, agent: step.agent, task: PROMPT_REDACTED, runner, externalProcess
|
|
691
|
+
metadata: { runId: ctx.id, agent: step.agent, task: PROMPT_REDACTED, runner, externalProcess, exitCode: external.exitCode, error: external.error, timestamp: Date.now() }
|
|
1168
692
|
}) : {};
|
|
1169
693
|
return omitUndefinedProperties({
|
|
1170
694
|
agent: step.agent,
|
|
@@ -1180,9 +704,10 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError : external.error;
|
|
|
1180
704
|
artifactPaths,
|
|
1181
705
|
outputSaveError: [resolvedOutput.saveError, artifactErrors.outputSaveError].filter(Boolean).join(`
|
|
1182
706
|
`) || undefined,
|
|
707
|
+
artifactOutputSaveFailed: artifactErrors.outputSaveError ? true : undefined,
|
|
1183
708
|
metadataSaveError: artifactErrors.metadataSaveError,
|
|
1184
709
|
runner,
|
|
1185
|
-
externalProcess
|
|
710
|
+
externalProcess
|
|
1186
711
|
});
|
|
1187
712
|
}
|
|
1188
713
|
if (step.runner?.type === "external-job") {
|
|
@@ -1246,6 +771,7 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError : external.error;
|
|
|
1246
771
|
artifactPaths,
|
|
1247
772
|
outputSaveError: [resolvedOutput.saveError, artifactErrors.outputSaveError].filter(Boolean).join(`
|
|
1248
773
|
`) || undefined,
|
|
774
|
+
artifactOutputSaveFailed: artifactErrors.outputSaveError ? true : undefined,
|
|
1249
775
|
metadataSaveError: artifactErrors.metadataSaveError,
|
|
1250
776
|
runner,
|
|
1251
777
|
externalJob: external.externalJob
|
|
@@ -1255,58 +781,51 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError : external.error;
|
|
|
1255
781
|
const cwdError = preflightLaunchCwd(step.requestedCwd ?? effectiveCwd, effectiveCwd);
|
|
1256
782
|
if (cwdError)
|
|
1257
783
|
return { agent: step.agent, output: cwdError, error: cwdError, exitCode: 1, context: step.context };
|
|
1258
|
-
|
|
1259
|
-
|
|
784
|
+
if (step.context === "fork" && step.sessionFile && fs.existsSync(step.sessionFile)) {
|
|
785
|
+
alignForkedSessionCwd(step.sessionFile, effectiveCwd);
|
|
786
|
+
}
|
|
787
|
+
const candidate = step.model;
|
|
1260
788
|
let capabilityAudit;
|
|
1261
789
|
let launchResolvedExtensions = step.launchResolvedExtensions;
|
|
1262
|
-
const modelAttempts = [];
|
|
1263
|
-
const writerProcesses = [];
|
|
1264
|
-
let writerAttemptCount = 0;
|
|
1265
|
-
const attemptNotes = [];
|
|
1266
790
|
let finalRequiredOutputMissing;
|
|
1267
791
|
const eventsPath = path.join(path.dirname(ctx.outputFile), "events.jsonl");
|
|
1268
792
|
let finalResult;
|
|
1269
793
|
let finalOutputSnapshot;
|
|
1270
794
|
let structuredAcceptanceReport;
|
|
1271
795
|
let structuredAcceptanceReportError;
|
|
1272
|
-
let completionGuardTriggeredFinal = false;
|
|
1273
796
|
let toolBudget = step.toolBudget ? initialToolBudgetState(step.toolBudget) : undefined;
|
|
1274
797
|
let toolBudgetBlocked = false;
|
|
1275
798
|
let actualLaunchContractDigest = step.launchContractDigest;
|
|
1276
|
-
const mutationSnapshot = snapshotTrackedMutations(step.cwd ?? ctx.cwd);
|
|
799
|
+
const mutationSnapshot = step.machine ? { source: "tracked-files", trackedOnly: true, cwd: step.cwd ?? ctx.cwd, dirtyFiles: [], fingerprints: {}, unavailable: "Local Git evidence is not authoritative for a pane-native remote run." } : snapshotTrackedMutations(step.cwd ?? ctx.cwd);
|
|
1277
800
|
let finalMutationEvidence = collectTrackedMutationEvidence(mutationSnapshot, step.cwd ?? ctx.cwd);
|
|
1278
|
-
let modelIndex = 0;
|
|
1279
|
-
let startupAttemptIndex = 0;
|
|
1280
|
-
let taskDeliveryOverride;
|
|
1281
801
|
let contextOverflow = false;
|
|
1282
802
|
let launchWarningsEmitted = false;
|
|
1283
|
-
|
|
1284
|
-
let
|
|
1285
|
-
|
|
1286
|
-
|
|
803
|
+
const aggregateUsage = emptyUsage();
|
|
804
|
+
let launched = false;
|
|
805
|
+
let recoveryTask = task;
|
|
806
|
+
let stagedIndexBaseline;
|
|
807
|
+
singleLaunch:
|
|
808
|
+
for (let attemptIndex = 0;attemptIndex < 2; attemptIndex++) {
|
|
1287
809
|
if (ctx.timeoutSignal?.aborted || ctx.stopSignal?.aborted || ctx.skipAcceptance?.())
|
|
1288
|
-
break;
|
|
1289
|
-
const
|
|
1290
|
-
const attemptTask = nextAttemptTask;
|
|
1291
|
-
const candidate = candidates[modelIndex];
|
|
1292
|
-
const expectedModelForVerification = candidate && !(step.skipPrimaryModelVerification && modelIndex === 0) ? candidate : undefined;
|
|
810
|
+
break singleLaunch;
|
|
811
|
+
const expectedModelForVerification = candidate && !step.skipPrimaryModelVerification ? candidate : undefined;
|
|
1293
812
|
try {
|
|
1294
|
-
assertThinkingWithinCeiling({ model: candidate, configThinking: step.thinking, ceiling: step.thinkingCeiling
|
|
813
|
+
assertThinkingWithinCeiling({ model: candidate, configThinking: step.thinking, ceiling: step.thinkingCeiling, agent: step.agent, runId: ctx.id });
|
|
1295
814
|
} catch (error) {
|
|
1296
815
|
const message = error instanceof Error ? error.message : String(error);
|
|
1297
816
|
return omitUndefinedProperties({ agent: step.agent, output: message, error: message, exitCode: 1, context: step.context, thinkingCeiling: step.thinkingCeiling });
|
|
1298
817
|
}
|
|
818
|
+
const attemptModel = omitUndefinedProperties({ model: candidate, thinking: resolveEffectiveThinking(candidate, step.thinking) });
|
|
1299
819
|
ctx.onAttemptStart?.(omitUndefinedProperties({
|
|
1300
|
-
|
|
1301
|
-
thinking: resolveEffectiveThinking(candidate, step.thinking),
|
|
820
|
+
...attemptModel,
|
|
1302
821
|
contextLimit: findModelInfo(candidate, step.modelVerificationRegistry)?.contextWindow
|
|
1303
822
|
}));
|
|
1304
823
|
const outputSnapshot = captureSingleOutputSnapshot(step.outputPath);
|
|
1305
824
|
if (effectiveStructuredOutput) {
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
}
|
|
825
|
+
const cleanupError = clearStructuredOutputCaptures(effectiveStructuredOutput);
|
|
826
|
+
if (cleanupError) {
|
|
827
|
+
return omitUndefinedProperties({ agent: step.agent, output: cleanupError, error: cleanupError, exitCode: 1, context: step.context });
|
|
828
|
+
}
|
|
1310
829
|
}
|
|
1311
830
|
const watchdogConfig = resolveWatchdogConfig(step.cwd ?? ctx.cwd);
|
|
1312
831
|
const extensionBindings = normalizeExtensionBindings(step.extensionBindings)?.value;
|
|
@@ -1316,61 +835,25 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError : external.error;
|
|
|
1316
835
|
runId: ctx.id,
|
|
1317
836
|
childIndex: ctx.flatIndex
|
|
1318
837
|
}) : undefined;
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
modelCandidates: step.modelCandidates,
|
|
1339
|
-
systemPrompt: step.systemPrompt ?? "",
|
|
1340
|
-
systemPromptMode: step.systemPromptMode,
|
|
1341
|
-
mcpDirectTools: step.mcpDirectTools,
|
|
1342
|
-
mcpConfig: step.mcpConfig,
|
|
1343
|
-
runtimeServerNames: step.runtimeServerNames,
|
|
1344
|
-
capabilityCeiling: step.capabilityCeiling ?? ctx.capabilityCeiling,
|
|
1345
|
-
cwd: step.cwd ?? ctx.cwd,
|
|
1346
|
-
promptFileStem: step.agent,
|
|
1347
|
-
intercomSessionName: ctx.childIntercomTarget,
|
|
1348
|
-
sessionName: childSessionName,
|
|
1349
|
-
orchestratorIntercomTarget: ctx.orchestratorIntercomTarget,
|
|
1350
|
-
runId: ctx.id,
|
|
1351
|
-
childAgentName: step.agent,
|
|
1352
|
-
childIndex: ctx.flatIndex,
|
|
1353
|
-
parentEventSink: ctx.nestedRoute?.eventSink,
|
|
1354
|
-
parentControlInbox: ctx.nestedRoute?.controlInbox,
|
|
1355
|
-
parentRootRunId: ctx.nestedRoute?.rootRunId,
|
|
1356
|
-
parentCapabilityToken: ctx.nestedRoute?.capabilityToken,
|
|
1357
|
-
runFanoutBudget: ctx.runFanoutBudget ? {
|
|
1358
|
-
...ctx.runFanoutBudget,
|
|
1359
|
-
...step.runFanoutPath ? { parentPath: `${ctx.runFanoutBudget.parentPath ? `${ctx.runFanoutBudget.parentPath}/` : ""}${step.runFanoutPath}` } : {}
|
|
1360
|
-
} : undefined,
|
|
1361
|
-
steerInboxDir: ctx.steerInboxDir,
|
|
1362
|
-
steerCapabilityPath: ctx.steerCapabilityPath,
|
|
1363
|
-
steerAckDir: ctx.steerAckDir,
|
|
1364
|
-
structuredOutput: effectiveStructuredOutput,
|
|
1365
|
-
toolBudget: step.toolBudget,
|
|
1366
|
-
permissionRules: step.permissionRules,
|
|
1367
|
-
permissionAuditPath: step.permissionRules && ctx.artifactsDir ? path.join(ctx.artifactsDir, "permission-audit", `${ctx.id}-${ctx.flatIndex}.jsonl`) : undefined,
|
|
1368
|
-
childWatchdog,
|
|
1369
|
-
waitToolEnabled: step.waitToolEnabled,
|
|
1370
|
-
waitToolDefaultTimeoutMs: step.waitToolDefaultTimeoutMs,
|
|
1371
|
-
thinkingCeiling: step.thinkingCeiling,
|
|
1372
|
-
extensionBindings
|
|
1373
|
-
}));
|
|
838
|
+
let watchdogSink;
|
|
839
|
+
let launch;
|
|
840
|
+
try {
|
|
841
|
+
launch = buildRunnerChildLaunch(step, ctx, {
|
|
842
|
+
sessionEnabled,
|
|
843
|
+
sessionDir,
|
|
844
|
+
model: candidate,
|
|
845
|
+
sessionName: childSessionName,
|
|
846
|
+
structuredOutput: effectiveStructuredOutput,
|
|
847
|
+
childWatchdog,
|
|
848
|
+
watchdogStatus: (event) => watchdogSink?.(event)
|
|
849
|
+
});
|
|
850
|
+
} catch (error) {
|
|
851
|
+
throw error;
|
|
852
|
+
}
|
|
853
|
+
if (effectiveStructuredOutput && launch.config.structuredOutput) {
|
|
854
|
+
launch.config.structuredOutput.capture = createStructuredOutputFileCapture(effectiveStructuredOutput);
|
|
855
|
+
}
|
|
856
|
+
const { warnings, capabilityAudit: attemptCapabilityAudit } = launch;
|
|
1374
857
|
if (!launchWarningsEmitted && warnings.length > 0) {
|
|
1375
858
|
for (const warning of warnings)
|
|
1376
859
|
console.warn(`[dm-subagents] ${warning}`);
|
|
@@ -1379,83 +862,116 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError : external.error;
|
|
|
1379
862
|
if (step.definitionDigest) {
|
|
1380
863
|
const toolPlan = resolvedTaskToolPlan ?? resolvePiLaunchToolPlan(omitUndefinedProperties({
|
|
1381
864
|
tools: step.tools,
|
|
865
|
+
excludeTools: step.excludeTools,
|
|
1382
866
|
allowNestedSubagents: step.allowNestedSubagents,
|
|
1383
867
|
extensions: step.extensions,
|
|
1384
868
|
subagentOnlyExtensions: step.subagentOnlyExtensions,
|
|
1385
869
|
fast: step.fast,
|
|
1386
870
|
model: step.model,
|
|
1387
|
-
modelCandidates: step.modelCandidates,
|
|
1388
871
|
mcpDirectTools: step.mcpDirectTools,
|
|
1389
|
-
mcpConfig: step.mcpConfig,
|
|
1390
|
-
runtimeServerNames: step.runtimeServerNames,
|
|
1391
872
|
cwd: step.cwd ?? ctx.cwd,
|
|
1392
873
|
requireReadTool: Boolean(step.skills?.length),
|
|
1393
874
|
structuredOutput: Boolean(effectiveStructuredOutput),
|
|
1394
875
|
capabilityCeiling: step.capabilityCeiling ?? ctx.capabilityCeiling,
|
|
1395
|
-
inheritedCapabilityCeiling:
|
|
876
|
+
inheritedCapabilityCeiling: ctx.inheritedChildRuntime?.capabilityCeiling,
|
|
877
|
+
requiredExtensions: step.requiredExtensions ?? ctx.inheritedChildRuntime?.requiredExtensions,
|
|
1396
878
|
permissionRules: step.permissionRules
|
|
1397
879
|
}));
|
|
1398
880
|
launchResolvedExtensions = projectLaunchResolvedChildExtensions(toolPlan);
|
|
1399
|
-
actualLaunchContractDigest =
|
|
881
|
+
actualLaunchContractDigest = resolveLaunchBinding({
|
|
1400
882
|
definitionDigest: step.definitionDigest,
|
|
1401
|
-
task: step.launchBindingTask ?? task,
|
|
1402
|
-
...candidate ? { model: candidate } : {},
|
|
1403
|
-
modelCandidates: candidates,
|
|
1404
|
-
...step.fast !== undefined ? { fast: step.fast } : {},
|
|
1405
|
-
...resolveEffectiveThinking(candidate, step.thinking) ? { thinking: resolveEffectiveThinking(candidate, step.thinking) } : {},
|
|
1406
|
-
...step.thinkingCeiling ? { thinkingCeiling: step.thinkingCeiling } : {},
|
|
1407
|
-
systemPrompt: step.systemPrompt ?? "",
|
|
1408
883
|
systemPromptMode: step.systemPromptMode,
|
|
1409
884
|
inheritProjectContext: step.inheritProjectContext,
|
|
1410
885
|
inheritGlobalContext: step.inheritGlobalContext,
|
|
1411
886
|
inheritSkills: step.inheritSkills,
|
|
887
|
+
task: step.launchBindingTask ?? task,
|
|
888
|
+
model: candidate,
|
|
889
|
+
fast: step.fast,
|
|
890
|
+
thinking: resolveEffectiveThinking(candidate, step.thinking),
|
|
891
|
+
systemPrompt: step.systemPrompt ?? "",
|
|
1412
892
|
skills: step.skills,
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
...extensionBindings ? { extensionBindings } : {}
|
|
1420
|
-
}));
|
|
893
|
+
toolPlan,
|
|
894
|
+
outputPath: step.outputPath,
|
|
895
|
+
outputMode: step.outputMode,
|
|
896
|
+
structuredOutputSchema: step.structuredOutputSchema,
|
|
897
|
+
extensionBindings
|
|
898
|
+
}).launchContractDigest;
|
|
1421
899
|
}
|
|
1422
900
|
capabilityAudit = attemptCapabilityAudit;
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
exitCode: run.exitCode,
|
|
1432
|
-
signal: run.processSignal ?? null,
|
|
1433
|
-
processTree: run.processTree
|
|
1434
|
-
});
|
|
901
|
+
fs.writeFileSync(ctx.outputFile, "", "utf-8");
|
|
902
|
+
if (step.effectiveAcceptance?.preserveStagedIndex && stagedIndexBaseline === undefined) {
|
|
903
|
+
try {
|
|
904
|
+
stagedIndexBaseline = captureStagedIndexBaseline(step.cwd ?? ctx.cwd);
|
|
905
|
+
} catch (error) {
|
|
906
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
907
|
+
return { agent: step.agent, output: message, error: message, exitCode: 1, context: step.context };
|
|
908
|
+
}
|
|
1435
909
|
}
|
|
1436
|
-
const
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
910
|
+
const run = await runChildSession(omitUndefinedProperties({
|
|
911
|
+
factory: ctx.childSessions,
|
|
912
|
+
launch,
|
|
913
|
+
prompt: `Task: ${recoveryTask}`,
|
|
914
|
+
childWatchdog,
|
|
915
|
+
childEventContext: { runId: ctx.id, stepIndex: ctx.flatIndex, agent: step.agent },
|
|
916
|
+
appendChildEvent: (event) => appendDiagnosticJsonl(eventsPath, JSON.stringify(event), typeof event.type === "string" ? event.type : undefined),
|
|
917
|
+
writeOutputLine: (line) => {
|
|
918
|
+
try {
|
|
919
|
+
fs.appendFileSync(ctx.outputFile, `${line}
|
|
920
|
+
`, "utf-8");
|
|
921
|
+
} catch {}
|
|
922
|
+
ctx.orcaProgressTab?.append(`${line}
|
|
923
|
+
`);
|
|
924
|
+
},
|
|
925
|
+
registerInterrupt: ctx.registerInterrupt,
|
|
926
|
+
registerTimeout: ctx.registerTimeout,
|
|
927
|
+
registerStop: ctx.registerStop,
|
|
928
|
+
registerSteer: ctx.registerSteer,
|
|
929
|
+
onSteerOutcome: ctx.onSteerOutcome,
|
|
930
|
+
registerWatchdogStatus: (sink) => {
|
|
931
|
+
watchdogSink = sink;
|
|
932
|
+
},
|
|
933
|
+
timeoutMessage: ctx.timeoutMessage,
|
|
934
|
+
stopMessage: ctx.stopMessage,
|
|
935
|
+
onChildEvent: ctx.onChildEvent,
|
|
936
|
+
onContextWindow: (contextLimit) => ctx.onAttemptStart?.({ ...attemptModel, contextLimit }),
|
|
937
|
+
transcriptWriter,
|
|
938
|
+
toolTimeoutMs: ctx.toolTimeoutMs,
|
|
939
|
+
runDeadlineAt: ctx.deadlineAt,
|
|
940
|
+
expectedModelForVerification,
|
|
941
|
+
modelVerificationRegistry: step.modelVerificationRegistry,
|
|
942
|
+
modelResponseAliases: step.modelResponseAliases,
|
|
943
|
+
mutationTools: step.mutationTools
|
|
944
|
+
}));
|
|
945
|
+
launched = true;
|
|
946
|
+
aggregateUsage.input += run.usage.input;
|
|
947
|
+
aggregateUsage.output += run.usage.output;
|
|
948
|
+
aggregateUsage.cacheRead += run.usage.cacheRead;
|
|
949
|
+
aggregateUsage.cacheWrite += run.usage.cacheWrite;
|
|
950
|
+
aggregateUsage.cost += run.usage.cost;
|
|
951
|
+
aggregateUsage.turns += run.usage.turns;
|
|
952
|
+
const terminalDiagnosticsEligible = !run.interrupted && !run.stopped && !run.timedOut;
|
|
953
|
+
const toolDiagnostic = run.exitCode === 0 && !run.error ? launch.capture.toolDiagnostic() : undefined;
|
|
954
|
+
const toolAvailabilityError = toolDiagnostic ? formatChildToolDiagnostic(toolDiagnostic) : undefined;
|
|
955
|
+
const runtimeAcknowledgedExtensions = launch.capture.runtimeAcknowledgedExtensions();
|
|
956
|
+
const midToolExitError = run.currentTool && isOrdinaryToolForMidToolExit(run.currentTool) && !run.interrupted && !run.timedOut && !run.stopped && !toolAvailabilityError ? formatMidToolExitError({ toolName: run.currentTool }) : undefined;
|
|
1444
957
|
let structuredOutput;
|
|
1445
958
|
let structuredError;
|
|
1446
959
|
let validatedStructuredOutput = false;
|
|
1447
|
-
if (effectiveStructuredOutput
|
|
1448
|
-
|
|
960
|
+
if (effectiveStructuredOutput) {
|
|
961
|
+
const otherwiseSuccessful = terminalDiagnosticsEligible && run.exitCode === 0 && !run.error && !toolAvailabilityError && !midToolExitError;
|
|
962
|
+
if (!run.structuredOutputToolInvoked && otherwiseSuccessful) {
|
|
1449
963
|
structuredError = MISSING_STRUCTURED_OUTPUT_CALL_ERROR;
|
|
1450
|
-
} else {
|
|
964
|
+
} else if (run.structuredOutputToolInvoked) {
|
|
1451
965
|
const structured = await readStructuredOutput({
|
|
1452
966
|
schema: effectiveStructuredOutput.schema,
|
|
1453
967
|
schemaPath: effectiveStructuredOutput.schemaPath,
|
|
1454
968
|
outputPath: effectiveStructuredOutput.outputPath
|
|
1455
969
|
});
|
|
1456
|
-
if (structured.error)
|
|
1457
|
-
|
|
1458
|
-
|
|
970
|
+
if (structured.error) {
|
|
971
|
+
if (otherwiseSuccessful) {
|
|
972
|
+
structuredError = structured.error === MISSING_STRUCTURED_OUTPUT_CALL_ERROR ? formatStructuredOutputRejectionError(run.messages) : structured.error;
|
|
973
|
+
}
|
|
974
|
+
} else {
|
|
1459
975
|
structuredOutput = structured.value;
|
|
1460
976
|
const acceptanceReport = readStructuredOutputAcceptanceReport(effectiveStructuredOutput);
|
|
1461
977
|
structuredAcceptanceReport = acceptanceReport.value;
|
|
@@ -1465,63 +981,21 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError : external.error;
|
|
|
1465
981
|
}
|
|
1466
982
|
}
|
|
1467
983
|
const errorMessages = validatedStructuredOutput ? run.messages.slice(run.structuredOutputMessageStartIndex ?? run.messages.length) : run.messages;
|
|
1468
|
-
const hiddenError = run.exitCode === 0 && !run.error && !toolAvailabilityError && !structuredError && !midToolExitError ? detectSubagentError(errorMessages) : null;
|
|
984
|
+
const hiddenError = terminalDiagnosticsEligible && run.exitCode === 0 && !run.error && !toolAvailabilityError && !structuredError && !midToolExitError ? detectSubagentError(errorMessages) : null;
|
|
1469
985
|
const terminalEmptyAfterUsefulWork = !validatedStructuredOutput && hasEmptyTerminalAssistantResponse(run.messages) && (run.toolCount > 0 || Boolean(run.finalOutput.trim()));
|
|
1470
|
-
const emptyOutputError = run.exitCode === 0 && !run.error && !toolAvailabilityError && !structuredError && !validatedStructuredOutput && (!run.finalOutput.trim() || terminalEmptyAfterUsefulWork) && (!hiddenError?.hasError || hasEmptyTerminalAssistantResponse(run.messages)) ? formatEmptyTerminalAssistantResponseError(run.messages) : undefined;
|
|
1471
|
-
const
|
|
1472
|
-
const
|
|
1473
|
-
const completionTools = completionToolPlan ? completionToolPlan.explicitToolAllowlist ? completionToolPlan.effectiveToolAllowlist : undefined : step.tools;
|
|
1474
|
-
const mutationEvidence = collectTrackedMutationEvidence(mutationSnapshot, step.cwd ?? ctx.cwd);
|
|
986
|
+
const emptyOutputError = terminalDiagnosticsEligible && run.exitCode === 0 && !run.error && !toolAvailabilityError && !structuredError && !validatedStructuredOutput && (!run.finalOutput.trim() || terminalEmptyAfterUsefulWork) && (!hiddenError?.hasError || hasEmptyTerminalAssistantResponse(run.messages)) ? formatEmptyTerminalAssistantResponseError(run.messages) : undefined;
|
|
987
|
+
const remoteGitChanged = run.nativeMachine?.initialGit && run.nativeMachine.finalGit ? run.nativeMachine.initialGit.head !== run.nativeMachine.finalGit.head || run.nativeMachine.initialGit.dirty !== run.nativeMachine.finalGit.dirty : undefined;
|
|
988
|
+
const mutationEvidence = run.nativeMachine ? { source: "tracked-files", trackedOnly: true, changedFiles: [], attemptedMutation: remoteGitChanged === true, ...remoteGitChanged === undefined ? { unavailable: "Remote Git before/after evidence was incomplete." } : {} } : collectTrackedMutationEvidence(mutationSnapshot, step.cwd ?? ctx.cwd);
|
|
1475
989
|
finalMutationEvidence = mutationEvidence;
|
|
1476
|
-
const
|
|
1477
|
-
const completionGuard = run.exitCode === 0 && !run.error && !structuredError && !hiddenError?.hasError && !midToolExitError && !emptyOutputError && completionGuardEnabled ? evaluateCompletionMutationGuard(omitUndefinedProperties({
|
|
1478
|
-
agent: step.agent,
|
|
1479
|
-
task: taskForCompletionGuard,
|
|
1480
|
-
messages: run.messages,
|
|
1481
|
-
tools: completionTools,
|
|
1482
|
-
mcpDirectTools: completionToolPlan?.effectiveMcpTools ?? step.mcpDirectTools,
|
|
1483
|
-
mutationTools: step.mutationTools,
|
|
1484
|
-
toolAvailabilityError,
|
|
1485
|
-
mutationEvidence: completionMutationEvidence
|
|
1486
|
-
})) : undefined;
|
|
1487
|
-
const mutationAttemptObserved = run.observedMutationAttempt === true || completionMutationEvidence?.attemptedMutation === true;
|
|
1488
|
-
const completionEvidence = planCompletionEvidence({
|
|
1489
|
-
guard: completionGuard,
|
|
1490
|
-
completionGuardEnabled,
|
|
1491
|
-
mutationCapable: hasMutationToolCapability(completionTools, completionToolPlan?.effectiveMcpTools ?? step.mcpDirectTools),
|
|
1492
|
-
implementationMutationExpected: expectsImplementationMutation(step.agent, taskForCompletionGuard),
|
|
1493
|
-
mutationAttemptObserved,
|
|
1494
|
-
mutationEvidence: completionMutationEvidence,
|
|
1495
|
-
agentContractV1: isAgentContractV1(step.agentContract)
|
|
1496
|
-
});
|
|
990
|
+
const mutationAttemptObserved = run.observedMutationAttempt === true || mutationEvidence.attemptedMutation === true;
|
|
1497
991
|
const finalOutputHasPersistableFileContent = run.exitCode === 0 && !run.error && !emptyOutputError && Boolean(stripAcceptanceReport(run.finalOutput).trim());
|
|
1498
992
|
const requiredOutput = step.outputMode === "file-only" && step.outputPath ? { kind: "file-only", path: step.outputPath, missing: !fs.existsSync(step.outputPath) && !finalOutputHasPersistableFileContent } : effectiveStructuredOutput ? { kind: "structured", path: effectiveStructuredOutput.outputPath, missing: !fs.existsSync(effectiveStructuredOutput.outputPath) } : undefined;
|
|
1499
993
|
finalRequiredOutputMissing = requiredOutput?.missing;
|
|
1500
|
-
const missingRequiredOutputError = formatRequiredOutputError(requiredOutput);
|
|
994
|
+
const missingRequiredOutputError = terminalDiagnosticsEligible ? formatRequiredOutputError(requiredOutput) : undefined;
|
|
1501
995
|
const missingRequiredOutputAfterMutation = Boolean(missingRequiredOutputError) && (mutationAttemptObserved || Boolean(mutationEvidence.changedFiles.length));
|
|
1502
|
-
const effectiveExitCode = toolAvailabilityError ||
|
|
1503
|
-
const
|
|
1504
|
-
|
|
1505
|
-
interrupted: run.interrupted,
|
|
1506
|
-
timedOut: run.timedOut,
|
|
1507
|
-
stopped: run.stopped
|
|
1508
|
-
})) ? formatProcessSignalError(run.processSignal) : undefined;
|
|
1509
|
-
const underlyingError = toolAvailabilityError ?? midToolExitError ?? structuredError ?? run.error ?? signalError ?? (run.exitCode !== 0 && run.stderr.trim() ? run.stderr.trim() : undefined) ?? ((emptyOutputError || missingRequiredOutputError) && run.stderr.trim() ? run.stderr.trim() : undefined) ?? emptyOutputError ?? (missingRequiredOutputAfterMutation ? missingRequiredOutputError : undefined) ?? (hiddenError?.hasError ? hiddenError.details ? `${hiddenError.errorType} failed (exit ${effectiveExitCode}): ${hiddenError.details}` : `${hiddenError.errorType} failed with exit code ${effectiveExitCode}` : undefined);
|
|
1510
|
-
const error = formatSubagentExtensionConflictError(underlyingError ?? missingRequiredOutputError ?? completionEvidence.legacyFailureError, {
|
|
1511
|
-
agent: step.agent,
|
|
1512
|
-
ambientExtensionsEnabled: launchResolvedExtensions?.disableAmbientExtensions === false
|
|
1513
|
-
});
|
|
1514
|
-
const attempt = omitUndefinedProperties({
|
|
1515
|
-
model: candidate ?? run.model ?? step.model ?? "default",
|
|
1516
|
-
success: effectiveExitCode === 0 && !error,
|
|
1517
|
-
exitCode: effectiveExitCode,
|
|
1518
|
-
error,
|
|
1519
|
-
usage: run.usage
|
|
1520
|
-
});
|
|
1521
|
-
modelAttempts.push(attempt);
|
|
1522
|
-
if (!recoveringAbort && candidate && startupAttemptIndex === 0)
|
|
1523
|
-
attemptedModels.push(candidate);
|
|
1524
|
-
completionGuardTriggeredFinal = completionEvidence.guardTriggered && !underlyingError && !missingRequiredOutputError;
|
|
996
|
+
const effectiveExitCode = toolAvailabilityError || midToolExitError || structuredError || emptyOutputError || missingRequiredOutputError ? 1 : hiddenError?.hasError ? hiddenError.exitCode ?? 1 : run.error && run.exitCode === 0 ? 1 : run.exitCode;
|
|
997
|
+
const underlyingError = toolAvailabilityError ?? midToolExitError ?? structuredError ?? run.error ?? emptyOutputError ?? (missingRequiredOutputAfterMutation ? missingRequiredOutputError : undefined) ?? (hiddenError?.hasError ? hiddenError.details ? `${hiddenError.errorType} failed (exit ${effectiveExitCode}): ${hiddenError.details}` : `${hiddenError.errorType} failed with exit code ${effectiveExitCode}` : undefined);
|
|
998
|
+
const error = underlyingError ?? missingRequiredOutputError;
|
|
1525
999
|
finalOutputSnapshot = outputSnapshot;
|
|
1526
1000
|
if (step.toolBudget) {
|
|
1527
1001
|
const toolMessages = run.messages.filter((message) => message.role === "toolResult");
|
|
@@ -1529,21 +1003,23 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError : external.error;
|
|
|
1529
1003
|
toolBudgetBlocked = Boolean(blockedMessage);
|
|
1530
1004
|
toolBudget = toolBudgetState(step.toolBudget, toolMessages.length, blockedMessage ? blockedMessage.toolName : undefined);
|
|
1531
1005
|
}
|
|
1532
|
-
const settlementDiagnostic =
|
|
1533
|
-
terminalFailed: effectiveExitCode !== 0,
|
|
1006
|
+
const settlementDiagnostic = effectiveExitCode !== 0 ? {
|
|
1534
1007
|
finalTextPresent: Boolean(stripAcceptanceReport(run.finalOutput).trim()),
|
|
1535
|
-
|
|
1536
|
-
requiredOutput,
|
|
1008
|
+
mutation: { attempted: mutationAttemptObserved, observed: mutationEvidence.attemptedMutation },
|
|
1009
|
+
...requiredOutput ? { requiredOutput } : {},
|
|
1537
1010
|
afterCompactionSettlement: run.afterCompactionSettlement === true
|
|
1538
|
-
}
|
|
1539
|
-
const fileMutationEffect =
|
|
1540
|
-
finalResult = { ...run, exitCode: effectiveExitCode, model: candidate ?? run.model, error, structuredOutput, runtimeAcknowledgedExtensions, ...step.agentContract ? { agentContract: step.agentContract } : {}, ...fileMutationEffect || settlementDiagnostic ? { effects: { ...fileMutationEffect ? { fileMutation: fileMutationEffect } : {}, ...settlementDiagnostic ? { settlementDiagnostic } : {} } } : {} };
|
|
1541
|
-
|
|
1011
|
+
} : undefined;
|
|
1012
|
+
const fileMutationEffect = missingRequiredOutputAfterMutation ? { status: "observed", attempted: true, evidence: mutationEvidence } : undefined;
|
|
1013
|
+
finalResult = { ...run, exitCode: effectiveExitCode, model: candidate ?? run.model, error, structuredOutput, structuredOutputFailed: structuredError ? true : undefined, runtimeAcknowledgedExtensions, ...step.agentContract ? { agentContract: step.agentContract } : {}, ...fileMutationEffect || settlementDiagnostic ? { effects: { ...fileMutationEffect ? { fileMutation: fileMutationEffect } : {}, ...settlementDiagnostic ? { settlementDiagnostic } : {} } } : {} };
|
|
1014
|
+
if (run.stopped || run.timedOut || ctx.timeoutSignal?.aborted || ctx.stopSignal?.aborted || ctx.skipAcceptance?.())
|
|
1015
|
+
break singleLaunch;
|
|
1016
|
+
if (effectiveExitCode === 0 && !error)
|
|
1017
|
+
break singleLaunch;
|
|
1018
|
+
const recovery = planAbortRecovery({
|
|
1542
1019
|
messages: run.messages,
|
|
1543
1020
|
error,
|
|
1544
|
-
processSignal: run.processSignal,
|
|
1545
1021
|
sessionAvailable: Boolean(step.sessionFile && fs.existsSync(step.sessionFile)),
|
|
1546
|
-
alreadyResumed:
|
|
1022
|
+
alreadyResumed: attemptIndex > 0,
|
|
1547
1023
|
stopped: run.stopped || ctx.stopSignal?.aborted || ctx.skipAcceptance?.(),
|
|
1548
1024
|
interrupted: run.interrupted,
|
|
1549
1025
|
timedOut: run.timedOut || ctx.timeoutSignal?.aborted,
|
|
@@ -1553,90 +1029,24 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError : external.error;
|
|
|
1553
1029
|
acceptanceFailed: false,
|
|
1554
1030
|
currentTool: run.currentTool,
|
|
1555
1031
|
afterCompactionSettlement: run.afterCompactionSettlement
|
|
1556
|
-
})
|
|
1557
|
-
if (
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
if (finalResult)
|
|
1561
|
-
finalResult.abortRecoveryDiagnostic = abortRecovery.diagnostic;
|
|
1562
|
-
}
|
|
1563
|
-
if (run.stopped || run.timedOut || ctx.timeoutSignal?.aborted || ctx.stopSignal?.aborted || ctx.skipAcceptance?.())
|
|
1564
|
-
break modelAttemptsLoop;
|
|
1565
|
-
if (abortRecovery?.action === "settle" && abortRecovery.diagnostic)
|
|
1566
|
-
break modelAttemptsLoop;
|
|
1567
|
-
if (attempt.success)
|
|
1568
|
-
break modelAttemptsLoop;
|
|
1569
|
-
if (recoveringAbort)
|
|
1570
|
-
break modelAttemptsLoop;
|
|
1571
|
-
if (abortRecovery?.action === "resume") {
|
|
1572
|
-
abortRecoveryAttempted = true;
|
|
1573
|
-
nextAttemptTask = abortRecovery.prompt;
|
|
1574
|
-
attemptNotes.push("[abort-recovery] provider/transport abort after useful progress; resuming the retained child session once.");
|
|
1575
|
-
continue;
|
|
1576
|
-
}
|
|
1577
|
-
if (completionEvidence.guardTriggered)
|
|
1578
|
-
break modelAttemptsLoop;
|
|
1579
|
-
const startupFailure = isRetryableSubagentStartupFailure(omitUndefinedProperties({
|
|
1580
|
-
exitCode: effectiveExitCode,
|
|
1581
|
-
error,
|
|
1582
|
-
finalOutput: run.finalOutput,
|
|
1583
|
-
messageCount: run.messages.length,
|
|
1584
|
-
toolCount: run.toolCount,
|
|
1585
|
-
usage: run.usage,
|
|
1586
|
-
durationMs: run.durationMs,
|
|
1587
|
-
protocolError: run.protocolError,
|
|
1588
|
-
processSignal: run.processSignal,
|
|
1589
|
-
observedMutationAttempt: run.observedMutationAttempt,
|
|
1590
|
-
interrupted: run.interrupted,
|
|
1591
|
-
timedOut: run.timedOut,
|
|
1592
|
-
stopped: run.stopped
|
|
1593
|
-
}));
|
|
1594
|
-
const retryDelayMs = SUBAGENT_STARTUP_RETRY_DELAYS_MS[startupAttemptIndex];
|
|
1595
|
-
if (startupFailure && retryDelayMs !== undefined) {
|
|
1596
|
-
const retryNote = formatSubagentStartupRetryNote({
|
|
1597
|
-
model: attempt.model,
|
|
1598
|
-
attempt: startupAttemptIndex + 1,
|
|
1599
|
-
maxAttempts: SUBAGENT_STARTUP_RETRY_DELAYS_MS.length + 1,
|
|
1600
|
-
delayMs: retryDelayMs
|
|
1601
|
-
});
|
|
1602
|
-
const shouldRetry = await waitForSubagentStartupRetry(retryDelayMs, [ctx.timeoutSignal, ctx.stopSignal]);
|
|
1603
|
-
if (!shouldRetry || ctx.skipAcceptance?.())
|
|
1604
|
-
break modelAttemptsLoop;
|
|
1605
|
-
if (!taskDeliveryOverride && run.processSignal === "SIGKILL") {
|
|
1606
|
-
taskDeliveryOverride = "file";
|
|
1607
|
-
attemptNotes.push("[startup-retry] retrying with file task delivery to keep the task text out of the child process argv.");
|
|
1608
|
-
}
|
|
1609
|
-
attempt.error = retryNote;
|
|
1610
|
-
attemptNotes.push(retryNote);
|
|
1611
|
-
startupAttemptIndex += 1;
|
|
1612
|
-
continue;
|
|
1032
|
+
});
|
|
1033
|
+
if (recovery.action === "resume") {
|
|
1034
|
+
recoveryTask = recovery.prompt;
|
|
1035
|
+
continue singleLaunch;
|
|
1613
1036
|
}
|
|
1614
|
-
if (
|
|
1615
|
-
|
|
1616
|
-
model: attempt.model,
|
|
1617
|
-
attempts: startupAttemptIndex + 1
|
|
1618
|
-
});
|
|
1619
|
-
attempt.error = startupError;
|
|
1620
|
-
finalResult.error = startupError;
|
|
1621
|
-
finalResult.finalOutput = startupError;
|
|
1622
|
-
break modelAttemptsLoop;
|
|
1037
|
+
if (recovery.diagnostic) {
|
|
1038
|
+
finalResult.abortRecoveryDiagnostic = recovery.diagnostic;
|
|
1623
1039
|
}
|
|
1624
|
-
const retryableModelFailure = isRetryableModelFailureAttempt({ error, messages: run.messages, toolCount: run.toolCount });
|
|
1625
|
-
if (retryableModelFailure)
|
|
1626
|
-
recordRetryableModelFailure(candidate ?? run.model ?? step.model, error);
|
|
1627
1040
|
if (isContextOverflow(error)) {
|
|
1628
1041
|
contextOverflow = true;
|
|
1629
|
-
|
|
1630
|
-
break modelAttemptsLoop;
|
|
1042
|
+
break singleLaunch;
|
|
1631
1043
|
}
|
|
1632
|
-
|
|
1633
|
-
break modelAttemptsLoop;
|
|
1634
|
-
attemptNotes.push(formatModelAttemptNote(attempt, candidates[modelIndex + 1]));
|
|
1635
|
-
modelIndex += 1;
|
|
1636
|
-
startupAttemptIndex = 0;
|
|
1044
|
+
break singleLaunch;
|
|
1637
1045
|
}
|
|
1638
1046
|
const rawOutput = finalResult?.finalOutput ?? "";
|
|
1639
|
-
|
|
1047
|
+
let outputForPersistence = stripAcceptanceReport(rawOutput);
|
|
1048
|
+
if (!outputForPersistence.trim() && finalResult?.structuredOutput !== undefined)
|
|
1049
|
+
outputForPersistence = JSON.stringify(finalResult.structuredOutput, null, 2);
|
|
1640
1050
|
const resolvedOutput = step.outputPath && finalResult?.exitCode === 0 ? resolveSingleOutput(step.outputPath, outputForPersistence, finalOutputSnapshot, step.outputClaimPath) : { fullOutput: outputForPersistence };
|
|
1641
1051
|
if (resolvedOutput.fatalError) {
|
|
1642
1052
|
if (finalResult) {
|
|
@@ -1648,12 +1058,6 @@ ${resolvedOutput.saveError}` : resolvedOutput.saveError;
|
|
|
1648
1058
|
const output = stripAcceptanceReport(resolvedOutput.fullOutput);
|
|
1649
1059
|
const outputReference = resolvedOutput.savedPath ? formatSavedOutputReference(resolvedOutput.savedPath, output) : undefined;
|
|
1650
1060
|
let outputForSummary = output;
|
|
1651
|
-
if (attemptNotes.length > 0) {
|
|
1652
|
-
outputForSummary = `${attemptNotes.join(`
|
|
1653
|
-
`)}
|
|
1654
|
-
|
|
1655
|
-
${outputForSummary}`.trim();
|
|
1656
|
-
}
|
|
1657
1061
|
if (finalResult?.stopped && !outputForSummary.trim()) {
|
|
1658
1062
|
outputForSummary = ctx.stopMessage ?? "Subagent stopped by user.";
|
|
1659
1063
|
}
|
|
@@ -1692,18 +1096,24 @@ ${timeoutRecovery.message}` : timeoutRecovery.message;
|
|
|
1692
1096
|
reportError: structuredAcceptanceReportError,
|
|
1693
1097
|
fileOutput: childWrittenOutput !== undefined && step.outputPath ? { content: childWrittenOutput, path: step.outputPath, authoritative: step.outputMode === "file-only", durable: resolvedOutput.savedPath !== undefined } : undefined,
|
|
1694
1098
|
cwd: step.cwd ?? ctx.cwd,
|
|
1099
|
+
stagedIndexBaseline,
|
|
1695
1100
|
signal: combinedAbortSignal([ctx.timeoutSignal, ctx.stopSignal]),
|
|
1696
1101
|
abortMessage: ctx.stopSignal?.aborted ? ctx.stopMessage ?? "Subagent stopped by user." : ctx.timeoutMessage ?? "Subagent timed out.",
|
|
1697
|
-
reportOptional:
|
|
1102
|
+
reportOptional: isAgentContract(step.agentContract),
|
|
1698
1103
|
artifactsDir: ctx.artifactsDir,
|
|
1699
|
-
runId: ctx.id
|
|
1104
|
+
runId: ctx.id,
|
|
1105
|
+
watchdog: finalResult?.watchdog
|
|
1700
1106
|
})) : undefined;
|
|
1701
1107
|
const stoppedAfterAcceptance = finalResult?.stopped === true || ctx.stopSignal?.aborted === true;
|
|
1702
1108
|
const timedOutAfterAcceptance = !stoppedAfterAcceptance && (finalResult?.timedOut === true || ctx.timeoutSignal?.aborted === true);
|
|
1703
1109
|
const effectiveAcceptance = step.effectiveAcceptance ? stoppedAfterAcceptance ? buildSkippedAcceptanceLedger(step.effectiveAcceptance, { id: "stopped", message: "Acceptance was not evaluated because the subagent was stopped." }) : timedOutAfterAcceptance ? buildSkippedAcceptanceLedger(step.effectiveAcceptance, { id: "timeout", message: "Acceptance was not evaluated because the subagent timed out." }) : acceptance : undefined;
|
|
1704
1110
|
const acceptanceFailure = effectiveAcceptance ? acceptanceFailureMessage(effectiveAcceptance) : undefined;
|
|
1705
|
-
const acceptanceCanFailRun = acceptanceFailure && effectiveAcceptance?.explicit && (finalResult?.exitCode ?? 1) === 0 && !finalResult?.interrupted && !timedOutAfterAcceptance && !stoppedAfterAcceptance && !
|
|
1111
|
+
const acceptanceCanFailRun = acceptanceFailure && effectiveAcceptance?.explicit && (finalResult?.exitCode ?? 1) === 0 && !finalResult?.interrupted && !timedOutAfterAcceptance && !stoppedAfterAcceptance && !isAgentContract(step.agentContract);
|
|
1706
1112
|
const effectiveFinalExitCode = timedOutAfterAcceptance || stoppedAfterAcceptance ? 1 : acceptanceCanFailRun ? 1 : finalResult?.exitCode ?? 1;
|
|
1113
|
+
const typedGate = typedVerifyOutput(effectiveAcceptance);
|
|
1114
|
+
if (typedGate && finalResult && finalResult.structuredOutput === undefined && effectiveFinalExitCode === 0) {
|
|
1115
|
+
finalResult = { ...finalResult, structuredOutput: typedGate.value };
|
|
1116
|
+
}
|
|
1707
1117
|
const intercomDetachReceipt = finalResult?.finalOutput === INTERCOM_DETACH_RECEIPT;
|
|
1708
1118
|
const baseFinalError = stoppedAfterAcceptance ? ctx.stopMessage ?? "Subagent stopped by user." : timedOutAfterAcceptance ? finalResult?.error ?? ctx.timeoutMessage ?? "Subagent timed out." : acceptanceCanFailRun ? finalResult?.error ? `${finalResult.error}
|
|
1709
1119
|
${acceptanceFailure}` : acceptanceFailure : finalResult?.error ?? (intercomDetachReceipt ? INTERCOM_DETACH_RECEIPT : undefined);
|
|
@@ -1713,7 +1123,7 @@ ${acceptanceFailure}` : acceptanceFailure : finalResult?.error ?? (intercomDetac
|
|
|
1713
1123
|
abortRecoveryDiagnostic: effectiveFinalExitCode !== 0 ? finalResult?.abortRecoveryDiagnostic : undefined,
|
|
1714
1124
|
requiredOutput: effectiveFinalExitCode !== 0 ? finalResult?.effects?.settlementDiagnostic?.requiredOutput : undefined
|
|
1715
1125
|
});
|
|
1716
|
-
const usage =
|
|
1126
|
+
const usage = launched ? aggregateUsage : undefined;
|
|
1717
1127
|
const artifactErrors = artifactPaths && ctx.artifactConfig?.enabled !== false ? persistStepArtifacts({
|
|
1718
1128
|
artifactPaths,
|
|
1719
1129
|
artifactConfig: ctx.artifactConfig,
|
|
@@ -1729,8 +1139,8 @@ ${acceptanceFailure}` : acceptanceFailure : finalResult?.error ?? (intercomDetac
|
|
|
1729
1139
|
task: PROMPT_REDACTED,
|
|
1730
1140
|
exitCode: effectiveFinalExitCode,
|
|
1731
1141
|
model: finalResult?.model,
|
|
1732
|
-
|
|
1733
|
-
|
|
1142
|
+
nativeMachine: finalResult?.nativeMachine,
|
|
1143
|
+
requestedModel: step.requestedModel,
|
|
1734
1144
|
usage,
|
|
1735
1145
|
error: effectiveFinalError,
|
|
1736
1146
|
acceptance: effectiveAcceptance,
|
|
@@ -1754,42 +1164,41 @@ ${acceptanceFailure}` : acceptanceFailure : finalResult?.error ?? (intercomDetac
|
|
|
1754
1164
|
outputState,
|
|
1755
1165
|
exitCode: effectiveFinalExitCode,
|
|
1756
1166
|
error: effectiveFinalError,
|
|
1757
|
-
protocolError: finalResult?.protocolError,
|
|
1758
1167
|
sessionFile: step.sessionFile,
|
|
1759
1168
|
intercomTarget: ctx.childIntercomTarget,
|
|
1760
1169
|
model: finalResult?.model,
|
|
1761
|
-
|
|
1762
|
-
|
|
1170
|
+
nativeMachine: finalResult?.nativeMachine,
|
|
1171
|
+
thinking: resolveEffectiveThinking(finalResult?.model, step.thinking),
|
|
1172
|
+
requestedModel: step.requestedModel,
|
|
1763
1173
|
contextOverflow: contextOverflow || undefined,
|
|
1764
|
-
totalCost:
|
|
1174
|
+
totalCost: costSummaryFromUsage(usage),
|
|
1765
1175
|
usage,
|
|
1766
1176
|
artifactPaths,
|
|
1177
|
+
savedOutputPath: finalizedOutput.savedPath,
|
|
1767
1178
|
outputSaveError: [resolvedOutput.saveError, artifactErrors.outputSaveError].filter(Boolean).join(`
|
|
1768
1179
|
`) || undefined,
|
|
1180
|
+
artifactOutputSaveFailed: artifactErrors.outputSaveError ? true : undefined,
|
|
1769
1181
|
metadataSaveError: artifactErrors.metadataSaveError,
|
|
1770
1182
|
transcriptPath: transcriptWriter ? artifactPaths?.transcriptPath : undefined,
|
|
1771
1183
|
transcriptError: transcriptWriter?.getError(),
|
|
1772
1184
|
interrupted: timedOutAfterAcceptance || stoppedAfterAcceptance ? false : finalResult?.interrupted,
|
|
1773
1185
|
timedOut: timedOutAfterAcceptance ? true : finalResult?.timedOut,
|
|
1774
1186
|
stopped: stoppedAfterAcceptance ? true : finalResult?.stopped,
|
|
1775
|
-
processSignal: finalResult?.processSignal,
|
|
1776
1187
|
timeoutRecovery,
|
|
1777
1188
|
toolBudget,
|
|
1778
1189
|
toolBudgetBlocked: toolBudgetBlocked || undefined,
|
|
1779
|
-
completionGuardTriggered: completionGuardTriggeredFinal,
|
|
1780
1190
|
...finalResult?.effects ? { effects: finalResult.effects } : {},
|
|
1781
|
-
structuredOutput:
|
|
1782
|
-
|
|
1783
|
-
|
|
1191
|
+
structuredOutput: finalResult?.structuredOutput,
|
|
1192
|
+
structuredOutputFailed: finalResult?.structuredOutputFailed,
|
|
1193
|
+
structuredOutputPath: effectiveStructuredOutput?.outputPath,
|
|
1194
|
+
structuredOutputSchemaPath: effectiveStructuredOutput?.schemaPath,
|
|
1784
1195
|
acceptance: effectiveAcceptance,
|
|
1785
1196
|
watchdog: finalResult?.watchdog,
|
|
1786
1197
|
...capabilityAudit ? { capabilityCeiling: capabilityAudit.ceiling, capabilityAudit } : {},
|
|
1787
1198
|
launchResolvedExtensions,
|
|
1788
|
-
...finalResult?.runtimeAcknowledgedExtensions ? { runtimeAcknowledgedExtensions: finalResult.runtimeAcknowledgedExtensions } : {}
|
|
1789
|
-
writerProcesses,
|
|
1790
|
-
writerAttemptCount
|
|
1199
|
+
...finalResult?.runtimeAcknowledgedExtensions ? { runtimeAcknowledgedExtensions: finalResult.runtimeAcknowledgedExtensions } : {}
|
|
1791
1200
|
});
|
|
1792
|
-
return
|
|
1201
|
+
return isAgentContract(step.agentContract) ? attachContractProjections(result) : result;
|
|
1793
1202
|
}
|
|
1794
1203
|
async function runSingleStep(step, ctx) {
|
|
1795
1204
|
if (!step.importAsyncRoot)
|
|
@@ -1832,6 +1241,10 @@ function requiredStatusStep(statusPayload, index) {
|
|
|
1832
1241
|
function setStatusWorktreeReference(statusStep, worktree) {
|
|
1833
1242
|
statusStep.worktreePath = worktree.path;
|
|
1834
1243
|
statusStep.branch = worktree.branch;
|
|
1244
|
+
if (worktree.provider)
|
|
1245
|
+
statusStep.provider = worktree.provider;
|
|
1246
|
+
if (worktree.naming)
|
|
1247
|
+
statusStep.naming = worktree.naming;
|
|
1835
1248
|
}
|
|
1836
1249
|
function markParallelGroupSetupFailure(input) {
|
|
1837
1250
|
for (let taskIndex = 0;taskIndex < input.group.parallel.length; taskIndex++) {
|
|
@@ -1840,12 +1253,15 @@ function markParallelGroupSetupFailure(input) {
|
|
|
1840
1253
|
const task = input.group.parallel[taskIndex];
|
|
1841
1254
|
if (!task)
|
|
1842
1255
|
throw new Error(`Missing parallel task at index ${taskIndex}`);
|
|
1843
|
-
statusStep.
|
|
1256
|
+
const stopped = statusStep.stopped || statusStep.stopRequested || input.statusPayload.stopped;
|
|
1257
|
+
const paused = !stopped && input.statusPayload.state === "paused";
|
|
1258
|
+
statusStep.status = stopped ? "stopped" : paused ? "paused" : "failed";
|
|
1844
1259
|
statusStep.startedAt = input.failedAt;
|
|
1845
1260
|
statusStep.endedAt = input.failedAt;
|
|
1846
1261
|
statusStep.durationMs = 0;
|
|
1847
|
-
statusStep.exitCode = 1;
|
|
1848
|
-
|
|
1262
|
+
statusStep.exitCode = paused ? 0 : 1;
|
|
1263
|
+
statusStep.error ??= input.setupError;
|
|
1264
|
+
input.results.push(omitUndefinedProperties({ agent: task.agent, context: task.context, output: input.setupError, error: input.setupError, success: false, exitCode: paused ? 0 : 1, sessionFile: task.sessionFile, stopped: stopped || undefined, interrupted: paused || undefined, timedOut: input.statusPayload.timedOut || undefined }));
|
|
1849
1265
|
}
|
|
1850
1266
|
input.statusPayload.currentStep = input.groupStartFlatIndex;
|
|
1851
1267
|
input.statusPayload.lastUpdate = input.failedAt;
|
|
@@ -1886,12 +1302,24 @@ function markParallelGroupRunning(input) {
|
|
|
1886
1302
|
count: input.group.parallel.length
|
|
1887
1303
|
}));
|
|
1888
1304
|
}
|
|
1305
|
+
function bindWorktreeCwd(step, worktreeCwd) {
|
|
1306
|
+
const bind = (value) => value === null || value === undefined ? value : value.replaceAll(WORKTREE_AGENT_CWD_PLACEHOLDER, worktreeCwd);
|
|
1307
|
+
return {
|
|
1308
|
+
...step,
|
|
1309
|
+
task: bind(step.task) ?? step.task,
|
|
1310
|
+
...step.systemPrompt !== undefined ? { systemPrompt: bind(step.systemPrompt) } : {},
|
|
1311
|
+
...step.outputPath !== undefined ? { outputPath: bind(step.outputPath) } : {},
|
|
1312
|
+
...step.launchBindingTask !== undefined ? { launchBindingTask: bind(step.launchBindingTask) } : {},
|
|
1313
|
+
...step.requestedCwd !== undefined ? { requestedCwd: bind(step.requestedCwd) } : {}
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1889
1316
|
function prepareParallelTaskRun(task, cwd, worktreeSetup, taskIndex) {
|
|
1890
1317
|
if (!worktreeSetup)
|
|
1891
1318
|
return { taskForRun: task, taskCwd: cwd };
|
|
1892
1319
|
const { cwd: _taskCwd, ...taskForRun } = task;
|
|
1320
|
+
const boundTask = bindWorktreeCwd(taskForRun, worktreeSetup.worktrees[taskIndex].agentCwd);
|
|
1893
1321
|
return {
|
|
1894
|
-
taskForRun,
|
|
1322
|
+
taskForRun: boundTask,
|
|
1895
1323
|
taskCwd: worktreeSetup.worktrees[taskIndex].agentCwd
|
|
1896
1324
|
};
|
|
1897
1325
|
}
|
|
@@ -1916,8 +1344,12 @@ function missingRequiredOutputAfterUsefulMutation(result) {
|
|
|
1916
1344
|
return effects?.settlementDiagnostic?.requiredOutput?.missing === true && (effects.settlementDiagnostic.mutation.attempted || effects.fileMutation?.attempted === true || Boolean(effects.fileMutation?.evidence?.changedFiles.length));
|
|
1917
1345
|
}
|
|
1918
1346
|
function partialExecutionWithUsefulMutation(result) {
|
|
1347
|
+
if (result.execution?.status !== "partial")
|
|
1348
|
+
return false;
|
|
1349
|
+
if (result.runner?.type === "external-cli" && result.runner.machine)
|
|
1350
|
+
return true;
|
|
1919
1351
|
const fileMutation = result.effects?.fileMutation;
|
|
1920
|
-
return
|
|
1352
|
+
return fileMutation?.attempted === true || Boolean(fileMutation?.evidence?.changedFiles.length);
|
|
1921
1353
|
}
|
|
1922
1354
|
function partialEvidenceResult(result) {
|
|
1923
1355
|
return missingRequiredOutputAfterUsefulMutation(result) || partialExecutionWithUsefulMutation(result);
|
|
@@ -1944,7 +1376,10 @@ function combinedAbortSignal(signals) {
|
|
|
1944
1376
|
}
|
|
1945
1377
|
async function runSingleStepWithTimeout(step, ctx, parentDeadlineAt) {
|
|
1946
1378
|
if (step.timeoutMs === undefined)
|
|
1947
|
-
return runSingleStep(step, ctx
|
|
1379
|
+
return runSingleStep(step, parentDeadlineAt === undefined ? ctx : {
|
|
1380
|
+
...ctx,
|
|
1381
|
+
deadlineAt: ctx.deadlineAt === undefined ? parentDeadlineAt : Math.min(ctx.deadlineAt, parentDeadlineAt)
|
|
1382
|
+
});
|
|
1948
1383
|
const parentRemainingMs = parentDeadlineAt === undefined ? undefined : Math.max(0, parentDeadlineAt - Date.now());
|
|
1949
1384
|
const timeoutMs = parentRemainingMs === undefined ? step.timeoutMs : Math.min(step.timeoutMs, parentRemainingMs);
|
|
1950
1385
|
const timeoutMessage = parentRemainingMs !== undefined && parentRemainingMs <= step.timeoutMs ? ctx.timeoutMessage : `Subagent timed out after ${step.timeoutMs}ms.`;
|
|
@@ -1979,7 +1414,7 @@ async function runSingleStepWithTimeout(step, ctx, parentDeadlineAt) {
|
|
|
1979
1414
|
ctx.registerTimeout?.(undefined);
|
|
1980
1415
|
}
|
|
1981
1416
|
}
|
|
1982
|
-
async function runSubagent(config,
|
|
1417
|
+
export async function runSubagent(config, childSessions) {
|
|
1983
1418
|
const { id, steps, resultPath, cwd, placeholder, taskIndex, totalTasks, maxOutput, artifactsDir, artifactConfig } = config;
|
|
1984
1419
|
const globalSemaphore = new Semaphore(config.globalConcurrencyLimit ?? DEFAULT_GLOBAL_CONCURRENCY_LIMIT);
|
|
1985
1420
|
let previousOutput = "";
|
|
@@ -1997,13 +1432,15 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
1997
1432
|
const activeChildInterrupts = new Map;
|
|
1998
1433
|
const activeChildTimeouts = new Map;
|
|
1999
1434
|
const activeChildStops = new Map;
|
|
1435
|
+
const activeChildSteers = new Map;
|
|
1436
|
+
const queuedStepSteers = new Map;
|
|
2000
1437
|
const childStopRequests = new Map;
|
|
2001
1438
|
const pendingStepSteers = [];
|
|
2002
|
-
const steeringCapabilities = new Map;
|
|
2003
1439
|
let interrupted = false;
|
|
2004
1440
|
let currentActivityState;
|
|
2005
1441
|
let activityTimer;
|
|
2006
1442
|
let timeoutTimer;
|
|
1443
|
+
let checkpointTimer;
|
|
2007
1444
|
let timedOut = false;
|
|
2008
1445
|
let stopped = false;
|
|
2009
1446
|
let usageBudgetExceeded = false;
|
|
@@ -2011,6 +1448,9 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2011
1448
|
const stopMessage = "Subagent stopped by user.";
|
|
2012
1449
|
const timeoutAbortController = new AbortController;
|
|
2013
1450
|
const stopAbortController = new AbortController;
|
|
1451
|
+
const setupInterruptController = new AbortController;
|
|
1452
|
+
const runStopSignal = AbortSignal.any([timeoutAbortController.signal, stopAbortController.signal]);
|
|
1453
|
+
const setupSignal = AbortSignal.any([timeoutAbortController.signal, stopAbortController.signal, setupInterruptController.signal]);
|
|
2014
1454
|
let previousCumulativeTokens = { input: 0, output: 0, total: 0 };
|
|
2015
1455
|
let latestSessionFile;
|
|
2016
1456
|
const flatSteps = flattenSteps(steps);
|
|
@@ -2050,7 +1490,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2050
1490
|
model: task.model,
|
|
2051
1491
|
...task.contextLimit !== undefined ? { contextLimit: task.contextLimit } : {},
|
|
2052
1492
|
thinking: task.thinking,
|
|
2053
|
-
|
|
1493
|
+
requestedModel: task.requestedModel,
|
|
2054
1494
|
recentTools: [],
|
|
2055
1495
|
recentOutput: []
|
|
2056
1496
|
}));
|
|
@@ -2104,7 +1544,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2104
1544
|
model: step.model,
|
|
2105
1545
|
...step.contextLimit !== undefined ? { contextLimit: step.contextLimit } : {},
|
|
2106
1546
|
thinking: step.thinking,
|
|
2107
|
-
|
|
1547
|
+
requestedModel: step.requestedModel,
|
|
2108
1548
|
recentTools: [],
|
|
2109
1549
|
recentOutput: []
|
|
2110
1550
|
}));
|
|
@@ -2168,22 +1608,32 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2168
1608
|
},
|
|
2169
1609
|
onError: (error, filePath) => console.error(`Failed to update async run index '${filePath}':`, error)
|
|
2170
1610
|
});
|
|
2171
|
-
const queueActiveRunIndex = () => {
|
|
2172
|
-
const state =
|
|
1611
|
+
const queueActiveRunIndex = (status) => {
|
|
1612
|
+
const state = status.state;
|
|
2173
1613
|
if (state === lastIndexedStatusState && indexPersistence.pendingCount() === 0)
|
|
2174
1614
|
return;
|
|
2175
|
-
indexPersistence.write(asyncDir, { state, toolCallId:
|
|
1615
|
+
indexPersistence.write(asyncDir, { state, toolCallId: status.toolCallId }, (_filePath, payload) => {
|
|
2176
1616
|
const indexPayload = payload;
|
|
2177
1617
|
updateActiveRunIndex(asyncDir, indexPayload.state, indexPayload.toolCallId, { retryCapacityErrors: true });
|
|
2178
1618
|
});
|
|
2179
1619
|
};
|
|
1620
|
+
let finalResultCommitted = false;
|
|
1621
|
+
let finalResultPublication;
|
|
2180
1622
|
const runPersistence = createCapacityResilientJsonWriter({
|
|
2181
1623
|
keepAlive: true,
|
|
2182
|
-
onSuccess: (filePath) => {
|
|
1624
|
+
onSuccess: (filePath, payload) => {
|
|
2183
1625
|
if (filePath === statusPath)
|
|
2184
|
-
queueActiveRunIndex();
|
|
1626
|
+
queueActiveRunIndex(payload);
|
|
1627
|
+
if (filePath === resultPath && finalResultPublication) {
|
|
1628
|
+
finalResultCommitted = true;
|
|
1629
|
+
finalResultPublication.resolve();
|
|
1630
|
+
}
|
|
2185
1631
|
},
|
|
2186
|
-
onError: (error, filePath) =>
|
|
1632
|
+
onError: (error, filePath) => {
|
|
1633
|
+
console.error(`Failed to persist async run state '${filePath}':`, error);
|
|
1634
|
+
if (filePath === resultPath)
|
|
1635
|
+
finalResultPublication?.reject(error);
|
|
1636
|
+
}
|
|
2187
1637
|
});
|
|
2188
1638
|
try {
|
|
2189
1639
|
fs.mkdirSync(asyncDir, { recursive: true });
|
|
@@ -2192,7 +1642,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2192
1642
|
throw error;
|
|
2193
1643
|
console.error(`Failed to prepare async run storage '${asyncDir}' while storage is full:`, error);
|
|
2194
1644
|
}
|
|
2195
|
-
runPersistence.write(statusPath, statusPayload);
|
|
1645
|
+
runPersistence.write(statusPath, { ...statusPayload });
|
|
2196
1646
|
let pendingParallelUsageCost = { inputTokens: 0, outputTokens: 0, costUsd: 0 };
|
|
2197
1647
|
const currentUsageTotals = () => {
|
|
2198
1648
|
const cost = results.reduce((sum, result) => ({
|
|
@@ -2210,6 +1660,11 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2210
1660
|
setOptionalProperty(statusPayload, "usageBudget", usageBudgetState(config.usageBudget, currentUsageTotals()));
|
|
2211
1661
|
return statusPayload.usageBudget;
|
|
2212
1662
|
};
|
|
1663
|
+
let continuationUsageUncertain = config.steps.some(isDynamicRunnerGroup) || flatSteps.some((step) => Boolean(step.runner || step.importAsyncRoot));
|
|
1664
|
+
const continuationUsageBudgetExhausted = () => {
|
|
1665
|
+
const exhausted = refreshUsageBudget()?.exhausted === true;
|
|
1666
|
+
return exhausted ? true : config.usageBudget && continuationUsageUncertain ? undefined : false;
|
|
1667
|
+
};
|
|
2213
1668
|
const emitNestedSelfEvent = (type) => {
|
|
2214
1669
|
if (!config.nestedRoute || !config.nestedSelf)
|
|
2215
1670
|
return;
|
|
@@ -2278,7 +1733,6 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2278
1733
|
updateNode(node);
|
|
2279
1734
|
statusPayload.workflowGraph = graph;
|
|
2280
1735
|
};
|
|
2281
|
-
let finalResultCommitted = false;
|
|
2282
1736
|
const statusResultState = () => {
|
|
2283
1737
|
if (statusPayload.state === "running" || statusPayload.state === "queued")
|
|
2284
1738
|
return;
|
|
@@ -2335,9 +1789,8 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2335
1789
|
success: statusResultSuccess(state, step),
|
|
2336
1790
|
sessionFile: step.sessionFile,
|
|
2337
1791
|
model: step.model,
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
usage: usageFromAttempts(step.modelAttempts),
|
|
1792
|
+
thinking: step.thinking,
|
|
1793
|
+
requestedModel: step.requestedModel,
|
|
2341
1794
|
contextOverflow: step.contextOverflow
|
|
2342
1795
|
})),
|
|
2343
1796
|
exitCode: state === "complete" || state === "paused" ? 0 : 1,
|
|
@@ -2351,14 +1804,16 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2351
1804
|
}), (filePath, payload) => writePendingAsyncResultFile(filePath, payload));
|
|
2352
1805
|
};
|
|
2353
1806
|
const writeStatusPayloadNow = () => {
|
|
1807
|
+
if (finalResultPublication)
|
|
1808
|
+
return;
|
|
2354
1809
|
refreshWorkflowGraph();
|
|
2355
1810
|
writeRecoverableStatusResult();
|
|
2356
|
-
runPersistence.write(statusPath, statusPayload);
|
|
1811
|
+
runPersistence.write(statusPath, { ...statusPayload });
|
|
2357
1812
|
emitNestedSelfEvent(statusPayload.state === "running" || statusPayload.state === "queued" ? "subagent.nested.updated" : "subagent.nested.completed");
|
|
2358
1813
|
};
|
|
2359
1814
|
const statusWriteCoalescer = createFileCoalescer(writeStatusPayloadNow, 100);
|
|
2360
1815
|
const writeStatusPayload = (immediate = true) => {
|
|
2361
|
-
if (immediate || statusPayload.state !== "running"
|
|
1816
|
+
if (immediate || statusPayload.state !== "running") {
|
|
2362
1817
|
if (!statusWriteCoalescer.flush(statusPath))
|
|
2363
1818
|
writeStatusPayloadNow();
|
|
2364
1819
|
return;
|
|
@@ -2483,6 +1938,17 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2483
1938
|
if (stopped || childStopRequests.has(flatIndex))
|
|
2484
1939
|
stop();
|
|
2485
1940
|
};
|
|
1941
|
+
const registerStepSteer = (flatIndex, steer) => {
|
|
1942
|
+
if (!steer) {
|
|
1943
|
+
activeChildSteers.delete(flatIndex);
|
|
1944
|
+
return;
|
|
1945
|
+
}
|
|
1946
|
+
activeChildSteers.set(flatIndex, steer);
|
|
1947
|
+
const queued = queuedStepSteers.get(flatIndex);
|
|
1948
|
+
queuedStepSteers.delete(flatIndex);
|
|
1949
|
+
for (const request of queued ?? [])
|
|
1950
|
+
steerLiveChild(flatIndex, request);
|
|
1951
|
+
};
|
|
2486
1952
|
const interruptActiveChildren = () => {
|
|
2487
1953
|
for (const interrupt of [...activeChildInterrupts.values()])
|
|
2488
1954
|
interrupt();
|
|
@@ -2502,6 +1968,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2502
1968
|
yield* nestedRuns(child.steps?.flatMap((step) => step.children ?? []));
|
|
2503
1969
|
}
|
|
2504
1970
|
};
|
|
1971
|
+
const isNestedControlDescendant = (run) => !config.nestedSelf || run.path.some((entry) => entry.runId === id);
|
|
2505
1972
|
const interruptNestedAsyncDescendants = () => {
|
|
2506
1973
|
if (!config.nestedRoute)
|
|
2507
1974
|
return;
|
|
@@ -2518,7 +1985,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2518
1985
|
return;
|
|
2519
1986
|
}
|
|
2520
1987
|
for (const run of nestedRuns(registry.children)) {
|
|
2521
|
-
if (run.state !== "running" && run.state !== "queued")
|
|
1988
|
+
if (!isNestedControlDescendant(run) || run.state !== "running" && run.state !== "queued")
|
|
2522
1989
|
continue;
|
|
2523
1990
|
const nestedAsyncDir = run.asyncDir ?? resolveNestedAsyncDir(config.nestedRoute.rootRunId, run);
|
|
2524
1991
|
if (!nestedAsyncDir)
|
|
@@ -2552,7 +2019,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2552
2019
|
return;
|
|
2553
2020
|
}
|
|
2554
2021
|
for (const run of nestedRuns(registry.children)) {
|
|
2555
|
-
if (run.state !== "running" && run.state !== "queued")
|
|
2022
|
+
if (!isNestedControlDescendant(run) || run.state !== "running" && run.state !== "queued")
|
|
2556
2023
|
continue;
|
|
2557
2024
|
const nestedAsyncDir = run.asyncDir ?? resolveNestedAsyncDir(config.nestedRoute.rootRunId, run);
|
|
2558
2025
|
if (!nestedAsyncDir)
|
|
@@ -2586,7 +2053,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2586
2053
|
return;
|
|
2587
2054
|
}
|
|
2588
2055
|
for (const run of nestedRuns(registry.children)) {
|
|
2589
|
-
if (run.state !== "running" && run.state !== "queued")
|
|
2056
|
+
if (!isNestedControlDescendant(run) || run.state !== "running" && run.state !== "queued")
|
|
2590
2057
|
continue;
|
|
2591
2058
|
const nestedAsyncDir = run.asyncDir ?? resolveNestedAsyncDir(config.nestedRoute.rootRunId, run);
|
|
2592
2059
|
if (!nestedAsyncDir)
|
|
@@ -2645,6 +2112,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2645
2112
|
}
|
|
2646
2113
|
const appendedSteps = requests.flatMap((request) => request.steps);
|
|
2647
2114
|
steps.push(...appendedSteps);
|
|
2115
|
+
flatSteps.push(...flattenSteps(appendedSteps));
|
|
2648
2116
|
const now = Date.now();
|
|
2649
2117
|
const pendingAppends = countPendingChainAppendRequests(asyncDir);
|
|
2650
2118
|
const added = appendRunnerStepsToStatus({
|
|
@@ -2680,9 +2148,64 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2680
2148
|
setOptionalProperty(groupNode, "error", error);
|
|
2681
2149
|
setOptionalProperty(groupNode, "acceptanceStatus", acceptance?.status ?? groupNode.acceptanceStatus);
|
|
2682
2150
|
};
|
|
2151
|
+
const EXTERNAL_GIT_PROBE_MIN_INTERVAL_MS = 2000;
|
|
2152
|
+
const externalActivityEvidence = new Map;
|
|
2153
|
+
const gitProbesByCwd = new Map;
|
|
2154
|
+
let periodicGitProbeFailure;
|
|
2155
|
+
const reportedGitProbeErrors = new Set;
|
|
2156
|
+
const reportGitProbeError = (externalCwd, error) => {
|
|
2157
|
+
if (reportedGitProbeErrors.has(externalCwd))
|
|
2158
|
+
return;
|
|
2159
|
+
reportedGitProbeErrors.add(externalCwd);
|
|
2160
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
2161
|
+
console.error(`[dm-subagents] Git activity evidence unavailable for '${externalCwd.slice(-300)}'; check the cwd and Git installation: ${detail.slice(0, 500)}`);
|
|
2162
|
+
};
|
|
2163
|
+
const readSharedGitFingerprint = (externalCwd) => {
|
|
2164
|
+
const inFlight = gitProbesByCwd.get(externalCwd);
|
|
2165
|
+
if (inFlight)
|
|
2166
|
+
return inFlight;
|
|
2167
|
+
const probe = readGitFingerprint(externalCwd, runStopSignal, (error) => reportGitProbeError(externalCwd, error)).finally(() => gitProbesByCwd.delete(externalCwd));
|
|
2168
|
+
gitProbesByCwd.set(externalCwd, probe);
|
|
2169
|
+
return probe;
|
|
2170
|
+
};
|
|
2171
|
+
const recordPeriodicGitProbeFailure = (index, error) => {
|
|
2172
|
+
if (periodicGitProbeFailure)
|
|
2173
|
+
return;
|
|
2174
|
+
const cause = error instanceof Error ? error : new Error(String(error));
|
|
2175
|
+
const message = `PROCESS_TREE_UNVERIFIED: ${cause.message}`;
|
|
2176
|
+
periodicGitProbeFailure = { index, error: cause, message };
|
|
2177
|
+
statusPayload.error = message;
|
|
2178
|
+
const step = statusPayload.steps[index];
|
|
2179
|
+
if (step)
|
|
2180
|
+
step.error = message;
|
|
2181
|
+
statusPayload.lastUpdate = Date.now();
|
|
2182
|
+
writeStatusPayload();
|
|
2183
|
+
appendJsonl(eventsPath, JSON.stringify({
|
|
2184
|
+
type: "subagent.run.process_tree_unverified",
|
|
2185
|
+
ts: statusPayload.lastUpdate,
|
|
2186
|
+
runId: id,
|
|
2187
|
+
index,
|
|
2188
|
+
code: "PROCESS_TREE_UNVERIFIED",
|
|
2189
|
+
message
|
|
2190
|
+
}));
|
|
2191
|
+
};
|
|
2192
|
+
const prepareExternalActivity = async (index, externalCwd, signal) => {
|
|
2193
|
+
if (!controlConfig.enabled)
|
|
2194
|
+
return;
|
|
2195
|
+
const resolvedCwd = path.resolve(externalCwd);
|
|
2196
|
+
const evidence = { cwd: resolvedCwd, lastProbeStartedAt: performance.now() };
|
|
2197
|
+
externalActivityEvidence.set(index, evidence);
|
|
2198
|
+
evidence.fingerprint = await readGitFingerprint(resolvedCwd, signal, (error) => reportGitProbeError(resolvedCwd, error));
|
|
2199
|
+
};
|
|
2200
|
+
const recordExternalStreamActivity = (index) => {
|
|
2201
|
+
const evidence = externalActivityEvidence.get(index) ?? {};
|
|
2202
|
+
externalActivityEvidence.set(index, evidence);
|
|
2203
|
+
evidence.lastStreamActivityAt = Date.now();
|
|
2204
|
+
};
|
|
2683
2205
|
const stepOutputActivityAt = (index) => {
|
|
2684
2206
|
const step = statusPayload.steps[index];
|
|
2685
2207
|
let lastActivityAt = step?.lastActivityAt ?? step?.startedAt ?? overallStartTime;
|
|
2208
|
+
lastActivityAt = Math.max(lastActivityAt, externalActivityEvidence.get(index)?.lastStreamActivityAt ?? 0);
|
|
2686
2209
|
const outputPath = path.join(asyncDir, `output-${index}.log`);
|
|
2687
2210
|
try {
|
|
2688
2211
|
lastActivityAt = Math.max(lastActivityAt, fs.statSync(outputPath).mtimeMs);
|
|
@@ -2934,23 +2457,15 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2934
2457
|
return { index, state: "scheduled" };
|
|
2935
2458
|
if (step.status !== "running")
|
|
2936
2459
|
return { index, state: "failed", reason: `child is ${step.status}` };
|
|
2937
|
-
if (steeringCapabilities.get(index)?.supported === false)
|
|
2938
|
-
return { index, state: "failed", reason: "child DM session does not support steering" };
|
|
2939
2460
|
return { index, state: "routed" };
|
|
2940
2461
|
});
|
|
2941
2462
|
recordSteeringLifecycle(request, targetStates);
|
|
2942
2463
|
emitSteeringEvent("subagent.steer.requested", request, undefined, { targets: targetStates });
|
|
2943
2464
|
for (const target of targetStates) {
|
|
2944
2465
|
if (target.state === "routed") {
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
emitSteeringEvent("subagent.steer.routed", request, target.index);
|
|
2949
|
-
} catch (error) {
|
|
2950
|
-
markSteeringAttention(target.index);
|
|
2951
|
-
updateSteeringLifecycleTarget(request.id, target.index, "failed", now, { reason: error instanceof Error ? error.message : String(error) });
|
|
2952
|
-
emitSteeringEvent("subagent.steer.failed", request, target.index, { reason: error instanceof Error ? error.message : String(error) });
|
|
2953
|
-
}
|
|
2466
|
+
updateSteeringLifecycleTarget(request.id, target.index, "routed", now);
|
|
2467
|
+
emitSteeringEvent("subagent.steer.routed", request, target.index);
|
|
2468
|
+
steerLiveChild(target.index, request);
|
|
2954
2469
|
} else if (target.state === "failed") {
|
|
2955
2470
|
markSteeringAttention(target.index);
|
|
2956
2471
|
emitSteeringEvent("subagent.steer.failed", request, target.index, { reason: target.reason });
|
|
@@ -2962,28 +2477,43 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
2962
2477
|
statusPayload.lastUpdate = now;
|
|
2963
2478
|
writeStatusPayload();
|
|
2964
2479
|
};
|
|
2965
|
-
const
|
|
2480
|
+
const applySteerDelivery = (requestId, index, delivery) => {
|
|
2966
2481
|
const lifecycle = steeringStatus(statusPayload);
|
|
2967
|
-
const request = lifecycle.recent.find((candidate) => candidate.id ===
|
|
2968
|
-
|
|
2482
|
+
const request = lifecycle.recent.find((candidate) => candidate.id === requestId);
|
|
2483
|
+
const target = request?.targets.find((candidate) => candidate.index === index);
|
|
2484
|
+
if (!request || !target)
|
|
2485
|
+
return;
|
|
2486
|
+
if (target.state === "delivered" || target.state === "late" || target.state === "failed")
|
|
2969
2487
|
return;
|
|
2970
|
-
|
|
2488
|
+
if (target.state === delivery.state)
|
|
2489
|
+
return;
|
|
2490
|
+
const late = fs.existsSync(steeringMarkerPath(requestId));
|
|
2971
2491
|
const now = Date.now();
|
|
2972
|
-
if (
|
|
2973
|
-
updateSteeringLifecycleTarget(
|
|
2974
|
-
emitSteeringEvent("subagent.steer.delivered", { type: "steer", id:
|
|
2975
|
-
} else if (
|
|
2976
|
-
updateSteeringLifecycleTarget(
|
|
2977
|
-
emitSteeringEvent("subagent.steer.queued", { type: "steer", id:
|
|
2492
|
+
if (delivery.state === "delivered") {
|
|
2493
|
+
updateSteeringLifecycleTarget(requestId, index, late ? "late" : "delivered", now, omitUndefinedProperties({ reason: late ? "acknowledged after recovery commit" : undefined }));
|
|
2494
|
+
emitSteeringEvent("subagent.steer.delivered", { type: "steer", id: requestId, ts: now, message: delivery.message }, index, { late, deliveryStatus: "delivered", message: delivery.message });
|
|
2495
|
+
} else if (delivery.state === "queued") {
|
|
2496
|
+
updateSteeringLifecycleTarget(requestId, index, "queued", now);
|
|
2497
|
+
emitSteeringEvent("subagent.steer.queued", { type: "steer", id: requestId, ts: now, message: delivery.message }, index, { deliveryStatus: "queued", message: delivery.message });
|
|
2978
2498
|
} else {
|
|
2979
|
-
markSteeringAttention(
|
|
2980
|
-
updateSteeringLifecycleTarget(
|
|
2981
|
-
emitSteeringEvent("subagent.steer.failed", { type: "steer", id:
|
|
2499
|
+
markSteeringAttention(index);
|
|
2500
|
+
updateSteeringLifecycleTarget(requestId, index, "failed", now, { reason: delivery.message });
|
|
2501
|
+
emitSteeringEvent("subagent.steer.failed", { type: "steer", id: requestId, ts: now, message: delivery.message }, index, { reason: delivery.message });
|
|
2982
2502
|
}
|
|
2983
|
-
emitTerminalSteeringNotice(
|
|
2503
|
+
emitTerminalSteeringNotice(requestId, `Steering failed for run ${id}: ${delivery.message}`);
|
|
2984
2504
|
statusPayload.lastUpdate = now;
|
|
2985
2505
|
writeStatusPayload();
|
|
2986
2506
|
};
|
|
2507
|
+
const steerLiveChild = (index, request) => {
|
|
2508
|
+
const steer = activeChildSteers.get(index);
|
|
2509
|
+
if (!steer) {
|
|
2510
|
+
const queued = queuedStepSteers.get(index) ?? [];
|
|
2511
|
+
queued.push(request);
|
|
2512
|
+
queuedStepSteers.set(index, queued);
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2515
|
+
steer(request).then((delivery) => applySteerDelivery(request.id, index, delivery), (error) => applySteerDelivery(request.id, index, { state: "failed", message: error instanceof Error ? error.message : String(error) }));
|
|
2516
|
+
};
|
|
2987
2517
|
const flushPendingStepSteers = (flatIndex) => {
|
|
2988
2518
|
const remaining = [];
|
|
2989
2519
|
for (const request of pendingStepSteers.splice(0)) {
|
|
@@ -3010,6 +2540,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3010
2540
|
const step = statusPayload.steps[flatIndex];
|
|
3011
2541
|
if (!step)
|
|
3012
2542
|
return;
|
|
2543
|
+
const previousActivityState = step.activityState;
|
|
3013
2544
|
const now = Date.now();
|
|
3014
2545
|
statusPayload.currentStep = flatIndex;
|
|
3015
2546
|
if (isChildWatchdogStatusEvent(event)) {
|
|
@@ -3029,6 +2560,16 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3029
2560
|
writeStatusPayload(false);
|
|
3030
2561
|
return;
|
|
3031
2562
|
}
|
|
2563
|
+
if (event.type === "message_end") {
|
|
2564
|
+
const next = applyChildWatchdogMessage(step.watchdog, event.message);
|
|
2565
|
+
if (next)
|
|
2566
|
+
step.watchdog = next;
|
|
2567
|
+
if (next && event.message?.role === "custom") {
|
|
2568
|
+
statusPayload.lastUpdate = now;
|
|
2569
|
+
writeStatusPayload(false);
|
|
2570
|
+
return;
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
3032
2573
|
if (event.type === "tool_execution_start" && event.toolName) {
|
|
3033
2574
|
const mutates = isMutatingTool(event.toolName, event.args, flatSteps[flatIndex]?.mutationTools);
|
|
3034
2575
|
const currentPath = resolveCurrentPath(event.toolName, event.args);
|
|
@@ -3064,6 +2605,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3064
2605
|
tokens: step.tokens?.total,
|
|
3065
2606
|
toolCount: step.toolCount,
|
|
3066
2607
|
currentTool: step.currentTool,
|
|
2608
|
+
toolCallId: event.toolCallId,
|
|
3067
2609
|
currentToolDurationMs: 0,
|
|
3068
2610
|
currentPath: step.currentPath
|
|
3069
2611
|
})));
|
|
@@ -3138,6 +2680,11 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3138
2680
|
`).slice(-10));
|
|
3139
2681
|
step.turnCount = (step.turnCount ?? 0) + 1;
|
|
3140
2682
|
const usage = event.message.usage;
|
|
2683
|
+
if (config.usageBudget) {
|
|
2684
|
+
const known = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
2685
|
+
if (!known(usage?.input ?? usage?.inputTokens) || !known(usage?.output ?? usage?.outputTokens))
|
|
2686
|
+
continuationUsageUncertain = true;
|
|
2687
|
+
}
|
|
3141
2688
|
if (usage) {
|
|
3142
2689
|
const input = usage.input ?? usage.inputTokens ?? 0;
|
|
3143
2690
|
const output = usage.output ?? usage.outputTokens ?? 0;
|
|
@@ -3157,9 +2704,9 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3157
2704
|
statusPayload.lastActivityAt = now;
|
|
3158
2705
|
statusPayload.lastUpdate = now;
|
|
3159
2706
|
maybeEmitActiveLongRunning(flatIndex, now);
|
|
3160
|
-
writeStatusPayload(
|
|
2707
|
+
writeStatusPayload(step.activityState !== previousActivityState);
|
|
3161
2708
|
};
|
|
3162
|
-
const updateRunnerActivityState = (now) => {
|
|
2709
|
+
const updateRunnerActivityState = (now, skipExternalProbeIndex) => {
|
|
3163
2710
|
if (!controlConfig.enabled)
|
|
3164
2711
|
return false;
|
|
3165
2712
|
let changed = false;
|
|
@@ -3178,11 +2725,37 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3178
2725
|
config: controlConfig,
|
|
3179
2726
|
startedAt: step.startedAt ?? overallStartTime,
|
|
3180
2727
|
lastActivityAt,
|
|
2728
|
+
turnCount: flatSteps[index]?.runner?.type === "external-cli" ? 1 : step.turnCount,
|
|
3181
2729
|
currentTool: step.currentTool,
|
|
3182
2730
|
thinking: step.thinking,
|
|
3183
2731
|
now
|
|
3184
2732
|
}));
|
|
3185
2733
|
if (idleState === "needs_attention") {
|
|
2734
|
+
const evidence = externalActivityEvidence.get(index);
|
|
2735
|
+
if (index !== skipExternalProbeIndex && evidence?.cwd && evidence.fingerprint) {
|
|
2736
|
+
if (evidence.probeInFlight)
|
|
2737
|
+
continue;
|
|
2738
|
+
if (performance.now() - (evidence.lastProbeStartedAt ?? 0) >= EXTERNAL_GIT_PROBE_MIN_INTERVAL_MS) {
|
|
2739
|
+
evidence.lastProbeStartedAt = performance.now();
|
|
2740
|
+
const baseline = evidence.fingerprint;
|
|
2741
|
+
evidence.probeInFlight = readSharedGitFingerprint(evidence.cwd).then((fingerprint) => {
|
|
2742
|
+
if (requiredStatusStep(statusPayload, index).status !== "running")
|
|
2743
|
+
return;
|
|
2744
|
+
if (fingerprint && fingerprint !== baseline) {
|
|
2745
|
+
evidence.fingerprint = fingerprint;
|
|
2746
|
+
evidence.lastStreamActivityAt = Date.now();
|
|
2747
|
+
updateRunnerActivityState(Date.now());
|
|
2748
|
+
} else {
|
|
2749
|
+
updateRunnerActivityState(Date.now(), index);
|
|
2750
|
+
}
|
|
2751
|
+
}).catch((error) => {
|
|
2752
|
+
recordPeriodicGitProbeFailure(index, error);
|
|
2753
|
+
}).finally(() => {
|
|
2754
|
+
delete evidence.probeInFlight;
|
|
2755
|
+
});
|
|
2756
|
+
continue;
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
3186
2759
|
const previous = step.activityState;
|
|
3187
2760
|
step.activityState = "needs_attention";
|
|
3188
2761
|
if (previous !== "needs_attention") {
|
|
@@ -3227,11 +2800,88 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3227
2800
|
}, 1000);
|
|
3228
2801
|
activityTimer.unref?.();
|
|
3229
2802
|
}
|
|
2803
|
+
const publishSetupUnknown = (progress) => {
|
|
2804
|
+
if (!progress.unknown)
|
|
2805
|
+
return;
|
|
2806
|
+
const proof = {
|
|
2807
|
+
version: 1,
|
|
2808
|
+
state: "unknown",
|
|
2809
|
+
runId: id,
|
|
2810
|
+
runnerProcessInstanceId: config.runnerProcessInstanceId ?? "unknown",
|
|
2811
|
+
reason: "process-tree-unverified",
|
|
2812
|
+
diagnostic: `Worktree setup settlement unknown: ${progress.unknown}; manual reconciliation required; ${parallelHandoffPath(asyncDir)}`
|
|
2813
|
+
};
|
|
2814
|
+
statusPayload.processTerminal = proof;
|
|
2815
|
+
writeAtomicJson(processTerminalPath(asyncDir), proof);
|
|
2816
|
+
};
|
|
2817
|
+
const finalizeWorktree = async (setup, stepIndex, flatStartIndex, action, deadlineAt) => {
|
|
2818
|
+
let admitted = false;
|
|
2819
|
+
try {
|
|
2820
|
+
await Promise.all([...externalActivityEvidence.values()].map((evidence) => evidence.probeInFlight).filter((probe) => probe !== undefined));
|
|
2821
|
+
if (periodicGitProbeFailure)
|
|
2822
|
+
throw periodicGitProbeFailure.error;
|
|
2823
|
+
await withWorktreeTransaction(() => {
|
|
2824
|
+
if (deadlineAt !== undefined && Date.now() >= deadlineAt)
|
|
2825
|
+
throw new Error("Run deadline expired before worktree cleanup");
|
|
2826
|
+
admitted = true;
|
|
2827
|
+
action();
|
|
2828
|
+
});
|
|
2829
|
+
} catch (error) {
|
|
2830
|
+
if (admitted)
|
|
2831
|
+
throw error;
|
|
2832
|
+
const reason = `Worktree finalization retained; manual reconciliation required: ${error instanceof Error ? error.message : String(error)}`;
|
|
2833
|
+
statusPayload.parallelHandoff = writeParallelHandoffGroup({
|
|
2834
|
+
manifestPath: parallelHandoffPath(asyncDir),
|
|
2835
|
+
runId: id,
|
|
2836
|
+
mode: (config.resultMode ?? statusPayload.mode) === "parallel" ? "parallel" : (config.resultMode ?? statusPayload.mode) === "single" ? "single" : "chain",
|
|
2837
|
+
source: "async",
|
|
2838
|
+
cwd,
|
|
2839
|
+
stepIndex,
|
|
2840
|
+
flatStartIndex,
|
|
2841
|
+
setup,
|
|
2842
|
+
diffs: [],
|
|
2843
|
+
results: [],
|
|
2844
|
+
cleanup: { state: "partial", pruned: false, errors: [reason], tasks: setup.worktrees.map((worktree) => ({
|
|
2845
|
+
index: worktree.index,
|
|
2846
|
+
path: worktree.path,
|
|
2847
|
+
branch: worktree.branch,
|
|
2848
|
+
provider: worktree.provider,
|
|
2849
|
+
naming: worktree.naming,
|
|
2850
|
+
worktreeRemoved: false,
|
|
2851
|
+
branchRemoved: false,
|
|
2852
|
+
preserved: true,
|
|
2853
|
+
reason
|
|
2854
|
+
})) }
|
|
2855
|
+
});
|
|
2856
|
+
previousOutput = [previousOutput, reason, formatParallelHandoffReference(statusPayload.parallelHandoff)].filter(Boolean).join(`
|
|
2857
|
+
|
|
2858
|
+
`);
|
|
2859
|
+
writeStatusPayload();
|
|
2860
|
+
}
|
|
2861
|
+
};
|
|
2862
|
+
const cleanupRemainingWorktree = (setup, stepIndex, flatStartIndex) => finalizeWorktree(setup, stepIndex, flatStartIndex, () => {
|
|
2863
|
+
const cleanup = cleanupWorktrees(setup);
|
|
2864
|
+
statusPayload.parallelHandoff = writeParallelHandoffGroup({
|
|
2865
|
+
manifestPath: parallelHandoffPath(asyncDir),
|
|
2866
|
+
runId: id,
|
|
2867
|
+
mode: (config.resultMode ?? statusPayload.mode) === "parallel" ? "parallel" : (config.resultMode ?? statusPayload.mode) === "single" ? "single" : "chain",
|
|
2868
|
+
source: "async",
|
|
2869
|
+
cwd,
|
|
2870
|
+
stepIndex,
|
|
2871
|
+
flatStartIndex,
|
|
2872
|
+
setup,
|
|
2873
|
+
diffs: [],
|
|
2874
|
+
results: [],
|
|
2875
|
+
cleanup
|
|
2876
|
+
});
|
|
2877
|
+
writeStatusPayload();
|
|
2878
|
+
}, config.deadlineAt);
|
|
3230
2879
|
const interruptRunner = () => {
|
|
3231
2880
|
consumeInterruptRequest(asyncDir);
|
|
3232
2881
|
if (interrupted || statusPayload.state !== "running")
|
|
3233
2882
|
return;
|
|
3234
2883
|
interrupted = true;
|
|
2884
|
+
setupInterruptController.abort();
|
|
3235
2885
|
const now = Date.now();
|
|
3236
2886
|
statusPayload.state = "paused";
|
|
3237
2887
|
currentActivityState = undefined;
|
|
@@ -3256,17 +2906,18 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3256
2906
|
interruptActiveChildren();
|
|
3257
2907
|
};
|
|
3258
2908
|
const stopRunner = () => {
|
|
3259
|
-
if (stopped || timedOut ||
|
|
2909
|
+
if (stopped || timedOut || statusPayload.state !== "running" && statusPayload.state !== "paused")
|
|
3260
2910
|
return;
|
|
3261
2911
|
stopped = true;
|
|
2912
|
+
interrupted = false;
|
|
3262
2913
|
const now = Date.now();
|
|
3263
2914
|
statusPayload.stopped = true;
|
|
3264
2915
|
statusPayload.error = stopMessage;
|
|
3265
2916
|
currentActivityState = undefined;
|
|
3266
2917
|
delete statusPayload.activityState;
|
|
3267
2918
|
statusPayload.lastUpdate = now;
|
|
3268
|
-
for (const step of statusPayload.steps) {
|
|
3269
|
-
if (step.status !== "running" && step.status !== "pending")
|
|
2919
|
+
for (const [index, step] of statusPayload.steps.entries()) {
|
|
2920
|
+
if (step.status !== "running" && step.status !== "pending" && step.status !== "paused")
|
|
3270
2921
|
continue;
|
|
3271
2922
|
step.status = "stopped";
|
|
3272
2923
|
step.error = stopMessage;
|
|
@@ -3276,6 +2927,9 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3276
2927
|
step.endedAt = now;
|
|
3277
2928
|
step.durationMs = step.startedAt ? now - step.startedAt : 0;
|
|
3278
2929
|
step.lastActivityAt = now;
|
|
2930
|
+
const result = results[index];
|
|
2931
|
+
if (result?.interrupted)
|
|
2932
|
+
results[index] = { ...result, output: stopMessage, error: stopMessage, exitCode: 1, success: false, interrupted: false, stopped: true };
|
|
3279
2933
|
}
|
|
3280
2934
|
writeStatusPayload();
|
|
3281
2935
|
appendJsonl(eventsPath, JSON.stringify({
|
|
@@ -3340,30 +2994,35 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3340
2994
|
deliverSteerRequest(request);
|
|
3341
2995
|
pendingStepSteers.push(request);
|
|
3342
2996
|
}
|
|
3343
|
-
}
|
|
3344
|
-
onSteerCapability: (capability) => {
|
|
3345
|
-
steeringCapabilities.set(capability.index, capability);
|
|
3346
|
-
if (!capability.supported) {
|
|
3347
|
-
const now = Date.now();
|
|
3348
|
-
const lifecycle = steeringStatus(statusPayload);
|
|
3349
|
-
for (const request of lifecycle.recent) {
|
|
3350
|
-
if (!request.targets.some((target) => target.index === capability.index && (target.state === "routed" || target.state === "scheduled")))
|
|
3351
|
-
continue;
|
|
3352
|
-
markSteeringAttention(capability.index);
|
|
3353
|
-
updateSteeringLifecycleTarget(request.id, capability.index, "failed", now, { reason: "child DM session does not support steering" });
|
|
3354
|
-
emitSteeringEvent("subagent.steer.failed", { type: "steer", id: request.id, ts: request.requestedAt, message: "child DM session does not support steering" }, capability.index, { reason: "child DM session does not support steering" });
|
|
3355
|
-
emitTerminalSteeringNotice(request.id, `Steering failed for run ${id}: child ${capability.index} does not support steering.`);
|
|
3356
|
-
}
|
|
3357
|
-
statusPayload.lastUpdate = now;
|
|
3358
|
-
writeStatusPayload();
|
|
3359
|
-
}
|
|
3360
|
-
},
|
|
3361
|
-
onSteerAck: consumeSteerAck
|
|
2997
|
+
}
|
|
3362
2998
|
});
|
|
3363
2999
|
if (config.deadlineAt !== undefined) {
|
|
3364
3000
|
const remainingMs = Math.max(0, config.deadlineAt - Date.now());
|
|
3365
3001
|
timeoutTimer = setTimeout(timeoutRunner, remainingMs);
|
|
3366
3002
|
timeoutTimer.unref?.();
|
|
3003
|
+
const checkpointBeforeDeadlineMs = config.checkpointBeforeDeadlineMs;
|
|
3004
|
+
const checkpointDelayMs = checkpointBeforeDeadlineMs === undefined || !Number.isInteger(checkpointBeforeDeadlineMs) || checkpointBeforeDeadlineMs <= 0 ? undefined : remainingMs - checkpointBeforeDeadlineMs;
|
|
3005
|
+
if (checkpointDelayMs !== undefined && checkpointDelayMs >= 1000) {
|
|
3006
|
+
const deadlineAt = config.deadlineAt;
|
|
3007
|
+
checkpointTimer = setTimeout(() => {
|
|
3008
|
+
checkpointTimer = undefined;
|
|
3009
|
+
if (timedOut || stopped || interrupted)
|
|
3010
|
+
return;
|
|
3011
|
+
if (!statusPayload.steps.some((step) => step.status === "running"))
|
|
3012
|
+
return;
|
|
3013
|
+
const now = Date.now();
|
|
3014
|
+
const seconds = Math.round(Math.max(0, deadlineAt - now) / 1000);
|
|
3015
|
+
deliverSteerRequest({
|
|
3016
|
+
type: "steer",
|
|
3017
|
+
id: `deadline-checkpoint-${now}`,
|
|
3018
|
+
ts: now,
|
|
3019
|
+
mode: "steer",
|
|
3020
|
+
source: "deadline-checkpoint",
|
|
3021
|
+
message: `Deadline checkpoint from the runner: this run is killed in about ${seconds} seconds. Finish the current tool call only, then stop and reply with a handoff: changed files, build/test state, remaining work, and commit/PR state. Do not start new work.`
|
|
3022
|
+
});
|
|
3023
|
+
}, checkpointDelayMs);
|
|
3024
|
+
checkpointTimer.unref?.();
|
|
3025
|
+
}
|
|
3367
3026
|
}
|
|
3368
3027
|
appendJsonl(eventsPath, JSON.stringify({
|
|
3369
3028
|
type: "subagent.run.started",
|
|
@@ -3406,10 +3065,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3406
3065
|
const thinkingOverride = step.thinkingOverrides?.[itemIndex];
|
|
3407
3066
|
const model = thinkingOverride ? applyThinkingSuffix(step.parallel.model, thinkingOverride, true) : step.parallel.model;
|
|
3408
3067
|
const configThinking = thinkingOverride ? thinkingOverride : step.parallel.thinking;
|
|
3409
|
-
|
|
3410
|
-
for (const candidate of candidates) {
|
|
3411
|
-
assertThinkingWithinCeiling({ model: candidate, configThinking, ceiling: step.parallel.thinkingCeiling ?? decodeThinkingCeiling(process.env[SUBAGENT_THINKING_CEILING_ENV]), agent: step.parallel.agent, runId: id });
|
|
3412
|
-
}
|
|
3068
|
+
assertThinkingWithinCeiling({ model, configThinking, ceiling: step.parallel.thinkingCeiling, agent: step.parallel.agent, runId: id });
|
|
3413
3069
|
}
|
|
3414
3070
|
if (materialized.collectedOnEmpty)
|
|
3415
3071
|
await validateDynamicCollection(step.collect.outputSchema, materialized.collectedOnEmpty);
|
|
@@ -3477,14 +3133,14 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3477
3133
|
cwd,
|
|
3478
3134
|
signal: combinedAbortSignal([timeoutAbortController.signal, stopAbortController.signal]),
|
|
3479
3135
|
abortMessage: stopAbortController.signal.aborted ? stopMessage : timeoutMessage ?? "Subagent timed out.",
|
|
3480
|
-
reportOptional:
|
|
3136
|
+
reportOptional: isAgentContract(step.agentContract)
|
|
3481
3137
|
})) : undefined;
|
|
3482
3138
|
const groupStopped = stopped || stopAbortController.signal.aborted;
|
|
3483
3139
|
const groupTimedOut = !groupStopped && (timedOut || timeoutAbortController.signal.aborted);
|
|
3484
3140
|
const effectiveGroupAcceptance = groupTimedOut || groupStopped ? undefined : groupAcceptance;
|
|
3485
3141
|
if (placeholder && effectiveGroupAcceptance)
|
|
3486
3142
|
placeholder.acceptance = effectiveGroupAcceptance;
|
|
3487
|
-
const groupAcceptanceFailure = effectiveGroupAcceptance && (!
|
|
3143
|
+
const groupAcceptanceFailure = effectiveGroupAcceptance && (!isAgentContract(step.agentContract) || step.gateOn === "acceptance") ? acceptanceFailureMessage(effectiveGroupAcceptance) : undefined;
|
|
3488
3144
|
if (groupTimedOut || groupStopped || groupAcceptanceFailure) {
|
|
3489
3145
|
const errorMessage = groupStopped ? stopMessage : groupTimedOut ? timeoutMessage ?? "Subagent timed out." : groupAcceptanceFailure;
|
|
3490
3146
|
statusPayload.state = groupStopped ? "stopped" : "failed";
|
|
@@ -3538,11 +3194,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3538
3194
|
...step.sessionFiles?.[itemIndex] ? { sessionFile: step.sessionFiles[itemIndex] } : {},
|
|
3539
3195
|
...thinkingOverride ? {
|
|
3540
3196
|
...model ? { model } : {},
|
|
3541
|
-
...thinking ? { thinking } : {}
|
|
3542
|
-
...step.parallel.modelCandidates ? { modelCandidates: step.parallel.modelCandidates.flatMap((candidate) => {
|
|
3543
|
-
const resolved = applyThinkingSuffix(candidate, thinkingOverride, true);
|
|
3544
|
-
return resolved ? [resolved] : [];
|
|
3545
|
-
}) } : {}
|
|
3197
|
+
...thinking ? { thinking } : {}
|
|
3546
3198
|
} : {},
|
|
3547
3199
|
structuredOutputSchema: step.parallel.structuredOutputSchema ?? step.parallel.structuredOutput?.schema
|
|
3548
3200
|
});
|
|
@@ -3569,7 +3221,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3569
3221
|
...task.contextLimit !== undefined ? { contextLimit: task.contextLimit } : {},
|
|
3570
3222
|
...task.thinking ? { thinking: task.thinking } : {},
|
|
3571
3223
|
...task.thinkingCeiling ? { thinkingCeiling: task.thinkingCeiling } : {},
|
|
3572
|
-
...task.
|
|
3224
|
+
...task.requestedModel ? { requestedModel: task.requestedModel } : {},
|
|
3573
3225
|
recentTools: [],
|
|
3574
3226
|
recentOutput: []
|
|
3575
3227
|
});
|
|
@@ -3687,11 +3339,9 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3687
3339
|
flatIndex: fi,
|
|
3688
3340
|
flatStepCount: Math.max(statusPayload.steps.length, 1),
|
|
3689
3341
|
outputFile: path.join(asyncDir, `output-${fi}.log`),
|
|
3690
|
-
steerInboxDir: stepSteerInboxDir(asyncDir, fi),
|
|
3691
|
-
steerCapabilityPath: steerCapabilityPath(asyncDir, fi),
|
|
3692
|
-
steerAckDir: steerAcksDir(asyncDir, fi),
|
|
3693
3342
|
piPackageRoot: config.piPackageRoot,
|
|
3694
|
-
|
|
3343
|
+
childSessions,
|
|
3344
|
+
inheritedChildRuntime: config.inheritedChildRuntime,
|
|
3695
3345
|
childIntercomTarget: config.childIntercomTargets?.[fi],
|
|
3696
3346
|
orchestratorIntercomTarget: config.controlIntercomTarget,
|
|
3697
3347
|
nestedRoute: config.nestedRoute,
|
|
@@ -3700,25 +3350,28 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3700
3350
|
registerInterrupt: (interrupt) => registerStepInterrupt(fi, interrupt),
|
|
3701
3351
|
registerTimeout: (interrupt) => registerStepTimeout(fi, interrupt),
|
|
3702
3352
|
registerStop: (stop) => registerStepStop(fi, stop),
|
|
3353
|
+
registerSteer: (steer) => registerStepSteer(fi, steer),
|
|
3354
|
+
onSteerOutcome: (request, delivery) => applySteerDelivery(request.id, fi, delivery),
|
|
3703
3355
|
timeoutSignal: timeoutAbortController.signal,
|
|
3704
3356
|
stopSignal: stopAbortController.signal,
|
|
3705
|
-
trackedMutationEvidenceForCompletionGuard: false,
|
|
3706
3357
|
timeoutMessage,
|
|
3707
3358
|
stopMessage,
|
|
3708
3359
|
toolTimeoutMs: task.toolTimeoutMs ?? config.toolTimeoutMs,
|
|
3709
3360
|
onAttemptStart: (attempt) => updateStepModel(fi, attempt.model, attempt.thinking, attempt.contextLimit),
|
|
3710
3361
|
onChildEvent: (event) => updateStepFromChildEvent(fi, event),
|
|
3711
|
-
onWriterProcess,
|
|
3712
3362
|
onExternalProcess: (process) => updateExternalProcess(fi, process),
|
|
3363
|
+
prepareExternalActivity: (externalCwd, signal) => prepareExternalActivity(fi, externalCwd, signal),
|
|
3364
|
+
onExternalStreamActivity: () => recordExternalStreamActivity(fi),
|
|
3713
3365
|
onExternalJob: (externalJob) => updateExternalJob(fi, externalJob),
|
|
3714
3366
|
skipAcceptance: () => timedOut || stopped || childStopRequests.has(fi),
|
|
3715
|
-
usageBudgetExhausted:
|
|
3367
|
+
usageBudgetExhausted: continuationUsageBudgetExhausted,
|
|
3368
|
+
usageBudget: config.usageBudget,
|
|
3716
3369
|
orcaProgressTab
|
|
3717
3370
|
}), config.deadlineAt);
|
|
3718
3371
|
const taskEndTime = Date.now();
|
|
3719
3372
|
const childInterrupted = singleResult.interrupted === true;
|
|
3720
3373
|
const childStopped = singleResult.stopped === true;
|
|
3721
|
-
requiredStatusStep(statusPayload, fi).status = stopped || childStopped ? "stopped" : timedOut ? "failed" : childInterrupted ? "paused" : singleResult.exitCode === 0 ? "complete" : "failed";
|
|
3374
|
+
requiredStatusStep(statusPayload, fi).status = stopped || childStopped ? "stopped" : timedOut ? "failed" : childInterrupted ? "paused" : singleResult.execution?.status === "partial" ? "partial" : singleResult.exitCode === 0 ? "complete" : "failed";
|
|
3722
3375
|
requiredStatusStep(statusPayload, fi).endedAt = taskEndTime;
|
|
3723
3376
|
requiredStatusStep(statusPayload, fi).durationMs = taskEndTime - taskStartTime;
|
|
3724
3377
|
requiredStatusStep(statusPayload, fi).exitCode = stopped || childStopped ? 1 : timedOut ? 1 : childInterrupted ? 0 : singleResult.exitCode;
|
|
@@ -3733,8 +3386,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3733
3386
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "sessionName", singleResult.sessionName);
|
|
3734
3387
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "model", singleResult.model);
|
|
3735
3388
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "thinking", resolveEffectiveThinking(singleResult.model, requiredStatusStep(statusPayload, fi).thinking));
|
|
3736
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "
|
|
3737
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "modelAttempts", singleResult.modelAttempts);
|
|
3389
|
+
setOptionalProperty(requiredStatusStep(statusPayload, fi), "requestedModel", singleResult.requestedModel);
|
|
3738
3390
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "contextOverflow", singleResult.contextOverflow);
|
|
3739
3391
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "totalCost", singleResult.totalCost);
|
|
3740
3392
|
if (singleResult.totalCost) {
|
|
@@ -3798,8 +3450,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3798
3450
|
output: pr.output,
|
|
3799
3451
|
outputState: pr.outputState,
|
|
3800
3452
|
error: pr.error,
|
|
3801
|
-
|
|
3802
|
-
success: pr.stopped !== true && pr.interrupted !== true && pr.exitCode === 0,
|
|
3453
|
+
success: pr.stopped !== true && pr.interrupted !== true && pr.exitCode === 0 && pr.execution?.status !== "partial",
|
|
3803
3454
|
exitCode: pr.interrupted === true ? 0 : pr.exitCode,
|
|
3804
3455
|
skipped: pr.skipped,
|
|
3805
3456
|
interrupted: pr.interrupted,
|
|
@@ -3810,12 +3461,14 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3810
3461
|
sessionFile: pr.sessionFile,
|
|
3811
3462
|
intercomTarget: pr.intercomTarget,
|
|
3812
3463
|
model: pr.model,
|
|
3813
|
-
|
|
3814
|
-
|
|
3464
|
+
thinking: pr.thinking,
|
|
3465
|
+
requestedModel: pr.requestedModel,
|
|
3815
3466
|
contextOverflow: pr.contextOverflow,
|
|
3816
3467
|
totalCost: pr.totalCost,
|
|
3817
3468
|
usage: pr.usage,
|
|
3818
3469
|
artifactPaths: pr.artifactPaths,
|
|
3470
|
+
outputSaveError: pr.outputSaveError,
|
|
3471
|
+
artifactOutputSaveFailed: pr.artifactOutputSaveFailed,
|
|
3819
3472
|
transcriptPath: pr.transcriptPath,
|
|
3820
3473
|
transcriptError: pr.transcriptError,
|
|
3821
3474
|
effects: pr.effects,
|
|
@@ -3823,6 +3476,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3823
3476
|
review: pr.review,
|
|
3824
3477
|
timeoutRecovery: pr.timeoutRecovery,
|
|
3825
3478
|
structuredOutput: pr.structuredOutput,
|
|
3479
|
+
structuredOutputFailed: pr.structuredOutputFailed,
|
|
3826
3480
|
structuredOutputPath: pr.structuredOutputPath,
|
|
3827
3481
|
structuredOutputSchemaPath: pr.structuredOutputSchemaPath,
|
|
3828
3482
|
acceptance: pr.acceptance,
|
|
@@ -3835,7 +3489,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3835
3489
|
refreshUsageBudget();
|
|
3836
3490
|
const collection = collectDynamicResults(step, materialized.items, parallelResults);
|
|
3837
3491
|
const failures = parallelResults.filter((result) => result.exitCode !== 0 && result.exitCode !== -1);
|
|
3838
|
-
const acceptanceFailures = parallelResults.map((result, originalIndex) => ({ result, originalIndex, task: dynamicSteps[originalIndex] })).filter(({ result, task }) =>
|
|
3492
|
+
const acceptanceFailures = parallelResults.map((result, originalIndex) => ({ result, originalIndex, task: dynamicSteps[originalIndex] })).filter(({ result, task }) => isAgentContract(task?.agentContract ?? step.agentContract) && task?.gateOn === "acceptance" && result.acceptance?.status === "rejected");
|
|
3839
3493
|
if (acceptanceFailures.length > 0) {
|
|
3840
3494
|
const message = acceptanceFailures.map(({ result, originalIndex }) => `Dynamic item ${originalIndex + 1} (${result.agent}, key ${materialized.items[originalIndex]?.key ?? originalIndex}) acceptance rejected: ${(result.acceptance ? acceptanceFailureMessage(result.acceptance) : undefined) ?? "acceptance rejected"}`).join(`
|
|
3841
3495
|
`);
|
|
@@ -3863,12 +3517,12 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3863
3517
|
cwd,
|
|
3864
3518
|
signal: combinedAbortSignal([timeoutAbortController.signal, stopAbortController.signal]),
|
|
3865
3519
|
abortMessage: stopAbortController.signal.aborted ? stopMessage : timeoutMessage ?? "Subagent timed out.",
|
|
3866
|
-
reportOptional:
|
|
3520
|
+
reportOptional: isAgentContract(step.agentContract)
|
|
3867
3521
|
})) : undefined;
|
|
3868
3522
|
const groupStopped = stopped || stopAbortController.signal.aborted;
|
|
3869
3523
|
const groupTimedOut = !groupStopped && (timedOut || timeoutAbortController.signal.aborted);
|
|
3870
3524
|
const effectiveGroupAcceptance = groupTimedOut || groupStopped ? undefined : groupAcceptance;
|
|
3871
|
-
const groupAcceptanceFailure = effectiveDynamicGroupAcceptance.explicit && effectiveGroupAcceptance && (!
|
|
3525
|
+
const groupAcceptanceFailure = effectiveDynamicGroupAcceptance.explicit && effectiveGroupAcceptance && (!isAgentContract(step.agentContract) || step.gateOn === "acceptance") ? acceptanceFailureMessage(effectiveGroupAcceptance) : undefined;
|
|
3872
3526
|
const groupError = groupStopped ? stopMessage : groupTimedOut ? timeoutMessage ?? "Subagent timed out." : groupAcceptanceFailure;
|
|
3873
3527
|
markDynamicGraphGroup(stepIndex, groupError ? groupStopped ? "stopped" : "failed" : "completed", groupError, effectiveGroupAcceptance);
|
|
3874
3528
|
if (groupError) {
|
|
@@ -3945,14 +3599,22 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3945
3599
|
break;
|
|
3946
3600
|
}
|
|
3947
3601
|
try {
|
|
3948
|
-
worktreeSetup = createWorktrees(cwd, `${id}-s${stepIndex}`, group.parallel.length, omitUndefinedProperties({
|
|
3602
|
+
worktreeSetup = await createWorktrees(cwd, `${id}-s${stepIndex}`, group.parallel.length, omitUndefinedProperties({
|
|
3603
|
+
signal: setupSignal,
|
|
3604
|
+
deadlineAt: config.deadlineAt,
|
|
3949
3605
|
agents: group.parallel.map((task) => task.agent),
|
|
3606
|
+
labels: group.parallel.map((task) => task.lane?.key ?? config.workflowKey ?? task.outputName ?? task.label),
|
|
3607
|
+
tasks: group.parallel.map((task) => task.task),
|
|
3608
|
+
provider: config.worktreeProvider,
|
|
3609
|
+
baseRef: config.baseRef,
|
|
3610
|
+
branchPrefix: config.worktreeBranchPrefix,
|
|
3950
3611
|
setupHook: config.worktreeSetupHook ? omitUndefinedProperties({ hookPath: config.worktreeSetupHook, timeoutMs: config.worktreeSetupHookTimeoutMs }) : undefined,
|
|
3951
3612
|
baseDir: config.worktreeBaseDir,
|
|
3952
|
-
|
|
3953
|
-
|
|
3613
|
+
onProgress: (progress) => {
|
|
3614
|
+
publishSetupUnknown(progress);
|
|
3615
|
+
for (const worktree of progress.setup.worktrees)
|
|
3954
3616
|
setStatusWorktreeReference(requiredStatusStep(statusPayload, groupStartFlatIndex + worktree.index), worktree);
|
|
3955
|
-
const pendingHandoff =
|
|
3617
|
+
const pendingHandoff = writeWorktreeSetupHandoff({
|
|
3956
3618
|
manifestPath: parallelHandoffPath(asyncDir),
|
|
3957
3619
|
runId: id,
|
|
3958
3620
|
mode: (config.resultMode ?? statusPayload.mode) === "parallel" ? "parallel" : "chain",
|
|
@@ -3960,16 +3622,32 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
3960
3622
|
cwd,
|
|
3961
3623
|
stepIndex,
|
|
3962
3624
|
flatStartIndex: groupStartFlatIndex,
|
|
3963
|
-
|
|
3625
|
+
progress,
|
|
3964
3626
|
laneBindings: handoffWorkflowKey || config.lane ? [{ index: groupStartFlatIndex, taskIndex: 0, ...handoffWorkflowKey ? { workflowKey: handoffWorkflowKey } : {}, ...handoffChildRunId ? { runId: handoffChildRunId } : {}, ...config.lane ? { lane: config.lane } : {} }] : undefined
|
|
3965
3627
|
});
|
|
3628
|
+
if (!pendingHandoff)
|
|
3629
|
+
return;
|
|
3966
3630
|
statusPayload.parallelHandoff = pendingHandoff;
|
|
3967
3631
|
statusPayload.lastUpdate = Date.now();
|
|
3968
3632
|
writeStatusPayload();
|
|
3969
3633
|
}
|
|
3970
3634
|
}));
|
|
3635
|
+
if (config.deadlineAt !== undefined && Date.now() >= config.deadlineAt)
|
|
3636
|
+
timeoutRunner();
|
|
3637
|
+
if (setupSignal.aborted)
|
|
3638
|
+
throw new Error(stopped ? stopMessage : timedOut ? timeoutMessage ?? "Subagent timed out." : "Subagent paused during worktree setup.");
|
|
3971
3639
|
} catch (error) {
|
|
3640
|
+
if (worktreeSetup)
|
|
3641
|
+
await cleanupRemainingWorktree(worktreeSetup, stepIndex, groupStartFlatIndex);
|
|
3642
|
+
if (config.deadlineAt !== undefined && Date.now() >= config.deadlineAt)
|
|
3643
|
+
timeoutRunner();
|
|
3972
3644
|
const setupError = error instanceof Error ? error.message : String(error);
|
|
3645
|
+
if (error instanceof WorktreeSetupError)
|
|
3646
|
+
publishSetupUnknown(error.snapshot);
|
|
3647
|
+
for (let index = groupStartFlatIndex;index < groupStartFlatIndex + group.parallel.length; index++) {
|
|
3648
|
+
if (childStopRequests.has(index))
|
|
3649
|
+
markChildStopped(index);
|
|
3650
|
+
}
|
|
3973
3651
|
const failedAt = Date.now();
|
|
3974
3652
|
markParallelGroupSetupFailure({
|
|
3975
3653
|
statusPayload,
|
|
@@ -4099,11 +3777,9 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4099
3777
|
flatIndex: fi,
|
|
4100
3778
|
flatStepCount: Math.max(statusPayload.steps.length, 1),
|
|
4101
3779
|
outputFile: path.join(asyncDir, `output-${fi}.log`),
|
|
4102
|
-
steerInboxDir: stepSteerInboxDir(asyncDir, fi),
|
|
4103
|
-
steerCapabilityPath: steerCapabilityPath(asyncDir, fi),
|
|
4104
|
-
steerAckDir: steerAcksDir(asyncDir, fi),
|
|
4105
3780
|
piPackageRoot: config.piPackageRoot,
|
|
4106
|
-
|
|
3781
|
+
childSessions,
|
|
3782
|
+
inheritedChildRuntime: config.inheritedChildRuntime,
|
|
4107
3783
|
childIntercomTarget: config.childIntercomTargets?.[fi],
|
|
4108
3784
|
orchestratorIntercomTarget: config.controlIntercomTarget,
|
|
4109
3785
|
nestedRoute: config.nestedRoute,
|
|
@@ -4112,19 +3788,22 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4112
3788
|
registerInterrupt: (interrupt) => registerStepInterrupt(fi, interrupt),
|
|
4113
3789
|
registerTimeout: (interrupt) => registerStepTimeout(fi, interrupt),
|
|
4114
3790
|
registerStop: (stop) => registerStepStop(fi, stop),
|
|
3791
|
+
registerSteer: (steer) => registerStepSteer(fi, steer),
|
|
3792
|
+
onSteerOutcome: (request, delivery) => applySteerDelivery(request.id, fi, delivery),
|
|
4115
3793
|
timeoutSignal: timeoutAbortController.signal,
|
|
4116
3794
|
stopSignal: stopAbortController.signal,
|
|
4117
|
-
trackedMutationEvidenceForCompletionGuard: Boolean(worktreeSetup),
|
|
4118
3795
|
timeoutMessage,
|
|
4119
3796
|
stopMessage,
|
|
4120
3797
|
toolTimeoutMs: taskForRun.toolTimeoutMs ?? config.toolTimeoutMs,
|
|
4121
3798
|
onAttemptStart: (attempt) => updateStepModel(fi, attempt.model, attempt.thinking, attempt.contextLimit),
|
|
4122
3799
|
onChildEvent: (event) => updateStepFromChildEvent(fi, event),
|
|
4123
|
-
onWriterProcess,
|
|
4124
3800
|
onExternalProcess: (process) => updateExternalProcess(fi, process),
|
|
3801
|
+
prepareExternalActivity: (externalCwd, signal) => prepareExternalActivity(fi, externalCwd, signal),
|
|
3802
|
+
onExternalStreamActivity: () => recordExternalStreamActivity(fi),
|
|
4125
3803
|
onExternalJob: (externalJob) => updateExternalJob(fi, externalJob),
|
|
4126
3804
|
skipAcceptance: () => timedOut || stopped || childStopRequests.has(fi),
|
|
4127
|
-
usageBudgetExhausted:
|
|
3805
|
+
usageBudgetExhausted: continuationUsageBudgetExhausted,
|
|
3806
|
+
usageBudget: config.usageBudget,
|
|
4128
3807
|
orcaProgressTab
|
|
4129
3808
|
}), config.deadlineAt);
|
|
4130
3809
|
if (task.sessionFile) {
|
|
@@ -4134,7 +3813,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4134
3813
|
const taskDuration = taskEndTime - taskStartTime;
|
|
4135
3814
|
const childInterrupted = singleResult.interrupted === true;
|
|
4136
3815
|
const childStopped = singleResult.stopped === true;
|
|
4137
|
-
requiredStatusStep(statusPayload, fi).status = stopped || childStopped ? "stopped" : timedOut ? "failed" : childInterrupted ? "paused" : singleResult.exitCode === 0 ? "complete" : "failed";
|
|
3816
|
+
requiredStatusStep(statusPayload, fi).status = stopped || childStopped ? "stopped" : timedOut ? "failed" : childInterrupted ? "paused" : singleResult.execution?.status === "partial" ? "partial" : singleResult.exitCode === 0 ? "complete" : "failed";
|
|
4138
3817
|
requiredStatusStep(statusPayload, fi).endedAt = taskEndTime;
|
|
4139
3818
|
requiredStatusStep(statusPayload, fi).durationMs = taskDuration;
|
|
4140
3819
|
requiredStatusStep(statusPayload, fi).exitCode = stopped || childStopped ? 1 : timedOut ? 1 : childInterrupted ? 0 : singleResult.exitCode;
|
|
@@ -4149,8 +3828,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4149
3828
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "sessionName", singleResult.sessionName);
|
|
4150
3829
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "model", singleResult.model);
|
|
4151
3830
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "thinking", resolveEffectiveThinking(singleResult.model, requiredStatusStep(statusPayload, fi).thinking));
|
|
4152
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "
|
|
4153
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "modelAttempts", singleResult.modelAttempts);
|
|
3831
|
+
setOptionalProperty(requiredStatusStep(statusPayload, fi), "requestedModel", singleResult.requestedModel);
|
|
4154
3832
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "contextOverflow", singleResult.contextOverflow);
|
|
4155
3833
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "totalCost", singleResult.totalCost);
|
|
4156
3834
|
if (singleResult.totalCost) {
|
|
@@ -4196,19 +3874,6 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4196
3874
|
}));
|
|
4197
3875
|
if (stopped || childStopped)
|
|
4198
3876
|
appendTerminalChildStatusEvent(fi, taskEndTime);
|
|
4199
|
-
if (singleResult.completionGuardTriggered) {
|
|
4200
|
-
const event = buildControlEvent(omitUndefinedProperties({
|
|
4201
|
-
from: requiredStatusStep(statusPayload, fi).activityState,
|
|
4202
|
-
to: "needs_attention",
|
|
4203
|
-
runId: id,
|
|
4204
|
-
agent: task.agent,
|
|
4205
|
-
index: fi,
|
|
4206
|
-
ts: taskEndTime,
|
|
4207
|
-
message: `${task.agent} completed without making edits for an implementation task`,
|
|
4208
|
-
reason: "completion_guard"
|
|
4209
|
-
}));
|
|
4210
|
-
appendControlEvent(event);
|
|
4211
|
-
}
|
|
4212
3877
|
if (singleResult.exitCode !== 0 && failFast && !childStopped)
|
|
4213
3878
|
aborted = true;
|
|
4214
3879
|
return stopped || childStopped ? { ...singleResult, output: stopMessage, error: stopMessage, exitCode: 1, interrupted: false, timedOut: false, stopped: true, skipped: false } : timedOut ? { ...singleResult, output: singleResult.output || (timeoutMessage ?? "Subagent timed out."), error: singleResult.error ?? timeoutMessage ?? "Subagent timed out.", exitCode: 1, interrupted: false, timedOut: true, skipped: false } : { ...singleResult, skipped: false };
|
|
@@ -4217,7 +3882,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4217
3882
|
for (let t = 0;t < group.parallel.length; t++) {
|
|
4218
3883
|
const fi = groupStartFlatIndex + t;
|
|
4219
3884
|
const sessionTokens = config.sessionDir ? parseSessionTokens(path.join(config.sessionDir, `parallel-${t}`)) : null;
|
|
4220
|
-
const fallbackTokens =
|
|
3885
|
+
const fallbackTokens = tokenUsageFromUsage(parallelResults[t]?.usage);
|
|
4221
3886
|
const observedTokens = requiredStatusStep(statusPayload, fi).tokens;
|
|
4222
3887
|
const taskTokens = sessionTokens ?? (fallbackTokens ? { ...fallbackTokens, ...observedTokens?.window !== undefined ? { window: observedTokens.window } : {}, ...observedTokens?.windowPeak !== undefined ? { windowPeak: observedTokens.windowPeak } : {} } : null);
|
|
4223
3888
|
if (!taskTokens)
|
|
@@ -4244,8 +3909,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4244
3909
|
output: pr.output,
|
|
4245
3910
|
outputState: pr.outputState,
|
|
4246
3911
|
error: pr.error,
|
|
4247
|
-
|
|
4248
|
-
success: pr.stopped !== true && pr.interrupted !== true && pr.exitCode === 0,
|
|
3912
|
+
success: pr.stopped !== true && pr.interrupted !== true && pr.exitCode === 0 && pr.execution?.status !== "partial",
|
|
4249
3913
|
exitCode: pr.interrupted === true ? 0 : pr.exitCode,
|
|
4250
3914
|
skipped: pr.skipped,
|
|
4251
3915
|
interrupted: pr.interrupted,
|
|
@@ -4256,12 +3920,14 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4256
3920
|
sessionFile: pr.sessionFile,
|
|
4257
3921
|
intercomTarget: pr.intercomTarget,
|
|
4258
3922
|
model: pr.model,
|
|
4259
|
-
|
|
4260
|
-
|
|
3923
|
+
thinking: pr.thinking,
|
|
3924
|
+
requestedModel: pr.requestedModel,
|
|
4261
3925
|
contextOverflow: pr.contextOverflow,
|
|
4262
3926
|
totalCost: pr.totalCost,
|
|
4263
3927
|
usage: pr.usage,
|
|
4264
3928
|
artifactPaths: pr.artifactPaths,
|
|
3929
|
+
outputSaveError: pr.outputSaveError,
|
|
3930
|
+
artifactOutputSaveFailed: pr.artifactOutputSaveFailed,
|
|
4265
3931
|
transcriptPath: pr.transcriptPath,
|
|
4266
3932
|
transcriptError: pr.transcriptError,
|
|
4267
3933
|
effects: pr.effects,
|
|
@@ -4269,6 +3935,7 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4269
3935
|
review: pr.review,
|
|
4270
3936
|
timeoutRecovery: pr.timeoutRecovery,
|
|
4271
3937
|
structuredOutput: pr.structuredOutput,
|
|
3938
|
+
structuredOutputFailed: pr.structuredOutputFailed,
|
|
4272
3939
|
structuredOutputPath: pr.structuredOutputPath,
|
|
4273
3940
|
structuredOutputSchemaPath: pr.structuredOutputSchemaPath,
|
|
4274
3941
|
acceptance: pr.acceptance,
|
|
@@ -4293,66 +3960,69 @@ async function runSubagent(config, onWriterProcess) {
|
|
|
4293
3960
|
exitCode: r.exitCode,
|
|
4294
3961
|
error: r.error,
|
|
4295
3962
|
model: r.model,
|
|
4296
|
-
|
|
3963
|
+
requestedModel: r.requestedModel
|
|
4297
3964
|
})));
|
|
4298
3965
|
if (worktreeSetup) {
|
|
4299
|
-
const
|
|
4300
|
-
|
|
4301
|
-
|
|
3966
|
+
const setup = worktreeSetup;
|
|
3967
|
+
worktreeFinalized = true;
|
|
3968
|
+
await finalizeWorktree(setup, stepIndex, groupStartFlatIndex, () => {
|
|
3969
|
+
const captured = captureParallelWorktreeDiffs(setup, asyncDir, stepIndex, group);
|
|
3970
|
+
if (captured.summary)
|
|
3971
|
+
previousOutput = `${previousOutput}
|
|
4302
3972
|
|
|
4303
3973
|
${captured.summary}`;
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
stopped: result.
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
}
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
previousOutput = `${previousOutput}
|
|
3974
|
+
const manifestPath = parallelHandoffPath(asyncDir);
|
|
3975
|
+
const handoff = {
|
|
3976
|
+
manifestPath,
|
|
3977
|
+
runId: id,
|
|
3978
|
+
mode: (config.resultMode ?? statusPayload.mode) === "parallel" ? "parallel" : "chain",
|
|
3979
|
+
source: "async",
|
|
3980
|
+
cwd,
|
|
3981
|
+
stepIndex,
|
|
3982
|
+
flatStartIndex: groupStartFlatIndex,
|
|
3983
|
+
setup,
|
|
3984
|
+
diffs: captured.diffs,
|
|
3985
|
+
results: parallelResults.map((result) => ({
|
|
3986
|
+
agent: result.agent,
|
|
3987
|
+
...handoffWorkflowKey ? { workflowKey: handoffWorkflowKey } : {},
|
|
3988
|
+
...handoffChildRunId ? { runId: handoffChildRunId } : {},
|
|
3989
|
+
...config.lane ? { lane: config.lane } : {},
|
|
3990
|
+
status: result.stopped || result.exitCode !== 0 && isUnexplainedProcessSignal(omitUndefinedProperties({
|
|
3991
|
+
processSignal: result.processSignal,
|
|
3992
|
+
interrupted: result.interrupted,
|
|
3993
|
+
timedOut: result.timedOut,
|
|
3994
|
+
stopped: result.stopped
|
|
3995
|
+
})) ? "stopped" : result.interrupted ? "paused" : result.exitCode === 0 ? "completed" : "failed",
|
|
3996
|
+
summary: result.output || result.error || "(no output)",
|
|
3997
|
+
...result.artifactPaths?.outputPath ? { outputPath: result.artifactPaths.outputPath } : {},
|
|
3998
|
+
...result.structuredOutput !== undefined ? { structuredOutput: result.structuredOutput } : {},
|
|
3999
|
+
...result.structuredOutputPath ? { structuredOutputPath: result.structuredOutputPath } : {},
|
|
4000
|
+
...result.sessionFile ? { sessionPath: result.sessionFile } : {}
|
|
4001
|
+
}))
|
|
4002
|
+
};
|
|
4003
|
+
try {
|
|
4004
|
+
writeParallelHandoffGroup(handoff);
|
|
4005
|
+
const cleanup = cleanupWorktrees(setup, { kind: "preserve", capturedDiffs: captured.diffs, handoffManifestPath: manifestPath });
|
|
4006
|
+
statusPayload.parallelHandoff = writeParallelHandoffGroup({ ...handoff, cleanup });
|
|
4007
|
+
previousOutput = `${previousOutput}
|
|
4339
4008
|
|
|
4340
4009
|
${formatParallelHandoffReference(statusPayload.parallelHandoff)}`;
|
|
4341
|
-
|
|
4342
|
-
|
|
4010
|
+
} catch (error) {
|
|
4011
|
+
previousOutput = `${previousOutput}
|
|
4343
4012
|
|
|
4344
4013
|
${formatParallelHandoffError(error)}`;
|
|
4345
|
-
|
|
4346
|
-
|
|
4014
|
+
}
|
|
4015
|
+
writeStatusPayload();
|
|
4016
|
+
});
|
|
4347
4017
|
}
|
|
4348
4018
|
appendJsonl(eventsPath, JSON.stringify({
|
|
4349
4019
|
type: "subagent.parallel.completed",
|
|
4350
4020
|
ts: Date.now(),
|
|
4351
4021
|
runId: id,
|
|
4352
4022
|
stepIndex,
|
|
4353
|
-
success: parallelResults.every((r) => r.exitCode === 0 || r.exitCode === -1) && parallelResults.every((result, index) => !(
|
|
4023
|
+
success: parallelResults.every((r) => r.exitCode === 0 || r.exitCode === -1) && parallelResults.every((result, index) => !(isAgentContract(group.parallel[index]?.agentContract) && group.parallel[index]?.gateOn === "acceptance" && result.acceptance?.status === "rejected"))
|
|
4354
4024
|
}));
|
|
4355
|
-
const acceptanceGateFailure = parallelResults.map((result, index) => ({ result, index, task: group.parallel[index] })).find(({ result, task }) =>
|
|
4025
|
+
const acceptanceGateFailure = parallelResults.map((result, index) => ({ result, index, task: group.parallel[index] })).find(({ result, task }) => isAgentContract(task?.agentContract) && task?.gateOn === "acceptance" && result.acceptance?.status === "rejected");
|
|
4356
4026
|
if (acceptanceGateFailure) {
|
|
4357
4027
|
statusPayload.error = (acceptanceGateFailure.result.acceptance ? acceptanceFailureMessage(acceptanceGateFailure.result.acceptance) : undefined) ?? "Parallel acceptance gate rejected the step.";
|
|
4358
4028
|
writeStatusPayload();
|
|
@@ -4363,7 +4033,7 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4363
4033
|
}
|
|
4364
4034
|
} finally {
|
|
4365
4035
|
if (worktreeSetup && !worktreeFinalized)
|
|
4366
|
-
|
|
4036
|
+
await cleanupRemainingWorktree(worktreeSetup, stepIndex, groupStartFlatIndex);
|
|
4367
4037
|
}
|
|
4368
4038
|
} else {
|
|
4369
4039
|
const seqStep = step;
|
|
@@ -4390,16 +4060,24 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4390
4060
|
let singleWorktreeSetup;
|
|
4391
4061
|
if (seqStep.worktree) {
|
|
4392
4062
|
try {
|
|
4393
|
-
singleWorktreeSetup = createWorktrees(cwd, `${id}-s${stepIndex}`, 1, omitUndefinedProperties({
|
|
4063
|
+
singleWorktreeSetup = await createWorktrees(cwd, `${id}-s${stepIndex}`, 1, omitUndefinedProperties({
|
|
4064
|
+
signal: setupSignal,
|
|
4065
|
+
deadlineAt: config.deadlineAt,
|
|
4394
4066
|
agents: [seqStep.agent],
|
|
4067
|
+
labels: [seqStep.lane?.key ?? config.workflowKey ?? seqStep.outputName ?? seqStep.label],
|
|
4068
|
+
tasks: [seqStep.task],
|
|
4069
|
+
provider: config.worktreeProvider,
|
|
4070
|
+
baseRef: config.baseRef,
|
|
4071
|
+
branchPrefix: config.worktreeBranchPrefix,
|
|
4395
4072
|
setupHook: config.worktreeSetupHook ? omitUndefinedProperties({ hookPath: config.worktreeSetupHook, timeoutMs: config.worktreeSetupHookTimeoutMs }) : undefined,
|
|
4396
4073
|
baseDir: config.worktreeBaseDir,
|
|
4397
|
-
|
|
4398
|
-
|
|
4074
|
+
onProgress: (progress) => {
|
|
4075
|
+
publishSetupUnknown(progress);
|
|
4076
|
+
const worktree = progress.setup.worktrees[0];
|
|
4399
4077
|
if (worktree) {
|
|
4400
4078
|
setStatusWorktreeReference(requiredStatusStep(statusPayload, flatIndex), worktree);
|
|
4401
4079
|
}
|
|
4402
|
-
const pendingHandoff =
|
|
4080
|
+
const pendingHandoff = writeWorktreeSetupHandoff({
|
|
4403
4081
|
manifestPath: parallelHandoffPath(asyncDir),
|
|
4404
4082
|
runId: id,
|
|
4405
4083
|
mode: "single",
|
|
@@ -4407,20 +4085,46 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4407
4085
|
cwd,
|
|
4408
4086
|
stepIndex,
|
|
4409
4087
|
flatStartIndex: flatIndex,
|
|
4410
|
-
|
|
4088
|
+
progress,
|
|
4411
4089
|
laneBindings: handoffWorkflowKey || config.lane ? [{ index: flatIndex, taskIndex: 0, ...handoffWorkflowKey ? { workflowKey: handoffWorkflowKey } : {}, ...handoffChildRunId ? { runId: handoffChildRunId } : {}, ...config.lane ? { lane: config.lane } : {} }] : undefined
|
|
4412
4090
|
});
|
|
4091
|
+
if (!pendingHandoff)
|
|
4092
|
+
return;
|
|
4413
4093
|
statusPayload.parallelHandoff = pendingHandoff;
|
|
4414
4094
|
statusPayload.lastUpdate = Date.now();
|
|
4415
4095
|
writeStatusPayload();
|
|
4416
4096
|
}
|
|
4417
4097
|
}));
|
|
4418
4098
|
} catch (error) {
|
|
4419
|
-
if (
|
|
4420
|
-
|
|
4421
|
-
|
|
4099
|
+
if (error instanceof WorktreeSetupError)
|
|
4100
|
+
publishSetupUnknown(error.snapshot);
|
|
4101
|
+
if (config.deadlineAt !== undefined && Date.now() >= config.deadlineAt)
|
|
4102
|
+
timeoutRunner();
|
|
4103
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4104
|
+
if (childStopRequests.has(flatIndex))
|
|
4105
|
+
markChildStopped(flatIndex);
|
|
4106
|
+
const statusStep = requiredStatusStep(statusPayload, flatIndex);
|
|
4107
|
+
statusStep.status = stopped || childStopRequests.has(flatIndex) ? "stopped" : interrupted ? "paused" : "failed";
|
|
4108
|
+
statusStep.error ??= message;
|
|
4109
|
+
statusStep.exitCode = interrupted ? 0 : 1;
|
|
4110
|
+
statusStep.endedAt = Date.now();
|
|
4111
|
+
results.push(stopped ? stoppedStepResult(seqStep.agent, seqStep.context, seqStep.sessionName) : childStopRequests.has(flatIndex) ? childStopResult(flatIndex, seqStep.agent, seqStep.context) : timedOut ? timedOutStepResult(seqStep.agent, seqStep.context, seqStep.sessionName) : interrupted ? pausedStepResult(seqStep.agent, seqStep.context, seqStep.sessionName) : { agent: seqStep.agent, output: message, error: message, exitCode: 1, success: false });
|
|
4112
|
+
statusPayload.error ??= message;
|
|
4113
|
+
writeStatusPayload();
|
|
4114
|
+
flatIndex++;
|
|
4115
|
+
break;
|
|
4422
4116
|
}
|
|
4423
4117
|
}
|
|
4118
|
+
if (singleWorktreeSetup && config.deadlineAt !== undefined && Date.now() >= config.deadlineAt)
|
|
4119
|
+
timeoutRunner();
|
|
4120
|
+
if (singleWorktreeSetup && (timedOut || stopped || interrupted || childStopRequests.has(flatIndex))) {
|
|
4121
|
+
await cleanupRemainingWorktree(singleWorktreeSetup, stepIndex, flatIndex);
|
|
4122
|
+
results.push(stopped ? stoppedStepResult(seqStep.agent, seqStep.context, seqStep.sessionName) : childStopRequests.has(flatIndex) ? childStopResult(flatIndex, seqStep.agent, seqStep.context) : timedOut ? timedOutStepResult(seqStep.agent, seqStep.context, seqStep.sessionName) : pausedStepResult(seqStep.agent, seqStep.context, seqStep.sessionName));
|
|
4123
|
+
if (interrupted)
|
|
4124
|
+
requiredStatusStep(statusPayload, flatIndex).status = "paused";
|
|
4125
|
+
flatIndex++;
|
|
4126
|
+
continue;
|
|
4127
|
+
}
|
|
4424
4128
|
const singleCwd = singleWorktreeSetup?.worktrees[0]?.agentCwd ?? cwd;
|
|
4425
4129
|
const stepStartTime = Date.now();
|
|
4426
4130
|
statusPayload.currentStep = flatIndex;
|
|
@@ -4443,7 +4147,7 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4443
4147
|
agent: seqStep.agent
|
|
4444
4148
|
}));
|
|
4445
4149
|
flushPendingStepSteers(flatIndex);
|
|
4446
|
-
const executionStep = singleWorktreeSetup ? { ...seqStep, cwd: singleCwd } : seqStep;
|
|
4150
|
+
const executionStep = singleWorktreeSetup ? bindWorktreeCwd({ ...seqStep, cwd: singleCwd }, singleCwd) : seqStep;
|
|
4447
4151
|
let singleResult;
|
|
4448
4152
|
try {
|
|
4449
4153
|
singleResult = await runSingleStepWithTimeout(executionStep, compactOptional({
|
|
@@ -4459,11 +4163,9 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4459
4163
|
flatIndex,
|
|
4460
4164
|
flatStepCount: Math.max(statusPayload.steps.length, 1),
|
|
4461
4165
|
outputFile: path.join(asyncDir, `output-${flatIndex}.log`),
|
|
4462
|
-
steerInboxDir: stepSteerInboxDir(asyncDir, flatIndex),
|
|
4463
|
-
steerCapabilityPath: steerCapabilityPath(asyncDir, flatIndex),
|
|
4464
|
-
steerAckDir: steerAcksDir(asyncDir, flatIndex),
|
|
4465
4166
|
piPackageRoot: config.piPackageRoot,
|
|
4466
|
-
|
|
4167
|
+
childSessions,
|
|
4168
|
+
inheritedChildRuntime: config.inheritedChildRuntime,
|
|
4467
4169
|
childIntercomTarget: config.childIntercomTargets?.[flatIndex],
|
|
4468
4170
|
orchestratorIntercomTarget: config.controlIntercomTarget,
|
|
4469
4171
|
nestedRoute: config.nestedRoute,
|
|
@@ -4472,6 +4174,8 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4472
4174
|
registerInterrupt: (interrupt) => registerStepInterrupt(flatIndex, interrupt),
|
|
4473
4175
|
registerTimeout: (interrupt) => registerStepTimeout(flatIndex, interrupt),
|
|
4474
4176
|
registerStop: (stop) => registerStepStop(flatIndex, stop),
|
|
4177
|
+
registerSteer: (steer) => registerStepSteer(flatIndex, steer),
|
|
4178
|
+
onSteerOutcome: (request, delivery) => applySteerDelivery(request.id, flatIndex, delivery),
|
|
4475
4179
|
timeoutSignal: timeoutAbortController.signal,
|
|
4476
4180
|
stopSignal: stopAbortController.signal,
|
|
4477
4181
|
timeoutMessage,
|
|
@@ -4479,16 +4183,18 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4479
4183
|
toolTimeoutMs: seqStep.toolTimeoutMs ?? config.toolTimeoutMs,
|
|
4480
4184
|
onAttemptStart: (attempt) => updateStepModel(flatIndex, attempt.model, attempt.thinking, attempt.contextLimit),
|
|
4481
4185
|
onChildEvent: (event) => updateStepFromChildEvent(flatIndex, event),
|
|
4482
|
-
onWriterProcess,
|
|
4483
4186
|
onExternalProcess: (process) => updateExternalProcess(flatIndex, process),
|
|
4187
|
+
prepareExternalActivity: (externalCwd, signal) => prepareExternalActivity(flatIndex, externalCwd, signal),
|
|
4188
|
+
onExternalStreamActivity: () => recordExternalStreamActivity(flatIndex),
|
|
4484
4189
|
onExternalJob: (externalJob) => updateExternalJob(flatIndex, externalJob),
|
|
4485
4190
|
skipAcceptance: () => timedOut || stopped || childStopRequests.has(flatIndex),
|
|
4486
|
-
usageBudgetExhausted:
|
|
4191
|
+
usageBudgetExhausted: continuationUsageBudgetExhausted,
|
|
4192
|
+
usageBudget: config.usageBudget,
|
|
4487
4193
|
orcaProgressTab
|
|
4488
4194
|
}), config.deadlineAt);
|
|
4489
4195
|
} catch (error) {
|
|
4490
4196
|
if (singleWorktreeSetup)
|
|
4491
|
-
|
|
4197
|
+
await cleanupRemainingWorktree(singleWorktreeSetup, stepIndex, flatIndex);
|
|
4492
4198
|
throw error;
|
|
4493
4199
|
}
|
|
4494
4200
|
if (seqStep.sessionFile) {
|
|
@@ -4507,18 +4213,20 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4507
4213
|
output: stopped || childStopped ? stopMessage : timedOut ? singleResult.output || (timeoutMessage ?? "Subagent timed out.") : singleResult.output,
|
|
4508
4214
|
outputState: singleResult.outputState,
|
|
4509
4215
|
error: stopped || childStopped ? stopMessage : timedOut ? timeoutMessage ?? "Subagent timed out." : singleResult.error,
|
|
4510
|
-
|
|
4511
|
-
success: !stopped && !childStopped && !timedOut && singleResult.interrupted !== true && singleResult.exitCode === 0,
|
|
4216
|
+
success: !stopped && !childStopped && !timedOut && singleResult.interrupted !== true && singleResult.exitCode === 0 && singleResult.execution?.status !== "partial",
|
|
4512
4217
|
exitCode: stopped || childStopped ? 1 : timedOut ? 1 : singleResult.interrupted === true ? 0 : singleResult.exitCode,
|
|
4513
4218
|
sessionFile: singleResult.sessionFile,
|
|
4514
4219
|
intercomTarget: singleResult.intercomTarget,
|
|
4515
4220
|
model: singleResult.model,
|
|
4516
|
-
|
|
4517
|
-
|
|
4221
|
+
thinking: singleResult.thinking,
|
|
4222
|
+
requestedModel: singleResult.requestedModel,
|
|
4518
4223
|
contextOverflow: singleResult.contextOverflow,
|
|
4519
4224
|
totalCost: singleResult.totalCost,
|
|
4520
4225
|
usage: singleResult.usage,
|
|
4521
4226
|
artifactPaths: singleResult.artifactPaths,
|
|
4227
|
+
savedOutputPath: singleResult.savedOutputPath,
|
|
4228
|
+
outputSaveError: singleResult.outputSaveError,
|
|
4229
|
+
artifactOutputSaveFailed: singleResult.artifactOutputSaveFailed,
|
|
4522
4230
|
transcriptPath: singleResult.transcriptPath,
|
|
4523
4231
|
transcriptError: singleResult.transcriptError,
|
|
4524
4232
|
effects: singleResult.effects,
|
|
@@ -4526,6 +4234,7 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4526
4234
|
review: singleResult.review,
|
|
4527
4235
|
timeoutRecovery: singleResult.timeoutRecovery,
|
|
4528
4236
|
structuredOutput: singleResult.structuredOutput,
|
|
4237
|
+
structuredOutputFailed: singleResult.structuredOutputFailed,
|
|
4529
4238
|
structuredOutputPath: singleResult.structuredOutputPath,
|
|
4530
4239
|
structuredOutputSchemaPath: singleResult.structuredOutputSchemaPath,
|
|
4531
4240
|
acceptance: singleResult.acceptance,
|
|
@@ -4560,7 +4269,7 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4560
4269
|
if (cumulativeTokens) {
|
|
4561
4270
|
previousCumulativeTokens = cumulativeTokens;
|
|
4562
4271
|
} else {
|
|
4563
|
-
const fallbackTokens =
|
|
4272
|
+
const fallbackTokens = tokenUsageFromUsage(singleResult.usage);
|
|
4564
4273
|
const observedTokens = requiredStatusStep(statusPayload, flatIndex).tokens;
|
|
4565
4274
|
stepTokens = fallbackTokens ? { ...fallbackTokens, ...observedTokens?.window !== undefined ? { window: observedTokens.window } : {}, ...observedTokens?.windowPeak !== undefined ? { windowPeak: observedTokens.windowPeak } : {} } : null;
|
|
4566
4275
|
if (stepTokens) {
|
|
@@ -4575,7 +4284,7 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4575
4284
|
}
|
|
4576
4285
|
const stepEndTime = Date.now();
|
|
4577
4286
|
const childInterrupted = singleResult.interrupted === true;
|
|
4578
|
-
requiredStatusStep(statusPayload, flatIndex).status = stopped || childStopped ? "stopped" : timedOut ? "failed" : childInterrupted ? "paused" : singleResult.exitCode === 0 ? "complete" : "failed";
|
|
4287
|
+
requiredStatusStep(statusPayload, flatIndex).status = stopped || childStopped ? "stopped" : timedOut ? "failed" : childInterrupted ? "paused" : singleResult.execution?.status === "partial" ? "partial" : singleResult.exitCode === 0 ? "complete" : "failed";
|
|
4579
4288
|
requiredStatusStep(statusPayload, flatIndex).endedAt = stepEndTime;
|
|
4580
4289
|
requiredStatusStep(statusPayload, flatIndex).durationMs = stepEndTime - stepStartTime;
|
|
4581
4290
|
requiredStatusStep(statusPayload, flatIndex).exitCode = stopped || childStopped ? 1 : timedOut ? 1 : childInterrupted ? 0 : singleResult.exitCode;
|
|
@@ -4590,8 +4299,7 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4590
4299
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "sessionName", singleResult.sessionName);
|
|
4591
4300
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "model", singleResult.model);
|
|
4592
4301
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "thinking", resolveEffectiveThinking(singleResult.model, requiredStatusStep(statusPayload, flatIndex).thinking));
|
|
4593
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "
|
|
4594
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "modelAttempts", singleResult.modelAttempts);
|
|
4302
|
+
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "requestedModel", singleResult.requestedModel);
|
|
4595
4303
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "contextOverflow", singleResult.contextOverflow);
|
|
4596
4304
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "totalCost", singleResult.totalCost);
|
|
4597
4305
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "error", stopped || childStopped ? stopMessage : timedOut ? timeoutMessage ?? "Subagent timed out." : singleResult.error);
|
|
@@ -4635,66 +4343,56 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4635
4343
|
if (stopped || childStopped)
|
|
4636
4344
|
appendTerminalChildStatusEvent(flatIndex, stepEndTime);
|
|
4637
4345
|
if (singleWorktreeSetup && !singleResult.detached) {
|
|
4638
|
-
const
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
manifestPath
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4346
|
+
const setup = singleWorktreeSetup;
|
|
4347
|
+
await finalizeWorktree(setup, stepIndex, flatIndex, () => {
|
|
4348
|
+
const diffs = diffWorktrees(setup, [seqStep.agent], path.join(asyncDir, "worktree-diffs", `step-${stepIndex}`));
|
|
4349
|
+
const diffSummary = formatWorktreeDiffSummary(diffs);
|
|
4350
|
+
const manifestPath = parallelHandoffPath(asyncDir);
|
|
4351
|
+
const handoff = {
|
|
4352
|
+
manifestPath,
|
|
4353
|
+
runId: id,
|
|
4354
|
+
mode: "single",
|
|
4355
|
+
source: "async",
|
|
4356
|
+
cwd,
|
|
4357
|
+
stepIndex,
|
|
4358
|
+
flatStartIndex: flatIndex,
|
|
4359
|
+
setup,
|
|
4360
|
+
diffs,
|
|
4361
|
+
results: [{
|
|
4362
|
+
agent: singleResult.agent,
|
|
4363
|
+
...handoffWorkflowKey ? { workflowKey: handoffWorkflowKey } : {},
|
|
4364
|
+
...handoffChildRunId ? { runId: handoffChildRunId } : {},
|
|
4365
|
+
...config.lane ? { lane: config.lane } : {},
|
|
4366
|
+
status: singleResult.stopped ? "stopped" : singleResult.interrupted ? "paused" : singleResult.exitCode === 0 ? "completed" : "failed",
|
|
4367
|
+
summary: singleResult.output || singleResult.error || "(no output)",
|
|
4368
|
+
...singleResult.artifactPaths?.outputPath ? { outputPath: singleResult.artifactPaths.outputPath } : {},
|
|
4369
|
+
...singleResult.structuredOutput !== undefined ? { structuredOutput: singleResult.structuredOutput } : {},
|
|
4370
|
+
...singleResult.structuredOutputPath ? { structuredOutputPath: singleResult.structuredOutputPath } : {},
|
|
4371
|
+
...singleResult.sessionFile ? { sessionPath: singleResult.sessionFile } : {}
|
|
4372
|
+
}]
|
|
4373
|
+
};
|
|
4374
|
+
try {
|
|
4375
|
+
writeParallelHandoffGroup(handoff);
|
|
4376
|
+
const cleanup = cleanupWorktrees(setup, {
|
|
4377
|
+
kind: "preserve",
|
|
4378
|
+
capturedDiffs: diffs,
|
|
4379
|
+
handoffManifestPath: manifestPath,
|
|
4380
|
+
...config.parentWorkflowRunId && singleResult.sessionFile && fs.existsSync(singleResult.sessionFile) && !singleResult.stopped ? { cleanupBlocker: "retained child resume requires managed worktree cwd" } : {}
|
|
4381
|
+
});
|
|
4382
|
+
statusPayload.parallelHandoff = writeParallelHandoffGroup({ ...handoff, cleanup });
|
|
4383
|
+
previousOutput = [previousOutput, diffSummary, formatParallelHandoffReference(statusPayload.parallelHandoff)].filter(Boolean).join(`
|
|
4674
4384
|
|
|
4675
4385
|
`);
|
|
4676
|
-
|
|
4677
|
-
|
|
4386
|
+
} catch (error) {
|
|
4387
|
+
previousOutput = [previousOutput, diffSummary, formatParallelHandoffError(error)].filter(Boolean).join(`
|
|
4678
4388
|
|
|
4679
4389
|
`);
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
if (singleResult.completionGuardTriggered) {
|
|
4684
|
-
const event = buildControlEvent(omitUndefinedProperties({
|
|
4685
|
-
from: requiredStatusStep(statusPayload, flatIndex).activityState,
|
|
4686
|
-
to: "needs_attention",
|
|
4687
|
-
runId: id,
|
|
4688
|
-
agent: seqStep.agent,
|
|
4689
|
-
index: flatIndex,
|
|
4690
|
-
ts: stepEndTime,
|
|
4691
|
-
message: `${seqStep.agent} completed without making edits for an implementation task`,
|
|
4692
|
-
reason: "completion_guard"
|
|
4693
|
-
}));
|
|
4694
|
-
appendControlEvent(event);
|
|
4390
|
+
}
|
|
4391
|
+
writeStatusPayload();
|
|
4392
|
+
});
|
|
4695
4393
|
}
|
|
4696
4394
|
flatIndex++;
|
|
4697
|
-
if (
|
|
4395
|
+
if (isAgentContract(seqStep.agentContract) && seqStep.gateOn === "acceptance" && singleResult.acceptance?.status === "rejected") {
|
|
4698
4396
|
statusPayload.error = acceptanceFailureMessage(singleResult.acceptance) ?? "Chain acceptance gate rejected the step.";
|
|
4699
4397
|
writeStatusPayload();
|
|
4700
4398
|
break;
|
|
@@ -4704,6 +4402,33 @@ ${formatParallelHandoffError(error)}`;
|
|
|
4704
4402
|
}
|
|
4705
4403
|
}
|
|
4706
4404
|
}
|
|
4405
|
+
await Promise.all([...externalActivityEvidence.values()].map((evidence) => evidence.probeInFlight).filter((probe) => probe !== undefined));
|
|
4406
|
+
if (periodicGitProbeFailure) {
|
|
4407
|
+
stopped = false;
|
|
4408
|
+
timedOut = false;
|
|
4409
|
+
interrupted = false;
|
|
4410
|
+
delete statusPayload.stopped;
|
|
4411
|
+
delete statusPayload.timedOut;
|
|
4412
|
+
statusPayload.error = periodicGitProbeFailure.message;
|
|
4413
|
+
const step = statusPayload.steps[periodicGitProbeFailure.index];
|
|
4414
|
+
if (step) {
|
|
4415
|
+
step.status = "failed";
|
|
4416
|
+
step.error = periodicGitProbeFailure.message;
|
|
4417
|
+
step.exitCode = 1;
|
|
4418
|
+
delete step.stopped;
|
|
4419
|
+
delete step.timedOut;
|
|
4420
|
+
}
|
|
4421
|
+
const result = results[periodicGitProbeFailure.index];
|
|
4422
|
+
if (result) {
|
|
4423
|
+
result.success = false;
|
|
4424
|
+
result.exitCode = 1;
|
|
4425
|
+
result.error = periodicGitProbeFailure.message;
|
|
4426
|
+
result.output = periodicGitProbeFailure.message;
|
|
4427
|
+
result.stopped = false;
|
|
4428
|
+
result.timedOut = false;
|
|
4429
|
+
result.interrupted = false;
|
|
4430
|
+
}
|
|
4431
|
+
}
|
|
4707
4432
|
let summary = results.map((r) => `${r.agent}:
|
|
4708
4433
|
${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(`
|
|
4709
4434
|
|
|
@@ -4763,9 +4488,16 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4763
4488
|
clearTimeout(timeoutTimer);
|
|
4764
4489
|
timeoutTimer = undefined;
|
|
4765
4490
|
}
|
|
4766
|
-
if (
|
|
4491
|
+
if (checkpointTimer) {
|
|
4492
|
+
clearTimeout(checkpointTimer);
|
|
4493
|
+
checkpointTimer = undefined;
|
|
4494
|
+
}
|
|
4495
|
+
if (!timedOut && !stopped && !interrupted && config.timeoutMs !== undefined && timeoutMessage !== undefined && results.some((result) => result.timedOut === true && result.error?.startsWith(timeoutMessage))) {
|
|
4767
4496
|
timedOut = true;
|
|
4768
4497
|
}
|
|
4498
|
+
disposeControlInbox();
|
|
4499
|
+
for (const request of consumeStopRequestPayloads(asyncDir))
|
|
4500
|
+
stopChildStep(request);
|
|
4769
4501
|
const signalTerminated = !stopped && !timedOut && !interrupted && results.some((result) => result.exitCode !== 0 && isUnexplainedProcessSignal(omitUndefinedProperties({
|
|
4770
4502
|
processSignal: result.processSignal,
|
|
4771
4503
|
interrupted: result.interrupted,
|
|
@@ -4773,9 +4505,12 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4773
4505
|
stopped: result.stopped
|
|
4774
4506
|
})));
|
|
4775
4507
|
const partialWithEvidence = !stopped && !signalTerminated && !timedOut && !usageBudgetExceeded && !interrupted && results.some(partialEvidenceResult) && !results.some(concreteFailureResult);
|
|
4508
|
+
statusWriteCoalescer.flush(statusPath);
|
|
4509
|
+
const publication = new Promise((resolve, reject) => {
|
|
4510
|
+
finalResultPublication = { resolve, reject };
|
|
4511
|
+
});
|
|
4776
4512
|
statusPayload.state = stopped || signalTerminated ? "stopped" : timedOut || usageBudgetExceeded ? "failed" : interrupted ? "paused" : results.every((r) => r.success) ? "complete" : partialWithEvidence ? "partial" : "failed";
|
|
4777
4513
|
closeSteerInbox(asyncDir, statusPayload.state, (filePath, payload) => runPersistence.write(filePath, payload));
|
|
4778
|
-
disposeControlInbox();
|
|
4779
4514
|
for (const request of consumeSteerRequests(asyncDir))
|
|
4780
4515
|
deliverSteerRequest(request);
|
|
4781
4516
|
const effectiveSessionFile = sessionFile ?? latestSessionFile;
|
|
@@ -4786,7 +4521,7 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4786
4521
|
if (target.state !== "scheduled" && target.state !== "routed" && target.state !== "queued")
|
|
4787
4522
|
continue;
|
|
4788
4523
|
changed = true;
|
|
4789
|
-
const reason = target.state === "queued" ?
|
|
4524
|
+
const reason = target.state === "queued" ? unconsumedSteerReason() : "child terminated before steering delivery";
|
|
4790
4525
|
updateSteeringLifecycleTarget(request.id, target.index, "failed", Date.now(), { reason });
|
|
4791
4526
|
markSteeringAttention(target.index);
|
|
4792
4527
|
emitSteeringEvent("subagent.steer.failed", { type: "steer", id: request.id, ts: request.requestedAt, message: reason }, target.index, { reason });
|
|
@@ -4814,7 +4549,7 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4814
4549
|
statusPayload.activityState = "needs_attention";
|
|
4815
4550
|
statusPayload.error = partialResult?.error ?? statusPayload.error;
|
|
4816
4551
|
for (const step of statusPayload.steps) {
|
|
4817
|
-
if (step.status === "failed")
|
|
4552
|
+
if (step.status === "failed" || step.status === "partial")
|
|
4818
4553
|
step.activityState = "needs_attention";
|
|
4819
4554
|
}
|
|
4820
4555
|
}
|
|
@@ -4837,7 +4572,8 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4837
4572
|
statusPayload.error = `Step failed: ${failedStep.agent}`;
|
|
4838
4573
|
}
|
|
4839
4574
|
}
|
|
4840
|
-
|
|
4575
|
+
let childSessionDisposal;
|
|
4576
|
+
const disposeChildSessions = () => childSessionDisposal ??= childSessions.dispose().catch((error) => console.error("Failed to dispose runner child sessions:", error));
|
|
4841
4577
|
try {
|
|
4842
4578
|
runPersistence.write(resultPath, {
|
|
4843
4579
|
lifecycleArtifactVersion: SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
@@ -4860,7 +4596,6 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4860
4596
|
output: r.output,
|
|
4861
4597
|
outputState: r.outputState,
|
|
4862
4598
|
error: r.error,
|
|
4863
|
-
protocolError: r.protocolError,
|
|
4864
4599
|
success: r.success,
|
|
4865
4600
|
skipped: r.skipped || undefined,
|
|
4866
4601
|
interrupted: r.interrupted || undefined,
|
|
@@ -4872,13 +4607,15 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4872
4607
|
sessionFile: r.sessionFile,
|
|
4873
4608
|
intercomTarget: r.intercomTarget,
|
|
4874
4609
|
model: r.model,
|
|
4875
|
-
|
|
4876
|
-
|
|
4610
|
+
thinking: r.thinking,
|
|
4611
|
+
requestedModel: r.requestedModel,
|
|
4877
4612
|
contextOverflow: r.contextOverflow,
|
|
4878
4613
|
totalCost: r.totalCost,
|
|
4879
4614
|
usage: r.usage,
|
|
4880
4615
|
artifactPaths: r.artifactPaths,
|
|
4616
|
+
savedOutputPath: r.savedOutputPath,
|
|
4881
4617
|
outputSaveError: r.outputSaveError,
|
|
4618
|
+
artifactOutputSaveFailed: r.artifactOutputSaveFailed,
|
|
4882
4619
|
metadataSaveError: r.metadataSaveError,
|
|
4883
4620
|
truncated: r.truncated,
|
|
4884
4621
|
transcriptPath: r.transcriptPath,
|
|
@@ -4894,6 +4631,7 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4894
4631
|
review: r.review,
|
|
4895
4632
|
effects: r.effects,
|
|
4896
4633
|
structuredOutput: r.structuredOutput,
|
|
4634
|
+
structuredOutputFailed: r.structuredOutputFailed,
|
|
4897
4635
|
structuredOutputPath: r.structuredOutputPath,
|
|
4898
4636
|
structuredOutputSchemaPath: r.structuredOutputSchemaPath,
|
|
4899
4637
|
acceptance: r.acceptance,
|
|
@@ -4934,16 +4672,19 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4934
4672
|
}, (filePath, payload) => {
|
|
4935
4673
|
writeAsyncResultFile(filePath, payload);
|
|
4936
4674
|
});
|
|
4937
|
-
finalResultCommitted
|
|
4675
|
+
if (!finalResultCommitted)
|
|
4676
|
+
await Promise.all([publication, disposeChildSessions()]);
|
|
4938
4677
|
} catch (err) {
|
|
4939
4678
|
const message = `Failed to write result file ${resultPath}: ${err instanceof Error ? err.message : String(err)}`;
|
|
4940
4679
|
console.error(message, err);
|
|
4941
4680
|
statusPayload.state = "failed";
|
|
4942
4681
|
statusPayload.error = message;
|
|
4943
4682
|
statusPayload.lastUpdate = Date.now();
|
|
4683
|
+
} finally {
|
|
4684
|
+
finalResultPublication = undefined;
|
|
4944
4685
|
}
|
|
4945
4686
|
writeStatusPayload();
|
|
4946
|
-
orcaProgressTab?.finish(statusPayload.state === "complete" ? "completed" : statusPayload.state === "stopped" ? "stopped" : "failed", effectiveSessionFile);
|
|
4687
|
+
await orcaProgressTab?.finish(statusPayload.state === "complete" ? "completed" : statusPayload.state === "stopped" ? "stopped" : "failed", effectiveSessionFile);
|
|
4947
4688
|
appendJsonl(eventsPath, JSON.stringify({
|
|
4948
4689
|
type: "subagent.run.completed",
|
|
4949
4690
|
lifecycleArtifactVersion: SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
@@ -4975,16 +4716,18 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
4975
4716
|
}), (filePath, content) => runPersistence.write(filePath, { content }, (_path, payload) => {
|
|
4976
4717
|
fs.writeFileSync(_path, payload.content, "utf-8");
|
|
4977
4718
|
}));
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4719
|
+
await disposeChildSessions();
|
|
4720
|
+
while (runPersistence.pendingCount() + indexPersistence.pendingCount() > 0) {
|
|
4721
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
4722
|
+
}
|
|
4723
|
+
runPersistence.dispose();
|
|
4724
|
+
indexPersistence.dispose();
|
|
4982
4725
|
if (config.runnerProcessInstanceId) {
|
|
4983
4726
|
const writers = {};
|
|
4984
4727
|
const expectedWriters = {};
|
|
4985
|
-
for (const
|
|
4986
|
-
writers[String(index)] =
|
|
4987
|
-
expectedWriters[String(index)] =
|
|
4728
|
+
for (const index of results.keys()) {
|
|
4729
|
+
writers[String(index)] = [];
|
|
4730
|
+
expectedWriters[String(index)] = 0;
|
|
4988
4731
|
}
|
|
4989
4732
|
const candidate = {
|
|
4990
4733
|
version: 1,
|
|
@@ -5002,117 +4745,38 @@ ${r.output || (r.exitCode !== 0 ? r.error : undefined) || "(no output)"}`).join(
|
|
|
5002
4745
|
}
|
|
5003
4746
|
}
|
|
5004
4747
|
}
|
|
5005
|
-
async function
|
|
5006
|
-
|
|
5007
|
-
while (Date.now() <= deadline) {
|
|
5008
|
-
if (fs.existsSync(controlPath)) {
|
|
5009
|
-
let payload;
|
|
5010
|
-
try {
|
|
5011
|
-
payload = JSON.parse(fs.readFileSync(controlPath, "utf-8"));
|
|
5012
|
-
} catch (error) {
|
|
5013
|
-
throw new Error(`Failed to read runner startup control '${controlPath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
5014
|
-
}
|
|
5015
|
-
if (payload.token !== token)
|
|
5016
|
-
throw new Error("Runner startup control token does not match.");
|
|
5017
|
-
if (payload.action === action)
|
|
5018
|
-
return;
|
|
5019
|
-
if (payload.action !== "ack" && payload.action !== "proceed")
|
|
5020
|
-
throw new Error("Runner startup control action is invalid.");
|
|
5021
|
-
}
|
|
5022
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
5023
|
-
}
|
|
5024
|
-
throw new Error(`Timed out after ${timeoutMs}ms waiting for runner startup control '${action}'.`);
|
|
5025
|
-
}
|
|
5026
|
-
async function runConfiguredSubagent(config) {
|
|
5027
|
-
let lease;
|
|
5028
|
-
let startupCommitted = config.revivalLease === undefined && config.launchBarrierToken === undefined;
|
|
5029
|
-
const startupPath = path.join(config.asyncDir, "runner-startup.json");
|
|
5030
|
-
const startupAckPath = path.join(config.asyncDir, "runner-startup-ack.json");
|
|
5031
|
-
const startupProceedPath = path.join(config.asyncDir, "runner-startup-proceed.json");
|
|
5032
|
-
const releaseOnExit = () => {
|
|
5033
|
-
try {
|
|
5034
|
-
lease?.release();
|
|
5035
|
-
} catch {}
|
|
5036
|
-
};
|
|
5037
|
-
process.once("exit", releaseOnExit);
|
|
4748
|
+
export async function runConfiguredSubagentExecution(config, options) {
|
|
4749
|
+
let childSessions;
|
|
5038
4750
|
try {
|
|
5039
|
-
if (
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
try {
|
|
5043
|
-
fs.rmSync(startupProceedPath, { force: true });
|
|
5044
|
-
} catch {}
|
|
5045
|
-
} else if (config.revivalLease) {
|
|
5046
|
-
lease = acquireSessionLease(config.revivalLease);
|
|
5047
|
-
config.revivalLeaseToken = lease.owner.token;
|
|
5048
|
-
writeAtomicJson(startupPath, { state: "ready", token: lease.owner.token, pid: process.pid, owner: lease.owner });
|
|
5049
|
-
await waitForStartupControl(startupAckPath, lease.owner.token, "ack");
|
|
5050
|
-
writeAtomicJson(startupPath, { state: "acknowledged", token: lease.owner.token, pid: process.pid });
|
|
5051
|
-
await waitForStartupControl(startupProceedPath, lease.owner.token, "proceed");
|
|
5052
|
-
startupCommitted = true;
|
|
5053
|
-
for (const controlPath of [startupAckPath, startupProceedPath]) {
|
|
5054
|
-
try {
|
|
5055
|
-
fs.rmSync(controlPath, { force: true });
|
|
5056
|
-
} catch {}
|
|
5057
|
-
}
|
|
5058
|
-
}
|
|
5059
|
-
await runSubagent(config, lease ? (writer) => lease.updateWriter(writer) : undefined);
|
|
4751
|
+
if (!options?.loadPiCodingAgent)
|
|
4752
|
+
installRunnerHttpDispatcher({ agentDir: getAgentDir(), cwd: process.cwd() });
|
|
4753
|
+
childSessions = await loadRunnerChildSessionFactory(config, options);
|
|
5060
4754
|
} catch (error) {
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
4755
|
+
try {
|
|
4756
|
+
persistRunnerStartupFailure({
|
|
4757
|
+
asyncDir: config.asyncDir,
|
|
4758
|
+
runId: config.id,
|
|
4759
|
+
runnerProcessInstanceId: config.runnerProcessInstanceId ?? "unknown-runner-instance",
|
|
4760
|
+
message: `Subagent runner startup failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
4761
|
+
...config.sessionId ? { sessionId: config.sessionId } : {},
|
|
4762
|
+
...config.completionOwnerId ? { completionOwnerId: config.completionOwnerId } : {},
|
|
4763
|
+
candidate: {
|
|
4764
|
+
...config.revivalLease?.sessionFile ? { sessionFile: config.revivalLease.sessionFile } : {},
|
|
4765
|
+
...config.revivalLeaseToken ? { revivalLeaseToken: config.revivalLeaseToken } : {}
|
|
4766
|
+
}
|
|
4767
|
+
});
|
|
4768
|
+
} catch (persistenceError) {
|
|
4769
|
+
console.error("Failed to persist runner setup failure:", persistenceError);
|
|
5065
4770
|
}
|
|
5066
4771
|
throw error;
|
|
5067
|
-
} finally {
|
|
5068
|
-
process.off("exit", releaseOnExit);
|
|
5069
|
-
if (lease) {
|
|
5070
|
-
let acknowledged = false;
|
|
5071
|
-
try {
|
|
5072
|
-
acknowledged = lease.release();
|
|
5073
|
-
} catch (error) {
|
|
5074
|
-
console.error("Failed to release session revival lease:", error);
|
|
5075
|
-
}
|
|
5076
|
-
try {
|
|
5077
|
-
markProcessTerminalCandidateLeaseRelease(config.asyncDir, lease.owner.token, acknowledged);
|
|
5078
|
-
} catch (error) {
|
|
5079
|
-
console.error("Failed to record session revival lease release:", error);
|
|
5080
|
-
}
|
|
5081
|
-
}
|
|
5082
4772
|
}
|
|
5083
|
-
}
|
|
5084
|
-
function startConfiguredSubagent(config) {
|
|
5085
|
-
runConfiguredSubagent(config).catch((runErr) => {
|
|
5086
|
-
console.error("Subagent runner error:", runErr);
|
|
5087
|
-
process.exit(1);
|
|
5088
|
-
});
|
|
5089
|
-
}
|
|
5090
|
-
const configArg = process.argv[2];
|
|
5091
|
-
if (configArg) {
|
|
5092
4773
|
try {
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
try {
|
|
5096
|
-
fs.unlinkSync(configArg);
|
|
5097
|
-
} catch {}
|
|
5098
|
-
startConfiguredSubagent(config);
|
|
5099
|
-
} catch (err) {
|
|
5100
|
-
console.error("Subagent runner error:", err);
|
|
5101
|
-
process.exit(1);
|
|
5102
|
-
}
|
|
5103
|
-
} else {
|
|
5104
|
-
let input = "";
|
|
5105
|
-
process.stdin.setEncoding("utf-8");
|
|
5106
|
-
process.stdin.on("data", (chunk) => {
|
|
5107
|
-
input += chunk;
|
|
5108
|
-
});
|
|
5109
|
-
process.stdin.on("end", () => {
|
|
4774
|
+
await runSubagent(config, childSessions);
|
|
4775
|
+
} finally {
|
|
5110
4776
|
try {
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
console.error("Subagent runner error:", err);
|
|
5115
|
-
process.exit(1);
|
|
4777
|
+
await childSessions.dispose();
|
|
4778
|
+
} catch (error) {
|
|
4779
|
+
console.error("Failed to dispose runner child sessions:", error);
|
|
5116
4780
|
}
|
|
5117
|
-
}
|
|
4781
|
+
}
|
|
5118
4782
|
}
|