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
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/research.ts
|
|
3
|
+
*
|
|
4
|
+
* Native research tools for the inner agent.
|
|
5
|
+
*
|
|
6
|
+
* These replace the previous external MCP servers (fetch, tavily, and eventually
|
|
7
|
+
* context7 / muonroi-docs) so that web/docs lookup and search are:
|
|
8
|
+
* - Always available without spawn / warmup / "Connection closed"
|
|
9
|
+
* - Subject to the same permission, capping, redaction and cost rules as other builtins
|
|
10
|
+
* - Fast and reliable on first turn
|
|
11
|
+
*
|
|
12
|
+
* memory and playwright were removed from defaults (see auto-setup.ts).
|
|
13
|
+
* Full browser automation (playwright) can still be added manually if needed.
|
|
14
|
+
*/
|
|
15
|
+
import { type ToolSet } from "ai";
|
|
16
|
+
export interface FetchUrlOptions {
|
|
17
|
+
format?: "markdown" | "text" | "html";
|
|
18
|
+
/** Max characters to return (soft cap) */
|
|
19
|
+
maxChars?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function fetchUrl(url: string, opts?: FetchUrlOptions): Promise<string>;
|
|
22
|
+
export interface WebSearchOptions {
|
|
23
|
+
maxResults?: number;
|
|
24
|
+
/** Optional override; otherwise loaded from keychain or TAVILY_API_KEY */
|
|
25
|
+
apiKey?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function webSearch(query: string, opts?: WebSearchOptions): Promise<string>;
|
|
28
|
+
/** Register the native research tools into the provided ToolSet. */
|
|
29
|
+
export declare function registerNativeResearchTools(tools: ToolSet): ToolSet;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/research.ts
|
|
3
|
+
*
|
|
4
|
+
* Native research tools for the inner agent.
|
|
5
|
+
*
|
|
6
|
+
* These replace the previous external MCP servers (fetch, tavily, and eventually
|
|
7
|
+
* context7 / muonroi-docs) so that web/docs lookup and search are:
|
|
8
|
+
* - Always available without spawn / warmup / "Connection closed"
|
|
9
|
+
* - Subject to the same permission, capping, redaction and cost rules as other builtins
|
|
10
|
+
* - Fast and reliable on first turn
|
|
11
|
+
*
|
|
12
|
+
* memory and playwright were removed from defaults (see auto-setup.ts).
|
|
13
|
+
* Full browser automation (playwright) can still be added manually if needed.
|
|
14
|
+
*/
|
|
15
|
+
import { dynamicTool, jsonSchema } from "ai";
|
|
16
|
+
import TurndownService from "turndown";
|
|
17
|
+
import { getMcpKey } from "../mcp/mcp-keychain.js";
|
|
18
|
+
const turndown = new TurndownService({
|
|
19
|
+
headingStyle: "atx",
|
|
20
|
+
codeBlockStyle: "fenced",
|
|
21
|
+
bulletListMarker: "-",
|
|
22
|
+
});
|
|
23
|
+
// Basic cleanup for HTML before turndown (remove scripts, styles, etc.)
|
|
24
|
+
function sanitizeForMarkdown(html) {
|
|
25
|
+
return html
|
|
26
|
+
.replace(/<script[\s\S]*?<\/script>/gi, "")
|
|
27
|
+
.replace(/<style[\s\S]*?<\/style>/gi, "")
|
|
28
|
+
.replace(/<noscript[\s\S]*?<\/noscript>/gi, "")
|
|
29
|
+
.replace(/<!--[\s\S]*?-->/g, "");
|
|
30
|
+
}
|
|
31
|
+
function extractTitle(html) {
|
|
32
|
+
const m = html.match(/<title[^>]*>([^<]+)<\/title>/i);
|
|
33
|
+
return m ? m[1].trim() : undefined;
|
|
34
|
+
}
|
|
35
|
+
export async function fetchUrl(url, opts = {}) {
|
|
36
|
+
const { format = "markdown", maxChars = 12000 } = opts;
|
|
37
|
+
const controller = new AbortController();
|
|
38
|
+
const timeout = setTimeout(() => controller.abort(), 15000);
|
|
39
|
+
try {
|
|
40
|
+
const res = await fetch(url, {
|
|
41
|
+
signal: controller.signal,
|
|
42
|
+
headers: {
|
|
43
|
+
"User-Agent": "muonroi-cli/1.0 (+https://github.com/muonroi/muonroi-cli)",
|
|
44
|
+
Accept: "text/html,application/xhtml+xml,application/json,text/plain,*/*",
|
|
45
|
+
},
|
|
46
|
+
redirect: "follow",
|
|
47
|
+
});
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
return `ERROR fetch_failed: HTTP ${res.status} ${res.statusText} for ${url}`;
|
|
50
|
+
}
|
|
51
|
+
const contentType = res.headers.get("content-type") || "";
|
|
52
|
+
let body = await res.text();
|
|
53
|
+
if (format === "html") {
|
|
54
|
+
return body.length > maxChars ? body.slice(0, maxChars) + "\n... [truncated]" : body;
|
|
55
|
+
}
|
|
56
|
+
if (contentType.includes("application/json")) {
|
|
57
|
+
try {
|
|
58
|
+
const obj = JSON.parse(body);
|
|
59
|
+
body = JSON.stringify(obj, null, 2);
|
|
60
|
+
}
|
|
61
|
+
catch { }
|
|
62
|
+
return body.length > maxChars ? body.slice(0, maxChars) + "\n... [truncated]" : body;
|
|
63
|
+
}
|
|
64
|
+
// Treat as HTML or plain text
|
|
65
|
+
const isHtml = /<\/?[a-z][\s\S]*>/i.test(body) || contentType.includes("html");
|
|
66
|
+
if (format === "text") {
|
|
67
|
+
// Very lightweight text extraction
|
|
68
|
+
const text = isHtml
|
|
69
|
+
? body
|
|
70
|
+
.replace(/<[^>]+>/g, " ")
|
|
71
|
+
.replace(/\s+/g, " ")
|
|
72
|
+
.trim()
|
|
73
|
+
: body;
|
|
74
|
+
return text.length > maxChars ? text.slice(0, maxChars) + "\n... [truncated]" : text;
|
|
75
|
+
}
|
|
76
|
+
// markdown (default)
|
|
77
|
+
if (isHtml) {
|
|
78
|
+
const cleaned = sanitizeForMarkdown(body);
|
|
79
|
+
const title = extractTitle(body);
|
|
80
|
+
let md = turndown.turndown(cleaned);
|
|
81
|
+
if (title && !md.startsWith("# ")) {
|
|
82
|
+
md = `# ${title}\n\n${md}`;
|
|
83
|
+
}
|
|
84
|
+
if (md.length > maxChars) {
|
|
85
|
+
md = md.slice(0, maxChars) + "\n\n... [truncated — use more specific URL or smaller scope]";
|
|
86
|
+
}
|
|
87
|
+
// Add source
|
|
88
|
+
return `${md}\n\n_Source: ${url}_`;
|
|
89
|
+
}
|
|
90
|
+
// Plain text → code block or just return
|
|
91
|
+
const out = body.length > maxChars ? body.slice(0, maxChars) + "\n... [truncated]" : body;
|
|
92
|
+
return `\`\`\`\n${out}\n\`\`\`\n\n_Source: ${url}_`;
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (err?.name === "AbortError") {
|
|
96
|
+
return `ERROR fetch_timeout: timed out after 15s fetching ${url}`;
|
|
97
|
+
}
|
|
98
|
+
return `ERROR fetch_error: ${err instanceof Error ? err.message : String(err)}`;
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
clearTimeout(timeout);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export async function webSearch(query, opts = {}) {
|
|
105
|
+
const maxResults = Math.max(1, Math.min(opts.maxResults ?? 8, 20));
|
|
106
|
+
let key = opts.apiKey;
|
|
107
|
+
if (!key) {
|
|
108
|
+
key = (await getMcpKey("tavily")) || process.env.TAVILY_API_KEY || "";
|
|
109
|
+
}
|
|
110
|
+
if (!key || key.length < 10) {
|
|
111
|
+
return ("ERROR no_tavily_key: Tavily API key is required for web_search. " +
|
|
112
|
+
"Run `muonroi-cli mcp setup-research` or set TAVILY_API_KEY. " +
|
|
113
|
+
"You can also use `fetch_url` for direct URLs.");
|
|
114
|
+
}
|
|
115
|
+
const controller = new AbortController();
|
|
116
|
+
const timeout = setTimeout(() => controller.abort(), 12000);
|
|
117
|
+
try {
|
|
118
|
+
const res = await fetch("https://api.tavily.com/search", {
|
|
119
|
+
method: "POST",
|
|
120
|
+
signal: controller.signal,
|
|
121
|
+
headers: {
|
|
122
|
+
"Content-Type": "application/json",
|
|
123
|
+
},
|
|
124
|
+
body: JSON.stringify({
|
|
125
|
+
api_key: key,
|
|
126
|
+
query,
|
|
127
|
+
max_results: maxResults,
|
|
128
|
+
include_answer: true,
|
|
129
|
+
include_raw_content: false,
|
|
130
|
+
search_depth: "basic",
|
|
131
|
+
}),
|
|
132
|
+
});
|
|
133
|
+
if (!res.ok) {
|
|
134
|
+
const text = await res.text().catch(() => "");
|
|
135
|
+
return `ERROR tavily_http_${res.status}: ${text.slice(0, 300)}`;
|
|
136
|
+
}
|
|
137
|
+
const data = await res.json();
|
|
138
|
+
const lines = [];
|
|
139
|
+
if (data.answer) {
|
|
140
|
+
lines.push("**Answer summary:**");
|
|
141
|
+
lines.push(data.answer);
|
|
142
|
+
lines.push("");
|
|
143
|
+
}
|
|
144
|
+
const results = Array.isArray(data.results) ? data.results : [];
|
|
145
|
+
if (results.length === 0) {
|
|
146
|
+
return "No web results found.";
|
|
147
|
+
}
|
|
148
|
+
lines.push(`**Web results** (top ${Math.min(results.length, maxResults)}):\n`);
|
|
149
|
+
for (const r of results.slice(0, maxResults)) {
|
|
150
|
+
const title = r.title || r.url;
|
|
151
|
+
const url = r.url;
|
|
152
|
+
const content = (r.content || r.raw_content || "").trim().slice(0, 600);
|
|
153
|
+
lines.push(`- **${title}**`);
|
|
154
|
+
lines.push(` ${url}`);
|
|
155
|
+
if (content)
|
|
156
|
+
lines.push(` ${content.replace(/\s+/g, " ")}`);
|
|
157
|
+
lines.push("");
|
|
158
|
+
}
|
|
159
|
+
if (data.query) {
|
|
160
|
+
lines.push(`_Query: ${data.query}_`);
|
|
161
|
+
}
|
|
162
|
+
return lines.join("\n");
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
if (err?.name === "AbortError") {
|
|
166
|
+
return "ERROR web_search_timeout: Tavily request timed out.";
|
|
167
|
+
}
|
|
168
|
+
return `ERROR web_search_failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
clearTimeout(timeout);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** Register the native research tools into the provided ToolSet. */
|
|
175
|
+
export function registerNativeResearchTools(tools) {
|
|
176
|
+
tools.fetch_url = dynamicTool({
|
|
177
|
+
description: "Fetch a URL and return clean, readable content as markdown (default), plain text, or raw HTML. " +
|
|
178
|
+
"Ideal for documentation, articles, GitHub, blog posts, raw files, and any public web page. " +
|
|
179
|
+
"Use this for most 'read this URL' needs instead of external MCP fetch.",
|
|
180
|
+
inputSchema: jsonSchema({
|
|
181
|
+
type: "object",
|
|
182
|
+
properties: {
|
|
183
|
+
url: { type: "string", description: "The full http(s) URL to fetch" },
|
|
184
|
+
format: {
|
|
185
|
+
type: "string",
|
|
186
|
+
enum: ["markdown", "text", "html"],
|
|
187
|
+
description: "Output format. Default: markdown (best for agents)",
|
|
188
|
+
},
|
|
189
|
+
maxChars: {
|
|
190
|
+
type: "number",
|
|
191
|
+
description: "Maximum characters to return (500-30000). Default ~12000.",
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
required: ["url"],
|
|
195
|
+
additionalProperties: false,
|
|
196
|
+
}),
|
|
197
|
+
execute: async (input) => {
|
|
198
|
+
const url = String(input?.url || "").trim();
|
|
199
|
+
if (!url || !/^https?:\/\//i.test(url)) {
|
|
200
|
+
return "ERROR invalid_url: fetch_url requires a full http(s):// URL";
|
|
201
|
+
}
|
|
202
|
+
const format = (["markdown", "text", "html"].includes(input?.format) ? input.format : "markdown");
|
|
203
|
+
const maxChars = typeof input?.maxChars === "number" ? input.maxChars : undefined;
|
|
204
|
+
return fetchUrl(url, { format, maxChars });
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
tools.web_search = dynamicTool({
|
|
208
|
+
description: "Search the live web using Tavily (LLM-optimized search with summaries). " +
|
|
209
|
+
"Returns titles, URLs, and content snippets. Requires a Tavily API key (free tier available). " +
|
|
210
|
+
"Use together with fetch_url when you need deeper content from specific results.",
|
|
211
|
+
inputSchema: jsonSchema({
|
|
212
|
+
type: "object",
|
|
213
|
+
properties: {
|
|
214
|
+
query: { type: "string", description: "Search query (natural language is fine)" },
|
|
215
|
+
maxResults: {
|
|
216
|
+
type: "number",
|
|
217
|
+
description: "How many results to return (1-20). Default 8.",
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
required: ["query"],
|
|
221
|
+
additionalProperties: false,
|
|
222
|
+
}),
|
|
223
|
+
execute: async (input) => {
|
|
224
|
+
const query = String(input?.query || "").trim();
|
|
225
|
+
if (!query)
|
|
226
|
+
return "ERROR invalid_query: web_search requires a non-empty query";
|
|
227
|
+
const maxResults = typeof input?.maxResults === "number" ? input.maxResults : undefined;
|
|
228
|
+
return webSearch(query, { maxResults });
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
return tools;
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=research.js.map
|
|
@@ -34,6 +34,8 @@ export interface TaskRequest {
|
|
|
34
34
|
description: string;
|
|
35
35
|
prompt: string;
|
|
36
36
|
maxToolRounds?: number;
|
|
37
|
+
/** When set, bypasses parent-tier cap and uses this model for the sub-agent. */
|
|
38
|
+
modelId?: string;
|
|
37
39
|
}
|
|
38
40
|
export interface TaskRun {
|
|
39
41
|
agent: string;
|
|
@@ -192,6 +194,13 @@ export interface ToolGroup {
|
|
|
192
194
|
items: ToolGroupItem[];
|
|
193
195
|
startedAt: number;
|
|
194
196
|
finishedAt?: number;
|
|
197
|
+
/**
|
|
198
|
+
* True when this group was rebuilt from a persisted transcript rather than
|
|
199
|
+
* observed live (see ui/utils/group-tool-entries.ts). Its timestamps come
|
|
200
|
+
* from entry write-time, so the elapsed span is NOT a real measurement and
|
|
201
|
+
* must not be displayed as one.
|
|
202
|
+
*/
|
|
203
|
+
restored?: boolean;
|
|
195
204
|
inputTokens?: number;
|
|
196
205
|
outputTokens?: number;
|
|
197
206
|
}
|
|
@@ -223,7 +232,7 @@ export interface StructuredResponse {
|
|
|
223
232
|
taskType: string;
|
|
224
233
|
data: Record<string, unknown>;
|
|
225
234
|
}
|
|
226
|
-
export type CouncilQuestionPhase = "clarify" | "preflight" | "plan-confirm" | "post-debate" | "pil-interview" | "pil-acceptance" | "tool-loop-cap" | "safety-override";
|
|
235
|
+
export type CouncilQuestionPhase = "clarify" | "preflight" | "plan-confirm" | "post-debate" | "pil-interview" | "pil-acceptance" | "tool-loop-cap" | "safety-override" | "ask-user";
|
|
227
236
|
export type CouncilOptionKind = "choice" | "freetext" | "chat";
|
|
228
237
|
export interface CouncilQuestionOption {
|
|
229
238
|
label: string;
|
|
@@ -246,7 +255,7 @@ export interface CouncilQuestionData {
|
|
|
246
255
|
options?: CouncilQuestionOption[];
|
|
247
256
|
defaultIndex?: number;
|
|
248
257
|
}
|
|
249
|
-
export type CouncilStatusPhase = "clarify" | "plan_debate" | "research" | "opening" | "exchange" | "evaluate" | "synthesis" | "summary";
|
|
258
|
+
export type CouncilStatusPhase = "clarify" | "panel_select" | "plan_debate" | "research" | "opening" | "exchange" | "evaluate" | "synthesis" | "summary";
|
|
250
259
|
export type CouncilStatusState = "start" | "tick" | "done" | "error";
|
|
251
260
|
export interface CouncilStatusData {
|
|
252
261
|
statusId: string;
|
|
@@ -256,12 +265,25 @@ export interface CouncilStatusData {
|
|
|
256
265
|
detail?: string;
|
|
257
266
|
role?: string;
|
|
258
267
|
elapsedMs?: number;
|
|
268
|
+
/** Client-side first-seen stamp (upsertStatus), back-dated by the emitted elapsedMs. Drives live-ticking elapsed. */
|
|
269
|
+
startedAt?: number;
|
|
259
270
|
tokensIn?: number;
|
|
260
271
|
tokensOut?: number;
|
|
272
|
+
/**
|
|
273
|
+
* Push-based stream liveness (additive, optional). `elapsedMs` alone cannot
|
|
274
|
+
* prove a council call is alive: the tick generator only advances when the
|
|
275
|
+
* CONSUMER pulls, so a round awaiting its pairs via Promise.all freezes it.
|
|
276
|
+
* These two come from the token stream itself — `streamedChars` counts text +
|
|
277
|
+
* reasoning deltas since the phase began, and `lastDeltaAgeMs` is the age of
|
|
278
|
+
* the most recent delta. Growing chars / small age = SLOW BUT ALIVE; static
|
|
279
|
+
* chars + growing age = genuinely STUCK.
|
|
280
|
+
*/
|
|
281
|
+
streamedChars?: number;
|
|
282
|
+
lastDeltaAgeMs?: number;
|
|
261
283
|
errorMessage?: string;
|
|
262
284
|
}
|
|
263
285
|
/** High-level lifecycle event for a council phase. Drives the phase timeline UI. */
|
|
264
|
-
export type CouncilPhaseKind = "clarification" | "clarification_round" | "preflight" | "debate_plan" | "research" | "opening" | "round" | "evaluation" | "mid_research" | "summary" | "synthesis" | "action_plan"
|
|
286
|
+
export type CouncilPhaseKind = "clarification" | "clarification_round" | "preflight" | "debate_plan" | "research" | "opening" | "round" | "evaluation" | "mid_research" | "grounding_verify" | "summary" | "synthesis" | "action_plan"
|
|
265
287
|
/**
|
|
266
288
|
* Sprint stage emitted by sprint-runner — one of planning/implementation/
|
|
267
289
|
* verification/judgment. label distinguishes the stage. Used so the user
|
|
@@ -333,6 +355,84 @@ export interface CouncilInfoCard {
|
|
|
333
355
|
title: string;
|
|
334
356
|
sections: CouncilInfoCardSection[];
|
|
335
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Incremental council metadata for the context rail (P3). Emitted as one or more
|
|
360
|
+
* `council_meta` chunks — the leader/panel/researchMode/costAware fields come
|
|
361
|
+
* from the council entrypoint, the round budget/ceiling from inside runDebate
|
|
362
|
+
* (locals invisible to the entrypoint). The UI upsert-merges each patch into a
|
|
363
|
+
* single `councilMeta` object, so any subset of fields may be present.
|
|
364
|
+
*/
|
|
365
|
+
/**
|
|
366
|
+
* One debate round's lifecycle record for the round-grouped transcript (P5/P6).
|
|
367
|
+
* Emitted as `council_round` chunks: a `running` record at round start, then a
|
|
368
|
+
* `done` record (guaranteed on every loop exit) carrying the outcome. The UI
|
|
369
|
+
* upsert-merges by `round` (running → done overwrite).
|
|
370
|
+
*/
|
|
371
|
+
export interface CouncilRoundRecord {
|
|
372
|
+
round: number;
|
|
373
|
+
state: "running" | "done";
|
|
374
|
+
/** This round's focus, carried from the prior round's `nextRoundFocus`. */
|
|
375
|
+
topic?: string;
|
|
376
|
+
/** Role labels of the participants active this round. */
|
|
377
|
+
participants: string[];
|
|
378
|
+
/** Number of debate pairs exchanged this round. */
|
|
379
|
+
pairCount: number;
|
|
380
|
+
/** True when this round is beyond the leader's original planned budget. */
|
|
381
|
+
emergent: boolean;
|
|
382
|
+
/** Leader-evaluated criteria met / total (absent until the round is done). */
|
|
383
|
+
criteriaMet?: number;
|
|
384
|
+
criteriaTotal?: number;
|
|
385
|
+
/** Leader's one-sentence decision reason. */
|
|
386
|
+
leaderReason?: string;
|
|
387
|
+
/** What the leader / engine decided at the end of this round. */
|
|
388
|
+
leaderDecision?: "continue" | "stop" | "extend" | "aborted" | "circuit-break" | "eval-unavailable";
|
|
389
|
+
/** Topic the leader set for the NEXT round (drives the overview). */
|
|
390
|
+
nextRoundFocus?: string;
|
|
391
|
+
/**
|
|
392
|
+
* B5 — the leader's pre-round DIRECTIVE for this round (goal + criteria still
|
|
393
|
+
* unmet going in). Captured on the round record so it survives into the
|
|
394
|
+
* post-debate conclusion card, not only the ephemeral live directive bubble —
|
|
395
|
+
* otherwise a user who looks away during the debate never sees the leader
|
|
396
|
+
* conduct the round. Present only when the conductor is on + criteria pinned.
|
|
397
|
+
*/
|
|
398
|
+
directive?: string;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Incremental council metadata for the context rail (P3). Emitted as one or more
|
|
402
|
+
* `council_meta` chunks — the leader/panel/researchMode/costAware fields come
|
|
403
|
+
* from the council entrypoint, the round budget/ceiling from inside runDebate
|
|
404
|
+
* (locals invisible to the entrypoint). The UI upsert-merges each patch into a
|
|
405
|
+
* single `councilMeta` object, so any subset of fields may be present.
|
|
406
|
+
*/
|
|
407
|
+
export interface CouncilMetaPatch {
|
|
408
|
+
/** The debate topic / question under discussion (shown at the top of the rail). */
|
|
409
|
+
topic?: string;
|
|
410
|
+
/** Leader model id driving the debate. */
|
|
411
|
+
leader?: string;
|
|
412
|
+
/** Panel member role labels. */
|
|
413
|
+
panel?: string[];
|
|
414
|
+
/** Planned round budget resolved for this debate. */
|
|
415
|
+
roundBudget?: number;
|
|
416
|
+
/** Hard ceiling rounds may extend to (emergent rounds). */
|
|
417
|
+
roundCeiling?: number;
|
|
418
|
+
/** Research mode enabled for this debate. */
|
|
419
|
+
researchMode?: boolean;
|
|
420
|
+
/** Cost-aware budgeting active. */
|
|
421
|
+
costAware?: boolean;
|
|
422
|
+
/**
|
|
423
|
+
* The pinned outcome criteria the debate is graded against (the user-owned
|
|
424
|
+
* `ClarifiedSpec.successCriteria`). Emitted once after clarify so the rail can
|
|
425
|
+
* show the OUTCOME the debate is chasing — fixes "criteria met là gì tôi không
|
|
426
|
+
* biết". Stable for the whole debate.
|
|
427
|
+
*/
|
|
428
|
+
successCriteria?: string[];
|
|
429
|
+
/**
|
|
430
|
+
* Per-criterion met status, index-aligned to `successCriteria`. Upsert-merged
|
|
431
|
+
* and refreshed after each round's leader evaluation so the rail shows live
|
|
432
|
+
* ✓/○ against the pinned criteria. Length matches `successCriteria`.
|
|
433
|
+
*/
|
|
434
|
+
criteriaMet?: boolean[];
|
|
435
|
+
}
|
|
336
436
|
export interface CouncilMessage {
|
|
337
437
|
kind: CouncilMessageKind;
|
|
338
438
|
speaker: {
|
|
@@ -343,6 +443,7 @@ export interface CouncilMessage {
|
|
|
343
443
|
role: string;
|
|
344
444
|
};
|
|
345
445
|
round?: number;
|
|
446
|
+
phase?: "directive" | "verdict";
|
|
346
447
|
text: string;
|
|
347
448
|
toolCalls?: {
|
|
348
449
|
name: string;
|
|
@@ -350,9 +451,19 @@ export interface CouncilMessage {
|
|
|
350
451
|
attempts?: number;
|
|
351
452
|
failureReason?: string;
|
|
352
453
|
runId?: string;
|
|
454
|
+
/**
|
|
455
|
+
* Wall-clock of THIS speaker's LLM call, including retries.
|
|
456
|
+
*
|
|
457
|
+
* Without it the only timed council rows are `debate_complete` (the whole
|
|
458
|
+
* debate, measured at 87s..1128s) and `council_summary` — aggregates that
|
|
459
|
+
* cannot say WHICH model burned the time, so every latency diagnosis is
|
|
460
|
+
* guesswork. Persisted to `interaction_logs.duration_ms` alongside the
|
|
461
|
+
* `speakerModel` this row already carries, making the bottleneck queryable.
|
|
462
|
+
*/
|
|
463
|
+
durationMs?: number;
|
|
353
464
|
}
|
|
354
465
|
export interface StreamChunk {
|
|
355
|
-
type: "content" | "tool_calls" | "tool_result" | "tool_approval_request" | "council_question" | "council_preflight" | "council_status" | "council_phase" | "council_message" | "council_info_card" | "done" | "error" | "reasoning" | "structured_response" | "product_status_card" | "experience_warning" | "experience_injected" | "push_notification" | "halt" | "task_list_update";
|
|
466
|
+
type: "content" | "tool_calls" | "tool_result" | "tool_approval_request" | "council_question" | "council_preflight" | "council_status" | "council_phase" | "council_message" | "council_info_card" | "council_meta" | "council_round" | "done" | "error" | "reasoning" | "structured_response" | "product_status_card" | "experience_warning" | "experience_injected" | "push_notification" | "halt" | "toast" | "task_list_update";
|
|
356
467
|
content?: string;
|
|
357
468
|
toolCalls?: ToolCall[];
|
|
358
469
|
toolCall?: ToolCall;
|
|
@@ -367,12 +478,21 @@ export interface StreamChunk {
|
|
|
367
478
|
councilPhase?: CouncilPhaseEvent;
|
|
368
479
|
councilMessage?: CouncilMessage;
|
|
369
480
|
councilInfoCard?: CouncilInfoCard;
|
|
481
|
+
councilMeta?: CouncilMetaPatch;
|
|
482
|
+
councilRound?: CouncilRoundRecord;
|
|
370
483
|
productStatusCard?: import("../product-loop/types.js").ProductStatusCardData;
|
|
371
484
|
/** Populated when type === "halt". Contains structured recovery options. */
|
|
372
485
|
haltChunk?: import("../product-loop/types.js").HaltChunk;
|
|
373
486
|
experienceWarning?: ExperienceWarningData;
|
|
374
487
|
experienceInjected?: ExperienceInjectedData;
|
|
375
488
|
taskListSnapshot?: TaskListSnapshot;
|
|
489
|
+
/**
|
|
490
|
+
* Populated when type === "toast". A transient, ephemeral notice (e.g.
|
|
491
|
+
* "initializing sub-session…") that the UI shows briefly then auto-dismisses
|
|
492
|
+
* — it is NOT appended to the persisted assistant message. `content` holds
|
|
493
|
+
* the text; `toastLevel` selects the style (defaults to "info").
|
|
494
|
+
*/
|
|
495
|
+
toastLevel?: "info" | "warn" | "error";
|
|
376
496
|
}
|
|
377
497
|
export type TaskListItemStatus = "pending" | "in_progress" | "completed";
|
|
378
498
|
export interface TaskListItem {
|
|
@@ -413,13 +533,28 @@ export interface ModelInfo {
|
|
|
413
533
|
multiAgent?: boolean;
|
|
414
534
|
supportsClientTools?: boolean;
|
|
415
535
|
supportsMaxOutputTokens?: boolean;
|
|
536
|
+
/**
|
|
537
|
+
* When set, the provider rejects any temperature other than this exact value
|
|
538
|
+
* (e.g. Moonshot/Kimi: "only 1 is allowed for this model"). Callers must send
|
|
539
|
+
* this value verbatim rather than their preferred temperature — see
|
|
540
|
+
* `resolveTemperature` in src/providers/capabilities.ts.
|
|
541
|
+
*/
|
|
542
|
+
fixedTemperature?: number;
|
|
416
543
|
defaultReasoningEffort?: ReasoningEffort;
|
|
417
544
|
supportsReasoningEffort?: boolean;
|
|
418
545
|
thinkingType?: "enabled" | "adaptive";
|
|
419
546
|
supportsVision?: boolean;
|
|
547
|
+
/** When false, excluded from getModelByTier / automatic compaction routing. Default: routable. */
|
|
548
|
+
tierRouting?: boolean;
|
|
549
|
+
/** Extra tiers this model may satisfy in getModelByTier (primary tier remains `tier`). */
|
|
550
|
+
routingTiers?: ModelTier[];
|
|
551
|
+
roles?: string[];
|
|
552
|
+
/** Part E — model has native online web research (its own web_search/browsing). */
|
|
553
|
+
nativeWebResearch?: boolean;
|
|
420
554
|
}
|
|
421
555
|
export type AgentMode = "agent" | "plan" | "ask";
|
|
422
556
|
export type SessionStatus = "active" | "completed" | "archived" | "abandoned";
|
|
557
|
+
export type SessionKind = "conversation" | "rotation" | "subagent";
|
|
423
558
|
export type UsageSource = "message" | "title" | "task" | "delegation" | "council" | "other";
|
|
424
559
|
export interface WorkspaceInfo {
|
|
425
560
|
id: string;
|
|
@@ -441,6 +576,14 @@ export interface SessionInfo {
|
|
|
441
576
|
createdAt: Date;
|
|
442
577
|
updatedAt: Date;
|
|
443
578
|
}
|
|
579
|
+
/**
|
|
580
|
+
* One row in the `/sessions` resume picker: a whole conversation tree collapsed
|
|
581
|
+
* to a single entry. `id`/`title`/`createdAt` describe the tree root; `resumeId`
|
|
582
|
+
* is the latest leaf to relaunch; `model`/`updatedAt`/`status` describe that leaf.
|
|
583
|
+
*/
|
|
584
|
+
export interface ResumeEntry extends SessionInfo {
|
|
585
|
+
resumeId: string;
|
|
586
|
+
}
|
|
444
587
|
export interface UsageEvent {
|
|
445
588
|
id: number;
|
|
446
589
|
sessionId: string;
|
package/dist/src/ui/app.js
CHANGED
|
Binary file
|
|
@@ -49,7 +49,7 @@ export function ProductStatusCard({ data, theme: t }) {
|
|
|
49
49
|
const costSpark = data.costHistory?.length
|
|
50
50
|
? sparkline(data.costHistory.map((h) => (data.costCap > 0 ? h.cumulativeUsd / data.costCap : 0)))
|
|
51
51
|
: "";
|
|
52
|
-
return (_jsx(Semantic, { id: "ideal-status", role: "region", name: "Ideal status", children: _jsxs("box", { flexDirection: "column", paddingLeft: 2, paddingTop: 0, flexShrink: 0, children: [_jsx("box", { children: _jsx("text", { fg: t.accent, children: `▶ Product Loop · ${data.currentStage}` }) }), _jsx(Semantic, { id: `ideal-phase-sprint`, role: "listitem", name: "Sprint", children: _jsxs("box", { children: [_jsx("text", { fg: t.textMuted, children: "Sprint: " }), _jsx("text", { fg: t.text, children: `${data.sprintN}/${data.totalSprints} ` }), _jsx("text", { fg: t.accent, children: bar(sprintPct) }), _jsx("text", { fg: t.textDim, children: ` ${sprintPct.toFixed(0)}%` })] }) }), _jsx(Semantic, { id: `ideal-phase-cost`, role: "listitem", name: "Cost", children: _jsxs("box", { children: [_jsx("text", { fg: t.textMuted, children: "Cost: " }), _jsx("text", { fg: t.text, children: `$${data.costSpent.toFixed(2)}/$${data.costCap.toFixed(2)} ` }), _jsx("text", { fg: costColor, children: bar(costPct) }), _jsx("text", { fg: t.textDim, children: ` ${costPct.toFixed(0)}%` })] }) }), costSpark && (_jsxs("box", { children: [_jsx("text", { fg: t.textMuted, children: "Burn: " }), _jsx("text", { fg: costColor, children: costSpark }), _jsx("text", { fg: t.textDim, children: `
|
|
52
|
+
return (_jsx(Semantic, { id: "ideal-status", role: "region", name: "Ideal status", children: _jsxs("box", { flexDirection: "column", paddingLeft: 2, paddingTop: 0, flexShrink: 0, children: [_jsx("box", { children: _jsx("text", { fg: t.accent, children: `▶ Product Loop · ${data.currentStage}` }) }), _jsx(Semantic, { id: `ideal-phase-sprint`, role: "listitem", name: "Sprint", children: _jsxs("box", { children: [_jsx("text", { fg: t.textMuted, children: "Sprint: " }), _jsx("text", { fg: t.text, children: `${data.sprintN}/${data.totalSprints} ` }), _jsx("text", { fg: t.accent, children: bar(sprintPct) }), _jsx("text", { fg: t.textDim, children: ` ${sprintPct.toFixed(0)}%` })] }) }), _jsx(Semantic, { id: `ideal-phase-cost`, role: "listitem", name: "Cost", children: _jsxs("box", { children: [_jsx("text", { fg: t.textMuted, children: "Cost: " }), _jsx("text", { fg: t.text, children: `$${data.costSpent.toFixed(2)}/$${data.costCap.toFixed(2)} ` }), _jsx("text", { fg: costColor, children: bar(costPct) }), _jsx("text", { fg: t.textDim, children: ` ${costPct.toFixed(0)}%` })] }) }), costSpark && (_jsxs("box", { children: [_jsx("text", { fg: t.textMuted, children: "Burn: " }), _jsx("text", { fg: costColor, children: costSpark }), _jsx("text", { fg: t.textDim, children: ` spend per sprint` })] })), _jsx(Semantic, { id: `ideal-phase-criteria`, role: "listitem", name: "Criteria", children: _jsxs("box", { children: [_jsx("text", { fg: t.textMuted, children: "Criteria: " }), _jsx("text", { fg: t.planOptionCheck, children: `✓ ${data.criteriaMet}` }), _jsx("text", { fg: t.text, children: " " }), _jsx("text", { fg: t.accent, children: `◐ ${data.criteriaPartial}` }), _jsx("text", { fg: t.text, children: " " }), _jsx("text", { fg: t.diffRemovedFg, children: `✗ ${data.criteriaUnmet}` }), _jsx("text", { fg: t.textDim, children: ` (of ${totalCriteria})` })] }) }), criteriaSpark && (_jsxs("box", { children: [_jsx("text", { fg: t.textMuted, children: "Trend: " }), _jsx("text", { fg: t.planOptionCheck, children: criteriaSpark }), _jsx("text", { fg: t.textDim, children: ` criteria met per sprint` })] }))] }) }));
|
|
53
53
|
}
|
|
54
54
|
export default ProductStatusCard;
|
|
55
55
|
//# sourceMappingURL=product-status-card.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/components/agent-rail-activities.tsx
|
|
3
|
+
*
|
|
4
|
+
* Rail block listing every sub-agent / background job this session spawned.
|
|
5
|
+
*
|
|
6
|
+
* Before this, a spawned agent was visible only as a transient line in the
|
|
7
|
+
* transcript: it scrolled away, and once done there was nowhere to see WHAT it
|
|
8
|
+
* was asked or what it returned. The rail keeps the roster on screen, and a row
|
|
9
|
+
* opens to show the prompt and the result.
|
|
10
|
+
*
|
|
11
|
+
* Selection is by click (OpenTUI onMouseDown per row, same as
|
|
12
|
+
* council-rail-rounds.tsx) — clicking the open row closes it again.
|
|
13
|
+
*/
|
|
14
|
+
import type { AgentActivity } from "../utils/agent-activities.js";
|
|
15
|
+
import type { Theme } from "../theme.js";
|
|
16
|
+
/** Row prefix naming what was spawned: the agent type, or "shell" for a job. */
|
|
17
|
+
export declare function activityPrefix(a: AgentActivity): string;
|
|
18
|
+
export interface AgentRailActivitiesProps {
|
|
19
|
+
activities: AgentActivity[];
|
|
20
|
+
/** Tool-call id of the open row, or null when all are collapsed. */
|
|
21
|
+
selected: string | null;
|
|
22
|
+
onSelect: (id: string | null) => void;
|
|
23
|
+
width: number;
|
|
24
|
+
t: Theme;
|
|
25
|
+
}
|
|
26
|
+
export declare function AgentRailActivities({ activities, selected, onSelect, width, t }: AgentRailActivitiesProps): import("react").ReactNode;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* src/ui/components/agent-rail-activities.tsx
|
|
4
|
+
*
|
|
5
|
+
* Rail block listing every sub-agent / background job this session spawned.
|
|
6
|
+
*
|
|
7
|
+
* Before this, a spawned agent was visible only as a transient line in the
|
|
8
|
+
* transcript: it scrolled away, and once done there was nowhere to see WHAT it
|
|
9
|
+
* was asked or what it returned. The rail keeps the roster on screen, and a row
|
|
10
|
+
* opens to show the prompt and the result.
|
|
11
|
+
*
|
|
12
|
+
* Selection is by click (OpenTUI onMouseDown per row, same as
|
|
13
|
+
* council-rail-rounds.tsx) — clicking the open row closes it again.
|
|
14
|
+
*/
|
|
15
|
+
import { ListItem, Region } from "../primitives/semantic-primitives.js";
|
|
16
|
+
import { trunc } from "../utils/text.js";
|
|
17
|
+
/** Characters of detail shown when a row is open. Keeps the rail scrollable. */
|
|
18
|
+
const DETAIL_LIMIT = 600;
|
|
19
|
+
const GLYPH = { running: "▸", done: "✓", failed: "✗" };
|
|
20
|
+
function statusColor(status, t) {
|
|
21
|
+
if (status === "failed")
|
|
22
|
+
return t.diffRemovedFg;
|
|
23
|
+
if (status === "done")
|
|
24
|
+
return t.diffAddedFg;
|
|
25
|
+
return t.accent;
|
|
26
|
+
}
|
|
27
|
+
/** Row prefix naming what was spawned: the agent type, or "shell" for a job. */
|
|
28
|
+
export function activityPrefix(a) {
|
|
29
|
+
if (a.kind === "background")
|
|
30
|
+
return "shell";
|
|
31
|
+
return a.agent || (a.kind === "delegate" ? "delegate" : "sub-agent");
|
|
32
|
+
}
|
|
33
|
+
export function AgentRailActivities({ activities, selected, onSelect, width, t }) {
|
|
34
|
+
if (activities.length === 0)
|
|
35
|
+
return null;
|
|
36
|
+
const running = activities.filter((a) => a.status === "running").length;
|
|
37
|
+
return (_jsx(Region, { id: "agent-rail-activities", name: "Agents", value: `${activities.length}`, props: {
|
|
38
|
+
count: activities.length,
|
|
39
|
+
running,
|
|
40
|
+
selected: selected ?? "",
|
|
41
|
+
ids: activities.map((a) => a.id).join(","),
|
|
42
|
+
}, children: _jsxs("box", { flexDirection: "column", flexShrink: 0, children: [_jsx("text", { fg: t.textMuted, attributes: 1, children: running > 0 ? `Agents (${running} running)` : "Agents" }), activities.map((a) => {
|
|
43
|
+
const isOpen = selected === a.id;
|
|
44
|
+
return (_jsx(ListItem, { id: `rail-agent-${a.id}`, name: `${activityPrefix(a)} ${a.label}`, state: a.status, selected: isOpen || undefined, children: _jsxs("box", { flexDirection: "column", flexShrink: 0, children: [_jsx("box", { flexDirection: "row", onMouseDown: () => onSelect(isOpen ? null : a.id), children: _jsxs("text", { children: [_jsx("span", { style: { fg: statusColor(a.status, t) }, children: `${GLYPH[a.status]} ` }), _jsx("span", { style: { fg: t.textMuted }, children: `${activityPrefix(a)} ` }), _jsx("span", { style: { fg: t.text }, children: trunc(a.label, Math.max(8, width - 12)) })] }) }), isOpen && (_jsx("box", { paddingLeft: 2, flexDirection: "column", children: _jsx("text", { fg: t.textDim, children: a.detail.trim() ? trunc(a.detail, DETAIL_LIMIT) : "(no output yet)" }) }))] }) }, a.id));
|
|
45
|
+
})] }) }));
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=agent-rail-activities.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render-time guard for council message bodies.
|
|
3
|
+
*
|
|
4
|
+
* Root cause it defends against (live-diagnosed 2026-07-08, run mrbj8v6w81a3):
|
|
5
|
+
* a single round-1 debate turn whose body contained a very long whitespace-free
|
|
6
|
+
* run (an import graph / path list / blob a Flash-tier model dumped over a
|
|
7
|
+
* 1286-file repo). `CouncilMessageBubble` hands the raw body to a single
|
|
8
|
+
* OpenTUI `<text>` node with NO length or line-length bound. OpenTUI's word-wrap
|
|
9
|
+
* on such a mega-line pegs the main thread at 100% CPU — and because render and
|
|
10
|
+
* the product-loop share one JS thread, the entire `/ideal` run hard-freezes
|
|
11
|
+
* (render + input + debate logic all starve). Every muonroi-owned text function
|
|
12
|
+
* on the path (`truncateCodeBlocks`, `renderMarkdown`, `parseInline`,
|
|
13
|
+
* `tokenize`) was benchmarked fast on 80–130KB adversarial input, so the block
|
|
14
|
+
* lives in the terminal's layout of an unbounded body.
|
|
15
|
+
*
|
|
16
|
+
* This function bounds BOTH failure axes before the body reaches `<text>`:
|
|
17
|
+
* 1. total length — cap at `maxChars`, append a muted pointer to /export.
|
|
18
|
+
* 2. line length — hard-break any whitespace-free run longer than the
|
|
19
|
+
* terminal width so the wrapper always has a break opportunity (turns a
|
|
20
|
+
* pathological O(n²) single-line wrap into linear per-segment wrapping).
|
|
21
|
+
*
|
|
22
|
+
* Pure + side-effect free — safe to unit-test without a terminal.
|
|
23
|
+
*/
|
|
24
|
+
/** Default ceiling on a rendered bubble body. Well above any real prose turn
|
|
25
|
+
* (~2–4KB) but far below the 100KB+ blobs that trigger the layout hang. */
|
|
26
|
+
export declare const MAX_BUBBLE_BODY_CHARS = 12000;
|
|
27
|
+
export declare function capBubbleBody(text: string, terminalCols: number, maxChars?: number): string;
|