assistant edit tool: Improve bad search output (#27012)

When we failed to match a search string, we were reporting the replace
string as not found, this confuses the model and can make it go into a
doom loop. This PR fixes that improves the error output in general to
help it recover faster.

Release Notes:

- N/A
This commit is contained in:
Agus Zubiaga 2025-03-18 21:53:20 -03:00 committed by GitHub
parent c042a02cf4
commit 68a572873b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -305,7 +305,7 @@ impl EditToolRequest {
if matches.is_empty() { if matches.is_empty() {
return Ok(DiffResult::BadSearch(BadSearch { return Ok(DiffResult::BadSearch(BadSearch {
search: new.clone(), search: old.clone(),
file_path: file_path.display().to_string(), file_path: file_path.display().to_string(),
})); }));
} }
@ -378,25 +378,29 @@ impl EditToolRequest {
if !self.bad_searches.is_empty() { if !self.bad_searches.is_empty() {
writeln!( writeln!(
&mut output, &mut output,
"\n\nThese searches failed because they didn't match any strings:" "\n\n# {} SEARCH/REPLACE block(s) failed to match:\n",
self.bad_searches.len()
)?; )?;
for replace in self.bad_searches { for replace in self.bad_searches {
writeln!( writeln!(
&mut output, &mut output,
"- '{}' does not appear in `{}`", "## No exact match in: {}\n```\n{}\n```\n",
replace.search.replace("\r", "\\r").replace("\n", "\\n"), replace.file_path, replace.search,
replace.file_path
)?; )?;
} }
write!(&mut output, "Make sure to use exact searches.")?; write!(&mut output,
"The SEARCH section must exactly match an existing block of lines including all white \
space, comments, indentation, docstrings, etc."
)?;
} }
if !errors.is_empty() { if !errors.is_empty() {
writeln!( writeln!(
&mut output, &mut output,
"\n\nThese SEARCH/REPLACE blocks failed to parse:" "\n\n# {} SEARCH/REPLACE blocks failed to parse:",
errors.len()
)?; )?;
for error in errors { for error in errors {
@ -404,10 +408,22 @@ impl EditToolRequest {
} }
} }
if changed_buffer_count > 0 {
writeln!(
&mut output,
"\n\nThe other SEARCH/REPLACE blocks were applied successfully. Do not re-send them!",
)?;
}
writeln!( writeln!(
&mut output, &mut output,
"\nYou can fix errors by running the tool again. You can include instructions, \ "{}You can fix errors by running the tool again. You can include instructions, \
but errors are part of the conversation so you don't need to repeat them." but errors are part of the conversation so you don't need to repeat them.",
if changed_buffer_count == 0 {
"\n\n"
} else {
""
}
)?; )?;
Err(anyhow!(output)) Err(anyhow!(output))