Skip to content

Avoid overaggressive unescaping#20520

Merged
scidomino merged 2 commits intomainfrom
tomm_unescape
Feb 27, 2026
Merged

Avoid overaggressive unescaping#20520
scidomino merged 2 commits intomainfrom
tomm_unescape

Conversation

@scidomino
Copy link
Collaborator

@scidomino scidomino commented Feb 27, 2026

Summary

When using newer models, don't aggressively unescape file writes.

Details

This makes two changes to write_file:

  1. Treat existing file overwrites the same as new file writes.
  2. Stop aggressive unescaping if the model is 3.0 or newer.

The first change is safe because the only difference between the two old paths was that with disableLLMCorrection=false , the overwrite path's call to the LLM included the old file contents which isn't super useful for figuring out if the new value is correctly escaped (it might even make performance worse). And anyways, disableLLMCorrection=true by default so this is unlikely to affect many users.

Note also: The reason why we had this difference in the first place was that we were treating an overwrite like an "edit where you replace the whole text". However, when we moved to smart-edit, the edit tool stopped using that codepath so the overwrite case was the only thing using that code (and most of it was dead code that could never be visited with the way overwrite was calling it).

Related Issues

Fixes #19802

How to Validate

Ask

please create a test file with a latex example using the title tag

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

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, 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 refactors the file writing and content correction mechanisms to prevent overaggressive unescaping, particularly when interacting with newer language models. By consolidating correction logic and introducing model-aware unescaping, the system ensures more accurate and predictable file modifications, addressing issues where content was incorrectly altered due to excessive escaping.

Highlights

  • Refactored File Content Correction: The complex ensureCorrectEdit function and its associated logic have been removed, simplifying the overall content correction mechanism.
  • Unified Write Operations: The logic for writing to new files and overwriting existing files has been unified, now consistently using ensureCorrectFileContent.
  • Model-Aware Unescaping: Aggressive unescaping of file writes is now conditionally applied, being disabled for newer models (Gemini 3.0 and above) to prevent over-correction and ensure more accurate output.
  • Codebase Simplification: Several helper functions and related test code within the editCorrector utility have been removed, leading to a cleaner and more maintainable codebase.
Changelog
  • packages/core/src/tools/confirmation-policy.test.ts
    • Added getActiveModel to mock configuration.
  • packages/core/src/tools/line-endings.test.ts
    • Removed import and mock for ensureCorrectEdit.
    • Added getActiveModel to mock configuration.
    • Updated test calls to use mockEnsureCorrectFileContent instead of mockEnsureCorrectEdit.
  • packages/core/src/tools/write-file.test.ts
    • Removed imports and mocks related to ensureCorrectEdit.
    • Added getActiveModel to mock configuration.
    • Modified calls to getCorrectedFileContent to include the new aggressiveUnescape parameter.
  • packages/core/src/tools/write-file.ts
    • Removed import for ensureCorrectEdit.
    • Imported isGemini3Model for model version checking.
    • Refactored getCorrectedFileContent to use a single call to ensureCorrectFileContent for both new and existing files.
    • Introduced aggressiveUnescape parameter for ensureCorrectFileContent, set conditionally based on the active model.
  • packages/core/src/utils/editCorrector.test.ts
    • Removed tests and mocks associated with the ensureCorrectEdit function.
    • Removed tests for countOccurrences.
  • packages/core/src/utils/editCorrector.ts
    • Removed ensureCorrectEdit, CorrectedEditResult, findLastEditTimestamp, correctOldStringMismatch, correctNewString, correctNewStringEscaping, trimPreservingTrailingNewline, trimPairIfPossible, and countOccurrences.
    • Updated ensureCorrectFileContent to accept an aggressiveUnescape boolean parameter, which controls unescaping behavior when LLM correction is disabled.
Activity
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.

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 significant refactoring to the file writing logic to prevent overaggressive unescaping of content, especially with newer models. The core change is the removal of the complex ensureCorrectEdit function, unifying the logic for both new and existing file writes under a simplified ensureCorrectFileContent function. A new aggressiveUnescape flag has been added, which is conditionally set based on the active Gemini model version. For Gemini 3.0 and newer models, aggressive unescaping is disabled, addressing the issue of incorrect content modification. For older models, the existing unescaping behavior is preserved. The tests have been thoroughly updated to reflect these changes, removing mocks for the deprecated ensureCorrectEdit and adding necessary mocks for getActiveModel. The changes simplify the codebase, improve maintainability, and correctly fix the reported bug. The implementation appears solid and well-tested.

@github-actions
Copy link

github-actions bot commented Feb 27, 2026

Size Change: -17.5 kB (-0.07%)

Total Size: 25.7 MB

Filename Size Change
./bundle/gemini.js 25.2 MB -17.5 kB (-0.07%)
ℹ️ View Unchanged
Filename Size
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 221 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 227 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 11.5 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B
./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

@scidomino scidomino marked this pull request as ready for review February 27, 2026 00:35
@scidomino scidomino requested a review from a team as a code owner February 27, 2026 00:35
@gemini-cli gemini-cli bot added priority/p1 Important and should be addressed in the near term. area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels Feb 27, 2026
mockBaseLlmClientInstance,
abortSignal,
true,
true, // aggressiveUnescape
Copy link
Contributor

@jacob314 jacob314 Feb 27, 2026

Choose a reason for hiding this comment

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

can you also added a test without aggressiveUnescape to verify the behavior there. Consider parameterizing all these tests to run with. and without aggressiveUnescape with modified expectations for each cases

Copy link
Contributor

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

lgtm

@scidomino scidomino enabled auto-merge February 27, 2026 01:34
@scidomino scidomino added this pull request to the merge queue Feb 27, 2026
Merged via the queue into main with commit 4b7ce1f Feb 27, 2026
28 checks passed
@scidomino scidomino deleted the tomm_unescape branch February 27, 2026 02:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality 🔒 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.

Gemini CLI replaces \t, \r etc. characters when it shouldn't in LaTeX

3 participants