muonroi-cli 1.8.3 → 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 +21 -21
- package/README.md +133 -122
- 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 +30 -15
- 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 +254 -84
- 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/oauth-callback.js +2 -2
- 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 +77 -76
- 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 +8 -8
- 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 +159 -159
- 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 +26 -0
- package/dist/src/orchestrator/tool-engine.js +669 -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/layer2_5-ponytail.js +8 -8
- 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/done-gate.js +3 -3
- 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 +327 -116
- 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/progress-snapshot.js +4 -4
- 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 +82 -172
- 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/reporter/index.js +1 -1
- 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/bb-ecosystem-apply.js +47 -47
- package/dist/src/scaffold/bb-quality-gate.js +5 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +86 -60
- package/dist/src/scaffold/init-new.js +453 -453
- 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 +22 -22
- 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/interaction-log.js +5 -5
- package/dist/src/storage/migrations.js +196 -126
- package/dist/src/storage/session-experience-store.js +4 -4
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +112 -55
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +383 -112
- package/dist/src/storage/usage.js +14 -14
- package/dist/src/storage/workspaces.js +12 -12
- 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-inspect.js +4 -4
- 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/clipboard-image.js +23 -23
- package/dist/src/utils/install-manager.js +14 -11
- 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/side-question.js +2 -2
- package/dist/src/utils/skills.js +3 -3
- 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
|
@@ -11,10 +11,11 @@
|
|
|
11
11
|
// original orchestrator.ts (see commit history), only `this.xxx` → `this.deps.xxx()`
|
|
12
12
|
// transposition where the field/method originally lived on Agent.
|
|
13
13
|
import { generateText, stepCountIs } from "ai";
|
|
14
|
-
import {
|
|
14
|
+
import { getModelsForProvider } from "../models/registry.js";
|
|
15
15
|
import { loadKeyForProvider } from "../providers/keychain.js";
|
|
16
|
-
import { createProviderFactory, detectProviderForModel, resolveModelRuntime, shouldDropParam, } from "../providers/runtime.js";
|
|
16
|
+
import { createProviderFactory, detectProviderForModel, resolveModelRuntime, resolveTemperatureParam, shouldDropParam, } from "../providers/runtime.js";
|
|
17
17
|
import { ALL_PROVIDER_IDS } from "../providers/types.js";
|
|
18
|
+
import { getRoutedModelByTier } from "../router/peak-hour.js";
|
|
18
19
|
import { appendSystemMessage } from "../storage/index.js";
|
|
19
20
|
import { createBuiltinTools } from "../tools/registry.js";
|
|
20
21
|
import { isProviderDisabled } from "../utils/settings.js";
|
|
@@ -35,6 +36,12 @@ export class CouncilManager {
|
|
|
35
36
|
deps;
|
|
36
37
|
// ---- Mutable state (was Agent private fields) ----
|
|
37
38
|
_lastSynthesis = null;
|
|
39
|
+
/**
|
|
40
|
+
* Post-debate action the user chose on the last runCouncilV2 (e.g.
|
|
41
|
+
* "continue_session", "save_exit"). Relayed to the auto-council caller
|
|
42
|
+
* (tool-engine) so it can honor the choice instead of always continuing.
|
|
43
|
+
*/
|
|
44
|
+
_lastPostDebateAction = null;
|
|
38
45
|
_isContinuation = false;
|
|
39
46
|
_questionResolvers = new Map();
|
|
40
47
|
_preflightResolvers = new Map();
|
|
@@ -52,6 +59,12 @@ export class CouncilManager {
|
|
|
52
59
|
setLastSynthesis(v) {
|
|
53
60
|
this._lastSynthesis = v;
|
|
54
61
|
}
|
|
62
|
+
get lastPostDebateAction() {
|
|
63
|
+
return this._lastPostDebateAction;
|
|
64
|
+
}
|
|
65
|
+
setLastPostDebateAction(v) {
|
|
66
|
+
this._lastPostDebateAction = v;
|
|
67
|
+
}
|
|
55
68
|
get isContinuation() {
|
|
56
69
|
return this._isContinuation;
|
|
57
70
|
}
|
|
@@ -62,7 +75,7 @@ export class CouncilManager {
|
|
|
62
75
|
this.stats = { calls: 0, startMs: startMs ?? 0 };
|
|
63
76
|
}
|
|
64
77
|
// ---- Public responder API (delegated from Agent.respondToCouncilQuestion etc) ----
|
|
65
|
-
respondToQuestion(questionId, answer) {
|
|
78
|
+
respondToQuestion(questionId, answer, questionText) {
|
|
66
79
|
if (process.env.MUONROI_DEBUG_LEADER === "1") {
|
|
67
80
|
process.stderr.write(`[responder] respondToCouncilQuestion: ${JSON.stringify({
|
|
68
81
|
questionId,
|
|
@@ -75,6 +88,14 @@ export class CouncilManager {
|
|
|
75
88
|
if (resolver) {
|
|
76
89
|
resolver(answer);
|
|
77
90
|
this._questionResolvers.delete(questionId);
|
|
91
|
+
if (questionText) {
|
|
92
|
+
import("../gsd/phase-sync.js")
|
|
93
|
+
.then(({ appendClarificationToContext }) => {
|
|
94
|
+
const cwd = this.deps.getBash().getCwd();
|
|
95
|
+
appendClarificationToContext(cwd, questionText, answer);
|
|
96
|
+
})
|
|
97
|
+
.catch(() => { });
|
|
98
|
+
}
|
|
78
99
|
}
|
|
79
100
|
else {
|
|
80
101
|
// Headless auto-answer: response arrived before the generator registered
|
|
@@ -135,7 +156,7 @@ export class CouncilManager {
|
|
|
135
156
|
system,
|
|
136
157
|
prompt,
|
|
137
158
|
...(shouldDropParam(runtime, "maxOutputTokens") ? {} : { maxOutputTokens: maxTokens }),
|
|
138
|
-
...(
|
|
159
|
+
...resolveTemperatureParam(runtime, 0.7),
|
|
139
160
|
...(runtime.providerOptions ? { providerOptions: runtime.providerOptions } : {}),
|
|
140
161
|
});
|
|
141
162
|
this.stats.calls++;
|
|
@@ -153,7 +174,8 @@ export class CouncilManager {
|
|
|
153
174
|
const runtime = resolveModelRuntime(provider, modelId);
|
|
154
175
|
// Build tool set with bash, grep, read_file for codebase research
|
|
155
176
|
const researchTools = createBuiltinTools(this.deps.getBash(), this.deps.getMode(), {
|
|
156
|
-
|
|
177
|
+
// research phase intentionally has no runTask/runDelegation handlers
|
|
178
|
+
sessionId: this.deps.getSessionId() ?? undefined,
|
|
157
179
|
});
|
|
158
180
|
const systemPrompt = `You are a research specialist. Your job is to gather FACTS about the topic below.\n\n` +
|
|
159
181
|
`## Instructions\n` +
|
|
@@ -182,7 +204,7 @@ export class CouncilManager {
|
|
|
182
204
|
tools: researchTools,
|
|
183
205
|
stopWhen: stepCountIs(10),
|
|
184
206
|
...(shouldDropParam(runtime, "maxOutputTokens") ? {} : { maxOutputTokens: 4096 }),
|
|
185
|
-
...(
|
|
207
|
+
...resolveTemperatureParam(runtime, 0.3),
|
|
186
208
|
...(runtime.providerOptions ? { providerOptions: runtime.providerOptions } : {}),
|
|
187
209
|
...(signal ? { abortSignal: signal } : {}),
|
|
188
210
|
});
|
|
@@ -251,8 +273,9 @@ export class CouncilManager {
|
|
|
251
273
|
}
|
|
252
274
|
/**
|
|
253
275
|
* Build conversation context for council discussion from current session messages.
|
|
254
|
-
* Extracts: compaction summary, recent user
|
|
255
|
-
*
|
|
276
|
+
* Extracts: compaction summary, recent conversation (user + analytical assistant),
|
|
277
|
+
* key decisions/outcomes/plans.
|
|
278
|
+
* Limited to ~8000 tokens (~32K chars) to balance depth vs cost.
|
|
256
279
|
*/
|
|
257
280
|
buildContext() {
|
|
258
281
|
const messages = this.deps.getMessages();
|
|
@@ -267,34 +290,52 @@ export class CouncilManager {
|
|
|
267
290
|
}
|
|
268
291
|
}
|
|
269
292
|
}
|
|
270
|
-
// 2. Recent user
|
|
271
|
-
|
|
272
|
-
|
|
293
|
+
// 2. Recent conversation turns — user + analytical assistant messages.
|
|
294
|
+
// Previously only captured user messages, losing assistant analysis,
|
|
295
|
+
// code changes, and decisions made during the session.
|
|
296
|
+
const conversationTurns = [];
|
|
297
|
+
for (let i = messages.length - 1; i >= 0 && conversationTurns.length < 8; i--) {
|
|
273
298
|
const msg = messages[i];
|
|
274
299
|
if (msg.role === "user") {
|
|
275
300
|
const text = typeof msg.content === "string" ? msg.content : extractUserContent(msg.content);
|
|
276
301
|
if (text.trim()) {
|
|
277
|
-
|
|
302
|
+
conversationTurns.unshift(`[User] ${text.slice(0, 3000).trim()}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else if (msg.role === "assistant") {
|
|
306
|
+
const text = typeof msg.content === "string" ? msg.content : extractUserContent(msg.content);
|
|
307
|
+
// Only include analytical assistant turns (≥80 chars of text — excludes pure tool-call results)
|
|
308
|
+
if (text.trim().length >= 80) {
|
|
309
|
+
conversationTurns.unshift(`[Assistant] ${text.slice(0, 1500).trim()}`);
|
|
278
310
|
}
|
|
279
311
|
}
|
|
280
312
|
}
|
|
281
|
-
if (
|
|
282
|
-
parts.push(`## Recent
|
|
313
|
+
if (conversationTurns.length > 0) {
|
|
314
|
+
parts.push(`## Recent Conversation\n${conversationTurns.join("\n\n")}`);
|
|
283
315
|
}
|
|
284
|
-
// 3. Key decisions from council
|
|
285
|
-
const
|
|
316
|
+
// 3. Key decisions from system messages (task outcomes, council results, plans, etc.)
|
|
317
|
+
const decisionMsgs = [];
|
|
286
318
|
for (const msg of messages) {
|
|
287
|
-
if (msg.role
|
|
288
|
-
|
|
319
|
+
if (msg.role !== "system" || typeof msg.content !== "string")
|
|
320
|
+
continue;
|
|
321
|
+
const c = msg.content;
|
|
322
|
+
if (c.includes("[Council Memory]") ||
|
|
323
|
+
c.includes("[Council Decision]") ||
|
|
324
|
+
c.includes("[Council Action Items]") ||
|
|
325
|
+
c.includes("[Council Plan Update]") ||
|
|
326
|
+
c.includes("[Decision]") ||
|
|
327
|
+
c.includes("[Task Completed]") ||
|
|
328
|
+
c.includes("[NEEDS HUMAN REVIEW]")) {
|
|
329
|
+
decisionMsgs.push(c);
|
|
289
330
|
}
|
|
290
331
|
}
|
|
291
|
-
if (
|
|
292
|
-
parts.push(`##
|
|
332
|
+
if (decisionMsgs.length > 0) {
|
|
333
|
+
parts.push(`## Key Decisions\n${decisionMsgs.slice(-4).join("\n\n")}`);
|
|
293
334
|
}
|
|
294
335
|
const combined = parts.join("\n\n---\n\n");
|
|
295
|
-
//
|
|
296
|
-
if (combined.length >
|
|
297
|
-
return `${combined.slice(0,
|
|
336
|
+
// ~8K token budget (char/4 ≈ token count; cap raised from original 12K chars)
|
|
337
|
+
if (combined.length > 32000) {
|
|
338
|
+
return `${combined.slice(0, 32000)}\n\n[... context truncated to fit token budget]`;
|
|
298
339
|
}
|
|
299
340
|
return combined;
|
|
300
341
|
}
|
|
@@ -414,7 +455,7 @@ export class CouncilManager {
|
|
|
414
455
|
if (!isProviderDisabled(p)) {
|
|
415
456
|
const key = await loadKeyForProvider(p).catch(() => null);
|
|
416
457
|
if (key) {
|
|
417
|
-
const m =
|
|
458
|
+
const m = getRoutedModelByTier("balanced", p);
|
|
418
459
|
// Guard: getModelByTier may return a model from a different provider
|
|
419
460
|
// when the preferred provider has no model for the requested tier.
|
|
420
461
|
if (m && m.provider === p)
|
|
@@ -32,6 +32,12 @@ export interface CrossTurnDedupEntry {
|
|
|
32
32
|
firstSeenTurn: number;
|
|
33
33
|
/** Tool name that originally produced the content (for the stub). */
|
|
34
34
|
firstSeenToolName: string;
|
|
35
|
+
/**
|
|
36
|
+
* Number of SAME-TURN repeat calls seen for this content (0 until the first
|
|
37
|
+
* in-turn re-call). Used to re-serve content once before hard-stopping a
|
|
38
|
+
* loop — see the same-turn branch of maybeDedup.
|
|
39
|
+
*/
|
|
40
|
+
sameTurnRepeats: number;
|
|
35
41
|
}
|
|
36
42
|
export interface CrossTurnDedupStats {
|
|
37
43
|
/** Total dedup hits across the lifetime of this instance. */
|
|
@@ -75,10 +75,30 @@ export class CrossTurnDedup {
|
|
|
75
75
|
const hash = shortHash(raw);
|
|
76
76
|
const existing = this.cache.get(hash);
|
|
77
77
|
if (existing) {
|
|
78
|
-
this.hits += 1;
|
|
79
78
|
// Refresh LRU position so frequently-reused outputs survive eviction.
|
|
80
79
|
this.cache.delete(hash);
|
|
81
80
|
this.cache.set(hash, existing);
|
|
81
|
+
const thisTurn = this.currentTurn || 1;
|
|
82
|
+
const sameTurnLoop = existing.firstSeenTurn === thisTurn;
|
|
83
|
+
if (sameTurnLoop) {
|
|
84
|
+
// O1/O2 fix — a re-call of identical content WITHIN the same turn is a
|
|
85
|
+
// model loop, not genuine cross-turn reuse. A cheap model (kimi /
|
|
86
|
+
// deepseek) that re-issues the same read usually did so because it did
|
|
87
|
+
// NOT retain the earlier result; a bare "reuse" stub then triggers a
|
|
88
|
+
// WORSE fallback — it re-reads each file singly, inflating fresh input
|
|
89
|
+
// (measured: batch read → stub → stub → 4 single reads). Re-serve the
|
|
90
|
+
// content ONCE (passthrough) to satisfy the loop, then hard-stop on any
|
|
91
|
+
// further in-turn repeat so an infinite loop stays bounded.
|
|
92
|
+
existing.sameTurnRepeats += 1;
|
|
93
|
+
if (existing.sameTurnRepeats === 1)
|
|
94
|
+
return null;
|
|
95
|
+
this.hits += 1;
|
|
96
|
+
return `[${existing.firstSeenToolName} already returned this EXACT result ${existing.sameTurnRepeats + 1}× this turn — it is unchanged and already in the context above. STOP re-calling it; answer from the result you already have.]`;
|
|
97
|
+
}
|
|
98
|
+
// Genuine cross-turn reuse (C3): the user prompted again and the agent
|
|
99
|
+
// re-ran an identical read. The model is not looping, so the short stub
|
|
100
|
+
// is the right, token-saving behavior.
|
|
101
|
+
this.hits += 1;
|
|
82
102
|
// G3 — short marker. Old format was ~110 chars; this is ~45.
|
|
83
103
|
return `[dup of ${existing.firstSeenToolName} from turn ${existing.firstSeenTurn} — reuse]`;
|
|
84
104
|
}
|
|
@@ -87,6 +107,7 @@ export class CrossTurnDedup {
|
|
|
87
107
|
content: raw,
|
|
88
108
|
firstSeenTurn: this.currentTurn || 1,
|
|
89
109
|
firstSeenToolName: toolName,
|
|
110
|
+
sameTurnRepeats: 0,
|
|
90
111
|
});
|
|
91
112
|
this.inserts += 1;
|
|
92
113
|
while (this.cache.size > this.maxEntries) {
|
|
@@ -27,6 +27,35 @@ export interface ApiErrorForensics {
|
|
|
27
27
|
urlHost: string | undefined;
|
|
28
28
|
responseBodyTrunc: string | undefined;
|
|
29
29
|
requestParamKeys: string[] | undefined;
|
|
30
|
+
/** Field-key signature per distinct assistant message shape (PII-safe).
|
|
31
|
+
* Diagnoses Z.ai 1210 / SiliconFlow 20015 "invalid parameter" rejections
|
|
32
|
+
* where the culprit is a missing/extra field on assistant turns in a
|
|
33
|
+
* multi-step tool loop (e.g. reasoning_content present on some turns but
|
|
34
|
+
* absent on tool-only turns). */
|
|
35
|
+
assistantFieldKeys: string[] | undefined;
|
|
36
|
+
/** Per-assistant-message char counts (PII-safe — lengths only, no text).
|
|
37
|
+
* Distinguishes the "uniform shape but still rejected" failure mode:
|
|
38
|
+
* H1 cumulative reasoning budget exceeded vs H2 empty reasoning_content
|
|
39
|
+
* string vs H3 oversized text/tool payload. Set when messages are present. */
|
|
40
|
+
assistantReasoningLens: number[] | undefined;
|
|
41
|
+
/** Total reasoning_content chars across assistant messages. */
|
|
42
|
+
totalReasoningChars: number | undefined;
|
|
43
|
+
/** Values of scalar SDK-config params (reasoning_effort, verbosity,
|
|
44
|
+
* tool_choice, response_format, max_tokens, temperature, top_p,
|
|
45
|
+
* frequency_penalty, presence_penalty, seed, stop, parallel_tool_calls).
|
|
46
|
+
* PII-safe (generation config, not prompt content) — pinpoints WHICH
|
|
47
|
+
* param value a provider rejects when the error is generic (Z.ai 1210,
|
|
48
|
+
* SiliconFlow 20015). */
|
|
49
|
+
configParamValues: Record<string, unknown> | undefined;
|
|
50
|
+
/** Per-assistant tool_calls counts (from assistant messages in the request
|
|
51
|
+
* that failed). Captures H3 for Z.ai 1210: a single assistant response
|
|
52
|
+
* emitting many parallel tool_calls (e.g. 8 or 12) → the follow-up request
|
|
53
|
+
* carrying that many role:tool results gets rejected by the coding endpoint
|
|
54
|
+
* with generic 1210. */
|
|
55
|
+
assistantToolCallCounts: number[] | undefined;
|
|
56
|
+
/** Count of role:"tool" messages in the failing request body. Complements
|
|
57
|
+
* assistantToolCallCounts to show the round-trip payload size for H3. */
|
|
58
|
+
toolMessageCount: number | undefined;
|
|
30
59
|
isRetryable: boolean | undefined;
|
|
31
60
|
}
|
|
32
61
|
export declare function summarizeApiErrorForLog(error: unknown): ApiErrorForensics | null;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { APICallError } from "@ai-sdk/provider";
|
|
2
2
|
const STATUS_MESSAGES = {
|
|
3
|
-
400: "The request
|
|
4
|
-
401: "
|
|
5
|
-
403: "
|
|
6
|
-
404: "The
|
|
7
|
-
408: "The request timed out.
|
|
8
|
-
422: "The request
|
|
9
|
-
429: "
|
|
10
|
-
500: "
|
|
11
|
-
502: "The
|
|
12
|
-
503: "The
|
|
13
|
-
529: "The
|
|
3
|
+
400: "The provider rejected this request as invalid — usually a parameter or model it doesn't support. Try switching models with `-m <model>`, or simplify the request and retry.",
|
|
4
|
+
401: "The provider didn't accept your API key — it may be missing, invalid, or expired. Run `keys login <provider>` to set a fresh key, then try again.",
|
|
5
|
+
403: "Your API key works, but it isn't allowed to make this request. Check your plan or key permissions on the provider's dashboard, or switch models with `-m <model>`.",
|
|
6
|
+
404: "The provider couldn't find that model or endpoint. Double-check the model name (see `models list`) and your base URL, then try again.",
|
|
7
|
+
408: "The request took too long and timed out. This is usually temporary — just try again.",
|
|
8
|
+
422: "The provider understood the request but couldn't process it. Check your message format and parameters, then retry — switching models with `-m <model>` can also help.",
|
|
9
|
+
429: "You're sending requests faster than the provider allows right now. Wait a moment and try again, or switch to another model with `-m <model>`.",
|
|
10
|
+
500: "Something went wrong on the provider's servers — not on your end. Give it a moment and try again later.",
|
|
11
|
+
502: "The provider's servers are temporarily unreachable. This usually clears up on its own — try again in a minute.",
|
|
12
|
+
503: "The provider is overloaded right now. Give it a minute and retry, or switch models with `-m <model>` in the meantime.",
|
|
13
|
+
529: "The provider is overloaded right now. Give it a minute and retry, or switch models with `-m <model>` in the meantime.",
|
|
14
14
|
};
|
|
15
15
|
export function isContextLimitError(error) {
|
|
16
16
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -48,14 +48,45 @@ function routingSuffix(error, ctx) {
|
|
|
48
48
|
if (status === undefined && /insufficient balance|out of (balance|credit)/i.test(message)) {
|
|
49
49
|
status = 402;
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
const rawMsg = (error instanceof Error ? error.message : String(error)).toLowerCase();
|
|
52
|
+
const isConsoleGo = rawMsg.includes("console go") || ctx?.providerId === "opencode-go";
|
|
53
|
+
const isRateLimitMsg = /rate limit|rate-limited|429|too many requests/i.test(rawMsg);
|
|
54
|
+
// If we have model context and it's a routing error (by status or by message content)
|
|
55
|
+
if (!ctx?.modelId)
|
|
56
|
+
return "";
|
|
57
|
+
if (!(status !== undefined && ROUTING_STATUSES.has(status)) && !isRateLimitMsg && !isConsoleGo)
|
|
52
58
|
return "";
|
|
53
59
|
const where = `routed to model "${ctx.modelId}"${ctx.providerId ? ` via provider "${ctx.providerId}"` : ""}`;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
// A generic "invalid request" rejection — NOT a rate limit. Console Go can
|
|
61
|
+
// silently re-route (e.g. deepseek-v4-flash → a kimi coding backend) and then
|
|
62
|
+
// reject a long tool-loop payload with a bare 400 invalid_request. Retrying
|
|
63
|
+
// as-is never helps (isRetryable:false), so the hint must NOT say "wait and
|
|
64
|
+
// retry" — it must point at the real levers (switch model / shorten payload).
|
|
65
|
+
const isInvalidRequest = status === 400 || status === 422;
|
|
66
|
+
let hint;
|
|
67
|
+
if (isConsoleGo && (isRateLimitMsg || status === 429)) {
|
|
68
|
+
hint =
|
|
69
|
+
"the Console Go proxy hit its own burst rate limit — this is separate from your web 'Rolling Usage' %, so the dashboard can look fine while the proxy still throttles. Wait a moment, use native DeepSeek with `-m deepseek-v4-flash`, or switch provider.";
|
|
70
|
+
}
|
|
71
|
+
else if (status === 402) {
|
|
72
|
+
hint =
|
|
73
|
+
"this provider account is out of balance or credit. Top it up on the provider's site, or switch to another model with `-m <model>`.";
|
|
74
|
+
}
|
|
75
|
+
else if (status === 401 || status === 403) {
|
|
76
|
+
hint =
|
|
77
|
+
"you're not authenticated for this provider. Run `keys login <provider>` (or set its API key), or switch to another model with `-m <model>`.";
|
|
78
|
+
}
|
|
79
|
+
else if (isInvalidRequest) {
|
|
80
|
+
hint =
|
|
81
|
+
"the provider rejected this request as invalid — often a param or backend model it doesn't support, or a tool-loop payload the routed model can't accept (some gateways re-route to a different backend than the one you picked). Switch models with `-m <model>` or shorten/simplify the request; retrying it unchanged won't help.";
|
|
82
|
+
}
|
|
83
|
+
else if (isRateLimitMsg || status === 429) {
|
|
84
|
+
hint = "the provider is rate-limiting you. Wait a moment and retry, or switch to another model with `-m <model>`.";
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
hint =
|
|
88
|
+
"the routed model or provider couldn't complete this request. Switch to another model with `-m <model>`, or try again.";
|
|
89
|
+
}
|
|
59
90
|
return ` [${where}] — ${hint}`;
|
|
60
91
|
}
|
|
61
92
|
export function humanizeApiError(error, ctx) {
|
|
@@ -63,7 +94,7 @@ export function humanizeApiError(error, ctx) {
|
|
|
63
94
|
}
|
|
64
95
|
function humanizeApiErrorBase(error) {
|
|
65
96
|
if (isMalformedFunctionNameError(error)) {
|
|
66
|
-
return "
|
|
97
|
+
return "The model produced a malformed tool call (its function name was missing), so this turn was skipped. Just send your request again — rephrasing slightly often helps.";
|
|
67
98
|
}
|
|
68
99
|
if (APICallError.isInstance(error)) {
|
|
69
100
|
const detail = extractResponseDetail(error.responseBody);
|
|
@@ -75,7 +106,8 @@ function humanizeApiErrorBase(error) {
|
|
|
75
106
|
// For 5xx prefer the canned "retry later" message + the status code; keep a
|
|
76
107
|
// body detail only when it actually adds information.
|
|
77
108
|
if (status && status >= 500) {
|
|
78
|
-
const canned = STATUS_MESSAGES[status] ??
|
|
109
|
+
const canned = STATUS_MESSAGES[status] ??
|
|
110
|
+
"The provider's servers returned an error — not something you did. Wait a bit and try again.";
|
|
79
111
|
if (!detail || isOpaqueDetail(detail))
|
|
80
112
|
return `${canned} (HTTP ${status})`;
|
|
81
113
|
return `${detail} (HTTP ${status})`;
|
|
@@ -93,9 +125,9 @@ function humanizeApiErrorBase(error) {
|
|
|
93
125
|
const toolMatch = raw.match(/Tool\s+"?(\w+)"?\s+(?:is\s+)?not\s+found/i) ?? raw.match(/tool\s+(\w+)/i);
|
|
94
126
|
const toolName = toolMatch?.[1] ?? "that tool";
|
|
95
127
|
if (toolName === "search_web") {
|
|
96
|
-
return `"search_web"
|
|
128
|
+
return `"search_web" isn't available here. For web requests, use bash with curl instead, or hand the research off to an explore agent.`;
|
|
97
129
|
}
|
|
98
|
-
return `Tool "${toolName}"
|
|
130
|
+
return `Tool "${toolName}" isn't available in this session. Check the TOOLS list in the system prompt to see which tools you can use.`;
|
|
99
131
|
}
|
|
100
132
|
return stripped;
|
|
101
133
|
}
|
|
@@ -135,9 +167,50 @@ export function summarizeApiErrorForLog(error) {
|
|
|
135
167
|
catch {
|
|
136
168
|
urlHost = undefined;
|
|
137
169
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
170
|
+
const bodyValues = error.requestBodyValues && typeof error.requestBodyValues === "object"
|
|
171
|
+
? error.requestBodyValues
|
|
172
|
+
: undefined;
|
|
173
|
+
const requestParamKeys = bodyValues ? Object.keys(bodyValues).sort() : undefined;
|
|
174
|
+
// Collect the distinct field-key signature across assistant wire messages.
|
|
175
|
+
// Only key NAMES are persisted — values may contain secrets/PII.
|
|
176
|
+
let assistantFieldKeys;
|
|
177
|
+
let assistantReasoningLens;
|
|
178
|
+
let assistantToolCallCounts;
|
|
179
|
+
let totalReasoningChars = 0;
|
|
180
|
+
let toolMessageCount = 0;
|
|
181
|
+
if (bodyValues && Array.isArray(bodyValues.messages)) {
|
|
182
|
+
const signatures = new Set();
|
|
183
|
+
const rcLens = [];
|
|
184
|
+
const tcLens = [];
|
|
185
|
+
for (const m of bodyValues.messages) {
|
|
186
|
+
const msg = m;
|
|
187
|
+
if (msg?.role === "tool") {
|
|
188
|
+
toolMessageCount++;
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (msg?.role !== "assistant")
|
|
192
|
+
continue;
|
|
193
|
+
const sig = Object.keys(msg ?? {})
|
|
194
|
+
.sort()
|
|
195
|
+
.join(",");
|
|
196
|
+
signatures.add(sig);
|
|
197
|
+
const rc = msg?.reasoning_content;
|
|
198
|
+
if (typeof rc === "string") {
|
|
199
|
+
rcLens.push(rc.length);
|
|
200
|
+
totalReasoningChars += rc.length;
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
rcLens.push(-1); // marker: reasoning_content missing/non-string on this turn
|
|
204
|
+
}
|
|
205
|
+
const tcs = Array.isArray(msg?.tool_calls) ? msg.tool_calls.length : 0;
|
|
206
|
+
tcLens.push(tcs);
|
|
207
|
+
}
|
|
208
|
+
if (signatures.size > 0)
|
|
209
|
+
assistantFieldKeys = [...signatures].sort();
|
|
210
|
+
if (rcLens.length > 0)
|
|
211
|
+
assistantReasoningLens = rcLens;
|
|
212
|
+
if (tcLens.length > 0)
|
|
213
|
+
assistantToolCallCounts = tcLens;
|
|
141
214
|
}
|
|
142
215
|
const body = typeof error.responseBody === "string" ? error.responseBody : undefined;
|
|
143
216
|
const responseBodyTrunc = body && body.length > RESPONSE_BODY_CAP ? `${body.slice(0, RESPONSE_BODY_CAP)}…[truncated]` : body;
|
|
@@ -146,8 +219,43 @@ export function summarizeApiErrorForLog(error) {
|
|
|
146
219
|
urlHost,
|
|
147
220
|
responseBodyTrunc,
|
|
148
221
|
requestParamKeys,
|
|
222
|
+
assistantFieldKeys,
|
|
223
|
+
assistantReasoningLens,
|
|
224
|
+
totalReasoningChars: assistantReasoningLens ? totalReasoningChars : undefined,
|
|
225
|
+
configParamValues: bodyValues ? extractConfigParamValues(bodyValues) : undefined,
|
|
226
|
+
assistantToolCallCounts,
|
|
227
|
+
toolMessageCount: bodyValues && Array.isArray(bodyValues.messages) ? toolMessageCount : undefined,
|
|
149
228
|
isRetryable: error.isRetryable,
|
|
150
229
|
};
|
|
151
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Scalar SDK-config params whose VALUES are PII-safe (generation config, not
|
|
233
|
+
* user prompt content). See `ApiErrorForensics.configParamValues`.
|
|
234
|
+
* Includes parallel_tool_calls because Z.ai GLM coding endpoint rejects
|
|
235
|
+
* high-parallelism tool call batches (observed 8-12 in one assistant turn)
|
|
236
|
+
* with generic 1210; capturing the value helps confirm if SDK overrode it.
|
|
237
|
+
*/
|
|
238
|
+
const CONFIG_PARAM_KEYS = [
|
|
239
|
+
"reasoning_effort",
|
|
240
|
+
"verbosity",
|
|
241
|
+
"tool_choice",
|
|
242
|
+
"response_format",
|
|
243
|
+
"max_tokens",
|
|
244
|
+
"temperature",
|
|
245
|
+
"top_p",
|
|
246
|
+
"frequency_penalty",
|
|
247
|
+
"presence_penalty",
|
|
248
|
+
"seed",
|
|
249
|
+
"stop",
|
|
250
|
+
"parallel_tool_calls",
|
|
251
|
+
];
|
|
252
|
+
function extractConfigParamValues(body) {
|
|
253
|
+
const out = {};
|
|
254
|
+
for (const k of CONFIG_PARAM_KEYS) {
|
|
255
|
+
if (k in body)
|
|
256
|
+
out[k] = body[k] ?? null;
|
|
257
|
+
}
|
|
258
|
+
return out;
|
|
259
|
+
}
|
|
152
260
|
export { extractResponseDetail, STATUS_MESSAGES };
|
|
153
261
|
//# sourceMappingURL=error-utils.js.map
|
|
@@ -41,6 +41,30 @@ const COUNT_RE = new RegExp(`\\b(\\d{1,3}(?:,\\d{3})+|\\d{2,})\\b(?:\\s+(?:\\w+\
|
|
|
41
41
|
const NOUN_SEP_NUM_RE = new RegExp(`\\b(?:${COUNT_NOUN})\\b[^.\\n:=]{0,40}?[:=]\\s*(\\d{1,3}(?:,\\d{3})+|\\d{2,})\\b`, "gi");
|
|
42
42
|
// filename.ext:line — basename only (the char class excludes "/").
|
|
43
43
|
const FILELINE_RE = /\b([\w.-]+\.[a-z]{1,5}):(\d+)\b/gi;
|
|
44
|
+
// read_file emits a header `[<path>: lines A-B of TOTAL]` (src/tools/file.ts:75).
|
|
45
|
+
// TOTAL is always the FULL file length (not the slice end B), so it is the
|
|
46
|
+
// ground truth for "does line N exist in this file". Path may use "/" or "\";
|
|
47
|
+
// the basename char class excludes both, so it captures just "planner.ts".
|
|
48
|
+
const READ_HEADER_RE = /([\w.-]+\.[a-z]{1,5}):\s*lines\s+\d+-\d+\s+of\s+(\d+)/gi;
|
|
49
|
+
/**
|
|
50
|
+
* Map basename → largest known full-file line count, parsed from read_file
|
|
51
|
+
* headers in the corpus. Used to catch a file:line that names a REAL (read)
|
|
52
|
+
* file but a FABRICATED line number beyond the file's length — the failure the
|
|
53
|
+
* basename-only check misses.
|
|
54
|
+
*/
|
|
55
|
+
function parseReadLineCounts(corpus) {
|
|
56
|
+
const totals = new Map();
|
|
57
|
+
for (const m of corpus.matchAll(READ_HEADER_RE)) {
|
|
58
|
+
const base = m[1].toLowerCase();
|
|
59
|
+
const total = Number.parseInt(m[2], 10);
|
|
60
|
+
if (!Number.isFinite(total))
|
|
61
|
+
continue;
|
|
62
|
+
const prev = totals.get(base);
|
|
63
|
+
if (prev === undefined || total > prev)
|
|
64
|
+
totals.set(base, total);
|
|
65
|
+
}
|
|
66
|
+
return totals;
|
|
67
|
+
}
|
|
44
68
|
// Hedge markers immediately before a number mean it is an estimate, not a fact.
|
|
45
69
|
const HEDGE_RE = /(~|≈|\babout\b|\bapprox(?:imately)?\b|\broughly\b|\baround\b|\bnearly\b|\best\.?\b)\s*$/i;
|
|
46
70
|
function stripCommas(s) {
|
|
@@ -56,6 +80,7 @@ export function findUnverifiedClaims(finalText, corpus) {
|
|
|
56
80
|
return [];
|
|
57
81
|
const corpusNorm = stripCommas(corpus).toLowerCase();
|
|
58
82
|
const corpusLower = corpus.toLowerCase();
|
|
83
|
+
const readTotals = parseReadLineCounts(corpus);
|
|
59
84
|
const out = [];
|
|
60
85
|
const seen = new Set();
|
|
61
86
|
const push = (claim) => {
|
|
@@ -103,8 +128,21 @@ export function findUnverifiedClaims(finalText, corpus) {
|
|
|
103
128
|
if (idx > 0 && finalText[idx - 1] === "/")
|
|
104
129
|
continue;
|
|
105
130
|
const basename = m[1];
|
|
131
|
+
const lineNo = Number.parseInt(m[2], 10);
|
|
132
|
+
const knownTotal = readTotals.get(basename.toLowerCase());
|
|
133
|
+
// Provably-fabricated line: the file WAS read this turn (header parsed), but
|
|
134
|
+
// the cited line exceeds its real length. Deterministic — flag even though
|
|
135
|
+
// the basename appears in the corpus (the basename check below would pass).
|
|
136
|
+
if (knownTotal !== undefined && Number.isFinite(lineNo) && lineNo > knownTotal) {
|
|
137
|
+
push({
|
|
138
|
+
kind: "fileline",
|
|
139
|
+
value: `${basename}:${m[2]}`,
|
|
140
|
+
text: `${basename}:${m[2]} (file has ${knownTotal} lines)`,
|
|
141
|
+
});
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
106
144
|
if (corpusLower.includes(basename.toLowerCase()))
|
|
107
|
-
continue; // file was read/grepped → verified
|
|
145
|
+
continue; // file was read/grepped & in-bounds → verified
|
|
108
146
|
push({ kind: "fileline", value: `${basename}:${m[2]}`, text: `${basename}:${m[2]}` });
|
|
109
147
|
}
|
|
110
148
|
return out.slice(0, MAX_CLAIMS);
|