From a0ee84d3ac2f44895bdc1c1b8d565c2e1a981867 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Mon, 17 Mar 2025 11:02:22 -0400 Subject: [PATCH] Use the main thread less on search tool (#26732) Release Notes: - N/A --- Cargo.lock | 1 + crates/assistant_tools/Cargo.toml | 1 + .../assistant_tools/src/path_search_tool.rs | 53 ++++++++++--------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ea631d7c4..58d232020a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -727,6 +727,7 @@ dependencies = [ "ui", "util", "workspace", + "worktree", ] [[package]] diff --git a/crates/assistant_tools/Cargo.toml b/crates/assistant_tools/Cargo.toml index 749ff927c3..087b883bb6 100644 --- a/crates/assistant_tools/Cargo.toml +++ b/crates/assistant_tools/Cargo.toml @@ -30,6 +30,7 @@ theme.workspace = true ui.workspace = true util.workspace = true workspace.workspace = true +worktree.workspace = true settings.workspace = true [dev-dependencies] diff --git a/crates/assistant_tools/src/path_search_tool.rs b/crates/assistant_tools/src/path_search_tool.rs index dfa7ab0f73..5e8080c8cf 100644 --- a/crates/assistant_tools/src/path_search_tool.rs +++ b/crates/assistant_tools/src/path_search_tool.rs @@ -1,12 +1,13 @@ use anyhow::{anyhow, Result}; use assistant_tool::{ActionLog, Tool}; -use gpui::{App, Entity, Task}; +use gpui::{App, AppContext, Entity, Task}; use language_model::LanguageModelRequestMessage; use project::Project; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::{path::PathBuf, sync::Arc}; use util::paths::PathMatcher; +use worktree::Snapshot; #[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct PathSearchToolInput { @@ -56,34 +57,38 @@ impl Tool for PathSearchTool { Ok(matcher) => matcher, Err(err) => return Task::ready(Err(anyhow!("Invalid glob: {}", err))), }; + let snapshots: Vec = project + .read(cx) + .worktrees(cx) + .map(|worktree| worktree.read(cx).snapshot()) + .collect(); - let mut matches = Vec::new(); + cx.background_spawn(async move { + let mut matches = Vec::new(); - for worktree_handle in project.read(cx).worktrees(cx) { - let worktree = worktree_handle.read(cx); - let root_name = worktree.root_name(); + for worktree in snapshots { + let root_name = worktree.root_name(); - // Don't consider ignored entries. - for entry in worktree.entries(false, 0) { - if path_matcher.is_match(&entry.path) { - matches.push( - PathBuf::from(root_name) - .join(&entry.path) - .to_string_lossy() - .to_string(), - ); + // Don't consider ignored entries. + for entry in worktree.entries(false, 0) { + if path_matcher.is_match(&entry.path) { + matches.push( + PathBuf::from(root_name) + .join(&entry.path) + .to_string_lossy() + .to_string(), + ); + } } } - } - if matches.is_empty() { - Task::ready(Ok(format!( - "No paths in the project matched the glob {glob:?}" - ))) - } else { - // Sort to group entries in the same directory together. - matches.sort(); - Task::ready(Ok(matches.join("\n"))) - } + if matches.is_empty() { + Ok(format!("No paths in the project matched the glob {glob:?}")) + } else { + // Sort to group entries in the same directory together. + matches.sort(); + Ok(matches.join("\n")) + } + }) } }