muonroi-cli 1.8.5 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/agent-harness-core/src/event-filter.js +11 -0
- package/dist/packages/agent-harness-core/src/event-redact.js +7 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +20 -4
- package/dist/packages/agent-harness-core/src/event-tee.js +32 -5
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +14 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +86 -10
- package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
- package/dist/packages/agent-harness-core/src/protocol.d.ts +24 -2
- package/dist/src/agent-harness/mock-model.d.ts +10 -0
- package/dist/src/agent-harness/mock-model.js +6 -2
- package/dist/src/chat/chat-keychain.d.ts +7 -12
- package/dist/src/chat/chat-keychain.js +19 -86
- package/dist/src/cli/keys.d.ts +8 -45
- package/dist/src/cli/keys.js +18 -324
- package/dist/src/council/clarifier.d.ts +4 -2
- package/dist/src/council/clarifier.js +158 -36
- package/dist/src/council/debate-planner.js +3 -2
- package/dist/src/council/debate.js +59 -5
- package/dist/src/council/index.d.ts +23 -0
- package/dist/src/council/index.js +37 -2
- package/dist/src/council/llm.d.ts +62 -0
- package/dist/src/council/llm.js +123 -23
- package/dist/src/council/panel-select.js +13 -3
- package/dist/src/council/planner.js +17 -0
- package/dist/src/council/preflight.d.ts +10 -0
- package/dist/src/council/preflight.js +36 -0
- package/dist/src/council/prompts.d.ts +9 -1
- package/dist/src/council/prompts.js +23 -6
- package/dist/src/council/types.d.ts +10 -0
- package/dist/src/ee/auth.d.ts +19 -0
- package/dist/src/ee/auth.js +39 -0
- package/dist/src/ee/client.js +28 -3
- package/dist/src/ee/ee-onboarding.js +6 -26
- package/dist/src/flow/compaction/compress.d.ts +2 -2
- package/dist/src/flow/compaction/compress.js +21 -8
- package/dist/src/flow/compaction/extract.d.ts +3 -3
- package/dist/src/flow/compaction/extract.js +6 -6
- package/dist/src/flow/compaction/index.d.ts +2 -1
- package/dist/src/flow/compaction/index.js +29 -3
- package/dist/src/flow/compaction/progress.d.ts +35 -0
- package/dist/src/flow/compaction/progress.js +35 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/flags.d.ts +11 -0
- package/dist/src/gsd/flags.js +19 -0
- package/dist/src/gsd/plan-council.js +104 -72
- package/dist/src/gsd/verdict-schema.d.ts +1 -1
- package/dist/src/headless/council-answers.js +4 -0
- package/dist/src/index.js +129 -260
- package/dist/src/lsp/builtins.js +3 -1
- package/dist/src/lsp/manager.d.ts +5 -1
- package/dist/src/lsp/manager.js +249 -3
- package/dist/src/lsp/npm-cache.d.ts +11 -1
- package/dist/src/lsp/npm-cache.js +17 -1
- package/dist/src/lsp/runtime.d.ts +6 -1
- package/dist/src/lsp/runtime.js +17 -1
- package/dist/src/lsp/types.d.ts +83 -1
- package/dist/src/lsp/types.js +10 -0
- package/dist/src/mcp/client-pool.js +43 -15
- package/dist/src/mcp/lsp-tools.d.ts +5 -1
- package/dist/src/mcp/lsp-tools.js +93 -2
- package/dist/src/mcp/mcp-keychain.d.ts +3 -5
- package/dist/src/mcp/mcp-keychain.js +9 -49
- package/dist/src/mcp/setup-guide-text.d.ts +1 -1
- package/dist/src/mcp/setup-guide-text.js +22 -2
- package/dist/src/mcp/tools-server.d.ts +10 -0
- package/dist/src/mcp/tools-server.js +10 -2
- package/dist/src/models/catalog.json +19 -19
- package/dist/src/orchestrator/ask-user.d.ts +61 -0
- package/dist/src/orchestrator/ask-user.js +65 -0
- package/dist/src/orchestrator/compaction.d.ts +2 -3
- package/dist/src/orchestrator/compaction.js +8 -8
- package/dist/src/orchestrator/council-manager.js +9 -8
- package/dist/src/orchestrator/council-request.d.ts +49 -0
- package/dist/src/orchestrator/council-request.js +62 -0
- package/dist/src/orchestrator/interactive-pause.d.ts +26 -0
- package/dist/src/orchestrator/interactive-pause.js +36 -0
- package/dist/src/orchestrator/message-processor.d.ts +4 -0
- package/dist/src/orchestrator/message-processor.js +26 -8
- package/dist/src/orchestrator/orchestrator.d.ts +25 -0
- package/dist/src/orchestrator/orchestrator.js +204 -50
- package/dist/src/orchestrator/preprocessor.js +2 -2
- package/dist/src/orchestrator/safety-askcard.d.ts +1 -1
- package/dist/src/orchestrator/safety-askcard.js +5 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +5 -0
- package/dist/src/orchestrator/safety-intercept.js +7 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +8 -1
- package/dist/src/orchestrator/stall-watchdog.js +24 -3
- package/dist/src/orchestrator/stream-runner.d.ts +13 -3
- package/dist/src/orchestrator/stream-runner.js +54 -21
- package/dist/src/orchestrator/tool-engine.d.ts +19 -0
- package/dist/src/orchestrator/tool-engine.js +241 -25
- package/dist/src/orchestrator/turn-watchdog.d.ts +7 -0
- package/dist/src/orchestrator/turn-watchdog.js +38 -9
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +6 -4
- package/dist/src/pil/discovery.d.ts +1 -1
- package/dist/src/pil/discovery.js +2 -2
- package/dist/src/pil/layer1_5-complexity-size.d.ts +7 -0
- package/dist/src/pil/layer1_5-complexity-size.js +31 -5
- package/dist/src/pil/llm-classify.d.ts +78 -3
- package/dist/src/pil/llm-classify.js +351 -111
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +7 -0
- package/dist/src/pil/pipeline.js +2 -0
- package/dist/src/pil/repo-grounding-probe.d.ts +15 -0
- package/dist/src/pil/repo-grounding-probe.js +136 -0
- package/dist/src/pil/repo-structure-hints.d.ts +7 -0
- package/dist/src/pil/repo-structure-hints.js +45 -0
- package/dist/src/product-loop/artifact-io.js +4 -0
- package/dist/src/product-loop/criteria-seed.d.ts +51 -0
- package/dist/src/product-loop/criteria-seed.js +200 -0
- package/dist/src/product-loop/discovery-interview.d.ts +9 -0
- package/dist/src/product-loop/discovery-interview.js +37 -18
- package/dist/src/product-loop/discovery-recommender.js +2 -1
- package/dist/src/product-loop/discovery-schema.js +14 -1
- package/dist/src/product-loop/discovery-triage.d.ts +23 -0
- package/dist/src/product-loop/discovery-triage.js +109 -0
- package/dist/src/product-loop/gather.js +150 -2
- package/dist/src/product-loop/index.js +7 -0
- package/dist/src/product-loop/loop-driver.js +21 -8
- package/dist/src/product-loop/phase-plan.d.ts +16 -0
- package/dist/src/product-loop/phase-plan.js +42 -4
- package/dist/src/product-loop/phase-rituals.d.ts +3 -0
- package/dist/src/product-loop/phase-rituals.js +8 -3
- package/dist/src/product-loop/phase-runner.js +30 -11
- package/dist/src/product-loop/plan-adherence-review.d.ts +26 -0
- package/dist/src/product-loop/plan-adherence-review.js +144 -0
- package/dist/src/product-loop/sprint-runner.d.ts +62 -0
- package/dist/src/product-loop/sprint-runner.js +309 -8
- package/dist/src/product-loop/types.d.ts +25 -0
- package/dist/src/providers/anthropic.d.ts +9 -8
- package/dist/src/providers/anthropic.js +13 -47
- package/dist/src/providers/auth/grok-oauth.d.ts +1 -0
- package/dist/src/providers/auth/grok-oauth.js +30 -5
- package/dist/src/providers/auth/openai-oauth.d.ts +1 -0
- package/dist/src/providers/auth/openai-oauth.js +14 -0
- package/dist/src/providers/auth/token-store.d.ts +9 -9
- package/dist/src/providers/auth/token-store.js +8 -70
- package/dist/src/providers/auth/types.d.ts +8 -0
- package/dist/src/providers/env-store.d.ts +17 -0
- package/dist/src/providers/env-store.js +228 -0
- package/dist/src/providers/keychain.d.ts +21 -17
- package/dist/src/providers/keychain.js +124 -135
- package/dist/src/providers/runtime.d.ts +24 -9
- package/dist/src/providers/runtime.js +48 -37
- package/dist/src/providers/strategies/thinking-mode.js +9 -1
- package/dist/src/providers/strategies/xai.strategy.js +27 -0
- package/dist/src/providers/warm.d.ts +65 -0
- package/dist/src/providers/warm.js +145 -0
- package/dist/src/self-qa/agentic-loop.js +3 -2
- package/dist/src/storage/transcript.js +56 -2
- package/dist/src/tools/git-safety.d.ts +19 -0
- package/dist/src/tools/git-safety.js +168 -0
- package/dist/src/tools/native-tools.d.ts +1 -1
- package/dist/src/tools/native-tools.js +76 -1
- package/dist/src/tools/registry.d.ts +17 -0
- package/dist/src/tools/registry.js +116 -1
- package/dist/src/types/index.d.ts +29 -1
- package/dist/src/ui/app.js +67 -4
- package/dist/src/ui/components/agent-rail-activities.d.ts +26 -0
- package/dist/src/ui/components/agent-rail-activities.js +47 -0
- package/dist/src/ui/components/compact-progress-card.d.ts +24 -0
- package/dist/src/ui/components/compact-progress-card.js +42 -0
- package/dist/src/ui/components/council-phase-timeline.js +17 -2
- package/dist/src/ui/components/council-question-card.js +1 -0
- package/dist/src/ui/components/message-view.d.ts +15 -0
- package/dist/src/ui/components/message-view.js +50 -1
- package/dist/src/ui/components/tool-group.d.ts +15 -3
- package/dist/src/ui/components/tool-group.js +69 -11
- package/dist/src/ui/containers/modals-layer.d.ts +2 -1
- package/dist/src/ui/containers/modals-layer.js +2 -2
- package/dist/src/ui/council-harness-event.d.ts +57 -0
- package/dist/src/ui/council-harness-event.js +46 -0
- package/dist/src/ui/heartbeat-debug.d.ts +29 -0
- package/dist/src/ui/heartbeat-debug.js +45 -0
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/model-picker-modal.d.ts +8 -18
- package/dist/src/ui/modals/model-picker-modal.js +8 -10
- package/dist/src/ui/slash/ee.js +81 -0
- package/dist/src/ui/slash/menu-items.js +11 -2
- package/dist/src/ui/use-app-logic.js +354 -224
- package/dist/src/ui/utils/agent-activities.d.ts +39 -0
- package/dist/src/ui/utils/agent-activities.js +96 -0
- package/dist/src/ui/utils/group-tool-entries.d.ts +26 -0
- package/dist/src/ui/utils/group-tool-entries.js +111 -0
- package/dist/src/ui/utils/tool-summary.d.ts +21 -0
- package/dist/src/ui/utils/tool-summary.js +91 -0
- package/dist/src/utils/event-loop-monitor.d.ts +85 -0
- package/dist/src/utils/event-loop-monitor.js +107 -0
- package/dist/src/utils/llm-deadline.d.ts +14 -0
- package/dist/src/utils/llm-deadline.js +19 -0
- package/dist/src/utils/loop-profiler.d.ts +102 -0
- package/dist/src/utils/loop-profiler.js +202 -0
- package/dist/src/utils/settings.d.ts +27 -0
- package/dist/src/utils/settings.js +38 -2
- package/dist/src/utils/side-question.d.ts +1 -2
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/verify/entrypoint.js +51 -16
- package/dist/src/verify/orchestrator.d.ts +1 -1
- package/dist/src/verify/orchestrator.js +20 -3
- package/package.json +1 -2
- package/dist/src/cli/bw-vault.d.ts +0 -55
- package/dist/src/cli/bw-vault.js +0 -133
- package/dist/src/mcp/ee-tools.d.ts +0 -46
- package/dist/src/mcp/ee-tools.js +0 -194
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
* one imperative line targeting that phase's most damaging failure mode. Kept
|
|
38
38
|
* tight (primacy matters more than detail; tokens are the cost).
|
|
39
39
|
*/
|
|
40
|
-
export declare const AGENT_OPERATING_CONTRACT = "[AGENT OPERATING CONTRACT \u2014 read first; applies to every step]\n\n1. BEFORE ACTING: do only what was asked. Never assume scope or facts \u2014 if ambiguous, ask or use defaults; never invent requirements. RESEARCH FIRST: explore code (read/grep) and recall EE brain
|
|
40
|
+
export declare const AGENT_OPERATING_CONTRACT = "[AGENT OPERATING CONTRACT \u2014 read first; applies to every step]\n\n1. BEFORE ACTING: do only what was asked. Never assume scope or facts \u2014 if ambiguous, ask or use defaults; never invent requirements. RESEARCH FIRST: explore code (read/grep) and recall the EE brain (ee.query in unfamiliar areas) before editing.\n2. READING: base statements on what you read/ran THIS turn. Do not infer contents of files you did not open.\n3. EXECUTING: smallest correct change; never widen scope or mask failures (no `|| true`, skipped tests, or swallowed catch).\n4. WHEN UNSURE: verify and cross-check BEFORE concluding. Reading code is not proof \u2014 reproduce the bug.\n5. REPORTING: answer ONLY what was asked. Every fact or file:line MUST come from this turn; else label \"unverified\"; do not guess. Don't dump verbatim tool outputs \u2014 cite concise file:line. Never claim a build/test ran, or edits you did not actually do this turn; if a check can't run, fix it or say so.\n\n6. LANGUAGE: reply in the user's detected language; internal reasoning, tools, and code stay English.\n\n7. ANTI-M\u00D9/COMPACTION: on compaction emit PRESERVE_FULL_CONTEXT (veto) or KEEP_TOOL_IDS (from stub id=) to protect results; re-hydrate via ee_query \"tool-artifact id=XXX\". Use 'compact' near limits.\n\n8. GIT SAFETY: never push on red \u2014 run the check, await its result in a SEPARATE step, confirm 0 failures, then push. Never `git add -A`/`commit -a`; stage explicitly so secrets (.env, .muonroi-cli/, keys) aren't committed. Never `--no-verify`.\n\n9. VERIFICATION: when finishing a task, ALWAYS self-verify your work. Use the `selfverify_*` native tools (start/status/result) to run the QA harness which drives the live TUI like a real user to catch regressions that unit tests can't.\n\n10. COUNCIL/ASK: call `convene_council` for high-stakes/conflicting calls \u2014 its conclusion returns as the tool result; then YOU decide. In impl discussion you MAY confirm via `ask_user` before building, else keep going.\n\n[END CONTRACT \u2014 instructions follow]";
|
|
41
41
|
export interface ContractSectionOptions {
|
|
42
42
|
/** Chitchat turns carry no tools and make no factual claims — skip the contract. */
|
|
43
43
|
chitchat?: boolean;
|
|
@@ -39,20 +39,22 @@
|
|
|
39
39
|
*/
|
|
40
40
|
export const AGENT_OPERATING_CONTRACT = `[AGENT OPERATING CONTRACT — read first; applies to every step]
|
|
41
41
|
|
|
42
|
-
1. BEFORE ACTING: do only what was asked. Never assume scope or facts — if ambiguous, ask or use defaults; never invent requirements. RESEARCH FIRST: explore code (read/grep) and recall EE brain
|
|
42
|
+
1. BEFORE ACTING: do only what was asked. Never assume scope or facts — if ambiguous, ask or use defaults; never invent requirements. RESEARCH FIRST: explore code (read/grep) and recall the EE brain (ee.query in unfamiliar areas) before editing.
|
|
43
43
|
2. READING: base statements on what you read/ran THIS turn. Do not infer contents of files you did not open.
|
|
44
44
|
3. EXECUTING: smallest correct change; never widen scope or mask failures (no \`|| true\`, skipped tests, or swallowed catch).
|
|
45
45
|
4. WHEN UNSURE: verify and cross-check BEFORE concluding. Reading code is not proof — reproduce the bug.
|
|
46
|
-
5. REPORTING: answer ONLY what was asked. Every fact or file:line MUST come from this turn; else label "unverified"; do not guess.
|
|
46
|
+
5. REPORTING: answer ONLY what was asked. Every fact or file:line MUST come from this turn; else label "unverified"; do not guess. Don't dump verbatim tool outputs — cite concise file:line. Never claim a build/test ran, or edits you did not actually do this turn; if a check can't run, fix it or say so.
|
|
47
47
|
|
|
48
|
-
6. LANGUAGE:
|
|
48
|
+
6. LANGUAGE: reply in the user's detected language; internal reasoning, tools, and code stay English.
|
|
49
49
|
|
|
50
|
-
7. ANTI-
|
|
50
|
+
7. ANTI-MÙ/COMPACTION: on compaction emit PRESERVE_FULL_CONTEXT (veto) or KEEP_TOOL_IDS (from stub id=) to protect results; re-hydrate via ee_query "tool-artifact id=XXX". Use 'compact' near limits.
|
|
51
51
|
|
|
52
52
|
8. GIT SAFETY: never push on red — run the check, await its result in a SEPARATE step, confirm 0 failures, then push. Never \`git add -A\`/\`commit -a\`; stage explicitly so secrets (.env, .muonroi-cli/, keys) aren't committed. Never \`--no-verify\`.
|
|
53
53
|
|
|
54
54
|
9. VERIFICATION: when finishing a task, ALWAYS self-verify your work. Use the \`selfverify_*\` native tools (start/status/result) to run the QA harness which drives the live TUI like a real user to catch regressions that unit tests can't.
|
|
55
55
|
|
|
56
|
+
10. COUNCIL/ASK: call \`convene_council\` for high-stakes/conflicting calls — its conclusion returns as the tool result; then YOU decide. In impl discussion you MAY confirm via \`ask_user\` before building, else keep going.
|
|
57
|
+
|
|
56
58
|
[END CONTRACT — instructions follow]`;
|
|
57
59
|
/**
|
|
58
60
|
* Build the contract block for insertion at the front of the system prompt.
|
|
@@ -15,4 +15,4 @@ export declare function runDiscovery(raw: string, l1: L1Result, cwd: string, han
|
|
|
15
15
|
* exact ModelCard[] it wants shown — full control over questions, options,
|
|
16
16
|
* option kinds, and cancel/adjust markers.
|
|
17
17
|
*/
|
|
18
|
-
export declare function createModelClarificationProposer(
|
|
18
|
+
export declare function createModelClarificationProposer(modelId: string): ModelClarificationProposer;
|
|
@@ -234,13 +234,13 @@ async function proposeModelCards(proposer, raw, l1, projectContext, recentTurnsS
|
|
|
234
234
|
* exact ModelCard[] it wants shown — full control over questions, options,
|
|
235
235
|
* option kinds, and cancel/adjust markers.
|
|
236
236
|
*/
|
|
237
|
-
export function createModelClarificationProposer(
|
|
237
|
+
export function createModelClarificationProposer(modelId) {
|
|
238
238
|
return async (input) => {
|
|
239
239
|
// process.stderr.write(`[discovery] createModelClarificationProposer CALLED!\n`);
|
|
240
240
|
try {
|
|
241
241
|
const { resolveModelRuntime } = await import("../providers/runtime.js");
|
|
242
242
|
const { generateText } = await import("ai");
|
|
243
|
-
const runtime = resolveModelRuntime(
|
|
243
|
+
const runtime = resolveModelRuntime(modelId);
|
|
244
244
|
const contextStr = input.additionalContext
|
|
245
245
|
? `\nCurrent CLI enrichment / context (use this to decide what is already known):\n${input.additionalContext}`
|
|
246
246
|
: "";
|
|
@@ -11,13 +11,20 @@
|
|
|
11
11
|
* "Layer 1.5 complexity-size (4C)"). Do NOT alter weights without re-running the
|
|
12
12
|
* baseline harness regression.
|
|
13
13
|
*/
|
|
14
|
+
import type { RepoStructureHint } from "./repo-structure-hints.js";
|
|
14
15
|
export interface ComplexitySizeInput {
|
|
15
16
|
rawText: string;
|
|
16
17
|
taskType: string;
|
|
18
|
+
repoHints?: RepoStructureHint[];
|
|
17
19
|
}
|
|
18
20
|
export interface ComplexitySizeResult {
|
|
19
21
|
size: "small" | "medium" | "large";
|
|
20
22
|
score: number;
|
|
21
23
|
features: Record<string, number | boolean>;
|
|
22
24
|
}
|
|
25
|
+
export declare function extractPathTokens(rawText: string): string[];
|
|
26
|
+
export declare function scoreRepoGrounding(paths: string[], hints: RepoStructureHint[]): {
|
|
27
|
+
score: number;
|
|
28
|
+
hits: number;
|
|
29
|
+
};
|
|
23
30
|
export declare function scoreComplexitySize(input: ComplexitySizeInput): ComplexitySizeResult;
|
|
@@ -62,14 +62,32 @@ function effectiveLen(rawText, taskType) {
|
|
|
62
62
|
// ---------------------------------------------------------------------------
|
|
63
63
|
// Path token counter — counts DISTINCT path-like tokens.
|
|
64
64
|
// ---------------------------------------------------------------------------
|
|
65
|
-
function
|
|
65
|
+
export function extractPathTokens(rawText) {
|
|
66
66
|
const matches = rawText.match(PATH_TOKEN_RE);
|
|
67
67
|
if (!matches)
|
|
68
|
-
return
|
|
68
|
+
return [];
|
|
69
69
|
const set = new Set();
|
|
70
70
|
for (const m of matches)
|
|
71
71
|
set.add(m.toLowerCase());
|
|
72
|
-
return set
|
|
72
|
+
return [...set];
|
|
73
|
+
}
|
|
74
|
+
export function scoreRepoGrounding(paths, hints) {
|
|
75
|
+
if (paths.length === 0 || hints.length === 0)
|
|
76
|
+
return { score: 0, hits: 0 };
|
|
77
|
+
const hinted = new Map(hints.map((hint) => [hint.path.toLowerCase(), hint]));
|
|
78
|
+
let score = 0;
|
|
79
|
+
let hits = 0;
|
|
80
|
+
for (const path of paths) {
|
|
81
|
+
const hint = hinted.get(path);
|
|
82
|
+
if (!hint)
|
|
83
|
+
continue;
|
|
84
|
+
hits += 1;
|
|
85
|
+
if (hint.lineCount >= 5000)
|
|
86
|
+
score = Math.max(score, 4);
|
|
87
|
+
else if (hint.lineCount >= 2000)
|
|
88
|
+
score = Math.max(score, 2);
|
|
89
|
+
}
|
|
90
|
+
return { score, hits };
|
|
73
91
|
}
|
|
74
92
|
// ---------------------------------------------------------------------------
|
|
75
93
|
// Main: scoreComplexitySize
|
|
@@ -77,6 +95,7 @@ function countDistinctPaths(rawText) {
|
|
|
77
95
|
export function scoreComplexitySize(input) {
|
|
78
96
|
const rawText = input.rawText ?? "";
|
|
79
97
|
const taskType = input.taskType ?? "general";
|
|
98
|
+
const repoHints = input.repoHints ?? [];
|
|
80
99
|
// 1. Length score (debug + stack-trace gets mitigation).
|
|
81
100
|
// CONTEXT-locked thresholds are <60 / >240. We use <80 for the "small" knee
|
|
82
101
|
// because the baseline-2 prompt "đổi default --max-tool-rounds từ 100 →
|
|
@@ -102,13 +121,18 @@ export function scoreComplexitySize(input) {
|
|
|
102
121
|
// baseline-2 "đổi default ... trong src/orchestrator/cli-args.ts")
|
|
103
122
|
// - zero paths is neutral (vagueness is handled by `vaguenessAmplifier`)
|
|
104
123
|
// - ≥3 paths is multi-file work, push toward large
|
|
105
|
-
const
|
|
124
|
+
const distinctPaths = extractPathTokens(rawText);
|
|
125
|
+
const pathCount = distinctPaths.length;
|
|
106
126
|
let pathScore = 0;
|
|
107
127
|
if (pathCount === 1)
|
|
108
128
|
pathScore = -1;
|
|
109
129
|
else if (pathCount >= 3)
|
|
110
130
|
pathScore = 2;
|
|
111
131
|
// 0 or 2 → 0 (neutral)
|
|
132
|
+
// 4.5 Repo-structure grounding probe. Cheap deterministic lookup against the
|
|
133
|
+
// checked-in REPO_DEEP_MAP index: monolith roots like src/ui/app.tsx should
|
|
134
|
+
// not size the same as a narrow leaf module when both appear as one-path asks.
|
|
135
|
+
const repoGrounding = scoreRepoGrounding(distinctPaths, repoHints);
|
|
112
136
|
// 5. Question form score.
|
|
113
137
|
const trimmed = rawText.trim();
|
|
114
138
|
const isQuestion = QUESTION_START_RE.test(trimmed) || trimmed.endsWith("?");
|
|
@@ -123,7 +147,7 @@ export function scoreComplexitySize(input) {
|
|
|
123
147
|
// "improve X" / "clean up Y" without targets is the canonical wandering shape.
|
|
124
148
|
const vaguenessAmplifier = sweepCount > 0 && pathCount === 0 ? 4 : 0;
|
|
125
149
|
// Total score → bucket.
|
|
126
|
-
const score = lenScore + sweepScore + heavyScore + pathScore + questionScore + vaguenessAmplifier;
|
|
150
|
+
const score = lenScore + sweepScore + heavyScore + pathScore + repoGrounding.score + questionScore + vaguenessAmplifier;
|
|
127
151
|
let size;
|
|
128
152
|
if (score <= -1)
|
|
129
153
|
size = "small";
|
|
@@ -142,6 +166,8 @@ export function scoreComplexitySize(input) {
|
|
|
142
166
|
heavyScore,
|
|
143
167
|
pathCount,
|
|
144
168
|
pathScore,
|
|
169
|
+
repoGroundingHits: repoGrounding.hits,
|
|
170
|
+
repoGroundingScore: repoGrounding.score,
|
|
145
171
|
isQuestion,
|
|
146
172
|
questionScore,
|
|
147
173
|
isImperative,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ProviderId } from "../providers/types.js";
|
|
2
2
|
import type { OutputStyle, TaskType } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* What the user wants the turn to PRODUCE — decided by the model (Phase 2b) so
|
|
@@ -92,6 +92,56 @@ export interface LlmClassifyOptions {
|
|
|
92
92
|
signal?: AbortSignal;
|
|
93
93
|
}
|
|
94
94
|
export type LlmClassifyFn = (prompt: string, opts?: LlmClassifyOptions) => Promise<LlmClassifyResult | null>;
|
|
95
|
+
/**
|
|
96
|
+
* Factory-level options for `createLlmClassifier` (distinct from the per-call
|
|
97
|
+
* `LlmClassifyOptions`). Chosen once when the closure is built.
|
|
98
|
+
*/
|
|
99
|
+
export interface CreateClassifierOptions {
|
|
100
|
+
/**
|
|
101
|
+
* Route the throwaway classify to the provider's fast tier when one exists
|
|
102
|
+
* (mirrors `classifySubSessionAction`). Same-provider only, so the already-
|
|
103
|
+
* bound factory/key still works. A no-op when the provider exposes no
|
|
104
|
+
* routable fast model (e.g. xai). Zero-hardcode: the fast id comes from
|
|
105
|
+
* `getRoutedModelByTier`, not a literal. Cheap — safe on every turn.
|
|
106
|
+
*/
|
|
107
|
+
routeFastTier?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* When the session provider has NO same-provider fast tier (e.g. xai, whose
|
|
110
|
+
* session model may be an agentic model that ignores the terse classify
|
|
111
|
+
* contract — measured 2026-07-15 for grok-composer), also try keyed fast
|
|
112
|
+
* models from OTHER configured providers, in catalog switch order, until one
|
|
113
|
+
* parses. Bounded by CLASSIFY_TOTAL_BUDGET_MS so a chain of dead/slow keys
|
|
114
|
+
* can't stall the turn. This adds latency ONLY on that fallback path, so it is
|
|
115
|
+
* opt-in per call-site: enable it for the high-value /ideal routing classify,
|
|
116
|
+
* NOT for the per-turn PIL classify (there a fast fail-open "standard" is fine
|
|
117
|
+
* and cheaper than chaining providers on every message).
|
|
118
|
+
*/
|
|
119
|
+
crossProviderFallback?: boolean;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Compute the classify call budget from the resolved model's catalog metadata.
|
|
123
|
+
*
|
|
124
|
+
* TIMEOUT is a flat safety-net ceiling for all models — see CLASSIFY_TIMEOUT_MS.
|
|
125
|
+
* Measurement showed classify latency is provider-independent and well under
|
|
126
|
+
* the ceiling, so keying the timeout off `tier`/`reasoning` added no value and
|
|
127
|
+
* amounted to an identity-proxy soft-hardcode.
|
|
128
|
+
*
|
|
129
|
+
* MAX-OUTPUT scales with REASONING only: a reasoning model burns its output
|
|
130
|
+
* budget on reasoning tokens before any visible text, so it needs the room in
|
|
131
|
+
* tokens; a non-reasoning model emits the 8 words directly. This knob is real —
|
|
132
|
+
* it is the fix for reasoning models routing the verdict into the reasoning
|
|
133
|
+
* channel — and stays decoupled from the (now flat) timeout.
|
|
134
|
+
*/
|
|
135
|
+
export declare function classifierBudget(modelInfo: {
|
|
136
|
+
reasoning?: boolean;
|
|
137
|
+
tier?: string;
|
|
138
|
+
} | undefined): {
|
|
139
|
+
isReasoning: boolean;
|
|
140
|
+
timeoutMs: number;
|
|
141
|
+
maxOutputTokens: number;
|
|
142
|
+
};
|
|
143
|
+
/** Test seam — clear the cross-provider factory cache between specs. */
|
|
144
|
+
export declare function __resetClassifyFactoryCache(): void;
|
|
95
145
|
/**
|
|
96
146
|
* Build a closure the PIL pipeline can call. Reuses the orchestrator's already-
|
|
97
147
|
* constructed providerFactory + modelId so we don't pay key-loading cost twice.
|
|
@@ -99,14 +149,39 @@ export type LlmClassifyFn = (prompt: string, opts?: LlmClassifyOptions) => Promi
|
|
|
99
149
|
* Returns null if the call fails / times out / parses to garbage. Callers must
|
|
100
150
|
* fail-open (keep prior taskType, do not block the turn).
|
|
101
151
|
*/
|
|
102
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Order the classify candidate list.
|
|
154
|
+
*
|
|
155
|
+
* - `hasSameFast` (e.g. openai → gpt-5.4-mini): the same-provider fast tier is a
|
|
156
|
+
* real fast model, so try it FIRST, then keyed cross-provider models as a
|
|
157
|
+
* FALLBACK. This is the fix for the failure-not-just-absence case: an
|
|
158
|
+
* openai-OAuth session's fast tier can 401 on the api-key path — previously
|
|
159
|
+
* the chain stopped there and fail-opened to "standard" (so /ideal
|
|
160
|
+
* over-councilled trivial tasks). Appending the cross-provider models lets a
|
|
161
|
+
* working alternative (a keyed deepseek/opencode fast model) rescue it.
|
|
162
|
+
* - No same-provider fast tier (e.g. xai, whose session model is agentic and
|
|
163
|
+
* ignores the terse contract): try keyed cross-provider fast models FIRST and
|
|
164
|
+
* keep the session model as the last-resort candidate.
|
|
165
|
+
*/
|
|
166
|
+
export declare function orderClassifyCandidates(args: {
|
|
167
|
+
primaryModelId: string;
|
|
168
|
+
hasSameFast: boolean;
|
|
169
|
+
crossModels: ReadonlyArray<{
|
|
170
|
+
modelId: string;
|
|
171
|
+
providerId: ProviderId;
|
|
172
|
+
}>;
|
|
173
|
+
}): Array<{
|
|
174
|
+
modelId: string;
|
|
175
|
+
providerId: ProviderId | null;
|
|
176
|
+
}>;
|
|
177
|
+
export declare function createLlmClassifier(modelId: string, classifyOpts?: CreateClassifierOptions): LlmClassifyFn;
|
|
103
178
|
export type SubSessionAction = "DIRECT_ANSWER" | "ROTATE_SESSION" | "SPAWN_SUB_SESSION";
|
|
104
179
|
export interface SubSessionRouteResult {
|
|
105
180
|
action: SubSessionAction;
|
|
106
181
|
confidence: number;
|
|
107
182
|
reason: string;
|
|
108
183
|
}
|
|
109
|
-
export declare function classifySubSessionAction(
|
|
184
|
+
export declare function classifySubSessionAction(modelId: string, prompt: string, contextInfo?: {
|
|
110
185
|
currentChars: number;
|
|
111
186
|
threshold: number;
|
|
112
187
|
/**
|