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
|
@@ -1,22 +1,37 @@
|
|
|
1
|
+
import type { ProviderId } from "../providers/types.js";
|
|
1
2
|
import type { ModelInfo, ReasoningEffort } from "../types/index.js";
|
|
3
|
+
import type { CatalogCouncilRouting, CatalogProviderPeakHour, CatalogVisionProxyRouting } from "./catalog-client.js";
|
|
2
4
|
export declare let MODELS: ModelInfo[];
|
|
3
5
|
export declare let isLoading: boolean;
|
|
6
|
+
export declare let SWITCH_PROVIDER_ORDER: readonly ProviderId[];
|
|
4
7
|
/**
|
|
5
|
-
* Load models from centralized catalog (
|
|
6
|
-
* Called once at boot. No provider API keys needed.
|
|
8
|
+
* Load models + routing policies from centralized catalog (API with static fallback).
|
|
7
9
|
*/
|
|
8
10
|
export declare function loadCatalog(): Promise<void>;
|
|
11
|
+
export declare function getProviderPeakHourRule(providerId: string): CatalogProviderPeakHour | undefined;
|
|
12
|
+
/** Catalog-defined default council lineup (multi-provider debate slots). */
|
|
13
|
+
export declare function getCatalogCouncilRouting(): CatalogCouncilRouting | undefined;
|
|
14
|
+
export declare function getVisionProxyRouting(): CatalogVisionProxyRouting | undefined;
|
|
9
15
|
export declare function getModelIds(): string[];
|
|
10
16
|
export declare function getModelInfo(idOrAlias: string): ModelInfo | undefined;
|
|
11
17
|
export declare function normalizeModelId(idOrAlias: string): string;
|
|
12
18
|
export declare function getEffectiveReasoningEffort(modelId: string, requestedEffort: ReasoningEffort | undefined): ReasoningEffort | undefined;
|
|
19
|
+
/** Returns true if the resolved model has built-in reasoning / extended thinking. */
|
|
20
|
+
export declare function isReasoningModel(modelId: string): boolean;
|
|
13
21
|
export declare function getSupportedReasoningEfforts(modelId: string): ReasoningEffort[];
|
|
14
|
-
/**
|
|
15
|
-
* Pick the first model matching a tier for a given provider.
|
|
16
|
-
* If no match for provider+tier, returns first model of that tier from any provider.
|
|
17
|
-
* Returns undefined if no models in that tier exist.
|
|
18
|
-
*/
|
|
19
22
|
export declare function getModelByTier(tier: "fast" | "balanced" | "premium", preferProvider?: string): ModelInfo | undefined;
|
|
20
23
|
export declare function getModelsForProvider(providerId: string): ModelInfo[];
|
|
24
|
+
/**
|
|
25
|
+
* Part E — does this model have NATIVE online web research (its own
|
|
26
|
+
* web_search/browsing/Live-Search)? Missing flag → false (safe default per the
|
|
27
|
+
* Kill #6 rule: never infer web capability from the provider).
|
|
28
|
+
*/
|
|
29
|
+
export declare function modelHasNativeWebResearch(idOrAlias: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* First catalog model with native web research (optionally constrained to a set
|
|
32
|
+
* of reachable model ids). Used by the council research phase to route the
|
|
33
|
+
* Researcher stance to a web-capable model. Returns undefined when none exist.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getWebResearchModel(reachableIds?: ReadonlySet<string>): ModelInfo | undefined;
|
|
21
36
|
export declare function getFirstCatalogModel(): ModelInfo;
|
|
22
37
|
export declare function getFirstCatalogProvider(): string;
|
|
@@ -1,19 +1,33 @@
|
|
|
1
|
-
import { catalogModelToModelInfo,
|
|
1
|
+
import { catalogModelToModelInfo, fetchCatalogDocument } from "./catalog-client.js";
|
|
2
2
|
const ALL_REASONING_EFFORTS = ["low", "medium", "high", "xhigh"];
|
|
3
|
+
const DEFAULT_SWITCH_PROVIDER_ORDER = ["deepseek", "zai", "opencode-go", "xai"];
|
|
3
4
|
// ---------------------------------------------------------------------------
|
|
4
5
|
// Centralized model registry — populated by loadCatalog() at boot
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
7
|
export let MODELS = [];
|
|
7
8
|
export let isLoading = true;
|
|
9
|
+
export let SWITCH_PROVIDER_ORDER = DEFAULT_SWITCH_PROVIDER_ORDER;
|
|
10
|
+
const providerPeakHourRules = new Map();
|
|
11
|
+
let catalogCouncilRouting;
|
|
12
|
+
let catalogVisionProxyRouting;
|
|
8
13
|
/**
|
|
9
|
-
* Load models from centralized catalog (
|
|
10
|
-
* Called once at boot. No provider API keys needed.
|
|
14
|
+
* Load models + routing policies from centralized catalog (API with static fallback).
|
|
11
15
|
*/
|
|
12
16
|
export async function loadCatalog() {
|
|
13
17
|
isLoading = true;
|
|
14
18
|
try {
|
|
15
|
-
const
|
|
16
|
-
MODELS =
|
|
19
|
+
const doc = await fetchCatalogDocument();
|
|
20
|
+
MODELS = doc.models.map(catalogModelToModelInfo);
|
|
21
|
+
SWITCH_PROVIDER_ORDER = doc.routing?.switch_provider_order ?? [
|
|
22
|
+
...DEFAULT_SWITCH_PROVIDER_ORDER,
|
|
23
|
+
];
|
|
24
|
+
providerPeakHourRules.clear();
|
|
25
|
+
for (const [providerId, policy] of Object.entries(doc.provider_policies ?? {})) {
|
|
26
|
+
if (policy.peak_hour)
|
|
27
|
+
providerPeakHourRules.set(providerId, policy.peak_hour);
|
|
28
|
+
}
|
|
29
|
+
catalogCouncilRouting = doc.routing?.council;
|
|
30
|
+
catalogVisionProxyRouting = doc.routing?.vision_proxy;
|
|
17
31
|
}
|
|
18
32
|
catch {
|
|
19
33
|
// On total failure, MODELS stays empty — callers must handle
|
|
@@ -22,6 +36,16 @@ export async function loadCatalog() {
|
|
|
22
36
|
isLoading = false;
|
|
23
37
|
}
|
|
24
38
|
}
|
|
39
|
+
export function getProviderPeakHourRule(providerId) {
|
|
40
|
+
return providerPeakHourRules.get(providerId);
|
|
41
|
+
}
|
|
42
|
+
/** Catalog-defined default council lineup (multi-provider debate slots). */
|
|
43
|
+
export function getCatalogCouncilRouting() {
|
|
44
|
+
return catalogCouncilRouting;
|
|
45
|
+
}
|
|
46
|
+
export function getVisionProxyRouting() {
|
|
47
|
+
return catalogVisionProxyRouting;
|
|
48
|
+
}
|
|
25
49
|
// ---------------------------------------------------------------------------
|
|
26
50
|
// Lookup helpers
|
|
27
51
|
// ---------------------------------------------------------------------------
|
|
@@ -29,7 +53,22 @@ export function getModelIds() {
|
|
|
29
53
|
return MODELS.map((m) => m.id);
|
|
30
54
|
}
|
|
31
55
|
export function getModelInfo(idOrAlias) {
|
|
32
|
-
|
|
56
|
+
const direct = MODELS.find((m) => m.id === idOrAlias || m.aliases?.includes(idOrAlias));
|
|
57
|
+
if (direct)
|
|
58
|
+
return direct;
|
|
59
|
+
// Gateway-prefix fallback: some routers/persisted configs prefix the model
|
|
60
|
+
// id with the gateway they came through (e.g. "opencode/deepseek-v4-flash",
|
|
61
|
+
// "deepseek-ai/DeepSeek-V4-Flash"). The native provider API rejects the
|
|
62
|
+
// prefixed form. Retry with the last path segment so the canonical catalog
|
|
63
|
+
// entry (and its provider) still resolves instead of leaking a dead id to
|
|
64
|
+
// runtime. Only matches when the stripped segment is a real catalog id/alias,
|
|
65
|
+
// so a non-catalog id still returns undefined (no false positives).
|
|
66
|
+
const slash = idOrAlias.lastIndexOf("/");
|
|
67
|
+
if (slash >= 0 && slash < idOrAlias.length - 1) {
|
|
68
|
+
const tail = idOrAlias.slice(slash + 1);
|
|
69
|
+
return MODELS.find((m) => m.id === tail || m.aliases?.includes(tail));
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
33
72
|
}
|
|
34
73
|
export function normalizeModelId(idOrAlias) {
|
|
35
74
|
const m = getModelInfo(idOrAlias);
|
|
@@ -43,6 +82,10 @@ export function getEffectiveReasoningEffort(modelId, requestedEffort) {
|
|
|
43
82
|
return undefined;
|
|
44
83
|
return requestedEffort;
|
|
45
84
|
}
|
|
85
|
+
/** Returns true if the resolved model has built-in reasoning / extended thinking. */
|
|
86
|
+
export function isReasoningModel(modelId) {
|
|
87
|
+
return getModelInfo(modelId)?.reasoning ?? false;
|
|
88
|
+
}
|
|
46
89
|
export function getSupportedReasoningEfforts(modelId) {
|
|
47
90
|
const info = getModelInfo(modelId);
|
|
48
91
|
if (!info?.reasoning)
|
|
@@ -54,17 +97,37 @@ export function getSupportedReasoningEfforts(modelId) {
|
|
|
54
97
|
* If no match for provider+tier, returns first model of that tier from any provider.
|
|
55
98
|
* Returns undefined if no models in that tier exist.
|
|
56
99
|
*/
|
|
100
|
+
function isTierRoutable(m) {
|
|
101
|
+
return m.tierRouting !== false;
|
|
102
|
+
}
|
|
103
|
+
function matchesTier(m, tier) {
|
|
104
|
+
return m.tier === tier || m.routingTiers?.includes(tier) === true;
|
|
105
|
+
}
|
|
57
106
|
export function getModelByTier(tier, preferProvider) {
|
|
58
107
|
if (preferProvider) {
|
|
59
|
-
|
|
60
|
-
if (providerMatch)
|
|
61
|
-
return providerMatch;
|
|
108
|
+
return MODELS.find((m) => matchesTier(m, tier) && m.provider === preferProvider && isTierRoutable(m));
|
|
62
109
|
}
|
|
63
|
-
return MODELS.find((m) => m
|
|
110
|
+
return MODELS.find((m) => matchesTier(m, tier) && isTierRoutable(m));
|
|
64
111
|
}
|
|
65
112
|
export function getModelsForProvider(providerId) {
|
|
66
113
|
return MODELS.filter((m) => m.provider === providerId);
|
|
67
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Part E — does this model have NATIVE online web research (its own
|
|
117
|
+
* web_search/browsing/Live-Search)? Missing flag → false (safe default per the
|
|
118
|
+
* Kill #6 rule: never infer web capability from the provider).
|
|
119
|
+
*/
|
|
120
|
+
export function modelHasNativeWebResearch(idOrAlias) {
|
|
121
|
+
return getModelInfo(idOrAlias)?.nativeWebResearch === true;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* First catalog model with native web research (optionally constrained to a set
|
|
125
|
+
* of reachable model ids). Used by the council research phase to route the
|
|
126
|
+
* Researcher stance to a web-capable model. Returns undefined when none exist.
|
|
127
|
+
*/
|
|
128
|
+
export function getWebResearchModel(reachableIds) {
|
|
129
|
+
return MODELS.find((m) => m.nativeWebResearch === true && isTierRoutable(m) && (!reachableIds || reachableIds.has(m.id)));
|
|
130
|
+
}
|
|
68
131
|
export function getFirstCatalogModel() {
|
|
69
132
|
const m = MODELS.find(() => true);
|
|
70
133
|
if (!m)
|
package/dist/src/ops/doctor.js
CHANGED
|
@@ -132,7 +132,7 @@ async function checkEEDetailed() {
|
|
|
132
132
|
// that contradicts a live ee_query working. See VERIFY F9.
|
|
133
133
|
if (!serverOk) {
|
|
134
134
|
const hint = result.mode === "thin-client"
|
|
135
|
-
? "Hint: check VPS
|
|
135
|
+
? "Hint: check VPS experience.muonroi.com is reachable; verify ~/.experience/config.json serverBaseUrl + serverReadAuthToken"
|
|
136
136
|
: "Hint: start EE locally or configure thin-client in ~/.experience/config.json";
|
|
137
137
|
return {
|
|
138
138
|
name: "ee.health",
|
|
@@ -169,9 +169,9 @@ async function checkBrainEmptiness() {
|
|
|
169
169
|
// Count ee_injection events with event_subtype='no_match' in last 30 days
|
|
170
170
|
const cutoff = new Date(Date.now() - 30 * 86_400_000).toISOString();
|
|
171
171
|
const row = db
|
|
172
|
-
.prepare(`SELECT COUNT(*) as cnt FROM interaction_logs
|
|
173
|
-
WHERE event_type = 'ee_injection'
|
|
174
|
-
AND event_subtype = 'no_match'
|
|
172
|
+
.prepare(`SELECT COUNT(*) as cnt FROM interaction_logs
|
|
173
|
+
WHERE event_type = 'ee_injection'
|
|
174
|
+
AND event_subtype = 'no_match'
|
|
175
175
|
AND created_at >= ?`)
|
|
176
176
|
.get(cutoff);
|
|
177
177
|
const noMatchCount = row?.cnt ?? 0;
|
|
@@ -293,10 +293,10 @@ async function checkCouncilMcpNudge() {
|
|
|
293
293
|
// 2. Query DB for [Council Memory] records with URL or research topics
|
|
294
294
|
const db = getDatabase();
|
|
295
295
|
const rows = db
|
|
296
|
-
.prepare(`SELECT message_json FROM messages
|
|
297
|
-
WHERE role = 'system'
|
|
298
|
-
AND message_json LIKE '%[Council Memory]%'
|
|
299
|
-
ORDER BY created_at DESC
|
|
296
|
+
.prepare(`SELECT message_json FROM messages
|
|
297
|
+
WHERE role = 'system'
|
|
298
|
+
AND message_json LIKE '%[Council Memory]%'
|
|
299
|
+
ORDER BY created_at DESC
|
|
300
300
|
LIMIT 50`)
|
|
301
301
|
.all();
|
|
302
302
|
let qualifyingCount = 0;
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
* cannot inject shell commands.
|
|
22
22
|
*/
|
|
23
23
|
import { execFile } from "node:child_process";
|
|
24
|
-
import { logger } from "../utils/logger.js";
|
|
25
24
|
import { resolve } from "node:path";
|
|
26
25
|
import { promisify } from "node:util";
|
|
26
|
+
import { logger } from "../utils/logger.js";
|
|
27
27
|
const pexecFile = promisify(execFile);
|
|
28
28
|
/** Attribution line every auto-commit message ends with (mirrors the prompt rule). */
|
|
29
29
|
export const AUTO_COMMIT_ATTRIBUTION = "Coding by - Muonroi-CLI";
|
|
@@ -133,7 +133,7 @@ export class BatchTurnRunner {
|
|
|
133
133
|
const batchRequestId = `turn-${Date.now()}-${stepNumber}`;
|
|
134
134
|
// Phase O1 — capture providerOptions SHAPE for batch path too.
|
|
135
135
|
deps.setLastProviderOptionsShape(extractProviderOptionsShape(runtime.providerOptions));
|
|
136
|
-
const _messagesForCall = deps.messages.map((m) =>
|
|
136
|
+
const _messagesForCall = deps.messages.map((m) => m === args.userModelMessage ? args.userEnrichedMessage : m);
|
|
137
137
|
await addBatchRequests({
|
|
138
138
|
...deps.getBatchClientOptions(signal),
|
|
139
139
|
batchId: batch.batch_id,
|
|
@@ -145,7 +145,7 @@ export class BatchTurnRunner {
|
|
|
145
145
|
modelId: runtime.modelId,
|
|
146
146
|
system,
|
|
147
147
|
messages: [..._messagesForCall, ...turnMessages],
|
|
148
|
-
temperature: 0.7,
|
|
148
|
+
temperature: runtime.modelInfo?.fixedTemperature ?? 0.7,
|
|
149
149
|
maxOutputTokens: !batchCaps.acceptsParam("maxOutputTokens", runtime.modelInfo)
|
|
150
150
|
? undefined
|
|
151
151
|
: deps.maxTokens,
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-Claude prompt-cache prefix stability (Task 3).
|
|
3
|
+
*
|
|
4
|
+
* On non-Claude providers (DeepSeek / GLM / other OpenAI-compatible backends)
|
|
5
|
+
* the whole system prompt is sent as a single string. Any per-turn-varying
|
|
6
|
+
* content that sits AFTER the byte-stable `staticPrefix` but BEFORE the
|
|
7
|
+
* conversation — the `dynamicSuffix` (plan / resume / cwd), the PIL output
|
|
8
|
+
* suffix, and the live MCP capability roster — shifts the cached prefix and
|
|
9
|
+
* forces a full cache miss on PIL-active turns. Measured: `pil_active=1` ⟺
|
|
10
|
+
* `cache_read=0` on 12/12 calls (session `47a774d272da`).
|
|
11
|
+
*
|
|
12
|
+
* Fix (variant b): split the assembled system string at the END of
|
|
13
|
+
* `staticPrefix`. The front stays as the `system` string; the dynamic tail is
|
|
14
|
+
* relocated into the trailing user message (see `foldDynamicTailIntoUserMessage`)
|
|
15
|
+
* rather than emitted as a mid-conversation system-role message, because
|
|
16
|
+
* OpenAI-compatible providers do not reliably accept a non-leading system role.
|
|
17
|
+
*
|
|
18
|
+
* IMPORTANT fast-tier caveat: for fast-tier models the cheap-model workbook /
|
|
19
|
+
* playbook / shell directive are front-loaded BEFORE `staticPrefix` for primacy,
|
|
20
|
+
* and the workbook's task addendum covaries with `taskType` (== `pil_active`).
|
|
21
|
+
* That portion still shifts the prefix and is a deliberate primacy design, so
|
|
22
|
+
* this split does NOT relocate it — the front is fully byte-stable only for
|
|
23
|
+
* non-fast-tier non-Claude models (the expensive-model path, which is where the
|
|
24
|
+
* cache payoff is per the plan). See task-3-report.md for the residual analysis.
|
|
25
|
+
*
|
|
26
|
+
* The Claude path keeps its own two-block cache split upstream and MUST NOT be
|
|
27
|
+
* routed through this helper.
|
|
28
|
+
*/
|
|
29
|
+
export interface FrontTailSplit {
|
|
30
|
+
/** The byte-stable front to send as the `system` string. */
|
|
31
|
+
front: string;
|
|
32
|
+
/** The per-turn-dynamic tail to relocate into the trailing user message. */
|
|
33
|
+
dynamicTail: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Split an assembled non-Claude system string into a byte-stable front and a
|
|
37
|
+
* per-turn-dynamic tail, cutting at the end of `staticPrefix`.
|
|
38
|
+
*
|
|
39
|
+
* Uses the established provider-family detection (`modelId.startsWith("claude")`)
|
|
40
|
+
* so the Claude branch is a no-op guard. If `staticPrefix` cannot be located in
|
|
41
|
+
* `systemWithCaps` (unexpected), returns the whole string as `front` with an
|
|
42
|
+
* empty tail so no instruction content is ever dropped.
|
|
43
|
+
*/
|
|
44
|
+
export declare function splitFrontAndDynamicTail(params: {
|
|
45
|
+
modelId: string;
|
|
46
|
+
systemWithCaps: string;
|
|
47
|
+
staticPrefix: string;
|
|
48
|
+
}): FrontTailSplit;
|
|
49
|
+
/**
|
|
50
|
+
* `assembleFrontSystem` — thin convenience wrapper returning only the byte-stable
|
|
51
|
+
* front (the value sent as the `system` string). Named to match the plan's
|
|
52
|
+
* invariant-test contract.
|
|
53
|
+
*/
|
|
54
|
+
export declare function assembleFrontSystem(params: {
|
|
55
|
+
modelId: string;
|
|
56
|
+
systemWithCaps: string;
|
|
57
|
+
staticPrefix: string;
|
|
58
|
+
}): string;
|
|
59
|
+
/**
|
|
60
|
+
* Fold a relocated dynamic tail into a user message's content. Handles both
|
|
61
|
+
* string content and structured (array-of-parts) content. Returns the message
|
|
62
|
+
* unchanged when the tail is empty. Never mutates the input.
|
|
63
|
+
*/
|
|
64
|
+
export declare function foldDynamicTailIntoUserMessage<T extends {
|
|
65
|
+
role: unknown;
|
|
66
|
+
content: unknown;
|
|
67
|
+
}>(msg: T, dynamicTail: string): T;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-Claude prompt-cache prefix stability (Task 3).
|
|
3
|
+
*
|
|
4
|
+
* On non-Claude providers (DeepSeek / GLM / other OpenAI-compatible backends)
|
|
5
|
+
* the whole system prompt is sent as a single string. Any per-turn-varying
|
|
6
|
+
* content that sits AFTER the byte-stable `staticPrefix` but BEFORE the
|
|
7
|
+
* conversation — the `dynamicSuffix` (plan / resume / cwd), the PIL output
|
|
8
|
+
* suffix, and the live MCP capability roster — shifts the cached prefix and
|
|
9
|
+
* forces a full cache miss on PIL-active turns. Measured: `pil_active=1` ⟺
|
|
10
|
+
* `cache_read=0` on 12/12 calls (session `47a774d272da`).
|
|
11
|
+
*
|
|
12
|
+
* Fix (variant b): split the assembled system string at the END of
|
|
13
|
+
* `staticPrefix`. The front stays as the `system` string; the dynamic tail is
|
|
14
|
+
* relocated into the trailing user message (see `foldDynamicTailIntoUserMessage`)
|
|
15
|
+
* rather than emitted as a mid-conversation system-role message, because
|
|
16
|
+
* OpenAI-compatible providers do not reliably accept a non-leading system role.
|
|
17
|
+
*
|
|
18
|
+
* IMPORTANT fast-tier caveat: for fast-tier models the cheap-model workbook /
|
|
19
|
+
* playbook / shell directive are front-loaded BEFORE `staticPrefix` for primacy,
|
|
20
|
+
* and the workbook's task addendum covaries with `taskType` (== `pil_active`).
|
|
21
|
+
* That portion still shifts the prefix and is a deliberate primacy design, so
|
|
22
|
+
* this split does NOT relocate it — the front is fully byte-stable only for
|
|
23
|
+
* non-fast-tier non-Claude models (the expensive-model path, which is where the
|
|
24
|
+
* cache payoff is per the plan). See task-3-report.md for the residual analysis.
|
|
25
|
+
*
|
|
26
|
+
* The Claude path keeps its own two-block cache split upstream and MUST NOT be
|
|
27
|
+
* routed through this helper.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Split an assembled non-Claude system string into a byte-stable front and a
|
|
31
|
+
* per-turn-dynamic tail, cutting at the end of `staticPrefix`.
|
|
32
|
+
*
|
|
33
|
+
* Uses the established provider-family detection (`modelId.startsWith("claude")`)
|
|
34
|
+
* so the Claude branch is a no-op guard. If `staticPrefix` cannot be located in
|
|
35
|
+
* `systemWithCaps` (unexpected), returns the whole string as `front` with an
|
|
36
|
+
* empty tail so no instruction content is ever dropped.
|
|
37
|
+
*/
|
|
38
|
+
export function splitFrontAndDynamicTail(params) {
|
|
39
|
+
const { modelId, systemWithCaps, staticPrefix } = params;
|
|
40
|
+
// Claude is handled by its own two-block ephemeral-cache split — never here.
|
|
41
|
+
if (modelId.startsWith("claude") || staticPrefix.length === 0) {
|
|
42
|
+
return { front: systemWithCaps, dynamicTail: "" };
|
|
43
|
+
}
|
|
44
|
+
const anchor = systemWithCaps.indexOf(staticPrefix);
|
|
45
|
+
if (anchor < 0) {
|
|
46
|
+
// staticPrefix not found — do not risk relocating (and possibly dropping)
|
|
47
|
+
// content we cannot precisely locate. Keep the original single string.
|
|
48
|
+
return { front: systemWithCaps, dynamicTail: "" };
|
|
49
|
+
}
|
|
50
|
+
const splitAt = anchor + staticPrefix.length;
|
|
51
|
+
return {
|
|
52
|
+
front: systemWithCaps.slice(0, splitAt),
|
|
53
|
+
dynamicTail: systemWithCaps.slice(splitAt),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* `assembleFrontSystem` — thin convenience wrapper returning only the byte-stable
|
|
58
|
+
* front (the value sent as the `system` string). Named to match the plan's
|
|
59
|
+
* invariant-test contract.
|
|
60
|
+
*/
|
|
61
|
+
export function assembleFrontSystem(params) {
|
|
62
|
+
return splitFrontAndDynamicTail(params).front;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Fold a relocated dynamic tail into a user message's content. Handles both
|
|
66
|
+
* string content and structured (array-of-parts) content. Returns the message
|
|
67
|
+
* unchanged when the tail is empty. Never mutates the input.
|
|
68
|
+
*/
|
|
69
|
+
export function foldDynamicTailIntoUserMessage(msg, dynamicTail) {
|
|
70
|
+
if (dynamicTail.trim().length === 0)
|
|
71
|
+
return msg;
|
|
72
|
+
const block = `\n\n---\n[Session context — working directory, task guidance, and available tools]\n${dynamicTail.trim()}`;
|
|
73
|
+
const content = msg.content;
|
|
74
|
+
if (typeof content === "string") {
|
|
75
|
+
return { ...msg, content: `${content}${block}` };
|
|
76
|
+
}
|
|
77
|
+
if (Array.isArray(content)) {
|
|
78
|
+
return { ...msg, content: [...content, { type: "text", text: block }] };
|
|
79
|
+
}
|
|
80
|
+
// Unknown content shape — do not risk corrupting it; leave unchanged.
|
|
81
|
+
return msg;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=cache-prefix.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/orchestrator/compact-request.ts
|
|
3
|
+
*
|
|
4
|
+
* Process-global one-shot channel for an AGENT-initiated proactive compaction.
|
|
5
|
+
*
|
|
6
|
+
* The `compact` tool (src/tools/registry.ts) sets a pending request when the
|
|
7
|
+
* model decides to free context mid-task; the tool-engine `prepareStep`
|
|
8
|
+
* boundary consumes it exactly once and forces a compaction of the accumulated
|
|
9
|
+
* tool/conversation history BEFORE the next LLM step, then continues the turn.
|
|
10
|
+
* This is the proactive counterpart to the reactive tool-limit auto-recover
|
|
11
|
+
* (tool-limit-auto-recover.ts): the agent no longer has to hit a round cap to
|
|
12
|
+
* shed context — it can ask for a clean history the moment it judges the turn
|
|
13
|
+
* has gone read-heavy, avoiding the interruption entirely.
|
|
14
|
+
*
|
|
15
|
+
* Single-active-turn assumption: the TUI streams one turn at a time, so a
|
|
16
|
+
* process-global slot is sufficient and cannot cross-talk between concurrent
|
|
17
|
+
* user turns. A nested sub-session runs within its parent's turn and consumes
|
|
18
|
+
* the flag on its own next step — worst case a harmless extra compaction, never
|
|
19
|
+
* data loss (compaction is snapshot + rehydratable via ee_query).
|
|
20
|
+
*/
|
|
21
|
+
export interface ProactiveCompactRequestState {
|
|
22
|
+
/** Optional focus note the model wants preserved in mind after compaction. */
|
|
23
|
+
instructions: string | null;
|
|
24
|
+
}
|
|
25
|
+
/** Queue a proactive compaction to run before the next tool-loop step. */
|
|
26
|
+
export declare function requestProactiveCompact(instructions?: string | null): void;
|
|
27
|
+
/** True when a proactive compaction is queued (non-consuming peek). */
|
|
28
|
+
export declare function hasPendingProactiveCompact(): boolean;
|
|
29
|
+
/** Consume the pending request exactly once (returns null when none queued). */
|
|
30
|
+
export declare function consumeProactiveCompact(): ProactiveCompactRequestState | null;
|
|
31
|
+
/** Test hook — clear any queued request. */
|
|
32
|
+
export declare function __resetProactiveCompactForTests(): void;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/orchestrator/compact-request.ts
|
|
3
|
+
*
|
|
4
|
+
* Process-global one-shot channel for an AGENT-initiated proactive compaction.
|
|
5
|
+
*
|
|
6
|
+
* The `compact` tool (src/tools/registry.ts) sets a pending request when the
|
|
7
|
+
* model decides to free context mid-task; the tool-engine `prepareStep`
|
|
8
|
+
* boundary consumes it exactly once and forces a compaction of the accumulated
|
|
9
|
+
* tool/conversation history BEFORE the next LLM step, then continues the turn.
|
|
10
|
+
* This is the proactive counterpart to the reactive tool-limit auto-recover
|
|
11
|
+
* (tool-limit-auto-recover.ts): the agent no longer has to hit a round cap to
|
|
12
|
+
* shed context — it can ask for a clean history the moment it judges the turn
|
|
13
|
+
* has gone read-heavy, avoiding the interruption entirely.
|
|
14
|
+
*
|
|
15
|
+
* Single-active-turn assumption: the TUI streams one turn at a time, so a
|
|
16
|
+
* process-global slot is sufficient and cannot cross-talk between concurrent
|
|
17
|
+
* user turns. A nested sub-session runs within its parent's turn and consumes
|
|
18
|
+
* the flag on its own next step — worst case a harmless extra compaction, never
|
|
19
|
+
* data loss (compaction is snapshot + rehydratable via ee_query).
|
|
20
|
+
*/
|
|
21
|
+
let pending = null;
|
|
22
|
+
/** Queue a proactive compaction to run before the next tool-loop step. */
|
|
23
|
+
export function requestProactiveCompact(instructions) {
|
|
24
|
+
const trimmed = typeof instructions === "string" ? instructions.trim() : "";
|
|
25
|
+
pending = { instructions: trimmed.length > 0 ? trimmed : null };
|
|
26
|
+
}
|
|
27
|
+
/** True when a proactive compaction is queued (non-consuming peek). */
|
|
28
|
+
export function hasPendingProactiveCompact() {
|
|
29
|
+
return pending !== null;
|
|
30
|
+
}
|
|
31
|
+
/** Consume the pending request exactly once (returns null when none queued). */
|
|
32
|
+
export function consumeProactiveCompact() {
|
|
33
|
+
const p = pending;
|
|
34
|
+
pending = null;
|
|
35
|
+
return p;
|
|
36
|
+
}
|
|
37
|
+
/** Test hook — clear any queued request. */
|
|
38
|
+
export function __resetProactiveCompactForTests() {
|
|
39
|
+
pending = null;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=compact-request.js.map
|
|
@@ -56,6 +56,16 @@ export declare function getCompactionSummaryText(message: ModelMessage | undefin
|
|
|
56
56
|
export declare function estimateMessageTokens(message: ModelMessage): number;
|
|
57
57
|
export declare function estimateConversationTokens(systemPrompt: string, messages: ModelMessage[], inFlightText?: string): number;
|
|
58
58
|
export declare function shouldCompactContext(contextTokens: number, contextWindow: number, settings: CompactionSettings): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Cross-turn anti-thrash guard: true when a post-turn compaction should be
|
|
61
|
+
* SKIPPED because too few new tokens have accumulated since the last
|
|
62
|
+
* compaction's `tokensAfter` — i.e. the cache-reset cost would not be
|
|
63
|
+
* amortized (observed: session ff932f8568e8 re-compacted after only ~14K
|
|
64
|
+
* new tokens against a 20K floor).
|
|
65
|
+
*
|
|
66
|
+
* `lastAfter === null` means no prior compaction this session — never skip.
|
|
67
|
+
*/
|
|
68
|
+
export declare function isCompactionThrash(tokens: number, lastAfter: number | null, minNew: number): boolean;
|
|
59
69
|
export declare function findCutPoint(messages: ModelMessage[], startIndex: number, keepRecentTokens: number): CutPointResult;
|
|
60
70
|
export declare function prepareCompaction(messages: ModelMessage[], systemPrompt: string, settings: CompactionSettings): PreparedCompaction | null;
|
|
61
71
|
export declare function relaxCompactionSettings(settings: CompactionSettings): CompactionSettings;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { generateText } from "ai";
|
|
2
2
|
import { isMetaAnalysisPrompt } from "../pil/layer6-output.js";
|
|
3
3
|
import { getProviderCapabilities } from "../providers/capabilities.js";
|
|
4
|
-
import { requireRuntimeProvider, resolveModelRuntime } from "../providers/runtime.js";
|
|
4
|
+
import { requireRuntimeProvider, resolveModelRuntime, resolveTemperatureParam } from "../providers/runtime.js";
|
|
5
|
+
import { logger } from "../utils/logger.js";
|
|
5
6
|
import { COMPACT_PROPOSER_SYSTEM_PROMPT } from "./compaction-proposer-prompt.js";
|
|
6
7
|
import { containsEncryptedReasoning } from "./reasoning.js";
|
|
7
8
|
import { countTokens } from "./token-counter.js";
|
|
@@ -21,28 +22,35 @@ export async function proposeCompaction(provider, modelId, messages, signal) {
|
|
|
21
22
|
prompt: `Current conversation messages:\n\n${serialized}\n\nDecide if compaction is needed and what to keep/drop/summarize. Return strict JSON.`,
|
|
22
23
|
abortSignal: signal,
|
|
23
24
|
maxRetries: 1,
|
|
24
|
-
|
|
25
|
+
...resolveTemperatureParam(runtime, 0.1),
|
|
25
26
|
...(!compactCaps.acceptsParam("maxOutputTokens", runtime.modelInfo) ? {} : { maxOutputTokens: 2048 }),
|
|
26
27
|
...(runtime.providerOptions ? { providerOptions: runtime.providerOptions } : {}),
|
|
27
28
|
});
|
|
28
29
|
const text = result.text.trim();
|
|
29
|
-
// Attempt to parse
|
|
30
|
-
const
|
|
31
|
-
|
|
30
|
+
// Attempt to parse JSON object robustly, even if the model wraps it in conversational text or markdown fences.
|
|
31
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
32
|
+
if (!jsonMatch) {
|
|
33
|
+
logger.warn("orchestrator", "Failed to extract JSON from proposer output", { text });
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
32
37
|
// Validate shape
|
|
33
38
|
if (typeof parsed.shouldCompact !== "boolean" || !Array.isArray(parsed.actions)) {
|
|
39
|
+
logger.warn("orchestrator", "Invalid JSON shape from proposer", { parsed });
|
|
34
40
|
return null;
|
|
35
41
|
}
|
|
36
42
|
// Validate each action
|
|
37
43
|
for (const action of parsed.actions) {
|
|
38
44
|
if (typeof action.messageIndex !== "number" || !["keep", "drop", "summarize"].includes(action.action)) {
|
|
45
|
+
logger.warn("orchestrator", "Invalid action shape from proposer", { action });
|
|
39
46
|
return null;
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
return parsed;
|
|
43
50
|
}
|
|
44
|
-
catch {
|
|
51
|
+
catch (err) {
|
|
45
52
|
// Proposer failure is non-fatal — caller falls back to heuristic or no-compact
|
|
53
|
+
logger.warn("orchestrator", "Proposer failure", { error: err });
|
|
46
54
|
return null;
|
|
47
55
|
}
|
|
48
56
|
}
|
|
@@ -347,6 +355,18 @@ export function estimateConversationTokens(systemPrompt, messages, inFlightText
|
|
|
347
355
|
export function shouldCompactContext(contextTokens, contextWindow, settings) {
|
|
348
356
|
return contextTokens > contextWindow - settings.reserveTokens;
|
|
349
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Cross-turn anti-thrash guard: true when a post-turn compaction should be
|
|
360
|
+
* SKIPPED because too few new tokens have accumulated since the last
|
|
361
|
+
* compaction's `tokensAfter` — i.e. the cache-reset cost would not be
|
|
362
|
+
* amortized (observed: session ff932f8568e8 re-compacted after only ~14K
|
|
363
|
+
* new tokens against a 20K floor).
|
|
364
|
+
*
|
|
365
|
+
* `lastAfter === null` means no prior compaction this session — never skip.
|
|
366
|
+
*/
|
|
367
|
+
export function isCompactionThrash(tokens, lastAfter, minNew) {
|
|
368
|
+
return lastAfter !== null && tokens - lastAfter < minNew;
|
|
369
|
+
}
|
|
350
370
|
function isValidCutPoint(message) {
|
|
351
371
|
return message.role !== "tool";
|
|
352
372
|
}
|
|
@@ -523,7 +543,7 @@ async function summarizeConversation(provider, modelId, messages, reserveTokens,
|
|
|
523
543
|
prompt: promptParts.filter(Boolean).join("\n\n"),
|
|
524
544
|
abortSignal: signal,
|
|
525
545
|
maxRetries: 0,
|
|
526
|
-
|
|
546
|
+
...resolveTemperatureParam(runtime, 0.2),
|
|
527
547
|
...(!compactCaps.acceptsParam("maxOutputTokens", runtime.modelInfo) ? {} : { maxOutputTokens: effectiveMax }),
|
|
528
548
|
...(runtime.providerOptions ? { providerOptions: runtime.providerOptions } : {}),
|
|
529
549
|
});
|
|
@@ -36,6 +36,12 @@ export interface CouncilManagerDeps {
|
|
|
36
36
|
export declare class CouncilManager {
|
|
37
37
|
private deps;
|
|
38
38
|
private _lastSynthesis;
|
|
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
|
+
private _lastPostDebateAction;
|
|
39
45
|
private _isContinuation;
|
|
40
46
|
private _questionResolvers;
|
|
41
47
|
private _preflightResolvers;
|
|
@@ -49,10 +55,12 @@ export declare class CouncilManager {
|
|
|
49
55
|
constructor(deps: CouncilManagerDeps);
|
|
50
56
|
get lastSynthesis(): string | null;
|
|
51
57
|
setLastSynthesis(v: string | null): void;
|
|
58
|
+
get lastPostDebateAction(): string | null;
|
|
59
|
+
setLastPostDebateAction(v: string | null): void;
|
|
52
60
|
get isContinuation(): boolean;
|
|
53
61
|
setContinuation(v: boolean): void;
|
|
54
62
|
resetStats(startMs?: number): void;
|
|
55
|
-
respondToQuestion(questionId: string, answer: string): void;
|
|
63
|
+
respondToQuestion(questionId: string, answer: string, questionText?: string): void;
|
|
56
64
|
respondToPreflight(preflightId: string, approved: boolean): void;
|
|
57
65
|
createQuestionResponder(): (questionId: string) => Promise<string>;
|
|
58
66
|
createPreflightResponder(): (preflightId: string) => Promise<boolean>;
|
|
@@ -84,8 +92,9 @@ export declare class CouncilManager {
|
|
|
84
92
|
generateRoundSummary(exchangeLogs: Map<string, string[]>, topic: string, round: number, modelId: string): Promise<string>;
|
|
85
93
|
/**
|
|
86
94
|
* Build conversation context for council discussion from current session messages.
|
|
87
|
-
* Extracts: compaction summary, recent user
|
|
88
|
-
*
|
|
95
|
+
* Extracts: compaction summary, recent conversation (user + analytical assistant),
|
|
96
|
+
* key decisions/outcomes/plans.
|
|
97
|
+
* Limited to ~8000 tokens (~32K chars) to balance depth vs cost.
|
|
89
98
|
*/
|
|
90
99
|
buildContext(): string;
|
|
91
100
|
parseOutcome(synthesisText: string, _topic: string): CouncilOutcome | null;
|