Skip to content

Comments

Utilize pipelining of grep_search -> read_file to eliminate turns#19574

Merged
gundermanc merged 23 commits intomainfrom
gundermanc/pipeline-greps
Feb 21, 2026
Merged

Utilize pipelining of grep_search -> read_file to eliminate turns#19574
gundermanc merged 23 commits intomainfrom
gundermanc/pipeline-greps

Conversation

@gundermanc
Copy link
Member

@gundermanc gundermanc commented Feb 19, 2026

Summary

Utilize 'pipelining' of tool calls, where we selectively optimize common multi-turn tool call sequences to eliminate unnecessary turns.

This change specifically:

  • Modifies grep_search to return file content in the response if there are 3 or fewer results. This enables the agent to skip turns that would be spent grepping -> reading, particularly when doing unambiguous searches, like navigating to a class or function definition via grep "class Foo".

  • Modifies write_file to return a diff of the file content in the response, helping the agent to avoid the need to do verification reads after writing a file. This is particularly important given the fuzzy matching strategy we use when editing files. The little corrections the tool makes makes it so that what is written might not exactly match what the agent expected.

Analysis

Nets a stat-sig 10% drop in turn count in SWEBench.

 Task-Wise Turn Percentiles



  ┌───────────────────┬────────────────────────────────┬───────────────────────────┬──────────────────┬────────────────────────────┐
  │ Percentile        │ Baseline (pipelining-baseline) │ Experimental (pipelining) │ Delta            │ Significance (p-value)     │
  ├───────────────────┼────────────────────────────────┼───────────────────────────┼──────────────────┼────────────────────────────┤
  │ 50th (Median) │ 49                             │ 44                        │ -5 (-10.2%)  │ 0.019 (Significant)    │
  │ 75th          │ 67                             │ 59                        │ -8 (-11.9%)  │ 0.003 (Highly Sig)     │
  │ 90th          │ 85                             │ 79                        │ -6 (-7.1%)       │ 0.167 (Not Sig)            │
  │ 95th          │ 104                            │ 89                        │ -15 (-14.4%) │ 0.088 (Marginally Sig) │
  │ 99th          │ 145                            │ 131                       │ -14 (-9.7%)      │ 0.193 (Not Sig)            │
  └───────────────────┴────────────────────────────────┴───────────────────────────┴──────────────────┴────────────────────────────┘

Token consumption

Ranging between neutral and a mild improvement

  ┌───────────────────────┬────────────────────────────────┬───────────────────────────┬──────────────────────┬────────────────────────────┐
  │ Metric                │ Baseline (pipelining-baseline) │ Experimental (pipelining) │ Delta                │ Significance (p-value)     │
  ├───────────────────────┼────────────────────────────────┼───────────────────────────┼──────────────────────┼────────────────────────────┤
  │ Aggregate (Total) │ 980.5M                         │ 945.8M                    │ -34.7M (-3.5%)   │ Derived from Mean        │
  │ Average (Mean)    │ 1.99M                          │ 1.90M                     │ -87.7k (-4.4%)   │ 0.437 (Not Sig)            │
  │ 50th (Median)     │ 1.41M                          │ 1.43M                     │ +12.9k (+0.9%)       │ 0.850 (Not Sig)            │
  │ 75th Percentile   │ 2.47M                          │ 2.23M                     │ -239.7k (-9.7%)  │ 0.096 (Marginally Sig) │
  │ 90th Percentile   │ 3.69M                          │ 3.64M                     │ -55.4k (-1.5%)       │ 0.754 (Not Sig)            │
  │ 95th Percentile   │ 5.47M                          │ 4.73M                     │ -743.0k (-13.6%) │ 0.489 (Not Sig)            │
  │ 99th Percentile   │ 11.17M                         │ 9.01M                     │ -2.15M (-19.3%)  │ 0.426 (Not Sig)            │
  └───────────────────────┴────────────────────────────────┴───────────────────────────┴──────────────────────┴────────────────────────────┘

Potential follow ups

Identify additional opportunities for pipelining of key workflows. Another that comes to mind is the write_file -> validate loop.

Details

Related Issues

How to Validate

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

…e efficiency

Analysis of Experiment 2 vs 3 showed that pruning grep_search results
caused the agent to lose context and enter redundant tool loops,
increasing turn counts by ~28%. This change restores full history
retention while keeping the readCache improvements.
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @gundermanc, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the user experience and efficiency of several core tools. It improves the clarity of file modification outputs by providing contextual code snippets, makes search results more informative by automatically including surrounding lines for a small number of matches, and optimizes file read operations through caching. These changes aim to provide more actionable and readable feedback from tool executions.

Highlights

  • Enhanced Tool Output Clarity: Implemented a new getDiffContextSnippet utility function in both edit and write-file tools to provide contextual code snippets in their success messages, making it easier to review changes.
  • Improved Grep Tool Context: The grep and ripGrep tools now automatically include contextual lines around search matches when the number of matches is small (1-3), enhancing the readability and usefulness of search results without explicit context requests.
  • ReadFile Tool Caching: Introduced caching for ReadFileTool invocations to improve performance, with an automatic cache invalidation mechanism triggered by file modification events.
  • Refactored Mock Message Bus: The MockMessageBus utility was refactored to extend Node.js's EventEmitter, simplifying its internal subscription and unsubscription logic.
Changelog
  • packages/core/src/core/geminiChat.ts
    • Added JSDoc comments to clarify the purpose of the extractCuratedHistory function.
  • packages/core/src/test-utils/mock-message-bus.ts
    • Refactored MockMessageBus to extend EventEmitter, removing manual subscription management.
    • Updated publish method to return a Promise.
    • Modified subscribe and unsubscribe methods to use EventEmitter's on and off methods.
    • Changed clear method to use removeAllListeners for complete cleanup.
  • packages/core/src/tools/edit.ts
    • Introduced a new getDiffContextSnippet utility function to generate contextual code snippets from file differences.
    • Integrated getDiffContextSnippet into EditToolInvocation to include updated code snippets in LLM success messages.
  • packages/core/src/tools/grep.test.ts
    • Updated existing grep tests to assert the presence of the new > prefix for matched lines.
    • Added a new test case to verify that the grep tool includes context lines when the number of matches is small.
  • packages/core/src/tools/grep.ts
    • Modified the GrepMatch interface to include an absolutePath property.
    • Implemented logic to automatically provide contextual lines around search matches when the total match count is between 1 and 3, and no explicit context was requested.
  • packages/core/src/tools/read-file.ts
    • Implemented a caching mechanism (readCache) for ReadFileTool invocations.
    • Added logic to clear the readCache when a tool_call_confirm event for 'edit' or 'write' operations is detected, ensuring cache freshness.
  • packages/core/src/tools/ripGrep.ts
    • Modified the GrepMatch interface to include an absolutePath property.
    • Implemented 'Greedy Grep' logic to automatically provide contextual lines around search matches when the total match count is between 1 and 3, and no explicit context was requested.
  • packages/core/src/tools/write-file.test.ts
    • Added a test case to verify that the write-file tool's llmContent includes the full updated file content.
    • Added a test case to ensure that for large updates, the write-file tool returns only changed lines plus context, indicating truncation with '...'.
  • packages/core/src/tools/write-file.ts
    • Introduced a new getDiffContextSnippet utility function to generate contextual code snippets from file differences.
    • Integrated getDiffContextSnippet into WriteFileToolInvocation to include updated code snippets in LLM success messages.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

github-actions bot commented Feb 19, 2026

Size Change: +4.65 kB (+0.02%)

Total Size: 25.2 MB

Filename Size Change
./bundle/gemini.js 25.2 MB +4.65 kB (+0.02%)
ℹ️ View Unchanged
Filename Size
./bundle/sandbox-macos-permissive-open.sb 890 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB
./bundle/sandbox-macos-strict-open.sb 4.82 kB
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB

compressed-size-action

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a "Greedy Grep" feature, enhances edit and write-file tools, and adds caching to the read-file tool. A security audit identified high-severity Denial of Service (DoS) vulnerabilities. The new caching mechanism in ReadFileTool uses an unbounded global map, which can lead to memory exhaustion, and should be replaced with an LruCache as per established guidelines. It also bypasses the Policy Engine. Furthermore, the 'Greedy Grep' logic in GrepTool and RipGrepTool lacks file size validation, posing a significant risk of Out Of Memory (OOM) crashes when encountering large files. Additionally, there is code duplication in the diff snippet generation between edit.ts and write-file.ts, with one version containing a potential bug, which should be addressed by extracting it into a shared utility.

Comment on lines 320 to 324
const content = await fsPromises.readFile(
fileMatches[0].absolutePath,
'utf8',
);
fileLines = content.split(/\r?\n/);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The 'Greedy Grep' logic reads the entire content of a matched file into memory using fsPromises.readFile without any size validation. This poses a high risk of an Out Of Memory (OOM) crash when encountering large files, which is a regression compared to the ReadFileTool's 20MB limit. Additionally, this logic is duplicated with packages/core/src/tools/ripGrep.ts; extracting it into a shared utility would improve maintainability and facilitate consistent application of necessary safeguards.

Comment on lines 328 to 332
const content = await fsPromises.readFile(
fileMatches[0].absolutePath,
'utf8',
);
fileLines = content.split(/\r?\n/);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The 'Greedy Grep' implementation in RipGrepTool reads the entire content of matched files into memory to provide context. There is no check on the file size before calling fsPromises.readFile. Reading large files into memory and splitting them into lines can cause the Node.js process to crash due to memory exhaustion (OOM), providing a straightforward vector for Denial of Service.

@gemini-cli gemini-cli bot added the priority/p1 Important and should be addressed in the near term. label Feb 19, 2026
@gundermanc gundermanc changed the title Gundermanc/pipeline greps Utilize pipelining of grep_search -> read_file to eliminate turns Feb 19, 2026
@gemini-cli gemini-cli bot added the 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. label Feb 19, 2026
@gundermanc gundermanc marked this pull request as ready for review February 19, 2026 23:38
@gundermanc gundermanc requested a review from a team as a code owner February 19, 2026 23:38

if (names_only) {
const filePaths = Object.keys(matchesByFile).sort();
let llmContent = `Found ${filePaths.length} files with matches for pattern "${pattern}" ${searchLocationDescription}${include ? ` (filter: "${include}")` : ''}${wasTruncated ? ` (results limited to ${totalMaxMatches} matches for performance)` : ''}:\n`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

array of strings might be a bit clearer than doing the manual newlines, but this is also fine.

@@ -351,6 +357,15 @@ class WriteFileToolInvocation extends BaseToolInvocation<
);
}

// Return a diff of the file before and after the write so that the agent
// can avoid the need to spend a turn doing a verification read.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmmmm, this one is an overwrite right? So the contents on disk are exactly as the model specified? Maybe I'm misunderstanding something, if the contents of the file after write are identical to what the model just passed to write_file this might not be necessary?

@gundermanc gundermanc enabled auto-merge February 20, 2026 23:58
@gundermanc gundermanc added this pull request to the merge queue Feb 21, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 21, 2026
@gundermanc gundermanc added this pull request to the merge queue Feb 21, 2026
Merged via the queue into main with commit 5d98ed5 Feb 21, 2026
27 checks passed
@gundermanc gundermanc deleted the gundermanc/pipeline-greps branch February 21, 2026 00:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Context Mgmt] Investigate pipelining of tool calls to reduce token consumption and scenario duration

2 participants