From fc24102491c3a644e53792c1a318b00bfdfd6d6b Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Tue, 15 Jul 2025 17:52:50 -0600 Subject: [PATCH] Tweaks to ACP for the Gemini PR (#34506) - **Update to use --experimental-acp** - **Fix tool locations** Closes #ISSUE Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: mkorwel Co-authored-by: Agus Zubiaga --- crates/acp/src/acp.rs | 47 +++++++++++++++++++++-- crates/agent_servers/src/agent_servers.rs | 2 +- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/crates/acp/src/acp.rs b/crates/acp/src/acp.rs index 8351aeaee0..a7e72b0c2d 100644 --- a/crates/acp/src/acp.rs +++ b/crates/acp/src/acp.rs @@ -1,10 +1,10 @@ pub use acp::ToolCallId; use agent_servers::AgentServer; -use agentic_coding_protocol::{self as acp, UserMessageChunk}; +use agentic_coding_protocol::{self as acp, ToolCallLocation, UserMessageChunk}; use anyhow::{Context as _, Result, anyhow}; use assistant_tool::ActionLog; use buffer_diff::BufferDiff; -use editor::{MultiBuffer, PathKey}; +use editor::{Bias, MultiBuffer, PathKey}; use futures::{FutureExt, channel::oneshot, future::BoxFuture}; use gpui::{AppContext, AsyncApp, Context, Entity, EventEmitter, SharedString, Task, WeakEntity}; use itertools::Itertools; @@ -769,6 +769,11 @@ impl AcpThread { status, }; + let location = call.locations.last().cloned(); + if let Some(location) = location { + self.set_project_location(location, cx) + } + self.push_entry(AgentThreadEntry::ToolCall(call), cx); id @@ -831,6 +836,11 @@ impl AcpThread { } } + let location = call.locations.last().cloned(); + if let Some(location) = location { + self.set_project_location(location, cx) + } + cx.emit(AcpThreadEvent::EntryUpdated(ix)); Ok(()) } @@ -852,6 +862,37 @@ impl AcpThread { } } + pub fn set_project_location(&self, location: ToolCallLocation, cx: &mut Context) { + self.project.update(cx, |project, cx| { + let Some(path) = project.project_path_for_absolute_path(&location.path, cx) else { + return; + }; + let buffer = project.open_buffer(path, cx); + cx.spawn(async move |project, cx| { + let buffer = buffer.await?; + + project.update(cx, |project, cx| { + let position = if let Some(line) = location.line { + let snapshot = buffer.read(cx).snapshot(); + let point = snapshot.clip_point(Point::new(line, 0), Bias::Left); + snapshot.anchor_before(point) + } else { + Anchor::MIN + }; + + project.set_agent_location( + Some(AgentLocation { + buffer: buffer.downgrade(), + position, + }), + cx, + ); + }) + }) + .detach_and_log_err(cx); + }); + } + /// Returns true if the last turn is awaiting tool authorization pub fn waiting_for_tool_confirmation(&self) -> bool { for entry in self.entries.iter().rev() { @@ -1780,7 +1821,7 @@ mod tests { Ok(AgentServerCommand { path: "node".into(), - args: vec![cli_path, "--acp".into()], + args: vec![cli_path, "--experimental-acp".into()], env: None, }) } diff --git a/crates/agent_servers/src/agent_servers.rs b/crates/agent_servers/src/agent_servers.rs index 5d588cd4ae..ba43122570 100644 --- a/crates/agent_servers/src/agent_servers.rs +++ b/crates/agent_servers/src/agent_servers.rs @@ -56,7 +56,7 @@ pub trait AgentServer: Send { ) -> impl Future> + Send; } -const GEMINI_ACP_ARG: &str = "--acp"; +const GEMINI_ACP_ARG: &str = "--experimental-acp"; impl AgentServer for Gemini { async fn command(