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,6 +1,14 @@
|
|
|
1
1
|
import { buildStackLockSection } from "./decisions-lock.js";
|
|
2
2
|
// ── Clarification prompts ────────────────────────────────────────────────────
|
|
3
|
-
export function buildClarificationPrompt(topic, conversationContext, previousQA
|
|
3
|
+
export function buildClarificationPrompt(topic, conversationContext, previousQA,
|
|
4
|
+
/**
|
|
5
|
+
* Interview language, already resolved by the caller (runClarification): a
|
|
6
|
+
* concrete language name ("vietnamese", "english", a pinned locale) or "auto".
|
|
7
|
+
* Feeds the shared `buildLanguageRule` so the cards follow the SAME language
|
|
8
|
+
* policy as the debate — the user's conversation language, not English-by-
|
|
9
|
+
* default. Defaults to "auto" so existing no-arg callers keep auto-detection.
|
|
10
|
+
*/
|
|
11
|
+
lang = "auto") {
|
|
4
12
|
const qaSection = previousQA?.length
|
|
5
13
|
? `\n\n## Already Clarified\n${previousQA.map((qa) => `Q: ${qa.question}\nA: ${qa.answer}`).join("\n\n")}`
|
|
6
14
|
: "";
|
|
@@ -12,10 +20,28 @@ export function buildClarificationPrompt(topic, conversationContext, previousQA)
|
|
|
12
20
|
`- SCOPE: what is in/out of scope for THIS change?\n` +
|
|
13
21
|
`- CONSTRAINTS: hard technical/time/business constraints not already implied by the context.\n` +
|
|
14
22
|
`- SUCCESS CRITERIA: how "done" is judged, when it isn't already obvious.\n\n` +
|
|
23
|
+
`## Ground your questions in the research (IMPORTANT)\n` +
|
|
24
|
+
`If a "## Scope Research" section is present, it is evidence gathered about THIS topic before you ` +
|
|
25
|
+
`were asked to clarify. Read it first, then use it to ask SHARPER, better-grounded questions — ` +
|
|
26
|
+
`research makes your questions more pointed, it does NOT reduce the need to ask. Treat the research's ` +
|
|
27
|
+
`own guesses/speculation as UNVERIFIED, never as the user's answer: if the research had to assume ` +
|
|
28
|
+
`what the user actually wants (their real goal, the concrete task, the system of record, the target ` +
|
|
29
|
+
`user), that assumption IS the gray area you must confirm with them — do not adopt it silently. ` +
|
|
30
|
+
`In particular, when the request is vague and the research could only speculate about the core goal, ` +
|
|
31
|
+
`asking the user to name that goal/pain concretely is the single highest-value question — ask it. ` +
|
|
32
|
+
`Only skip a question when the research (or the topic/context) settles it with real evidence, not a guess.\n\n` +
|
|
15
33
|
`## How many questions\n` +
|
|
16
34
|
`Ask the minimum that unblocks a focused discussion — typically 0-2. A well-scoped topic, or one ` +
|
|
17
35
|
`whose context already answers the gaps, needs ZERO questions: return []. Do NOT pad to a quota, ` +
|
|
18
36
|
`and never ask a question whose answer is already in the topic or the project context.\n\n` +
|
|
37
|
+
`## Ask ONLY when the answer forks the debate (ROI gate — critical)\n` +
|
|
38
|
+
`Before emitting ANY question, ask yourself: "If the user said 'you decide', would I be confident?" ` +
|
|
39
|
+
`If YES and picking wrong would be cheap to correct once the debate surfaces it, DO NOT ask — return [] ` +
|
|
40
|
+
`and let the debate proceed on your recommended reading. A card that merely asks the user to CONFIRM the ` +
|
|
41
|
+
`default you already recommend is pure noise: it cost a real user 60s for zero new information. Only ask ` +
|
|
42
|
+
`when the answer MATERIALLY changes what the experts debate — e.g. two incompatible scopes that produce ` +
|
|
43
|
+
`entirely different debates — AND you genuinely cannot pick for them. When in doubt, return [] and proceed ` +
|
|
44
|
+
`on your best reading; the debate itself will expose any wrong assumption far more cheaply than a gate.\n\n` +
|
|
19
45
|
`## Existing-repo grounding (IMPORTANT)\n` +
|
|
20
46
|
`If a "## Current Project" section is present you are working in an EXISTING repository — NOT a ` +
|
|
21
47
|
`greenfield project. Ground every question and every option in what that snapshot actually shows ` +
|
|
@@ -28,17 +54,19 @@ export function buildClarificationPrompt(topic, conversationContext, previousQA)
|
|
|
28
54
|
`the project IS the one described in the "## Current Project" section of the context. DO NOT ask which project.\n` +
|
|
29
55
|
`- Only ask about project identity when the topic mentions multiple distinct projects or external products.\n` +
|
|
30
56
|
`- Use the project's package.json name and description as implicit context for follow-up questions.\n\n` +
|
|
31
|
-
|
|
32
|
-
`
|
|
33
|
-
`
|
|
34
|
-
`
|
|
35
|
-
`NOT default to English. Keep code identifiers, file paths, tech/product names, and JSON keys in English.\n\n` +
|
|
57
|
+
buildLanguageRule(lang) +
|
|
58
|
+
`The user reads and answers these on a card, so the "question", "why", and every option ` +
|
|
59
|
+
`"label"/"description" MUST be in that language — never default to English for card text, and ` +
|
|
60
|
+
`do NOT mirror the language of any "## Scope Research"/context block; follow the user's language.\n\n` +
|
|
36
61
|
`Output ONLY a JSON array (no markdown, no preamble):\n` +
|
|
37
|
-
`[{"question": "...", "why": "why this matters for a focused discussion", "
|
|
38
|
-
`
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
`-
|
|
62
|
+
`[{"question": "...", "why": "why this matters for a focused discussion", "options": [` +
|
|
63
|
+
`{"label": "option A", "description": "what picking this means and its trade-off — one line", "recommended": true}, ` +
|
|
64
|
+
`{"label": "option B", "description": "what picking this means and its trade-off — one line"}], "isRequired": true}]\n\n` +
|
|
65
|
+
`Rules for "options" (each option is a real, distinct fork the user picks between):\n` +
|
|
66
|
+
`- Every option MUST carry a "label" (the short button text) AND a "description" (one line explaining what choosing it means / its trade-off) so the user can decide without guessing. Never emit a bare label with no description.\n` +
|
|
67
|
+
`- Mark EXACTLY ONE option with "recommended": true — the option you would choose if the user said "you decide", given the topic + project context. Be decisive; the user should never face an unranked list.\n` +
|
|
68
|
+
`- Omit "recommended" on every option ONLY in a genuine 50/50 tie where recommending either would be misleading. A missing recommendation must be the rare exception, not the default.\n` +
|
|
69
|
+
`- Provide 2-4 options per question. Do NOT add "type your own" / "let's discuss" options yourself — those escape hatches are appended automatically.\n` +
|
|
42
70
|
`Return [] if no clarification is needed.`,
|
|
43
71
|
prompt: `## Topic\n${topic}\n\n` +
|
|
44
72
|
(conversationContext ? `## Conversation Context\n${conversationContext}\n` : "") +
|
|
@@ -125,6 +153,79 @@ const ENGLISH_ONLY_RULE = `\n## Language Rule (mandatory)\n` +
|
|
|
125
153
|
`Code identifiers, tool output, JSON keys, and citation tags must remain in English. ` +
|
|
126
154
|
`The user-facing summary at the end of the council is the only place where ` +
|
|
127
155
|
`the user's native language is used; the debate is engineering-internal.\n`;
|
|
156
|
+
/**
|
|
157
|
+
* Feature B — the debate language rule, parameterized. The user's chosen
|
|
158
|
+
* language IS the debate language (no separate translate-back pass), so the
|
|
159
|
+
* prompts that used to hard-force English now select their rule from the
|
|
160
|
+
* resolved `councilLanguage` setting.
|
|
161
|
+
*
|
|
162
|
+
* Regardless of language, machine-readable tokens stay verbatim English so the
|
|
163
|
+
* original stability guarantee (citation tags, JSON, cross-turn citations) is
|
|
164
|
+
* preserved: `[CONFIRMED via …]` / `[REFUTED via …]` / `[UNVERIFIED: …]` tags,
|
|
165
|
+
* JSON keys and the `type` field, code identifiers, tool output, and STACK LOCK
|
|
166
|
+
* technology names.
|
|
167
|
+
*
|
|
168
|
+
* Modes (`lang` is already normalized by `normalizeCouncilLanguage`):
|
|
169
|
+
* - undefined / "english" → the historical English-only rule, byte-identical
|
|
170
|
+
* so existing prompt-string tests and machine-stability are unaffected.
|
|
171
|
+
* - "auto" → write in the SAME language as the user's brief/topic (detected
|
|
172
|
+
* from the brief that every debate prompt already embeds).
|
|
173
|
+
* - any other value → write in that named language.
|
|
174
|
+
*/
|
|
175
|
+
const NON_ENGLISH_TOKENS_RULE = `Keep these verbatim in English no matter what: code identifiers, tool output, ` +
|
|
176
|
+
`JSON keys and the \`type\` field, citation tags (\`[CONFIRMED via …]\`, ` +
|
|
177
|
+
`\`[REFUTED via …]\`, \`[UNVERIFIED: …]\`), and any STACK LOCK technology names. ` +
|
|
178
|
+
`Only your prose/analysis text switches language.\n`;
|
|
179
|
+
export function buildLanguageRule(lang) {
|
|
180
|
+
if (!lang || lang === "english")
|
|
181
|
+
return ENGLISH_ONLY_RULE;
|
|
182
|
+
if (lang === "auto") {
|
|
183
|
+
return (`\n## Language Rule (mandatory)\n` +
|
|
184
|
+
`Write your ENTIRE response in the SAME language the user used in the ` +
|
|
185
|
+
`Discussion Brief / topic below. If the brief is in Vietnamese, write in ` +
|
|
186
|
+
`Vietnamese; if Japanese, Japanese; if English, English. ` +
|
|
187
|
+
NON_ENGLISH_TOKENS_RULE);
|
|
188
|
+
}
|
|
189
|
+
return (`\n## Language Rule (mandatory)\n` +
|
|
190
|
+
`Write your ENTIRE response in ${lang}. Do not switch to English for the ` +
|
|
191
|
+
`prose even if the brief or your partner's message is in another language. ` +
|
|
192
|
+
NON_ENGLISH_TOKENS_RULE);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Feature B — synthesis-specific language rule. The synthesis prompt already
|
|
196
|
+
* localizes its user-facing output to the user's language; this only adjusts (a)
|
|
197
|
+
* the now-possibly-inaccurate "debate above is entirely in English" preamble and
|
|
198
|
+
* (b) the language-selection instruction when the user PINNED a specific locale.
|
|
199
|
+
*
|
|
200
|
+
* undefined / "english" → the historical block, byte-identical (debate was
|
|
201
|
+
* English-only, output detected from the Problem Statement).
|
|
202
|
+
* "auto" → same "detect from the Problem Statement" output behavior, but the
|
|
203
|
+
* preamble no longer falsely claims the debate ran in English.
|
|
204
|
+
* pinned locale → force all prose into that language instead of detecting it.
|
|
205
|
+
*/
|
|
206
|
+
export function buildSynthesisLanguageRule(lang) {
|
|
207
|
+
const pinned = lang && lang !== "english" && lang !== "auto" ? lang : undefined;
|
|
208
|
+
const debatePreamble = !lang || lang === "english"
|
|
209
|
+
? `The debate above is entirely in English (debate language is forced). `
|
|
210
|
+
: `The debate above was conducted in the same language as the Problem Statement. `;
|
|
211
|
+
const selectLine = pinned
|
|
212
|
+
? `- Write ALL prose (JSON free-text values AND Part-2 markdown body) in ${pinned}. ` +
|
|
213
|
+
`Do not translate code, identifiers, or quoted citation tags ` +
|
|
214
|
+
`(\`[REFUTED via ...]\`, \`[CONFIRMED via ...]\`).\n\n`
|
|
215
|
+
: `- Detect the user's language from the Problem Statement. If it's Vietnamese, write in ` +
|
|
216
|
+
`Vietnamese. If Japanese, Japanese. If English, English. Do not translate code, identifiers, ` +
|
|
217
|
+
`or quoted citation tags (\`[REFUTED via ...]\`, \`[CONFIRMED via ...]\`).\n\n`;
|
|
218
|
+
return (`## Language Rule (mandatory)\n` +
|
|
219
|
+
`${debatePreamble}The user wrote the ` +
|
|
220
|
+
`Problem Statement above in their own native language. You must:\n` +
|
|
221
|
+
`- **Part 1 (JSON)**: keys, the \`type\` field, and citation/tag strings stay in ENGLISH. ` +
|
|
222
|
+
`Free-text values inside JSON fields (\`summary\`, list items, prose sections) MUST use ` +
|
|
223
|
+
`the SAME language the user used in the Problem Statement.\n` +
|
|
224
|
+
`- **Part 2 (Markdown)**: write entirely in the user's native language. Markdown headings ` +
|
|
225
|
+
`that we control (the ones listed below) stay in English as printed, but body text under ` +
|
|
226
|
+
`each heading is in the user's language.\n` +
|
|
227
|
+
selectLine);
|
|
228
|
+
}
|
|
128
229
|
/**
|
|
129
230
|
* Evidence rule injected into stance prompts. Verification tools may be
|
|
130
231
|
* absent (fast-tier participants skip them) — the rule covers both cases.
|
|
@@ -159,6 +260,20 @@ const EVIDENCE_RULE_FOLLOWUP = `\n## Evidence Rule\n` +
|
|
|
159
260
|
`- Most follow-up turns will not need any tool call.\n` +
|
|
160
261
|
`Tag verified results: \`[CONFIRMED via <tool>:<evidence>]\` or \`[REFUTED via <tool>:<evidence>]\`.\n` +
|
|
161
262
|
`Uncited numbers you cannot verify: \`[UNVERIFIED: <claim>]\`.\n`;
|
|
263
|
+
/**
|
|
264
|
+
* Scope discipline (F10). Debate turns are for DIRECTION — a stance, its
|
|
265
|
+
* reasoning, and a cross-question — not for delivering the work product. Left
|
|
266
|
+
* unconstrained, models "over-deliver": a researcher opening once emitted a full
|
|
267
|
+
* `docs/plans/…-implementation-plan.md` with file contents and a
|
|
268
|
+
* "REQUIRED SUB-SKILL: executing-plans / Which approach?" handoff — the
|
|
269
|
+
* synthesis stage's job, not a debate turn's. This keeps turns argumentative and
|
|
270
|
+
* leaves the plan/spec/code to the Leader's synthesis.
|
|
271
|
+
*/
|
|
272
|
+
const DEBATE_SCOPE_RULE = `\n## Scope\n` +
|
|
273
|
+
`This is a debate about DIRECTION, not an implementation handoff. In your turn do NOT:\n` +
|
|
274
|
+
`- write out file contents, code files, or a full step-by-step implementation/execution plan;\n` +
|
|
275
|
+
`- emit task lists, "Final file content:", plan-file templates, or "next steps / which approach?" handoffs.\n` +
|
|
276
|
+
`Argue your position and its trade-offs; the Leader's synthesis owns the plan and any artifacts.\n`;
|
|
162
277
|
/**
|
|
163
278
|
* Length discipline injected into every debate turn (F13 token-thrift). The
|
|
164
279
|
* debate-turn ceilings are generous (4096-6144 maxTokens) and reasoning models
|
|
@@ -187,7 +302,33 @@ function personaOf(role, stance) {
|
|
|
187
302
|
focus: stance.focus ?? "",
|
|
188
303
|
};
|
|
189
304
|
}
|
|
190
|
-
return {
|
|
305
|
+
return {
|
|
306
|
+
label: `${role} specialist`,
|
|
307
|
+
lens: `the ${role} discipline — what a proposal costs, breaks, or unlocks in your domain, judged with a practitioner's scar tissue`,
|
|
308
|
+
focus: "",
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Ongoing-task context block, threaded from `spec.parentContext`. Both the
|
|
313
|
+
* explicit `/council` path and auto-council attach the session/task context onto
|
|
314
|
+
* the spec (see council/index.ts), so EVERY debate stage — rebuttal, follow-up,
|
|
315
|
+
* leader evaluation, synthesis — stays anchored to the parent task and the
|
|
316
|
+
* decisions already made, instead of drifting off the isolated sub-task.
|
|
317
|
+
*
|
|
318
|
+
* `buildOpeningPrompt` already injects `conversationContext` directly, so it does
|
|
319
|
+
* NOT call this (avoids double-inclusion in the opening statement). Capped so a
|
|
320
|
+
* long session context cannot blow the per-turn debate prompt budget.
|
|
321
|
+
*/
|
|
322
|
+
function ongoingContextBlock(spec, cap = 4000) {
|
|
323
|
+
const ctx = spec.parentContext?.trim();
|
|
324
|
+
if (!ctx)
|
|
325
|
+
return "";
|
|
326
|
+
const body = ctx.length > cap ? `${ctx.slice(0, cap)}\n…(earlier context truncated)` : ctx;
|
|
327
|
+
return (`\n## Ongoing Task Context\n` +
|
|
328
|
+
`You are mid-way through a larger task — this debate continues that work; it does not restart it. ` +
|
|
329
|
+
`Treat every decision recorded below as settled input: build directly on it, and make your arguments advance the parent task from where it stands now. ` +
|
|
330
|
+
`Do not reopen settled decisions, do not propose starting over, and do not wander onto any problem other than the one this step serves.\n` +
|
|
331
|
+
`${body}\n\n---\n\n`);
|
|
191
332
|
}
|
|
192
333
|
export function buildOpeningPrompt(ctx) {
|
|
193
334
|
const me = personaOf(ctx.speakerRole, ctx.speakerStance);
|
|
@@ -198,11 +339,14 @@ export function buildOpeningPrompt(ctx) {
|
|
|
198
339
|
const focusLine = me.focus ? `\nYour specific focus: ${me.focus}\n` : "";
|
|
199
340
|
const stackLock = buildStackLockSection(ctx.spec);
|
|
200
341
|
return {
|
|
201
|
-
system: `You are the "${me.label}". Your lens: ${me.lens}
|
|
202
|
-
`
|
|
342
|
+
system: `You are the "${me.label}", and you own that chair. Your lens: ${me.lens}. ` +
|
|
343
|
+
`Speak like someone who has watched this exact class of problem fail before — not like a document.\n` +
|
|
344
|
+
`You are entering a discussion with the "${them.label}" (${them.lens}). ` +
|
|
345
|
+
`They are sharp and they will push back; a claim you cannot defend is a claim you should not open with.\n` +
|
|
203
346
|
focusLine +
|
|
204
|
-
|
|
347
|
+
buildLanguageRule(ctx.language) +
|
|
205
348
|
EVIDENCE_RULE_OPENING +
|
|
349
|
+
DEBATE_SCOPE_RULE +
|
|
206
350
|
concisenessRule(220) +
|
|
207
351
|
(stackLock ? `\n${stackLock}\n` : "") +
|
|
208
352
|
guardrails +
|
|
@@ -212,9 +356,10 @@ export function buildOpeningPrompt(ctx) {
|
|
|
212
356
|
`Constraints: ${ctx.spec.constraints.join("; ")}\n` +
|
|
213
357
|
`Success Criteria: ${ctx.spec.successCriteria.join("; ")}\n` +
|
|
214
358
|
`Scope: ${ctx.spec.scope}\n\n` +
|
|
215
|
-
`
|
|
216
|
-
`
|
|
217
|
-
|
|
359
|
+
`Deliver your opening analysis in your own voice. Take the success criteria one by one: say plainly ` +
|
|
360
|
+
`which are easy, which are hard, and where — from your seat — the bodies are buried. ` +
|
|
361
|
+
`Close by putting one pointed question to the "${them.label}": the question you most need answered before you would sign off.`,
|
|
362
|
+
prompt: `Open the debate from your stated lens. Stake out a real position — a stance nobody could disagree with is not a stance. Be specific and evidence-based, and do not drift into another role's perspective; your value here is depth, not coverage.`,
|
|
218
363
|
};
|
|
219
364
|
}
|
|
220
365
|
export function buildResponsePrompt(ctx) {
|
|
@@ -222,19 +367,22 @@ export function buildResponsePrompt(ctx) {
|
|
|
222
367
|
const them = personaOf(ctx.partnerRole, ctx.partnerStance);
|
|
223
368
|
const stackLock = buildStackLockSection(ctx.spec);
|
|
224
369
|
return {
|
|
225
|
-
system: `You are the "${me.label}" (lens: ${me.lens}) responding to the "${them.label}" (lens: ${them.lens})
|
|
226
|
-
|
|
370
|
+
system: `You are the "${me.label}" (lens: ${me.lens}) responding to the "${them.label}" (lens: ${them.lens}). ` +
|
|
371
|
+
`This is a working session between peers — candid, specific, zero diplomacy theater.\n` +
|
|
372
|
+
buildLanguageRule(ctx.language) +
|
|
227
373
|
EVIDENCE_RULE_RESPONSE +
|
|
374
|
+
DEBATE_SCOPE_RULE +
|
|
228
375
|
concisenessRule(160) +
|
|
229
376
|
(stackLock ? `\n${stackLock}\n` : "") +
|
|
230
377
|
`\n## Discussion Brief\n` +
|
|
231
378
|
`Problem: ${ctx.spec.problemStatement}\n` +
|
|
232
379
|
`Success Criteria: ${ctx.spec.successCriteria.join("; ")}\n\n` +
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
`- Where
|
|
236
|
-
`-
|
|
237
|
-
|
|
380
|
+
ongoingContextBlock(ctx.spec) +
|
|
381
|
+
`React the way a good colleague does:\n` +
|
|
382
|
+
`- Where they are right, concede fast — one line — then build their point somewhere they did not take it\n` +
|
|
383
|
+
`- Where they are wrong, say so plainly and name the exact assumption that breaks\n` +
|
|
384
|
+
`- Name the blind spot: the thing your lens sees that theirs structurally cannot\n\n` +
|
|
385
|
+
`End by pressing them with one sharp question — aimed at the weakest joint in their argument.\n\n` +
|
|
238
386
|
`Do NOT include round numbers (e.g. "Round N", "Round 2 Response", "Reply #3") ` +
|
|
239
387
|
`or any numeric counter referring to the discussion round in your output. ` +
|
|
240
388
|
`The orchestrator already prints round headers above your response.`,
|
|
@@ -247,28 +395,41 @@ export function buildFollowupPrompt(ctx) {
|
|
|
247
395
|
const them = personaOf(ctx.partnerRole, ctx.partnerStance);
|
|
248
396
|
const stackLock = buildStackLockSection(ctx.spec);
|
|
249
397
|
return {
|
|
250
|
-
|
|
251
|
-
|
|
398
|
+
// Cache-prefix stability (see project_cache_prefix_stability): every clause
|
|
399
|
+
// here depends ONLY on (speaker, partner, stance, spec, language) — all
|
|
400
|
+
// stable across rounds — so this `system` string is byte-identical from
|
|
401
|
+
// round 2..N for the same speaker. The per-round-dynamic bits (round number,
|
|
402
|
+
// running summary) MUST live in the `prompt` tail below, never here: a
|
|
403
|
+
// provider prompt-cache keys on the exact prefix, and the round number used
|
|
404
|
+
// to sit in the FIRST sentence, busting the cached prefix every round.
|
|
405
|
+
system: `You are the "${me.label}" (lens: ${me.lens}) continuing a discussion with the "${them.label}" (lens: ${them.lens}). ` +
|
|
406
|
+
`The easy points are settled; what remains is the hard residue — spend your words only there.\n` +
|
|
407
|
+
buildLanguageRule(ctx.language) +
|
|
252
408
|
EVIDENCE_RULE_FOLLOWUP +
|
|
253
409
|
concisenessRule(140) +
|
|
254
410
|
(stackLock ? `\n${stackLock}\n` : "") +
|
|
255
411
|
`\n` +
|
|
256
|
-
(ctx.
|
|
257
|
-
? `## Discussion State So Far\n${ctx.runningSummary}\n\nFocus on UNRESOLVED points only. Do not repeat agreed positions.\n\n`
|
|
258
|
-
: "") +
|
|
412
|
+
ongoingContextBlock(ctx.spec) +
|
|
259
413
|
`## Success Criteria (what we need to resolve)\n` +
|
|
260
414
|
ctx.spec.successCriteria.map((c, i) => `${i + 1}. ${c}`).join("\n") +
|
|
261
415
|
`\n\n` +
|
|
262
|
-
`Read their latest response. Then:\n` +
|
|
263
|
-
`- If they
|
|
264
|
-
`- If you still disagree, bring
|
|
265
|
-
`- If you
|
|
266
|
-
`Stay
|
|
416
|
+
`Read their latest response like a peer, not a debater scoring points. Then:\n` +
|
|
417
|
+
`- If they landed a real hit, say so and update — changing your mind on evidence is strength, not defeat\n` +
|
|
418
|
+
`- If you still disagree, do not repeat yourself louder; bring NEW evidence or attack from an angle you have not used\n` +
|
|
419
|
+
`- If you have genuinely converged, declare it in one sentence and stop arguing\n\n` +
|
|
420
|
+
`Stay in your lane — your lens, not theirs. ` +
|
|
267
421
|
`Be concise. End with: do you agree on where we've landed?\n\n` +
|
|
422
|
+
`When a "Discussion State So Far" summary is present in the message below, ` +
|
|
423
|
+
`focus on UNRESOLVED points only — restating agreed positions is dead weight.\n\n` +
|
|
268
424
|
`Do NOT include round numbers (e.g. "Round N", "Response Round 2", "Round 4") ` +
|
|
269
425
|
`or any numeric counter referring to the discussion round in your output. ` +
|
|
270
426
|
`The orchestrator already prints round headers above your response.`,
|
|
271
|
-
|
|
427
|
+
// Per-round dynamic content lives here so the `system` prefix above stays
|
|
428
|
+
// cacheable. The first user message already changes every round (partner's
|
|
429
|
+
// latest response differs), so nothing cacheable is lost by placing the
|
|
430
|
+
// round number / running summary here.
|
|
431
|
+
prompt: (ctx.runningSummary ? `## Discussion State So Far\n${ctx.runningSummary}\n\n` : "") +
|
|
432
|
+
(ctx.speakerLastPosition ? `Your previous position:\n${ctx.speakerLastPosition}\n\n` : "") +
|
|
272
433
|
`Their latest (${them.label}):\n${ctx.partnerPosition}`,
|
|
273
434
|
};
|
|
274
435
|
}
|
|
@@ -284,11 +445,12 @@ export function buildLeaderEvaluationPrompt(ctx) {
|
|
|
284
445
|
: "";
|
|
285
446
|
return {
|
|
286
447
|
system: `You are the discussion moderator evaluating whether a multi-expert debate has produced sufficient results.\n` +
|
|
287
|
-
|
|
448
|
+
buildLanguageRule(ctx.language) +
|
|
288
449
|
(stackLock ? `\n${stackLock}\n` : "") +
|
|
289
450
|
`\n## Success Criteria to Evaluate\n` +
|
|
290
451
|
ctx.spec.successCriteria.map((c, i) => `${i + 1}. ${c}`).join("\n") +
|
|
291
452
|
`\n\n` +
|
|
453
|
+
ongoingContextBlock(ctx.spec) +
|
|
292
454
|
`For EACH criterion, determine:\n` +
|
|
293
455
|
`- Is it adequately addressed by the debate? (met/not-met)\n` +
|
|
294
456
|
`- What evidence from the debate supports this?\n\n` +
|
|
@@ -302,8 +464,9 @@ export function buildLeaderEvaluationPrompt(ctx) {
|
|
|
302
464
|
outOfStackCheck +
|
|
303
465
|
`Output ONLY a JSON object (no markdown):\n` +
|
|
304
466
|
`{\n` +
|
|
467
|
+
` "nextRoundFocus": "one short phrase naming the single most important point the NEXT round should resolve (empty string if you are stopping)",\n` +
|
|
305
468
|
` "allCriteriaMet": true/false,\n` +
|
|
306
|
-
` "criteriaStatus": [{"criterion": "...", "met": true/false, "evidence": "..."}]
|
|
469
|
+
` "criteriaStatus": [{"criterion": "...", "met": true/false, "evidence": "..."}], // EXACTLY one entry per Success Criterion above, IN THE SAME ORDER. Do not merge, split, reorder, or invent criteria — the user pins these and watches each one.\n` +
|
|
307
470
|
` "unresolvedPoints": ["point 1"],\n` +
|
|
308
471
|
` "needsResearch": false,\n` +
|
|
309
472
|
` "researchQuery": null,\n` +
|
|
@@ -319,15 +482,17 @@ export function buildLeaderEvaluationPrompt(ctx) {
|
|
|
319
482
|
};
|
|
320
483
|
}
|
|
321
484
|
// ── Round summary ────────────────────────────────────────────────────────────
|
|
322
|
-
export function buildRoundSummaryPrompt(allExchanges, topic, round
|
|
485
|
+
export function buildRoundSummaryPrompt(allExchanges, topic, round,
|
|
486
|
+
/** Feature B — resolved council debate language (undefined → English). */
|
|
487
|
+
language) {
|
|
323
488
|
return {
|
|
324
489
|
system: `Summarize this discussion in 3-5 bullet points.` +
|
|
325
|
-
|
|
326
|
-
`\
|
|
327
|
-
`1.
|
|
328
|
-
`2.
|
|
329
|
-
`3.
|
|
330
|
-
`Be concise — one line per bullet. No preamble. ` +
|
|
490
|
+
buildLanguageRule(language) +
|
|
491
|
+
`\nYou are the debate's working memory — later turns see ONLY your bullets, so anything you drop is lost. Capture:\n` +
|
|
492
|
+
`1. AGREED — points both sides now share\n` +
|
|
493
|
+
`2. DISPUTED — live disagreements, with each side's strongest single argument (not their weakest)\n` +
|
|
494
|
+
`3. NEW — evidence, verified facts, or angles that first surfaced this round\n` +
|
|
495
|
+
`Be concise — one line per bullet. No preamble, no color commentary. ` +
|
|
331
496
|
`Do NOT write "Round N" or any round-number counter in your bullets — this summary is fed into later turns, where round labels read as robotic noise. Refer to points by their content.`,
|
|
332
497
|
prompt: `Round ${round} discussion on: ${topic}\n\n${allExchanges}`,
|
|
333
498
|
};
|
|
@@ -431,7 +596,8 @@ export function buildDebatePlanPrompt(spec) {
|
|
|
431
596
|
prompt: `## Topic\n${spec.problemStatement}\n\n` +
|
|
432
597
|
`## Constraints\n${spec.constraints.map((c) => `- ${c}`).join("\n") || "- (none)"}\n\n` +
|
|
433
598
|
`## Success Criteria\n${spec.successCriteria.map((c) => `- ${c}`).join("\n")}\n\n` +
|
|
434
|
-
`## Scope\n${spec.scope || "(unspecified)"}
|
|
599
|
+
`## Scope\n${spec.scope || "(unspecified)"}` +
|
|
600
|
+
ongoingContextBlock(spec),
|
|
435
601
|
};
|
|
436
602
|
}
|
|
437
603
|
function shapeHint(s) {
|
|
@@ -505,33 +671,26 @@ export function buildSynthesisPrompt(ctx) {
|
|
|
505
671
|
const decisiveness = finalShape.kind === "decision" || finalShape.kind === "implementation_plan"
|
|
506
672
|
? `\n## Decisiveness (recommendation/verdict)\n` +
|
|
507
673
|
`Lead with the single choice you would make if the user said "you decide" — name it in the first sentence of the recommendation. ` +
|
|
508
|
-
`Do NOT hedge with "it depends", "both have merits", or an unranked list of options. ` +
|
|
674
|
+
`Do NOT hedge with "it depends", "both have merits", or an unranked list of options; the user hired a panel to get a call, not a menu. ` +
|
|
509
675
|
`If the debate genuinely did not converge, say so in one sentence and STILL give your best single recommendation plus the one condition that would change it.\n`
|
|
510
676
|
: "";
|
|
511
|
-
let system = `You are the team lead synthesizing a multi-specialist discussion
|
|
677
|
+
let system = `You are the team lead synthesizing a multi-specialist discussion. The panel has argued; now you rule. ` +
|
|
678
|
+
`Work like an editor-in-chief: keep what survived scrutiny, cut what got refuted, credit the dissent worth keeping, ` +
|
|
679
|
+
`and hand the user something they can act on without re-reading the debate.\n\n` +
|
|
512
680
|
`## Original Brief\n` +
|
|
513
681
|
`Problem: ${ctx.spec.problemStatement}\n` +
|
|
514
682
|
`Constraints: ${ctx.spec.constraints.join("; ")}\n` +
|
|
515
683
|
`Success Criteria: ${ctx.spec.successCriteria.join("; ")}\n` +
|
|
684
|
+
ongoingContextBlock(ctx.spec) +
|
|
516
685
|
intent +
|
|
517
686
|
(stackLockForSynth ? `\n${stackLockForSynth}\n` : "") +
|
|
518
687
|
guardrailBlock +
|
|
519
688
|
decisiveness +
|
|
520
|
-
`\nProduce the answer the user
|
|
689
|
+
`\nProduce the answer the user actually asked for — do NOT default to an implementation plan ` +
|
|
521
690
|
`unless the output shape explicitly asks for actionItems/plan. ` +
|
|
522
|
-
`Stay grounded in the
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
`Problem Statement above in their own native language. You must:\n` +
|
|
526
|
-
`- **Part 1 (JSON)**: keys, the \`type\` field, and citation/tag strings stay in ENGLISH. ` +
|
|
527
|
-
`Free-text values inside JSON fields (\`summary\`, list items, prose sections) MUST use ` +
|
|
528
|
-
`the SAME language the user used in the Problem Statement.\n` +
|
|
529
|
-
`- **Part 2 (Markdown)**: write entirely in the user's native language. Markdown headings ` +
|
|
530
|
-
`that we control (the ones listed below) stay in English as printed, but body text under ` +
|
|
531
|
-
`each heading is in the user's language.\n` +
|
|
532
|
-
`- Detect the user's language from the Problem Statement. If it's Vietnamese, write in ` +
|
|
533
|
-
`Vietnamese. If Japanese, Japanese. If English, English. Do not translate code, identifiers, ` +
|
|
534
|
-
`or quoted citation tags (\`[REFUTED via ...]\`, \`[CONFIRMED via ...]\`).\n\n` +
|
|
691
|
+
`Stay grounded in what was actually said in the debate: you may sharpen and arbitrate, but never invent facts ` +
|
|
692
|
+
`the specialists did not raise, and mark unverified claims explicitly.\n\n` +
|
|
693
|
+
buildSynthesisLanguageRule(ctx.language) +
|
|
535
694
|
`Output TWO parts separated by the exact line \`---READABLE---\`:\n\n` +
|
|
536
695
|
`**Part 1: JSON** — a single JSON object:\n` +
|
|
537
696
|
`{\n` +
|
|
@@ -539,10 +698,36 @@ export function buildSynthesisPrompt(ctx) {
|
|
|
539
698
|
` "summary": "1-2 sentence executive summary in the user's native language",\n` +
|
|
540
699
|
sectionLines +
|
|
541
700
|
"\n" +
|
|
701
|
+
` "nextActions": [ /* 2-4 items, see the Next Actions rule below */ ]\n` +
|
|
542
702
|
`}\n\n` +
|
|
703
|
+
`## Next Actions (mandatory — YOU decide, do not default)\n` +
|
|
704
|
+
`After reading this outcome, what should the user be offered to do NEXT? This depends ` +
|
|
705
|
+
`entirely on WHY this debate happened — a bug investigation, an evaluation, a plan, and a ` +
|
|
706
|
+
`decision each warrant DIFFERENT follow-ups. A fixed "accept / research / apply" menu is wrong. ` +
|
|
707
|
+
`Choose 2-4 actions from this fixed vocabulary, ordered best-first (index 0 = your recommended ` +
|
|
708
|
+
`default), writing each label/reason in the user's native language:\n` +
|
|
709
|
+
` - "implement" → the conclusion is ready to BUILD. Offer this whenever acting on the outcome ` +
|
|
710
|
+
`means changing code — INCLUDING a decision to refactor / remove / add. The conclusion itself is ` +
|
|
711
|
+
`the spec (no separate plan artifact needed); picking it loads that spec and carries it out ` +
|
|
712
|
+
`through the normal workflow (plan → change → verify). Make it the recommended default (index 0) ` +
|
|
713
|
+
`when the debate converged on a concrete, buildable decision. Label it with the ACTION (e.g. ` +
|
|
714
|
+
`"Triển khai …" / "Implement …"), never "continue".\n` +
|
|
715
|
+
` - "continue_session" → return to the composer WITHOUT building. The user keeps DISCUSSING with ` +
|
|
716
|
+
`this debate as context (their next message inherits the conclusion automatically). The right ` +
|
|
717
|
+
`default for a pure evaluation / discussion whose deliverable is the analysis itself, or when the ` +
|
|
718
|
+
`user should weigh in before any code change. This ALSO covers "ask a follow-up" — do NOT emit a ` +
|
|
719
|
+
`separate follow-up action.\n` +
|
|
720
|
+
` - "save_exit" → the analysis IS the deliverable; save it and stop here.\n` +
|
|
721
|
+
`Rules: choose from {"implement","continue_session","save_exit"}. Offer "implement" whenever the ` +
|
|
722
|
+
`outcome is actionable in code (a build decision, an implementation_plan, or a bug investigation ` +
|
|
723
|
+
`ready to fix) and make it index 0; otherwise lead with "continue_session". NEVER attach an ` +
|
|
724
|
+
`implementation-flavoured label ("triển khai", "build", "fix now") to "continue_session" — if you ` +
|
|
725
|
+
`mean build, the action MUST be "implement". Always include an escape ("save_exit" or ` +
|
|
726
|
+
`"continue_session"). Emit each as ` +
|
|
727
|
+
`{"action":"<id>","label":"<short button text>","reason":"<one line: why this fits THIS debate>"}.\n\n` +
|
|
543
728
|
`**Part 2: Human-readable** — after \`---READABLE---\`, write in markdown with these headings (in this order):\n` +
|
|
544
729
|
headingLines +
|
|
545
|
-
`\n\nBe decisive but evidence-grounded.`;
|
|
730
|
+
`\n\nBe decisive but evidence-grounded — a verdict without evidence is noise; evidence without a verdict is homework handed back to the user.`;
|
|
546
731
|
if (styleDirective) {
|
|
547
732
|
system = `${styleDirective}\n\n${system}`;
|
|
548
733
|
}
|
|
@@ -582,16 +767,18 @@ ${ctx.allExchanges}${extraContext}`,
|
|
|
582
767
|
/**
|
|
583
768
|
* Builds the system prompt for the research role.
|
|
584
769
|
*
|
|
585
|
-
* When `hasUrl` is true, injects a mandatory instruction to
|
|
586
|
-
* or
|
|
770
|
+
* When `hasUrl` is true, injects a mandatory instruction to use fetch_url (preferred
|
|
771
|
+
* for content) or a browser tool (playwright/chrome when screenshots or heavy JS interaction
|
|
772
|
+
* are required) before reporting Frontend Findings (CQ-04).
|
|
587
773
|
*
|
|
588
774
|
* Output format enforces 3 labelled sections with citation requirements (CQ-05).
|
|
589
775
|
*/
|
|
590
776
|
export function buildResearchSystemPrompt(hasUrl, internetFirst = false) {
|
|
591
777
|
const urlInstruction = hasUrl
|
|
592
778
|
? `\n## URL Research Requirement\n` +
|
|
593
|
-
`This topic contains a URL. You MUST
|
|
594
|
-
`
|
|
779
|
+
`This topic contains a URL. You MUST use the native fetch_url tool (preferred for most pages) ` +
|
|
780
|
+
`or a browser tool (playwright/chrome-devtools when you need screenshots, rendered layout, or interaction) ` +
|
|
781
|
+
`before reporting Frontend Findings. Do not skip this step.\n`
|
|
595
782
|
: "";
|
|
596
783
|
const modeBlock = internetFirst
|
|
597
784
|
? `\n## Research Mode: INTERNET-FIRST\n` +
|
|
@@ -615,8 +802,8 @@ export function buildResearchSystemPrompt(hasUrl, internetFirst = false) {
|
|
|
615
802
|
`If no internet search was performed, write: ` +
|
|
616
803
|
`_No internet research performed (tavily/web-fetch unavailable or not needed)._\n\n` +
|
|
617
804
|
`## Frontend Findings (live)\n` +
|
|
618
|
-
`Each finding must cite [snapshot:uid] from a Playwright screenshot
|
|
619
|
-
`
|
|
805
|
+
`Each finding must cite [snapshot:uid] from a Playwright/Chrome-DevTools screenshot/inspection **if** a browser tool was used.\n` +
|
|
806
|
+
`For ordinary pages, cite the result of fetch_url. If no URL inspection happened, write: _No live frontend inspection performed._\n\n` +
|
|
620
807
|
`Do NOT speculate. Only report what you verified with tools.`);
|
|
621
808
|
}
|
|
622
809
|
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/council/stance-recall.ts
|
|
3
|
+
*
|
|
4
|
+
* Sprint-2 item 3 — per-stance recall at debate opening. Builds the
|
|
5
|
+
* `CouncilConfig.stanceRecall` function from an EE client: given the panel's
|
|
6
|
+
* unique roles and a query, it fires ONE stance-weighted `/api/recall` per role
|
|
7
|
+
* (in parallel, bounded, failure-tolerant) and returns a `role → seed-text` map.
|
|
8
|
+
*
|
|
9
|
+
* The server weights the recall collections by the stance/role hint (researcher
|
|
10
|
+
* → principles, implementer → behavioral, verifier → self-QA), so each stance
|
|
11
|
+
* opens grounded in the slice of the brain its lens cares about — instead of the
|
|
12
|
+
* whole panel sharing one generic recall.
|
|
13
|
+
*
|
|
14
|
+
* Contract: never throws. A role whose recall fails/empties/ times out simply
|
|
15
|
+
* gets no entry in the map (that participant opens unchanged).
|
|
16
|
+
*/
|
|
17
|
+
import type { EERecallResponse } from "../ee/types.js";
|
|
18
|
+
/** Minimal EE-client surface this helper needs (keeps it unit-testable). */
|
|
19
|
+
export interface StanceRecallClient {
|
|
20
|
+
recall(query: string, opts?: {
|
|
21
|
+
stance?: string;
|
|
22
|
+
cwd?: string;
|
|
23
|
+
project?: string;
|
|
24
|
+
sourceSession?: string;
|
|
25
|
+
timeoutMs?: number;
|
|
26
|
+
}): Promise<EERecallResponse | null>;
|
|
27
|
+
}
|
|
28
|
+
export interface StanceRecallOptions {
|
|
29
|
+
cwd?: string;
|
|
30
|
+
project?: string;
|
|
31
|
+
sourceSession?: string;
|
|
32
|
+
/** Per-recall timeout. Kept modest so N parallel recalls don't stall openings. */
|
|
33
|
+
timeoutMs?: number;
|
|
34
|
+
/** Cap the seed text folded into each opening so it can't blow the prompt. */
|
|
35
|
+
maxSeedChars?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build a `stanceRecall(roles, query)` function bound to an EE client. Returns
|
|
39
|
+
* undefined when no client is available, so callers can spread it into
|
|
40
|
+
* CouncilConfig without a conditional (`stanceRecall: makeStanceRecall(...)`).
|
|
41
|
+
*/
|
|
42
|
+
export declare function makeStanceRecall(client: StanceRecallClient | null | undefined, opts?: StanceRecallOptions): ((roles: string[], query: string) => Promise<Map<string, string>>) | undefined;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/council/stance-recall.ts
|
|
3
|
+
*
|
|
4
|
+
* Sprint-2 item 3 — per-stance recall at debate opening. Builds the
|
|
5
|
+
* `CouncilConfig.stanceRecall` function from an EE client: given the panel's
|
|
6
|
+
* unique roles and a query, it fires ONE stance-weighted `/api/recall` per role
|
|
7
|
+
* (in parallel, bounded, failure-tolerant) and returns a `role → seed-text` map.
|
|
8
|
+
*
|
|
9
|
+
* The server weights the recall collections by the stance/role hint (researcher
|
|
10
|
+
* → principles, implementer → behavioral, verifier → self-QA), so each stance
|
|
11
|
+
* opens grounded in the slice of the brain its lens cares about — instead of the
|
|
12
|
+
* whole panel sharing one generic recall.
|
|
13
|
+
*
|
|
14
|
+
* Contract: never throws. A role whose recall fails/empties/ times out simply
|
|
15
|
+
* gets no entry in the map (that participant opens unchanged).
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_TIMEOUT_MS = 4000;
|
|
18
|
+
const DEFAULT_MAX_SEED_CHARS = 1200;
|
|
19
|
+
/**
|
|
20
|
+
* Build a `stanceRecall(roles, query)` function bound to an EE client. Returns
|
|
21
|
+
* undefined when no client is available, so callers can spread it into
|
|
22
|
+
* CouncilConfig without a conditional (`stanceRecall: makeStanceRecall(...)`).
|
|
23
|
+
*/
|
|
24
|
+
export function makeStanceRecall(client, opts = {}) {
|
|
25
|
+
if (!client)
|
|
26
|
+
return undefined;
|
|
27
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
28
|
+
const maxSeedChars = opts.maxSeedChars ?? DEFAULT_MAX_SEED_CHARS;
|
|
29
|
+
return async (roles, query) => {
|
|
30
|
+
const seeds = new Map();
|
|
31
|
+
const q = (query ?? "").trim();
|
|
32
|
+
if (!q)
|
|
33
|
+
return seeds;
|
|
34
|
+
const unique = Array.from(new Set(roles.filter((r) => typeof r === "string" && r.trim())));
|
|
35
|
+
if (unique.length === 0)
|
|
36
|
+
return seeds;
|
|
37
|
+
await Promise.all(unique.map(async (role) => {
|
|
38
|
+
try {
|
|
39
|
+
const resp = await client.recall(q, {
|
|
40
|
+
stance: role,
|
|
41
|
+
cwd: opts.cwd,
|
|
42
|
+
project: opts.project,
|
|
43
|
+
sourceSession: opts.sourceSession,
|
|
44
|
+
timeoutMs,
|
|
45
|
+
});
|
|
46
|
+
const text = resp?.text?.trim();
|
|
47
|
+
if (text)
|
|
48
|
+
seeds.set(role, text.slice(0, maxSeedChars));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
/* per-role failure is non-fatal — that stance just opens unseeded */
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
return seeds;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=stance-recall.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strip inline chain-of-thought markup from council LLM output.
|
|
3
|
+
*
|
|
4
|
+
* Some providers (kimi-k2.7 via opencode-go, GLM thinking variants) emit
|
|
5
|
+
* reasoning inline as `<think>…</think>` in `result.text` instead of the AI
|
|
6
|
+
* SDK's separated `reasoningText`. Rendered verbatim, the user sees hundreds
|
|
7
|
+
* of words of internal drafting above every debate turn (live-verified
|
|
8
|
+
* 2026-07-06). Applied at the council LLM boundary (src/council/llm.ts) so
|
|
9
|
+
* every consumer — debate turns, leader evals, synthesis — is covered.
|
|
10
|
+
*
|
|
11
|
+
* Handles three shapes:
|
|
12
|
+
* - complete `<think>…</think>` blocks anywhere (global, case-insensitive)
|
|
13
|
+
* - an unclosed trailing `<think>…` block (output truncated mid-reasoning)
|
|
14
|
+
* - a stray leading `…</think>` (model omitted the opener; everything up to
|
|
15
|
+
* and including the close tag is reasoning)
|
|
16
|
+
*/
|
|
17
|
+
export declare function stripThinkBlocks(text: string): string;
|