From 6b7167a32d986a62015bef7759d6c91266436dfd Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Tue, 25 Mar 2025 12:32:20 -0400 Subject: [PATCH] Gracefully handle models searching for empty glob (#27370) Sometimes we've seen models provide an empty string for the path search glob. This assumes they meant "*" when that happens. Separately, this also removes an unnecessary `clone` of a `String`. Release Notes: - N/A --- crates/assistant_tools/src/edit_files_tool/replace.rs | 5 +++-- crates/assistant_tools/src/path_search_tool.rs | 6 +++++- crates/util/src/paths.rs | 6 +++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/crates/assistant_tools/src/edit_files_tool/replace.rs b/crates/assistant_tools/src/edit_files_tool/replace.rs index f98aa7e4fa3887c914cae02988030a14f22934ab..46f54bb8a562ea4a57448513b08be70b4a7ebbf5 100644 --- a/crates/assistant_tools/src/edit_files_tool/replace.rs +++ b/crates/assistant_tools/src/edit_files_tool/replace.rs @@ -1,5 +1,6 @@ use language::{BufferSnapshot, Diff, Point, ToOffset}; use project::search::SearchQuery; +use std::iter; use util::{paths::PathMatcher, ResultExt as _}; /// Performs an exact string replacement in a buffer, requiring precise character-for-character matching. @@ -11,8 +12,8 @@ pub async fn replace_exact(old: &str, new: &str, snapshot: &BufferSnapshot) -> O false, true, true, - PathMatcher::new(&[]).ok()?, - PathMatcher::new(&[]).ok()?, + PathMatcher::new(iter::empty::<&str>()).ok()?, + PathMatcher::new(iter::empty::<&str>()).ok()?, None, ) .log_err()?; diff --git a/crates/assistant_tools/src/path_search_tool.rs b/crates/assistant_tools/src/path_search_tool.rs index e2621e3f96667fc364f8cc2e8917c8f9077538ed..401489ca15052badf1b595f9110b9af6cf1eb177 100644 --- a/crates/assistant_tools/src/path_search_tool.rs +++ b/crates/assistant_tools/src/path_search_tool.rs @@ -71,7 +71,11 @@ impl Tool for PathSearchTool { Ok(input) => (input.offset.unwrap_or(0), input.glob), Err(err) => return Task::ready(Err(anyhow!(err))), }; - let path_matcher = match PathMatcher::new(&[glob.clone()]) { + + let path_matcher = match PathMatcher::new([ + // Sometimes models try to search for "". In this case, return all paths in the project. + if glob.is_empty() { "*" } else { &glob }, + ]) { Ok(matcher) => matcher, Err(err) => return Task::ready(Err(anyhow!("Invalid glob: {err}"))), }; diff --git a/crates/util/src/paths.rs b/crates/util/src/paths.rs index ecaa0d9bc2f9f46c706dfc0c8c0a4a4f9d434b43..bdeee4a23e57aa5f68a7f4c1b1ab3cc6deb2787e 100644 --- a/crates/util/src/paths.rs +++ b/crates/util/src/paths.rs @@ -377,10 +377,10 @@ impl PartialEq for PathMatcher { impl Eq for PathMatcher {} impl PathMatcher { - pub fn new(globs: &[String]) -> Result { + pub fn new(globs: impl IntoIterator>) -> Result { let globs = globs - .iter() - .map(|glob| Glob::new(glob)) + .into_iter() + .map(|as_str| Glob::new(as_str.as_ref())) .collect::, _>>()?; let sources = globs.iter().map(|glob| glob.glob().to_owned()).collect(); let mut glob_builder = GlobSetBuilder::new();