muonroi-cli 1.8.4 → 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 +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-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 +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 +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 +234 -64
- 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/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -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/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 +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-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 +22 -0
- package/dist/src/orchestrator/tool-engine.js +620 -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/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/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 +310 -99
- 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/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 +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 +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/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 +3 -3
- 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 +284 -13
- 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.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/install-manager.js +2 -1
- 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/visible-retry.d.ts +11 -0
- package/dist/src/utils/visible-retry.js +10 -1
- package/dist/src/verify/entrypoint.d.ts +1 -1
- package/dist/src/verify/entrypoint.js +1 -1
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +135 -132
- package/dist/src/providers/auth/gcloud.d.ts +0 -28
- package/dist/src/providers/auth/gcloud.js +0 -102
- package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
- package/dist/src/providers/auth/gemini-oauth.js +0 -472
- package/dist/src/providers/gemini.d.ts +0 -11
- package/dist/src/providers/gemini.js +0 -45
- package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
- package/dist/src/providers/siliconflow-sse-repair.js +0 -177
- package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
- package/dist/src/providers/strategies/google.strategy.js +0 -174
- package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
- package/dist/src/ui/containers/chat-feed.d.ts +0 -40
- package/dist/src/ui/containers/chat-feed.js +0 -66
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/pil/layer1-intent.ts
|
|
3
3
|
*
|
|
4
|
-
* Layer 1: Intent detection.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* Layer 1: Intent detection — MODEL-FIRST ONLY.
|
|
5
|
+
* The configured chat model (via opts.llmFallback) classifies taskType / intent
|
|
6
|
+
* / style / depth / clarity / scope / language. The old keyword-regex "Pass 0-4"
|
|
7
|
+
* cascade was DELETED (2026-07-07, no-regex rule) — regex no longer decides
|
|
8
|
+
* intent. When no classifier is wired the layer degrades to UNKNOWN (taskType
|
|
9
|
+
* null, keep-tools), never a regex guess. On a classify miss the classifier
|
|
10
|
+
* self-repairs (see createLlmClassifier) before surfacing UNKNOWN.
|
|
10
11
|
* Fail-open: any error returns ctx unchanged with applied=false.
|
|
12
|
+
*
|
|
13
|
+
* NOTE: scoreComplexity / scoreSufficiency below are retained ONLY because other
|
|
14
|
+
* modules (playbook, discovery, orchestrator) still import them; they no longer
|
|
15
|
+
* run on this layer's classification path.
|
|
11
16
|
*/
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
17
|
+
import { pilContext } from "../ee/bridge.js";
|
|
18
|
+
import { getUnifiedPilBudgetMs, isLlmFirstBrainEnabled } from "./config.js";
|
|
19
|
+
function mapBrainGsdPhase(value) {
|
|
20
|
+
if (value === "discuss" || value === "execute")
|
|
21
|
+
return value;
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
15
24
|
/** File/path reference regex — matches common source-file extensions. */
|
|
16
25
|
const FILE_REF_RE = /[\w./-]+\.(ts|tsx|js|jsx|json|md|py|rs|go|cs)\b/gi;
|
|
17
26
|
/** Keywords that force a "low" complexity signal (additive score -3). */
|
|
@@ -109,33 +118,6 @@ export function scoreComplexity(input) {
|
|
|
109
118
|
complexity = "high";
|
|
110
119
|
return { complexity, score };
|
|
111
120
|
}
|
|
112
|
-
// Maps every classifier reason string to a TaskType (or null for non-coding signals).
|
|
113
|
-
const REASON_TO_TASK_TYPE = {
|
|
114
|
-
"regex:refactor": "refactor",
|
|
115
|
-
"regex:edit": "generate",
|
|
116
|
-
"regex:create-file": "generate",
|
|
117
|
-
"regex:run-command": "analyze",
|
|
118
|
-
"regex:explain": "analyze",
|
|
119
|
-
"regex:search": "analyze",
|
|
120
|
-
"regex:install": "analyze",
|
|
121
|
-
// tree-sitter:* parses indicate code presence ONLY — no intent signal.
|
|
122
|
-
// Mapping these to "refactor" caused 4/5 baseline misclassifications
|
|
123
|
-
// (Phase 4, 4P-1). Leave undefined so Pass 2 keyword fallback decides.
|
|
124
|
-
"tree-sitter:typescript": undefined,
|
|
125
|
-
"tree-sitter:python": undefined,
|
|
126
|
-
"regex:read": "analyze",
|
|
127
|
-
"regex:git": "analyze",
|
|
128
|
-
"regex:short-message": "general",
|
|
129
|
-
"regex:design": "plan",
|
|
130
|
-
"regex:debug": "debug",
|
|
131
|
-
// no-match / error / cold / low-confidence → null (conversational passthrough)
|
|
132
|
-
"regex:no-match": undefined,
|
|
133
|
-
"tree-sitter:no-fenced-code": undefined,
|
|
134
|
-
"tree-sitter:cold": undefined,
|
|
135
|
-
"tree-sitter:typescript-parse-error": undefined,
|
|
136
|
-
"tree-sitter:python-parse-error": undefined,
|
|
137
|
-
"low-confidence": undefined,
|
|
138
|
-
};
|
|
139
121
|
/**
|
|
140
122
|
* Pass 0 — deterministic full-prompt overrides.
|
|
141
123
|
*
|
|
@@ -300,56 +282,6 @@ export function isStatusCheckQuestion(raw) {
|
|
|
300
282
|
return false;
|
|
301
283
|
return STATUS_CHECK_VI_RE.test(t) || STATUS_CHECK_EN_RE.test(t);
|
|
302
284
|
}
|
|
303
|
-
// Keyword patterns for task types the classifier doesn't natively handle.
|
|
304
|
-
// Applied when classifier abstains OR matches the low-signal "general" path.
|
|
305
|
-
// Patterns are bilingual (EN + VN) — Vietnamese cues use accent-insensitive
|
|
306
|
-
// alternations so common diacritic drops still match.
|
|
307
|
-
const KEYWORD_PATTERNS = [
|
|
308
|
-
{
|
|
309
|
-
// EN: fix/bug/error/etc. VN: sửa lỗi, lỗi, hỏng, không chạy
|
|
310
|
-
pattern: /\b(fix|bug|error|exception|crash|fail(?:s|ed|ing)?|broken|wrong|issue|traceback)\b|(sửa lỗi|sua loi|báo lỗi|bao loi|\blỗi\b|\bloi\b|hỏng|hong|không chạy|khong chay)/i,
|
|
311
|
-
taskType: "debug",
|
|
312
|
-
confidence: 0.65,
|
|
313
|
-
},
|
|
314
|
-
{
|
|
315
|
-
// EN: plan/roadmap/architecture. VN: kế hoạch, thiết kế, kiến trúc, lộ trình
|
|
316
|
-
pattern: /\b(plan|roadmap|phase|step(?:s)?|approach|design|architect(?:ure)?|strategy)\b|(kế hoạch|ke hoach|thiết kế|thiet ke|kiến trúc|kien truc|lộ trình|lo trinh)/i,
|
|
317
|
-
taskType: "plan",
|
|
318
|
-
confidence: 0.6,
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
// EN: docs/readme/jsdoc. VN: tài liệu, viết doc, ghi chú, comment
|
|
322
|
-
pattern: /\b(doc(?:s|umentation)?|readme|comment|jsdoc|tsdoc|docstring)\b|(tài liệu|tai lieu|viết doc|viet doc|ghi chú|ghi chu)/i,
|
|
323
|
-
taskType: "documentation",
|
|
324
|
-
confidence: 0.6,
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
// EN: test/spec/coverage. VN: kiểm thử, viết test, kiểm tra
|
|
328
|
-
pattern: /\b(test(?:s|ing)?|spec|unit test|coverage|assert(?:ion)?)\b|(kiểm thử|kiem thu|viết test|viet test|kiểm tra|kiem tra)/i,
|
|
329
|
-
taskType: "analyze",
|
|
330
|
-
confidence: 0.65,
|
|
331
|
-
},
|
|
332
|
-
{
|
|
333
|
-
// EN: refactor. VN: tái cấu trúc, viết lại, tổ chức lại
|
|
334
|
-
pattern: /\brefactor(?:ing)?\b|(tái cấu trúc|tai cau truc|viết lại|viet lai|tổ chức lại|to chuc lai)/i,
|
|
335
|
-
taskType: "refactor",
|
|
336
|
-
confidence: 0.7,
|
|
337
|
-
},
|
|
338
|
-
{
|
|
339
|
-
// EN: create/generate. VN: tạo, sinh, viết mới
|
|
340
|
-
pattern: /\b(generate|scaffold|bootstrap)\b|(tạo file|tao file|tạo module|tao module|sinh code|viết mới|viet moi)/i,
|
|
341
|
-
taskType: "generate",
|
|
342
|
-
confidence: 0.65,
|
|
343
|
-
},
|
|
344
|
-
];
|
|
345
|
-
// Catch-all classifier reasons whose taskType assignment is weak — Pass 2 keyword
|
|
346
|
-
// rescue is allowed to override them when confidence is sub-threshold. Specific
|
|
347
|
-
// rules like `regex:run-command` / `regex:git` stay authoritative.
|
|
348
|
-
const CATCHALL_REASONS = new Set(["regex:edit", "regex:create-file"]);
|
|
349
|
-
const HIGH_CONF_THRESHOLD_PASS2 = 0.7;
|
|
350
|
-
// Valid task types for bridge classification parsing (matches RESPONSE_SCHEMAS keys minus 'general').
|
|
351
|
-
const VALID_TASK_TYPES = ["refactor", "debug", "plan", "analyze", "documentation", "generate"];
|
|
352
|
-
const VALID_STYLES = ["concise", "balanced", "detailed"];
|
|
353
285
|
// Detect language/domain from prompt content. Order matters: code fences first
|
|
354
286
|
// (highest signal), file extensions next, then bare keywords.
|
|
355
287
|
const DOMAIN_PATTERNS = [
|
|
@@ -397,7 +329,7 @@ const STYLE_PATTERNS = [
|
|
|
397
329
|
},
|
|
398
330
|
{ pattern: /\b(balanced|normal|standard|cân bằng|bình thường)\b/i, style: "balanced" },
|
|
399
331
|
];
|
|
400
|
-
function
|
|
332
|
+
function _detectStyleFromText(raw) {
|
|
401
333
|
for (const { pattern, style } of STYLE_PATTERNS) {
|
|
402
334
|
if (pattern.test(raw))
|
|
403
335
|
return style;
|
|
@@ -599,11 +531,14 @@ export async function layer1Intent(ctx, opts = {}) {
|
|
|
599
531
|
// downstream (layer3 retrieval) as before. Trivial turns ("ok", greetings)
|
|
600
532
|
// also go through the model so chitchat is a semantic decision, not a regex
|
|
601
533
|
// whitelist; the model returns intentKind="chat" for pure pleasantries.
|
|
602
|
-
|
|
534
|
+
// Model-first is the SOLE classifier whenever one is wired. The old
|
|
535
|
+
// MUONROI_LLM_FIRST_CLASSIFY killswitch is gone: it used to select the
|
|
536
|
+
// keyword-regex cascade, which was deleted (2026-07-07, no-regex rule).
|
|
537
|
+
if (opts.llmFallback) {
|
|
603
538
|
let llmRes = null;
|
|
604
539
|
let classifyError = null;
|
|
605
540
|
try {
|
|
606
|
-
llmRes = await opts.llmFallback(ctx.raw);
|
|
541
|
+
llmRes = await opts.llmFallback(ctx.raw, { recentTurns: opts.recentTurns });
|
|
607
542
|
}
|
|
608
543
|
catch (err) {
|
|
609
544
|
classifyError = err?.message ?? String(err);
|
|
@@ -615,14 +550,14 @@ export async function layer1Intent(ctx, opts = {}) {
|
|
|
615
550
|
// breaks the turn. Only ever upgrades chitchat → task.
|
|
616
551
|
if (intentKind === "chitchat" && hasActionableToolIntent(ctx.raw))
|
|
617
552
|
intentKind = "task";
|
|
618
|
-
|
|
553
|
+
// Style + complexity come from the MODEL, never a keyword regex. Style
|
|
554
|
+
// is the model's word or null (layer4/6 handle null without regex).
|
|
555
|
+
// Complexity is derived from the model's depthTier purely for the
|
|
556
|
+
// telemetry trace — routing reads depthTier directly, not this.
|
|
557
|
+
const outputStyle = llmRes.outputStyle;
|
|
619
558
|
const domain = extractDomain("", ctx.raw);
|
|
620
|
-
const
|
|
621
|
-
|
|
622
|
-
taskType: llmRes.taskType,
|
|
623
|
-
t0HitCount: 0,
|
|
624
|
-
hasMaxSprintsOne: false,
|
|
625
|
-
});
|
|
559
|
+
const complexity = llmRes.depthTier === "heavy" ? "high" : llmRes.depthTier === "quick" ? "low" : "medium";
|
|
560
|
+
const complexityScore = 0;
|
|
626
561
|
const intentTrace = {
|
|
627
562
|
pass1Reason: "llm-first",
|
|
628
563
|
pass1Confidence: llmRes.confidence,
|
|
@@ -639,7 +574,7 @@ export async function layer1Intent(ctx, opts = {}) {
|
|
|
639
574
|
pass3LegacyStyleSucceeded: false,
|
|
640
575
|
pass4LlmAttempted: true,
|
|
641
576
|
pass4LlmSucceeded: true,
|
|
642
|
-
styleSource: llmRes.outputStyle ? "brain-unified" :
|
|
577
|
+
styleSource: llmRes.outputStyle ? "brain-unified" : "none",
|
|
643
578
|
finalTaskType: llmRes.taskType,
|
|
644
579
|
finalConfidence: llmRes.confidence,
|
|
645
580
|
complexity,
|
|
@@ -655,6 +590,7 @@ export async function layer1Intent(ctx, opts = {}) {
|
|
|
655
590
|
// stays null → layer3 legacy path (behaviour unchanged). Gate:
|
|
656
591
|
// MUONROI_LLM_FIRST_BRAIN=0 reverts.
|
|
657
592
|
let llmFirstBrainData = null;
|
|
593
|
+
let llmFirstGsdPhase = mapBrainGsdPhase(ctx.gsdPhase);
|
|
658
594
|
if (isLlmFirstBrainEnabled() && intentKind !== "chitchat") {
|
|
659
595
|
let brainRaw = ctx.raw;
|
|
660
596
|
if (ctx.sessionId) {
|
|
@@ -685,12 +621,14 @@ export async function layer1Intent(ctx, opts = {}) {
|
|
|
685
621
|
t2_patterns: resp.t2_patterns,
|
|
686
622
|
retrieval_skipped_reason: resp.retrieval_skipped_reason,
|
|
687
623
|
};
|
|
624
|
+
llmFirstGsdPhase = mapBrainGsdPhase(resp.gsd_phase) ?? llmFirstGsdPhase;
|
|
688
625
|
intentTrace.pass3UnifiedSucceeded = true;
|
|
689
626
|
}
|
|
690
627
|
}
|
|
691
628
|
return {
|
|
692
629
|
...ctx,
|
|
693
630
|
taskType: llmRes.taskType,
|
|
631
|
+
gsdPhase: llmFirstGsdPhase,
|
|
694
632
|
domain,
|
|
695
633
|
confidence: llmRes.confidence,
|
|
696
634
|
outputStyle,
|
|
@@ -733,12 +671,10 @@ export async function layer1Intent(ctx, opts = {}) {
|
|
|
733
671
|
console.error("[pil.layer1] model-first classify produced no usable result — NOT falling back to regex. " +
|
|
734
672
|
`reason=${classifyError ?? "null/unparseable model response"} ` +
|
|
735
673
|
`model-classifier=wired rawPreview=${JSON.stringify(ctx.raw.slice(0, 120))}`);
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
hasMaxSprintsOne: false,
|
|
741
|
-
});
|
|
674
|
+
// No regex on the failure path either — UNKNOWN classification carries a
|
|
675
|
+
// neutral "medium" complexity for the telemetry trace, decided by nothing.
|
|
676
|
+
const failComplexity = "medium";
|
|
677
|
+
const failComplexityScore = 0;
|
|
742
678
|
return {
|
|
743
679
|
...ctx,
|
|
744
680
|
taskType: null,
|
|
@@ -780,228 +716,27 @@ export async function layer1Intent(ctx, opts = {}) {
|
|
|
780
716
|
],
|
|
781
717
|
};
|
|
782
718
|
}
|
|
783
|
-
//
|
|
784
|
-
//
|
|
785
|
-
//
|
|
786
|
-
//
|
|
787
|
-
//
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
pass1Reason: "pass0:continuation",
|
|
803
|
-
pass1Confidence: 0.9,
|
|
804
|
-
pass1TaskType: "general",
|
|
805
|
-
pass1Hit: true,
|
|
806
|
-
pass2Hit: false,
|
|
807
|
-
pass25ChitchatHit: false,
|
|
808
|
-
pass3UnifiedAttempted: false,
|
|
809
|
-
pass3UnifiedSucceeded: false,
|
|
810
|
-
pass3LegacyTaskAttempted: false,
|
|
811
|
-
pass3LegacyTaskSucceeded: false,
|
|
812
|
-
pass3LegacyStyleAttempted: false,
|
|
813
|
-
pass3LegacyStyleSucceeded: false,
|
|
814
|
-
pass4LlmAttempted: false,
|
|
815
|
-
pass4LlmSucceeded: false,
|
|
816
|
-
styleSource: "chitchat-default",
|
|
817
|
-
finalTaskType: "general",
|
|
818
|
-
finalConfidence: 0.9,
|
|
819
|
-
complexity,
|
|
820
|
-
complexityScore,
|
|
821
|
-
};
|
|
822
|
-
return {
|
|
823
|
-
...ctx,
|
|
824
|
-
taskType: "general",
|
|
825
|
-
domain: null,
|
|
826
|
-
confidence: 0.9,
|
|
827
|
-
outputStyle: "concise",
|
|
828
|
-
intentKind: "chitchat",
|
|
829
|
-
_brainData: null,
|
|
830
|
-
_intentTrace: intentTrace,
|
|
831
|
-
layers: [
|
|
832
|
-
...ctx.layers,
|
|
833
|
-
{
|
|
834
|
-
name: "intent-detection",
|
|
835
|
-
applied: true,
|
|
836
|
-
delta: "taskType=general,kind=chitchat,conf=0.90,domain=none,style=concise,pass0=continuation",
|
|
837
|
-
},
|
|
838
|
-
],
|
|
839
|
-
};
|
|
840
|
-
}
|
|
841
|
-
if (isStatusCheckQuestion(ctx.raw)) {
|
|
842
|
-
// A meta question about prior work → conversational continuation. Route to
|
|
843
|
-
// chitchat so layer4-gsd skips the "make a NEW plan + implement" scaffold
|
|
844
|
-
// and the agent answers from the existing thread context (session
|
|
845
|
-
// c6387d2c6e1b root cause). Mirrors the continuation branch above.
|
|
846
|
-
const { complexity, score: complexityScore } = scoreComplexity({
|
|
847
|
-
rawText: ctx.raw,
|
|
848
|
-
taskType: "general",
|
|
849
|
-
t0HitCount: 0,
|
|
850
|
-
hasMaxSprintsOne: false,
|
|
851
|
-
});
|
|
852
|
-
const intentTrace = {
|
|
853
|
-
pass1Reason: "pass0:status-check",
|
|
854
|
-
pass1Confidence: 0.9,
|
|
855
|
-
pass1TaskType: "general",
|
|
856
|
-
pass1Hit: true,
|
|
857
|
-
pass2Hit: false,
|
|
858
|
-
pass25ChitchatHit: false,
|
|
859
|
-
pass3UnifiedAttempted: false,
|
|
860
|
-
pass3UnifiedSucceeded: false,
|
|
861
|
-
pass3LegacyTaskAttempted: false,
|
|
862
|
-
pass3LegacyTaskSucceeded: false,
|
|
863
|
-
pass3LegacyStyleAttempted: false,
|
|
864
|
-
pass3LegacyStyleSucceeded: false,
|
|
865
|
-
pass4LlmAttempted: false,
|
|
866
|
-
pass4LlmSucceeded: false,
|
|
867
|
-
styleSource: "chitchat-default",
|
|
868
|
-
finalTaskType: "general",
|
|
869
|
-
finalConfidence: 0.9,
|
|
870
|
-
complexity,
|
|
871
|
-
complexityScore,
|
|
872
|
-
};
|
|
873
|
-
return {
|
|
874
|
-
...ctx,
|
|
875
|
-
taskType: "general",
|
|
876
|
-
domain: null,
|
|
877
|
-
confidence: 0.9,
|
|
878
|
-
outputStyle: "concise",
|
|
879
|
-
intentKind: "chitchat",
|
|
880
|
-
_brainData: null,
|
|
881
|
-
_intentTrace: intentTrace,
|
|
882
|
-
layers: [
|
|
883
|
-
...ctx.layers,
|
|
884
|
-
{
|
|
885
|
-
name: "intent-detection",
|
|
886
|
-
applied: true,
|
|
887
|
-
delta: "taskType=general,kind=chitchat,conf=0.90,domain=none,style=concise,pass0=status-check",
|
|
888
|
-
},
|
|
889
|
-
],
|
|
890
|
-
};
|
|
891
|
-
}
|
|
892
|
-
if (isTestGenerationTask(ctx.raw)) {
|
|
893
|
-
const domainPass0 = extractDomain("", ctx.raw);
|
|
894
|
-
const styleFromText = detectStyleFromText(ctx.raw) ?? "balanced";
|
|
895
|
-
const { complexity, score: complexityScore } = scoreComplexity({
|
|
896
|
-
rawText: ctx.raw,
|
|
897
|
-
taskType: "generate",
|
|
898
|
-
t0HitCount: 0,
|
|
899
|
-
hasMaxSprintsOne: false,
|
|
900
|
-
});
|
|
901
|
-
const intentTrace = {
|
|
902
|
-
pass1Reason: "pass0:test-generation",
|
|
903
|
-
pass1Confidence: 0.9,
|
|
904
|
-
pass1TaskType: "generate",
|
|
905
|
-
pass1Hit: true,
|
|
906
|
-
pass2Hit: false,
|
|
907
|
-
pass25ChitchatHit: false,
|
|
908
|
-
pass3UnifiedAttempted: false,
|
|
909
|
-
pass3UnifiedSucceeded: false,
|
|
910
|
-
pass3LegacyTaskAttempted: false,
|
|
911
|
-
pass3LegacyTaskSucceeded: false,
|
|
912
|
-
pass3LegacyStyleAttempted: false,
|
|
913
|
-
pass3LegacyStyleSucceeded: false,
|
|
914
|
-
pass4LlmAttempted: false,
|
|
915
|
-
pass4LlmSucceeded: false,
|
|
916
|
-
styleSource: detectStyleFromText(ctx.raw) ? "explicit-regex" : "classifier-default",
|
|
917
|
-
finalTaskType: "generate",
|
|
918
|
-
finalConfidence: 0.9,
|
|
919
|
-
complexity,
|
|
920
|
-
complexityScore,
|
|
921
|
-
};
|
|
922
|
-
return {
|
|
923
|
-
...ctx,
|
|
924
|
-
taskType: "generate",
|
|
925
|
-
domain: domainPass0,
|
|
926
|
-
confidence: 0.9,
|
|
927
|
-
outputStyle: styleFromText,
|
|
928
|
-
intentKind: "task",
|
|
929
|
-
_brainData: null,
|
|
930
|
-
_intentTrace: intentTrace,
|
|
931
|
-
layers: [
|
|
932
|
-
...ctx.layers,
|
|
933
|
-
{
|
|
934
|
-
name: "intent-detection",
|
|
935
|
-
applied: true,
|
|
936
|
-
delta: `taskType=generate,kind=task,conf=0.90,domain=${domainPass0 ?? "none"},style=${styleFromText},pass0=test-generation`,
|
|
937
|
-
},
|
|
938
|
-
],
|
|
939
|
-
};
|
|
940
|
-
}
|
|
941
|
-
if (isPerformanceRefactor(ctx.raw)) {
|
|
942
|
-
const domainPass0 = extractDomain("", ctx.raw);
|
|
943
|
-
const styleFromText = detectStyleFromText(ctx.raw) ?? "balanced";
|
|
944
|
-
const { complexity, score: complexityScore } = scoreComplexity({
|
|
945
|
-
rawText: ctx.raw,
|
|
946
|
-
taskType: "refactor",
|
|
947
|
-
t0HitCount: 0,
|
|
948
|
-
hasMaxSprintsOne: false,
|
|
949
|
-
});
|
|
950
|
-
const intentTrace = {
|
|
951
|
-
pass1Reason: "pass0:performance",
|
|
952
|
-
pass1Confidence: 0.85,
|
|
953
|
-
pass1TaskType: "refactor",
|
|
954
|
-
pass1Hit: true,
|
|
955
|
-
pass2Hit: false,
|
|
956
|
-
pass25ChitchatHit: false,
|
|
957
|
-
pass3UnifiedAttempted: false,
|
|
958
|
-
pass3UnifiedSucceeded: false,
|
|
959
|
-
pass3LegacyTaskAttempted: false,
|
|
960
|
-
pass3LegacyTaskSucceeded: false,
|
|
961
|
-
pass3LegacyStyleAttempted: false,
|
|
962
|
-
pass3LegacyStyleSucceeded: false,
|
|
963
|
-
pass4LlmAttempted: false,
|
|
964
|
-
pass4LlmSucceeded: false,
|
|
965
|
-
styleSource: detectStyleFromText(ctx.raw) ? "explicit-regex" : "classifier-default",
|
|
966
|
-
finalTaskType: "refactor",
|
|
967
|
-
finalConfidence: 0.85,
|
|
968
|
-
complexity,
|
|
969
|
-
complexityScore,
|
|
970
|
-
};
|
|
971
|
-
return {
|
|
972
|
-
...ctx,
|
|
973
|
-
taskType: "refactor",
|
|
974
|
-
domain: domainPass0,
|
|
975
|
-
confidence: 0.85,
|
|
976
|
-
outputStyle: styleFromText,
|
|
977
|
-
intentKind: "task",
|
|
978
|
-
_brainData: null,
|
|
979
|
-
_intentTrace: intentTrace,
|
|
980
|
-
layers: [
|
|
981
|
-
...ctx.layers,
|
|
982
|
-
{
|
|
983
|
-
name: "intent-detection",
|
|
984
|
-
applied: true,
|
|
985
|
-
delta: `taskType=refactor,kind=task,conf=0.85,domain=${domainPass0 ?? "none"},style=${styleFromText},pass0=performance`,
|
|
986
|
-
},
|
|
987
|
-
],
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
if (isGreenfieldBuildTask(ctx.raw)) {
|
|
991
|
-
const domainPass0 = extractDomain("", ctx.raw);
|
|
992
|
-
const styleFromText = detectStyleFromText(ctx.raw) ?? "balanced";
|
|
993
|
-
const { complexity, score: complexityScore } = scoreComplexity({
|
|
994
|
-
rawText: ctx.raw,
|
|
995
|
-
taskType: "build",
|
|
996
|
-
t0HitCount: 0,
|
|
997
|
-
hasMaxSprintsOne: false,
|
|
998
|
-
});
|
|
999
|
-
const intentTrace = {
|
|
1000
|
-
pass1Reason: "pass0:greenfield-build",
|
|
1001
|
-
pass1Confidence: 0.85,
|
|
1002
|
-
pass1TaskType: "build",
|
|
1003
|
-
pass1Hit: true,
|
|
719
|
+
// No model classifier wired (opts.llmFallback absent) → the regex
|
|
720
|
+
// classification cascade that used to run here was DELETED (2026-07-07,
|
|
721
|
+
// no-regex rule). Degrade to UNKNOWN (keep-tools): no PIL scaffold is
|
|
722
|
+
// imposed and the chat model still answers the turn, but nothing fabricates
|
|
723
|
+
// an intent from keyword regex.
|
|
724
|
+
console.error("[pil.layer1] no model classifier wired (opts.llmFallback absent) — UNKNOWN classification, NO regex cascade.");
|
|
725
|
+
return {
|
|
726
|
+
...ctx,
|
|
727
|
+
taskType: null,
|
|
728
|
+
domain: null,
|
|
729
|
+
confidence: 0,
|
|
730
|
+
outputStyle: null,
|
|
731
|
+
intentKind: "task",
|
|
732
|
+
_brainData: null,
|
|
733
|
+
_intentTrace: {
|
|
734
|
+
pass1Reason: "no-classifier-wired",
|
|
735
|
+
pass1Confidence: 0,
|
|
736
|
+
pass1TaskType: null,
|
|
737
|
+
pass1Hit: false,
|
|
1004
738
|
pass2Hit: false,
|
|
739
|
+
pass2Pattern: undefined,
|
|
1005
740
|
pass25ChitchatHit: false,
|
|
1006
741
|
pass3UnifiedAttempted: false,
|
|
1007
742
|
pass3UnifiedSucceeded: false,
|
|
@@ -1011,441 +746,15 @@ export async function layer1Intent(ctx, opts = {}) {
|
|
|
1011
746
|
pass3LegacyStyleSucceeded: false,
|
|
1012
747
|
pass4LlmAttempted: false,
|
|
1013
748
|
pass4LlmSucceeded: false,
|
|
1014
|
-
styleSource:
|
|
1015
|
-
finalTaskType:
|
|
1016
|
-
finalConfidence: 0
|
|
1017
|
-
complexity,
|
|
1018
|
-
complexityScore,
|
|
1019
|
-
}
|
|
1020
|
-
return {
|
|
1021
|
-
...ctx,
|
|
1022
|
-
taskType: "build",
|
|
1023
|
-
domain: domainPass0,
|
|
1024
|
-
confidence: 0.85,
|
|
1025
|
-
outputStyle: styleFromText,
|
|
1026
|
-
intentKind: "task",
|
|
1027
|
-
_brainData: null,
|
|
1028
|
-
_intentTrace: intentTrace,
|
|
1029
|
-
layers: [
|
|
1030
|
-
...ctx.layers,
|
|
1031
|
-
{
|
|
1032
|
-
name: "intent-detection",
|
|
1033
|
-
applied: true,
|
|
1034
|
-
delta: `taskType=build,kind=task,conf=0.85,domain=${domainPass0 ?? "none"},style=${styleFromText},pass0=greenfield-build`,
|
|
1035
|
-
},
|
|
1036
|
-
],
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
// Pass 1: local classifier.
|
|
1040
|
-
const result = classify(ctx.raw);
|
|
1041
|
-
const pass1TaskType = REASON_TO_TASK_TYPE[result.reason] ?? null;
|
|
1042
|
-
let taskType = pass1TaskType;
|
|
1043
|
-
let confidence = result.confidence;
|
|
1044
|
-
const domain = extractDomain(result.reason, ctx.raw);
|
|
1045
|
-
let outputStyle = null;
|
|
1046
|
-
let intentKind = null;
|
|
1047
|
-
let brainData = null;
|
|
1048
|
-
// Step-by-step trace — populated as each pass runs so cost reports can
|
|
1049
|
-
// attribute which pass actually decided the outcome.
|
|
1050
|
-
let pass2Pattern;
|
|
1051
|
-
let pass2Hit = false;
|
|
1052
|
-
let pass25ChitchatHit = false;
|
|
1053
|
-
let pass3UnifiedSucceeded = false;
|
|
1054
|
-
let pass3LegacyTaskAttempted = false;
|
|
1055
|
-
let pass3LegacyTaskSucceeded = false;
|
|
1056
|
-
let pass3LegacyStyleAttempted = false;
|
|
1057
|
-
let pass3LegacyStyleSucceeded = false;
|
|
1058
|
-
let styleSource = "none";
|
|
1059
|
-
// Pass 2: keyword fallback. Runs when classifier abstains OR when the
|
|
1060
|
-
// classifier match was a low-signal "general" (regex:short-message) OR
|
|
1061
|
-
// when the catch-all `regex:edit` / `regex:create-file` mapped a vague
|
|
1062
|
-
// "fix X" / "tạo X" verb to taskType=generate at sub-threshold confidence
|
|
1063
|
-
// (< 0.7). The catch-all v2 rules are deliberately weak (conf 0.55) so a
|
|
1064
|
-
// VN debug prompt like "ci/cd đang bị lỗi, check và fix cho tôi" still
|
|
1065
|
-
// routes through the keyword rescue here — which carries the bare-`lỗi`
|
|
1066
|
-
// and `\bfix\b` debug cues that the catch-all regex cannot tell apart
|
|
1067
|
-
// from generic edit.
|
|
1068
|
-
const lowSignal = taskType === "general" && result.reason === "regex:short-message";
|
|
1069
|
-
const catchAllRescue = taskType !== null && confidence < HIGH_CONF_THRESHOLD_PASS2 && CATCHALL_REASONS.has(result.reason);
|
|
1070
|
-
if (taskType === null || lowSignal || catchAllRescue) {
|
|
1071
|
-
for (const { pattern, taskType: kwType, confidence: kwConf } of KEYWORD_PATTERNS) {
|
|
1072
|
-
if (pattern.test(ctx.raw)) {
|
|
1073
|
-
taskType = kwType;
|
|
1074
|
-
confidence = kwConf;
|
|
1075
|
-
pass2Hit = true;
|
|
1076
|
-
pass2Pattern = pattern.source;
|
|
1077
|
-
break;
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
// Pass 2.5: hot-path chitchat short-circuit for ultra-short greetings
|
|
1082
|
-
// ("hi", "ok", "thanks", "ty") — mapped to taskType="general" without
|
|
1083
|
-
// burning a brain round-trip. Both conditions required (AND) so we don't
|
|
1084
|
-
// accidentally swallow phrases like "refactor this" or "fix the bug" that
|
|
1085
|
-
// happen to be short.
|
|
1086
|
-
//
|
|
1087
|
-
// WhoAmI v4.0: the outputStyle baseline from communication.brevity +
|
|
1088
|
-
// decision_speed is now wired below (getWhoAmIProfile/outputStyleFromProfile
|
|
1089
|
-
// at the classifier-default branch — it replaces "balanced" when no per-turn
|
|
1090
|
-
// signal resolves the style). Not applied at this chitchat hot-path: greetings
|
|
1091
|
-
// already force "concise" regardless of profile.
|
|
1092
|
-
const trimmed = ctx.raw.trim();
|
|
1093
|
-
const wordCount = trimmed.split(/\s+/).filter(Boolean).length;
|
|
1094
|
-
const noTaskSignal = taskType === null || (taskType === "general" && result.reason === "regex:short-message");
|
|
1095
|
-
if (noTaskSignal && trimmed.length < 10 && wordCount <= 2) {
|
|
1096
|
-
taskType = "general";
|
|
1097
|
-
confidence = 0.5;
|
|
1098
|
-
intentKind = "chitchat";
|
|
1099
|
-
outputStyle = "concise";
|
|
1100
|
-
pass25ChitchatHit = true;
|
|
1101
|
-
styleSource = "chitchat-default";
|
|
1102
|
-
}
|
|
1103
|
-
// Pass 2.6 — multi-word PURE social pleasantries ("cảm ơn bạn rất nhiều
|
|
1104
|
-
// nhé", "thank you so much", "ok great thanks") that the 2-word hot-path
|
|
1105
|
-
// above misses. Without this they fall through to the brain/LLM passes,
|
|
1106
|
-
// which classify intentKind inconsistently (live session 40c726a31a37
|
|
1107
|
-
// returned intentKind=null → toolCount=37, ~15-20K wasted tool-schema
|
|
1108
|
-
// tokens for a thank-you). isSocialPleasantry is strict (every token is
|
|
1109
|
-
// greeting/thanks/ack/filler vocab) so it can never swallow a task; the
|
|
1110
|
-
// hasActionableToolIntent veto is belt-and-suspenders. Classifying here is
|
|
1111
|
-
// also a cost win: it skips the brain round-trip (needsBrain requires
|
|
1112
|
-
// intentKind !== "chitchat").
|
|
1113
|
-
if (intentKind !== "chitchat" &&
|
|
1114
|
-
(taskType === null || taskType === "general") &&
|
|
1115
|
-
!hasActionableToolIntent(trimmed) &&
|
|
1116
|
-
isSocialPleasantry(trimmed)) {
|
|
1117
|
-
taskType = "general";
|
|
1118
|
-
confidence = 0.5;
|
|
1119
|
-
intentKind = "chitchat";
|
|
1120
|
-
outputStyle = "concise";
|
|
1121
|
-
pass25ChitchatHit = true;
|
|
1122
|
-
styleSource = "chitchat-default";
|
|
1123
|
-
}
|
|
1124
|
-
// Pass 3 UNIFIED: single /api/pil-context call replaces the multi-call
|
|
1125
|
-
// cascade (classifier rescue + style brain). Fires only when flag is on
|
|
1126
|
-
// AND local signal is weak (no taskType or low confidence) AND we haven't
|
|
1127
|
-
// already short-circuited to chitchat.
|
|
1128
|
-
const HIGH_CONF_THRESHOLD = 0.7;
|
|
1129
|
-
const needsBrain = isUnifiedPilEnabled() && intentKind !== "chitchat" && (taskType === null || confidence < HIGH_CONF_THRESHOLD);
|
|
1130
|
-
let unifiedFailed = false;
|
|
1131
|
-
if (needsBrain) {
|
|
1132
|
-
// Step 8 (ee-anti-mu): enrich the raw passed to pilContext for sessions that may have
|
|
1133
|
-
// experienced compaction (or any sessionId-bearing turn) so the brain sees EE checkpoints
|
|
1134
|
-
// + the PRESERVE_FULL_CONTEXT veto token. Unconditional for any turn with sessionId
|
|
1135
|
-
// (covers _compactionStats.count > 0 or step > K cases even if local conf high).
|
|
1136
|
-
let brainRaw = ctx.raw;
|
|
1137
|
-
if (ctx.sessionId) {
|
|
1138
|
-
brainRaw =
|
|
1139
|
-
ctx.raw +
|
|
1140
|
-
' [EE task checkpoints ("Context checkpoint summary" with ✔ DONE) from prior compactions are available via the ee.query tool. ' +
|
|
1141
|
-
"To keep full tool history this turn when you see pre-warn or compaction note, emit exact literal PRESERVE_FULL_CONTEXT in reasoning or assistant note. " +
|
|
1142
|
-
'Self-check "task finished?" or "compacted yet this turn?" using the checkpoints.]';
|
|
1143
|
-
}
|
|
1144
|
-
const resp = await pilContext(brainRaw, {
|
|
1145
|
-
projectCtx: domain ? { domain } : undefined,
|
|
1146
|
-
budgetMs: getUnifiedPilBudgetMs(),
|
|
1147
|
-
});
|
|
1148
|
-
if (resp) {
|
|
1149
|
-
if (resp.taskType)
|
|
1150
|
-
taskType = resp.taskType;
|
|
1151
|
-
if (resp.intentKind)
|
|
1152
|
-
intentKind = resp.intentKind;
|
|
1153
|
-
if (resp.outputStyle) {
|
|
1154
|
-
outputStyle = resp.outputStyle;
|
|
1155
|
-
styleSource = "brain-unified";
|
|
1156
|
-
}
|
|
1157
|
-
if (resp.confidence)
|
|
1158
|
-
confidence = resp.confidence;
|
|
1159
|
-
brainData = {
|
|
1160
|
-
t0_principles: resp.t0_principles,
|
|
1161
|
-
t1_rules: resp.t1_rules,
|
|
1162
|
-
t2_patterns: resp.t2_patterns,
|
|
1163
|
-
retrieval_skipped_reason: resp.retrieval_skipped_reason,
|
|
1164
|
-
};
|
|
1165
|
-
pass3UnifiedSucceeded = true;
|
|
1166
|
-
}
|
|
1167
|
-
else {
|
|
1168
|
-
unifiedFailed = true;
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
// Pass 4 LLM FALLBACK: fires when the brain's confidence is below the
|
|
1172
|
-
// hot-path skip threshold (HIGH_CONF_THRESHOLD = 0.7).
|
|
1173
|
-
//
|
|
1174
|
-
// Earlier iteration tried a tighter floor (0.5) to skip Pass 4 on "good
|
|
1175
|
-
// enough" brain answers, but session eda85985dce9 showed the brain
|
|
1176
|
-
// routinely returns 0.55–0.65 for ambiguous prompts like "fix CI fail"
|
|
1177
|
-
// — and at that confidence band the brain's answer is wrong often
|
|
1178
|
-
// enough that skipping Pass 4 reintroduces the classification leak we
|
|
1179
|
-
// shipped Pass 4 to fix. The ~1s LLM round-trip is the price of
|
|
1180
|
-
// correctness on borderline turns; high-confidence turns (brain ≥ 0.7)
|
|
1181
|
-
// bypass Pass 4 entirely so the cost only hits weak signals.
|
|
1182
|
-
let pass4LlmAttempted = false;
|
|
1183
|
-
let pass4LlmSucceeded = false;
|
|
1184
|
-
const llmFallbackEligible = !!opts.llmFallback &&
|
|
1185
|
-
intentKind !== "chitchat" &&
|
|
1186
|
-
(taskType === null || unifiedFailed || confidence < HIGH_CONF_THRESHOLD);
|
|
1187
|
-
if (llmFallbackEligible) {
|
|
1188
|
-
pass4LlmAttempted = true;
|
|
1189
|
-
try {
|
|
1190
|
-
const llmRes = await opts.llmFallback(ctx.raw);
|
|
1191
|
-
if (llmRes) {
|
|
1192
|
-
pass4LlmSucceeded = true;
|
|
1193
|
-
taskType = llmRes.taskType;
|
|
1194
|
-
confidence = llmRes.confidence;
|
|
1195
|
-
// Pass 4 is reached ONLY when intentKind !== "chitchat" (see
|
|
1196
|
-
// llmFallbackEligible above) — every genuine social pleasantry was
|
|
1197
|
-
// already short-circuited upstream by Pass 0 (continuation /
|
|
1198
|
-
// status-check), Pass 2.5 (ultra-short greeting) and Pass 2.6
|
|
1199
|
-
// (isSocialPleasantry). So a taskType="general" result HERE is a
|
|
1200
|
-
// SUBSTANTIVE question that slipped past the greeting detectors —
|
|
1201
|
-
// NOT chitchat. Live repro (session b51ba653e890): "bạn đang được
|
|
1202
|
-
// chạy bên trong CLI này thì ... CLI tác động thế nào đến bạn?" was
|
|
1203
|
-
// mapped general→chitchat, which nuked the entire action toolset
|
|
1204
|
-
// (message-processor.ts:1285 `isChitchat && !_priorTurnHadTools →
|
|
1205
|
-
// {}`). The model announced "Tôi cần điều tra code ... không đoán"
|
|
1206
|
-
// (Evidence-First contract) but had only respond_general — no
|
|
1207
|
-
// read_file/grep/bash to act with → narration → respond_general
|
|
1208
|
-
// spam-abort, zero answer. A general question is tool-capable:
|
|
1209
|
-
// classify it "task" so the toolset survives. Per the established
|
|
1210
|
-
// keep-tools precedent in this file (TOOL_NAME_RE veto), a false
|
|
1211
|
-
// "task" merely re-adds ~1.5K tokens of tool schema, while a false
|
|
1212
|
-
// "chitchat" BREAKS the turn.
|
|
1213
|
-
intentKind = "task";
|
|
1214
|
-
if (llmRes.outputStyle) {
|
|
1215
|
-
outputStyle = llmRes.outputStyle;
|
|
1216
|
-
styleSource = "brain-unified"; // closest existing source — LLM acts in same role
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
catch (err) {
|
|
1221
|
-
console.error(`[pil.layer1] LLM fallback failed: ${err?.message}`);
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
// Pass 3 LEGACY FALLBACK: only runs when flag off.
|
|
1225
|
-
// Cost optimization: when unified call FAILED, we skip the legacy brain
|
|
1226
|
-
// round-trips entirely. The unified pilContext already tried the same
|
|
1227
|
-
// backend; a second classifyViaBrain ~1.5s after a failure almost always
|
|
1228
|
-
// fails too, wasting tokens and ~2.3s of wall time. The cheap regex style
|
|
1229
|
-
// detector still runs below to recover explicit "ngắn gọn"/"detailed" cues.
|
|
1230
|
-
const runLegacyBrain = !isUnifiedPilEnabled();
|
|
1231
|
-
let legacyBrainAttempted = false;
|
|
1232
|
-
if (runLegacyBrain) {
|
|
1233
|
-
if (taskType === null) {
|
|
1234
|
-
legacyBrainAttempted = true;
|
|
1235
|
-
pass3LegacyTaskAttempted = true;
|
|
1236
|
-
// 4P-2: neutral bridge-classifier prompt. Earlier wording biased the
|
|
1237
|
-
// LLM toward `refactor` for any code touch (baseline trace
|
|
1238
|
-
// taskType=refactor,conf=0.75 on a clear feature-add). The rewrite:
|
|
1239
|
-
// - Lists categories in neutral order (analyze first, refactor 4th).
|
|
1240
|
-
// - Restricts refactor to explicit restructure verbs.
|
|
1241
|
-
// - Tells the model to prefer 'general' over guessing when ambiguous.
|
|
1242
|
-
// - Clarifies that feature additions are 'generate' even when they
|
|
1243
|
-
// touch existing files.
|
|
1244
|
-
// 0.7 confidence threshold for Pass 2 keyword override remains
|
|
1245
|
-
// unchanged (HIGH_CONF_THRESHOLD_PASS2 above).
|
|
1246
|
-
const brainRaw = await classifyViaBrain(`You are a multilingual prompt classifier. The user's prompt may be in English, Vietnamese, or a mix of both.
|
|
1247
|
-
Classify the prompt's INTENT (not its language). Reply with TWO lowercase words separated by a comma: <category>,<style>
|
|
1248
|
-
|
|
1249
|
-
Category — pick ONE (listed in neutral order, no precedence):
|
|
1250
|
-
analyze — explain / inspect / review existing code (giải thích, phân tích, review)
|
|
1251
|
-
debug — fix a bug or investigate failure (sửa lỗi, fix bug, lỗi, traceback)
|
|
1252
|
-
generate — create new code/file or add new behavior (tạo, sinh code, viết function mới, thêm)
|
|
1253
|
-
refactor — restructure existing code (tái cấu trúc, refactor)
|
|
1254
|
-
plan — design / roadmap / architecture (kế hoạch, thiết kế, kiến trúc)
|
|
1255
|
-
documentation — write docs/comments (viết docs, comment, jsdoc)
|
|
1256
|
-
general — chitchat OR unclear / ambiguous coding intent
|
|
1257
|
-
|
|
1258
|
-
Rules (Phase 4 4P-2 disambiguation):
|
|
1259
|
-
- Only return refactor when the user EXPLICITLY uses one of: rename, restructure, reorganize, extract, inline, move, migrate, reshape — applied to EXISTING code WITHOUT adding new behavior.
|
|
1260
|
-
- Feature additions ('add flag', 'thêm', 'create endpoint', 'thêm option'), changing a DEFAULT value, adding tests, or improving coverage are 'generate' — NOT refactor.
|
|
1261
|
-
- 'improve', 'change', 'update', 'modify', 'đổi', 'cải thiện' alone do NOT imply refactor — pick the specific category by what the change actually does.
|
|
1262
|
-
- When the request is ambiguous, prefer 'general' over guessing refactor.
|
|
1263
|
-
|
|
1264
|
-
Negative examples (NOT refactor):
|
|
1265
|
-
- "đổi default --max-tool-rounds 8 sang 12" → generate
|
|
1266
|
-
- "improve test coverage" → generate
|
|
1267
|
-
- "tại sao X trả empty" → analyze
|
|
1268
|
-
- "fix CI failing" → debug
|
|
1269
|
-
|
|
1270
|
-
Style — pick ONE:
|
|
1271
|
-
concise (ngắn gọn) | balanced (cân bằng) | detailed (chi tiết)
|
|
1272
|
-
|
|
1273
|
-
Examples:
|
|
1274
|
-
"Refactor this function" → refactor,balanced
|
|
1275
|
-
"tại sao test fail" → debug,balanced
|
|
1276
|
-
"thiết kế hệ thống auth" → plan,detailed
|
|
1277
|
-
"thêm flag --foo" → generate,concise
|
|
1278
|
-
"hi" → general,concise
|
|
1279
|
-
|
|
1280
|
-
Prompt: "${ctx.raw.slice(0, 500)}"`, 1500);
|
|
1281
|
-
if (brainRaw) {
|
|
1282
|
-
pass3LegacyTaskSucceeded = true;
|
|
1283
|
-
const lower = brainRaw.toLowerCase();
|
|
1284
|
-
// 4P-2: match `general` BEFORE the coding-category list so an
|
|
1285
|
-
// ambiguous prompt the model marked `general,*` doesn't accidentally
|
|
1286
|
-
// fall through to a substring hit later. `none` kept as legacy alias.
|
|
1287
|
-
if (/\bgeneral\b/.test(lower) || /\bnone\b/.test(lower)) {
|
|
1288
|
-
taskType = "general";
|
|
1289
|
-
confidence = 0.6;
|
|
1290
|
-
intentKind = "chitchat";
|
|
1291
|
-
if (outputStyle === null) {
|
|
1292
|
-
outputStyle = "concise";
|
|
1293
|
-
styleSource = "chitchat-default";
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
else {
|
|
1297
|
-
const matched = VALID_TASK_TYPES.find((t) => lower.includes(t));
|
|
1298
|
-
if (matched) {
|
|
1299
|
-
taskType = matched;
|
|
1300
|
-
confidence = 0.55;
|
|
1301
|
-
intentKind = "task";
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
const styleMatched = VALID_STYLES.find((s) => lower.includes(s));
|
|
1305
|
-
if (styleMatched) {
|
|
1306
|
-
outputStyle = styleMatched;
|
|
1307
|
-
styleSource = "brain-legacy";
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
// Pass 3.5: regex style detection — free, always runs before any brain call.
|
|
1312
|
-
// Catches explicit user cues ("ngắn gọn", "chi tiết", "step by step").
|
|
1313
|
-
if (outputStyle === null) {
|
|
1314
|
-
const regexStyle = detectStyleFromText(ctx.raw);
|
|
1315
|
-
if (regexStyle) {
|
|
1316
|
-
outputStyle = regexStyle;
|
|
1317
|
-
styleSource = "explicit-regex";
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
// Pass 3b: style brain call — only when task detection ITSELF needed the
|
|
1321
|
-
// brain (pass3LegacyTaskAttempted). When pass1 or pass2 already decided
|
|
1322
|
-
// the task cheaply, the 800ms style call adds no signal (confirmed by
|
|
1323
|
-
// 112/112 wasted calls in production — 100% returned styleSource=none).
|
|
1324
|
-
// Default to "balanced" instead: clear, cheap, and accurate for most
|
|
1325
|
-
// coding turns.
|
|
1326
|
-
if (outputStyle === null && taskType !== null) {
|
|
1327
|
-
if (pass3LegacyTaskAttempted) {
|
|
1328
|
-
legacyBrainAttempted = true;
|
|
1329
|
-
pass3LegacyStyleAttempted = true;
|
|
1330
|
-
const brainRawStyle = await classifyViaBrain(`Detect the user's preferred output style. The prompt may be EN or VN.
|
|
1331
|
-
Reply with ONE word: concise (ngắn gọn) | balanced (bình thường) | detailed (chi tiết).
|
|
1332
|
-
|
|
1333
|
-
Prompt: "${ctx.raw.slice(0, 300)}"`, 800);
|
|
1334
|
-
if (brainRawStyle) {
|
|
1335
|
-
pass3LegacyStyleSucceeded = true;
|
|
1336
|
-
const styleMatched = VALID_STYLES.find((s) => brainRawStyle.toLowerCase().includes(s));
|
|
1337
|
-
if (styleMatched) {
|
|
1338
|
-
outputStyle = styleMatched;
|
|
1339
|
-
styleSource = "brain-legacy";
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
else if (opts.profileStyleBaseline) {
|
|
1344
|
-
// WhoAmI v4.0 baseline: a standing communication.brevity/decision_speed
|
|
1345
|
-
// preference (computed once in the pipeline from the on-device profile)
|
|
1346
|
-
// fills in when no per-turn signal resolved the style. Per-turn detection
|
|
1347
|
-
// above still wins (override); this only replaces the generic "balanced".
|
|
1348
|
-
outputStyle = opts.profileStyleBaseline;
|
|
1349
|
-
styleSource = "whoami-profile";
|
|
1350
|
-
}
|
|
1351
|
-
else {
|
|
1352
|
-
outputStyle = "balanced";
|
|
1353
|
-
styleSource = "classifier-default";
|
|
1354
|
-
}
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
else if (unifiedFailed && outputStyle === null) {
|
|
1358
|
-
// Cheap rescue path when unified PIL is enabled but its call failed:
|
|
1359
|
-
// run only the free regex style detector. The L6 brain-rescue call is
|
|
1360
|
-
// suppressed below by the `_brainData` sentinel so we don't repeat the
|
|
1361
|
-
// same network round-trip that just timed out.
|
|
1362
|
-
const regexStyle = detectStyleFromText(ctx.raw);
|
|
1363
|
-
if (regexStyle) {
|
|
1364
|
-
outputStyle = regexStyle;
|
|
1365
|
-
styleSource = "explicit-regex";
|
|
1366
|
-
}
|
|
1367
|
-
}
|
|
1368
|
-
if (intentKind === null && taskType !== null && taskType !== "general") {
|
|
1369
|
-
intentKind = "task";
|
|
1370
|
-
}
|
|
1371
|
-
// Safety net (harness 817e508f57ee): an explicit command/tool-execution
|
|
1372
|
-
// request must NEVER be chitchat. Chitchat drops the whole toolset (incl.
|
|
1373
|
-
// bash) in message-processor, so a "run this command" turn would leave the
|
|
1374
|
-
// agent unable to act. Only ever UPGRADES chitchat → task (never the
|
|
1375
|
-
// reverse), so the token-saving for genuine greetings is preserved.
|
|
1376
|
-
if (intentKind === "chitchat" && hasActionableToolIntent(ctx.raw)) {
|
|
1377
|
-
intentKind = "task";
|
|
1378
|
-
}
|
|
1379
|
-
// L6 brain-rescue suppression sentinel. L6 only checks truthiness of
|
|
1380
|
-
// _brainData to decide whether to spend another 50ms brain round-trip on
|
|
1381
|
-
// style detection. If we either (a) succeeded with unified pilContext,
|
|
1382
|
-
// (b) failed unified (network already down), or (c) attempted a legacy
|
|
1383
|
-
// brain call here, then L6 has nothing new to learn — set a sentinel.
|
|
1384
|
-
const brainDataOut = brainData ??
|
|
1385
|
-
(unifiedFailed || legacyBrainAttempted
|
|
1386
|
-
? {
|
|
1387
|
-
t0_principles: [],
|
|
1388
|
-
t1_rules: [],
|
|
1389
|
-
t2_patterns: [],
|
|
1390
|
-
retrieval_skipped_reason: unifiedFailed ? "unified-failed" : "legacy-attempted",
|
|
1391
|
-
}
|
|
1392
|
-
: null);
|
|
1393
|
-
// pass1Hit = Pass 1 alone decided the final outcome (no later pass overrode).
|
|
1394
|
-
// Note: chitchat short-circuit overrides Pass 1, so we exclude that case.
|
|
1395
|
-
const pass1Hit = pass1TaskType !== null &&
|
|
1396
|
-
taskType === pass1TaskType &&
|
|
1397
|
-
!pass2Hit &&
|
|
1398
|
-
!pass25ChitchatHit &&
|
|
1399
|
-
!pass3UnifiedSucceeded &&
|
|
1400
|
-
!pass3LegacyTaskSucceeded;
|
|
1401
|
-
const { complexity, score: complexityScore } = scoreComplexity({
|
|
1402
|
-
rawText: ctx.raw,
|
|
1403
|
-
taskType,
|
|
1404
|
-
t0HitCount: 0, // TODO P2: feed from prior-run state.md if available
|
|
1405
|
-
hasMaxSprintsOne: false, // TODO P2: thread CLI flag down through ctx
|
|
1406
|
-
});
|
|
1407
|
-
const intentTrace = {
|
|
1408
|
-
pass1Reason: result.reason,
|
|
1409
|
-
pass1Confidence: result.confidence,
|
|
1410
|
-
pass1TaskType,
|
|
1411
|
-
pass1Hit,
|
|
1412
|
-
pass2Hit,
|
|
1413
|
-
pass2Pattern,
|
|
1414
|
-
pass25ChitchatHit,
|
|
1415
|
-
pass3UnifiedAttempted: needsBrain,
|
|
1416
|
-
pass3UnifiedSucceeded,
|
|
1417
|
-
pass3LegacyTaskAttempted,
|
|
1418
|
-
pass3LegacyTaskSucceeded,
|
|
1419
|
-
pass3LegacyStyleAttempted,
|
|
1420
|
-
pass3LegacyStyleSucceeded,
|
|
1421
|
-
pass4LlmAttempted,
|
|
1422
|
-
pass4LlmSucceeded,
|
|
1423
|
-
styleSource,
|
|
1424
|
-
finalTaskType: taskType,
|
|
1425
|
-
finalConfidence: confidence,
|
|
1426
|
-
complexity,
|
|
1427
|
-
complexityScore,
|
|
1428
|
-
};
|
|
1429
|
-
return {
|
|
1430
|
-
...ctx,
|
|
1431
|
-
taskType,
|
|
1432
|
-
domain,
|
|
1433
|
-
confidence,
|
|
1434
|
-
outputStyle,
|
|
1435
|
-
intentKind,
|
|
1436
|
-
_brainData: brainDataOut,
|
|
1437
|
-
_intentTrace: intentTrace,
|
|
749
|
+
styleSource: "none",
|
|
750
|
+
finalTaskType: null,
|
|
751
|
+
finalConfidence: 0,
|
|
752
|
+
complexity: "medium",
|
|
753
|
+
complexityScore: 0,
|
|
754
|
+
},
|
|
1438
755
|
layers: [
|
|
1439
756
|
...ctx.layers,
|
|
1440
|
-
{
|
|
1441
|
-
name: "intent-detection",
|
|
1442
|
-
applied: taskType !== null,
|
|
1443
|
-
delta: taskType !== null
|
|
1444
|
-
? `taskType=${taskType},kind=${intentKind ?? "unknown"},conf=${confidence.toFixed(2)},domain=${domain ?? "none"},style=${outputStyle ?? "none"},unified=${brainData ? "ok" : unifiedFailed ? "fail" : "skip"},llm=${pass4LlmSucceeded ? "ok" : pass4LlmAttempted ? "fail" : "skip"}`
|
|
1445
|
-
: unifiedFailed
|
|
1446
|
-
? `taskType=null,unified=fail,llm=${pass4LlmSucceeded ? "ok" : pass4LlmAttempted ? "fail" : "skip"}`
|
|
1447
|
-
: null,
|
|
1448
|
-
},
|
|
757
|
+
{ name: "intent-detection", applied: false, delta: "no-model-classifier — UNKNOWN, NO regex cascade" },
|
|
1449
758
|
],
|
|
1450
759
|
};
|
|
1451
760
|
}
|