@quantiya/codevibe-core 2.0.85 → 2.0.87

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.
@@ -28751,8 +28751,13 @@ var PlannerOutputUnparseableError = class _PlannerOutputUnparseableError extends
28751
28751
  "brainstorm",
28752
28752
  "refuse"
28753
28753
  ]);
28754
+ function isRealHttpUrl(url) {
28755
+ if (typeof url != "string") return !1;
28756
+ let trimmed = url.trim();
28757
+ return trimmed.length === 0 || trimmed === "http(s) url" || trimmed === "https://[path]" ? !1 : new RegExp("^" + HTTP_URL_PATTERN_SOURCE + "$").test(trimmed);
28758
+ }
28754
28759
  function hasRealBrowseFields(obj) {
28755
- let hasRealBrowseUrls = Array.isArray(obj.browseUrls) && obj.browseUrls.length > 0, hasRealBrowseQuery = typeof obj.browseQuery == "string" && obj.browseQuery.trim().length > 0;
28760
+ let hasRealBrowseUrls = Array.isArray(obj.browseUrls) && obj.browseUrls.some(isRealHttpUrl), hasRealBrowseQuery = typeof obj.browseQuery == "string" && obj.browseQuery.trim().length > 0;
28756
28761
  return hasRealBrowseUrls || hasRealBrowseQuery;
28757
28762
  }
28758
28763
  function validationError(message2, obj, canDegrade) {
@@ -28938,7 +28943,7 @@ function renderLocalGemmaPlannerPromptWithShape(input) {
28938
28943
  'User: "also add a --cv-quiet flag to release.sh" (session.currentTaskState is in_progress) -> {"action":"start_task","rationale":"asks for a new deliverable while a task runs"}',
28939
28944
  "",
28940
28945
  OUTPUT_CONTRACT_HEADER,
28941
- `{"action":"${[...localGemmaAllowedActions()].join("|")}","rationale":"short reason","clarifying_question":"question text or null","advisory_summary":"answer text or null","browseUrls":["http(s) url"] or null,"browseQuery":"web-search query or null"}`,
28946
+ `{"action":"${[...localGemmaAllowedActions()].join("|")}","rationale":"short reason","clarifying_question":"question text or null","advisory_summary":"answer text or null","browseUrls":["https://example.com"] or null,"browseQuery":"web-search query or null"}`,
28942
28947
  "Only a browse action may set browseUrls/browseQuery (null for every other action). ask_user always sets clarifying_question to the question for the user. Do not include gateRequest or any other keys.",
28943
28948
  "Destructive workspace operations: a bounded operation that removes named project files requires explicit confirmation of that operation and target before dispatch, rather than blanket refusal. If confirmation is not yet present in clarifications, choose ask_user and ask a concise question identifying the target and consequence. If the user confirms the same operation and target in clarifications, choose start_task; the implementor still enforces filesystem authority and execution safeguards. If the user declines, choose advisory_response acknowledging cancellation and do not start a task. This does not permit destructive root/home deletion or override unsafe-request refusal rules. Keep rationale to one short sentence.",
28944
28949
  'turnState identifies this submission: new_request means the user has submitted a NEW request, even when its text repeats an earlier request; clarification_answer means the user is answering the current question in clarifications. priorSessionContext is historical reference material only. Never treat an old answer as the current answer or respond to an earlier request instead of userPrompt. For example: history says the user declined deletion; turnState is new_request; userPrompt asks to delete the same file -> ask_user for fresh confirmation, NOT advisory_response about the old cancellation. A previous approval also cannot authorize a new deletion \u2014 even when the LAST line of priorSessionContext is a bare "yes": that answered an EARLIER question, and turnState says this is a NEW request that needs its own confirmation.',
@@ -29157,8 +29162,8 @@ function parseLocalGemmaPlannerDecision(raw) {
29157
29162
  if (obj.advisory_summary !== void 0 || obj.clarifying_question !== void 0)
29158
29163
  throw validationError("Gemma planner browse output must not include advisory_summary or clarifying_question", obj, canDegrade);
29159
29164
  } else {
29160
- let hasRealBrowseUrls = Array.isArray(obj.browseUrls) && obj.browseUrls.length > 0, hasRealBrowseQuery = typeof obj.browseQuery == "string" && obj.browseQuery.trim().length > 0, userFacingAction = obj.action === "advisory_response" || obj.action === "ask_user" || obj.action === "refuse", taskStartingAction = obj.action === "start_task" || obj.action === "team_decompose";
29161
- if ((hasRealBrowseUrls || hasRealBrowseQuery) && (userFacingAction || taskStartingAction || obj.advisory_summary !== void 0 || obj.clarifying_question !== void 0))
29165
+ let hasRealBrowseUrls = Array.isArray(obj.browseUrls) && obj.browseUrls.some(isRealHttpUrl), hasRealBrowseQuery = typeof obj.browseQuery == "string" && obj.browseQuery.trim().length > 0, userFacingPlannerText = typeof obj.advisory_summary == "string" && obj.advisory_summary.trim().length > 0 || typeof obj.clarifying_question == "string" && obj.clarifying_question.trim().length > 0, taskStartingAction = obj.action === "start_task" || obj.action === "team_decompose";
29166
+ if ((hasRealBrowseUrls || hasRealBrowseQuery) && (userFacingPlannerText || taskStartingAction || obj.action === "refuse" || obj.action === "ask_user"))
29162
29167
  throw new PlannerOutputUnparseableError(
29163
29168
  "Gemma planner non-browse output must not combine browse fields with user-facing or task-starting planner output",
29164
29169
  { kind: "validation" }
@@ -35885,14 +35890,6 @@ function attachmentsToPipelineImages(attachments) {
35885
35890
  read: () => readImageFdSafe(attachment.sourcePath, MAX_IMAGE_BYTES)
35886
35891
  }));
35887
35892
  }
35888
- function isBlindImageClarification(prompt, clarifyingQuestion) {
35889
- if (clarifyingQuestion && clarifyingQuestion.trim().length > 0) {
35890
- let q = clarifyingQuestion.toLowerCase();
35891
- return /what .*like me to do with the (screenshot|image)/i.test(q) || /what .*want me to do with the (screenshot|image)/i.test(q) || /how should i use (that|this) information/i.test(q) || /information from the (screenshot|image)/i.test(q) || /rephrase that as a specific command or request/i.test(q) || /cannot (see|view|read|inspect) (the )?(image|screenshot)/i.test(q) || /describe what you('d| would) like me to do with (the )?(screenshot|image)/i.test(q);
35892
- }
35893
- let p = prompt.toLowerCase();
35894
- return /what('s| is| do you see) (in |on )?(the |this )?(screenshot|image|picture)/i.test(p) || /what does (the |this )?(screenshot|image|picture) (show|contain|depict)/i.test(p) || /what (shape|color|text) is (in |on )?(this |the )?(image|screenshot)/i.test(p);
35895
- }
35896
35893
 
35897
35894
  // src/orchestration-shell/slash-suggest.ts
35898
35895
  function isSlashCommandInProgress(value) {
@@ -67590,34 +67587,6 @@ function isWebAccessNeeded(text2) {
67590
67587
  text2
67591
67588
  ));
67592
67589
  }
67593
- function hasFileMutationIntent(text2) {
67594
- if (!text2 || typeof text2 != "string") return !1;
67595
- let stripped = stripLeadingAgentControlToken(text2).trim(), textWithoutUrls = stripped.replace(/https?:\/\/[^\s]+/gi, " ").trim();
67596
- if (/\b(?:how\s+(?:to|do\s+I|can\s+I)|explain\s+how\s+to|tell\s+me\s+how\s+to)\b/i.test(stripped) || /(?:^|[.?!;])\s*(?:what\s+(?:is|are)\b|c[oó]mo\s+(?:hacer|puedo|se\s+puede|escribir|guardar|crear)|comment\s+(?:faire|écrire|sauvegarder|créer|enregistrer)|wie\s+(?:kann\s+ich|macht\s+man|schreibt\s+man|speichert\s+man|erstellt\s+man))\b/i.test(stripped) || /(?:如何|怎么|怎样|告诉我(?:如何|怎么|怎样)|解释如何|请问|什么是)/.test(stripped) || /(?:どうやって|方法(?:を(?:教えて|説明して))|やり方を教えて|でしょうか|とは(?:何|なん)ですか)/.test(stripped) || /(?:어떻게|방법을?\s*(?:알려줘|설명해줘)|법\s*설명|하는지\s*알려줘)/.test(stripped))
67597
- return !1;
67598
- if (/>{1,2}\s*[\w./-]+\b/.test(textWithoutUrls))
67599
- return !0;
67600
- let fileExt = "(?:md|markdown|txt|json|csv|ts|js|tsx|jsx|py|html|css|yaml|yml|log|sh|xml|toml|sql|env)", writeToFilePatternEn = new RegExp(
67601
- `\\b(?:write|save|create|dump|output|put|export|store|record|guardar|escribir|crear|enregistrer|\xE9crire|cr\xE9er|sauvegarder|speichern|schreiben|erstellen)\\b[\\s\\S]*?\\b(?:into|to|in|as|en|dans|auf|zu)\\b(?!\\s+(?:chat|console|stdout|screen|terminal)\\b)[\\s\\S]*?(?:(?:a|an|the|un|une|ein|eine|el|la)?\\s*file(?:\\s+named|\\s+called)?\\s+)?[\\w./-]+\\.${fileExt}\\b`,
67602
- "i"
67603
- ), writeToFilePatternGermanic = new RegExp(
67604
- `\\b(?:in|auf|zu|into|to)\\s+[\\w./-]+\\.${fileExt}[\\s\\S]*?\\b(?:speichern|schreiben|erstellen|ablegen)\\b`,
67605
- "i"
67606
- ), namedFilePatternEn = /\b(?:into|to|in|en|dans|auf|zu)\s+(?:a|an|un|une|ein|eine|el|la)?\s*file(?:\s+(?:named|called))?\s+[\w./-]+\b/i, createFilePatternEn = /\b(?:create|add|touch)\s+(?:a|an|the)?\s*(?:new\s+)?(?:file|markdown\s+file|script)\b/i, directFileVerbPatternEn = new RegExp(
67607
- `\\b(?:create|write|touch|add|crear|escribir|cr\xE9er|\xE9crire|erstellen)\\s+[\\w./-]+\\.${fileExt}\\b`,
67608
- "i"
67609
- ), writeToFilePatternZh = new RegExp(
67610
- `(?:\u5199\u5165|\u4FDD\u5B58\u5230?|\u521B\u5EFA|\u751F\u6210|\u8F93\u51FA\u5230|\u5B58\u5165|\u5BFC\u51FA\u5230?|\u8BB0\u5F55\u5230?)[\\s\\S]*?[\\w./-]+\\.${fileExt}\\b`,
67611
- "i"
67612
- ), writeToFilePatternJa = new RegExp(
67613
- `(?:[\\w./-]+\\.${fileExt}[\\s\\S]*?(?:\u306B|\u3078)?\\s*(?:\u66F8\u304D\u51FA|\u4FDD\u5B58|\u4F5C\u6210|\u751F\u6210|\u51FA\u529B|\u8A18\u9332|\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8)|(?:\u66F8\u304D\u51FA|\u4FDD\u5B58|\u4F5C\u6210|\u751F\u6210|\u51FA\u529B|\u8A18\u9332|\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8)[\\s\\S]*?[\\w./-]+\\.${fileExt})`,
67614
- "i"
67615
- ), writeToFilePatternKo = new RegExp(
67616
- `(?:[\\w./-]+\\.${fileExt}[\\s\\S]*?(?:\uC5D0|\uC73C\uB85C|\uB85C)?\\s*(?:\uC800\uC7A5|\uC791\uC131|\uC0DD\uC131|\uAE30\uB85D|\uCD9C\uB825|\uB0B4\uBCF4\uB0B4\uAE30)|(?:\uC800\uC7A5|\uC791\uC131|\uC0DD\uC131|\uAE30\uB85D|\uCD9C\uB825|\uB0B4\uBCF4\uB0B4\uAE30)[\\s\\S]*?[\\w./-]+\\.${fileExt})`,
67617
- "i"
67618
- );
67619
- return writeToFilePatternEn.test(textWithoutUrls) || writeToFilePatternGermanic.test(textWithoutUrls) || namedFilePatternEn.test(textWithoutUrls) || createFilePatternEn.test(textWithoutUrls) || directFileVerbPatternEn.test(textWithoutUrls) || writeToFilePatternZh.test(textWithoutUrls) || writeToFilePatternJa.test(textWithoutUrls) || writeToFilePatternKo.test(textWithoutUrls);
67620
- }
67621
67590
 
67622
67591
  // src/orchestration-shell/quorum-loop.ts
67623
67592
  var CONTINUATION_EXPIRES_TTL_MS = 1440 * 60 * 1e3, ACTIVE_AGENT_KINDS = ["CLAUDE", "CODEX", "ANTIGRAVITY"], TEAM_RECOVERY_RELAUNCH_CONCURRENCY = 3;
@@ -83856,6 +83825,155 @@ var DEFAULT_REFRESH_MS = 300 * 1e3, MAX_RESOLUTION_TICK_ATTEMPTS = 12, TERMINAL_
83856
83825
  }
83857
83826
  };
83858
83827
 
83828
+ // src/orchestration-shell/gemma-intent-classifier.ts
83829
+ var INTENT_CLASSIFIER_JSON_SCHEMA = {
83830
+ type: "object",
83831
+ properties: {
83832
+ action: {
83833
+ type: "string",
83834
+ enum: ["start_task", "familiarize", "advisory_response", "browse", "brainstorm", "ask_user"]
83835
+ },
83836
+ is_code_or_disk_mutation: { type: "boolean" },
83837
+ confidence: { type: "string", enum: ["high", "low"] },
83838
+ requires_file_read: { type: "boolean" },
83839
+ rationale: { type: "string" }
83840
+ },
83841
+ required: ["action", "is_code_or_disk_mutation", "confidence", "requires_file_read", "rationale"]
83842
+ }, DEFAULT_INTENT_TIMEOUT_MS = 5e3, INTENT_MAX_OUTPUT_TOKENS = 256;
83843
+ function buildIntentClassifierPrompt(prompt, clarifications) {
83844
+ return [
83845
+ "You are a strict code/workspace intent classifier for CodeVibe.",
83846
+ "Analyze the user prompt and clarifications to determine whether the user is requesting a code or filesystem mutation, or an informational/read-only turn.",
83847
+ "Output STRICT JSON ONLY matching this schema:",
83848
+ '{"action": "start_task"|"familiarize"|"advisory_response"|"browse"|"brainstorm"|"ask_user", "is_code_or_disk_mutation": boolean, "confidence": "high"|"low", "requires_file_read": boolean, "rationale": "short explanation"}',
83849
+ "",
83850
+ "Rules:",
83851
+ '1. "is_code_or_disk_mutation": true if the user asks to create, modify, edit, delete, write, record, note, save, append, refactor, implement, or run code/tests/files on disk (e.g. "fix auth.ts", "delete temp.js", "create a React component", "run the test suite", "update the config file"). CRITICAL: writing, noting, recording, or saving data into any file (e.g. "note X in file.csv", "write X into file.txt", "record X in file.json") IS a disk mutation ("is_code_or_disk_mutation": true, "action": "start_task"). CRITICAL: adding comments to code or commenting helpers/functions in source files (e.g. "comment the helpers in auth.ts", "prepend a comment to auth.ts", "comment out the unused helpers") IS a code modification ("is_code_or_disk_mutation": true, "action": "start_task"), whereas providing commentary or feedback about code in chat (e.g. "comment on the logic in auth.ts", "comment on the error handling") is read-only ("is_code_or_disk_mutation": false, "action": "advisory_response").',
83852
+ '2. "is_code_or_disk_mutation": false for read-only understanding, file inspection, or informational questions (e.g. "What files are here?", "Summarize numbers in statement.pdf", "Explain how auth works", "Organize them by category in your response", "Explain what happens when I press tab and enter", "Read auth.ts and explain why we can populate the values in output.json"). Questions asking to explain why tests fail, analyze crashes, explain system behavior after a change, or explain why an action/step is taken (e.g. "Explain why we update config.json", "Explain why we read notice.pdf and redact the amounts", "Explain why we inspect auth.ts and note findings into report.md"), or asking to paste example commands in a chat reply, are explanatory inquiries ("is_code_or_disk_mutation": false, "action": "advisory_response") when no explicit disk edit is commanded.',
83853
+ "3. Action routing:",
83854
+ ' - "familiarize": Read-only overview or exploration of the project, folder, files, or workspace structure without file modification.',
83855
+ ' - "advisory_response": General questions, capability queries, or reading/summarizing/explaining specific files without disk mutation.',
83856
+ ' - "start_task": Direct request to modify code, edit files, fix bugs, implement features, or run commands on disk.',
83857
+ ' - "browse": Web browsing or search without disk mutation.',
83858
+ ' - "brainstorm": Exploring architecture choices or design options.',
83859
+ '4. "requires_file_read": true if answering the prompt requires reading or inspecting specific file(s) or document(s) in the workspace (e.g. "Tell me the wage amount from w2_2024_employer.txt", "Summarize statement.pdf", "Inspect auth.ts", "w2_2024_employer.txt"). false for general conceptual questions, project structure/familiarize, or questions not referencing specific workspace files.',
83860
+ '5. Conversational keypresses (e.g. "press enter", "hit tab") and data attributes (e.g. "comment text", "table columns") are NOT code or file mutations.',
83861
+ '6. If the request is ambiguous, self-contradictory, contains mixed read and write instructions, or you are uncertain, set "confidence": "low", "is_code_or_disk_mutation": true, and "action": "start_task".',
83862
+ "",
83863
+ clarifications && clarifications.length > 0 ? [
83864
+ "Prior clarifications in this turn:",
83865
+ ...clarifications.map((c, i) => `Q${i + 1}: ${c.question}
83866
+ A${i + 1}: ${c.answer}`),
83867
+ ""
83868
+ ].join(`
83869
+ `) : "",
83870
+ "=== BEGIN USER PROMPT ===",
83871
+ prompt,
83872
+ "=== END USER PROMPT ==="
83873
+ ].join(`
83874
+ `);
83875
+ }
83876
+ function parseIntentGemmaResponse(raw) {
83877
+ try {
83878
+ let parsed = JSON.parse(raw.trim());
83879
+ return typeof parsed != "object" || parsed === null || typeof parsed.is_code_or_disk_mutation != "boolean" || !["start_task", "familiarize", "advisory_response", "browse", "brainstorm", "ask_user"].includes(
83880
+ parsed.action
83881
+ ) || parsed.confidence !== "high" && parsed.confidence !== "low" || typeof parsed.rationale != "string" || parsed.rationale.trim().length === 0 || parsed.action === "start_task" && !parsed.is_code_or_disk_mutation || parsed.action !== "start_task" && parsed.is_code_or_disk_mutation || typeof parsed.requires_file_read != "boolean" ? null : {
83882
+ action: parsed.action,
83883
+ is_code_or_disk_mutation: !!parsed.is_code_or_disk_mutation,
83884
+ confidence: parsed.confidence,
83885
+ rationale: parsed.rationale.trim(),
83886
+ source: "model",
83887
+ requires_file_read: parsed.requires_file_read
83888
+ };
83889
+ } catch {
83890
+ return null;
83891
+ }
83892
+ }
83893
+ function failClosedDefault(rationale, source2 = "semantic_fail_closed") {
83894
+ return {
83895
+ action: "start_task",
83896
+ is_code_or_disk_mutation: !0,
83897
+ confidence: "low",
83898
+ rationale,
83899
+ source: source2,
83900
+ requires_file_read: !1
83901
+ };
83902
+ }
83903
+ function isInfrastructureTransportOutage(err) {
83904
+ if (!err || err instanceof GemmaPolicyError || err instanceof GemmaContextFullError || err instanceof GemmaEmptyOutputError || err instanceof GemmaHiddenTokenLoopError || err instanceof GemmaBackendTooOldError || err?.name === "GemmaPolicyError" || err?.name === "GemmaContextFullError" || err?.name === "GemmaEmptyOutputError" || err?.name === "GemmaHiddenTokenLoopError" || err?.name === "GemmaBackendTooOldError" || err?.name === "AssertionError" || err?.constructor?.name === "AssertionError")
83905
+ return !1;
83906
+ let errMessage = String(err?.message || ""), causeObj = err?.cause, causeMessage = String(causeObj?.message || "");
83907
+ if (/\b(?:has no classify|no classify)\b/i.test(errMessage) || /\b(?:has no classify|no classify)\b/i.test(causeMessage))
83908
+ return !1;
83909
+ let e = err, cause = e.cause || void 0, causeCode = String(cause?.code || ""), causeName = String(cause?.name || ""), nestedCause = cause?.cause || void 0, nestedCauseCode = String(nestedCause?.code || ""), nestedCauseName = String(nestedCause?.name || ""), deepCause = nestedCause?.cause || void 0, deepCauseCode = String(deepCause?.code || "");
83910
+ if (causeName === "AssertionError" || nestedCauseName === "AssertionError" || cause instanceof ReferenceError || cause instanceof RangeError || cause instanceof SyntaxError || nestedCause instanceof ReferenceError || nestedCause instanceof RangeError || nestedCause instanceof SyntaxError || causeName === "ReferenceError" || causeName === "RangeError" || causeName === "SyntaxError" || nestedCauseName === "ReferenceError" || nestedCauseName === "RangeError" || nestedCauseName === "SyntaxError")
83911
+ return !1;
83912
+ let networkCodes = [
83913
+ "ECONNREFUSED",
83914
+ "ENOTFOUND",
83915
+ "EAI_AGAIN",
83916
+ "EHOSTUNREACH",
83917
+ "ENETUNREACH",
83918
+ "ECONNRESET",
83919
+ "EPIPE",
83920
+ "ETIMEDOUT",
83921
+ "UND_ERR_CONNECT_TIMEOUT",
83922
+ "UND_ERR_SOCKET",
83923
+ "UND_ERR_HEADERS_TIMEOUT",
83924
+ "UND_ERR_BODY_TIMEOUT",
83925
+ "UND_ERR_DESTROYED",
83926
+ "UND_ERR_CLOSED"
83927
+ ];
83928
+ if (networkCodes.includes(causeCode) || networkCodes.includes(nestedCauseCode) || networkCodes.includes(deepCauseCode))
83929
+ return !0;
83930
+ if (err instanceof GemmaTransportError || err?.name === "GemmaTransportError")
83931
+ return cause instanceof TypeError || causeName === "TypeError" || nestedCause instanceof TypeError || nestedCauseName === "TypeError" ? !!(networkCodes.includes(nestedCauseCode) || networkCodes.includes(causeCode) || networkCodes.includes(deepCauseCode)) : !0;
83932
+ if (err instanceof TypeError || err?.name === "TypeError") {
83933
+ let causeMsg = String(cause?.message || ""), parentMsg = String(e.message || "");
83934
+ return !!(/\b(?:fetch failed)\b/i.test(parentMsg) && (/\b(?:connect ECONNREFUSED|ENOTFOUND|EAI_AGAIN|network|socket|timed?\s*out|und_err)\b/i.test(causeMsg) || /\b(?:connect ECONNREFUSED|ENOTFOUND|EAI_AGAIN|network|socket|und_err)\b/i.test(parentMsg)));
83935
+ }
83936
+ if (err instanceof ReferenceError || err instanceof RangeError || err instanceof SyntaxError || err?.name === "ReferenceError" || err?.name === "RangeError" || err?.name === "SyntaxError")
83937
+ return !1;
83938
+ if (err instanceof GemmaAbortError || err?.name === "AbortError")
83939
+ return !0;
83940
+ let name = String(e.name || ""), msg = String(e.message || ""), code = String(e.code || "");
83941
+ return !!(name === "TimeoutError" || name === "AbortError" || code === "ETIMEDOUT" || code === "UND_ERR_CONNECT_TIMEOUT" || code === "UND_ERR_SOCKET" || code === "UND_ERR_HEADERS_TIMEOUT" || code === "UND_ERR_BODY_TIMEOUT" || code === "UND_ERR_DESTROYED" || code === "UND_ERR_CLOSED" || /\b(?:timed?\s*out|caller_aborted)\b/i.test(msg) || networkCodes.includes(code) || /\b(?:fetch failed|socket hang up|connection refused|network error|dns lookup failed|cannot reach|und_err_socket|und_err_connect_timeout)\b/i.test(
83942
+ msg
83943
+ ));
83944
+ }
83945
+ async function classifyPromptIntentWithGemma(input, port, opts) {
83946
+ if (!input || !input.prompt || input.prompt.trim().length === 0)
83947
+ return failClosedDefault("empty_prompt", "semantic_fail_closed");
83948
+ if (opts?.signal?.aborted)
83949
+ return failClosedDefault("caller_aborted", "infrastructure_outage");
83950
+ let timeoutMs = opts?.timeoutMs ?? DEFAULT_INTENT_TIMEOUT_MS, controller = new AbortController(), timer, callerAbortHandler, failurePromise = new Promise((_, reject) => {
83951
+ timer = setTimeout(() => {
83952
+ reject(new Error(`Gemma intent classification timed out after ${timeoutMs}ms`)), controller.abort();
83953
+ }, timeoutMs), opts?.signal && (callerAbortHandler = () => {
83954
+ reject(new Error("caller_aborted")), controller.abort();
83955
+ }, opts.signal.addEventListener("abort", callerAbortHandler, { once: !0 }));
83956
+ });
83957
+ try {
83958
+ let prompt = buildIntentClassifierPrompt(input.prompt, input.clarifications), classifyPromise = port.classify({
83959
+ prompt,
83960
+ jsonSchema: INTENT_CLASSIFIER_JSON_SCHEMA,
83961
+ maxOutputTokens: INTENT_MAX_OUTPUT_TOKENS,
83962
+ signal: controller.signal,
83963
+ timeoutMs
83964
+ });
83965
+ classifyPromise.catch(() => {
83966
+ });
83967
+ let res = await Promise.race([classifyPromise, failurePromise]), parsed = parseIntentGemmaResponse(res.text);
83968
+ return parsed ? parsed.confidence === "low" ? failClosedDefault("low_confidence_intent", "semantic_fail_closed") : parsed : failClosedDefault("unparseable_gemma_intent_response", "semantic_fail_closed");
83969
+ } catch (err) {
83970
+ let msg = err?.message || "unknown";
83971
+ return err instanceof GemmaPolicyError || err instanceof GemmaContextFullError || err instanceof GemmaEmptyOutputError || err instanceof GemmaHiddenTokenLoopError || err instanceof GemmaBackendTooOldError || err?.name === "GemmaPolicyError" || err?.name === "GemmaContextFullError" || err?.name === "GemmaEmptyOutputError" || err?.name === "GemmaHiddenTokenLoopError" || err?.name === "GemmaBackendTooOldError" ? failClosedDefault(`gemma_policy_or_capacity_error: ${msg}`, "semantic_fail_closed") : isInfrastructureTransportOutage(err) ? failClosedDefault(`gemma_transport_outage: ${msg}`, "infrastructure_outage") : failClosedDefault(`gemma_intent_error: ${msg}`, "semantic_fail_closed");
83972
+ } finally {
83973
+ timer && clearTimeout(timer), opts?.signal && callerAbortHandler && opts.signal.removeEventListener("abort", callerAbortHandler);
83974
+ }
83975
+ }
83976
+
83859
83977
  // src/orchestration-shell/brainstorm-quorum.ts
83860
83978
  var BRAINSTORM_PANEL_MIN_TIER = "MAX";
83861
83979
  function resolveBrainstormPanel(input) {
@@ -86351,6 +86469,11 @@ async function runOrchestrationShellSession(args) {
86351
86469
  }
86352
86470
  ), handleUserInput = (text2, images, options) => {
86353
86471
  if (shellSubmissionsFenced) return Promise.resolve();
86472
+ if (args.appsyncClient && args.session?.userId && !args.appsyncClient.companionSyncStatusSnapshot?.(args.session.userId)) {
86473
+ let refreshAbort = new AbortController(), timeout = setTimeout(() => refreshAbort.abort(), 4500);
86474
+ timeout.unref?.(), args.appsyncClient.getCompanionSyncState(refreshAbort.signal).catch(() => {
86475
+ }).finally(() => clearTimeout(timeout));
86476
+ }
86354
86477
  let submission = serializedHandleUserInput(text2, images, options);
86355
86478
  return isShellSlashCommand(text2) || (activeShellSubmissions.add(submission), submission.then(
86356
86479
  () => activeShellSubmissions.delete(submission),
@@ -89197,7 +89320,7 @@ async function redelegateRepoStateReadQuietly(deps) {
89197
89320
  if (!repoStateRedelegationsInFlight.has(workspaceId)) {
89198
89321
  repoStateRedelegationsInFlight.add(workspaceId);
89199
89322
  try {
89200
- let workingDir = args.quorumLoop.getWorkingDir(), detected = typeof args.quorumLoop.getDetectedAgents == "function" ? args.quorumLoop.getDetectedAgents() : [], { agent } = selectImplementorAgent(detected), brief = renderFamiliarizeAgentBrief(
89323
+ let workingDir = args.quorumLoop.getWorkingDir(), detected = typeof args.quorumLoop.getDetectedAgents == "function" ? args.quorumLoop.getDetectedAgents() : [], pref = readImplementorPreferenceSync(), { agent } = selectImplementorAgent(detected, null, [], pref.priorityOrder), brief = renderFamiliarizeAgentBrief(
89201
89324
  "The repository HEAD moved since the last codebase overview. Re-read the codebase and produce an updated structural overview."
89202
89325
  ), baseIntent = agentMentionIntentFromOverride(agent), intent = baseIntent ? { ...baseIntent, promptForPlanning: brief } : {
89203
89326
  target: "CLAUDE",
@@ -89277,7 +89400,7 @@ async function routeFamiliarize(deps) {
89277
89400
  let state = store.getState(), frontierAvailable = !!(args.localExecutor && args.quorumLoop);
89278
89401
  if (state.structuralSummary && frontierAvailable)
89279
89402
  try {
89280
- let workingDir = args.quorumLoop.getWorkingDir(), detected = typeof args.quorumLoop.getDetectedAgents == "function" ? args.quorumLoop.getDetectedAgents() : [], { agent } = selectImplementorAgent(detected), brief = renderFamiliarizeAgentBrief(deps.userPrompt), baseIntent = agentMentionIntentFromOverride(agent), intent = baseIntent ? { ...baseIntent, promptForPlanning: brief } : {
89403
+ let workingDir = args.quorumLoop.getWorkingDir(), detected = typeof args.quorumLoop.getDetectedAgents == "function" ? args.quorumLoop.getDetectedAgents() : [], pref = readImplementorPreferenceSync(), { agent } = selectImplementorAgent(detected, null, [], pref.priorityOrder), brief = renderFamiliarizeAgentBrief(deps.userPrompt), baseIntent = agentMentionIntentFromOverride(agent), intent = baseIntent ? { ...baseIntent, promptForPlanning: brief } : {
89281
89404
  target: "CLAUDE",
89282
89405
  rawMention: "@claude",
89283
89406
  isLeadingControlToken: !0,
@@ -89373,6 +89496,61 @@ function renderFamiliarizeAgentBrief(userPrompt) {
89373
89496
  ].join(`
89374
89497
  `);
89375
89498
  }
89499
+ async function routeDocumentInspectionAdvisory(deps) {
89500
+ let { store, args, userPrompt } = deps;
89501
+ if (!args.localExecutor || !args.quorumLoop)
89502
+ return store.dispatch({
89503
+ type: "SHELL_ADVISORY",
89504
+ source: "shell",
89505
+ text: "A read-capable model is required to inspect and summarize documents in this workspace. No task was started and no files were modified."
89506
+ }), !1;
89507
+ let workingDir = args.quorumLoop.getWorkingDir(), detected = typeof args.quorumLoop.getDetectedAgents == "function" ? args.quorumLoop.getDetectedAgents() : [], pref = readImplementorPreferenceSync(), { agent } = selectImplementorAgent(detected, null, [], pref.priorityOrder), baseIntent = agentMentionIntentFromOverride(agent), intent = baseIntent ? { ...baseIntent, promptForPlanning: userPrompt } : {
89508
+ target: "CLAUDE",
89509
+ rawMention: "@claude",
89510
+ isLeadingControlToken: !1,
89511
+ promptForPlanning: userPrompt,
89512
+ tokenStartUtf16: 0,
89513
+ tokenEndUtf16: 0
89514
+ }, showSpinner = store.getState().progress === null;
89515
+ showSpinner && deps.onProgress?.({
89516
+ phase: "advisory_dispatched",
89517
+ agents: [agentDisplayName(agent)]
89518
+ });
89519
+ try {
89520
+ let result = await runReadOnlyAgentAdvisoryResult({
89521
+ shellArgs: args,
89522
+ agent,
89523
+ intent,
89524
+ advisoryBrief: userPrompt,
89525
+ workingDir
89526
+ });
89527
+ if (result.ok) {
89528
+ let output = sanitizeForTerminal(result.text);
89529
+ return store.dispatch({
89530
+ type: "SHELL_ADVISORY",
89531
+ source: "shell",
89532
+ text: output
89533
+ }), !0;
89534
+ } else {
89535
+ let failureMessage = "A read-capable model is required to inspect and summarize documents in this workspace. No task was started and no files were modified.";
89536
+ return result.usage.unavailableReason === "workspace_mutation_detected" ? failureMessage = "A workspace mutation was detected during document inspection. Please inspect the workspace." : result.usage.unavailableReason === "workspace_verification_unavailable" ? failureMessage = "Workspace integrity could not be verified following document inspection." : result.timedOut && (failureMessage = "Document inspection timed out. No task was started and no files were modified."), store.dispatch({
89537
+ type: "SHELL_ADVISORY",
89538
+ source: "shell",
89539
+ text: failureMessage
89540
+ }), !1;
89541
+ }
89542
+ } catch (err) {
89543
+ return logger.warn("[orchestration-shell] document inspection advisory failed", {
89544
+ error: err.message
89545
+ }), store.dispatch({
89546
+ type: "SHELL_ADVISORY",
89547
+ source: "shell",
89548
+ text: "Document inspection encountered an unexpected error. Please inspect the workspace."
89549
+ }), !1;
89550
+ } finally {
89551
+ showSpinner && deps.onProgress?.({ phase: "waiting_user" });
89552
+ }
89553
+ }
89376
89554
  async function routeBrainstorm(deps) {
89377
89555
  let {
89378
89556
  store,
@@ -91090,7 +91268,7 @@ async function handleShellUserInput(deps) {
91090
91268
  wallClockMsRemaining: 3e4,
91091
91269
  reviseAttempts: 0
91092
91270
  }
91093
- }, decision, pendingStartConfirmation, showClassifySpinner = store.getState().progress === null, classifyPipeline = args.localAdvisoryRunner, stopClassifyRelabel;
91271
+ }, decision, pendingStartConfirmation, isDemotedDocumentInspection = !1, showClassifySpinner = store.getState().progress === null, classifyPipeline = args.localAdvisoryRunner, stopClassifyRelabel;
91094
91272
  showClassifySpinner && (dispatchProgress({
91095
91273
  phase: "planner_classifying",
91096
91274
  ...classifyPipeline ? { runtimeNoun: progressRuntimeNoun(classifyPipeline) } : {}
@@ -91106,20 +91284,71 @@ async function handleShellUserInput(deps) {
91106
91284
  } finally {
91107
91285
  stopClassifyRelabel?.();
91108
91286
  }
91109
- if (logger.info("[orchestration-shell] Planner classified input", {
91287
+ logger.info("[orchestration-shell] Planner classified input", {
91110
91288
  prompt: plannerInput.prompt,
91111
91289
  action: decision.action,
91112
91290
  rationale: decision.rationale
91113
- }), decision.action === "browse" && hasFileMutationIntent(plannerInput.prompt) && (decision = {
91114
- action: "start_task",
91115
- rationale: decision.rationale ? `${decision.rationale} (promoted to start_task due to file mutation intent)` : "web request with file mutation intent"
91116
- }), turnAttachments.length > 0 && decision.action === "ask_user" && isBlindImageClarification(plannerInput.prompt, decision.clarifying_question) && !hasFileMutationIntent(plannerInput.prompt) && !isDestructiveFileRequest(plannerInput.prompt) && (decision = {
91117
- action: "advisory_response",
91118
- rationale: decision.rationale || "analyze and answer inquiry about the attached image"
91119
- }), freshRetainedPage && decision.action === "ask_user" && isPromptRelevantToPage && !hasFileMutationIntent(plannerInput.prompt) && !isDestructiveFileRequest(plannerInput.prompt) && (decision = {
91120
- action: "advisory_response",
91121
- rationale: decision.rationale || "answer inquiry using retained web page context"
91122
- }), decision.action === "start_task" && plannerInput.clarifications.length === 0 && isDestructiveFileRequest(plannerInput.prompt))
91291
+ }), isDemotedDocumentInspection = !1;
91292
+ let gemmaEvaluatedIntent = !1, allTurnTexts = [
91293
+ plannerInput.prompt,
91294
+ ...plannerInput.clarifications.map((c) => c.answer)
91295
+ ];
91296
+ if ((decision.action === "start_task" || decision.action === "browse") && args.localAdvisoryRunner && process.env.CODEVIBE_INTENT_CLASSIFIER !== "regex") {
91297
+ let gemmaIntent = await classifyPromptIntentWithGemma(
91298
+ { prompt: plannerInput.prompt, clarifications: plannerInput.clarifications },
91299
+ args.localAdvisoryRunner
91300
+ );
91301
+ if (gemmaIntent.source === "model")
91302
+ gemmaEvaluatedIntent = !0, decision.action === "browse" ? gemmaIntent.is_code_or_disk_mutation && (logger.info(
91303
+ "[orchestration-shell] Gemma intent classifier: promoting browse to start_task with code/disk mutation",
91304
+ { prompt: plannerInput.prompt, rationale: gemmaIntent.rationale }
91305
+ ), decision = {
91306
+ action: "start_task",
91307
+ rationale: decision.rationale ? `${decision.rationale} (promoted to start_task via Gemma intent classifier)` : gemmaIntent.rationale
91308
+ }) : gemmaIntent.is_code_or_disk_mutation ? logger.info(
91309
+ "[orchestration-shell] Gemma intent classifier: confirmed start_task with code/disk mutation",
91310
+ { prompt: plannerInput.prompt, rationale: gemmaIntent.rationale }
91311
+ ) : gemmaIntent.action === "familiarize" && !gemmaIntent.requires_file_read ? (logger.info(
91312
+ "[orchestration-shell] Gemma intent classifier: demoting start_task to familiarize",
91313
+ { prompt: plannerInput.prompt, rationale: gemmaIntent.rationale }
91314
+ ), decision = {
91315
+ action: "familiarize",
91316
+ rationale: decision.rationale ? `${decision.rationale} (demoted to familiarize via Gemma intent classifier)` : gemmaIntent.rationale
91317
+ }) : (logger.info(
91318
+ "[orchestration-shell] Gemma intent classifier: demoting start_task to advisory_response",
91319
+ { prompt: plannerInput.prompt, rationale: gemmaIntent.rationale }
91320
+ ), gemmaIntent.requires_file_read && (isDemotedDocumentInspection = !0), decision = {
91321
+ action: "advisory_response",
91322
+ rationale: decision.rationale ? `${decision.rationale} (demoted to advisory_response via Gemma intent classifier)` : gemmaIntent.rationale,
91323
+ advisory_summary: void 0
91324
+ });
91325
+ else if (gemmaIntent.source === "semantic_fail_closed")
91326
+ gemmaEvaluatedIntent = !0, logger.warn(
91327
+ "[orchestration-shell] Gemma intent classifier: semantic fail-closed; asking user to clarify intent",
91328
+ { rationale: gemmaIntent.rationale }
91329
+ ), decision = {
91330
+ action: "ask_user",
91331
+ rationale: gemmaIntent.rationale,
91332
+ clarifying_question: "Could you please clarify whether you would like to inspect/read files or modify code on disk?"
91333
+ };
91334
+ else {
91335
+ gemmaEvaluatedIntent = !0;
91336
+ let outageMessage = "Model service is temporarily unavailable. CodeVibe cannot process requests without a responsive model.";
91337
+ logger.warn(
91338
+ "[orchestration-shell] Gemma intent classifier: infrastructure outage; halting with user outage advisory",
91339
+ { rationale: gemmaIntent.rationale }
91340
+ ), store.dispatch({
91341
+ type: "PLANNER_DECISION",
91342
+ decision: {
91343
+ action: "advisory_response",
91344
+ rationale: gemmaIntent.rationale,
91345
+ advisory_summary: outageMessage
91346
+ }
91347
+ }), clearPendingClarificationIfPresent(store);
91348
+ return;
91349
+ }
91350
+ }
91351
+ if (decision.action === "start_task" && plannerInput.clarifications.length === 0 && isDestructiveFileRequest(plannerInput.prompt))
91123
91352
  logger.warn(
91124
91353
  "[orchestration-shell] P43 backstop: a destructive file request was classified start_task without a confirmation this turn; asking first",
91125
91354
  { rationale: decision.rationale }
@@ -91232,7 +91461,7 @@ async function handleShellUserInput(deps) {
91232
91461
  } : void 0, isImageAdvisory = decision.action === "advisory_response" && turnAttachments.length > 0, mentionIntentForLocalSuppression = mentionIntent ?? agentMentionIntentFromOverride(effectiveExplicitAgentOverride), suppressMentionLocalAnswer = shouldSuppressMentionLocalAnswer(
91233
91462
  mentionIntentForLocalSuppression,
91234
91463
  decision
91235
- ), contextualAdvisoryTurns = decision.action === "advisory_response" && !isImageAdvisory && !suppressMentionLocalAnswer && args.localAdvisoryRunner ? collectPriorBrainstormTurns(store.getState().conversation, dispatchText) : [], isTextAdvisory = decision.action === "advisory_response" && !isImageAdvisory && !suppressMentionLocalAnswer && !!args.localAdvisoryRunner, reducerDecision = isImageAdvisory ? { ...decision, advisory_summary: void 0, clarifying_question: void 0, rationale: "" } : isTextAdvisory ? { ...decision, advisory_summary: void 0, clarifying_question: void 0, rationale: "" } : suppressMentionLocalAnswer ? { ...decision, advisory_summary: void 0, clarifying_question: void 0, rationale: "" } : decision.action === "team_decompose" || decision.action === "familiarize" || decision.action === "brainstorm" || // WEB-BROWSING (Stage-2-r3 MED): strip any advisory_summary/clarifying_question
91464
+ ), contextualAdvisoryTurns = decision.action === "advisory_response" && !isImageAdvisory && !suppressMentionLocalAnswer && args.localAdvisoryRunner ? collectPriorBrainstormTurns(store.getState().conversation, dispatchText) : [], isTextAdvisory = decision.action === "advisory_response" && !isImageAdvisory && !suppressMentionLocalAnswer && !!args.localAdvisoryRunner, reducerDecision = isImageAdvisory ? { ...decision, advisory_summary: void 0, clarifying_question: void 0, rationale: "" } : isTextAdvisory ? { ...decision, advisory_summary: void 0, clarifying_question: void 0, rationale: "" } : suppressMentionLocalAnswer ? { ...decision, advisory_summary: void 0, clarifying_question: void 0, rationale: "" } : isDemotedDocumentInspection ? { ...decision, advisory_summary: void 0, clarifying_question: void 0, rationale: "" } : decision.action === "team_decompose" || decision.action === "familiarize" || decision.action === "brainstorm" || // WEB-BROWSING (Stage-2-r3 MED): strip any advisory_summary/clarifying_question
91236
91465
  // off a `browse` so no ungrounded planner text renders before the fetched answer.
91237
91466
  decision.action === "browse" ? { ...decision, advisory_summary: void 0, clarifying_question: void 0 } : decision;
91238
91467
  if (store.dispatch({
@@ -91240,7 +91469,21 @@ async function handleShellUserInput(deps) {
91240
91469
  decision: reducerDecision,
91241
91470
  ...brainstormMetadata ? { brainstorm: brainstormMetadata } : {},
91242
91471
  ...pendingStartConfirmation ? { startConfirmation: pendingStartConfirmation } : {}
91243
- }), suppressMentionLocalAnswer && mentionIntentForLocalSuppression) {
91472
+ }), isDemotedDocumentInspection && !suppressMentionLocalAnswer) {
91473
+ let advisoryBrief = composeReadOnlyAdvisoryBrief(
91474
+ pendingForPlanning,
91475
+ plannerPromptText,
91476
+ answeredThisTurn
91477
+ );
91478
+ await routeDocumentInspectionAdvisory({
91479
+ store,
91480
+ args,
91481
+ userPrompt: advisoryBrief,
91482
+ onProgress: deps.onProgress
91483
+ });
91484
+ return;
91485
+ }
91486
+ if (suppressMentionLocalAnswer && mentionIntentForLocalSuppression) {
91244
91487
  let carriedMentionTargets = mentionTargets.length > 0 ? mentionTargets : latestMentionTargetsFromPendingClarification(pending2, answeredThisTurn), multiDirectedCarried = carriedMentionTargets.length > 1 && !carriedMentionTargets.includes("ALL"), advisoryBrief = composeReadOnlyAdvisoryBrief(
91245
91488
  multiDirectedCarried ? pending2 : pendingForPlanning,
91246
91489
  multiDirectedCarried ? dispatchText : plannerPromptText,
@@ -97671,14 +97914,16 @@ async function triggerStartupOrphanSweep(appsyncClient, currentSessionId, staleT
97671
97914
  ownerRootDir: shadowEnv?.ownerRootDir ?? processOwnerRoot(),
97672
97915
  ...shadowEnv
97673
97916
  };
97674
- return await reapOrphanShadows(/* @__PURE__ */ new Set(), env).catch((err) => {
97917
+ await reapOrphanShadows(/* @__PURE__ */ new Set(), env).catch((err) => {
97675
97918
  logger.warn("[cli] shadow orphan startup sweep error (non-fatal)", {
97676
97919
  err: err?.message
97677
97920
  });
97678
- }), await appsyncClient.sweepOrphanSessions({
97921
+ });
97922
+ let envExcludes = (process.env.CODEVIBE_SWEEP_EXCLUDE_SESSION_IDS ?? "").split(",").map((s) => s.trim()).filter(Boolean), excludeSessionIds = Array.from(/* @__PURE__ */ new Set([currentSessionId, ...envExcludes]));
97923
+ return await appsyncClient.sweepOrphanSessions({
97679
97924
  agentType: "CODEVIBE" /* CODEVIBE */,
97680
97925
  staleThresholdMs,
97681
- excludeSessionIds: [currentSessionId]
97926
+ excludeSessionIds
97682
97927
  });
97683
97928
  } catch (err) {
97684
97929
  return logger.warn("[cli] startup orphan sweep failed (non-fatal)", {
@@ -61,6 +61,24 @@ export declare function buildCommandIntentMetadata(text: string): CommandIntentM
61
61
  * Supports language-agnostic URLs, as well as English, Chinese, and Japanese web search intents.
62
62
  */
63
63
  export declare function isWebAccessNeeded(text: string): boolean;
64
+ /**
65
+ * Common file and document extensions for code, documentation, scripts, data, and office files.
66
+ */
67
+ export declare const DOCUMENT_AND_CODE_EXTENSIONS = "(?:pdf|docx|doc|xlsx|xls|csv|tsv|txt|md|markdown|json|yaml|yml|toml|env|log|ts|js|tsx|jsx|py|rs|go|java|c|cpp|h|html|css|sql|sh)";
68
+ /**
69
+ * Strips negated mutation verb phrases (e.g. "do not fix ...", "don't modify ...",
70
+ * "without changing any code", "不做修改", "修正しないで", "수정하지 말고", "do not write report.md")
71
+ * from text so that negative constraints do not trigger mutation action verbs,
72
+ * while preserving any independent affirmative mutation instructions in the same clause.
73
+ */
74
+ export declare function stripNegatedMutationSpans(text: string): string;
75
+ /**
76
+ * Helper to recognize source content references that describe entities or topics inside a file or database
77
+ * (e.g. "generate a list of the fields in config.json", "generate a summary of the functions in README.md",
78
+ * "generate a summary of the error handling in auth.ts", "output a list of the functions in auth.sh")
79
+ * rather than write destinations.
80
+ */
81
+ export declare function isGenerateSourceContentRef(target: string, hasWebContext?: boolean): boolean;
64
82
  /**
65
83
  * Detects whether a prompt expresses intent to create, write, save, or modify local files/reports,
66
84
  * as opposed to a purely read-only conversational request.
@@ -0,0 +1,48 @@
1
+ export type PromptIntentAction = 'start_task' | 'familiarize' | 'advisory_response' | 'browse' | 'brainstorm' | 'ask_user';
2
+ export type PromptIntentSource = 'model' | 'semantic_fail_closed' | 'infrastructure_outage';
3
+ export interface PromptIntentClassification {
4
+ action: PromptIntentAction;
5
+ is_code_or_disk_mutation: boolean;
6
+ confidence: 'high' | 'low';
7
+ rationale: string;
8
+ source: PromptIntentSource;
9
+ requires_file_read?: boolean;
10
+ }
11
+ export interface GemmaIntentPort {
12
+ classify(req: {
13
+ prompt: string;
14
+ jsonSchema?: Record<string, unknown>;
15
+ maxOutputTokens: number;
16
+ signal?: AbortSignal;
17
+ timeoutMs?: number;
18
+ }): Promise<{
19
+ text: string;
20
+ }>;
21
+ }
22
+ export declare const INTENT_CLASSIFIER_JSON_SCHEMA: Record<string, unknown>;
23
+ export declare function buildIntentClassifierPrompt(prompt: string, clarifications?: {
24
+ question: string;
25
+ answer: string;
26
+ }[]): string;
27
+ export declare function parseIntentGemmaResponse(raw: string): PromptIntentClassification | null;
28
+ /**
29
+ * Detect whether an error represents a genuine infrastructure transport/network/timeout outage
30
+ * rather than a model semantic, contract, capability, or internal programming error.
31
+ * Only genuine infrastructure outages permit falling back to secondary regex heuristics (Codex R50-F4, Claude NB2).
32
+ */
33
+ export declare function isInfrastructureTransportOutage(err: unknown): boolean;
34
+ /**
35
+ * Classify a user turn using Gemma with structured JSON.
36
+ * Returns `PromptIntentClassification`.
37
+ * Always fails closed to `start_task` on any error or ambiguity.
38
+ */
39
+ export declare function classifyPromptIntentWithGemma(input: {
40
+ prompt: string;
41
+ clarifications?: {
42
+ question: string;
43
+ answer: string;
44
+ }[];
45
+ }, port: GemmaIntentPort, opts?: {
46
+ timeoutMs?: number;
47
+ signal?: AbortSignal;
48
+ }): Promise<PromptIntentClassification>;
@@ -343,7 +343,7 @@ export { reducer } from './reducer';
343
343
  export { createOrchestrationStore, type OrchestrationStore } from './store';
344
344
  export { routeBrowse, RETAINED_PAGE_MAX_CHARS, type RouteBrowseDeps, type RetainedBrowsePage, } from './route-browse';
345
345
  export { composeBrainstormPanelBrief, fitTextToBudget, MAX_BRAINSTORM_PAGE_CHARS, MAX_BRAINSTORM_PAGE_TOKENS, MAX_BRAINSTORM_PAGE_BYTES, } from './brainstorm-quorum';
346
- export { extractQueryRelevantSnippets, isPromptRelevantToRetainedPage, htmlToText } from './web/extract';
346
+ export { extractQueryRelevantSnippets, isPromptRelevantToRetainedPage, isBlindBrowseClarification, htmlToText } from './web/extract';
347
347
  export { validateAgyArgPrompt, AGY_ARG_PROMPT_MAX_UTF8_BYTES, } from '../agy-cli-contract';
348
348
  export type { Mode, Tier, PlannerDecision, AgentKind, PlannerHealthState, RunningTaskState, ReviewerSeatState, GateState, ExecutionEventEntry, RefusalEventEntry, BypassEventEntry, MobileEventEntry, EventStreamEntry, ConversationEntry, QueuedTask, PendingClarification, OrchestrationState, OrchestrationAction, LastModeFile, TeamState, TeamTrackEntry, TeamTrackState, TeamMergeGateStatus, LiveProgress, } from './types';
349
349
  export { formatElapsed, isSpinnerPhase, renderProgressLine, type TaskProgressEvent, type OnProgress, } from './task-progress';
@@ -925,6 +925,35 @@ export declare function routeFamiliarize(deps: {
925
925
  userPrompt?: string;
926
926
  onProgress?: (event: TaskProgressEvent) => void;
927
927
  }): Promise<void>;
928
+ /**
929
+ * Routes a bare document inspection or file summarization inquiry
930
+ * (e.g. "Pick a file and summarize its numbers and key details", "Summarize package.json", "Summarize notice.pdf")
931
+ * to a read-only frontier agent in plan mode.
932
+ *
933
+ * When a frontier agent is available (`localExecutor` + `quorumLoop`):
934
+ * - Selects the default implementor agent from detected agents (default CLAUDE or ANTIGRAVITY).
935
+ * - Spawns the read-only agent via `runReadOnlyAgentAdvisoryResult` in plan mode.
936
+ * - The agent reads the file(s) and produces grounded document facts.
937
+ * - Dispatches the sanitized text to `store` as `SHELL_ADVISORY`.
938
+ * - NEVER calls `writeRepoState` and NEVER creates a task or shadow workspace.
939
+ *
940
+ * When no frontier agent is wired or invocation fails:
941
+ * - Fails closed with an explicit user-facing message explaining that a read-capable model is required.
942
+ * - NEVER displays internal classifier rationale as the user's answer.
943
+ */
944
+ /**
945
+ * Parses numbered or disjunctive alternatives from a clarifying question string.
946
+ * Supports:
947
+ * - Numbered lists: "1. View in chat 2. Group in chat 3. Write summary to report.md" or "1) ... 2) ..."
948
+ * - Disjunctive lists: "A, B, or C?" or "A or B?"
949
+ */
950
+ export declare function parseNumberedOptions(question: string): string[];
951
+ export declare function routeDocumentInspectionAdvisory(deps: {
952
+ store: OrchestrationStore;
953
+ args: RunOrchestrationShellArgs;
954
+ userPrompt: string;
955
+ onProgress?: (event: TaskProgressEvent) => void;
956
+ }): Promise<boolean>;
928
957
  export declare function routeBrainstorm(deps: {
929
958
  store: OrchestrationStore;
930
959
  args: RunOrchestrationShellArgs;
@@ -56,3 +56,9 @@ export declare function isPromptRelevantToRetainedPage(prompt: string, retainedP
56
56
  title?: string;
57
57
  text?: string;
58
58
  } | null): boolean;
59
+ /**
60
+ * Detects whether a planner clarifying question is a blind deflection regarding web browsing
61
+ * (e.g. asking for a URL, link, or website address because the model lacks awareness of the retained page),
62
+ * as opposed to a genuine question about user preferences, sections, files, or instructions.
63
+ */
64
+ export declare function isBlindBrowseClarification(clarifyingQuestion?: string): boolean;