muonroi-cli 1.8.4 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -5
- package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
- package/dist/packages/agent-harness-core/src/driver.js +46 -0
- package/dist/packages/agent-harness-core/src/event-filter.js +11 -0
- package/dist/packages/agent-harness-core/src/event-redact.js +7 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +64 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +104 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +25 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +169 -21
- package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
- package/dist/packages/agent-harness-core/src/protocol.d.ts +90 -4
- package/dist/packages/agent-harness-core/src/protocol.js +15 -0
- package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
- package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
- package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
- package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
- package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
- package/dist/packages/agent-harness-opentui/src/install.js +10 -0
- package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
- package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
- package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
- package/dist/src/agent-harness/mock-model.d.ts +38 -0
- package/dist/src/agent-harness/mock-model.js +69 -3
- package/dist/src/agent-harness/test-spawn.js +31 -0
- package/dist/src/chat/chat-keychain.d.ts +7 -12
- package/dist/src/chat/chat-keychain.js +19 -86
- package/dist/src/cli/config/screen-providers.js +1 -1
- package/dist/src/cli/cost-forensics.d.ts +10 -0
- package/dist/src/cli/cost-forensics.js +18 -3
- package/dist/src/cli/keys-bundle.d.ts +1 -1
- package/dist/src/cli/keys-bundle.js +1 -1
- package/dist/src/cli/keys.d.ts +10 -47
- package/dist/src/cli/keys.js +31 -399
- package/dist/src/council/clarifier.d.ts +31 -3
- package/dist/src/council/clarifier.js +220 -32
- package/dist/src/council/context.js +49 -15
- package/dist/src/council/debate-checkpoint.d.ts +129 -0
- package/dist/src/council/debate-checkpoint.js +176 -0
- package/dist/src/council/debate-planner.js +54 -5
- package/dist/src/council/debate-summary.d.ts +25 -0
- package/dist/src/council/debate-summary.js +85 -0
- package/dist/src/council/debate.d.ts +169 -2
- package/dist/src/council/debate.js +1265 -135
- package/dist/src/council/index.d.ts +108 -1
- package/dist/src/council/index.js +670 -197
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +94 -0
- package/dist/src/council/llm.js +348 -55
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +82 -0
- package/dist/src/council/planner.js +40 -0
- package/dist/src/council/preflight.d.ts +17 -0
- package/dist/src/council/preflight.js +50 -2
- package/dist/src/council/prompts.d.ts +39 -4
- package/dist/src/council/prompts.js +256 -69
- package/dist/src/council/stance-recall.d.ts +42 -0
- package/dist/src/council/stance-recall.js +57 -0
- package/dist/src/council/strip-think.d.ts +17 -0
- package/dist/src/council/strip-think.js +33 -0
- package/dist/src/council/types.d.ts +138 -0
- package/dist/src/ee/artifact-cache.d.ts +16 -0
- package/dist/src/ee/artifact-cache.js +32 -0
- package/dist/src/ee/auth.d.ts +20 -0
- package/dist/src/ee/auth.js +54 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +109 -21
- package/dist/src/ee/ee-onboarding.js +6 -26
- package/dist/src/ee/export-transcripts.d.ts +1 -0
- package/dist/src/ee/export-transcripts.js +8 -10
- package/dist/src/ee/extract-session.js +29 -0
- package/dist/src/ee/extract-style.d.ts +58 -0
- package/dist/src/ee/extract-style.js +270 -0
- package/dist/src/ee/recall-ledger.d.ts +9 -0
- package/dist/src/ee/recall-ledger.js +3 -0
- package/dist/src/ee/scope.d.ts +1 -0
- package/dist/src/ee/scope.js +26 -1
- package/dist/src/ee/search.d.ts +7 -0
- package/dist/src/ee/search.js +24 -0
- package/dist/src/ee/transcript-emit.js +2 -0
- package/dist/src/ee/types.d.ts +22 -0
- package/dist/src/ee/who-am-i-brain.d.ts +35 -0
- package/dist/src/ee/who-am-i-brain.js +220 -0
- package/dist/src/ee/who-am-i.d.ts +10 -3
- package/dist/src/ee/who-am-i.js +12 -0
- package/dist/src/ee/workflow-event.d.ts +48 -0
- package/dist/src/ee/workflow-event.js +81 -0
- package/dist/src/flow/compaction/compress.d.ts +3 -3
- package/dist/src/flow/compaction/compress.js +58 -8
- package/dist/src/flow/compaction/extract.d.ts +4 -7
- package/dist/src/flow/compaction/extract.js +50 -10
- package/dist/src/flow/compaction/index.d.ts +14 -1
- package/dist/src/flow/compaction/index.js +96 -3
- package/dist/src/flow/compaction/input-guard.d.ts +24 -0
- package/dist/src/flow/compaction/input-guard.js +43 -0
- package/dist/src/flow/compaction/progress.d.ts +35 -0
- package/dist/src/flow/compaction/progress.js +35 -0
- package/dist/src/flow/fold-planning.d.ts +36 -0
- package/dist/src/flow/fold-planning.js +83 -0
- package/dist/src/flow/hierarchy.d.ts +146 -0
- package/dist/src/flow/hierarchy.js +427 -0
- package/dist/src/flow/index.d.ts +1 -0
- package/dist/src/flow/index.js +2 -0
- package/dist/src/flow/run-artifacts.d.ts +102 -0
- package/dist/src/flow/run-artifacts.js +208 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/assessment-schema.d.ts +44 -0
- package/dist/src/gsd/assessment-schema.js +134 -0
- package/dist/src/gsd/capability-registry.d.ts +45 -0
- package/dist/src/gsd/capability-registry.js +337 -0
- package/dist/src/gsd/complexity-assessor.d.ts +39 -0
- package/dist/src/gsd/complexity-assessor.js +152 -0
- package/dist/src/gsd/config-bridge.d.ts +7 -0
- package/dist/src/gsd/config-bridge.js +114 -0
- package/dist/src/gsd/config-loader.d.ts +27 -0
- package/dist/src/gsd/config-loader.js +50 -0
- package/dist/src/gsd/council-context.d.ts +44 -0
- package/dist/src/gsd/council-context.js +114 -0
- package/dist/src/gsd/ee-closure.d.ts +28 -0
- package/dist/src/gsd/ee-closure.js +49 -0
- package/dist/src/gsd/flags.d.ts +66 -0
- package/dist/src/gsd/flags.js +102 -0
- package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
- package/dist/src/gsd/gsd-dispatch.js +131 -0
- package/dist/src/gsd/gsd-runtime.d.ts +22 -0
- package/dist/src/gsd/gsd-runtime.js +37 -0
- package/dist/src/gsd/host-adapter.d.ts +11 -0
- package/dist/src/gsd/host-adapter.js +29 -0
- package/dist/src/gsd/index.d.ts +24 -1
- package/dist/src/gsd/index.js +27 -0
- package/dist/src/gsd/loop-host-contract.d.ts +21 -0
- package/dist/src/gsd/loop-host-contract.js +39 -0
- package/dist/src/gsd/loop-host.d.ts +69 -0
- package/dist/src/gsd/loop-host.js +245 -0
- package/dist/src/gsd/loop-resolver.d.ts +36 -0
- package/dist/src/gsd/loop-resolver.js +79 -0
- package/dist/src/gsd/model-tier.d.ts +13 -0
- package/dist/src/gsd/model-tier.js +45 -0
- package/dist/src/gsd/mutation-gate.d.ts +16 -0
- package/dist/src/gsd/mutation-gate.js +41 -0
- package/dist/src/gsd/native-roadmap.d.ts +89 -0
- package/dist/src/gsd/native-roadmap.js +343 -0
- package/dist/src/gsd/native-state.d.ts +47 -0
- package/dist/src/gsd/native-state.js +220 -0
- package/dist/src/gsd/paths.d.ts +23 -0
- package/dist/src/gsd/paths.js +66 -0
- package/dist/src/gsd/phase-dag.d.ts +12 -0
- package/dist/src/gsd/phase-dag.js +94 -0
- package/dist/src/gsd/phase-sync.d.ts +42 -0
- package/dist/src/gsd/phase-sync.js +321 -0
- package/dist/src/gsd/pil-gate-context.d.ts +13 -0
- package/dist/src/gsd/pil-gate-context.js +64 -0
- package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
- package/dist/src/gsd/pil-gate-critic.js +74 -0
- package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
- package/dist/src/gsd/plan-council-prompts.js +79 -0
- package/dist/src/gsd/plan-council.d.ts +44 -0
- package/dist/src/gsd/plan-council.js +283 -0
- package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
- package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
- package/dist/src/gsd/product-workspace.d.ts +13 -0
- package/dist/src/gsd/product-workspace.js +124 -0
- package/dist/src/gsd/ship-bridge.d.ts +25 -0
- package/dist/src/gsd/ship-bridge.js +65 -0
- package/dist/src/gsd/state-document.d.ts +40 -0
- package/dist/src/gsd/state-document.js +163 -0
- package/dist/src/gsd/verdict-schema.d.ts +39 -0
- package/dist/src/gsd/verdict-schema.js +144 -0
- package/dist/src/gsd/verify-context.d.ts +22 -0
- package/dist/src/gsd/verify-context.js +27 -0
- package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
- package/dist/src/gsd/verify-council-prompts.js +85 -0
- package/dist/src/gsd/verify-council.d.ts +25 -0
- package/dist/src/gsd/verify-council.js +119 -0
- package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
- package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
- package/dist/src/gsd/workflow-engine.d.ts +60 -0
- package/dist/src/gsd/workflow-engine.js +207 -0
- package/dist/src/gsd/workflow-tools.d.ts +13 -0
- package/dist/src/gsd/workflow-tools.js +277 -0
- package/dist/src/headless/council-answers.js +4 -0
- package/dist/src/hooks/index.js +1 -1
- package/dist/src/index.js +172 -270
- package/dist/src/lsp/builtins.js +3 -1
- package/dist/src/lsp/manager.d.ts +5 -1
- package/dist/src/lsp/manager.js +249 -3
- package/dist/src/lsp/npm-cache.d.ts +11 -1
- package/dist/src/lsp/npm-cache.js +17 -1
- package/dist/src/lsp/runtime.d.ts +6 -1
- package/dist/src/lsp/runtime.js +17 -1
- package/dist/src/lsp/types.d.ts +83 -1
- package/dist/src/lsp/types.js +10 -0
- package/dist/src/maintain/pr-builder.js +23 -13
- package/dist/src/mcp/auto-setup.js +57 -32
- package/dist/src/mcp/client-pool.js +44 -16
- package/dist/src/mcp/lsp-tools.d.ts +5 -1
- package/dist/src/mcp/lsp-tools.js +93 -2
- package/dist/src/mcp/mcp-keychain.d.ts +3 -5
- package/dist/src/mcp/mcp-keychain.js +9 -49
- package/dist/src/mcp/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -2
- package/dist/src/mcp/setup-guide-text.d.ts +1 -1
- package/dist/src/mcp/setup-guide-text.js +22 -2
- package/dist/src/mcp/tools-server.d.ts +10 -0
- package/dist/src/mcp/tools-server.js +10 -2
- package/dist/src/models/catalog-client.d.ts +87 -0
- package/dist/src/models/catalog-client.js +105 -38
- package/dist/src/models/catalog.json +528 -265
- package/dist/src/models/registry.d.ts +22 -7
- package/dist/src/models/registry.js +73 -10
- package/dist/src/ops/doctor.js +1 -1
- package/dist/src/orchestrator/ask-user.d.ts +61 -0
- package/dist/src/orchestrator/ask-user.js +65 -0
- package/dist/src/orchestrator/auto-commit.js +1 -1
- package/dist/src/orchestrator/batch-turn-runner.js +2 -2
- package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
- package/dist/src/orchestrator/cache-prefix.js +83 -0
- package/dist/src/orchestrator/compact-request.d.ts +32 -0
- package/dist/src/orchestrator/compact-request.js +41 -0
- package/dist/src/orchestrator/compaction.d.ts +12 -3
- package/dist/src/orchestrator/compaction.js +35 -15
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +74 -32
- package/dist/src/orchestrator/council-request.d.ts +49 -0
- package/dist/src/orchestrator/council-request.js +62 -0
- package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
- package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
- package/dist/src/orchestrator/error-utils.d.ts +29 -0
- package/dist/src/orchestrator/error-utils.js +132 -24
- package/dist/src/orchestrator/grounding-check.js +39 -1
- package/dist/src/orchestrator/interactive-pause.d.ts +26 -0
- package/dist/src/orchestrator/interactive-pause.js +36 -0
- package/dist/src/orchestrator/message-processor.d.ts +4 -0
- package/dist/src/orchestrator/message-processor.js +268 -41
- package/dist/src/orchestrator/orchestrator.d.ts +64 -3
- package/dist/src/orchestrator/orchestrator.js +823 -120
- package/dist/src/orchestrator/preprocessor.js +3 -3
- package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
- package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
- package/dist/src/orchestrator/prompts.js +17 -17
- package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
- package/dist/src/orchestrator/reactive-delegation.js +59 -0
- package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
- package/dist/src/orchestrator/retry-classifier.js +46 -2
- package/dist/src/orchestrator/safety-askcard.d.ts +1 -1
- package/dist/src/orchestrator/safety-askcard.js +5 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +50 -0
- package/dist/src/orchestrator/safety-intercept.js +62 -0
- package/dist/src/orchestrator/scope-reminder.js +1 -1
- package/dist/src/orchestrator/session-experience.d.ts +2 -1
- package/dist/src/orchestrator/session-experience.js +2 -1
- package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
- package/dist/src/orchestrator/should-run-gate.js +18 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +31 -3
- package/dist/src/orchestrator/stall-watchdog.js +65 -10
- package/dist/src/orchestrator/stream-runner.d.ts +13 -3
- package/dist/src/orchestrator/stream-runner.js +115 -49
- package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-cap.js +16 -1
- package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
- package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
- package/dist/src/orchestrator/subagent-compactor.js +126 -15
- package/dist/src/orchestrator/tool-engine.d.ts +41 -0
- package/dist/src/orchestrator/tool-engine.js +846 -66
- package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
- package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
- package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
- package/dist/src/orchestrator/turn-watchdog.d.ts +44 -0
- package/dist/src/orchestrator/turn-watchdog.js +84 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +6 -4
- package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
- package/dist/src/pil/cheap-model-playbook.js +5 -1
- package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
- package/dist/src/pil/cheap-model-workbooks.js +1 -1
- package/dist/src/pil/discovery-types.d.ts +1 -0
- package/dist/src/pil/discovery.d.ts +1 -1
- package/dist/src/pil/discovery.js +18 -13
- package/dist/src/pil/layer1-intent.d.ts +18 -6
- package/dist/src/pil/layer1-intent.js +66 -757
- package/dist/src/pil/layer15-context-scan.js +15 -1
- package/dist/src/pil/layer1_5-complexity-size.d.ts +7 -0
- package/dist/src/pil/layer1_5-complexity-size.js +31 -5
- package/dist/src/pil/layer3-ee-injection.js +23 -8
- package/dist/src/pil/layer4-gsd.js +69 -16
- package/dist/src/pil/layer5-context.js +7 -3
- package/dist/src/pil/layer6-output.d.ts +23 -0
- package/dist/src/pil/layer6-output.js +5 -1
- package/dist/src/pil/llm-classify.d.ts +111 -5
- package/dist/src/pil/llm-classify.js +421 -189
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +8 -0
- package/dist/src/pil/pipeline.js +36 -2
- package/dist/src/pil/repo-grounding-probe.d.ts +15 -0
- package/dist/src/pil/repo-grounding-probe.js +136 -0
- package/dist/src/pil/repo-structure-hints.d.ts +7 -0
- package/dist/src/pil/repo-structure-hints.js +45 -0
- package/dist/src/pil/response-tools.js +5 -3
- package/dist/src/pil/schema.d.ts +1 -0
- package/dist/src/pil/schema.js +2 -0
- package/dist/src/pil/types.d.ts +18 -0
- package/dist/src/playbook/directives.d.ts +4 -0
- package/dist/src/playbook/directives.js +17 -5
- package/dist/src/product-loop/artifact-io.js +4 -0
- package/dist/src/product-loop/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- package/dist/src/product-loop/criteria-seed.d.ts +51 -0
- package/dist/src/product-loop/criteria-seed.js +200 -0
- package/dist/src/product-loop/discovery-context-format.js +3 -1
- package/dist/src/product-loop/discovery-ecosystem.js +4 -1
- package/dist/src/product-loop/discovery-interview.d.ts +9 -0
- package/dist/src/product-loop/discovery-interview.js +60 -12
- package/dist/src/product-loop/discovery-recommender.js +2 -1
- package/dist/src/product-loop/discovery-schema.js +19 -2
- package/dist/src/product-loop/discovery-triage.d.ts +23 -0
- package/dist/src/product-loop/discovery-triage.js +109 -0
- package/dist/src/product-loop/gather.js +150 -2
- package/dist/src/product-loop/ideal-trace.d.ts +7 -0
- package/dist/src/product-loop/ideal-trace.js +64 -0
- package/dist/src/product-loop/index.d.ts +13 -1
- package/dist/src/product-loop/index.js +340 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +330 -106
- package/dist/src/product-loop/phase-plan.d.ts +21 -0
- package/dist/src/product-loop/phase-plan.js +81 -6
- package/dist/src/product-loop/phase-rituals.d.ts +3 -0
- package/dist/src/product-loop/phase-rituals.js +8 -3
- package/dist/src/product-loop/phase-runner.js +39 -12
- package/dist/src/product-loop/plan-adherence-review.d.ts +26 -0
- package/dist/src/product-loop/plan-adherence-review.js +144 -0
- package/dist/src/product-loop/sprint-runner.d.ts +173 -0
- package/dist/src/product-loop/sprint-runner.js +863 -19
- package/dist/src/product-loop/types.d.ts +61 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- package/dist/src/providers/anthropic.d.ts +9 -8
- package/dist/src/providers/anthropic.js +13 -47
- package/dist/src/providers/auth/browser-flow.d.ts +1 -1
- package/dist/src/providers/auth/browser-flow.js +1 -1
- package/dist/src/providers/auth/grok-oauth.d.ts +1 -0
- package/dist/src/providers/auth/grok-oauth.js +30 -5
- package/dist/src/providers/auth/openai-oauth.d.ts +1 -0
- package/dist/src/providers/auth/openai-oauth.js +15 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.d.ts +9 -9
- package/dist/src/providers/auth/token-store.js +8 -67
- package/dist/src/providers/auth/types.d.ts +9 -1
- package/dist/src/providers/auth/types.js +1 -1
- package/dist/src/providers/capabilities.d.ts +24 -5
- package/dist/src/providers/capabilities.js +42 -24
- package/dist/src/providers/endpoints.d.ts +2 -2
- package/dist/src/providers/endpoints.js +11 -10
- package/dist/src/providers/env-store.d.ts +17 -0
- package/dist/src/providers/env-store.js +228 -0
- package/dist/src/providers/keychain.d.ts +22 -18
- package/dist/src/providers/keychain.js +127 -140
- package/dist/src/providers/mcp-vision-bridge.js +56 -146
- package/dist/src/providers/openai-compatible.js +8 -1
- package/dist/src/providers/pricing.d.ts +2 -2
- package/dist/src/providers/pricing.js +3 -13
- package/dist/src/providers/runtime.d.ts +43 -3
- package/dist/src/providers/runtime.js +88 -14
- package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
- package/dist/src/providers/strategies/base.strategy.js +24 -1
- package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
- package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
- package/dist/src/providers/strategies/registry.js +4 -4
- package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
- package/dist/src/providers/strategies/thinking-mode.js +288 -1
- package/dist/src/providers/strategies/xai.strategy.js +27 -0
- package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
- package/dist/src/providers/strategies/zai.strategy.js +44 -0
- package/dist/src/providers/types.d.ts +5 -6
- package/dist/src/providers/types.js +2 -2
- package/dist/src/providers/vision-backend.d.ts +47 -0
- package/dist/src/providers/vision-backend.js +258 -0
- package/dist/src/providers/vision-proxy.d.ts +22 -9
- package/dist/src/providers/vision-proxy.js +63 -132
- package/dist/src/providers/warm.d.ts +65 -0
- package/dist/src/providers/warm.js +145 -0
- package/dist/src/providers/wire-debug.js +95 -0
- package/dist/src/router/decide.d.ts +13 -0
- package/dist/src/router/decide.js +138 -36
- package/dist/src/router/peak-hour.d.ts +38 -0
- package/dist/src/router/peak-hour.js +107 -0
- package/dist/src/router/step-router.js +3 -2
- package/dist/src/router/warm.js +4 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +26 -0
- package/dist/src/scaffold/point-to-existing.d.ts +21 -0
- package/dist/src/scaffold/point-to-existing.js +25 -0
- package/dist/src/self-qa/agentic-loop.js +6 -5
- package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
- package/dist/src/{ui/state → state}/active-run.js +21 -0
- package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
- package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
- package/dist/src/state/turn-trace.d.ts +43 -0
- package/dist/src/state/turn-trace.js +32 -0
- package/dist/src/storage/db.js +2 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/interaction-log.d.ts +1 -1
- package/dist/src/storage/migrations.js +71 -1
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +78 -21
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +340 -15
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/git-safety.d.ts +19 -0
- package/dist/src/tools/git-safety.js +168 -0
- package/dist/src/tools/native-tools.d.ts +1 -1
- package/dist/src/tools/native-tools.js +81 -1
- package/dist/src/tools/registry.d.ts +20 -0
- package/dist/src/tools/registry.js +576 -23
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +147 -4
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- package/dist/src/ui/components/agent-rail-activities.d.ts +26 -0
- package/dist/src/ui/components/agent-rail-activities.js +47 -0
- package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
- package/dist/src/ui/components/bubble-body-guard.js +50 -0
- package/dist/src/ui/components/compact-progress-card.d.ts +24 -0
- package/dist/src/ui/components/compact-progress-card.js +42 -0
- package/dist/src/ui/components/context-rail.d.ts +26 -0
- package/dist/src/ui/components/context-rail.js +33 -0
- package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
- package/dist/src/ui/components/council-conclusion-card.js +420 -0
- package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
- package/dist/src/ui/components/council-debate-pill.js +34 -0
- package/dist/src/ui/components/council-info-card.js +2 -2
- package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
- package/dist/src/ui/components/council-leader-bubble.js +21 -11
- package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
- package/dist/src/ui/components/council-message-bubble.js +16 -15
- package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
- package/dist/src/ui/components/council-phase-timeline.js +66 -17
- package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
- package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
- package/dist/src/ui/components/council-question-card.js +13 -12
- package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
- package/dist/src/ui/components/council-rail-rounds.js +57 -0
- package/dist/src/ui/components/council-round-group.d.ts +38 -0
- package/dist/src/ui/components/council-round-group.js +88 -0
- package/dist/src/ui/components/council-status-list.d.ts +3 -1
- package/dist/src/ui/components/council-status-list.js +36 -24
- package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
- package/dist/src/ui/components/council-synthesis-banner.js +20 -5
- package/dist/src/ui/components/halt-recovery-card.js +9 -5
- package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
- package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
- package/dist/src/ui/components/message-view.d.ts +15 -0
- package/dist/src/ui/components/message-view.js +50 -1
- package/dist/src/ui/components/prompt-box.js +18 -16
- package/dist/src/ui/components/session-tree-card.d.ts +14 -0
- package/dist/src/ui/components/session-tree-card.js +46 -0
- package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
- package/dist/src/ui/components/slash-inline-menu.js +26 -5
- package/dist/src/ui/components/task-list-panel.d.ts +14 -1
- package/dist/src/ui/components/task-list-panel.js +22 -2
- package/dist/src/ui/components/tool-group.d.ts +15 -3
- package/dist/src/ui/components/tool-group.js +69 -11
- package/dist/src/ui/containers/modals-layer.d.ts +4 -2
- package/dist/src/ui/containers/modals-layer.js +2 -2
- package/dist/src/ui/council-harness-event.d.ts +57 -0
- package/dist/src/ui/council-harness-event.js +46 -0
- package/dist/src/ui/heartbeat-debug.d.ts +29 -0
- package/dist/src/ui/heartbeat-debug.js +45 -0
- package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
- package/dist/src/ui/mcp-modal.js +2 -4
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/connect-modal.js +4 -3
- package/dist/src/ui/modals/model-picker-modal.d.ts +8 -18
- package/dist/src/ui/modals/model-picker-modal.js +8 -10
- package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
- package/dist/src/ui/modals/session-picker-modal.js +3 -5
- package/dist/src/ui/picker-providers.d.ts +1 -1
- package/dist/src/ui/picker-providers.js +1 -1
- package/dist/src/ui/primitives/index.d.ts +1 -0
- package/dist/src/ui/primitives/index.js +2 -0
- package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
- package/dist/src/ui/primitives/semantic-primitives.js +81 -0
- package/dist/src/ui/slash/compact.js +5 -7
- package/dist/src/ui/slash/cost.js +1 -1
- package/dist/src/ui/slash/council.js +19 -1
- package/dist/src/ui/slash/debug.d.ts +3 -31
- package/dist/src/ui/slash/debug.js +9 -20
- package/dist/src/ui/slash/ee.js +81 -0
- package/dist/src/ui/slash/ideal.d.ts +6 -2
- package/dist/src/ui/slash/ideal.js +97 -7
- package/dist/src/ui/slash/menu-items.d.ts +7 -0
- package/dist/src/ui/slash/menu-items.js +23 -20
- package/dist/src/ui/slash/registry.d.ts +2 -0
- package/dist/src/ui/slash/registry.js +4 -0
- package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
- package/dist/src/ui/status-bar/cache-hit.js +9 -0
- package/dist/src/ui/status-bar/index.d.ts +1 -1
- package/dist/src/ui/status-bar/index.js +7 -3
- package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
- package/dist/src/ui/status-bar/usd-meter.js +6 -4
- package/dist/src/ui/theme.d.ts +1 -0
- package/dist/src/ui/theme.js +2 -0
- package/dist/src/ui/types.d.ts +7 -0
- package/dist/src/ui/use-app-logic.js +0 -0
- package/dist/src/ui/utils/agent-activities.d.ts +39 -0
- package/dist/src/ui/utils/agent-activities.js +96 -0
- package/dist/src/ui/utils/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/ui/utils/group-tool-entries.d.ts +26 -0
- package/dist/src/ui/utils/group-tool-entries.js +111 -0
- package/dist/src/ui/utils/tool-summary.d.ts +21 -0
- package/dist/src/ui/utils/tool-summary.js +91 -0
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/event-loop-monitor.d.ts +85 -0
- package/dist/src/utils/event-loop-monitor.js +107 -0
- package/dist/src/utils/install-manager.js +2 -1
- package/dist/src/utils/llm-deadline.d.ts +14 -0
- package/dist/src/utils/llm-deadline.js +19 -0
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/loop-profiler.d.ts +102 -0
- package/dist/src/utils/loop-profiler.js +202 -0
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +180 -5
- package/dist/src/utils/settings.js +271 -31
- package/dist/src/utils/side-question.d.ts +1 -2
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/utils/visible-retry.d.ts +11 -0
- package/dist/src/utils/visible-retry.js +10 -1
- package/dist/src/verify/entrypoint.d.ts +1 -1
- package/dist/src/verify/entrypoint.js +52 -17
- package/dist/src/verify/orchestrator.d.ts +1 -1
- package/dist/src/verify/orchestrator.js +20 -3
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +134 -132
- package/dist/src/cli/bw-vault.d.ts +0 -55
- package/dist/src/cli/bw-vault.js +0 -133
- package/dist/src/mcp/ee-tools.d.ts +0 -46
- package/dist/src/mcp/ee-tools.js +0 -193
- package/dist/src/providers/auth/gcloud.d.ts +0 -28
- package/dist/src/providers/auth/gcloud.js +0 -102
- package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
- package/dist/src/providers/auth/gemini-oauth.js +0 -472
- package/dist/src/providers/gemini.d.ts +0 -11
- package/dist/src/providers/gemini.js +0 -45
- package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
- package/dist/src/providers/siliconflow-sse-repair.js +0 -177
- package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
- package/dist/src/providers/strategies/google.strategy.js +0 -174
- package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
- package/dist/src/ui/containers/chat-feed.d.ts +0 -40
- package/dist/src/ui/containers/chat-feed.js +0 -66
|
@@ -70,36 +70,84 @@ export function shouldContinueAfterMidLoopStall(s) {
|
|
|
70
70
|
export function stallRepromptBackoffMs(attempt) {
|
|
71
71
|
return Math.min(500 * 2 ** (Math.max(1, attempt) - 1), 4_000);
|
|
72
72
|
}
|
|
73
|
-
export function createStallWatchdog(timeoutMs, onFire
|
|
73
|
+
export function createStallWatchdog(timeoutMs, onFire, progressOpts,
|
|
74
|
+
/**
|
|
75
|
+
* Optional gate consulted the instant a timer would fire. When it returns
|
|
76
|
+
* true the watchdog RE-ARMS instead of aborting — used to hold the stream
|
|
77
|
+
* open while a blocking interactive card (`ask_user`) awaits a human, without
|
|
78
|
+
* counting that wait as a provider stall.
|
|
79
|
+
*/
|
|
80
|
+
shouldSuppressFire) {
|
|
74
81
|
const controller = new AbortController();
|
|
75
82
|
let firedFlag = false;
|
|
76
83
|
let timer = null;
|
|
77
84
|
const enabled = Number.isFinite(timeoutMs) && timeoutMs > 0;
|
|
85
|
+
const progressTimeoutMs = progressOpts?.progressTimeoutMs ?? 0;
|
|
86
|
+
const progressEnabled = Number.isFinite(progressTimeoutMs) && progressTimeoutMs > 0;
|
|
87
|
+
let progressTimer = null;
|
|
88
|
+
const fire = (onSpecificFire) => {
|
|
89
|
+
if (firedFlag)
|
|
90
|
+
return;
|
|
91
|
+
firedFlag = true;
|
|
92
|
+
// Stop the OTHER timer so it can't also fire after the abort (e.g. the
|
|
93
|
+
// any-activity stall timer that was armed just before the progress timer
|
|
94
|
+
// tripped — otherwise both onFire callbacks would run).
|
|
95
|
+
clearBoth();
|
|
96
|
+
// DOMException(TimeoutError) mirrors AbortSignal.timeout() semantics so
|
|
97
|
+
// downstream isAbortError-style checks treat it as an abort.
|
|
98
|
+
controller.abort(new DOMException(STALL_ABORT_REASON, "TimeoutError"));
|
|
99
|
+
try {
|
|
100
|
+
onSpecificFire?.();
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
/* callback must not break the watchdog */
|
|
104
|
+
}
|
|
105
|
+
};
|
|
78
106
|
const arm = () => {
|
|
79
107
|
if (!enabled)
|
|
80
108
|
return;
|
|
81
109
|
timer = setTimeout(() => {
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
onFire?.();
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
/* callback must not break the watchdog */
|
|
110
|
+
// Hold open (re-arm) while an interactive card blocks the turn — the
|
|
111
|
+
// human is thinking, not a stalled provider.
|
|
112
|
+
if (shouldSuppressFire?.()) {
|
|
113
|
+
arm();
|
|
114
|
+
return;
|
|
91
115
|
}
|
|
116
|
+
fire(onFire);
|
|
92
117
|
}, timeoutMs);
|
|
93
118
|
// Don't keep the event loop alive solely for the watchdog (Node).
|
|
94
119
|
timer.unref?.();
|
|
95
120
|
};
|
|
121
|
+
const armProgress = () => {
|
|
122
|
+
if (!progressEnabled)
|
|
123
|
+
return;
|
|
124
|
+
progressTimer = setTimeout(() => {
|
|
125
|
+
if (shouldSuppressFire?.()) {
|
|
126
|
+
armProgress();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
fire(progressOpts?.onProgressFire);
|
|
130
|
+
}, progressTimeoutMs);
|
|
131
|
+
progressTimer.unref?.();
|
|
132
|
+
};
|
|
96
133
|
const clear = () => {
|
|
97
134
|
if (timer) {
|
|
98
135
|
clearTimeout(timer);
|
|
99
136
|
timer = null;
|
|
100
137
|
}
|
|
101
138
|
};
|
|
139
|
+
const clearProgress = () => {
|
|
140
|
+
if (progressTimer) {
|
|
141
|
+
clearTimeout(progressTimer);
|
|
142
|
+
progressTimer = null;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
function clearBoth() {
|
|
146
|
+
clear();
|
|
147
|
+
clearProgress();
|
|
148
|
+
}
|
|
102
149
|
arm();
|
|
150
|
+
armProgress();
|
|
103
151
|
return {
|
|
104
152
|
signal: controller.signal,
|
|
105
153
|
pet() {
|
|
@@ -108,8 +156,15 @@ export function createStallWatchdog(timeoutMs, onFire) {
|
|
|
108
156
|
clear();
|
|
109
157
|
arm();
|
|
110
158
|
},
|
|
159
|
+
petProgress() {
|
|
160
|
+
if (!progressEnabled || firedFlag)
|
|
161
|
+
return;
|
|
162
|
+
clearProgress();
|
|
163
|
+
armProgress();
|
|
164
|
+
},
|
|
111
165
|
dispose() {
|
|
112
166
|
clear();
|
|
167
|
+
clearProgress();
|
|
113
168
|
},
|
|
114
169
|
fired() {
|
|
115
170
|
return firedFlag;
|
|
@@ -3,7 +3,6 @@ import { type ResolvedModelRuntime } from "../providers/runtime.js";
|
|
|
3
3
|
import type { ProviderId } from "../providers/types.js";
|
|
4
4
|
import { BashTool } from "../tools/bash.js";
|
|
5
5
|
import type { AgentMode, TaskRequest, ToolResult } from "../types/index.js";
|
|
6
|
-
import type { LegacyProvider } from "./agent-options.js";
|
|
7
6
|
import type { CrossTurnDedup } from "./cross-turn-dedup.js";
|
|
8
7
|
import type { ReadPathBudget } from "./read-path-budget.js";
|
|
9
8
|
/**
|
|
@@ -11,8 +10,6 @@ import type { ReadPathBudget } from "./read-path-budget.js";
|
|
|
11
10
|
* without holding a circular reference. Mirrors the CouncilManager DI pattern.
|
|
12
11
|
*/
|
|
13
12
|
export interface StreamRunnerDeps {
|
|
14
|
-
/** Current top-level provider instance (already validated). */
|
|
15
|
-
getProvider(): LegacyProvider;
|
|
16
13
|
/** Resolve a specific task tier's model id (uses Agent's role config). */
|
|
17
14
|
resolveModelForTask(task: "compact" | "explore" | "general" | "title" | "verify"): string;
|
|
18
15
|
/** Top-level model id (for routed_from telemetry). */
|
|
@@ -108,6 +105,19 @@ export type SetupOutcome = {
|
|
|
108
105
|
kind: "prepared";
|
|
109
106
|
prepared: PreparedSubAgentCall;
|
|
110
107
|
} | SetupShortCircuit;
|
|
108
|
+
/**
|
|
109
|
+
* Emit one sub-agent diagnostic line (MUONROI_DEBUG_SUBAGENT=1).
|
|
110
|
+
*
|
|
111
|
+
* Writes to the file named by MUONROI_SUBAGENT_DEBUG_LOG when set, else stderr.
|
|
112
|
+
* The file sink exists because stderr is a dead end for the case this
|
|
113
|
+
* diagnostic was written for: under the MCP harness the TUI runs as a child
|
|
114
|
+
* whose stderr nobody reads (opentui-spawn.ts consumes only the fd3/named-pipe
|
|
115
|
+
* stream), so every line went into a pipe no one drains. G1 — "Task failed: No
|
|
116
|
+
* output generated" — was named, given this flag, and never diagnosed, because
|
|
117
|
+
* the diagnostic could not reach whoever turned it on. Mirrors the working
|
|
118
|
+
* MUONROI_COUNCIL_DEBUG_LOG sink in council/llm.ts.
|
|
119
|
+
*/
|
|
120
|
+
export declare function writeSubagentDebug(enabled: boolean, line: string): void;
|
|
111
121
|
/**
|
|
112
122
|
* StreamRunner — extracted sub-agent stream lifecycle.
|
|
113
123
|
*
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
// - C1 (DeepSeek cache split read) — onFinish normalization
|
|
26
26
|
// - C3 (cross-turn dedup wrap) — wrapToolSetWithDedup
|
|
27
27
|
// - F1 (sub-agent cumulative cap) — wrapToolSetWithCap
|
|
28
|
-
// -
|
|
28
|
+
// - reasoning-strip (provider quirk) — taskCaps.sanitizeHistory
|
|
29
|
+
import { appendFileSync } from "node:fs";
|
|
29
30
|
import { stepCountIs, streamText } from "ai";
|
|
30
31
|
import { recordArtifact } from "../ee/artifact-cache.js";
|
|
31
32
|
import { getDefaultEEClient } from "../ee/intercept.js";
|
|
@@ -36,14 +37,14 @@ import { injectCheapModelWorkbook, shouldInjectCheapModelWorkbook, subagentTaskT
|
|
|
36
37
|
import { getProviderCapabilities } from "../providers/capabilities.js";
|
|
37
38
|
import { getVisionGuidanceForTextOnly } from "../providers/mcp-vision-bridge.js";
|
|
38
39
|
import { captureToolSchemas } from "../providers/patch-zod-schema.js";
|
|
39
|
-
import { buildTurnProviderOptions, requireRuntimeProvider, resolveModelRuntime, shouldDropParam, } from "../providers/runtime.js";
|
|
40
|
+
import { buildTurnProviderOptions, factoryForModel, requireRuntimeProvider, resolveModelRuntime, resolveTemperatureParam, shouldDropParam, } from "../providers/runtime.js";
|
|
40
41
|
import { needsVisionProxy } from "../providers/vision-proxy.js";
|
|
41
42
|
import { wireDebug } from "../providers/wire-debug.js";
|
|
43
|
+
import { statusBarStore } from "../state/status-bar-store.js";
|
|
42
44
|
import { BashTool } from "../tools/bash.js";
|
|
43
45
|
import { createBuiltinTools } from "../tools/registry.js";
|
|
44
|
-
import { statusBarStore } from "../ui/status-bar/store.js";
|
|
45
46
|
import { openUrl } from "../utils/open-url.js";
|
|
46
|
-
import { getCurrentShellSettings, getProviderStallTimeoutMs, getSubAgentBudgetChars, getSubAgentCompactKeepLast, getSubAgentCompactThresholdChars, loadMcpServers, loadValidSubAgents, } from "../utils/settings.js";
|
|
47
|
+
import { getCurrentShellSettings, getProviderProgressTimeoutMs, getProviderStallTimeoutMs, getSubAgentBudgetChars, getSubAgentCompactKeepLast, getSubAgentCompactThresholdChars, loadMcpServers, loadValidSubAgents, } from "../utils/settings.js";
|
|
47
48
|
import { resolveShell } from "../utils/shell.js";
|
|
48
49
|
import { prepareVerifySandbox } from "../verify/entrypoint.js";
|
|
49
50
|
import { asNumber } from "./batch-utils.js";
|
|
@@ -58,8 +59,37 @@ import { attachReminderToMessages, buildScopeReminder, cadenceForSize, shouldInj
|
|
|
58
59
|
import { recordCompaction, recordElision } from "./session-experience.js";
|
|
59
60
|
import { createStallWatchdog, STALL_ERROR_MESSAGE } from "./stall-watchdog.js";
|
|
60
61
|
import { wrapToolSetWithCap } from "./sub-agent-cap.js";
|
|
61
|
-
import {
|
|
62
|
+
import { applyAnthropicPromptCaching, compactSubAgentMessages } from "./subagent-compactor.js";
|
|
62
63
|
import { combineAbortSignals, firstLine, formatSubagentActivity } from "./tool-utils.js";
|
|
64
|
+
/**
|
|
65
|
+
* Emit one sub-agent diagnostic line (MUONROI_DEBUG_SUBAGENT=1).
|
|
66
|
+
*
|
|
67
|
+
* Writes to the file named by MUONROI_SUBAGENT_DEBUG_LOG when set, else stderr.
|
|
68
|
+
* The file sink exists because stderr is a dead end for the case this
|
|
69
|
+
* diagnostic was written for: under the MCP harness the TUI runs as a child
|
|
70
|
+
* whose stderr nobody reads (opentui-spawn.ts consumes only the fd3/named-pipe
|
|
71
|
+
* stream), so every line went into a pipe no one drains. G1 — "Task failed: No
|
|
72
|
+
* output generated" — was named, given this flag, and never diagnosed, because
|
|
73
|
+
* the diagnostic could not reach whoever turned it on. Mirrors the working
|
|
74
|
+
* MUONROI_COUNCIL_DEBUG_LOG sink in council/llm.ts.
|
|
75
|
+
*/
|
|
76
|
+
export function writeSubagentDebug(enabled, line) {
|
|
77
|
+
if (!enabled)
|
|
78
|
+
return;
|
|
79
|
+
const text = `[subagent] ${line}\n`;
|
|
80
|
+
const path = process.env.MUONROI_SUBAGENT_DEBUG_LOG?.trim();
|
|
81
|
+
if (!path) {
|
|
82
|
+
process.stderr.write(text);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
appendFileSync(path, text);
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
// Never let diagnostics become the failure. Fall back to stderr and say why.
|
|
90
|
+
process.stderr.write(`[subagent] debug-log append failed (path=${path}): ${err instanceof Error ? err.message : String(err)}\n${text}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
63
93
|
/**
|
|
64
94
|
* StreamRunner — extracted sub-agent stream lifecycle.
|
|
65
95
|
*
|
|
@@ -81,7 +111,6 @@ export class StreamRunner {
|
|
|
81
111
|
* Returns either a prepared call or a short-circuit ToolResult.
|
|
82
112
|
*/
|
|
83
113
|
async setup(request, onActivity, signal) {
|
|
84
|
-
const provider = this.deps.getProvider();
|
|
85
114
|
const agentKey = String(request.agent);
|
|
86
115
|
const isExplore = agentKey === "explore";
|
|
87
116
|
const isGeneral = agentKey === "general";
|
|
@@ -137,23 +166,36 @@ export class StreamRunner {
|
|
|
137
166
|
});
|
|
138
167
|
// Resolve child model early so we can pass modelId to createBuiltinTools
|
|
139
168
|
// (needed for vision-proxy tools: analyze_image / ask_vision_proxy).
|
|
140
|
-
const childModelId = normalizeModelId(
|
|
141
|
-
?
|
|
142
|
-
:
|
|
143
|
-
?
|
|
144
|
-
:
|
|
145
|
-
?
|
|
146
|
-
:
|
|
169
|
+
const childModelId = normalizeModelId(request.modelId
|
|
170
|
+
? request.modelId
|
|
171
|
+
: isVision
|
|
172
|
+
? VISION_MODEL
|
|
173
|
+
: isComputer
|
|
174
|
+
? COMPUTER_MODEL
|
|
175
|
+
: custom
|
|
176
|
+
? custom.model
|
|
177
|
+
: this.deps.resolveModelForTask(isExplore ? "explore" : isVerify || isVerifyDetect || isVerifyManifest ? "verify" : "general"));
|
|
147
178
|
// Mirror the file-local `createTools` wrapper from orchestrator.ts —
|
|
148
179
|
// pass modelId so registry can inject analyze_image/ask_vision_proxy for
|
|
149
180
|
// text-only child models (needsVisionProxy).
|
|
150
|
-
const childBaseToolsRaw = createBuiltinTools(childBash, childMode, {
|
|
181
|
+
const childBaseToolsRaw = createBuiltinTools(childBash, childMode, {
|
|
182
|
+
modelId: childModelId,
|
|
183
|
+
sessionId: this.deps.getSessionId(),
|
|
184
|
+
});
|
|
151
185
|
// Wrap with the cumulative cap so the sub-agent's tool loop cannot
|
|
152
186
|
// accumulate unbounded tool_result tokens. See sub-agent-cap.ts for the
|
|
153
187
|
// tiered compression schedule. The cap is per-invocation; each sub-agent
|
|
154
188
|
// gets a fresh budget.
|
|
155
189
|
const subAgentCapBudget = getSubAgentBudgetChars();
|
|
156
|
-
const subAgentCap = wrapToolSetWithCap(childBaseToolsRaw, {
|
|
190
|
+
const subAgentCap = wrapToolSetWithCap(childBaseToolsRaw, {
|
|
191
|
+
maxCumulativeChars: subAgentCapBudget,
|
|
192
|
+
// Opt-out toggle (default ON). The cap dedups identical tool outputs by
|
|
193
|
+
// content hash; set MUONROI_SUBAGENT_CAP_DEDUP=0 to disable. Used by the
|
|
194
|
+
// B3 compaction E2E, where the harness re-processes each tool result and
|
|
195
|
+
// the self-dedup would otherwise collapse distinct reads into pointer
|
|
196
|
+
// stubs before cumulative history can grow enough to trigger compaction.
|
|
197
|
+
dedupRepeatOutputs: process.env.MUONROI_SUBAGENT_CAP_DEDUP !== "0",
|
|
198
|
+
});
|
|
157
199
|
// Phase C3: layer cross-turn dedup ON TOP of the per-invocation cap. The
|
|
158
200
|
// cap sees raw output (for accurate cumulative accounting); dedup sees
|
|
159
201
|
// the already-trimmed output that will actually reach the model.
|
|
@@ -176,12 +218,18 @@ export class StreamRunner {
|
|
|
176
218
|
if (childModelId !== topModelId) {
|
|
177
219
|
statusBarStore.setState({ routed_from: topModelId, model: childModelId });
|
|
178
220
|
}
|
|
221
|
+
// The vision branch must build its model from the CHILD model's own factory.
|
|
222
|
+
// It previously called the PARENT session's factory directly, so a sub-agent
|
|
223
|
+
// routed to another provider had its id POSTed to the parent's endpoint.
|
|
179
224
|
const childRuntime = isVision
|
|
180
|
-
? {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
225
|
+
? (() => {
|
|
226
|
+
const childFactory = factoryForModel(childModelId);
|
|
227
|
+
return {
|
|
228
|
+
...resolveModelRuntime(childModelId),
|
|
229
|
+
model: childFactory.responses?.(childModelId) ?? childFactory(childModelId),
|
|
230
|
+
};
|
|
231
|
+
})()
|
|
232
|
+
: resolveModelRuntime(childModelId);
|
|
185
233
|
const taskCaps = getProviderCapabilities(requireRuntimeProvider(childRuntime));
|
|
186
234
|
if (isComputer && !taskCaps.supportsClientTools(childRuntime.modelInfo)) {
|
|
187
235
|
return {
|
|
@@ -255,7 +303,7 @@ export class StreamRunner {
|
|
|
255
303
|
void signal;
|
|
256
304
|
const childMessages = [{ role: "user", content: childPrompt }];
|
|
257
305
|
// The main agent manages its sub-agents, so don't apply an arbitrary hard limit.
|
|
258
|
-
const maxSteps = request.maxToolRounds ??
|
|
306
|
+
const maxSteps = request.maxToolRounds ?? this.deps.getMaxToolRounds() * 2;
|
|
259
307
|
// F1 parity — derive per-turn providerOptions so the sub-agent OpenAI calls
|
|
260
308
|
// carry a stable session-derived promptCacheKey (every tool round routes to
|
|
261
309
|
// the same cache node, keeping the unchanging prefix cached). The top-level
|
|
@@ -308,10 +356,7 @@ export class StreamRunner {
|
|
|
308
356
|
// diagnose "No output generated" / silent task failures (e.g. with
|
|
309
357
|
// gpt-5.4 reasoning models). Disabled by default — zero cost.
|
|
310
358
|
const debugSubagent = process.env.MUONROI_DEBUG_SUBAGENT === "1";
|
|
311
|
-
const debugLog = (
|
|
312
|
-
if (debugSubagent)
|
|
313
|
-
process.stderr.write(`[subagent] ${line}\n`);
|
|
314
|
-
};
|
|
359
|
+
const debugLog = writeSubagentDebug.bind(null, debugSubagent);
|
|
315
360
|
if (debugSubagent) {
|
|
316
361
|
const mi = childRuntime.modelInfo;
|
|
317
362
|
debugLog(`start: model=${childRuntime.modelId} provider=${mi?.provider} reasoning=${mi?.reasoning} thinkingType=${mi?.thinkingType} supportsClientTools=${mi?.supportsClientTools} supportsMaxOutputTokens=${mi?.supportsMaxOutputTokens} agent=${prepared.request.agent}`);
|
|
@@ -328,7 +373,6 @@ export class StreamRunner {
|
|
|
328
373
|
// already strips it via `dropParam`, the sub-agent path was missing
|
|
329
374
|
// the same guard, causing G1: "Task failed: No output generated.").
|
|
330
375
|
const childDropMaxOutput = shouldDropParam(childRuntime, "maxOutputTokens");
|
|
331
|
-
const childDropTemperature = shouldDropParam(childRuntime, "temperature");
|
|
332
376
|
// Phase B3: compact older tool_results out of the running message history
|
|
333
377
|
// before each AI SDK step. First step (stepNumber === 0) has no history
|
|
334
378
|
// worth compacting; later steps are where cumulative input balloons.
|
|
@@ -346,8 +390,8 @@ export class StreamRunner {
|
|
|
346
390
|
providerOptions: childProviderOptions,
|
|
347
391
|
});
|
|
348
392
|
}
|
|
349
|
-
//
|
|
350
|
-
// `reasoning` parts (HTTP 400 code 20015).
|
|
393
|
+
// Some DeepSeek thinking-mode endpoints reject assistant history with
|
|
394
|
+
// `reasoning` parts (HTTP 400 code 20015). A provider capability
|
|
351
395
|
// override strips them; every other provider's capability is identity.
|
|
352
396
|
const subMessagesForCall = taskCaps.sanitizeHistory(childMessages);
|
|
353
397
|
// Phase 4 Plan 04 (4B) — mirror top-level scope-ceiling integration.
|
|
@@ -377,8 +421,26 @@ export class StreamRunner {
|
|
|
377
421
|
// and is re-armed by stall.pet() on every chunk. Cheap models (which run
|
|
378
422
|
// mostly as sub-agents via SAMR) hit this most.
|
|
379
423
|
let stallTriggered = false;
|
|
424
|
+
// Second timer (progressTimeoutMs) is the no-forward-progress guard: the
|
|
425
|
+
// stall timer re-arms on EVERY chunk — including a reasoning model's
|
|
426
|
+
// `reasoning-delta` chunks — so a sub-agent stuck in an endless
|
|
427
|
+
// chain-of-thought keeps petting it and it never fires (observed live
|
|
428
|
+
// 2026-07-10: a deepseek-v4-flash sprint sub-agent churned reasoning for
|
|
429
|
+
// 30+ min, 1.4M input tokens, ZERO text/tool output; the 2-min stall
|
|
430
|
+
// watchdog never tripped). The progress timer is reset ONLY by
|
|
431
|
+
// stall.petProgress() on real output (text-delta / tool-call), so a runaway
|
|
432
|
+
// reasoning loop is aborted while a legitimately long reasoning burst that
|
|
433
|
+
// DOES eventually emit output survives. Both timers abort the same signal
|
|
434
|
+
// and set stallTriggered, so the existing surface-and-return path handles it.
|
|
380
435
|
const stall = createStallWatchdog(getProviderStallTimeoutMs(), () => {
|
|
381
436
|
stallTriggered = true;
|
|
437
|
+
}, {
|
|
438
|
+
progressTimeoutMs: getProviderProgressTimeoutMs(),
|
|
439
|
+
onProgressFire: () => {
|
|
440
|
+
stallTriggered = true;
|
|
441
|
+
console.error(`[stream-runner] sub-agent aborted: no text/tool output for ${getProviderProgressTimeoutMs()}ms ` +
|
|
442
|
+
`(runaway reasoning / no forward progress) model=${childRuntime.modelId}`);
|
|
443
|
+
},
|
|
382
444
|
});
|
|
383
445
|
const result = streamText({
|
|
384
446
|
model: childRuntime.model,
|
|
@@ -396,11 +458,11 @@ export class StreamRunner {
|
|
|
396
458
|
prepareStep: ({ messages, stepNumber }) => {
|
|
397
459
|
if (stepNumber < 1)
|
|
398
460
|
return undefined;
|
|
399
|
-
//
|
|
400
|
-
//
|
|
401
|
-
//
|
|
402
|
-
//
|
|
403
|
-
//
|
|
461
|
+
// Internal multi-step loop: AI-SDK accumulates streamed reasoning
|
|
462
|
+
// parts into in-flight assistant history and re-POSTs them on the
|
|
463
|
+
// next step within the same streamText call — orchestrator-level
|
|
464
|
+
// strip at call setup never sees this. Strip per step too via the
|
|
465
|
+
// capability hook (identity for providers without the quirk).
|
|
404
466
|
const stripped = taskCaps.sanitizeHistory(messages);
|
|
405
467
|
// G1 + G2 — pass the sub-agent's model context window so the
|
|
406
468
|
// compactor can use a token-aware threshold and shrink the keep
|
|
@@ -428,17 +490,16 @@ export class StreamRunner {
|
|
|
428
490
|
break;
|
|
429
491
|
}
|
|
430
492
|
}
|
|
431
|
-
|
|
432
|
-
const persistSubArtifact = (toolCallId, toolName, fullContent, reason) => {
|
|
493
|
+
const persistSubArtifact = (toolCallId, toolName, fullContent, reason, summary) => {
|
|
433
494
|
// Local-first durable cache so ee_query rehydrates even when EE is down.
|
|
434
495
|
recordArtifact(toolCallId, toolName, fullContent);
|
|
435
|
-
recordElision(toolCallId, toolName, fullContent.length, stepNumber);
|
|
496
|
+
recordElision(toolCallId, toolName, fullContent.length, stepNumber, summary);
|
|
436
497
|
try {
|
|
437
498
|
getDefaultEEClient()
|
|
438
499
|
.extract({
|
|
439
500
|
transcript: fullContent.slice(0, 4000),
|
|
440
501
|
projectPath: process.cwd(),
|
|
441
|
-
meta: { source: "tool-artifact", toolCallId, toolName, reason },
|
|
502
|
+
meta: { source: "tool-artifact", toolCallId, toolName, reason, summary },
|
|
442
503
|
}, AbortSignal.timeout(600))
|
|
443
504
|
.catch(() => { });
|
|
444
505
|
}
|
|
@@ -494,7 +555,7 @@ export class StreamRunner {
|
|
|
494
555
|
return undefined;
|
|
495
556
|
return { messages: finalMessages };
|
|
496
557
|
},
|
|
497
|
-
...(
|
|
558
|
+
...resolveTemperatureParam(childRuntime, isExplore ? 0.2 : 0.5),
|
|
498
559
|
...(childDropMaxOutput ? {} : { maxOutputTokens: Math.min(this.deps.getMaxTokens(), 8_192) }),
|
|
499
560
|
...(childProviderOptions ? { providerOptions: childProviderOptions } : {}),
|
|
500
561
|
onFinish: ({ totalUsage, finishReason }) => {
|
|
@@ -557,6 +618,7 @@ export class StreamRunner {
|
|
|
557
618
|
});
|
|
558
619
|
}
|
|
559
620
|
if (part.type === "text-delta") {
|
|
621
|
+
stall.petProgress(); // real forward progress — reset the no-progress guard
|
|
560
622
|
textDeltaCount++;
|
|
561
623
|
assistantText += part.text;
|
|
562
624
|
// Task 2.6b — emit llm-token (agent-mode only; high-volume, default-off per Phase 4).
|
|
@@ -576,6 +638,7 @@ export class StreamRunner {
|
|
|
576
638
|
continue;
|
|
577
639
|
}
|
|
578
640
|
if (part.type === "tool-call") {
|
|
641
|
+
stall.petProgress(); // real forward progress — reset the no-progress guard
|
|
579
642
|
toolCallCount++;
|
|
580
643
|
lastActivity = formatSubagentActivity(part.toolName, part.input);
|
|
581
644
|
onActivity?.(lastActivity);
|
|
@@ -653,7 +716,9 @@ export class StreamRunner {
|
|
|
653
716
|
...priorMessages,
|
|
654
717
|
{
|
|
655
718
|
role: "user",
|
|
656
|
-
content: "You've reached your
|
|
719
|
+
content: "You've reached your tool execution budget (max steps) for this turn and have not written your final answer yet. Stop now — do NOT call any more tools.\n\n" +
|
|
720
|
+
"Option A: If you have enough findings, write your final synthesis FOR THE PARENT AGENT: lead with the answer to the delegated task, cite the concrete file:line behind each claim, then note any gaps or the recommended next step. Be concise; the parent only ingests this message.\n\n" +
|
|
721
|
+
"Option B: If you need to continue working but are blocked by this limit, you can request the system to compact the context and start a fresh turn. To do this, reply with EXACTLY this format and nothing else:\n/compact <instructions on what to focus on after compaction>",
|
|
657
722
|
},
|
|
658
723
|
],
|
|
659
724
|
tools: {},
|
|
@@ -756,30 +821,31 @@ export class StreamRunner {
|
|
|
756
821
|
// MUONROI_DEBUG_SUBAGENT=1 so we can see whether `msg` is "No output
|
|
757
822
|
// generated" (AI SDK validation failure on empty assistant response)
|
|
758
823
|
// or a deeper provider error.
|
|
759
|
-
|
|
824
|
+
const debugCatch = process.env.MUONROI_DEBUG_SUBAGENT === "1";
|
|
825
|
+
if (debugCatch) {
|
|
760
826
|
const e = err;
|
|
761
|
-
|
|
827
|
+
writeSubagentDebug(true, `catch: name=${e.name ?? "?"} statusCode=${e.statusCode ?? "?"} message=${(e.message ?? "").slice(0, 400)}`);
|
|
762
828
|
if (e.cause !== undefined) {
|
|
763
829
|
try {
|
|
764
|
-
|
|
830
|
+
writeSubagentDebug(true, `catch.cause=${JSON.stringify(e.cause, Object.getOwnPropertyNames(e.cause)).slice(0, 600)}`);
|
|
765
831
|
}
|
|
766
|
-
catch {
|
|
767
|
-
|
|
832
|
+
catch (jsonErr) {
|
|
833
|
+
writeSubagentDebug(true, `catch.cause(string)=${String(e.cause).slice(0, 400)} [stringify failed: ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}]`);
|
|
768
834
|
}
|
|
769
835
|
}
|
|
770
836
|
if (e.responseBody !== undefined) {
|
|
771
|
-
|
|
837
|
+
writeSubagentDebug(true, `catch.responseBody=${String(e.responseBody).slice(0, 600)}`);
|
|
772
838
|
}
|
|
773
839
|
if (e.data !== undefined) {
|
|
774
840
|
try {
|
|
775
|
-
|
|
841
|
+
writeSubagentDebug(true, `catch.data=${JSON.stringify(e.data).slice(0, 400)}`);
|
|
776
842
|
}
|
|
777
|
-
catch {
|
|
778
|
-
|
|
843
|
+
catch (jsonErr) {
|
|
844
|
+
writeSubagentDebug(true, `catch.data(unserializable): ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}`);
|
|
779
845
|
}
|
|
780
846
|
}
|
|
781
847
|
if (e.stack)
|
|
782
|
-
|
|
848
|
+
writeSubagentDebug(true, `stack: ${e.stack.split("\n").slice(0, 6).join(" | ")}`);
|
|
783
849
|
}
|
|
784
850
|
const output = `Task failed: ${msg}`;
|
|
785
851
|
return {
|
|
@@ -18,7 +18,19 @@
|
|
|
18
18
|
* returns a fresh wrapper with its own counters. Don't share across
|
|
19
19
|
* sub-agent runs.
|
|
20
20
|
*
|
|
21
|
-
*
|
|
21
|
+
* BUDGET SOURCE — do not read the 120_000 below as "the sub-agent budget".
|
|
22
|
+
* DEFAULT_MAX_CUMULATIVE_CHARS (120_000) is only the fallback used when
|
|
23
|
+
* wrapToolSetWithCap() is called WITHOUT maxCumulativeChars. The wired
|
|
24
|
+
* budgets come from settings, not this constant:
|
|
25
|
+
* - sub-agent (`task`) turns: getSubAgentBudgetChars() → default 240_000
|
|
26
|
+
* (settings.ts), passed at stream-runner.ts.
|
|
27
|
+
* - top-level orchestrator turn: getTopLevelToolBudgetChars() → default
|
|
28
|
+
* 400_000, wired at tool-engine.ts with looser 0.5/0.8 tier ratios.
|
|
29
|
+
* See docs/agent-harness/CONTEXT-CONTROL-LAYERS.md for how this cap relates
|
|
30
|
+
* to the other four context-control layers (compactor, rotation, reactive
|
|
31
|
+
* sub-session, top-level cap).
|
|
32
|
+
*
|
|
33
|
+
* Tiers (percentages of whichever budget is in effect, NOT of 120_000):
|
|
22
34
|
* < 30% → pass through (A1's 32KB per-call cap already applied)
|
|
23
35
|
* 30-70% → truncate each new result to 8_000 chars head/tail
|
|
24
36
|
* 70-100% → truncate to 2_000 chars head + "[budget low, finalize work]" note
|
|
@@ -18,13 +18,28 @@
|
|
|
18
18
|
* returns a fresh wrapper with its own counters. Don't share across
|
|
19
19
|
* sub-agent runs.
|
|
20
20
|
*
|
|
21
|
-
*
|
|
21
|
+
* BUDGET SOURCE — do not read the 120_000 below as "the sub-agent budget".
|
|
22
|
+
* DEFAULT_MAX_CUMULATIVE_CHARS (120_000) is only the fallback used when
|
|
23
|
+
* wrapToolSetWithCap() is called WITHOUT maxCumulativeChars. The wired
|
|
24
|
+
* budgets come from settings, not this constant:
|
|
25
|
+
* - sub-agent (`task`) turns: getSubAgentBudgetChars() → default 240_000
|
|
26
|
+
* (settings.ts), passed at stream-runner.ts.
|
|
27
|
+
* - top-level orchestrator turn: getTopLevelToolBudgetChars() → default
|
|
28
|
+
* 400_000, wired at tool-engine.ts with looser 0.5/0.8 tier ratios.
|
|
29
|
+
* See docs/agent-harness/CONTEXT-CONTROL-LAYERS.md for how this cap relates
|
|
30
|
+
* to the other four context-control layers (compactor, rotation, reactive
|
|
31
|
+
* sub-session, top-level cap).
|
|
32
|
+
*
|
|
33
|
+
* Tiers (percentages of whichever budget is in effect, NOT of 120_000):
|
|
22
34
|
* < 30% → pass through (A1's 32KB per-call cap already applied)
|
|
23
35
|
* 30-70% → truncate each new result to 8_000 chars head/tail
|
|
24
36
|
* 70-100% → truncate to 2_000 chars head + "[budget low, finalize work]" note
|
|
25
37
|
* ≥ 100% → return error stub that signals the agent to stop expanding scope
|
|
26
38
|
*/
|
|
27
39
|
import { createHash } from "node:crypto";
|
|
40
|
+
// Fallback ONLY — used when wrapToolSetWithCap gets no maxCumulativeChars.
|
|
41
|
+
// Real wired budgets are 240_000 (sub-agent) / 400_000 (top-level) from
|
|
42
|
+
// settings; see the header note. Keep this in sync only as the no-arg floor.
|
|
28
43
|
const DEFAULT_MAX_CUMULATIVE_CHARS = 120_000;
|
|
29
44
|
const DEFAULT_DEDUP_MIN_CHARS = 500;
|
|
30
45
|
const DEFAULT_MID_TIER_RATIO = 0.3;
|
|
@@ -9,5 +9,17 @@ export type TierLookup = (tier: "fast" | "balanced" | "premium", preferProvider?
|
|
|
9
9
|
* Resolve the model id for a task kind on a given provider. Walks the tier
|
|
10
10
|
* preference list, accepting only same-provider matches, and falls back to
|
|
11
11
|
* `fallbackModelId` (the parent model) when nothing matches.
|
|
12
|
+
*
|
|
13
|
+
* `opts.parentTier` (the top-level / parent model's tier) acts as a ceiling:
|
|
14
|
+
* a delegated sub-task never runs on a HIGHER tier than the parent. Without
|
|
15
|
+
* this cap, a `verify` sub-agent (prefs `["premium","balanced"]`) spawned from
|
|
16
|
+
* a flash (fast) parent silently promotes to premium — e.g. on a DeepSeek-only
|
|
17
|
+
* setup (no balanced model) every verify sub-agent lands on deepseek-v4-pro.
|
|
18
|
+
* The parent already did the hard thinking; the sub-task should not exceed it.
|
|
19
|
+
*
|
|
20
|
+
* The cap is skipped when `parentTier` is omitted (preserves legacy behavior
|
|
21
|
+
* for callers that have not been threaded yet).
|
|
12
22
|
*/
|
|
13
|
-
export declare function resolveModelForTask(task: ModelTaskKind, providerId: string, fallbackModelId: string, lookup?: TierLookup
|
|
23
|
+
export declare function resolveModelForTask(task: ModelTaskKind, providerId: string, fallbackModelId: string, lookup?: TierLookup, opts?: {
|
|
24
|
+
parentTier?: "fast" | "balanced" | "premium";
|
|
25
|
+
}): string;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* - verify : validation/verification → premium first; rigor matters
|
|
17
17
|
* more than cost here, so we do NOT downgrade by default.
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
19
|
+
import { getRoutedModelByTier } from "../router/peak-hour.js";
|
|
20
20
|
export const TASK_TIER_PREFS = {
|
|
21
21
|
compact: ["fast", "balanced"],
|
|
22
22
|
title: ["fast", "balanced"],
|
|
@@ -29,13 +29,27 @@ export const TASK_TIER_PREFS = {
|
|
|
29
29
|
// exists to perform. Mirrors council `verify` role preference.
|
|
30
30
|
verify: ["premium", "balanced"],
|
|
31
31
|
};
|
|
32
|
+
const TIER_RANK = { fast: 0, balanced: 1, premium: 2 };
|
|
32
33
|
/**
|
|
33
34
|
* Resolve the model id for a task kind on a given provider. Walks the tier
|
|
34
35
|
* preference list, accepting only same-provider matches, and falls back to
|
|
35
36
|
* `fallbackModelId` (the parent model) when nothing matches.
|
|
37
|
+
*
|
|
38
|
+
* `opts.parentTier` (the top-level / parent model's tier) acts as a ceiling:
|
|
39
|
+
* a delegated sub-task never runs on a HIGHER tier than the parent. Without
|
|
40
|
+
* this cap, a `verify` sub-agent (prefs `["premium","balanced"]`) spawned from
|
|
41
|
+
* a flash (fast) parent silently promotes to premium — e.g. on a DeepSeek-only
|
|
42
|
+
* setup (no balanced model) every verify sub-agent lands on deepseek-v4-pro.
|
|
43
|
+
* The parent already did the hard thinking; the sub-task should not exceed it.
|
|
44
|
+
*
|
|
45
|
+
* The cap is skipped when `parentTier` is omitted (preserves legacy behavior
|
|
46
|
+
* for callers that have not been threaded yet).
|
|
36
47
|
*/
|
|
37
|
-
export function resolveModelForTask(task, providerId, fallbackModelId, lookup =
|
|
48
|
+
export function resolveModelForTask(task, providerId, fallbackModelId, lookup = getRoutedModelByTier, opts) {
|
|
49
|
+
const ceilingRank = opts?.parentTier ? TIER_RANK[opts.parentTier] : undefined;
|
|
38
50
|
for (const tier of TASK_TIER_PREFS[task] ?? ["balanced"]) {
|
|
51
|
+
if (ceilingRank !== undefined && TIER_RANK[tier] > ceilingRank)
|
|
52
|
+
continue;
|
|
39
53
|
const m = lookup(tier, providerId);
|
|
40
54
|
if (m?.provider === providerId)
|
|
41
55
|
return m.id;
|