Skip to content

Commit a8914e7

Browse files
committed
fix: clarify apply_diff is for surgical edits only, not full file rewrites
- Updated apply_diff tool description to emphasize it is for SURGICAL EDITS ONLY - Added CRITICAL warning that apply_diff is NOT for rewriting entire files - Added clear examples of GOOD use (single line change) vs BAD use (entire file rewrite) - Updated rules section to emphasize using apply_diff for small, targeted changes - Applied same improvements to both single-file and multi-file diff strategies - Fixed ESLint warning by removing unused directive This should help prevent models from misusing apply_diff to rewrite entire files when they should be using write_to_file instead.
1 parent 2170c61 commit a8914e7

File tree

3 files changed

+57
-29
lines changed

3 files changed

+57
-29
lines changed

src/core/diff/strategies/multi-file-search-replace.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,18 @@ export class MultiFileSearchReplaceDiffStrategy implements DiffStrategy {
9393
getToolDescription(args: { cwd: string; toolOptions?: { [key: string]: string } }): string {
9494
return `## apply_diff
9595
96-
Description: Request to apply targeted modifications to one or more files by searching for specific sections of content and replacing them. This tool supports both single-file and multi-file operations, allowing you to make changes across multiple files in a single request.
96+
Description: Request to apply PRECISE, TARGETED modifications to one or more files by searching for specific sections of content and replacing them. This tool is for SURGICAL EDITS ONLY - small, specific changes to existing code. This tool supports both single-file and multi-file operations, allowing you to make changes across multiple files in a single request.
97+
98+
**CRITICAL: This tool is NOT for rewriting entire files or making large-scale changes. Use write_to_file for that purpose.**
9799
98100
**IMPORTANT: You MUST use multiple files in a single operation whenever possible to maximize efficiency and minimize back-and-forth.**
99101
102+
Key characteristics:
103+
- Ideal for changing specific lines, functions, or small code blocks
104+
- Preserves the rest of the file unchanged
105+
- Requires exact matching of existing content (including whitespace)
106+
- Can perform multiple small edits in one operation across multiple files
107+
100108
You can perform multiple distinct search and replace operations within a single \`apply_diff\` call by providing multiple SEARCH/REPLACE blocks in the \`diff\` parameter. This is the preferred way to make several targeted changes efficiently.
101109
102110
The SEARCH section must exactly match existing content including whitespace and indentation.

src/core/diff/strategies/multi-search-replace.ts

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* eslint-disable no-irregular-whitespace */
2-
31
import { distance } from "fastest-levenshtein"
42

53
import { ToolProgressStatus } from "@roo-code/types"
@@ -92,11 +90,22 @@ export class MultiSearchReplaceDiffStrategy implements DiffStrategy {
9290

9391
getToolDescription(args: { cwd: string; toolOptions?: { [key: string]: string } }): string {
9492
return `## apply_diff
95-
Description: Request to apply targeted modifications to an existing file by searching for specific sections of content and replacing them. This tool is ideal for precise, surgical edits when you know the exact content to change. It helps maintain proper indentation and formatting.
93+
Description: Request to apply PRECISE, TARGETED modifications to an existing file by searching for specific sections of content and replacing them. This tool is for SURGICAL EDITS ONLY - small, specific changes to existing code.
94+
95+
**CRITICAL: This tool is NOT for rewriting entire files or making large-scale changes. Use write_to_file for that purpose.**
96+
97+
Key characteristics:
98+
- Ideal for changing specific lines, functions, or small code blocks
99+
- Preserves the rest of the file unchanged
100+
- Requires exact matching of existing content (including whitespace)
101+
- Can perform multiple small edits in one operation
102+
96103
You can perform multiple distinct search and replace operations within a single \`apply_diff\` call by providing multiple SEARCH/REPLACE blocks in the \`diff\` parameter. This is the preferred way to make several targeted changes efficiently.
97-
The SEARCH section must exactly match existing content including whitespace and indentation.
98-
If you're not confident in the exact content to search for, use the read_file tool first to get the exact content.
104+
105+
IMPORTANT: The SEARCH section must exactly match existing content including whitespace and indentation. If you're not confident in the exact content to search for, use the read_file tool first to get the exact content.
106+
99107
When applying the diffs, be extra careful to remember to change any closing brackets or other syntax that may be affected by the diff farther down in the file.
108+
100109
ALWAYS make as many changes in a single 'apply_diff' request as possible using multiple SEARCH/REPLACE blocks
101110
102111
Parameters:
@@ -116,7 +125,7 @@ Diff format:
116125
\`\`\`
117126
118127
119-
Example:
128+
Example of GOOD use (surgical edit - changing a single line):
120129
121130
Original file:
122131
\`\`\`
@@ -129,43 +138,53 @@ Original file:
129138
130139
Search/Replace content:
131140
\`\`\`
132-
<<<<<<< SEARCH
141+
\\<<<<<<< SEARCH
142+
:start_line:2
143+
-------
144+
total = 0
145+
\\=======
146+
total = 0 # Initialize sum
147+
\\>>>>>>> REPLACE
148+
\`\`\`
149+
150+
Example of BAD use (trying to rewrite entire file - use write_to_file instead):
151+
\`\`\`
152+
\\<<<<<<< SEARCH
133153
:start_line:1
134154
-------
135155
def calculate_total(items):
136156
total = 0
137157
for item in items:
138158
total += item
139159
return total
140-
=======
160+
\\=======
141161
def calculate_total(items):
142162
"""Calculate total with 10% markup"""
143163
return sum(item * 1.1 for item in items)
144-
>>>>>>> REPLACE
145-
164+
\\>>>>>>> REPLACE
146165
\`\`\`
147166
148-
Search/Replace content with multiple edits:
167+
Example with multiple surgical edits:
149168
\`\`\`
150-
<<<<<<< SEARCH
169+
\\<<<<<<< SEARCH
151170
:start_line:1
152171
-------
153172
def calculate_total(items):
154173
sum = 0
155-
=======
174+
\\=======
156175
def calculate_sum(items):
157176
sum = 0
158-
>>>>>>> REPLACE
177+
\\>>>>>>> REPLACE
159178
160-
<<<<<<< SEARCH
179+
\\<<<<<<< SEARCH
161180
:start_line:4
162181
-------
163182
total += item
164183
return total
165-
=======
184+
\\=======
166185
sum += item
167186
return sum
168-
>>>>>>> REPLACE
187+
\\>>>>>>> REPLACE
169188
\`\`\`
170189
171190
@@ -349,31 +368,31 @@ Only use a single line of '=======' between search and replacement content, beca
349368
Regex parts:
350369
351370
1. (?:^|\n)
352-
  Ensures the first marker starts at the beginning of the file or right after a newline.
371+
Ensures the first marker starts at the beginning of the file or right after a newline.
353372
354373
2. (?<!\\)<<<<<<< SEARCH\s*\n
355-
  Matches the line <<<<<<< SEARCH (ignoring any trailing spaces) – the negative lookbehind makes sure it isnt escaped.
374+
Matches the line "<<<<<<< SEARCH" (ignoring any trailing spaces) – the negative lookbehind makes sure it isn't escaped.
356375
357376
3. ((?:\:start_line:\s*(\d+)\s*\n))?
358-
  Optionally matches a :start_line: line. The outer capturing group is group1 and the inner (\d+) is group2.
377+
Optionally matches a ":start_line:" line. The outer capturing group is group 1 and the inner (\d+) is group 2.
359378
360379
4. ((?:\:end_line:\s*(\d+)\s*\n))?
361-
  Optionally matches a :end_line: line. Group3 is the whole match and group4 is the digits.
380+
Optionally matches a ":end_line:" line. Group 3 is the whole match and group 4 is the digits.
362381
363382
5. ((?<!\\)-------\s*\n)?
364-
  Optionally matches the ------- marker line (group5).
383+
Optionally matches the "-------" marker line (group 5).
365384
366385
6. ([\s\S]*?)(?:\n)?
367-
  Non‐greedy match for the search content (group6) up to the next marker.
386+
Non‐greedy match for the "search content" (group 6) up to the next marker.
368387
369388
7. (?:(?<=\n)(?<!\\)=======\s*\n)
370-
  Matches the ======= marker on its own line.
389+
Matches the "=======" marker on its own line.
371390
372391
8. ([\s\S]*?)(?:\n)?
373-
  Non‐greedy match for the replace content (group7).
392+
Non‐greedy match for the "replace content" (group 7).
374393
375394
9. (?:(?<=\n)(?<!\\)>>>>>>> REPLACE)(?=\n|$)
376-
  Matches the final >>>>>>> REPLACE marker on its own line (and requires a following newline or the end of file).
395+
Matches the final ">>>>>>> REPLACE" marker on its own line (and requires a following newline or the end of file).
377396
*/
378397

379398
let matches = [

src/core/prompts/sections/rules.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ function getEditingInstructions(diffStrategy?: DiffStrategy): string {
88
// Collect available editing tools
99
if (diffStrategy) {
1010
availableTools.push(
11-
"apply_diff (for replacing lines in existing files)",
11+
"apply_diff (for surgical edits - small, targeted changes to specific lines or functions)",
1212
"write_to_file (for creating new files or complete file rewrites)",
1313
)
1414
} else {
@@ -34,7 +34,8 @@ function getEditingInstructions(diffStrategy?: DiffStrategy): string {
3434

3535
if (availableTools.length > 1) {
3636
instructions.push(
37-
"- You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.",
37+
"- CRITICAL: Use apply_diff for small, surgical edits to existing files. Do NOT use apply_diff to rewrite entire files - use write_to_file for that purpose.",
38+
"- You should always prefer using apply_diff, insert_content, or search_and_replace over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.",
3839
)
3940
}
4041

0 commit comments

Comments
 (0)