muonroi-cli 1.8.4 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -5
- package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
- package/dist/packages/agent-harness-core/src/driver.js +46 -0
- package/dist/packages/agent-harness-core/src/event-filter.js +11 -0
- package/dist/packages/agent-harness-core/src/event-redact.js +7 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +64 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +104 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +25 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +169 -21
- package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
- package/dist/packages/agent-harness-core/src/protocol.d.ts +90 -4
- package/dist/packages/agent-harness-core/src/protocol.js +15 -0
- package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
- package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
- package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
- package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
- package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
- package/dist/packages/agent-harness-opentui/src/install.js +10 -0
- package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
- package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
- package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
- package/dist/src/agent-harness/mock-model.d.ts +38 -0
- package/dist/src/agent-harness/mock-model.js +69 -3
- package/dist/src/agent-harness/test-spawn.js +31 -0
- package/dist/src/chat/chat-keychain.d.ts +7 -12
- package/dist/src/chat/chat-keychain.js +19 -86
- package/dist/src/cli/config/screen-providers.js +1 -1
- package/dist/src/cli/cost-forensics.d.ts +10 -0
- package/dist/src/cli/cost-forensics.js +18 -3
- package/dist/src/cli/keys-bundle.d.ts +1 -1
- package/dist/src/cli/keys-bundle.js +1 -1
- package/dist/src/cli/keys.d.ts +10 -47
- package/dist/src/cli/keys.js +31 -399
- package/dist/src/council/clarifier.d.ts +31 -3
- package/dist/src/council/clarifier.js +220 -32
- package/dist/src/council/context.js +49 -15
- package/dist/src/council/debate-checkpoint.d.ts +129 -0
- package/dist/src/council/debate-checkpoint.js +176 -0
- package/dist/src/council/debate-planner.js +54 -5
- package/dist/src/council/debate-summary.d.ts +25 -0
- package/dist/src/council/debate-summary.js +85 -0
- package/dist/src/council/debate.d.ts +169 -2
- package/dist/src/council/debate.js +1265 -135
- package/dist/src/council/index.d.ts +108 -1
- package/dist/src/council/index.js +670 -197
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +94 -0
- package/dist/src/council/llm.js +348 -55
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +82 -0
- package/dist/src/council/planner.js +40 -0
- package/dist/src/council/preflight.d.ts +17 -0
- package/dist/src/council/preflight.js +50 -2
- package/dist/src/council/prompts.d.ts +39 -4
- package/dist/src/council/prompts.js +256 -69
- package/dist/src/council/stance-recall.d.ts +42 -0
- package/dist/src/council/stance-recall.js +57 -0
- package/dist/src/council/strip-think.d.ts +17 -0
- package/dist/src/council/strip-think.js +33 -0
- package/dist/src/council/types.d.ts +138 -0
- package/dist/src/ee/artifact-cache.d.ts +16 -0
- package/dist/src/ee/artifact-cache.js +32 -0
- package/dist/src/ee/auth.d.ts +20 -0
- package/dist/src/ee/auth.js +54 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +109 -21
- package/dist/src/ee/ee-onboarding.js +6 -26
- package/dist/src/ee/export-transcripts.d.ts +1 -0
- package/dist/src/ee/export-transcripts.js +8 -10
- package/dist/src/ee/extract-session.js +29 -0
- package/dist/src/ee/extract-style.d.ts +58 -0
- package/dist/src/ee/extract-style.js +270 -0
- package/dist/src/ee/recall-ledger.d.ts +9 -0
- package/dist/src/ee/recall-ledger.js +3 -0
- package/dist/src/ee/scope.d.ts +1 -0
- package/dist/src/ee/scope.js +26 -1
- package/dist/src/ee/search.d.ts +7 -0
- package/dist/src/ee/search.js +24 -0
- package/dist/src/ee/transcript-emit.js +2 -0
- package/dist/src/ee/types.d.ts +22 -0
- package/dist/src/ee/who-am-i-brain.d.ts +35 -0
- package/dist/src/ee/who-am-i-brain.js +220 -0
- package/dist/src/ee/who-am-i.d.ts +10 -3
- package/dist/src/ee/who-am-i.js +12 -0
- package/dist/src/ee/workflow-event.d.ts +48 -0
- package/dist/src/ee/workflow-event.js +81 -0
- package/dist/src/flow/compaction/compress.d.ts +3 -3
- package/dist/src/flow/compaction/compress.js +58 -8
- package/dist/src/flow/compaction/extract.d.ts +4 -7
- package/dist/src/flow/compaction/extract.js +50 -10
- package/dist/src/flow/compaction/index.d.ts +14 -1
- package/dist/src/flow/compaction/index.js +96 -3
- package/dist/src/flow/compaction/input-guard.d.ts +24 -0
- package/dist/src/flow/compaction/input-guard.js +43 -0
- package/dist/src/flow/compaction/progress.d.ts +35 -0
- package/dist/src/flow/compaction/progress.js +35 -0
- package/dist/src/flow/fold-planning.d.ts +36 -0
- package/dist/src/flow/fold-planning.js +83 -0
- package/dist/src/flow/hierarchy.d.ts +146 -0
- package/dist/src/flow/hierarchy.js +427 -0
- package/dist/src/flow/index.d.ts +1 -0
- package/dist/src/flow/index.js +2 -0
- package/dist/src/flow/run-artifacts.d.ts +102 -0
- package/dist/src/flow/run-artifacts.js +208 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/assessment-schema.d.ts +44 -0
- package/dist/src/gsd/assessment-schema.js +134 -0
- package/dist/src/gsd/capability-registry.d.ts +45 -0
- package/dist/src/gsd/capability-registry.js +337 -0
- package/dist/src/gsd/complexity-assessor.d.ts +39 -0
- package/dist/src/gsd/complexity-assessor.js +152 -0
- package/dist/src/gsd/config-bridge.d.ts +7 -0
- package/dist/src/gsd/config-bridge.js +114 -0
- package/dist/src/gsd/config-loader.d.ts +27 -0
- package/dist/src/gsd/config-loader.js +50 -0
- package/dist/src/gsd/council-context.d.ts +44 -0
- package/dist/src/gsd/council-context.js +114 -0
- package/dist/src/gsd/ee-closure.d.ts +28 -0
- package/dist/src/gsd/ee-closure.js +49 -0
- package/dist/src/gsd/flags.d.ts +66 -0
- package/dist/src/gsd/flags.js +102 -0
- package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
- package/dist/src/gsd/gsd-dispatch.js +131 -0
- package/dist/src/gsd/gsd-runtime.d.ts +22 -0
- package/dist/src/gsd/gsd-runtime.js +37 -0
- package/dist/src/gsd/host-adapter.d.ts +11 -0
- package/dist/src/gsd/host-adapter.js +29 -0
- package/dist/src/gsd/index.d.ts +24 -1
- package/dist/src/gsd/index.js +27 -0
- package/dist/src/gsd/loop-host-contract.d.ts +21 -0
- package/dist/src/gsd/loop-host-contract.js +39 -0
- package/dist/src/gsd/loop-host.d.ts +69 -0
- package/dist/src/gsd/loop-host.js +245 -0
- package/dist/src/gsd/loop-resolver.d.ts +36 -0
- package/dist/src/gsd/loop-resolver.js +79 -0
- package/dist/src/gsd/model-tier.d.ts +13 -0
- package/dist/src/gsd/model-tier.js +45 -0
- package/dist/src/gsd/mutation-gate.d.ts +16 -0
- package/dist/src/gsd/mutation-gate.js +41 -0
- package/dist/src/gsd/native-roadmap.d.ts +89 -0
- package/dist/src/gsd/native-roadmap.js +343 -0
- package/dist/src/gsd/native-state.d.ts +47 -0
- package/dist/src/gsd/native-state.js +220 -0
- package/dist/src/gsd/paths.d.ts +23 -0
- package/dist/src/gsd/paths.js +66 -0
- package/dist/src/gsd/phase-dag.d.ts +12 -0
- package/dist/src/gsd/phase-dag.js +94 -0
- package/dist/src/gsd/phase-sync.d.ts +42 -0
- package/dist/src/gsd/phase-sync.js +321 -0
- package/dist/src/gsd/pil-gate-context.d.ts +13 -0
- package/dist/src/gsd/pil-gate-context.js +64 -0
- package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
- package/dist/src/gsd/pil-gate-critic.js +74 -0
- package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
- package/dist/src/gsd/plan-council-prompts.js +79 -0
- package/dist/src/gsd/plan-council.d.ts +44 -0
- package/dist/src/gsd/plan-council.js +283 -0
- package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
- package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
- package/dist/src/gsd/product-workspace.d.ts +13 -0
- package/dist/src/gsd/product-workspace.js +124 -0
- package/dist/src/gsd/ship-bridge.d.ts +25 -0
- package/dist/src/gsd/ship-bridge.js +65 -0
- package/dist/src/gsd/state-document.d.ts +40 -0
- package/dist/src/gsd/state-document.js +163 -0
- package/dist/src/gsd/verdict-schema.d.ts +39 -0
- package/dist/src/gsd/verdict-schema.js +144 -0
- package/dist/src/gsd/verify-context.d.ts +22 -0
- package/dist/src/gsd/verify-context.js +27 -0
- package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
- package/dist/src/gsd/verify-council-prompts.js +85 -0
- package/dist/src/gsd/verify-council.d.ts +25 -0
- package/dist/src/gsd/verify-council.js +119 -0
- package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
- package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
- package/dist/src/gsd/workflow-engine.d.ts +60 -0
- package/dist/src/gsd/workflow-engine.js +207 -0
- package/dist/src/gsd/workflow-tools.d.ts +13 -0
- package/dist/src/gsd/workflow-tools.js +277 -0
- package/dist/src/headless/council-answers.js +4 -0
- package/dist/src/hooks/index.js +1 -1
- package/dist/src/index.js +172 -270
- package/dist/src/lsp/builtins.js +3 -1
- package/dist/src/lsp/manager.d.ts +5 -1
- package/dist/src/lsp/manager.js +249 -3
- package/dist/src/lsp/npm-cache.d.ts +11 -1
- package/dist/src/lsp/npm-cache.js +17 -1
- package/dist/src/lsp/runtime.d.ts +6 -1
- package/dist/src/lsp/runtime.js +17 -1
- package/dist/src/lsp/types.d.ts +83 -1
- package/dist/src/lsp/types.js +10 -0
- package/dist/src/maintain/pr-builder.js +23 -13
- package/dist/src/mcp/auto-setup.js +57 -32
- package/dist/src/mcp/client-pool.js +44 -16
- package/dist/src/mcp/lsp-tools.d.ts +5 -1
- package/dist/src/mcp/lsp-tools.js +93 -2
- package/dist/src/mcp/mcp-keychain.d.ts +3 -5
- package/dist/src/mcp/mcp-keychain.js +9 -49
- package/dist/src/mcp/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -2
- package/dist/src/mcp/setup-guide-text.d.ts +1 -1
- package/dist/src/mcp/setup-guide-text.js +22 -2
- package/dist/src/mcp/tools-server.d.ts +10 -0
- package/dist/src/mcp/tools-server.js +10 -2
- package/dist/src/models/catalog-client.d.ts +87 -0
- package/dist/src/models/catalog-client.js +105 -38
- package/dist/src/models/catalog.json +528 -265
- package/dist/src/models/registry.d.ts +22 -7
- package/dist/src/models/registry.js +73 -10
- package/dist/src/ops/doctor.js +1 -1
- package/dist/src/orchestrator/ask-user.d.ts +61 -0
- package/dist/src/orchestrator/ask-user.js +65 -0
- package/dist/src/orchestrator/auto-commit.js +1 -1
- package/dist/src/orchestrator/batch-turn-runner.js +2 -2
- package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
- package/dist/src/orchestrator/cache-prefix.js +83 -0
- package/dist/src/orchestrator/compact-request.d.ts +32 -0
- package/dist/src/orchestrator/compact-request.js +41 -0
- package/dist/src/orchestrator/compaction.d.ts +12 -3
- package/dist/src/orchestrator/compaction.js +35 -15
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +74 -32
- package/dist/src/orchestrator/council-request.d.ts +49 -0
- package/dist/src/orchestrator/council-request.js +62 -0
- package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
- package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
- package/dist/src/orchestrator/error-utils.d.ts +29 -0
- package/dist/src/orchestrator/error-utils.js +132 -24
- package/dist/src/orchestrator/grounding-check.js +39 -1
- package/dist/src/orchestrator/interactive-pause.d.ts +26 -0
- package/dist/src/orchestrator/interactive-pause.js +36 -0
- package/dist/src/orchestrator/message-processor.d.ts +4 -0
- package/dist/src/orchestrator/message-processor.js +268 -41
- package/dist/src/orchestrator/orchestrator.d.ts +64 -3
- package/dist/src/orchestrator/orchestrator.js +823 -120
- package/dist/src/orchestrator/preprocessor.js +3 -3
- package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
- package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
- package/dist/src/orchestrator/prompts.js +17 -17
- package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
- package/dist/src/orchestrator/reactive-delegation.js +59 -0
- package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
- package/dist/src/orchestrator/retry-classifier.js +46 -2
- package/dist/src/orchestrator/safety-askcard.d.ts +1 -1
- package/dist/src/orchestrator/safety-askcard.js +5 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +50 -0
- package/dist/src/orchestrator/safety-intercept.js +62 -0
- package/dist/src/orchestrator/scope-reminder.js +1 -1
- package/dist/src/orchestrator/session-experience.d.ts +2 -1
- package/dist/src/orchestrator/session-experience.js +2 -1
- package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
- package/dist/src/orchestrator/should-run-gate.js +18 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +31 -3
- package/dist/src/orchestrator/stall-watchdog.js +65 -10
- package/dist/src/orchestrator/stream-runner.d.ts +13 -3
- package/dist/src/orchestrator/stream-runner.js +115 -49
- package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-cap.js +16 -1
- package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
- package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
- package/dist/src/orchestrator/subagent-compactor.js +126 -15
- package/dist/src/orchestrator/tool-engine.d.ts +41 -0
- package/dist/src/orchestrator/tool-engine.js +846 -66
- package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
- package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
- package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
- package/dist/src/orchestrator/turn-watchdog.d.ts +44 -0
- package/dist/src/orchestrator/turn-watchdog.js +84 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +6 -4
- package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
- package/dist/src/pil/cheap-model-playbook.js +5 -1
- package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
- package/dist/src/pil/cheap-model-workbooks.js +1 -1
- package/dist/src/pil/discovery-types.d.ts +1 -0
- package/dist/src/pil/discovery.d.ts +1 -1
- package/dist/src/pil/discovery.js +18 -13
- package/dist/src/pil/layer1-intent.d.ts +18 -6
- package/dist/src/pil/layer1-intent.js +66 -757
- package/dist/src/pil/layer15-context-scan.js +15 -1
- package/dist/src/pil/layer1_5-complexity-size.d.ts +7 -0
- package/dist/src/pil/layer1_5-complexity-size.js +31 -5
- package/dist/src/pil/layer3-ee-injection.js +23 -8
- package/dist/src/pil/layer4-gsd.js +69 -16
- package/dist/src/pil/layer5-context.js +7 -3
- package/dist/src/pil/layer6-output.d.ts +23 -0
- package/dist/src/pil/layer6-output.js +5 -1
- package/dist/src/pil/llm-classify.d.ts +111 -5
- package/dist/src/pil/llm-classify.js +421 -189
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +8 -0
- package/dist/src/pil/pipeline.js +36 -2
- package/dist/src/pil/repo-grounding-probe.d.ts +15 -0
- package/dist/src/pil/repo-grounding-probe.js +136 -0
- package/dist/src/pil/repo-structure-hints.d.ts +7 -0
- package/dist/src/pil/repo-structure-hints.js +45 -0
- package/dist/src/pil/response-tools.js +5 -3
- package/dist/src/pil/schema.d.ts +1 -0
- package/dist/src/pil/schema.js +2 -0
- package/dist/src/pil/types.d.ts +18 -0
- package/dist/src/playbook/directives.d.ts +4 -0
- package/dist/src/playbook/directives.js +17 -5
- package/dist/src/product-loop/artifact-io.js +4 -0
- package/dist/src/product-loop/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- package/dist/src/product-loop/criteria-seed.d.ts +51 -0
- package/dist/src/product-loop/criteria-seed.js +200 -0
- package/dist/src/product-loop/discovery-context-format.js +3 -1
- package/dist/src/product-loop/discovery-ecosystem.js +4 -1
- package/dist/src/product-loop/discovery-interview.d.ts +9 -0
- package/dist/src/product-loop/discovery-interview.js +60 -12
- package/dist/src/product-loop/discovery-recommender.js +2 -1
- package/dist/src/product-loop/discovery-schema.js +19 -2
- package/dist/src/product-loop/discovery-triage.d.ts +23 -0
- package/dist/src/product-loop/discovery-triage.js +109 -0
- package/dist/src/product-loop/gather.js +150 -2
- package/dist/src/product-loop/ideal-trace.d.ts +7 -0
- package/dist/src/product-loop/ideal-trace.js +64 -0
- package/dist/src/product-loop/index.d.ts +13 -1
- package/dist/src/product-loop/index.js +340 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +330 -106
- package/dist/src/product-loop/phase-plan.d.ts +21 -0
- package/dist/src/product-loop/phase-plan.js +81 -6
- package/dist/src/product-loop/phase-rituals.d.ts +3 -0
- package/dist/src/product-loop/phase-rituals.js +8 -3
- package/dist/src/product-loop/phase-runner.js +39 -12
- package/dist/src/product-loop/plan-adherence-review.d.ts +26 -0
- package/dist/src/product-loop/plan-adherence-review.js +144 -0
- package/dist/src/product-loop/sprint-runner.d.ts +173 -0
- package/dist/src/product-loop/sprint-runner.js +863 -19
- package/dist/src/product-loop/types.d.ts +61 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- package/dist/src/providers/anthropic.d.ts +9 -8
- package/dist/src/providers/anthropic.js +13 -47
- package/dist/src/providers/auth/browser-flow.d.ts +1 -1
- package/dist/src/providers/auth/browser-flow.js +1 -1
- package/dist/src/providers/auth/grok-oauth.d.ts +1 -0
- package/dist/src/providers/auth/grok-oauth.js +30 -5
- package/dist/src/providers/auth/openai-oauth.d.ts +1 -0
- package/dist/src/providers/auth/openai-oauth.js +15 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.d.ts +9 -9
- package/dist/src/providers/auth/token-store.js +8 -67
- package/dist/src/providers/auth/types.d.ts +9 -1
- package/dist/src/providers/auth/types.js +1 -1
- package/dist/src/providers/capabilities.d.ts +24 -5
- package/dist/src/providers/capabilities.js +42 -24
- package/dist/src/providers/endpoints.d.ts +2 -2
- package/dist/src/providers/endpoints.js +11 -10
- package/dist/src/providers/env-store.d.ts +17 -0
- package/dist/src/providers/env-store.js +228 -0
- package/dist/src/providers/keychain.d.ts +22 -18
- package/dist/src/providers/keychain.js +127 -140
- package/dist/src/providers/mcp-vision-bridge.js +56 -146
- package/dist/src/providers/openai-compatible.js +8 -1
- package/dist/src/providers/pricing.d.ts +2 -2
- package/dist/src/providers/pricing.js +3 -13
- package/dist/src/providers/runtime.d.ts +43 -3
- package/dist/src/providers/runtime.js +88 -14
- package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
- package/dist/src/providers/strategies/base.strategy.js +24 -1
- package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
- package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
- package/dist/src/providers/strategies/registry.js +4 -4
- package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
- package/dist/src/providers/strategies/thinking-mode.js +288 -1
- package/dist/src/providers/strategies/xai.strategy.js +27 -0
- package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
- package/dist/src/providers/strategies/zai.strategy.js +44 -0
- package/dist/src/providers/types.d.ts +5 -6
- package/dist/src/providers/types.js +2 -2
- package/dist/src/providers/vision-backend.d.ts +47 -0
- package/dist/src/providers/vision-backend.js +258 -0
- package/dist/src/providers/vision-proxy.d.ts +22 -9
- package/dist/src/providers/vision-proxy.js +63 -132
- package/dist/src/providers/warm.d.ts +65 -0
- package/dist/src/providers/warm.js +145 -0
- package/dist/src/providers/wire-debug.js +95 -0
- package/dist/src/router/decide.d.ts +13 -0
- package/dist/src/router/decide.js +138 -36
- package/dist/src/router/peak-hour.d.ts +38 -0
- package/dist/src/router/peak-hour.js +107 -0
- package/dist/src/router/step-router.js +3 -2
- package/dist/src/router/warm.js +4 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +26 -0
- package/dist/src/scaffold/point-to-existing.d.ts +21 -0
- package/dist/src/scaffold/point-to-existing.js +25 -0
- package/dist/src/self-qa/agentic-loop.js +6 -5
- package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
- package/dist/src/{ui/state → state}/active-run.js +21 -0
- package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
- package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
- package/dist/src/state/turn-trace.d.ts +43 -0
- package/dist/src/state/turn-trace.js +32 -0
- package/dist/src/storage/db.js +2 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/interaction-log.d.ts +1 -1
- package/dist/src/storage/migrations.js +71 -1
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +78 -21
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +340 -15
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/git-safety.d.ts +19 -0
- package/dist/src/tools/git-safety.js +168 -0
- package/dist/src/tools/native-tools.d.ts +1 -1
- package/dist/src/tools/native-tools.js +81 -1
- package/dist/src/tools/registry.d.ts +20 -0
- package/dist/src/tools/registry.js +576 -23
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +147 -4
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- package/dist/src/ui/components/agent-rail-activities.d.ts +26 -0
- package/dist/src/ui/components/agent-rail-activities.js +47 -0
- package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
- package/dist/src/ui/components/bubble-body-guard.js +50 -0
- package/dist/src/ui/components/compact-progress-card.d.ts +24 -0
- package/dist/src/ui/components/compact-progress-card.js +42 -0
- package/dist/src/ui/components/context-rail.d.ts +26 -0
- package/dist/src/ui/components/context-rail.js +33 -0
- package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
- package/dist/src/ui/components/council-conclusion-card.js +420 -0
- package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
- package/dist/src/ui/components/council-debate-pill.js +34 -0
- package/dist/src/ui/components/council-info-card.js +2 -2
- package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
- package/dist/src/ui/components/council-leader-bubble.js +21 -11
- package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
- package/dist/src/ui/components/council-message-bubble.js +16 -15
- package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
- package/dist/src/ui/components/council-phase-timeline.js +66 -17
- package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
- package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
- package/dist/src/ui/components/council-question-card.js +13 -12
- package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
- package/dist/src/ui/components/council-rail-rounds.js +57 -0
- package/dist/src/ui/components/council-round-group.d.ts +38 -0
- package/dist/src/ui/components/council-round-group.js +88 -0
- package/dist/src/ui/components/council-status-list.d.ts +3 -1
- package/dist/src/ui/components/council-status-list.js +36 -24
- package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
- package/dist/src/ui/components/council-synthesis-banner.js +20 -5
- package/dist/src/ui/components/halt-recovery-card.js +9 -5
- package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
- package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
- package/dist/src/ui/components/message-view.d.ts +15 -0
- package/dist/src/ui/components/message-view.js +50 -1
- package/dist/src/ui/components/prompt-box.js +18 -16
- package/dist/src/ui/components/session-tree-card.d.ts +14 -0
- package/dist/src/ui/components/session-tree-card.js +46 -0
- package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
- package/dist/src/ui/components/slash-inline-menu.js +26 -5
- package/dist/src/ui/components/task-list-panel.d.ts +14 -1
- package/dist/src/ui/components/task-list-panel.js +22 -2
- package/dist/src/ui/components/tool-group.d.ts +15 -3
- package/dist/src/ui/components/tool-group.js +69 -11
- package/dist/src/ui/containers/modals-layer.d.ts +4 -2
- package/dist/src/ui/containers/modals-layer.js +2 -2
- package/dist/src/ui/council-harness-event.d.ts +57 -0
- package/dist/src/ui/council-harness-event.js +46 -0
- package/dist/src/ui/heartbeat-debug.d.ts +29 -0
- package/dist/src/ui/heartbeat-debug.js +45 -0
- package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
- package/dist/src/ui/mcp-modal.js +2 -4
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/connect-modal.js +4 -3
- package/dist/src/ui/modals/model-picker-modal.d.ts +8 -18
- package/dist/src/ui/modals/model-picker-modal.js +8 -10
- package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
- package/dist/src/ui/modals/session-picker-modal.js +3 -5
- package/dist/src/ui/picker-providers.d.ts +1 -1
- package/dist/src/ui/picker-providers.js +1 -1
- package/dist/src/ui/primitives/index.d.ts +1 -0
- package/dist/src/ui/primitives/index.js +2 -0
- package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
- package/dist/src/ui/primitives/semantic-primitives.js +81 -0
- package/dist/src/ui/slash/compact.js +5 -7
- package/dist/src/ui/slash/cost.js +1 -1
- package/dist/src/ui/slash/council.js +19 -1
- package/dist/src/ui/slash/debug.d.ts +3 -31
- package/dist/src/ui/slash/debug.js +9 -20
- package/dist/src/ui/slash/ee.js +81 -0
- package/dist/src/ui/slash/ideal.d.ts +6 -2
- package/dist/src/ui/slash/ideal.js +97 -7
- package/dist/src/ui/slash/menu-items.d.ts +7 -0
- package/dist/src/ui/slash/menu-items.js +23 -20
- package/dist/src/ui/slash/registry.d.ts +2 -0
- package/dist/src/ui/slash/registry.js +4 -0
- package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
- package/dist/src/ui/status-bar/cache-hit.js +9 -0
- package/dist/src/ui/status-bar/index.d.ts +1 -1
- package/dist/src/ui/status-bar/index.js +7 -3
- package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
- package/dist/src/ui/status-bar/usd-meter.js +6 -4
- package/dist/src/ui/theme.d.ts +1 -0
- package/dist/src/ui/theme.js +2 -0
- package/dist/src/ui/types.d.ts +7 -0
- package/dist/src/ui/use-app-logic.js +0 -0
- package/dist/src/ui/utils/agent-activities.d.ts +39 -0
- package/dist/src/ui/utils/agent-activities.js +96 -0
- package/dist/src/ui/utils/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/ui/utils/group-tool-entries.d.ts +26 -0
- package/dist/src/ui/utils/group-tool-entries.js +111 -0
- package/dist/src/ui/utils/tool-summary.d.ts +21 -0
- package/dist/src/ui/utils/tool-summary.js +91 -0
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/event-loop-monitor.d.ts +85 -0
- package/dist/src/utils/event-loop-monitor.js +107 -0
- package/dist/src/utils/install-manager.js +2 -1
- package/dist/src/utils/llm-deadline.d.ts +14 -0
- package/dist/src/utils/llm-deadline.js +19 -0
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/loop-profiler.d.ts +102 -0
- package/dist/src/utils/loop-profiler.js +202 -0
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +180 -5
- package/dist/src/utils/settings.js +271 -31
- package/dist/src/utils/side-question.d.ts +1 -2
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/utils/visible-retry.d.ts +11 -0
- package/dist/src/utils/visible-retry.js +10 -1
- package/dist/src/verify/entrypoint.d.ts +1 -1
- package/dist/src/verify/entrypoint.js +52 -17
- package/dist/src/verify/orchestrator.d.ts +1 -1
- package/dist/src/verify/orchestrator.js +20 -3
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +134 -132
- package/dist/src/cli/bw-vault.d.ts +0 -55
- package/dist/src/cli/bw-vault.js +0 -133
- package/dist/src/mcp/ee-tools.d.ts +0 -46
- package/dist/src/mcp/ee-tools.js +0 -193
- package/dist/src/providers/auth/gcloud.d.ts +0 -28
- package/dist/src/providers/auth/gcloud.js +0 -102
- package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
- package/dist/src/providers/auth/gemini-oauth.js +0 -472
- package/dist/src/providers/gemini.d.ts +0 -11
- package/dist/src/providers/gemini.js +0 -45
- package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
- package/dist/src/providers/siliconflow-sse-repair.js +0 -177
- package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
- package/dist/src/providers/strategies/google.strategy.js +0 -174
- package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
- package/dist/src/ui/containers/chat-feed.d.ts +0 -40
- package/dist/src/ui/containers/chat-feed.js +0 -66
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { getMcpKey } from "../mcp/mcp-keychain.js";
|
|
2
|
+
import { getWebResearchModel } from "../models/registry.js";
|
|
3
|
+
import { getCouncilLanguage } from "../utils/settings.js";
|
|
1
4
|
import { pickCouncilTaskModel } from "./leader.js";
|
|
2
|
-
import { tracedGenerate } from "./llm.js";
|
|
5
|
+
import { tracedAsync, tracedGenerate, tracedGenerateWithFallback } from "./llm.js";
|
|
3
6
|
import { phaseDone, phaseError, phaseStart } from "./phase-events.js";
|
|
4
7
|
import { buildClarificationPrompt, buildReadinessJudgePrompt, buildSpecSynthesisPrompt } from "./prompts.js";
|
|
5
8
|
/** P5: Hard cap on clarification rounds regardless of judge verdict. */
|
|
@@ -97,6 +100,51 @@ function grayAreaToRoundQuestion(g) {
|
|
|
97
100
|
isRequired: true,
|
|
98
101
|
};
|
|
99
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Resolve the concrete interview language from the council language setting +
|
|
105
|
+
* the topic. Pinned locale → that locale; "english" → English; "auto" (default)
|
|
106
|
+
* → detect from the topic (Vietnamese diacritics, mirroring
|
|
107
|
+
* `detectReplyLanguageHint`). Returned as a concrete name so the clarify prompt
|
|
108
|
+
* FORCES it (immune to an English "## Scope Research" block) and the escape-hatch
|
|
109
|
+
* labels can be localized.
|
|
110
|
+
*/
|
|
111
|
+
const VI_DIACRITIC_RE = /[à-ỹÀ-Ỹ]/;
|
|
112
|
+
export function resolveInterviewLanguage(topic) {
|
|
113
|
+
const setting = getCouncilLanguage();
|
|
114
|
+
if (setting && setting !== "auto" && setting !== "english")
|
|
115
|
+
return setting;
|
|
116
|
+
if (setting === "english")
|
|
117
|
+
return "english";
|
|
118
|
+
return VI_DIACRITIC_RE.test(topic ?? "") ? "vietnamese" : "english";
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* The two escape-hatch options appended to every clarification card, localized to
|
|
122
|
+
* the interview language so a Vietnamese interview doesn't show English buttons.
|
|
123
|
+
* `lang` is a concrete language name; anything not recognized as Vietnamese falls
|
|
124
|
+
* back to English labels (the LLM-authored question itself is still localized).
|
|
125
|
+
* When `lang` is undefined the historical English-label pair is kept byte-
|
|
126
|
+
* identical so existing callers/tests are unaffected.
|
|
127
|
+
*/
|
|
128
|
+
function escapeHatchOptions(lang) {
|
|
129
|
+
const isVi = typeof lang === "string" && /vietnamese|tiếng việt/i.test(lang.trim());
|
|
130
|
+
if (isVi) {
|
|
131
|
+
return [
|
|
132
|
+
{ label: "Nhập câu trả lời", description: "Nhập câu trả lời tự do", value: "", kind: "freetext" },
|
|
133
|
+
{ label: "Thảo luận thêm", description: "Thảo luận thêm trước khi trả lời", value: "", kind: "chat" },
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
if (lang === undefined) {
|
|
137
|
+
// Historical default preserved byte-identical (EN label + VN description).
|
|
138
|
+
return [
|
|
139
|
+
{ label: "Type something", description: "Nhập câu trả lời tự do", value: "", kind: "freetext" },
|
|
140
|
+
{ label: "Chat about this", description: "Thảo luận thêm trước khi trả lời", value: "", kind: "chat" },
|
|
141
|
+
];
|
|
142
|
+
}
|
|
143
|
+
return [
|
|
144
|
+
{ label: "Type something", description: "Type a free-form answer", value: "", kind: "freetext" },
|
|
145
|
+
{ label: "Chat about this", description: "Discuss before answering", value: "", kind: "chat" },
|
|
146
|
+
];
|
|
147
|
+
}
|
|
100
148
|
/**
|
|
101
149
|
* Convert legacy `suggestions: string[]` into the new options schema with
|
|
102
150
|
* standard "Type something" / "Chat about this" escape-hatches appended.
|
|
@@ -110,25 +158,11 @@ function grayAreaToRoundQuestion(g) {
|
|
|
110
158
|
* returned `defaultIndex` points to it. Otherwise `defaultIndex` is omitted
|
|
111
159
|
* so the UI knows to suppress the "(Recommended)" tag.
|
|
112
160
|
*/
|
|
113
|
-
export function buildClarifyOptions(suggestions, recommended) {
|
|
161
|
+
export function buildClarifyOptions(suggestions, recommended, lang) {
|
|
114
162
|
const choices = (suggestions ?? [])
|
|
115
163
|
.filter((s) => typeof s === "string" && s.trim().length > 0)
|
|
116
164
|
.map((s) => ({ label: s.trim(), value: s.trim(), kind: "choice" }));
|
|
117
|
-
const options = [
|
|
118
|
-
...choices,
|
|
119
|
-
{
|
|
120
|
-
label: "Type something",
|
|
121
|
-
description: "Nhập câu trả lời tự do",
|
|
122
|
-
value: "",
|
|
123
|
-
kind: "freetext",
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
label: "Chat about this",
|
|
127
|
-
description: "Thảo luận thêm trước khi trả lời",
|
|
128
|
-
value: "",
|
|
129
|
-
kind: "chat",
|
|
130
|
-
},
|
|
131
|
-
];
|
|
165
|
+
const options = [...choices, ...escapeHatchOptions(lang)];
|
|
132
166
|
let defaultIndex;
|
|
133
167
|
if (typeof recommended === "string" && recommended.trim().length > 0) {
|
|
134
168
|
const target = recommended.trim().toLowerCase();
|
|
@@ -138,6 +172,123 @@ export function buildClarifyOptions(suggestions, recommended) {
|
|
|
138
172
|
}
|
|
139
173
|
return { options, defaultIndex };
|
|
140
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Build council options from the model's richer `{label, description,
|
|
177
|
+
* recommended}` objects, preserving each choice's explanation as `description`
|
|
178
|
+
* and pointing `defaultIndex` at the option the model flagged `recommended`
|
|
179
|
+
* (falling back to the first when none is flagged). The same "Type something" /
|
|
180
|
+
* "Chat about this" escape-hatches are appended as in `buildClarifyOptions`.
|
|
181
|
+
* Pure + exported for unit testing.
|
|
182
|
+
*/
|
|
183
|
+
export function buildClarifyOptionsRich(specs, lang) {
|
|
184
|
+
const cleaned = (specs ?? []).filter((s) => !!s && typeof s.label === "string" && s.label.trim().length > 0);
|
|
185
|
+
const choices = cleaned.map((s) => ({
|
|
186
|
+
label: s.label.trim(),
|
|
187
|
+
value: s.label.trim(),
|
|
188
|
+
kind: "choice",
|
|
189
|
+
...(typeof s.description === "string" && s.description.trim().length > 0
|
|
190
|
+
? { description: s.description.trim() }
|
|
191
|
+
: {}),
|
|
192
|
+
}));
|
|
193
|
+
const options = [...choices, ...escapeHatchOptions(lang)];
|
|
194
|
+
let defaultIndex;
|
|
195
|
+
const recIdx = cleaned.findIndex((s) => s.recommended === true);
|
|
196
|
+
if (recIdx !== -1)
|
|
197
|
+
defaultIndex = recIdx;
|
|
198
|
+
return { options, defaultIndex };
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Pre-clarify scope research (research-first grounding).
|
|
202
|
+
*
|
|
203
|
+
* Before asking ANY clarification question, research the topic — codebase for an
|
|
204
|
+
* existing repo (the research method reads the tree) plus web — so the
|
|
205
|
+
* question-generator surfaces the REAL gray areas the evidence exposes instead
|
|
206
|
+
* of guessing blind ("hỏi tào lao"). The returned brief is appended to the
|
|
207
|
+
* `conversationContext` that `buildClarificationPrompt` already reads, so both
|
|
208
|
+
* `/council` and `/ideal` (which reuses this clarifier as its gather engine)
|
|
209
|
+
* inherit evidence-grounded questions from one shared code path.
|
|
210
|
+
*
|
|
211
|
+
* Web-capability policy (owner's Part E rule): PREFER a model with native web
|
|
212
|
+
* research integrated (catalog `nativeWebResearch`), switching the research call
|
|
213
|
+
* to it when one is reachable. Only when no native-web model is reachable fall
|
|
214
|
+
* back to Tavily (via the research method's builtin web tools). When NEITHER a
|
|
215
|
+
* native-web model NOR a Tavily key exists, warn the user before continuing —
|
|
216
|
+
* research proceeds on the codebase + model knowledge only, never silently blind.
|
|
217
|
+
* (Codebase evidence is always gathered by the research tool regardless of the
|
|
218
|
+
* web tier, so an existing repo is still grounded.)
|
|
219
|
+
*
|
|
220
|
+
* Never throws and never blocks the interview: if the flag is off, the llm has
|
|
221
|
+
* no `research` method (most unit-test mocks), the run is aborted, or the call
|
|
222
|
+
* fails, it yields nothing and returns "". Default ON; opt out with
|
|
223
|
+
* MUONROI_CLARIFY_RESEARCH_FIRST=0.
|
|
224
|
+
*/
|
|
225
|
+
async function hasTavilyKey() {
|
|
226
|
+
try {
|
|
227
|
+
const k = ((await getMcpKey("tavily")) || process.env.TAVILY_API_KEY || "").trim();
|
|
228
|
+
return k.length >= 10;
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return (process.env.TAVILY_API_KEY ?? "").trim().length >= 10;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
export async function* researchScopeForClarification(topic, conversationContext, leaderModelId, llm, signal, reachableModels) {
|
|
235
|
+
if (process.env.MUONROI_CLARIFY_RESEARCH_FIRST === "0")
|
|
236
|
+
return "";
|
|
237
|
+
if (signal?.aborted)
|
|
238
|
+
return "";
|
|
239
|
+
// Skip cleanly when the injected llm can't research (generate-only test mocks)
|
|
240
|
+
// — keeps every existing clarifier test on its current, research-free path.
|
|
241
|
+
if (typeof llm.research !== "function")
|
|
242
|
+
return "";
|
|
243
|
+
// Choose the research model + web tier. Prefer a reachable native-web model.
|
|
244
|
+
const reachable = new Set([leaderModelId, ...reachableModels].filter(Boolean));
|
|
245
|
+
const nativeModel = getWebResearchModel(reachable);
|
|
246
|
+
let researchModel = leaderModelId;
|
|
247
|
+
let webTier;
|
|
248
|
+
if (nativeModel) {
|
|
249
|
+
researchModel = nativeModel.id;
|
|
250
|
+
webTier = "native";
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
webTier = (await hasTavilyKey()) ? "tavily" : "none";
|
|
254
|
+
}
|
|
255
|
+
const phaseId = "phase:clarification-scope-research";
|
|
256
|
+
const startedAt = Date.now();
|
|
257
|
+
yield phaseStart({ phaseId, kind: "clarification", label: "Scope research" });
|
|
258
|
+
// Owner's Part E principle: never research the web fully blind without telling
|
|
259
|
+
// the user. Codebase + model-knowledge research still runs, but web findings
|
|
260
|
+
// will be absent — surface that so they can wire a native-web model or Tavily.
|
|
261
|
+
if (webTier === "none") {
|
|
262
|
+
yield {
|
|
263
|
+
type: "content",
|
|
264
|
+
content: `\n> ⚠ Scope research: no web-research-native model is reachable and no Tavily key is configured. ` +
|
|
265
|
+
`Researching from the codebase + model knowledge only — no live web findings. ` +
|
|
266
|
+
`Configure a native-web model or a Tavily API key for grounded web research.\n`,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
const goal = `${topic}\n\n(Research goal: narrow the scope of this request. Report verified findings, and — ` +
|
|
271
|
+
`critically — END with an explicit "## Open Questions / Assumptions" section listing what you could ` +
|
|
272
|
+
`NOT verify and had to ASSUME (the real goal/pain, the concrete task, the system of record, the ` +
|
|
273
|
+
`target user, hard constraints). Those unresolved items are exactly what the user must clarify next, ` +
|
|
274
|
+
`so name them plainly rather than papering over them with a plausible guess.)`;
|
|
275
|
+
const brief = yield* tracedAsync(() => llm.research(researchModel, goal, conversationContext, signal, undefined, {
|
|
276
|
+
internetFirst: webTier !== "none",
|
|
277
|
+
}), { phase: "clarify", label: "Scope research" });
|
|
278
|
+
yield phaseDone({ phaseId, kind: "clarification", label: "Scope research", startedAt });
|
|
279
|
+
return typeof brief === "string" ? brief.trim() : "";
|
|
280
|
+
}
|
|
281
|
+
catch (err) {
|
|
282
|
+
yield phaseError({
|
|
283
|
+
phaseId,
|
|
284
|
+
kind: "clarification",
|
|
285
|
+
label: "Scope research",
|
|
286
|
+
startedAt,
|
|
287
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
288
|
+
});
|
|
289
|
+
return "";
|
|
290
|
+
}
|
|
291
|
+
}
|
|
141
292
|
export async function* runClarification(topic, leaderModelId, conversationContext, respondToQuestion, llm, signal, seedQuestions, maxRounds,
|
|
142
293
|
/**
|
|
143
294
|
* Optional pre-filled answers keyed by seed-question id. When the loop's
|
|
@@ -152,16 +303,32 @@ prefillAnswers,
|
|
|
152
303
|
* a cheaper tier model on the same provider as the leader. Falls back to
|
|
153
304
|
* the leader model if no cheaper model is cataloged. Default false.
|
|
154
305
|
*/
|
|
155
|
-
costAware = false
|
|
306
|
+
costAware = false,
|
|
307
|
+
/**
|
|
308
|
+
* Healthy panel models to fall back to when the leader's cost-tier spec-synth
|
|
309
|
+
* model is on a failing proxy — keeps the spec's ≥3 observable criteria (and
|
|
310
|
+
* thus a meaningful leader eval) instead of degrading to one generic criterion.
|
|
311
|
+
*/
|
|
312
|
+
fallbackModels = []) {
|
|
156
313
|
// P5: use MAX_CLARIFY_ROUNDS (12) as the hard cap; respect explicit override
|
|
157
314
|
// from callers that pass maxRounds (e.g. tests that want old 3-round behavior).
|
|
158
315
|
const max = typeof maxRounds === "number" && maxRounds > 0 ? maxRounds : MAX_CLARIFY_ROUNDS;
|
|
316
|
+
// Interview language (the user's conversation language, not English-by-default).
|
|
317
|
+
// Resolved once and forced into the clarify prompt + escape-hatch labels.
|
|
318
|
+
const uiLang = resolveInterviewLanguage(topic);
|
|
159
319
|
const allQA = [];
|
|
160
320
|
// P5: full Q&A history with timestamps for clarifyHistory field
|
|
161
321
|
const clarifyHistory = [];
|
|
162
322
|
const phaseStartedAt = Date.now();
|
|
163
323
|
yield phaseStart({ phaseId: "phase:clarification", kind: "clarification", label: "Clarification" });
|
|
164
324
|
const seeded = (seedQuestions ?? []).map(grayAreaToRoundQuestion);
|
|
325
|
+
// Research-first: ground the interview in evidence BEFORE asking anything, so
|
|
326
|
+
// the question-generator targets the real gray areas the research surfaced
|
|
327
|
+
// rather than guessing. Appended to the context every round's prompt reads.
|
|
328
|
+
const scopeBrief = yield* researchScopeForClarification(topic, conversationContext, leaderModelId, llm, signal, fallbackModels);
|
|
329
|
+
if (scopeBrief) {
|
|
330
|
+
conversationContext = `${conversationContext}${conversationContext ? "\n\n" : ""}## Scope Research\n${scopeBrief}`;
|
|
331
|
+
}
|
|
165
332
|
// P5: track ready-gate state across rounds
|
|
166
333
|
let gateReady = false;
|
|
167
334
|
let gateConfidence = 0;
|
|
@@ -195,7 +362,7 @@ costAware = false) {
|
|
|
195
362
|
const gapHint = pendingGaps.length > 0
|
|
196
363
|
? `\n\n## Known Gaps (target these with follow-up questions)\n${pendingGaps.map((g) => `- ${g}`).join("\n")}`
|
|
197
364
|
: "";
|
|
198
|
-
const { system, prompt } = buildClarificationPrompt(topic, conversationContext, allQA.length > 0 ? allQA : undefined);
|
|
365
|
+
const { system, prompt } = buildClarificationPrompt(topic, conversationContext, allQA.length > 0 ? allQA : undefined, uiLang);
|
|
199
366
|
let questionsRaw;
|
|
200
367
|
try {
|
|
201
368
|
const clarifyModel = pickCouncilTaskModel("clarify_questions", leaderModelId, costAware);
|
|
@@ -284,7 +451,16 @@ costAware = false) {
|
|
|
284
451
|
continue;
|
|
285
452
|
}
|
|
286
453
|
const questionId = crypto.randomUUID();
|
|
287
|
-
|
|
454
|
+
// Prefer the model's richer {label, description, recommended} options so
|
|
455
|
+
// every choice shows its own explanation + the recommended default is
|
|
456
|
+
// pre-selected. Fall back to the legacy string `suggestions` shape (PIL
|
|
457
|
+
// gray-area seeds and any model still emitting the old format).
|
|
458
|
+
const { options, defaultIndex } = q.options && q.options.length > 0
|
|
459
|
+
? buildClarifyOptionsRich(q.options, uiLang)
|
|
460
|
+
: buildClarifyOptions(q.suggestions, q.recommended, uiLang);
|
|
461
|
+
// Keep the deprecated `suggestions` mirror populated for consumers that
|
|
462
|
+
// still read it (audit/replay), deriving labels from rich options.
|
|
463
|
+
const suggestionLabels = q.suggestions ?? (q.options ? q.options.map((o) => o.label).filter((l) => typeof l === "string") : undefined);
|
|
288
464
|
yield {
|
|
289
465
|
type: "council_question",
|
|
290
466
|
content: `**${q.question}**\n${q.why ? `> ${q.why}` : ""}`,
|
|
@@ -293,7 +469,7 @@ costAware = false) {
|
|
|
293
469
|
phase: "clarify",
|
|
294
470
|
question: q.question,
|
|
295
471
|
context: q.why,
|
|
296
|
-
suggestions:
|
|
472
|
+
suggestions: suggestionLabels,
|
|
297
473
|
options,
|
|
298
474
|
isRequired: q.isRequired,
|
|
299
475
|
defaultIndex,
|
|
@@ -329,7 +505,7 @@ costAware = false) {
|
|
|
329
505
|
startedAt: phaseStartedAt,
|
|
330
506
|
detail: allQA.length > 0 ? `${allQA.length} Q&A` : "no clarification needed",
|
|
331
507
|
});
|
|
332
|
-
const spec = yield* synthesizeSpec(topic, conversationContext, allQA, leaderModelId, llm, costAware);
|
|
508
|
+
const spec = yield* synthesizeSpec(topic, conversationContext, allQA, leaderModelId, llm, costAware, fallbackModels);
|
|
333
509
|
// P5: attach ready-gate metadata to the returned spec
|
|
334
510
|
spec.confidenceScore = gateConfidence;
|
|
335
511
|
spec.remainingGaps = gateGaps;
|
|
@@ -355,13 +531,18 @@ costAware = false) {
|
|
|
355
531
|
};
|
|
356
532
|
return spec;
|
|
357
533
|
}
|
|
358
|
-
export function buildSpecFromTopic(topic,
|
|
534
|
+
export function buildSpecFromTopic(topic, conversationContext) {
|
|
359
535
|
return {
|
|
360
536
|
problemStatement: topic,
|
|
361
537
|
constraints: [],
|
|
362
538
|
successCriteria: [`Address the topic: ${topic.slice(0, 100)}`],
|
|
363
539
|
scope: "Determined by conversation context",
|
|
364
540
|
rawQA: [],
|
|
541
|
+
// Carry the session/task context onto the spec so every debate stage (not
|
|
542
|
+
// just the opening) can stay anchored to the parent task. Previously this
|
|
543
|
+
// argument was dropped (prefixed `_`), which is why auto-council debates saw
|
|
544
|
+
// only the isolated sub-task and drifted off-topic.
|
|
545
|
+
parentContext: conversationContext?.trim() || undefined,
|
|
365
546
|
};
|
|
366
547
|
}
|
|
367
548
|
/**
|
|
@@ -374,7 +555,7 @@ export function buildSpecFromTopic(topic, _conversationContext) {
|
|
|
374
555
|
* We LLM-extract criteria/constraints/scope from the topic when QA is empty.
|
|
375
556
|
* Falls back to the original buildSpecFromTopic if the LLM call fails.
|
|
376
557
|
*/
|
|
377
|
-
async function* inferSpecFromTopicOnly(topic, conversationContext, leaderModelId, llm, costAware) {
|
|
558
|
+
async function* inferSpecFromTopicOnly(topic, conversationContext, leaderModelId, llm, costAware, fallbackModels = []) {
|
|
378
559
|
const system = `You are extracting an implicit specification from a short topic statement. ` +
|
|
379
560
|
`The user did not answer clarification questions, but the topic itself often ` +
|
|
380
561
|
`implies scope, criteria, and constraints. Tease them out.\n\n` +
|
|
@@ -396,16 +577,21 @@ async function* inferSpecFromTopicOnly(topic, conversationContext, leaderModelId
|
|
|
396
577
|
`- Write all fields in the user's language (detected from the topic).`;
|
|
397
578
|
const prompt = `## Topic\n${topic}\n\n${conversationContext ? `## Context\n${conversationContext}\n` : ""}`;
|
|
398
579
|
try {
|
|
580
|
+
// Model-fallback: the cost-tier synth model can sit on a flaky proxy
|
|
581
|
+
// (Console Go glm/kimi → "Upstream request failed"). Falling back to
|
|
582
|
+
// buildSpecFromTopic yields a single generic criterion, which makes the
|
|
583
|
+
// leader eval read a vague "1/1 criteria met". Retry on healthy panel models
|
|
584
|
+
// first so the spec keeps its ≥3 observable criteria.
|
|
399
585
|
const synthModel = pickCouncilTaskModel("spec_synthesis", leaderModelId, costAware);
|
|
400
|
-
const raw = yield*
|
|
586
|
+
const raw = yield* tracedGenerateWithFallback(llm, {
|
|
401
587
|
phase: "synthesis",
|
|
402
588
|
label: "Inferring spec from topic (no clarification answers)",
|
|
403
|
-
|
|
589
|
+
models: [synthModel, ...fallbackModels],
|
|
404
590
|
system,
|
|
405
591
|
prompt,
|
|
406
592
|
maxTokens: 1024,
|
|
407
593
|
});
|
|
408
|
-
const match = raw
|
|
594
|
+
const match = raw?.match(/\{[\s\S]*\}/);
|
|
409
595
|
if (match) {
|
|
410
596
|
const parsed = JSON.parse(match[0]);
|
|
411
597
|
const criteria = Array.isArray(parsed.successCriteria) && parsed.successCriteria.length >= 1
|
|
@@ -429,12 +615,12 @@ async function* inferSpecFromTopicOnly(topic, conversationContext, leaderModelId
|
|
|
429
615
|
}
|
|
430
616
|
return buildSpecFromTopic(topic, conversationContext);
|
|
431
617
|
}
|
|
432
|
-
async function* synthesizeSpec(topic, conversationContext, qa, leaderModelId, llm, costAware = false) {
|
|
618
|
+
async function* synthesizeSpec(topic, conversationContext, qa, leaderModelId, llm, costAware = false, fallbackModels = []) {
|
|
433
619
|
if (qa.length === 0) {
|
|
434
620
|
// Clarifier asked 0 questions OR user skipped all of them. Use the LLM to
|
|
435
621
|
// pull implicit criteria/constraints/scope from the topic alone instead of
|
|
436
622
|
// returning the single-criterion fallback that makes leader-eval trivial.
|
|
437
|
-
return yield* inferSpecFromTopicOnly(topic, conversationContext, leaderModelId, llm, costAware);
|
|
623
|
+
return yield* inferSpecFromTopicOnly(topic, conversationContext, leaderModelId, llm, costAware, fallbackModels);
|
|
438
624
|
}
|
|
439
625
|
const { system, prompt } = buildSpecSynthesisPrompt(topic, conversationContext, qa);
|
|
440
626
|
const resolved = {};
|
|
@@ -444,16 +630,18 @@ async function* synthesizeSpec(topic, conversationContext, qa, leaderModelId, ll
|
|
|
444
630
|
}
|
|
445
631
|
}
|
|
446
632
|
try {
|
|
633
|
+
// Model-fallback (see inferSpecFromTopicOnly): keep the ≥3-criteria spec even
|
|
634
|
+
// when the leader's cost-tier synth model is on a failing proxy.
|
|
447
635
|
const synthModel = pickCouncilTaskModel("spec_synthesis", leaderModelId, costAware);
|
|
448
|
-
const raw = yield*
|
|
636
|
+
const raw = yield* tracedGenerateWithFallback(llm, {
|
|
449
637
|
phase: "synthesis",
|
|
450
638
|
label: "Synthesizing clarified spec",
|
|
451
|
-
|
|
639
|
+
models: [synthModel, ...fallbackModels],
|
|
452
640
|
system,
|
|
453
641
|
prompt,
|
|
454
642
|
maxTokens: 2048,
|
|
455
643
|
});
|
|
456
|
-
const match = raw
|
|
644
|
+
const match = raw?.match(/\{[\s\S]*\}/);
|
|
457
645
|
if (match) {
|
|
458
646
|
const parsed = JSON.parse(match[0]);
|
|
459
647
|
return {
|
|
@@ -98,7 +98,7 @@ function getCompactionText(msg) {
|
|
|
98
98
|
return null;
|
|
99
99
|
return msg.content;
|
|
100
100
|
}
|
|
101
|
-
function
|
|
101
|
+
function extractText(content) {
|
|
102
102
|
if (typeof content === "string")
|
|
103
103
|
return content;
|
|
104
104
|
if (Array.isArray(content)) {
|
|
@@ -109,40 +109,74 @@ function extractUserText(content) {
|
|
|
109
109
|
}
|
|
110
110
|
return "";
|
|
111
111
|
}
|
|
112
|
+
/** Filter assistant messages to exclude tool-call-only turns (tool_use + tool_result
|
|
113
|
+
* pairs that carry no analytical text). An assistant turn with ≥80 chars of text
|
|
114
|
+
* content is considered "analytical" (contains decisions, analysis, code, or plans). */
|
|
115
|
+
function isAnalyticalAssistant(content) {
|
|
116
|
+
const text = extractText(content);
|
|
117
|
+
return text.trim().length >= 80;
|
|
118
|
+
}
|
|
119
|
+
/** Maximum total characters for the built context string. Raised from 12K to 32K
|
|
120
|
+
* (~8K tokens) so council participants get meaningful session history rather than
|
|
121
|
+
* only 5 user-message snippets. */
|
|
122
|
+
const MAX_CONTEXT_CHARS = 32_000;
|
|
112
123
|
export function buildCouncilContext(messages) {
|
|
113
124
|
const parts = [];
|
|
125
|
+
// 1. Compaction summary (first message if it's a system compaction)
|
|
114
126
|
if (messages.length > 0 && isCompactionSummary(messages[0])) {
|
|
115
127
|
const summary = getCompactionText(messages[0]);
|
|
116
128
|
if (summary) {
|
|
117
129
|
parts.push(`## Session Context (from compaction summary)\n${summary}`);
|
|
118
130
|
}
|
|
119
131
|
}
|
|
120
|
-
|
|
121
|
-
|
|
132
|
+
// 2. Recent conversation turns — scan BOTH user + analytical assistant messages
|
|
133
|
+
// from the tail, capturing at most 8 meaningful entries.
|
|
134
|
+
// Previously only captured 5 user messages — lost ALL assistant analysis,
|
|
135
|
+
// code changes, and decisions made during the session.
|
|
136
|
+
const conversationTurns = [];
|
|
137
|
+
for (let i = messages.length - 1; i >= 0 && conversationTurns.length < 8; i--) {
|
|
122
138
|
const msg = messages[i];
|
|
123
139
|
if (msg.role === "user") {
|
|
124
|
-
const text =
|
|
140
|
+
const text = extractText(msg.content);
|
|
141
|
+
if (text.trim()) {
|
|
142
|
+
conversationTurns.unshift(`[User] ${text.slice(0, 3000).trim()}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else if (msg.role === "assistant" && isAnalyticalAssistant(msg.content)) {
|
|
146
|
+
const text = extractText(msg.content);
|
|
125
147
|
if (text.trim()) {
|
|
126
|
-
|
|
148
|
+
// Cap assistant text to 1500 chars — enough to convey analysis/decisions
|
|
149
|
+
// without blowing the context budget on long code outputs.
|
|
150
|
+
conversationTurns.unshift(`[Assistant] ${text.slice(0, 1500).trim()}`);
|
|
127
151
|
}
|
|
128
152
|
}
|
|
129
153
|
}
|
|
130
|
-
if (
|
|
131
|
-
parts.push(`## Recent
|
|
154
|
+
if (conversationTurns.length > 0) {
|
|
155
|
+
parts.push(`## Recent Conversation\n${conversationTurns.join("\n\n")}`);
|
|
132
156
|
}
|
|
133
|
-
|
|
157
|
+
// 3. Key decisions from system messages (task outcomes, decisions, plans)
|
|
158
|
+
const decisionMsgs = [];
|
|
134
159
|
for (const msg of messages) {
|
|
135
|
-
if (msg.role
|
|
136
|
-
|
|
160
|
+
if (msg.role !== "system" || typeof msg.content !== "string")
|
|
161
|
+
continue;
|
|
162
|
+
const c = msg.content;
|
|
163
|
+
if (c.includes("[Council Memory]") ||
|
|
164
|
+
c.includes("[Council Decision]") ||
|
|
165
|
+
c.includes("[Council Action Items]") ||
|
|
166
|
+
c.includes("[Council Plan Update]") ||
|
|
167
|
+
c.includes("[Decision]") ||
|
|
168
|
+
c.includes("[Task Completed]") ||
|
|
169
|
+
c.includes("[NEEDS HUMAN REVIEW]")) {
|
|
170
|
+
decisionMsgs.push(c);
|
|
137
171
|
}
|
|
138
172
|
}
|
|
139
|
-
if (
|
|
140
|
-
const digests =
|
|
141
|
-
parts.push(`##
|
|
173
|
+
if (decisionMsgs.length > 0) {
|
|
174
|
+
const digests = decisionMsgs.slice(-4).map(formatCouncilMemoryDigest);
|
|
175
|
+
parts.push(`## Key Decisions\n${digests.join("\n\n")}`);
|
|
142
176
|
}
|
|
143
177
|
const combined = parts.join("\n\n---\n\n");
|
|
144
|
-
if (combined.length >
|
|
145
|
-
return `${combined.slice(0,
|
|
178
|
+
if (combined.length > MAX_CONTEXT_CHARS) {
|
|
179
|
+
return `${combined.slice(0, MAX_CONTEXT_CHARS)}\n\n[... context truncated to fit token budget]`;
|
|
146
180
|
}
|
|
147
181
|
return combined;
|
|
148
182
|
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/council/debate-checkpoint.ts
|
|
3
|
+
*
|
|
4
|
+
* C (mid-debate checkpoint) — persist the CB-1 council debate's per-round state
|
|
5
|
+
* so a break mid-debate (provider 5xx on round 5, host crash, cap breach) can
|
|
6
|
+
* resume from the last completed round instead of re-running the whole debate.
|
|
7
|
+
*
|
|
8
|
+
* The debate accumulates all state in RAM (`exchangeLogs`, `active`,
|
|
9
|
+
* `runningSummary`, `archive`, convergence trackers). Without a checkpoint a
|
|
10
|
+
* break loses every round — a 5-round multi-provider debate must restart from
|
|
11
|
+
* round 1. This module owns the on-disk snapshot: `runDebate` writes it after
|
|
12
|
+
* each completed round and deletes it on normal completion; the resume path
|
|
13
|
+
* reads it and seeds `runDebate` so it skips research + openings + completed
|
|
14
|
+
* rounds.
|
|
15
|
+
*
|
|
16
|
+
* File: `<checkpointDir>/debate-checkpoint.json` (checkpointDir = the run dir,
|
|
17
|
+
* `.muonroi-flow/runs/<runId>`). Written atomically (tmp + rename) so a crash
|
|
18
|
+
* mid-write can never leave a half-JSON file.
|
|
19
|
+
*/
|
|
20
|
+
import type { ClarifiedSpec, CouncilParticipant, DebateArchiveEntry } from "./types.js";
|
|
21
|
+
/** Bump when the checkpoint shape changes incompatibly so stale files are ignored. */
|
|
22
|
+
export declare const DEBATE_CHECKPOINT_VERSION: 1;
|
|
23
|
+
export declare const DEBATE_CHECKPOINT_FILE = "debate-checkpoint.json";
|
|
24
|
+
/**
|
|
25
|
+
* Serializable snapshot of an in-flight debate, written after each completed
|
|
26
|
+
* discussion round. `exchangeLogs` (a `Map`) is stored as entry tuples since
|
|
27
|
+
* JSON has no Map; everything else in the payload is already JSON-native.
|
|
28
|
+
*/
|
|
29
|
+
export interface DebateCheckpoint {
|
|
30
|
+
version: typeof DEBATE_CHECKPOINT_VERSION;
|
|
31
|
+
/**
|
|
32
|
+
* Identity guard — the checkpoint is only restored when it matches the debate
|
|
33
|
+
* about to run. `problemStatement` pins the spec; `participantModels` pins the
|
|
34
|
+
* panel. A mismatch (spec changed, panel re-resolved differently) => ignore
|
|
35
|
+
* the stale checkpoint and run the debate fresh rather than splice wrong state.
|
|
36
|
+
*/
|
|
37
|
+
problemStatement: string;
|
|
38
|
+
participantModels: string[];
|
|
39
|
+
/** Rounds fully completed (transcript + summary persisted). Resume starts at roundCount+1. */
|
|
40
|
+
roundCount: number;
|
|
41
|
+
/** Current round budget after any leader/user extensions. */
|
|
42
|
+
maxRounds: number;
|
|
43
|
+
/** Accumulated per-pair transcript (Map<pairKey, turns[]> serialized as entries). */
|
|
44
|
+
exchangeLogs: Array<[string, string[]]>;
|
|
45
|
+
/** Latest inter-round summary. */
|
|
46
|
+
runningSummary: string;
|
|
47
|
+
/** Research findings (so the research phase is not re-run on resume). */
|
|
48
|
+
researchFindings?: string;
|
|
49
|
+
/** Surviving participants with their latest position + stance (so openings are not re-run). */
|
|
50
|
+
active: CouncilParticipant[];
|
|
51
|
+
/** Citation archive accumulated so far. */
|
|
52
|
+
archive: DebateArchiveEntry[];
|
|
53
|
+
/** Convergence continuity: last round's per-criterion met flags. */
|
|
54
|
+
lastCriteriaMet: boolean[];
|
|
55
|
+
/** B4 auto-remedy high-water mark of pinned criteria met. */
|
|
56
|
+
bestCriteriaMetCount: number;
|
|
57
|
+
/** B4 consecutive evaluated rounds with no new met criterion. */
|
|
58
|
+
roundsSinceProgress: number;
|
|
59
|
+
/** Topic carried into the next round from the prior leader nextRoundFocus. */
|
|
60
|
+
nextTopic?: string;
|
|
61
|
+
/** Wall-clock the checkpoint was written (ISO). Diagnostics only. */
|
|
62
|
+
savedAt: string;
|
|
63
|
+
}
|
|
64
|
+
/** Input to {@link buildDebateCheckpoint} — the live round-loop locals. */
|
|
65
|
+
export interface DebateCheckpointInput {
|
|
66
|
+
problemStatement: string;
|
|
67
|
+
roundCount: number;
|
|
68
|
+
maxRounds: number;
|
|
69
|
+
exchangeLogs: Map<string, string[]>;
|
|
70
|
+
runningSummary: string;
|
|
71
|
+
researchFindings?: string;
|
|
72
|
+
active: CouncilParticipant[];
|
|
73
|
+
archive: DebateArchiveEntry[];
|
|
74
|
+
lastCriteriaMet: boolean[];
|
|
75
|
+
bestCriteriaMetCount: number;
|
|
76
|
+
roundsSinceProgress: number;
|
|
77
|
+
nextTopic?: string;
|
|
78
|
+
/** ISO timestamp; the caller supplies it (Date.now is unavailable in some sandboxes). */
|
|
79
|
+
savedAt: string;
|
|
80
|
+
}
|
|
81
|
+
/** Build the serializable checkpoint payload from live debate state. */
|
|
82
|
+
export declare function buildDebateCheckpoint(input: DebateCheckpointInput): DebateCheckpoint;
|
|
83
|
+
/** Rehydrate `exchangeLogs` from the serialized entry tuples. */
|
|
84
|
+
export declare function restoreExchangeLogs(cp: DebateCheckpoint): Map<string, string[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Whether `cp` describes the debate that is about to run. Guards against
|
|
87
|
+
* splicing a stale checkpoint (different question, re-resolved panel) into a
|
|
88
|
+
* fresh debate. Participant order is not significant; the model SET must match.
|
|
89
|
+
*/
|
|
90
|
+
export declare function checkpointMatches(cp: DebateCheckpoint, problemStatement: string, participantModels: string[]): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Atomically write the checkpoint to `<dir>/debate-checkpoint.json`.
|
|
93
|
+
* Non-fatal: a checkpoint write failure must never break the live debate — it
|
|
94
|
+
* only forfeits resumability for that round. Logs with context (No-Silent-Catch).
|
|
95
|
+
*/
|
|
96
|
+
export declare function writeDebateCheckpoint(dir: string, cp: DebateCheckpoint): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Read + parse the checkpoint. Returns null when absent or unparseable (a
|
|
99
|
+
* corrupt checkpoint must not crash resume — the debate just runs fresh).
|
|
100
|
+
*/
|
|
101
|
+
export declare function readDebateCheckpoint(dir: string): Promise<DebateCheckpoint | null>;
|
|
102
|
+
/**
|
|
103
|
+
* Delete the checkpoint (debate completed normally, or the run was aborted).
|
|
104
|
+
* Non-fatal — a leftover checkpoint is only re-validated (and discarded on
|
|
105
|
+
* mismatch) on the next resume, never silently mis-applied.
|
|
106
|
+
*/
|
|
107
|
+
export declare function deleteDebateCheckpoint(dir: string): Promise<void>;
|
|
108
|
+
export declare const DEBATE_INPUTS_FILE = "debate-inputs.json";
|
|
109
|
+
/**
|
|
110
|
+
* C-v2 — the minimal gather-stage outputs needed to re-enter the council debate
|
|
111
|
+
* on a fresh session (cross-process resume) WITHOUT re-running the interactive
|
|
112
|
+
* discovery + interview. Persisted once at debate start; the loop-driver resume
|
|
113
|
+
* entry restores `clarifiedSpec` + `conversationContext` and jumps straight to
|
|
114
|
+
* the research/debate stage (participants + leader are re-resolved from the
|
|
115
|
+
* session model deterministically, then matched against the checkpoint panel).
|
|
116
|
+
*/
|
|
117
|
+
export interface DebateInputs {
|
|
118
|
+
version: typeof DEBATE_CHECKPOINT_VERSION;
|
|
119
|
+
problemStatement: string;
|
|
120
|
+
clarifiedSpec: ClarifiedSpec;
|
|
121
|
+
conversationContext: string;
|
|
122
|
+
savedAt: string;
|
|
123
|
+
}
|
|
124
|
+
/** Atomically persist the debate inputs. Non-fatal on failure (forfeits cross-session resume only). */
|
|
125
|
+
export declare function writeDebateInputs(dir: string, inputs: DebateInputs): Promise<void>;
|
|
126
|
+
/** Read the debate inputs. Returns null when absent/unparseable/version-mismatched. */
|
|
127
|
+
export declare function readDebateInputs(dir: string): Promise<DebateInputs | null>;
|
|
128
|
+
/** Delete the debate inputs (debate + scoping finished, or run aborted). Non-fatal. */
|
|
129
|
+
export declare function deleteDebateInputs(dir: string): Promise<void>;
|