From 01edf95e54d0759652695142223840f4ef3ba318 Mon Sep 17 00:00:00 2001 From: code-crusher Date: Fri, 21 Aug 2026 10:00:41 +0530 Subject: [PATCH 1/2] release: v6.7.8 - Version bump 6.7.7 -> 6.7.8 (package.json, package-lock.json) - Investigation efficiency guidance in system prompt (classify comprehension vs implementation, form hypothesis before searching, read call sites not internals, stop when answerable) - Zero-result guidance in search_files executor (tighten/simplify regex, widen path scope, stop after 2+ failed attempts) - Tool description improvements: read_file (no prose reads for control flow, no region re-reads) and search_files (narrowest path scope, stop after 2+ zero-result searches) --- CHANGELOG.md | 6 ++++++ package-lock.json | 4 ++-- package.json | 2 +- src/prompts/system.ts | 10 ++++++++++ src/tools/executors/searchFiles.ts | 13 ++++++++++++- src/tools/schemas/read_file.ts | 2 +- src/tools/schemas/search_files.ts | 2 +- 7 files changed, 33 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fca9a0..f7594c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- **Investigation efficiency guidance in system prompt.** Added an "Investigation efficiency" section to the tool guide (`src/prompts/system.ts`) that directs the agent to classify comprehension questions separately from implementation tasks, form a one-line hypothesis before searching, read call sites rather than implementation internals, avoid reading prose/content when the question is about control flow, and stop exploring as soon as it can answer. +- **Zero-result guidance in `search_files`.** `searchFiles.ts` executor now appends actionable guidance when a search returns 0 matches, directing the model to tighten or simplify the regex, widen the path scope, try a different glob, or stop searching after 2+ failed attempts. +- **Native tool description improvements.** The `read_file` schema description now tells the model not to read file contents (prompt text, config values, prose) when investigating control flow, and not to re-read regions already read earlier. The `search_files` schema description now tells the model to scope the path to the narrowest plausible directory and to stop after 2+ zero-result searches. + +### Changed + - **Default model is now `axon-auto-232k`.** The previous default (`axon-eido-3.2-code-mini-232k`) is preserved as a paid option (`axon-auto` now dynamically picks Code, Code Pro, or Flash for each task). Auto is diff --git a/package-lock.json b/package-lock.json index a91ea25..3c49239 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@matterailab/orbcode", - "version": "6.7.6", + "version": "6.7.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@matterailab/orbcode", - "version": "6.7.6", + "version": "6.7.8", "license": "MIT", "dependencies": { "@ai-sdk/anthropic": "^3.0.85", diff --git a/package.json b/package.json index 8c089f9..769436a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@matterailab/orbcode", - "version": "6.7.7", + "version": "6.7.8", "description": "OrbCode CLI — agentic coding in your terminal, powered by Axon models by MatterAI", "type": "module", "bin": { diff --git a/src/prompts/system.ts b/src/prompts/system.ts index e1de5fd..e5e23f7 100644 --- a/src/prompts/system.ts +++ b/src/prompts/system.ts @@ -215,6 +215,16 @@ If \`Next cursor\` is \`none\`, the search is complete: stop and never pass the - Investigate first, edit second. Once the root cause is confirmed, write out the full change plan — which files, the exact locations, and the edit order — BEFORE touching anything. - Then execute the edits in one pass (batched via \`multi_file_edit\`) and verify with a single typecheck/build at the end, rather than alternating between editing and checking. +## Investigation efficiency + +Before every tool call, ask: "Will this result change my answer or my implementation?" If no, do not make the call. + +- **Classify the question first.** Is this a comprehension question ("how does X work?", "is this by design or a bug?") or an implementation task? Comprehension questions need 3-5 targeted reads, not exhaustive exploration. +- **Form a hypothesis, then verify.** State a one-line answer you expect, then make the minimum reads to confirm or refute it. Do not explore speculatively. +- **Read the call site, not the implementation.** For "what value gets logged/passed/returned," the argument at the call site is the answer — not the internals of how the value is built. +- **Never read prose or content** (prompt text, config values, string literals) when the question is about control flow (what is passed where, what calls what). +- **Stop when you can answer.** Once you have enough to answer the user's question, stop exploring. Do not read additional files "for completeness." + ## update_todo_list **Description:** diff --git a/src/tools/executors/searchFiles.ts b/src/tools/executors/searchFiles.ts index 06baae5..0b7a0c0 100644 --- a/src/tools/executors/searchFiles.ts +++ b/src/tools/executors/searchFiles.ts @@ -82,7 +82,18 @@ export async function searchFiles(args: Record, context: ToolCo } } - return { text: formatSearchPage(page) } + const output = formatSearchPage(page) + + // forked_change: append guidance when a search returns no matches, + // steering the model toward tightening/loosening the regex or scoping + // the path instead of blindly retrying with a slightly different pattern. + if (output.includes("Matches: 0")) { + return { + text: output + "\n\nNo matches found. Before retrying:\n- Tighten or simplify the regex (e.g. use a shorter, more specific pattern).\n- Widen the path scope (e.g. search from the repo root instead of a subdirectory).\n- Try a different file_pattern glob.\n- If you have already searched 2+ times with no results, stop searching and reason from what you already know.", + } + } + + return { text: output } } catch (error) { return { text: `Error searching files:\n${error instanceof Error ? error.message : String(error)}`, isError: true } } finally { diff --git a/src/tools/schemas/read_file.ts b/src/tools/schemas/read_file.ts index 28e43a7..2afb1e3 100644 --- a/src/tools/schemas/read_file.ts +++ b/src/tools/schemas/read_file.ts @@ -5,7 +5,7 @@ export const read_file = { function: { name: "read_file", description: - "Read one or more files and return line-numbered contents. Batch every independent file or region needed for the current investigation into this single call. Prefer 200-1000 lines per source-code region; for files up to 1000 lines, omit offset and limit to read the file once. Do not walk adjacent regions through many small calls. Each requested region is capped at 1000 lines.", + "Read one or more files and return line-numbered contents. Batch every independent file or region needed for the current investigation into this single call. Prefer 200-1000 lines per source-code region; for files up to 1000 lines, omit offset and limit to read the file once. Do not walk adjacent regions through many small calls. Each requested region is capped at 1000 lines. Do not read file contents (prompt text, config values, prose) when investigating control flow — read the call site, not the implementation. If a region was already read earlier in the conversation, do not re-read it; use the earlier content.", strict: true, parameters: { type: "object", diff --git a/src/tools/schemas/search_files.ts b/src/tools/schemas/search_files.ts index 48e05ac..7af4569 100644 --- a/src/tools/schemas/search_files.ts +++ b/src/tools/schemas/search_files.ts @@ -5,7 +5,7 @@ export default { function: { name: "search_files", description: - "Search file contents recursively under a directory using a Rust-compatible regex and optional file glob. Returns a compact, paginated page with at most three matches per file; use context_lines 0 for discovery, then read the relevant file. Continue only with the opaque cursor returned by the same path, regex, and file_pattern; pass JSON null without quotes for the first page. If Next cursor is none, the search is complete: stop and never pass the word none. A rare FFF continuation failure may restart with ripgrep and is marked Restarted: yes.", + "Search file contents recursively under a directory using a Rust-compatible regex and optional file glob. Returns a compact, paginated page with at most three matches per file; use context_lines 0 for discovery, then read the relevant file. Continue only with the opaque cursor returned by the same path, regex, and file_pattern; pass JSON null without quotes for the first page. If Next cursor is none, the search is complete: stop and never pass the word none. A rare FFF continuation failure may restart with ripgrep and is marked Restarted: yes. Scope path to the narrowest plausible directory instead of searching from the repository root. If a search returns 0 matches, tighten or simplify the regex rather than retrying with a slightly different pattern. After 2+ searches with no results, stop and reason from what you already know.", strict: true, parameters: { type: "object", From 03a2f21472977d2601de8f19901171758cdcfd4e Mon Sep 17 00:00:00 2001 From: code-crusher Date: Fri, 21 Aug 2026 10:12:29 +0530 Subject: [PATCH 2/2] fix: use page.matches.length instead of string-matching for zero-result guidance Code review found that output.includes('Matches: 0') could false-positive when matched file content contains that literal text. The page object is directly available in the executor, so check page.matches.length === 0. --- src/tools/executors/searchFiles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/executors/searchFiles.ts b/src/tools/executors/searchFiles.ts index 0b7a0c0..b4a0435 100644 --- a/src/tools/executors/searchFiles.ts +++ b/src/tools/executors/searchFiles.ts @@ -87,7 +87,7 @@ export async function searchFiles(args: Record, context: ToolCo // forked_change: append guidance when a search returns no matches, // steering the model toward tightening/loosening the regex or scoping // the path instead of blindly retrying with a slightly different pattern. - if (output.includes("Matches: 0")) { + if (page.matches.length === 0) { return { text: output + "\n\nNo matches found. Before retrying:\n- Tighten or simplify the regex (e.g. use a shorter, more specific pattern).\n- Widen the path scope (e.g. search from the repo root instead of a subdirectory).\n- Try a different file_pattern glob.\n- If you have already searched 2+ times with no results, stop searching and reason from what you already know.", }