muonroi-cli 1.8.3 → 1.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +133 -122
- package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
- package/dist/packages/agent-harness-core/src/driver.js +46 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +48 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +77 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +11 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +87 -15
- package/dist/packages/agent-harness-core/src/protocol.d.ts +66 -2
- package/dist/packages/agent-harness-core/src/protocol.js +15 -0
- package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
- package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
- package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
- package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
- package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
- package/dist/packages/agent-harness-opentui/src/install.js +10 -0
- package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
- package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
- package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
- package/dist/src/agent-harness/mock-model.d.ts +28 -0
- package/dist/src/agent-harness/mock-model.js +63 -1
- package/dist/src/agent-harness/test-spawn.js +31 -0
- package/dist/src/cli/config/screen-providers.js +1 -1
- package/dist/src/cli/cost-forensics.d.ts +10 -0
- package/dist/src/cli/cost-forensics.js +30 -15
- package/dist/src/cli/keys-bundle.d.ts +1 -1
- package/dist/src/cli/keys-bundle.js +1 -1
- package/dist/src/cli/keys.d.ts +2 -2
- package/dist/src/cli/keys.js +19 -81
- package/dist/src/council/clarifier.d.ts +28 -2
- package/dist/src/council/clarifier.js +81 -15
- package/dist/src/council/context.js +49 -15
- package/dist/src/council/debate-checkpoint.d.ts +129 -0
- package/dist/src/council/debate-checkpoint.js +176 -0
- package/dist/src/council/debate-planner.js +51 -3
- package/dist/src/council/debate-summary.d.ts +25 -0
- package/dist/src/council/debate-summary.js +85 -0
- package/dist/src/council/debate.d.ts +169 -2
- package/dist/src/council/debate.js +1210 -134
- package/dist/src/council/index.d.ts +85 -1
- package/dist/src/council/index.js +634 -196
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +32 -0
- package/dist/src/council/llm.js +231 -38
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +72 -0
- package/dist/src/council/planner.js +23 -0
- package/dist/src/council/preflight.d.ts +7 -0
- package/dist/src/council/preflight.js +14 -2
- package/dist/src/council/prompts.d.ts +30 -3
- package/dist/src/council/prompts.js +254 -84
- package/dist/src/council/stance-recall.d.ts +42 -0
- package/dist/src/council/stance-recall.js +57 -0
- package/dist/src/council/strip-think.d.ts +17 -0
- package/dist/src/council/strip-think.js +33 -0
- package/dist/src/council/types.d.ts +128 -0
- package/dist/src/ee/artifact-cache.d.ts +16 -0
- package/dist/src/ee/artifact-cache.js +32 -0
- package/dist/src/ee/auth.d.ts +1 -0
- package/dist/src/ee/auth.js +15 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +81 -18
- package/dist/src/ee/export-transcripts.d.ts +1 -0
- package/dist/src/ee/export-transcripts.js +8 -10
- package/dist/src/ee/extract-session.js +29 -0
- package/dist/src/ee/extract-style.d.ts +58 -0
- package/dist/src/ee/extract-style.js +270 -0
- package/dist/src/ee/recall-ledger.d.ts +9 -0
- package/dist/src/ee/recall-ledger.js +3 -0
- package/dist/src/ee/scope.d.ts +1 -0
- package/dist/src/ee/scope.js +26 -1
- package/dist/src/ee/search.d.ts +7 -0
- package/dist/src/ee/search.js +24 -0
- package/dist/src/ee/transcript-emit.js +2 -0
- package/dist/src/ee/types.d.ts +22 -0
- package/dist/src/ee/who-am-i-brain.d.ts +35 -0
- package/dist/src/ee/who-am-i-brain.js +220 -0
- package/dist/src/ee/who-am-i.d.ts +10 -3
- package/dist/src/ee/who-am-i.js +12 -0
- package/dist/src/ee/workflow-event.d.ts +48 -0
- package/dist/src/ee/workflow-event.js +81 -0
- package/dist/src/flow/compaction/compress.d.ts +3 -3
- package/dist/src/flow/compaction/compress.js +45 -8
- package/dist/src/flow/compaction/extract.d.ts +4 -7
- package/dist/src/flow/compaction/extract.js +50 -10
- package/dist/src/flow/compaction/index.d.ts +13 -1
- package/dist/src/flow/compaction/index.js +70 -3
- package/dist/src/flow/compaction/input-guard.d.ts +24 -0
- package/dist/src/flow/compaction/input-guard.js +43 -0
- package/dist/src/flow/fold-planning.d.ts +36 -0
- package/dist/src/flow/fold-planning.js +83 -0
- package/dist/src/flow/hierarchy.d.ts +146 -0
- package/dist/src/flow/hierarchy.js +427 -0
- package/dist/src/flow/index.d.ts +1 -0
- package/dist/src/flow/index.js +2 -0
- package/dist/src/flow/run-artifacts.d.ts +102 -0
- package/dist/src/flow/run-artifacts.js +208 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/assessment-schema.d.ts +44 -0
- package/dist/src/gsd/assessment-schema.js +134 -0
- package/dist/src/gsd/capability-registry.d.ts +45 -0
- package/dist/src/gsd/capability-registry.js +337 -0
- package/dist/src/gsd/complexity-assessor.d.ts +39 -0
- package/dist/src/gsd/complexity-assessor.js +152 -0
- package/dist/src/gsd/config-bridge.d.ts +7 -0
- package/dist/src/gsd/config-bridge.js +114 -0
- package/dist/src/gsd/config-loader.d.ts +27 -0
- package/dist/src/gsd/config-loader.js +50 -0
- package/dist/src/gsd/council-context.d.ts +44 -0
- package/dist/src/gsd/council-context.js +114 -0
- package/dist/src/gsd/ee-closure.d.ts +28 -0
- package/dist/src/gsd/ee-closure.js +49 -0
- package/dist/src/gsd/flags.d.ts +55 -0
- package/dist/src/gsd/flags.js +83 -0
- package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
- package/dist/src/gsd/gsd-dispatch.js +131 -0
- package/dist/src/gsd/gsd-runtime.d.ts +22 -0
- package/dist/src/gsd/gsd-runtime.js +37 -0
- package/dist/src/gsd/host-adapter.d.ts +11 -0
- package/dist/src/gsd/host-adapter.js +29 -0
- package/dist/src/gsd/index.d.ts +24 -1
- package/dist/src/gsd/index.js +27 -0
- package/dist/src/gsd/loop-host-contract.d.ts +21 -0
- package/dist/src/gsd/loop-host-contract.js +39 -0
- package/dist/src/gsd/loop-host.d.ts +69 -0
- package/dist/src/gsd/loop-host.js +245 -0
- package/dist/src/gsd/loop-resolver.d.ts +36 -0
- package/dist/src/gsd/loop-resolver.js +79 -0
- package/dist/src/gsd/model-tier.d.ts +13 -0
- package/dist/src/gsd/model-tier.js +45 -0
- package/dist/src/gsd/mutation-gate.d.ts +16 -0
- package/dist/src/gsd/mutation-gate.js +41 -0
- package/dist/src/gsd/native-roadmap.d.ts +89 -0
- package/dist/src/gsd/native-roadmap.js +343 -0
- package/dist/src/gsd/native-state.d.ts +47 -0
- package/dist/src/gsd/native-state.js +220 -0
- package/dist/src/gsd/paths.d.ts +23 -0
- package/dist/src/gsd/paths.js +66 -0
- package/dist/src/gsd/phase-dag.d.ts +12 -0
- package/dist/src/gsd/phase-dag.js +94 -0
- package/dist/src/gsd/phase-sync.d.ts +42 -0
- package/dist/src/gsd/phase-sync.js +321 -0
- package/dist/src/gsd/pil-gate-context.d.ts +13 -0
- package/dist/src/gsd/pil-gate-context.js +64 -0
- package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
- package/dist/src/gsd/pil-gate-critic.js +74 -0
- package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
- package/dist/src/gsd/plan-council-prompts.js +79 -0
- package/dist/src/gsd/plan-council.d.ts +44 -0
- package/dist/src/gsd/plan-council.js +251 -0
- package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
- package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
- package/dist/src/gsd/product-workspace.d.ts +13 -0
- package/dist/src/gsd/product-workspace.js +124 -0
- package/dist/src/gsd/ship-bridge.d.ts +25 -0
- package/dist/src/gsd/ship-bridge.js +65 -0
- package/dist/src/gsd/state-document.d.ts +40 -0
- package/dist/src/gsd/state-document.js +163 -0
- package/dist/src/gsd/verdict-schema.d.ts +39 -0
- package/dist/src/gsd/verdict-schema.js +144 -0
- package/dist/src/gsd/verify-context.d.ts +22 -0
- package/dist/src/gsd/verify-context.js +27 -0
- package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
- package/dist/src/gsd/verify-council-prompts.js +85 -0
- package/dist/src/gsd/verify-council.d.ts +25 -0
- package/dist/src/gsd/verify-council.js +119 -0
- package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
- package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
- package/dist/src/gsd/workflow-engine.d.ts +60 -0
- package/dist/src/gsd/workflow-engine.js +207 -0
- package/dist/src/gsd/workflow-tools.d.ts +13 -0
- package/dist/src/gsd/workflow-tools.js +277 -0
- package/dist/src/hooks/index.js +1 -1
- package/dist/src/index.js +44 -11
- package/dist/src/maintain/pr-builder.js +23 -13
- package/dist/src/mcp/auto-setup.js +57 -32
- package/dist/src/mcp/client-pool.js +1 -1
- package/dist/src/mcp/ee-tools.js +1 -0
- package/dist/src/mcp/oauth-callback.js +2 -2
- package/dist/src/mcp/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -2
- package/dist/src/mcp/setup-guide-text.d.ts +1 -1
- package/dist/src/mcp/setup-guide-text.js +77 -76
- package/dist/src/models/catalog-client.d.ts +87 -0
- package/dist/src/models/catalog-client.js +105 -38
- package/dist/src/models/catalog.json +528 -265
- package/dist/src/models/registry.d.ts +22 -7
- package/dist/src/models/registry.js +73 -10
- package/dist/src/ops/doctor.js +8 -8
- package/dist/src/orchestrator/auto-commit.js +1 -1
- package/dist/src/orchestrator/batch-turn-runner.js +2 -2
- package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
- package/dist/src/orchestrator/cache-prefix.js +83 -0
- package/dist/src/orchestrator/compact-request.d.ts +32 -0
- package/dist/src/orchestrator/compact-request.js +41 -0
- package/dist/src/orchestrator/compaction.d.ts +10 -0
- package/dist/src/orchestrator/compaction.js +27 -7
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +65 -24
- package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
- package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
- package/dist/src/orchestrator/error-utils.d.ts +29 -0
- package/dist/src/orchestrator/error-utils.js +132 -24
- package/dist/src/orchestrator/grounding-check.js +39 -1
- package/dist/src/orchestrator/message-processor.js +242 -33
- package/dist/src/orchestrator/orchestrator.d.ts +39 -3
- package/dist/src/orchestrator/orchestrator.js +651 -102
- package/dist/src/orchestrator/preprocessor.js +1 -1
- package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
- package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
- package/dist/src/orchestrator/prompts.js +159 -159
- package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
- package/dist/src/orchestrator/reactive-delegation.js +59 -0
- package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
- package/dist/src/orchestrator/retry-classifier.js +46 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +45 -0
- package/dist/src/orchestrator/safety-intercept.js +55 -0
- package/dist/src/orchestrator/scope-reminder.js +1 -1
- package/dist/src/orchestrator/session-experience.d.ts +2 -1
- package/dist/src/orchestrator/session-experience.js +2 -1
- package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
- package/dist/src/orchestrator/should-run-gate.js +18 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +24 -3
- package/dist/src/orchestrator/stall-watchdog.js +47 -13
- package/dist/src/orchestrator/stream-runner.js +62 -29
- package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-cap.js +16 -1
- package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
- package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
- package/dist/src/orchestrator/subagent-compactor.js +126 -15
- package/dist/src/orchestrator/tool-engine.d.ts +26 -0
- package/dist/src/orchestrator/tool-engine.js +669 -56
- package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
- package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
- package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
- package/dist/src/orchestrator/turn-watchdog.d.ts +37 -0
- package/dist/src/orchestrator/turn-watchdog.js +55 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +1 -1
- package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
- package/dist/src/pil/cheap-model-playbook.js +5 -1
- package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
- package/dist/src/pil/cheap-model-workbooks.js +1 -1
- package/dist/src/pil/discovery-types.d.ts +1 -0
- package/dist/src/pil/discovery.js +16 -11
- package/dist/src/pil/layer1-intent.d.ts +18 -6
- package/dist/src/pil/layer1-intent.js +66 -757
- package/dist/src/pil/layer15-context-scan.js +15 -1
- package/dist/src/pil/layer2_5-ponytail.js +8 -8
- package/dist/src/pil/layer3-ee-injection.js +23 -8
- package/dist/src/pil/layer4-gsd.js +69 -16
- package/dist/src/pil/layer5-context.js +7 -3
- package/dist/src/pil/layer6-output.d.ts +23 -0
- package/dist/src/pil/layer6-output.js +5 -1
- package/dist/src/pil/llm-classify.d.ts +33 -2
- package/dist/src/pil/llm-classify.js +123 -131
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +1 -0
- package/dist/src/pil/pipeline.js +34 -2
- package/dist/src/pil/response-tools.js +5 -3
- package/dist/src/pil/schema.d.ts +1 -0
- package/dist/src/pil/schema.js +2 -0
- package/dist/src/pil/types.d.ts +18 -0
- package/dist/src/playbook/directives.d.ts +4 -0
- package/dist/src/playbook/directives.js +17 -5
- package/dist/src/product-loop/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- package/dist/src/product-loop/discovery-context-format.js +3 -1
- package/dist/src/product-loop/discovery-ecosystem.js +4 -1
- package/dist/src/product-loop/discovery-interview.js +32 -3
- package/dist/src/product-loop/discovery-schema.js +5 -1
- package/dist/src/product-loop/done-gate.js +3 -3
- package/dist/src/product-loop/ideal-trace.d.ts +7 -0
- package/dist/src/product-loop/ideal-trace.js +64 -0
- package/dist/src/product-loop/index.d.ts +13 -1
- package/dist/src/product-loop/index.js +333 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +327 -116
- package/dist/src/product-loop/phase-plan.d.ts +5 -0
- package/dist/src/product-loop/phase-plan.js +39 -2
- package/dist/src/product-loop/phase-runner.js +9 -1
- package/dist/src/product-loop/progress-snapshot.js +4 -4
- package/dist/src/product-loop/sprint-runner.d.ts +111 -0
- package/dist/src/product-loop/sprint-runner.js +559 -16
- package/dist/src/product-loop/types.d.ts +36 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- package/dist/src/providers/auth/browser-flow.d.ts +1 -1
- package/dist/src/providers/auth/browser-flow.js +1 -1
- package/dist/src/providers/auth/openai-oauth.js +1 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.js +4 -1
- package/dist/src/providers/auth/types.d.ts +1 -1
- package/dist/src/providers/auth/types.js +1 -1
- package/dist/src/providers/capabilities.d.ts +24 -5
- package/dist/src/providers/capabilities.js +42 -24
- package/dist/src/providers/endpoints.d.ts +2 -2
- package/dist/src/providers/endpoints.js +11 -10
- package/dist/src/providers/keychain.d.ts +1 -1
- package/dist/src/providers/keychain.js +7 -9
- package/dist/src/providers/mcp-vision-bridge.js +82 -172
- package/dist/src/providers/openai-compatible.js +8 -1
- package/dist/src/providers/pricing.d.ts +2 -2
- package/dist/src/providers/pricing.js +3 -13
- package/dist/src/providers/runtime.d.ts +27 -2
- package/dist/src/providers/runtime.js +78 -15
- package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
- package/dist/src/providers/strategies/base.strategy.js +24 -1
- package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
- package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
- package/dist/src/providers/strategies/registry.js +4 -4
- package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
- package/dist/src/providers/strategies/thinking-mode.js +280 -1
- package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
- package/dist/src/providers/strategies/zai.strategy.js +44 -0
- package/dist/src/providers/types.d.ts +5 -6
- package/dist/src/providers/types.js +2 -2
- package/dist/src/providers/vision-backend.d.ts +47 -0
- package/dist/src/providers/vision-backend.js +258 -0
- package/dist/src/providers/vision-proxy.d.ts +22 -9
- package/dist/src/providers/vision-proxy.js +63 -132
- package/dist/src/providers/wire-debug.js +95 -0
- package/dist/src/reporter/index.js +1 -1
- package/dist/src/router/decide.d.ts +13 -0
- package/dist/src/router/decide.js +138 -36
- package/dist/src/router/peak-hour.d.ts +38 -0
- package/dist/src/router/peak-hour.js +107 -0
- package/dist/src/router/step-router.js +3 -2
- package/dist/src/router/warm.js +4 -5
- package/dist/src/scaffold/bb-ecosystem-apply.js +47 -47
- package/dist/src/scaffold/bb-quality-gate.js +5 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +86 -60
- package/dist/src/scaffold/init-new.js +453 -453
- package/dist/src/scaffold/point-to-existing.d.ts +21 -0
- package/dist/src/scaffold/point-to-existing.js +25 -0
- package/dist/src/self-qa/agentic-loop.js +22 -22
- package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
- package/dist/src/{ui/state → state}/active-run.js +21 -0
- package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
- package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
- package/dist/src/state/turn-trace.d.ts +43 -0
- package/dist/src/state/turn-trace.js +32 -0
- package/dist/src/storage/db.js +2 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/interaction-log.d.ts +1 -1
- package/dist/src/storage/interaction-log.js +5 -5
- package/dist/src/storage/migrations.js +196 -126
- package/dist/src/storage/session-experience-store.js +4 -4
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +112 -55
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +383 -112
- package/dist/src/storage/usage.js +14 -14
- package/dist/src/storage/workspaces.js +12 -12
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/native-tools.js +5 -0
- package/dist/src/tools/registry.d.ts +3 -0
- package/dist/src/tools/registry.js +460 -22
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +118 -3
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
- package/dist/src/ui/components/bubble-body-guard.js +50 -0
- package/dist/src/ui/components/context-rail.d.ts +26 -0
- package/dist/src/ui/components/context-rail.js +33 -0
- package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
- package/dist/src/ui/components/council-conclusion-card.js +420 -0
- package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
- package/dist/src/ui/components/council-debate-pill.js +34 -0
- package/dist/src/ui/components/council-info-card.js +2 -2
- package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
- package/dist/src/ui/components/council-leader-bubble.js +21 -11
- package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
- package/dist/src/ui/components/council-message-bubble.js +16 -15
- package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
- package/dist/src/ui/components/council-phase-timeline.js +49 -15
- package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
- package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
- package/dist/src/ui/components/council-question-card.js +12 -12
- package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
- package/dist/src/ui/components/council-rail-rounds.js +57 -0
- package/dist/src/ui/components/council-round-group.d.ts +38 -0
- package/dist/src/ui/components/council-round-group.js +88 -0
- package/dist/src/ui/components/council-status-list.d.ts +3 -1
- package/dist/src/ui/components/council-status-list.js +36 -24
- package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
- package/dist/src/ui/components/council-synthesis-banner.js +20 -5
- package/dist/src/ui/components/halt-recovery-card.js +9 -5
- package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
- package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
- package/dist/src/ui/components/prompt-box.js +18 -16
- package/dist/src/ui/components/session-tree-card.d.ts +14 -0
- package/dist/src/ui/components/session-tree-card.js +46 -0
- package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
- package/dist/src/ui/components/slash-inline-menu.js +26 -5
- package/dist/src/ui/components/task-list-panel.d.ts +14 -1
- package/dist/src/ui/components/task-list-panel.js +22 -2
- package/dist/src/ui/containers/modals-layer.d.ts +2 -1
- package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
- package/dist/src/ui/mcp-modal.js +2 -4
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/connect-modal.js +4 -3
- package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
- package/dist/src/ui/modals/session-picker-modal.js +3 -5
- package/dist/src/ui/picker-providers.d.ts +1 -1
- package/dist/src/ui/picker-providers.js +1 -1
- package/dist/src/ui/primitives/index.d.ts +1 -0
- package/dist/src/ui/primitives/index.js +2 -0
- package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
- package/dist/src/ui/primitives/semantic-primitives.js +81 -0
- package/dist/src/ui/slash/compact.js +5 -7
- package/dist/src/ui/slash/cost.js +1 -1
- package/dist/src/ui/slash/council-inspect.js +4 -4
- package/dist/src/ui/slash/council.js +19 -1
- package/dist/src/ui/slash/debug.d.ts +3 -31
- package/dist/src/ui/slash/debug.js +9 -20
- package/dist/src/ui/slash/ideal.d.ts +6 -2
- package/dist/src/ui/slash/ideal.js +97 -7
- package/dist/src/ui/slash/menu-items.d.ts +7 -0
- package/dist/src/ui/slash/menu-items.js +12 -18
- package/dist/src/ui/slash/registry.d.ts +2 -0
- package/dist/src/ui/slash/registry.js +4 -0
- package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
- package/dist/src/ui/status-bar/cache-hit.js +9 -0
- package/dist/src/ui/status-bar/index.d.ts +1 -1
- package/dist/src/ui/status-bar/index.js +7 -3
- package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
- package/dist/src/ui/status-bar/usd-meter.js +6 -4
- package/dist/src/ui/theme.d.ts +1 -0
- package/dist/src/ui/theme.js +2 -0
- package/dist/src/ui/types.d.ts +7 -0
- package/dist/src/ui/use-app-logic.js +0 -0
- package/dist/src/ui/utils/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/clipboard-image.js +23 -23
- package/dist/src/utils/install-manager.js +14 -11
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +153 -5
- package/dist/src/utils/settings.js +233 -29
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/utils/skills.js +3 -3
- package/dist/src/utils/visible-retry.d.ts +11 -0
- package/dist/src/utils/visible-retry.js +10 -1
- package/dist/src/verify/entrypoint.d.ts +1 -1
- package/dist/src/verify/entrypoint.js +1 -1
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +135 -132
- package/dist/src/providers/auth/gcloud.d.ts +0 -28
- package/dist/src/providers/auth/gcloud.js +0 -102
- package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
- package/dist/src/providers/auth/gemini-oauth.js +0 -472
- package/dist/src/providers/gemini.d.ts +0 -11
- package/dist/src/providers/gemini.js +0 -45
- package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
- package/dist/src/providers/siliconflow-sse-repair.js +0 -177
- package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
- package/dist/src/providers/strategies/google.strategy.js +0 -174
- package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
- package/dist/src/ui/containers/chat-feed.d.ts +0 -40
- package/dist/src/ui/containers/chat-feed.js +0 -66
|
@@ -6,15 +6,19 @@
|
|
|
6
6
|
* is sent to the API for all providers (including DeepSeek, Gemini, etc.).
|
|
7
7
|
*/
|
|
8
8
|
import { dynamicTool, jsonSchema } from "ai";
|
|
9
|
+
import { registerGsdWorkflowTools } from "../gsd/workflow-tools.js";
|
|
10
|
+
import { requestProactiveCompact } from "../orchestrator/compact-request.js";
|
|
9
11
|
import { canonicalizeBashCommand } from "../orchestrator/tool-args-hash.js";
|
|
10
12
|
import { analyzeImageFromSource, askVisionProxy, listCachedImages } from "../providers/mcp-vision-bridge.js";
|
|
11
13
|
import { needsVisionProxy } from "../providers/vision-proxy.js";
|
|
14
|
+
import { loadMcpServers } from "../utils/settings.js";
|
|
12
15
|
import { getBashRun, sliceBashOutput } from "./bash-output-cache.js";
|
|
13
|
-
import { editFile, readFile, writeFile } from "./file.js";
|
|
16
|
+
import { editFile, readFile, readFiles, writeFile } from "./file.js";
|
|
14
17
|
import { FileTracker } from "./file-tracker.js";
|
|
15
18
|
import { analyzeGitCommand, checkPushGate, checkSensitiveStaging, commitBlockedMessage, pushBlockedMessage, recordCommandOutcome, } from "./git-safety.js";
|
|
16
19
|
import { executeGrep } from "./grep.js";
|
|
17
20
|
import { registerNativeMuonroiTools } from "./native-tools.js";
|
|
21
|
+
import { registerNativeResearchTools } from "./research.js";
|
|
18
22
|
import { VISION_TOOL_NAMES } from "./vision-gate.js";
|
|
19
23
|
function getSafetyApprovedMap() {
|
|
20
24
|
if (!globalThis.__muonroiSafetyApproved) {
|
|
@@ -84,20 +88,38 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
84
88
|
// One tracker per tool registry instance — shared across read/write/edit
|
|
85
89
|
// calls in the same session. Enforces "must read before edit/overwrite".
|
|
86
90
|
const fileTracker = new FileTracker();
|
|
91
|
+
// Native research tools (fetch_url, web_search) — always available.
|
|
92
|
+
// These are the in-process replacements for the old external MCP research servers.
|
|
93
|
+
registerNativeResearchTools(tools);
|
|
87
94
|
// read_file
|
|
88
95
|
tools.read_file = dynamicTool({
|
|
89
|
-
description: "Read file contents.
|
|
96
|
+
description: "Read file contents. To read SEVERAL files, pass them ALL in one call via file_paths (array) — STRONGLY PREFERRED over issuing separate read_file calls: each extra call re-sends the whole conversation as input, so N single reads cost O(N²) tokens while one batched read costs O(N). For a large SINGLE file, use start_line/end_line to extract only the needed section (start_line/end_line apply to file_path only; file_paths reads whole files). Use grep or lsp first to find line numbers.",
|
|
90
97
|
inputSchema: jsonSchema({
|
|
91
98
|
type: "object",
|
|
92
99
|
properties: {
|
|
93
|
-
file_path: { type: "string", description: "Path to
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
file_path: { type: "string", description: "Path to a single file to read (supports start_line/end_line)." },
|
|
101
|
+
file_paths: {
|
|
102
|
+
type: "array",
|
|
103
|
+
items: { type: "string" },
|
|
104
|
+
description: "Read MULTIPLE files in ONE call (preferred when you need 2+ files). Each is returned with its own header; each is capped independently so none is dropped. Best for small-to-medium files; for a large file use file_path + line range.",
|
|
105
|
+
},
|
|
106
|
+
start_line: { type: "number", description: "First line to read (1-based). Applies to file_path only." },
|
|
107
|
+
end_line: { type: "number", description: "Last line to read (1-based). Applies to file_path only." },
|
|
96
108
|
},
|
|
97
|
-
required: ["file_path"],
|
|
98
109
|
}),
|
|
99
110
|
execute: async (input) => {
|
|
100
|
-
const
|
|
111
|
+
const batch = Array.isArray(input.file_paths) && input.file_paths.length > 0
|
|
112
|
+
? input.file_paths.filter((p) => typeof p === "string" && p.trim() !== "")
|
|
113
|
+
: [];
|
|
114
|
+
if (batch.length > 1) {
|
|
115
|
+
// Per-file fair-share of the output cap so the concatenated result
|
|
116
|
+
// stays under MAX_TOOL_OUTPUT_CHARS and every file survives (no silent
|
|
117
|
+
// head/tail drop of whole files). Floor keeps each file legible.
|
|
118
|
+
const perFileCap = Math.max(4_000, Math.floor(MAX_TOOL_OUTPUT_CHARS / batch.length));
|
|
119
|
+
return formatResult(readFiles(batch, bash.getCwd(), fileTracker, perFileCap));
|
|
120
|
+
}
|
|
121
|
+
const single = batch.length === 1 ? batch[0] : input.file_path;
|
|
122
|
+
const result = readFile(single, bash.getCwd(), input.start_line, input.end_line, fileTracker);
|
|
101
123
|
return formatResult(result);
|
|
102
124
|
},
|
|
103
125
|
});
|
|
@@ -118,6 +140,34 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
118
140
|
return formatResult(result);
|
|
119
141
|
},
|
|
120
142
|
});
|
|
143
|
+
// compact — agent-initiated proactive context compaction. The model calls
|
|
144
|
+
// this to shed accumulated tool/conversation history mid-task (freeing
|
|
145
|
+
// context + resetting tool-call bloat) BEFORE it hits a tool-round limit,
|
|
146
|
+
// so a long task never gets interrupted. The request is queued here and
|
|
147
|
+
// consumed by the tool-engine's prepareStep boundary, which forces a
|
|
148
|
+
// compaction pass before the next LLM step, then the turn continues. A
|
|
149
|
+
// decisions/facts snapshot is preserved and high-value tool results stay
|
|
150
|
+
// rehydratable via ee_query "tool-artifact id=…". This is the proactive
|
|
151
|
+
// counterpart to the reactive tool-limit auto-recover.
|
|
152
|
+
tools.compact = dynamicTool({
|
|
153
|
+
description: "Proactively compress THIS turn's accumulated tool/conversation history to free context and reset tool-call bloat, then CONTINUE the task automatically. Call it after a read-heavy stretch (many read_file/grep/bash results) when context feels heavy and BEFORE you approach a tool-round limit — it prevents the 'reached tool limit' interruption entirely. The compaction runs before your next step; older tool results are summarized (a decisions/facts snapshot is kept) and remain rehydratable via ee_query \"tool-artifact id=…\". Do NOT stop after calling it — keep working toward the goal.",
|
|
154
|
+
inputSchema: jsonSchema({
|
|
155
|
+
type: "object",
|
|
156
|
+
properties: {
|
|
157
|
+
focus: {
|
|
158
|
+
type: "string",
|
|
159
|
+
description: "Short note on what to keep in mind / preserve after compaction (e.g. the current sub-task).",
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
}),
|
|
163
|
+
execute: async (input) => {
|
|
164
|
+
requestProactiveCompact(typeof input?.focus === "string" ? input.focus : null);
|
|
165
|
+
return formatResult({
|
|
166
|
+
success: true,
|
|
167
|
+
output: 'Context compaction scheduled — older tool history will be compressed before your next step; continue the task afterward. High-value results stay rehydratable via ee_query "tool-artifact id=…".',
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
});
|
|
121
171
|
// bash — every foreground call goes through here. We track the LAST
|
|
122
172
|
// canonical command + runId in SESSION-SCOPED state so we can inject a
|
|
123
173
|
// reminder when the model issues another bash call that canonicalizes to
|
|
@@ -253,7 +303,20 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
253
303
|
}
|
|
254
304
|
}
|
|
255
305
|
}
|
|
256
|
-
|
|
306
|
+
const isLongRunning = (c) => {
|
|
307
|
+
const lower = c.toLowerCase().trim();
|
|
308
|
+
return (/\bvite\b/.test(lower) ||
|
|
309
|
+
/\bnodemon\b/.test(lower) ||
|
|
310
|
+
/\bwebpack-dev-server\b/.test(lower) ||
|
|
311
|
+
/\bnext\s+dev\b/.test(lower) ||
|
|
312
|
+
/\bwatch\b/.test(lower) ||
|
|
313
|
+
/--watch\b/.test(lower) ||
|
|
314
|
+
/\b-w\b/.test(lower) ||
|
|
315
|
+
/\bdev-server\b/.test(lower) ||
|
|
316
|
+
/\blive-server\b/.test(lower) ||
|
|
317
|
+
/\bhttp-server\b/.test(lower));
|
|
318
|
+
};
|
|
319
|
+
if (input.background || isLongRunning(cmd)) {
|
|
257
320
|
const result = await bash.startBackground(input.command);
|
|
258
321
|
return formatResult(result);
|
|
259
322
|
}
|
|
@@ -378,6 +441,9 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
378
441
|
});
|
|
379
442
|
// Agent mode gets write/edit/task/delegate tools
|
|
380
443
|
if (mode === "agent") {
|
|
444
|
+
// Capture delegation functions for auto-routing logic below
|
|
445
|
+
const runTaskFn = opts?.runTask;
|
|
446
|
+
const runDelegationFn = opts?.runDelegation;
|
|
381
447
|
// write_file
|
|
382
448
|
tools.write_file = dynamicTool({
|
|
383
449
|
description: "Create a new file or overwrite an existing file with full content. SAFETY: overwriting an existing file requires you to call read_file on it first in the same session. New-file creation does not.",
|
|
@@ -390,6 +456,13 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
390
456
|
required: ["file_path", "content"],
|
|
391
457
|
}),
|
|
392
458
|
execute: async (input) => {
|
|
459
|
+
if (!input?.file_path?.trim() || input.content === undefined || input.content === null) {
|
|
460
|
+
return {
|
|
461
|
+
success: false,
|
|
462
|
+
output: 'BLOCKED (empty-write_file): write_file requires non-empty "file_path" and "content". ' +
|
|
463
|
+
'Example: {"file_path":"src/foo.ts","content":"export const x = 1;\\n"}',
|
|
464
|
+
};
|
|
465
|
+
}
|
|
393
466
|
const result = await writeFile(input.file_path, input.content, bash.getCwd(), fileTracker);
|
|
394
467
|
return {
|
|
395
468
|
success: result.success,
|
|
@@ -412,6 +485,17 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
412
485
|
required: ["file_path", "old_string", "new_string"],
|
|
413
486
|
}),
|
|
414
487
|
execute: async (input) => {
|
|
488
|
+
if (!input?.file_path?.trim() ||
|
|
489
|
+
input.old_string === undefined ||
|
|
490
|
+
input.old_string === null ||
|
|
491
|
+
input.new_string === undefined ||
|
|
492
|
+
input.new_string === null) {
|
|
493
|
+
return {
|
|
494
|
+
success: false,
|
|
495
|
+
output: "BLOCKED (empty-edit_file): edit_file requires file_path, old_string, and new_string. " +
|
|
496
|
+
'Example: {"file_path":"src/foo.ts","old_string":"a","new_string":"b"}',
|
|
497
|
+
};
|
|
498
|
+
}
|
|
415
499
|
const result = await editFile(input.file_path, input.old_string, input.new_string, bash.getCwd(), fileTracker);
|
|
416
500
|
return {
|
|
417
501
|
success: result.success,
|
|
@@ -475,9 +559,11 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
475
559
|
});
|
|
476
560
|
// task
|
|
477
561
|
if (opts?.runTask) {
|
|
478
|
-
const runTask = opts.runTask;
|
|
479
562
|
tools.task = dynamicTool({
|
|
480
|
-
description: "Delegate a
|
|
563
|
+
description: "Delegate a FOCUSED, SHORT foreground task to a sub-agent that blocks the current turn until complete. " +
|
|
564
|
+
"Use ONLY for quick edit/execute/verify work (default max ~12 rounds). " +
|
|
565
|
+
"For long research, exploration, or anything that may take many steps (explore agent), you MUST use the 'delegate' tool instead — it runs in true background and does not block. " +
|
|
566
|
+
"Using task for long work will cause stalls and timeouts.",
|
|
481
567
|
inputSchema: jsonSchema({
|
|
482
568
|
type: "object",
|
|
483
569
|
properties: {
|
|
@@ -489,13 +575,20 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
489
575
|
prompt: { type: "string", description: "Detailed instructions for the sub-agent" },
|
|
490
576
|
maxToolRounds: {
|
|
491
577
|
type: "number",
|
|
492
|
-
description: "Optional maximum tool execution rounds (default
|
|
578
|
+
description: "Optional maximum tool execution rounds. For research/explore use delegate + higher values (default 60); low values (≤20) only for task.",
|
|
493
579
|
},
|
|
494
580
|
},
|
|
495
581
|
required: ["agent", "description", "prompt"],
|
|
496
582
|
}),
|
|
497
583
|
execute: async (input) => {
|
|
498
|
-
|
|
584
|
+
// Auto-route long research (explore agent or high round count) to true background delegation
|
|
585
|
+
// to prevent blocking the main turn and causing stall timeouts.
|
|
586
|
+
const isLongResearch = input.agent === "explore" || (typeof input.maxToolRounds === "number" && input.maxToolRounds > 25);
|
|
587
|
+
const executor = isLongResearch && runDelegationFn ? runDelegationFn : runTaskFn;
|
|
588
|
+
if (!executor) {
|
|
589
|
+
return { success: false, output: "No delegation executor available." };
|
|
590
|
+
}
|
|
591
|
+
const result = await executor({
|
|
499
592
|
agent: input.agent,
|
|
500
593
|
description: input.description,
|
|
501
594
|
prompt: input.prompt,
|
|
@@ -530,7 +623,10 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
530
623
|
if (opts?.runDelegation) {
|
|
531
624
|
const runDelegation = opts.runDelegation;
|
|
532
625
|
tools.delegate = dynamicTool({
|
|
533
|
-
description: "Launch a read-only
|
|
626
|
+
description: "Launch a read-only BACKGROUND research agent (usually 'explore') that runs independently in a separate process. " +
|
|
627
|
+
"Use this for ANY long-running research, codebase exploration, analysis, or tasks with high maxToolRounds. " +
|
|
628
|
+
"Main session continues working immediately. Results are delivered later via notifications or delegation_read. " +
|
|
629
|
+
"This is the PREFERRED tool over 'task' for explore/research to avoid blocking and timeouts.",
|
|
534
630
|
inputSchema: jsonSchema({
|
|
535
631
|
type: "object",
|
|
536
632
|
properties: {
|
|
@@ -539,7 +635,7 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
539
635
|
prompt: { type: "string", description: "Detailed research instructions" },
|
|
540
636
|
maxToolRounds: {
|
|
541
637
|
type: "number",
|
|
542
|
-
description: "Optional maximum tool execution rounds (
|
|
638
|
+
description: "Optional maximum tool execution rounds (high values like 60+ expected for background research; do not use task for high values).",
|
|
543
639
|
},
|
|
544
640
|
},
|
|
545
641
|
required: ["agent", "description", "prompt"],
|
|
@@ -652,7 +748,7 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
652
748
|
// output in-process by toolCallId. For an exact "tool-artifact id=X"
|
|
653
749
|
// lookup this is the authoritative full content for THIS session and
|
|
654
750
|
// works even when EE is down — the failure window long sessions hit.
|
|
655
|
-
const { findArtifactByQuery, findArtifactOnDisk } = await import("../ee/artifact-cache.js");
|
|
751
|
+
const { findArtifactByQuery, findArtifactByHint, findArtifactOnDisk } = await import("../ee/artifact-cache.js");
|
|
656
752
|
// Lived-experience telemetry: record where the rehydrate came from so
|
|
657
753
|
// a "cảm nhận trong CLI" question (and the measure-first instrumentation)
|
|
658
754
|
// sees cache vs disk vs ee vs needed-but-unavailable.
|
|
@@ -664,6 +760,15 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
664
760
|
recordRehydration(mem ? "cache" : "disk");
|
|
665
761
|
return truncateOutput(`[tool-artifact id=${local.toolCallId} tool=${local.toolName} — rehydrated from ${src}]\n${local.content}`);
|
|
666
762
|
}
|
|
763
|
+
// B (cheap-model anti-mù) — the exact id missed locally. Cheap models
|
|
764
|
+
// often pass FILE PATHS instead of the opaque toolCallId, which
|
|
765
|
+
// extractArtifactId can't parse. Try a path match against the local
|
|
766
|
+
// cache before the EE round-trip so a botched id still recovers.
|
|
767
|
+
const fuzzy = findArtifactByHint(query);
|
|
768
|
+
if (fuzzy) {
|
|
769
|
+
recordRehydration("cache");
|
|
770
|
+
return truncateOutput(`[tool-artifact id=${fuzzy.toolCallId} tool=${fuzzy.toolName} — rehydrated by path match; your id was malformed (pass the exact id from the "[… elided id=X …]" stub next time)]\n${fuzzy.content}`);
|
|
771
|
+
}
|
|
667
772
|
// EE fallback (cross-session / post-restart) → raw /api/search exact lookup.
|
|
668
773
|
const { searchEE } = await import("../ee/search.js");
|
|
669
774
|
const resp = await searchEE(query, {
|
|
@@ -721,6 +826,204 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
721
826
|
}
|
|
722
827
|
},
|
|
723
828
|
});
|
|
829
|
+
tools.retrieve_tool_result = dynamicTool({
|
|
830
|
+
description: "Retrieve the full output of a previous tool call by its tool_call_id. " +
|
|
831
|
+
"Searches local cache, disk cache, database history (including parent sessions), and remote Experience Engine. " +
|
|
832
|
+
"Use this to rehydrate elided tool outputs. Optional max_chars and chunk_index allow paginated retrieval.",
|
|
833
|
+
inputSchema: jsonSchema({
|
|
834
|
+
type: "object",
|
|
835
|
+
properties: {
|
|
836
|
+
tool_call_id: { type: "string", description: "The unique ID of the tool call (e.g. 'call_123')." },
|
|
837
|
+
max_chars: {
|
|
838
|
+
type: "number",
|
|
839
|
+
description: "Optional character limit for the returned chunk (useful for very large outputs).",
|
|
840
|
+
},
|
|
841
|
+
chunk_index: {
|
|
842
|
+
type: "number",
|
|
843
|
+
description: "Optional chunk index if splitting the output by max_chars (0-based, default 0).",
|
|
844
|
+
},
|
|
845
|
+
},
|
|
846
|
+
required: ["tool_call_id"],
|
|
847
|
+
}),
|
|
848
|
+
execute: async (input) => {
|
|
849
|
+
const toolCallId = typeof input.tool_call_id === "string" ? input.tool_call_id.trim() : "";
|
|
850
|
+
if (!toolCallId) {
|
|
851
|
+
return "ERROR: tool_call_id is required.";
|
|
852
|
+
}
|
|
853
|
+
const maxChars = typeof input.max_chars === "number" ? input.max_chars : undefined;
|
|
854
|
+
const chunkIndex = typeof input.chunk_index === "number" ? input.chunk_index : 0;
|
|
855
|
+
let content = null;
|
|
856
|
+
let source = "";
|
|
857
|
+
// Tier 1: LRU cache
|
|
858
|
+
try {
|
|
859
|
+
const { getArtifact } = await import("../ee/artifact-cache.js");
|
|
860
|
+
const tier1 = getArtifact(toolCallId);
|
|
861
|
+
if (tier1) {
|
|
862
|
+
content = tier1.content;
|
|
863
|
+
source = "Tier 1 LRU cache";
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
catch (err) {
|
|
867
|
+
console.error(`[tools:retrieve_tool_result] Tier 1 LRU check failed: ${err.message}`);
|
|
868
|
+
}
|
|
869
|
+
// Tier 2: Disk cache
|
|
870
|
+
if (!content) {
|
|
871
|
+
try {
|
|
872
|
+
const { findArtifactOnDisk } = await import("../ee/artifact-cache.js");
|
|
873
|
+
const tier2 = await findArtifactOnDisk(`id=${toolCallId}`);
|
|
874
|
+
if (tier2) {
|
|
875
|
+
content = tier2.content;
|
|
876
|
+
source = "Tier 2 disk cache";
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
catch (err) {
|
|
880
|
+
console.error(`[tools:retrieve_tool_result] Tier 2 disk check failed: ${err.message}`);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
// Tier 3: SQLite database
|
|
884
|
+
if (!content && opts?.sessionId) {
|
|
885
|
+
try {
|
|
886
|
+
const { getSessionChain } = await import("../storage/index.js");
|
|
887
|
+
const { getDatabase } = await import("../storage/db.js");
|
|
888
|
+
const chain = getSessionChain(opts.sessionId);
|
|
889
|
+
const db = getDatabase();
|
|
890
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
891
|
+
const row = db
|
|
892
|
+
.prepare(`
|
|
893
|
+
SELECT tr.output_json
|
|
894
|
+
FROM tool_results tr
|
|
895
|
+
JOIN tool_calls tc ON tc.id = tr.tool_call_row_id
|
|
896
|
+
WHERE tc.tool_call_id = ? AND tc.session_id = ?
|
|
897
|
+
LIMIT 1
|
|
898
|
+
`)
|
|
899
|
+
.get(toolCallId, chain[i]);
|
|
900
|
+
if (row?.output_json) {
|
|
901
|
+
const parsed = JSON.parse(row.output_json);
|
|
902
|
+
if (parsed && typeof parsed === "object") {
|
|
903
|
+
if ("output" in parsed && typeof parsed.output === "string") {
|
|
904
|
+
content = parsed.output;
|
|
905
|
+
}
|
|
906
|
+
else if ("error" in parsed && typeof parsed.error === "string") {
|
|
907
|
+
content = `ERROR: ${parsed.error}`;
|
|
908
|
+
}
|
|
909
|
+
else {
|
|
910
|
+
content = JSON.stringify(parsed);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
else {
|
|
914
|
+
content = String(parsed);
|
|
915
|
+
}
|
|
916
|
+
source = `Tier 3 SQLite database (session ${chain[i]})`;
|
|
917
|
+
break;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
catch (err) {
|
|
922
|
+
console.error(`[tools:retrieve_tool_result] Tier 3 DB check failed: ${err.message}`);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
// Tier 4: Remote EE (behavioral collection only)
|
|
926
|
+
if (!content) {
|
|
927
|
+
try {
|
|
928
|
+
const { searchEE } = await import("../ee/search.js");
|
|
929
|
+
const resp = await searchEE(`tool-artifact id=${toolCallId}`, {
|
|
930
|
+
collections: ["experience-behavioral"],
|
|
931
|
+
limit: 1,
|
|
932
|
+
});
|
|
933
|
+
const bestHit = resp?.points?.[0];
|
|
934
|
+
if (bestHit?.text) {
|
|
935
|
+
content = bestHit.text;
|
|
936
|
+
source = "Tier 4 remote EE (behavioral collection)";
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
catch (err) {
|
|
940
|
+
console.error(`[tools:retrieve_tool_result] Tier 4 EE check failed: ${err.message}`);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (content === null) {
|
|
944
|
+
return `ERROR: Tool result not found for tool_call_id: ${toolCallId} in any tier.`;
|
|
945
|
+
}
|
|
946
|
+
const totalLength = content.length;
|
|
947
|
+
if (maxChars !== undefined && maxChars > 0) {
|
|
948
|
+
const totalChunks = Math.ceil(totalLength / maxChars);
|
|
949
|
+
const start = chunkIndex * maxChars;
|
|
950
|
+
const end = Math.min(start + maxChars, totalLength);
|
|
951
|
+
if (start >= totalLength) {
|
|
952
|
+
return `ERROR: chunk_index ${chunkIndex} is out of bounds. Total chunks available: ${totalChunks} (max_chars: ${maxChars}, total length: ${totalLength}).`;
|
|
953
|
+
}
|
|
954
|
+
const chunk = content.slice(start, end);
|
|
955
|
+
return JSON.stringify({
|
|
956
|
+
tool_call_id: toolCallId,
|
|
957
|
+
source,
|
|
958
|
+
chunk_index: chunkIndex,
|
|
959
|
+
total_chunks: totalChunks,
|
|
960
|
+
chunk_length: chunk.length,
|
|
961
|
+
total_length: totalLength,
|
|
962
|
+
content: chunk,
|
|
963
|
+
}, null, 2);
|
|
964
|
+
}
|
|
965
|
+
return JSON.stringify({
|
|
966
|
+
tool_call_id: toolCallId,
|
|
967
|
+
source,
|
|
968
|
+
total_length: totalLength,
|
|
969
|
+
content,
|
|
970
|
+
}, null, 2);
|
|
971
|
+
},
|
|
972
|
+
});
|
|
973
|
+
tools.search_session_history = dynamicTool({
|
|
974
|
+
description: "Search the full message history across all sessions using an FTS5 MATCH expression. " +
|
|
975
|
+
"Useful to locate past questions, answers, and context across the session lineage.",
|
|
976
|
+
inputSchema: jsonSchema({
|
|
977
|
+
type: "object",
|
|
978
|
+
properties: {
|
|
979
|
+
query: {
|
|
980
|
+
type: "string",
|
|
981
|
+
description: "FTS5 MATCH expression query (e.g. 'compaction AND error' or 'content:Vitest').",
|
|
982
|
+
},
|
|
983
|
+
},
|
|
984
|
+
required: ["query"],
|
|
985
|
+
}),
|
|
986
|
+
execute: async (input) => {
|
|
987
|
+
const query = typeof input.query === "string" ? input.query.trim() : "";
|
|
988
|
+
if (!query) {
|
|
989
|
+
return "ERROR: query MATCH expression is required.";
|
|
990
|
+
}
|
|
991
|
+
try {
|
|
992
|
+
const { getDatabase } = await import("../storage/db.js");
|
|
993
|
+
const db = getDatabase();
|
|
994
|
+
// Wrap FTS search query execution in try-catch to prevent malformed FTS syntax crashes (fixing GAP-03)
|
|
995
|
+
const rows = db
|
|
996
|
+
.prepare(`
|
|
997
|
+
SELECT session_id, seq, role, tool_name, content, tool_args, tool_output
|
|
998
|
+
FROM session_history_fts
|
|
999
|
+
WHERE session_history_fts MATCH ?
|
|
1000
|
+
ORDER BY rank
|
|
1001
|
+
LIMIT 50
|
|
1002
|
+
`)
|
|
1003
|
+
.all(query);
|
|
1004
|
+
if (rows.length === 0) {
|
|
1005
|
+
return `No session history matched the query: "${query}"`;
|
|
1006
|
+
}
|
|
1007
|
+
const results = rows.map((row) => ({
|
|
1008
|
+
session_id: row.session_id,
|
|
1009
|
+
seq: row.seq,
|
|
1010
|
+
role: row.role,
|
|
1011
|
+
tool_name: row.tool_name ?? undefined,
|
|
1012
|
+
content: row.content ?? undefined,
|
|
1013
|
+
tool_args: row.tool_args ?? undefined,
|
|
1014
|
+
tool_output: row.tool_output ?? undefined,
|
|
1015
|
+
}));
|
|
1016
|
+
return JSON.stringify({
|
|
1017
|
+
query,
|
|
1018
|
+
match_count: results.length,
|
|
1019
|
+
results,
|
|
1020
|
+
}, null, 2);
|
|
1021
|
+
}
|
|
1022
|
+
catch (err) {
|
|
1023
|
+
return `ERROR: FTS MATCH query failed. The FTS syntax might be malformed: ${err.message}`;
|
|
1024
|
+
}
|
|
1025
|
+
},
|
|
1026
|
+
});
|
|
724
1027
|
// Native muonroi-tools builtins — ee_health, ee_feedback, usage_forensics,
|
|
725
1028
|
// lsp_query, setup_guide, selfverify_*. These run IN-PROCESS; the CLI no
|
|
726
1029
|
// longer self-spawns itself as an MCP server to expose them to its own inner
|
|
@@ -728,16 +1031,25 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
728
1031
|
// and a seed-time bug once persisted a crashing vitest-worker command). The
|
|
729
1032
|
// muonroi-tools MCP server stays only for EXTERNAL agents. See native-tools.ts.
|
|
730
1033
|
registerNativeMuonroiTools(tools, { cwd: bash.getCwd() });
|
|
1034
|
+
registerGsdWorkflowTools(tools, {
|
|
1035
|
+
cwd: bash.getCwd(),
|
|
1036
|
+
sessionModelId: opts?.modelId ?? "unknown",
|
|
1037
|
+
sessionId: opts?.sessionId,
|
|
1038
|
+
depth: opts?.depthTier ?? "standard",
|
|
1039
|
+
runTask: opts?.runTask,
|
|
1040
|
+
runDebate: opts?.runDebate,
|
|
1041
|
+
});
|
|
731
1042
|
}
|
|
732
1043
|
// Vision proxy tools — only for text-only models (DeepSeek, etc.)
|
|
733
1044
|
if (opts?.modelId && needsVisionProxy(opts.modelId)) {
|
|
734
1045
|
const cwd = bash.getCwd();
|
|
735
1046
|
tools.analyze_image = dynamicTool({
|
|
736
|
-
description: "
|
|
737
|
-
"Use
|
|
738
|
-
"or when the user references an image.
|
|
1047
|
+
description: "Inspect an image and receive a <vision-observation> block — treat the result as your direct sight. " +
|
|
1048
|
+
"Use IMMEDIATELY when you encounter any image file (.png, .jpg, .gif, .webp, .svg, etc.) " +
|
|
1049
|
+
"or when the user references an image. Do not guess visual content. " +
|
|
739
1050
|
"Accepts file paths, data URIs, or base64 strings. " +
|
|
740
|
-
"Optionally provide a question to focus the analysis."
|
|
1051
|
+
"Optionally provide a question to focus the analysis (OCR, layout, specific UI element). " +
|
|
1052
|
+
"If details remain unclear, call ask_vision_proxy or ask the user for another screenshot.",
|
|
741
1053
|
inputSchema: jsonSchema({
|
|
742
1054
|
type: "object",
|
|
743
1055
|
properties: {
|
|
@@ -757,9 +1069,10 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
757
1069
|
},
|
|
758
1070
|
});
|
|
759
1071
|
tools.ask_vision_proxy = dynamicTool({
|
|
760
|
-
description: "Ask a follow-up
|
|
761
|
-
"
|
|
762
|
-
"
|
|
1072
|
+
description: "Ask a follow-up about an image you are viewing (cached ID) or analyze a new file with a specific question. " +
|
|
1073
|
+
"Returns a <vision-observation> — respond as if you saw it yourself. " +
|
|
1074
|
+
"Use when any detail in a prior observation is unclear: zoom on a region, read text, compare colors, verify UI state. " +
|
|
1075
|
+
"Reference a cached image by ID (from list_vision_cache) or provide a file path for a new image.",
|
|
763
1076
|
inputSchema: jsonSchema({
|
|
764
1077
|
type: "object",
|
|
765
1078
|
properties: {
|
|
@@ -854,6 +1167,131 @@ export function createBuiltinTools(bash, mode, opts) {
|
|
|
854
1167
|
for (const name of VISION_TOOL_NAMES)
|
|
855
1168
|
delete tools[name];
|
|
856
1169
|
}
|
|
1170
|
+
// ── Agent introspection tools: help the inner agent discover capabilities ──
|
|
1171
|
+
// These are always added last (after all filtering) so list_tools reflects reality.
|
|
1172
|
+
tools.list_mcp_servers = dynamicTool({
|
|
1173
|
+
description: "List every MCP server in the current user config (enabled or not). Returns id, label, enabled, transport, endpoint, and recommended_native (if any). " +
|
|
1174
|
+
"Use this to discover exactly what MCPs you have right now. For each MCP, see if there is a preferred native replacement (e.g. fetch_url instead of legacy fetch). " +
|
|
1175
|
+
"Memory, playwright, figma removed from defaults. Only enabled servers contribute tools this turn.",
|
|
1176
|
+
inputSchema: jsonSchema({
|
|
1177
|
+
type: "object",
|
|
1178
|
+
properties: {},
|
|
1179
|
+
additionalProperties: false,
|
|
1180
|
+
}),
|
|
1181
|
+
execute: async () => {
|
|
1182
|
+
const servers = loadMcpServers();
|
|
1183
|
+
// Native replacement recommendations (helps agent choose better tools)
|
|
1184
|
+
const RECOMMENDATIONS = {
|
|
1185
|
+
fetch: "Prefer native fetch_url (faster, always available, no external spawn).",
|
|
1186
|
+
tavily: "Prefer native web_search (direct Tavily API call, same results).",
|
|
1187
|
+
context7: "Consider keeping for library docs, or cache important docs into Experience Engine for offline use.",
|
|
1188
|
+
"muonroi-docs": null, // already our own controlled service
|
|
1189
|
+
playwright: "Use for full browser interaction/screenshots only; fetch_url sufficient for most content needs.",
|
|
1190
|
+
memory: "Use native ee_query / ee_write (Experience Engine) instead.",
|
|
1191
|
+
figma: "Add manually only if needed; no native equivalent yet.",
|
|
1192
|
+
};
|
|
1193
|
+
const summary = servers.map((s) => {
|
|
1194
|
+
const rec = RECOMMENDATIONS[s.id] ?? null;
|
|
1195
|
+
return {
|
|
1196
|
+
id: s.id,
|
|
1197
|
+
label: s.label,
|
|
1198
|
+
enabled: s.enabled,
|
|
1199
|
+
transport: s.transport,
|
|
1200
|
+
endpoint: s.url || (s.command ? `${s.command} ${(s.args || []).join(" ")}` : undefined),
|
|
1201
|
+
recommended_native: rec,
|
|
1202
|
+
};
|
|
1203
|
+
});
|
|
1204
|
+
return JSON.stringify({ count: summary.length, servers: summary }, null, 2);
|
|
1205
|
+
},
|
|
1206
|
+
});
|
|
1207
|
+
tools.list_tools = dynamicTool({
|
|
1208
|
+
description: "Compact grouped summary of every tool available this turn. " +
|
|
1209
|
+
"native = always-on builtins (fetch_url, web_search, bash, read_file, grep, ee_query, list_mcp_servers, list_tools, ...). " +
|
|
1210
|
+
"mcp = tools from your enabled MCP servers (prefixed mcp_<server-id>__). " +
|
|
1211
|
+
"Each line: name + short description (tells you purpose and rough usage). " +
|
|
1212
|
+
"Call list_mcp_servers() to see your MCP sources, then this to see concrete tools + how to use them. Full parameter schemas are in the system tool list this turn.",
|
|
1213
|
+
inputSchema: jsonSchema({
|
|
1214
|
+
type: "object",
|
|
1215
|
+
properties: {
|
|
1216
|
+
category: {
|
|
1217
|
+
type: "string",
|
|
1218
|
+
enum: ["all", "native", "mcp"],
|
|
1219
|
+
description: "Optional filter.",
|
|
1220
|
+
},
|
|
1221
|
+
},
|
|
1222
|
+
additionalProperties: false,
|
|
1223
|
+
}),
|
|
1224
|
+
execute: async (input) => {
|
|
1225
|
+
const cat = input?.category || "all";
|
|
1226
|
+
const grouped = { native: [], mcp: [] };
|
|
1227
|
+
for (const [name, tool] of Object.entries(tools)) {
|
|
1228
|
+
const t = tool;
|
|
1229
|
+
const shortDesc = (t.description || "").split("\n")[0].slice(0, 140);
|
|
1230
|
+
const entry = `${name}: ${shortDesc}`;
|
|
1231
|
+
if (name.startsWith("mcp_")) {
|
|
1232
|
+
if (cat === "all" || cat === "mcp")
|
|
1233
|
+
grouped.mcp.push(entry);
|
|
1234
|
+
}
|
|
1235
|
+
else {
|
|
1236
|
+
if (cat === "all" || cat === "native")
|
|
1237
|
+
grouped.native.push(entry);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
grouped.native.sort();
|
|
1241
|
+
grouped.mcp.sort();
|
|
1242
|
+
return JSON.stringify({
|
|
1243
|
+
total: Object.keys(tools).length,
|
|
1244
|
+
native_count: grouped.native.length,
|
|
1245
|
+
mcp_count: grouped.mcp.length,
|
|
1246
|
+
...grouped,
|
|
1247
|
+
note: "Native tools are always preferred. MCP tools only from servers where enabled=true (see list_mcp_servers).",
|
|
1248
|
+
}, null, 2);
|
|
1249
|
+
},
|
|
1250
|
+
});
|
|
1251
|
+
tools.describe_tool = dynamicTool({
|
|
1252
|
+
description: "Get detailed usage information for a specific tool by name. Returns description, full input schema (parameters), and a short usage example or note. " +
|
|
1253
|
+
"Call this when you need precise 'how to use' details for a tool (e.g. describe_tool with name='fetch_url' or name='mcp_context7__something'). " +
|
|
1254
|
+
"This complements list_tools and list_mcp_servers.",
|
|
1255
|
+
inputSchema: jsonSchema({
|
|
1256
|
+
type: "object",
|
|
1257
|
+
properties: {
|
|
1258
|
+
name: {
|
|
1259
|
+
type: "string",
|
|
1260
|
+
description: "Exact tool name (e.g. 'fetch_url', 'web_search', 'mcp_context7__search' or any from list_tools)",
|
|
1261
|
+
},
|
|
1262
|
+
},
|
|
1263
|
+
required: ["name"],
|
|
1264
|
+
additionalProperties: false,
|
|
1265
|
+
}),
|
|
1266
|
+
execute: async (input) => {
|
|
1267
|
+
const name = typeof input?.name === "string" ? input.name.trim() : "";
|
|
1268
|
+
if (!name)
|
|
1269
|
+
return "ERROR: name is required";
|
|
1270
|
+
const tool = tools[name];
|
|
1271
|
+
if (!tool) {
|
|
1272
|
+
return JSON.stringify({
|
|
1273
|
+
name,
|
|
1274
|
+
error: "Tool not found in current tool set. Use list_tools to see available names.",
|
|
1275
|
+
}, null, 2);
|
|
1276
|
+
}
|
|
1277
|
+
const t = tool;
|
|
1278
|
+
const schema = t.inputSchema || tool.parameters || null;
|
|
1279
|
+
// Provide a minimal example note for common tools
|
|
1280
|
+
const examples = {
|
|
1281
|
+
fetch_url: 'Example: {"url": "https://example.com/docs", "format": "markdown"}',
|
|
1282
|
+
web_search: 'Example: {"query": "muonroi building block best practices", "maxResults": 5}',
|
|
1283
|
+
list_mcp_servers: "Call with no args: {}",
|
|
1284
|
+
list_tools: 'Example: {"category": "native"}',
|
|
1285
|
+
};
|
|
1286
|
+
return JSON.stringify({
|
|
1287
|
+
name,
|
|
1288
|
+
description: t.description,
|
|
1289
|
+
inputSchema: schema,
|
|
1290
|
+
example: examples[name] || "See inputSchema above. Call with correct parameters.",
|
|
1291
|
+
note: "Use the exact parameters from inputSchema when calling this tool.",
|
|
1292
|
+
}, null, 2);
|
|
1293
|
+
},
|
|
1294
|
+
});
|
|
857
1295
|
return tools;
|
|
858
1296
|
}
|
|
859
1297
|
//# sourceMappingURL=registry.js.map
|
|
@@ -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;
|