muonroi-cli 1.8.4 → 1.8.5
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-tee.d.ts +48 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +77 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +11 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +87 -15
- package/dist/packages/agent-harness-core/src/protocol.d.ts +66 -2
- 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 +28 -0
- package/dist/src/agent-harness/mock-model.js +63 -1
- package/dist/src/agent-harness/test-spawn.js +31 -0
- 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 +2 -2
- package/dist/src/cli/keys.js +19 -81
- package/dist/src/council/clarifier.d.ts +28 -2
- package/dist/src/council/clarifier.js +81 -15
- 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 +51 -3
- 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 +1210 -134
- package/dist/src/council/index.d.ts +85 -1
- package/dist/src/council/index.js +634 -196
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +32 -0
- package/dist/src/council/llm.js +231 -38
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +72 -0
- package/dist/src/council/planner.js +23 -0
- package/dist/src/council/preflight.d.ts +7 -0
- package/dist/src/council/preflight.js +14 -2
- package/dist/src/council/prompts.d.ts +30 -3
- package/dist/src/council/prompts.js +234 -64
- 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 +128 -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 +1 -0
- package/dist/src/ee/auth.js +15 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +81 -18
- 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 +45 -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 +13 -1
- package/dist/src/flow/compaction/index.js +70 -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/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 +55 -0
- package/dist/src/gsd/flags.js +83 -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 +251 -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/hooks/index.js +1 -1
- package/dist/src/index.js +44 -11
- 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 +1 -1
- package/dist/src/mcp/ee-tools.js +1 -0
- package/dist/src/mcp/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -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/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 +10 -0
- package/dist/src/orchestrator/compaction.js +27 -7
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +65 -24
- 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/message-processor.js +242 -33
- package/dist/src/orchestrator/orchestrator.d.ts +39 -3
- package/dist/src/orchestrator/orchestrator.js +651 -102
- package/dist/src/orchestrator/preprocessor.js +1 -1
- 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-intercept.d.ts +45 -0
- package/dist/src/orchestrator/safety-intercept.js +55 -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 +24 -3
- package/dist/src/orchestrator/stall-watchdog.js +47 -13
- package/dist/src/orchestrator/stream-runner.js +62 -29
- 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 +22 -0
- package/dist/src/orchestrator/tool-engine.js +620 -56
- 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 +37 -0
- package/dist/src/orchestrator/turn-watchdog.js +55 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +1 -1
- 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.js +16 -11
- 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/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 +33 -2
- package/dist/src/pil/llm-classify.js +123 -131
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +1 -0
- package/dist/src/pil/pipeline.js +34 -2
- 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/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- 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.js +32 -3
- package/dist/src/product-loop/discovery-schema.js +5 -1
- 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 +333 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +310 -99
- package/dist/src/product-loop/phase-plan.d.ts +5 -0
- package/dist/src/product-loop/phase-plan.js +39 -2
- package/dist/src/product-loop/phase-runner.js +9 -1
- package/dist/src/product-loop/sprint-runner.d.ts +111 -0
- package/dist/src/product-loop/sprint-runner.js +559 -16
- package/dist/src/product-loop/types.d.ts +36 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- 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/openai-oauth.js +1 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.js +4 -1
- package/dist/src/providers/auth/types.d.ts +1 -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/keychain.d.ts +1 -1
- package/dist/src/providers/keychain.js +7 -9
- 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 +27 -2
- package/dist/src/providers/runtime.js +78 -15
- 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 +280 -1
- 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/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 +3 -3
- 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 +284 -13
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/native-tools.js +5 -0
- package/dist/src/tools/registry.d.ts +3 -0
- package/dist/src/tools/registry.js +460 -22
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +118 -3
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- 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/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 +49 -15
- 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 +12 -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/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/containers/modals-layer.d.ts +2 -1
- 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/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/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 +12 -18
- 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/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/install-manager.js +2 -1
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +153 -5
- package/dist/src/utils/settings.js +233 -29
- 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 +1 -1
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +135 -132
- 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
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
// - A4 (tool_call write-ahead) — persistToolCallWriteAhead
|
|
49
49
|
// - A5 (message_seq write-ahead) — persistMessageWriteAhead
|
|
50
50
|
// - O1 (providerOptions shape forensics) — extractProviderOptionsShape
|
|
51
|
-
// -
|
|
51
|
+
// - reasoning-strip (provider quirk) — turnCaps.sanitizeHistory
|
|
52
52
|
import { getCachedAuthToken, getCachedServerBaseUrl } from "../ee/auth.js";
|
|
53
53
|
import { routeModel } from "../ee/bridge.js";
|
|
54
54
|
import { getMistakeDetector } from "../ee/mistake-detector.js";
|
|
@@ -57,20 +57,26 @@ import * as phaseTracker from "../ee/phase-tracker.js";
|
|
|
57
57
|
import { buildScope as buildScopeForVeto } from "../ee/scope.js";
|
|
58
58
|
import { fireTrajectoryEvent } from "../ee/session-trajectory.js";
|
|
59
59
|
import { getTenantId as getTenantIdForVeto } from "../ee/tenant.js";
|
|
60
|
+
import { assessComplexity } from "../gsd/complexity-assessor.js";
|
|
61
|
+
import { isComplexityAssessorEnabled, isGsdNativeEnabled, isPilGateEnrichEnabled } from "../gsd/flags.js";
|
|
62
|
+
import { getGsdLoopHost } from "../gsd/loop-host.js";
|
|
63
|
+
import { readState, syncWorkflowContext } from "../gsd/workflow-engine.js";
|
|
60
64
|
import { applyPilSuffix, getResponseToolSet, } from "../pil/index.js";
|
|
65
|
+
import { isContinuationPhrase } from "../pil/layer1-intent.js";
|
|
61
66
|
import { loadKeyForProvider } from "../providers/keychain.js";
|
|
62
67
|
import { getVisionGuidanceForTextOnly, } from "../providers/mcp-vision-bridge.js";
|
|
63
68
|
import { detectProviderForModel, resolveModelRuntime, } from "../providers/runtime.js";
|
|
64
|
-
import { needsVisionProxy, proxyVision } from "../providers/vision-proxy.js";
|
|
69
|
+
import { canHandleImagesForTextOnlyModel, needsVisionProxy, planImageHandlingForTextOnlyModel, proxyVision, } from "../providers/vision-proxy.js";
|
|
65
70
|
import { decideStepRouting, eeSamrGuidance, getStepRouterConfig } from "../router/step-router.js";
|
|
66
71
|
import { routerStore } from "../router/store.js";
|
|
67
|
-
import {
|
|
68
|
-
import { isDebugEnabled } from "../
|
|
69
|
-
import {
|
|
72
|
+
import { statusBarStore } from "../state/status-bar-store.js";
|
|
73
|
+
import { isDebugEnabled } from "../state/turn-trace.js";
|
|
74
|
+
import { getLastApprovedPlan, getNextMessageSequence, logInteraction, persistMessageWriteAhead, } from "../storage/index.js";
|
|
70
75
|
import { isProviderDisabled, loadValidSubAgents, } from "../utils/settings.js";
|
|
71
76
|
import { prepareTurnContext } from "./preprocessor.js";
|
|
72
77
|
import { applyModelConstraints, buildSystemPromptParts } from "./prompts.js";
|
|
73
78
|
import { parseBudgetOverride, resetSessionStep, } from "./scope-ceiling.js";
|
|
79
|
+
import { shouldRunGate } from "./should-run-gate.js";
|
|
74
80
|
import { executeToolEngine } from "./tool-engine.js";
|
|
75
81
|
/**
|
|
76
82
|
* F2 — approximate the char cost of the FIXED prompt envelope (system +
|
|
@@ -107,6 +113,50 @@ function computeEnvelopeChars(system, tools) {
|
|
|
107
113
|
* guidance entries it stays informed until new entries arrive.
|
|
108
114
|
*/
|
|
109
115
|
const _injectedGuidanceSha = new Map();
|
|
116
|
+
/**
|
|
117
|
+
* Single-shot leader-tier LLM runner for the GSD complexity assessor
|
|
118
|
+
* (Task 4 `assessComplexity`). Mirrors the orchestrator's own council LLM
|
|
119
|
+
* construction (`createCouncilLLM` — see `runCouncil` / `runProductLoop` in
|
|
120
|
+
* orchestrator.ts) so the assessor call auto-records usage as
|
|
121
|
+
* `source=council` (no cost-leak) instead of a bespoke unaccounted call.
|
|
122
|
+
* Leader model resolution goes ONLY through `resolvePlanCouncilLeader` —
|
|
123
|
+
* Zero Hardcode Rule, no literal model/provider IDs here.
|
|
124
|
+
*/
|
|
125
|
+
function buildLeaderAssessorRunner(deps, sessionModel) {
|
|
126
|
+
return async (prompt) => {
|
|
127
|
+
const { createCouncilLLM } = await import("../council/llm.js");
|
|
128
|
+
const { resolvePlanCouncilLeader } = await import("../council/leader.js");
|
|
129
|
+
const leader = await resolvePlanCouncilLeader(sessionModel);
|
|
130
|
+
const stats = { calls: 0, startMs: Date.now(), phases: [] };
|
|
131
|
+
const llm = createCouncilLLM(deps.bash, deps.mode, deps.session?.id, stats);
|
|
132
|
+
// Small budget — this is a single classification, not a synthesis.
|
|
133
|
+
return llm.generate(leader.modelId, "You are a task complexity assessor.", prompt, 512, undefined, AbortSignal.timeout(PIL_GATE_DEADLINE_MS));
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Turn-start PIL gate budget: the assessor + heavy-tier critics run BEFORE the
|
|
138
|
+
* model message is assembled, so they must be short — a slow gate call would
|
|
139
|
+
* delay every turn, not just heavy ones. `createCouncilLLM.generate` has no
|
|
140
|
+
* per-call timeout of its own (`llm.ts:331` defaults to 5 minutes), so this
|
|
141
|
+
* deadline is threaded explicitly as the `signal` arg on every gate call.
|
|
142
|
+
*/
|
|
143
|
+
const PIL_GATE_DEADLINE_MS = 2500;
|
|
144
|
+
/**
|
|
145
|
+
* Heavy-tier gate critic runner (Task 4 `runGateCritics`). Reuses the council
|
|
146
|
+
* LLM (billed `source=council`, no cost leak) with the same tight deadline as
|
|
147
|
+
* the assessor — three critics run in parallel via `Promise.all` inside
|
|
148
|
+
* `runGateCritics`, each individually bounded by this signal.
|
|
149
|
+
*/
|
|
150
|
+
function buildGateCriticRunner(deps, sessionModel) {
|
|
151
|
+
return async (prompt) => {
|
|
152
|
+
const { createCouncilLLM } = await import("../council/llm.js");
|
|
153
|
+
const { resolvePlanCouncilLeader } = await import("../council/leader.js");
|
|
154
|
+
const leader = await resolvePlanCouncilLeader(sessionModel);
|
|
155
|
+
const stats = { calls: 0, startMs: Date.now(), phases: [] };
|
|
156
|
+
const llm = createCouncilLLM(deps.bash, deps.mode, deps.session?.id, stats);
|
|
157
|
+
return llm.generate(leader.modelId, "You are a prompt-enrichment critic.", prompt, 512, undefined, AbortSignal.timeout(PIL_GATE_DEADLINE_MS));
|
|
158
|
+
};
|
|
159
|
+
}
|
|
110
160
|
/**
|
|
111
161
|
* MessageProcessor — extracted streaming turn loop.
|
|
112
162
|
*
|
|
@@ -316,6 +366,89 @@ export class MessageProcessor {
|
|
|
316
366
|
yield res.value;
|
|
317
367
|
}
|
|
318
368
|
const { pilCtx, _stepCeiling, _pilStart, _naturalCeiling, _ceilingTaskType, _ceilingSize } = prepResult;
|
|
369
|
+
const cwd = deps.bash.getCwd();
|
|
370
|
+
if (isGsdNativeEnabled() &&
|
|
371
|
+
shouldRunGate(pilCtx, () => {
|
|
372
|
+
try {
|
|
373
|
+
return readState(cwd).phase;
|
|
374
|
+
}
|
|
375
|
+
catch (err) {
|
|
376
|
+
// Missing/corrupt .planning state is the normal "no active run" case, not an error.
|
|
377
|
+
console.error(`[pil-gate] readState failed while checking resume phase (treating as no active run): ${err.message}`);
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
})) {
|
|
381
|
+
try {
|
|
382
|
+
const sessionModel = deps.session?.model ?? "unknown";
|
|
383
|
+
let depth = pilCtx.modelDepthTier ?? pilCtx.complexityTier ?? "standard";
|
|
384
|
+
// Leader-tier assessor enrichment: OVERRIDES the fast-classifier depth
|
|
385
|
+
// before it's written to SDK STATE.md. `assessComplexity` itself never
|
|
386
|
+
// throws (every internal step is caught, degrading to `priorDepth`),
|
|
387
|
+
// but this inner try/catch is defensive fail-open insurance so even an
|
|
388
|
+
// unexpected throw here keeps `depth` at its fast-classifier value —
|
|
389
|
+
// syncWorkflowContext below is never skipped because of the assessor.
|
|
390
|
+
let brief = "";
|
|
391
|
+
if (isComplexityAssessorEnabled()) {
|
|
392
|
+
try {
|
|
393
|
+
const { buildGateContextBundle } = await import("../gsd/pil-gate-context.js");
|
|
394
|
+
const bundle = buildGateContextBundle({
|
|
395
|
+
cwd,
|
|
396
|
+
conversationDigest: deps.buildRecentTurnsSummary(),
|
|
397
|
+
brainData: pilCtx._brainData,
|
|
398
|
+
});
|
|
399
|
+
const assessed = await assessComplexity({
|
|
400
|
+
cwd,
|
|
401
|
+
raw: pilCtx.raw,
|
|
402
|
+
priorDepth: depth,
|
|
403
|
+
confidence: pilCtx.confidence,
|
|
404
|
+
bundle,
|
|
405
|
+
sessionModelId: sessionModel,
|
|
406
|
+
runAssessor: buildLeaderAssessorRunner(deps, sessionModel), // single-shot leader call
|
|
407
|
+
});
|
|
408
|
+
depth = assessed.depth;
|
|
409
|
+
// Keep the native depth slot authoritative: write the assessed depth
|
|
410
|
+
// back to pilCtx.modelDepthTier so every downstream consumer that reads
|
|
411
|
+
// it (tool-engine depthTier -> gsd tool registration + gsd_verify depth
|
|
412
|
+
// + layer-derived tiering) sees the SAME value the mutation gate reads
|
|
413
|
+
// from STATE.md. Without this, the gate (readState().depth) and gsd_verify
|
|
414
|
+
// (pilCtx.modelDepthTier) diverge on any assessor override. Same pilCtx
|
|
415
|
+
// ref, and this block runs before executeToolEngine in the same turn.
|
|
416
|
+
pilCtx.modelDepthTier = depth;
|
|
417
|
+
if (assessed.assessed)
|
|
418
|
+
pilCtx.gsdAutoCouncil = assessed.autoCouncil;
|
|
419
|
+
if (isPilGateEnrichEnabled() && assessed.enrichedPrompt) {
|
|
420
|
+
let verdict = assessed.quality?.verdict ?? "enriched";
|
|
421
|
+
brief = assessed.enrichedPrompt;
|
|
422
|
+
if (depth === "heavy") {
|
|
423
|
+
const { runGateCritics } = await import("../gsd/pil-gate-critic.js");
|
|
424
|
+
const critiqued = await runGateCritics({
|
|
425
|
+
draftBrief: brief,
|
|
426
|
+
draftVerdict: verdict,
|
|
427
|
+
bundle,
|
|
428
|
+
runCritic: buildGateCriticRunner(deps, sessionModel),
|
|
429
|
+
});
|
|
430
|
+
verdict = critiqued.verdict;
|
|
431
|
+
brief = critiqued.brief;
|
|
432
|
+
}
|
|
433
|
+
if (verdict === "adequate")
|
|
434
|
+
brief = "";
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
catch (assessErr) {
|
|
438
|
+
brief = "";
|
|
439
|
+
console.error(`[pil-gate] enrichment failed, using raw prompt: ${assessErr.message}`);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (brief) {
|
|
443
|
+
pilCtx.enriched = `[PIL Gate brief]\n${brief.slice(0, 1500)}\n\n${pilCtx.enriched}`;
|
|
444
|
+
}
|
|
445
|
+
getGsdLoopHost().ensureHost(cwd, sessionModel);
|
|
446
|
+
syncWorkflowContext(cwd, sessionModel, depth);
|
|
447
|
+
}
|
|
448
|
+
catch (err) {
|
|
449
|
+
console.error(`[gsd-loop-host] turn sync failed: ${err.message}`);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
319
452
|
// Track whether forced-finalize is needed (set by stopWhen when the
|
|
320
453
|
// ceiling fires). Read AFTER the streamText fullStream finishes.
|
|
321
454
|
const _ceilingHit = false;
|
|
@@ -332,8 +465,8 @@ export class MessageProcessor {
|
|
|
332
465
|
enrichedMessage = `[PIL fallback: ${pilCtx.fallbackReason} — classification/routing may be inaccurate or layers skipped; using raw input.]\n\n${enrichedMessage}`;
|
|
333
466
|
}
|
|
334
467
|
deps.setPilActive(pilCtx.taskType !== null);
|
|
335
|
-
deps.setPilEnrichmentDelta(pilCtx.metrics?.suffixInstructionTokens ?? Math.round((enrichedMessage.length - userMessage.length) / 4));
|
|
336
|
-
const _pilEnrichmentDeltaSnapshot = pilCtx.metrics?.suffixInstructionTokens ?? Math.round((enrichedMessage.length - userMessage.length) / 4);
|
|
468
|
+
deps.setPilEnrichmentDelta(pilCtx.metrics?.suffixInstructionTokens ?? Math.round(((enrichedMessage ?? "").length - userMessage.length) / 4));
|
|
469
|
+
const _pilEnrichmentDeltaSnapshot = pilCtx.metrics?.suffixInstructionTokens ?? Math.round(((enrichedMessage ?? "").length - userMessage.length) / 4);
|
|
337
470
|
// P1 Item 3 wiring: phase-boundary detection. setPhase returns a snapshot
|
|
338
471
|
// of the prior phase iff the phase NAME just changed. We classify the
|
|
339
472
|
// outcome (pass/fail/abandoned/null) and fire phase-outcome to the EE
|
|
@@ -423,9 +556,17 @@ export class MessageProcessor {
|
|
|
423
556
|
const turnStartMs = Date.now();
|
|
424
557
|
let turnModelId = deps.modelId;
|
|
425
558
|
let taskHash = null;
|
|
559
|
+
let routeReason = null;
|
|
560
|
+
const historyHasImages = deps.messages.some((m) => Array.isArray(m.content) && m.content.some((p) => p.type === "image"));
|
|
561
|
+
const turnHasImages = (images?.length ?? 0) > 0;
|
|
562
|
+
let visionUnavailableNotice = null;
|
|
426
563
|
const _routeStart = Date.now();
|
|
427
564
|
try {
|
|
428
565
|
const { decide } = await import("../router/decide.js");
|
|
566
|
+
const compactionMsg = deps.messages.find((m) => typeof m.content === "string" && m.content.startsWith("[Context checkpoint summary]"));
|
|
567
|
+
const compactionSummary = compactionMsg && typeof compactionMsg.content === "string"
|
|
568
|
+
? compactionMsg.content.slice("[Context checkpoint summary]".length).trim()
|
|
569
|
+
: null;
|
|
429
570
|
const routeDecision = await decide(userMessage, {
|
|
430
571
|
tenantId: "local",
|
|
431
572
|
cwd: deps.bash.getCwd(),
|
|
@@ -441,6 +582,11 @@ export class MessageProcessor {
|
|
|
441
582
|
projectSize: deps.estimateProjectSize(),
|
|
442
583
|
filesTouched: deps.countFilesTouched(),
|
|
443
584
|
mode: deps.mode,
|
|
585
|
+
turnIndex: deps.messages.filter((m) => m.role === "user").length,
|
|
586
|
+
messageCount: deps.messages.length,
|
|
587
|
+
compactionCount: deps.getCompactionStats().count,
|
|
588
|
+
totalSavedTokens: deps.getCompactionStats().totalSaved,
|
|
589
|
+
compactionSummary,
|
|
444
590
|
},
|
|
445
591
|
});
|
|
446
592
|
if (routeDecision.model && routeDecision.model !== "HALT") {
|
|
@@ -449,14 +595,15 @@ export class MessageProcessor {
|
|
|
449
595
|
// images to text, so there's no need to switch to a vision-capable
|
|
450
596
|
// (and usually pricier / rate-limited) model.
|
|
451
597
|
const defaultHasVisionProxy = needsVisionProxy(deps.modelId);
|
|
452
|
-
const
|
|
453
|
-
const
|
|
454
|
-
const skipVisionRoute = defaultHasVisionProxy &&
|
|
598
|
+
const imagesOnTurn = turnHasImages || historyHasImages;
|
|
599
|
+
const canHandleImages = !defaultHasVisionProxy || !imagesOnTurn || (await canHandleImagesForTextOnlyModel(deps.modelId));
|
|
600
|
+
const skipVisionRoute = defaultHasVisionProxy && imagesOnTurn && canHandleImages;
|
|
455
601
|
if (!skipVisionRoute) {
|
|
456
602
|
turnModelId = routeDecision.model;
|
|
457
603
|
}
|
|
458
604
|
}
|
|
459
605
|
taskHash = routeDecision.taskHash ?? null;
|
|
606
|
+
routeReason = routeDecision.reason ?? null;
|
|
460
607
|
// Update status bar with router switch info. Also reset back to the
|
|
461
608
|
// session default when the router does NOT switch on this turn —
|
|
462
609
|
// otherwise the bar stays "stuck" showing the previously-routed model
|
|
@@ -487,14 +634,39 @@ export class MessageProcessor {
|
|
|
487
634
|
taskHash = eeRoute?.taskHash ?? null;
|
|
488
635
|
}
|
|
489
636
|
}
|
|
637
|
+
if (needsVisionProxy(turnModelId) && (turnHasImages || historyHasImages)) {
|
|
638
|
+
const imageCount = turnHasImages ? images.length : 1;
|
|
639
|
+
const plan = await planImageHandlingForTextOnlyModel({
|
|
640
|
+
primaryModelId: turnModelId,
|
|
641
|
+
imageCount,
|
|
642
|
+
});
|
|
643
|
+
if (plan.strategy === "native_model") {
|
|
644
|
+
turnModelId = plan.fallback.modelId;
|
|
645
|
+
routeReason = routeReason ? `${routeReason}; vision-native-fallback` : "vision-native-fallback";
|
|
646
|
+
yield {
|
|
647
|
+
type: "content",
|
|
648
|
+
content: `[Vision: routed to ${plan.fallback.modelId} — no proxy backend; using native image support]\n`,
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
else if (plan.strategy === "unavailable") {
|
|
652
|
+
visionUnavailableNotice = plan.notice;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
490
655
|
// Interaction log: model routing
|
|
491
656
|
try {
|
|
492
657
|
if (deps.session) {
|
|
658
|
+
const promoted = turnModelId !== deps.modelId;
|
|
493
659
|
logInteraction(deps.session.id, "routing", {
|
|
494
660
|
model: turnModelId,
|
|
661
|
+
eventSubtype: promoted ? "promoted" : "default",
|
|
495
662
|
data: {
|
|
496
663
|
defaultModel: deps.modelId,
|
|
497
664
|
routedModel: turnModelId,
|
|
665
|
+
promoted,
|
|
666
|
+
// promo-cap(...) tag appears here when the promotion ceiling clamped
|
|
667
|
+
// an EE premium pick down to balanced — queryable via event_subtype +
|
|
668
|
+
// data.reason to audit cost-leak prevention (session 89b34ce9a4e8 class).
|
|
669
|
+
reason: routeReason,
|
|
498
670
|
taskHash,
|
|
499
671
|
pilTaskType: pilCtx.taskType ?? null,
|
|
500
672
|
pilIntentKind: pilCtx.intentKind ?? null,
|
|
@@ -566,10 +738,38 @@ export class MessageProcessor {
|
|
|
566
738
|
// still carry image parts — otherwise sending the conversation back to a
|
|
567
739
|
// text-only provider (e.g. DeepSeek) fails with "unknown variant
|
|
568
740
|
// `image_url`" once history contains an image from a prior turn.
|
|
569
|
-
if (needsVisionProxy(turnModelId)) {
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
|
|
741
|
+
if (needsVisionProxy(turnModelId) && (turnHasImages || historyHasImages)) {
|
|
742
|
+
const stripImagesFromMessages = (msgs) => msgs.map((m) => {
|
|
743
|
+
if (!Array.isArray(m.content))
|
|
744
|
+
return m;
|
|
745
|
+
const textParts = m.content.filter((p) => p.type === "text");
|
|
746
|
+
const joined = textParts.map((p) => p.text ?? "").join("\n");
|
|
747
|
+
return { ...m, content: joined || "[image removed — vision unavailable]" };
|
|
748
|
+
});
|
|
749
|
+
if (visionUnavailableNotice) {
|
|
750
|
+
yield {
|
|
751
|
+
type: "content",
|
|
752
|
+
content: "[Vision: cannot analyze images — no vision API key or vision model available]\n",
|
|
753
|
+
};
|
|
754
|
+
if (historyHasImages) {
|
|
755
|
+
deps.setMessages(stripImagesFromMessages(deps.messages).map((m) => {
|
|
756
|
+
if (m.role !== "user" || typeof m.content !== "string")
|
|
757
|
+
return m;
|
|
758
|
+
return { ...m, content: `${m.content}\n\n${visionUnavailableNotice}` };
|
|
759
|
+
}));
|
|
760
|
+
}
|
|
761
|
+
if (turnHasImages) {
|
|
762
|
+
userModelMessage = {
|
|
763
|
+
role: "user",
|
|
764
|
+
content: `${messageForDb}\n\n${visionUnavailableNotice}`,
|
|
765
|
+
};
|
|
766
|
+
userEnrichedMessage = {
|
|
767
|
+
role: "user",
|
|
768
|
+
content: `${messageForModel}\n\n${visionUnavailableNotice}`,
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
else {
|
|
573
773
|
try {
|
|
574
774
|
if (historyHasImages) {
|
|
575
775
|
const historyResult = await proxyVision(deps.messages, turnModelId, signal);
|
|
@@ -588,25 +788,23 @@ export class MessageProcessor {
|
|
|
588
788
|
userEnrichedMessage = proxyResult.messages[1];
|
|
589
789
|
yield {
|
|
590
790
|
type: "content",
|
|
591
|
-
content: `[Vision proxy: ${proxyResult.imageCount} image(s)
|
|
791
|
+
content: `[Vision proxy: ${proxyResult.imageCount} image(s) analyzed for ${turnModelId}]\n`,
|
|
592
792
|
};
|
|
593
793
|
}
|
|
594
794
|
}
|
|
595
795
|
}
|
|
596
|
-
catch {
|
|
597
|
-
|
|
796
|
+
catch (err) {
|
|
797
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
798
|
+
console.warn(`[vision-proxy] message path failed: ${errMsg}`);
|
|
799
|
+
const notice = visionUnavailableNotice ?? `[vision unavailable: ${errMsg}]`;
|
|
800
|
+
yield { type: "content", content: "[Vision proxy: failed — images not sent to model]\n" };
|
|
801
|
+
if (historyHasImages) {
|
|
802
|
+
deps.setMessages(stripImagesFromMessages(deps.messages));
|
|
803
|
+
}
|
|
598
804
|
if (turnHasImages) {
|
|
599
|
-
userModelMessage = { role: "user", content: messageForDb };
|
|
600
|
-
userEnrichedMessage = { role: "user", content: messageForModel };
|
|
805
|
+
userModelMessage = { role: "user", content: `${messageForDb}\n\n${notice}` };
|
|
806
|
+
userEnrichedMessage = { role: "user", content: `${messageForModel}\n\n${notice}` };
|
|
601
807
|
}
|
|
602
|
-
// Strip image parts from history as a last-resort fallback so the
|
|
603
|
-
// request doesn't blow up at the provider serialization layer.
|
|
604
|
-
deps.setMessages(deps.messages.map((m) => {
|
|
605
|
-
if (!Array.isArray(m.content))
|
|
606
|
-
return m;
|
|
607
|
-
const filtered = m.content.filter((p) => p.type !== "image");
|
|
608
|
-
return { ...m, content: filtered };
|
|
609
|
-
}));
|
|
610
808
|
}
|
|
611
809
|
}
|
|
612
810
|
}
|
|
@@ -666,12 +864,13 @@ export class MessageProcessor {
|
|
|
666
864
|
.slice(0, 10)
|
|
667
865
|
.map((p) => ` - ee_feedback(id="${p.id}", collection="${p.collection ?? "?"}", verdict=followed|ignored|noise)`);
|
|
668
866
|
const more = pending.length > 10 ? `\n ...and ${pending.length - 10} more` : "";
|
|
669
|
-
const recallContent =
|
|
670
|
-
`
|
|
671
|
-
`
|
|
672
|
-
`Verdict: followed (you used
|
|
867
|
+
const recallContent = `↳ ${pending.length} earlier EE hint(s) still unrated. Rate the one(s) you actually ` +
|
|
868
|
+
`acted on so the brain keeps what helped — this does NOT block the task; batch the ` +
|
|
869
|
+
`ee_feedback call(s) alongside your work, don't stall the user's request on it.\n` +
|
|
870
|
+
`Verdict: followed (you used it) | ignored (topical, didn't apply) | noise (wrong — needs reason).\n` +
|
|
673
871
|
`${hintLines.join("\n")}${more}\n` +
|
|
674
|
-
`
|
|
872
|
+
`Rate once and move on — a hint you can't judge yet, leave for later; re-rating the same ` +
|
|
873
|
+
`id does not help. If the brain is unreachable the verdict is queued, so never retry-loop on it.`;
|
|
675
874
|
const sid = deps.session?.id ?? "_anon";
|
|
676
875
|
const { createHash: _recallHash } = await import("node:crypto");
|
|
677
876
|
const recallSha = _recallHash("sha256").update(recallContent).digest("hex").slice(0, 16);
|
|
@@ -749,7 +948,17 @@ export class MessageProcessor {
|
|
|
749
948
|
output_summary: stepRouterDecision.reason,
|
|
750
949
|
});
|
|
751
950
|
}
|
|
752
|
-
|
|
951
|
+
// Phase 5 continuation fix: do not clear planContext on bare "tiếp tục"/"continue".
|
|
952
|
+
// Re-hydrate from persisted approved plan if needed (cross-process or after abort).
|
|
953
|
+
const _isCont = isContinuationPhrase(userMessage);
|
|
954
|
+
if (!_isCont) {
|
|
955
|
+
deps.setPlanContext(null);
|
|
956
|
+
}
|
|
957
|
+
else if (!deps.getPlanContext()) {
|
|
958
|
+
const _p = getLastApprovedPlan(deps.session?.id ?? "");
|
|
959
|
+
if (_p)
|
|
960
|
+
deps.setPlanContext(_p);
|
|
961
|
+
}
|
|
753
962
|
const attemptedOverflowRecovery = false;
|
|
754
963
|
// Stream-retry state: track how many transient retries have been attempted
|
|
755
964
|
// for the current turn. Reset to 0 on each new user turn (we're in processMessage).
|
|
@@ -4,9 +4,13 @@ import { type ScheduleDaemonStatus, type StoredSchedule } from "../tools/schedul
|
|
|
4
4
|
import type { AgentMode, ChatEntry, SessionInfo, SessionSnapshot, StreamChunk, SubagentStatus, TaskListSnapshot, TaskRequest, ToolResult, VerifyRecipe } from "../types/index.js";
|
|
5
5
|
import { type SandboxMode, type SandboxSettings } from "../utils/settings.js";
|
|
6
6
|
import { type SideQuestionResult } from "../utils/side-question.js";
|
|
7
|
-
import { type AgentOptions, type ProcessMessageObserver } from "./agent-options.js";
|
|
7
|
+
import { type AgentOptions, type LegacyProvider, type ProcessMessageObserver } from "./agent-options.js";
|
|
8
8
|
import type { SafetyOverrideAskInfo, SafetyOverrideVerdict } from "./safety-askcard.js";
|
|
9
9
|
import type { ToolLoopCapAsk } from "./tool-loop-cap.js";
|
|
10
|
+
/** Deterministic fallback title: truncated first user message, or "" when the
|
|
11
|
+
* message is empty or a JSON-ish payload (so the caller leaves title = NULL
|
|
12
|
+
* and the picker renders a clean "(untitled)" instead of a literal "{}"). */
|
|
13
|
+
export declare function fallbackTitle(userMessage: string): string;
|
|
10
14
|
export declare class Agent {
|
|
11
15
|
private provider;
|
|
12
16
|
private providerId;
|
|
@@ -25,6 +29,8 @@ export declare class Agent {
|
|
|
25
29
|
private steerDrain;
|
|
26
30
|
private maxToolRounds;
|
|
27
31
|
private hardMaxToolRounds;
|
|
32
|
+
/** Original hard ceiling at construction — bounds auto-compaction extension. */
|
|
33
|
+
private _initialHardMaxToolRounds;
|
|
28
34
|
private mode;
|
|
29
35
|
private modelId;
|
|
30
36
|
private maxTokens;
|
|
@@ -83,6 +89,9 @@ export declare class Agent {
|
|
|
83
89
|
private _turnUserGoalExcerpt;
|
|
84
90
|
/** Compaction statistics tracking count and total tokens saved. */
|
|
85
91
|
private _compactionStats;
|
|
92
|
+
/** Token count immediately after the last successful compaction (or null if none yet this
|
|
93
|
+
* session). Used by the cross-turn anti-thrash guard in postTurnCompact. */
|
|
94
|
+
private _lastCompactionTokensAfter;
|
|
86
95
|
/**
|
|
87
96
|
* Pinned message sequences. A pinned user message is preserved verbatim across
|
|
88
97
|
* compaction — it is re-injected as a system note immediately after the
|
|
@@ -93,6 +102,8 @@ export declare class Agent {
|
|
|
93
102
|
/** One-shot cwd note injected at the start of the next processMessage turn after setCwd(). Cleared after injection. */
|
|
94
103
|
private _pendingCwdNote;
|
|
95
104
|
private _crossTurnDedup;
|
|
105
|
+
private _lastTurnToolChars;
|
|
106
|
+
private _turnLoadOrdinal;
|
|
96
107
|
private _readBudget;
|
|
97
108
|
constructor(apiKey: string | undefined, baseURL?: string, model?: string, maxToolRounds?: number, options?: AgentOptions);
|
|
98
109
|
/**
|
|
@@ -123,6 +134,12 @@ export declare class Agent {
|
|
|
123
134
|
setApiKey(apiKey: string, baseURL?: string): void;
|
|
124
135
|
setProviderAndKey(providerId: ProviderId, apiKey: string, baseURL?: string): void;
|
|
125
136
|
getProviderId(): ProviderId;
|
|
137
|
+
/**
|
|
138
|
+
* Expose the provider factory for external callers (e.g., /compact slash command,
|
|
139
|
+
* sub-agent spawning) that need to make LLM calls outside the normal processMessage flow.
|
|
140
|
+
* Throws if no provider is configured.
|
|
141
|
+
*/
|
|
142
|
+
getProvider(): LegacyProvider;
|
|
126
143
|
getCwd(): string;
|
|
127
144
|
setCwd(dir: string): void;
|
|
128
145
|
getMessages(): ModelMessage[];
|
|
@@ -143,6 +160,18 @@ export declare class Agent {
|
|
|
143
160
|
cleanup(): Promise<void>;
|
|
144
161
|
private _toolLoopCapHandler;
|
|
145
162
|
setToolLoopCapHandler(fn: ToolLoopCapAsk | null): void;
|
|
163
|
+
/**
|
|
164
|
+
* Extend the absolute hard-cap ceiling when the turn is being sustained by
|
|
165
|
+
* AUTO-COMPACTION (a productive long task, not a runaway). Rationale: each
|
|
166
|
+
* auto-compacted round resets context to O(N) input, so it is cheap — the
|
|
167
|
+
* hard cap's cost-runaway purpose is already served by the compaction. We
|
|
168
|
+
* grant `maxToolRounds/2` more headroom per compaction, bounded to at most
|
|
169
|
+
* one extra auto-recover budget's worth above the ORIGINAL ceiling so a
|
|
170
|
+
* genuinely wedged turn (which trips the pattern guard, not this path) can
|
|
171
|
+
* never grow the cap without limit. Called from the tool-engine auto-recover
|
|
172
|
+
* branch after a successful compaction.
|
|
173
|
+
*/
|
|
174
|
+
extendHardCeilingForAutoCompaction(): void;
|
|
146
175
|
private _safetyOverrideHandler;
|
|
147
176
|
setSafetyOverrideHandler(fn: ((block: SafetyOverrideAskInfo) => Promise<SafetyOverrideVerdict>) | null): void;
|
|
148
177
|
respondToToolApproval(approvalId: string, approved: boolean): void;
|
|
@@ -166,6 +195,13 @@ export declare class Agent {
|
|
|
166
195
|
unpinMessageBySeq(seq: number): boolean;
|
|
167
196
|
getPinnedSeqs(): number[];
|
|
168
197
|
getChatEntries(): ChatEntry[];
|
|
198
|
+
/**
|
|
199
|
+
* The session tree this TUI currently hosts: the root conversation plus every
|
|
200
|
+
* rotation / sub-agent descendant, with per-session metadata. Content from
|
|
201
|
+
* these sessions is already merged into the transcript on resume; this exposes
|
|
202
|
+
* WHICH sessions produced it so the rail can show the multi-session structure.
|
|
203
|
+
*/
|
|
204
|
+
getSessionTree(): import("../storage/transcript.js").SessionChainNode[];
|
|
169
205
|
getLastTodoSnapshot(): TaskListSnapshot | null;
|
|
170
206
|
getSessionSnapshot(): SessionSnapshot | null;
|
|
171
207
|
onSubagentStatus(listener: (status: SubagentStatus | null) => void): () => void;
|
|
@@ -195,7 +231,7 @@ export declare class Agent {
|
|
|
195
231
|
private _resolveModelForTask;
|
|
196
232
|
private compactForContext;
|
|
197
233
|
private postTurnCompact;
|
|
198
|
-
respondToCouncilQuestion(questionId: string, answer: string): void;
|
|
234
|
+
respondToCouncilQuestion(questionId: string, answer: string, questionText?: string): void;
|
|
199
235
|
respondToCouncilPreflight(preflightId: string, approved: boolean): void;
|
|
200
236
|
runCouncilV2(topic: string, options?: {
|
|
201
237
|
skipClarification?: boolean;
|
|
@@ -203,7 +239,7 @@ export declare class Agent {
|
|
|
203
239
|
userModelMessage?: ModelMessage;
|
|
204
240
|
}): AsyncGenerator<StreamChunk, void, unknown>;
|
|
205
241
|
runProductLoopV1(payload: {
|
|
206
|
-
subcommand: "start" | "status" | "resume" | "abort" | "ship";
|
|
242
|
+
subcommand: "start" | "status" | "resume" | "abort" | "ship" | "review";
|
|
207
243
|
idea?: string;
|
|
208
244
|
runId?: string;
|
|
209
245
|
flags: {
|