acp: Use new Rust SDK (#52997)

Testing out Niko's new SDK design

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable


Release Notes:

- N/A
This commit is contained in:
Ben Brandt authored and GitHub committed 2026-04-22 15:02:57 +00:00
1 parent 7107fdc008
commit e77b071c39
62 files changed
+1861 -897

No files matched your search

Generated
+276 -116
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -496,7 +496,7 @@ ztracing_macro = { path = "crates/ztracing_macro" }
# External crates
#
agent-client-protocol = { version = "=0.10.2", features = ["unstable"] }
agent-client-protocol = { version = "=0.11.1", features = ["unstable"] }
aho-corasick = "1.1"
alacritty_terminal = { git = "https://github.com/zed-industries/alacritty", rev = "9d9640d4" }
any_vec = "0.14"
+1 -1
View File
@@ -3,7 +3,7 @@ mod diff;
mod mention;
mod terminal;
use action_log::{ActionLog, ActionLogTelemetry};
use agent_client_protocol::{self as acp};
use agent_client_protocol::schema as acp;
use anyhow::{Context as _, Result, anyhow};
use collections::HashSet;
pub use connection::*;
+2 -2
View File
@@ -1,5 +1,5 @@
use crate::AcpThread;
use agent_client_protocol::{self as acp};
use agent_client_protocol::schema as acp;
use anyhow::Result;
use chrono::{DateTime, Utc};
use collections::{HashMap, IndexMap};
@@ -954,7 +954,7 @@ mod test_support {
fn truncate(
&self,
_session_id: &agent_client_protocol::SessionId,
_session_id: &acp::SessionId,
_cx: &App,
) -> Option<Rc<dyn AgentSessionTruncate>> {
Some(Rc::new(StubAgentSessionEditor))
+1 -1
View File
@@ -1,4 +1,4 @@
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::{Context as _, Result, bail};
use file_icons::FileIcons;
use prompt_store::{PromptId, UserPromptId};
+1 -1
View File
@@ -1,4 +1,4 @@
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::Result;
use futures::{FutureExt as _, future::Shared};
use gpui::{App, AppContext, AsyncApp, Context, Entity, Task};
+5
View File
@@ -13,15 +13,20 @@ workspace = true
path = "src/acp_tools.rs"
doctest = false
[features]
test-support = ["workspace/test-support"]
[dependencies]
agent-client-protocol.workspace = true
collections.workspace = true
gpui.workspace = true
language.workspace= true
log.workspace = true
markdown.workspace = true
project.workspace = true
serde.workspace = true
serde_json.workspace = true
smol.workspace = true
settings.workspace = true
theme_settings.workspace = true
ui.workspace = true
+349 -65
View File
@@ -1,12 +1,13 @@
use std::{
cell::RefCell,
collections::HashSet,
collections::{HashSet, VecDeque},
fmt::Display,
rc::{Rc, Weak},
sync::Arc,
sync::{
Arc,
atomic::{AtomicBool, Ordering},
},
};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use collections::HashMap;
use gpui::{
App, Empty, Entity, EventEmitter, FocusHandle, Focusable, Global, ListAlignment, ListState,
@@ -23,6 +24,111 @@ use workspace::{
Item, ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace,
};
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum StreamMessageDirection {
Incoming,
Outgoing,
/// Lines captured from the agent's stderr. These are not part of the
/// JSON-RPC protocol, but agents often emit useful diagnostics there.
Stderr,
}
#[derive(Clone)]
pub enum StreamMessageContent {
Request {
id: acp::RequestId,
method: Arc<str>,
params: Option<serde_json::Value>,
},
Response {
id: acp::RequestId,
result: Result<Option<serde_json::Value>, acp::Error>,
},
Notification {
method: Arc<str>,
params: Option<serde_json::Value>,
},
/// A raw stderr line from the agent process.
Stderr { line: Arc<str> },
}
#[derive(Clone)]
pub struct StreamMessage {
pub direction: StreamMessageDirection,
pub message: StreamMessageContent,
}
impl StreamMessage {
/// Build a `StreamMessage` from a raw line captured off the transport.
///
/// For `Stderr`, the line is wrapped as-is (no JSON parsing). For
/// `Incoming`/`Outgoing`, the line is parsed as JSON-RPC; returns `None`
/// if it doesn't look like a valid JSON-RPC message.
pub fn from_raw_line(direction: StreamMessageDirection, line: &str) -> Option<Self> {
if direction == StreamMessageDirection::Stderr {
return Some(StreamMessage {
direction,
message: StreamMessageContent::Stderr {
line: Arc::from(line),
},
});
}
let value: serde_json::Value = serde_json::from_str(line).ok()?;
let obj = value.as_object()?;
let parsed_id = obj
.get("id")
.map(|raw| serde_json::from_value::<acp::RequestId>(raw.clone()));
let message = if let Some(method) = obj.get("method").and_then(|m| m.as_str()) {
match parsed_id {
Some(Ok(id)) => StreamMessageContent::Request {
id,
method: method.into(),
params: obj.get("params").cloned(),
},
Some(Err(err)) => {
log::warn!("Skipping JSON-RPC message with unparsable id: {err}");
return None;
}
None => StreamMessageContent::Notification {
method: method.into(),
params: obj.get("params").cloned(),
},
}
} else if let Some(parsed_id) = parsed_id {
let id = match parsed_id {
Ok(id) => id,
Err(err) => {
log::warn!("Skipping JSON-RPC response with unparsable id: {err}");
return None;
}
};
if let Some(error) = obj.get("error") {
let acp_err =
serde_json::from_value::<acp::Error>(error.clone()).unwrap_or_else(|err| {
log::warn!("Failed to deserialize ACP error: {err}");
acp::Error::internal_error().data(error.to_string())
});
StreamMessageContent::Response {
id,
result: Err(acp_err),
}
} else {
StreamMessageContent::Response {
id,
result: Ok(obj.get("result").cloned()),
}
}
} else {
return None;
};
Some(StreamMessage { direction, message })
}
}
actions!(dev, [OpenAcpLogs]);
pub fn init(cx: &mut App) {
@@ -42,14 +148,87 @@ struct GlobalAcpConnectionRegistry(Entity<AcpConnectionRegistry>);
impl Global for GlobalAcpConnectionRegistry {}
#[derive(Default)]
pub struct AcpConnectionRegistry {
active_connection: RefCell<Option<ActiveConnection>>,
/// A raw line captured from the transport (or from stderr), tagged with
/// direction. Deserialization into [`StreamMessage`] happens on the
/// registry's foreground task so the ring buffer can be replayed to late
/// subscribers.
struct RawStreamLine {
direction: StreamMessageDirection,
line: Arc<str>,
}
struct ActiveConnection {
agent_id: AgentId,
connection: Weak<acp::ClientSideConnection>,
/// Handle to an ACP connection's log tap. Passed back by
/// [`AcpConnectionRegistry::set_active_connection`] so that the connection
/// can publish transport and stderr lines without knowing anything about
/// the logs panel's channel.
///
/// The tap carries a shared `enabled` flag that the registry flips on when
/// the first observer subscribes. Until then, `emit_*` methods are
/// effectively free: they check an atomic and return. This keeps the
/// logs panel's memory footprint opt-in — if no one ever opens it, the
/// transport never allocates a line or pushes a channel item.
#[derive(Clone)]
pub struct AcpLogTap {
enabled: Arc<AtomicBool>,
sender: smol::channel::Sender<RawStreamLine>,
}
impl AcpLogTap {
fn is_enabled(&self) -> bool {
self.enabled.load(Ordering::Relaxed)
}
fn enable(&self) {
self.enabled.store(true, Ordering::Relaxed);
}
fn emit(&self, direction: StreamMessageDirection, line: &str) {
if !self.is_enabled() {
return;
}
self.sender
.try_send(RawStreamLine {
direction,
line: Arc::from(line),
})
.log_err();
}
/// Record a line read from the agent's stdout.
pub fn emit_incoming(&self, line: &str) {
self.emit(StreamMessageDirection::Incoming, line);
}
/// Record a line written to the agent's stdin.
pub fn emit_outgoing(&self, line: &str) {
self.emit(StreamMessageDirection::Outgoing, line);
}
/// Record a line read from the agent's stderr.
pub fn emit_stderr(&self, line: &str) {
self.emit(StreamMessageDirection::Stderr, line);
}
}
/// Maximum number of messages retained in the registry's backlog.
///
/// Mirrors `MAX_STORED_LOG_ENTRIES` in the LSP log store, so that opening the
/// ACP logs panel after a session has been running for a while still shows
/// meaningful history.
const MAX_BACKLOG_MESSAGES: usize = 2000;
#[derive(Default)]
pub struct AcpConnectionRegistry {
active_agent_id: Option<AgentId>,
generation: u64,
/// Bounded ring buffer of every message observed on the current connection.
/// When a new connection is set, this is cleared.
backlog: VecDeque<StreamMessage>,
subscribers: Vec<smol::channel::Sender<StreamMessage>>,
/// The tap handed to the currently active connection, so the registry
/// can flip its `enabled` flag the first time someone subscribes.
active_tap: Option<AcpLogTap>,
_broadcast_task: Option<Task<()>>,
}
impl AcpConnectionRegistry {
@@ -63,17 +242,94 @@ impl AcpConnectionRegistry {
}
}
/// Register a new active connection and return an [`AcpLogTap`] that
/// the connection should hand to its transport + stderr readers.
///
/// The tap starts out disabled: transport lines are dropped cheaply
/// until someone subscribes via [`Self::subscribe`], at which point
/// the tap is flipped on and subsequent lines are broadcast to all
/// current and future subscribers.
pub fn set_active_connection(
&self,
&mut self,
agent_id: AgentId,
connection: &Rc<acp::ClientSideConnection>,
cx: &mut Context<Self>,
) {
self.active_connection.replace(Some(ActiveConnection {
agent_id,
connection: Rc::downgrade(connection),
) -> AcpLogTap {
let (sender, raw_rx) = smol::channel::unbounded::<RawStreamLine>();
let tap = AcpLogTap {
enabled: Arc::new(AtomicBool::new(false)),
sender,
};
self.active_agent_id = Some(agent_id);
self.generation += 1;
self.backlog.clear();
self.subscribers.clear();
self.active_tap = Some(tap.clone());
self._broadcast_task = Some(cx.spawn(async move |this, cx| {
while let Ok(raw) = raw_rx.recv().await {
this.update(cx, |this, _cx| {
let Some(message) = StreamMessage::from_raw_line(raw.direction, &raw.line)
else {
return;
};
if this.backlog.len() == MAX_BACKLOG_MESSAGES {
this.backlog.pop_front();
}
this.backlog.push_back(message.clone());
this.subscribers.retain(|sender| !sender.is_closed());
for sender in &this.subscribers {
sender.try_send(message.clone()).log_err();
}
})
.log_err();
}
// The transport closed — clear state so observers (e.g. the ACP
// logs tab) can transition back to the disconnected state.
this.update(cx, |this, cx| {
this.active_agent_id = None;
this.subscribers.clear();
this.active_tap = None;
cx.notify();
})
.log_err();
}));
cx.notify();
tap
}
/// Clear the retained message history for the current connection and force
/// watchers to resubscribe so their local correlation state is reset too.
pub fn clear_messages(&mut self, cx: &mut Context<Self>) {
self.backlog.clear();
self.generation += 1;
self.subscribers.clear();
cx.notify();
}
/// Subscribe to messages on the current connection.
///
/// Returns the existing backlog (already-observed messages) together with
/// a receiver for new messages. The caller is responsible for flushing the
/// backlog into its local state before draining the receiver, so that no
/// messages are dropped between the snapshot and live subscription.
///
/// The first subscription enables the connection's log tap; prior
/// messages are therefore not available. This is intentional: the tap
/// is opt-in so that the default case (no one ever opens the ACP logs
/// panel) performs zero per-message bookkeeping.
pub fn subscribe(&mut self) -> (Vec<StreamMessage>, smol::channel::Receiver<StreamMessage>) {
if let Some(tap) = &self.active_tap {
tap.enable();
}
let backlog = self.backlog.iter().cloned().collect();
let (sender, receiver) = smol::channel::unbounded();
self.subscribers.push(sender);
(backlog, receiver)
}
}
@@ -88,9 +344,9 @@ struct AcpTools {
struct WatchedConnection {
agent_id: AgentId,
generation: u64,
messages: Vec<WatchedConnectionMessage>,
list_state: ListState,
connection: Weak<acp::ClientSideConnection>,
incoming_request_methods: HashMap<acp::RequestId, Arc<str>>,
outgoing_request_methods: HashMap<acp::RequestId, Arc<str>>,
_task: Task<()>,
@@ -118,44 +374,54 @@ impl AcpTools {
}
fn update_connection(&mut self, cx: &mut Context<Self>) {
let active_connection = self.connection_registry.read(cx).active_connection.borrow();
let Some(active_connection) = active_connection.as_ref() else {
let (generation, agent_id) = {
let registry = self.connection_registry.read(cx);
(registry.generation, registry.active_agent_id.clone())
};
let Some(agent_id) = agent_id else {
self.watched_connection = None;
self.expanded.clear();
return;
};
if let Some(watched_connection) = self.watched_connection.as_ref() {
if Weak::ptr_eq(
&watched_connection.connection,
&active_connection.connection,
) {
if let Some(watched) = self.watched_connection.as_ref() {
if watched.generation == generation {
return;
}
}
if let Some(connection) = active_connection.connection.upgrade() {
let mut receiver = connection.subscribe();
let task = cx.spawn(async move |this, cx| {
while let Ok(message) = receiver.recv().await {
this.update(cx, |this, cx| {
this.push_stream_message(message, cx);
})
.ok();
}
});
self.expanded.clear();
self.watched_connection = Some(WatchedConnection {
agent_id: active_connection.agent_id.clone(),
messages: vec![],
list_state: ListState::new(0, ListAlignment::Bottom, px(2048.)),
connection: active_connection.connection.clone(),
incoming_request_methods: HashMap::default(),
outgoing_request_methods: HashMap::default(),
_task: task,
});
let (backlog, messages_rx) = self
.connection_registry
.update(cx, |registry, _cx| registry.subscribe());
let task = cx.spawn(async move |this, cx| {
while let Ok(message) = messages_rx.recv().await {
this.update(cx, |this, cx| {
this.push_stream_message(message, cx);
})
.log_err();
}
});
self.watched_connection = Some(WatchedConnection {
agent_id,
generation,
messages: vec![],
list_state: ListState::new(0, ListAlignment::Bottom, px(2048.)),
incoming_request_methods: HashMap::default(),
outgoing_request_methods: HashMap::default(),
_task: task,
});
for message in backlog {
self.push_stream_message(message, cx);
}
}
fn push_stream_message(&mut self, stream_message: acp::StreamMessage, cx: &mut Context<Self>) {
fn push_stream_message(&mut self, stream_message: StreamMessage, cx: &mut Context<Self>) {
let Some(connection) = self.watched_connection.as_mut() else {
return;
};
@@ -163,27 +429,22 @@ impl AcpTools {
let index = connection.messages.len();
let (request_id, method, message_type, params) = match stream_message.message {
acp::StreamMessageContent::Request { id, method, params } => {
StreamMessageContent::Request { id, method, params } => {
let method_map = match stream_message.direction {
acp::StreamMessageDirection::Incoming => {
&mut connection.incoming_request_methods
}
acp::StreamMessageDirection::Outgoing => {
&mut connection.outgoing_request_methods
}
StreamMessageDirection::Incoming => &mut connection.incoming_request_methods,
StreamMessageDirection::Outgoing => &mut connection.outgoing_request_methods,
// Stderr lines never carry request/response correlation.
StreamMessageDirection::Stderr => return,
};
method_map.insert(id.clone(), method.clone());
(Some(id), method.into(), MessageType::Request, Ok(params))
}
acp::StreamMessageContent::Response { id, result } => {
StreamMessageContent::Response { id, result } => {
let method_map = match stream_message.direction {
acp::StreamMessageDirection::Incoming => {
&mut connection.outgoing_request_methods
}
acp::StreamMessageDirection::Outgoing => {
&mut connection.incoming_request_methods
}
StreamMessageDirection::Incoming => &mut connection.outgoing_request_methods,
StreamMessageDirection::Outgoing => &mut connection.incoming_request_methods,
StreamMessageDirection::Stderr => return,
};
if let Some(method) = method_map.remove(&id) {
@@ -197,9 +458,20 @@ impl AcpTools {
)
}
}
acp::StreamMessageContent::Notification { method, params } => {
StreamMessageContent::Notification { method, params } => {
(None, method.into(), MessageType::Notification, Ok(params))
}
StreamMessageContent::Stderr { line } => {
// Stderr is rendered as plain text inline with JSON-RPC traffic,
// using `stderr` as the pseudo-method name so it shows up in the
// header the same way real methods do.
(
None,
"stderr".into(),
MessageType::Stderr,
Ok(Some(serde_json::Value::String(line.to_string()))),
)
}
};
let message = WatchedConnectionMessage {
@@ -243,8 +515,9 @@ impl AcpTools {
};
Some(serde_json::json!({
"_direction": match message.direction {
acp::StreamMessageDirection::Incoming => "incoming",
acp::StreamMessageDirection::Outgoing => "outgoing",
StreamMessageDirection::Incoming => "incoming",
StreamMessageDirection::Outgoing => "outgoing",
StreamMessageDirection::Stderr => "stderr",
},
"_type": message.message_type.to_string().to_lowercase(),
"id": message.request_id,
@@ -261,6 +534,8 @@ impl AcpTools {
if let Some(connection) = self.watched_connection.as_mut() {
connection.messages.clear();
connection.list_state.reset(0);
connection.incoming_request_methods.clear();
connection.outgoing_request_methods.clear();
self.expanded.clear();
cx.notify();
}
@@ -326,12 +601,15 @@ impl AcpTools {
cx.notify()
}))
.child(match message.direction {
acp::StreamMessageDirection::Incoming => Icon::new(IconName::ArrowDown)
StreamMessageDirection::Incoming => Icon::new(IconName::ArrowDown)
.color(Color::Error)
.size(IconSize::Small),
acp::StreamMessageDirection::Outgoing => Icon::new(IconName::ArrowUp)
StreamMessageDirection::Outgoing => Icon::new(IconName::ArrowUp)
.color(Color::Success)
.size(IconSize::Small),
StreamMessageDirection::Stderr => Icon::new(IconName::Warning)
.color(Color::Warning)
.size(IconSize::Small),
})
.child(
Label::new(message.name.clone())
@@ -403,7 +681,7 @@ impl AcpTools {
struct WatchedConnectionMessage {
name: SharedString,
request_id: Option<acp::RequestId>,
direction: acp::StreamMessageDirection,
direction: StreamMessageDirection,
message_type: MessageType,
params: Result<Option<serde_json::Value>, acp::Error>,
collapsed_params_md: Option<Entity<Markdown>>,
@@ -463,6 +741,7 @@ enum MessageType {
Request,
Response,
Notification,
Stderr,
}
impl Display for MessageType {
@@ -471,6 +750,7 @@ impl Display for MessageType {
MessageType::Request => write!(f, "Request"),
MessageType::Response => write!(f, "Response"),
MessageType::Notification => write!(f, "Notification"),
MessageType::Stderr => write!(f, "Stderr"),
}
}
}
@@ -561,6 +841,7 @@ impl Render for AcpToolsToolbarItemView {
};
let acp_tools = acp_tools.clone();
let connection_registry = acp_tools.read(cx).connection_registry.clone();
let has_messages = acp_tools
.read(cx)
.watched_connection
@@ -585,6 +866,9 @@ impl Render for AcpToolsToolbarItemView {
.tooltip(Tooltip::text("Clear Messages"))
.disabled(!has_messages)
.on_click(cx.listener(move |_this, _, _window, cx| {
connection_registry.update(cx, |registry, cx| {
registry.clear_messages(cx);
});
acp_tools.update(cx, |acp_tools, cx| {
acp_tools.clear_messages(cx);
});
+1 -1
View File
@@ -28,7 +28,7 @@ use acp_thread::{
AcpThread, AgentModelSelector, AgentSessionInfo, AgentSessionList, AgentSessionListRequest,
AgentSessionListResponse, TokenUsageRatio, UserMessageId,
};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::{Context as _, Result, anyhow};
use chrono::{DateTime, Utc};
use collections::{HashMap, HashSet, IndexMap};
+1 -1
View File
@@ -1,6 +1,6 @@
use crate::{AgentMessage, AgentMessageContent, UserMessage, UserMessageContent};
use acp_thread::UserMessageId;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_settings::AgentProfileId;
use anyhow::{Result, anyhow};
use chrono::{DateTime, Utc};
+1 -1
View File
@@ -1,6 +1,6 @@
use std::{any::Any, rc::Rc, sync::Arc};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_servers::{AgentServer, AgentServerDelegate};
use agent_settings::{AgentSettings, language_model_to_selection};
use anyhow::Result;
+2 -2
View File
@@ -3,7 +3,7 @@ use acp_thread::{
AgentConnection, AgentModelGroupName, AgentModelList, PermissionOptions, ThreadStatus,
UserMessageId,
};
use agent_client_protocol::{self as acp};
use agent_client_protocol::schema as acp;
use agent_settings::AgentProfileId;
use anyhow::Result;
use client::{Client, RefreshLlmTokenListener, UserStore};
@@ -5402,7 +5402,7 @@ async fn test_max_subagent_depth_prevents_tool_registration(cx: &mut TestAppCont
cx,
);
thread.set_subagent_context(SubagentContext {
parent_thread_id: agent_client_protocol::SessionId::new("parent-id"),
parent_thread_id: acp::SessionId::new("parent-id"),
depth: MAX_SUBAGENT_DEPTH - 1,
});
thread
+2 -2
View File
@@ -12,7 +12,7 @@ use feature_flags::{
FeatureFlagAppExt as _, StreamingEditFileToolFeatureFlag, UpdatePlanToolFeatureFlag,
};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_settings::{
AgentProfileId, AgentSettings, SUMMARIZE_THREAD_DETAILED_PROMPT, SUMMARIZE_THREAD_PROMPT,
};
@@ -3445,7 +3445,7 @@ where
T::description()
}
fn kind(&self) -> agent_client_protocol::ToolKind {
fn kind(&self) -> acp::ToolKind {
T::kind()
}
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::{DbThread, DbThreadMetadata, ThreadsDatabase};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::{Result, anyhow};
use gpui::{App, Context, Entity, Global, Task, prelude::*};
use util::path_list::PathList;
@@ -1,5 +1,5 @@
use crate::{AgentToolOutput, AnyAgentTool, ToolCallEventStream, ToolInput};
use agent_client_protocol::ToolKind;
use agent_client_protocol::schema as acp;
use anyhow::Result;
use collections::{BTreeMap, HashMap};
use context_server::{ContextServerId, client::NotificationSubscription};
@@ -304,8 +304,8 @@ impl AnyAgentTool for ContextServerTool {
self.tool.description.clone().unwrap_or_default().into()
}
fn kind(&self) -> ToolKind {
ToolKind::Other
fn kind(&self) -> acp::ToolKind {
acp::ToolKind::Other
}
fn initial_title(&self, _input: serde_json::Value, _cx: &mut App) -> SharedString {
+3 -4
View File
@@ -5,7 +5,7 @@ use super::tool_permissions::{
use crate::{
AgentTool, ToolCallEventStream, ToolInput, ToolPermissionDecision, decide_permission_for_paths,
};
use agent_client_protocol::ToolKind;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use futures::FutureExt as _;
use gpui::{App, Entity, Task};
@@ -61,8 +61,8 @@ impl AgentTool for CopyPathTool {
const NAME: &'static str = "copy_path";
fn kind() -> ToolKind {
ToolKind::Move
fn kind() -> acp::ToolKind {
acp::ToolKind::Move
}
fn initial_title(
@@ -198,7 +198,6 @@ impl AgentTool for CopyPathTool {
#[cfg(test)]
mod tests {
use super::*;
use agent_client_protocol as acp;
use fs::Fs as _;
use gpui::TestAppContext;
use project::{FakeFs, Project};
@@ -2,7 +2,7 @@ use super::tool_permissions::{
SensitiveSettingsKind, authorize_symlink_access, canonicalize_worktree_roots,
detect_symlink_escape, sensitive_settings_kind,
};
use agent_client_protocol::ToolKind;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use futures::FutureExt as _;
use gpui::{App, Entity, SharedString, Task};
@@ -52,8 +52,8 @@ impl AgentTool for CreateDirectoryTool {
const NAME: &'static str = "create_directory";
fn kind() -> ToolKind {
ToolKind::Read
fn kind() -> acp::ToolKind {
acp::ToolKind::Read
}
fn initial_title(
@@ -169,7 +169,6 @@ impl AgentTool for CreateDirectoryTool {
#[cfg(test)]
mod tests {
use super::*;
use agent_client_protocol as acp;
use fs::Fs as _;
use gpui::TestAppContext;
use project::{FakeFs, Project};
+3 -4
View File
@@ -6,7 +6,7 @@ use crate::{
AgentTool, ToolCallEventStream, ToolInput, ToolPermissionDecision, decide_permission_for_path,
};
use action_log::ActionLog;
use agent_client_protocol::ToolKind;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use futures::{FutureExt as _, SinkExt, StreamExt, channel::mpsc};
use gpui::{App, AppContext, Entity, SharedString, Task};
@@ -55,8 +55,8 @@ impl AgentTool for DeletePathTool {
const NAME: &'static str = "delete_path";
fn kind() -> ToolKind {
ToolKind::Delete
fn kind() -> acp::ToolKind {
acp::ToolKind::Delete
}
fn initial_title(
@@ -228,7 +228,6 @@ impl AgentTool for DeletePathTool {
#[cfg(test)]
mod tests {
use super::*;
use agent_client_protocol as acp;
use fs::Fs as _;
use gpui::TestAppContext;
use project::{FakeFs, Project};
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::{AgentTool, ToolCallEventStream, ToolInput};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::Result;
use futures::FutureExt as _;
use gpui::{App, Entity, Task};
+3 -3
View File
@@ -6,7 +6,7 @@ use crate::{
edit_agent::{EditAgent, EditAgentOutputEvent, EditFormat},
};
use acp_thread::Diff;
use agent_client_protocol::{self as acp, ToolCallLocation, ToolCallUpdateFields};
use agent_client_protocol::schema as acp;
use anyhow::{Context as _, Result};
use collections::HashSet;
use futures::{FutureExt as _, StreamExt as _};
@@ -260,7 +260,7 @@ impl AgentTool for EditFileTool {
let abs_path = project.read(cx).absolute_path(&project_path, cx);
if let Some(abs_path) = abs_path.clone() {
event_stream.update_fields(
ToolCallUpdateFields::new()
acp::ToolCallUpdateFields::new()
.locations(vec![acp::ToolCallLocation::new(abs_path)]),
);
}
@@ -409,7 +409,7 @@ impl AgentTool for EditFileTool {
range.start.to_point(&buffer.snapshot()).row
}));
if let Some(abs_path) = abs_path.clone() {
event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![ToolCallLocation::new(abs_path).line(line)]));
event_stream.update_fields(acp::ToolCallUpdateFields::new().locations(vec![acp::ToolCallLocation::new(abs_path).line(line)]));
}
emitted_location = true;
}
+1 -1
View File
@@ -2,7 +2,7 @@ use std::rc::Rc;
use std::sync::Arc;
use std::{borrow::Cow, cell::RefCell};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use anyhow::{Context as _, Result, bail};
use futures::{AsyncReadExt as _, FutureExt as _};
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::{AgentTool, ToolCallEventStream, ToolInput};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::{Result, anyhow};
use futures::FutureExt as _;
use gpui::{App, AppContext, Entity, SharedString, Task};
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::{AgentTool, ToolCallEventStream, ToolInput};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::Result;
use futures::{FutureExt as _, StreamExt};
use gpui::{App, Entity, SharedString, Task};
@@ -3,7 +3,7 @@ use super::tool_permissions::{
resolve_project_path,
};
use crate::{AgentTool, ToolCallEventStream, ToolInput};
use agent_client_protocol::ToolKind;
use agent_client_protocol::schema as acp;
use anyhow::{Context as _, Result, anyhow};
use gpui::{App, Entity, SharedString, Task};
use project::{Project, ProjectPath, WorktreeSettings};
@@ -127,8 +127,8 @@ impl AgentTool for ListDirectoryTool {
const NAME: &'static str = "list_directory";
fn kind() -> ToolKind {
ToolKind::Read
fn kind() -> acp::ToolKind {
acp::ToolKind::Read
}
fn initial_title(
@@ -267,7 +267,6 @@ impl AgentTool for ListDirectoryTool {
#[cfg(test)]
mod tests {
use super::*;
use agent_client_protocol as acp;
use fs::Fs as _;
use gpui::{TestAppContext, UpdateGlobal};
use indoc::indoc;
+3 -4
View File
@@ -5,7 +5,7 @@ use super::tool_permissions::{
use crate::{
AgentTool, ToolCallEventStream, ToolInput, ToolPermissionDecision, decide_permission_for_paths,
};
use agent_client_protocol::ToolKind;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use futures::FutureExt as _;
use gpui::{App, Entity, SharedString, Task};
@@ -62,8 +62,8 @@ impl AgentTool for MovePathTool {
const NAME: &'static str = "move_path";
fn kind() -> ToolKind {
ToolKind::Move
fn kind() -> acp::ToolKind {
acp::ToolKind::Move
}
fn initial_title(
@@ -205,7 +205,6 @@ impl AgentTool for MovePathTool {
#[cfg(test)]
mod tests {
use super::*;
use agent_client_protocol as acp;
use fs::Fs as _;
use gpui::TestAppContext;
use project::{FakeFs, Project};
+1 -1
View File
@@ -1,6 +1,6 @@
use std::sync::Arc;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use chrono::{Local, Utc};
use gpui::{App, SharedString, Task};
use schemars::JsonSchema;
+3 -3
View File
@@ -3,7 +3,7 @@ use super::tool_permissions::{
resolve_project_path,
};
use crate::{AgentTool, ToolInput};
use agent_client_protocol::ToolKind;
use agent_client_protocol::schema as acp;
use futures::FutureExt as _;
use gpui::{App, AppContext as _, Entity, SharedString, Task};
use project::Project;
@@ -43,8 +43,8 @@ impl AgentTool for OpenTool {
const NAME: &'static str = "open";
fn kind() -> ToolKind {
ToolKind::Execute
fn kind() -> acp::ToolKind {
acp::ToolKind::Execute
}
fn initial_title(
+4 -5
View File
@@ -1,5 +1,5 @@
use action_log::ActionLog;
use agent_client_protocol::{self as acp, ToolCallUpdateFields};
use agent_client_protocol::schema as acp;
use anyhow::{Context as _, Result, anyhow};
use futures::FutureExt as _;
use gpui::{App, Entity, SharedString, Task};
@@ -200,7 +200,7 @@ impl AgentTool for ReadFileTool {
let file_path = input.path.clone();
cx.update(|_cx| {
event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![
event_stream.update_fields(acp::ToolCallUpdateFields::new().locations(vec![
acp::ToolCallLocation::new(&abs_path)
.line(input.start_line.map(|line| line.saturating_sub(1))),
]));
@@ -228,7 +228,7 @@ impl AgentTool for ReadFileTool {
.context("processing image")
.map_err(tool_content_err)?;
event_stream.update_fields(ToolCallUpdateFields::new().content(vec![
event_stream.update_fields(acp::ToolCallUpdateFields::new().content(vec![
acp::ToolCallContent::Content(acp::Content::new(acp::ContentBlock::Image(
acp::ImageContent::new(language_model_image.source.clone(), "image/png"),
))),
@@ -333,7 +333,7 @@ impl AgentTool for ReadFileTool {
text,
}
.to_string();
event_stream.update_fields(ToolCallUpdateFields::new().content(vec![
event_stream.update_fields(acp::ToolCallUpdateFields::new().content(vec![
acp::ToolCallContent::Content(acp::Content::new(markdown)),
]));
}
@@ -347,7 +347,6 @@ impl AgentTool for ReadFileTool {
#[cfg(test)]
mod test {
use super::*;
use agent_client_protocol as acp;
use fs::Fs as _;
use gpui::{AppContext, TestAppContext, UpdateGlobal as _};
use project::{FakeFs, Project};
@@ -3,7 +3,7 @@ use super::tool_permissions::{
canonicalize_worktree_roots, path_has_symlink_escape, resolve_project_path,
sensitive_settings_kind,
};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use collections::FxHashSet;
use futures::FutureExt as _;
+1 -1
View File
@@ -1,4 +1,4 @@
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use collections::FxHashSet;
use futures::FutureExt as _;
+1 -1
View File
@@ -1,5 +1,5 @@
use acp_thread::{SUBAGENT_SESSION_INFO_META_KEY, SubagentSessionInfo};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::Result;
use gpui::{App, SharedString, Task};
use language_model::LanguageModelToolResultContent;
@@ -12,7 +12,7 @@ use crate::{
};
use acp_thread::Diff;
use action_log::ActionLog;
use agent_client_protocol::{self as acp, ToolCallLocation, ToolCallUpdateFields};
use agent_client_protocol::schema::{self as acp, ToolCallLocation, ToolCallUpdateFields};
use anyhow::Result;
use collections::HashSet;
use futures::FutureExt as _;
+1 -1
View File
@@ -1,4 +1,4 @@
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use anyhow::Result;
use futures::FutureExt as _;
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::{AgentTool, ToolCallEventStream, ToolInput};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use gpui::{App, SharedString, Task};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
+1 -1
View File
@@ -4,7 +4,7 @@ use crate::{
AgentTool, ToolCallEventStream, ToolInput, ToolPermissionDecision,
decide_permission_from_settings,
};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use anyhow::Result;
use cloud_llm_client::WebSearchResponse;
+1 -4
View File
@@ -6,7 +6,7 @@ publish.workspace = true
license = "GPL-3.0-or-later"
[features]
test-support = ["acp_thread/test-support", "gpui/test-support", "project/test-support", "dep:async-pipe", "dep:env_logger", "client/test-support", "dep:gpui_tokio", "reqwest_client/test-support"]
test-support = ["acp_tools/test-support", "acp_thread/test-support", "gpui/test-support", "project/test-support", "dep:env_logger", "client/test-support", "dep:gpui_tokio", "reqwest_client/test-support"]
e2e = []
[lints]
@@ -22,8 +22,6 @@ acp_thread.workspace = true
action_log.workspace = true
agent-client-protocol.workspace = true
anyhow.workspace = true
async-pipe = { workspace = true, optional = true }
async-trait.workspace = true
chrono.workspace = true
client.workspace = true
collections.workspace = true
@@ -67,7 +65,6 @@ fs.workspace = true
indoc.workspace = true
acp_thread = { workspace = true, features = ["test-support"] }
async-pipe.workspace = true
gpui = { workspace = true, features = ["test-support"] }
gpui_tokio.workspace = true
project = { workspace = true, features = ["test-support"] }
File diff suppressed because it is too large. Load diff
+11 -10
View File
@@ -12,6 +12,7 @@ use http_client::read_no_proxy_from_env;
use project::{AgentId, Project, agent_server_store::AgentServerStore};
use acp_thread::AgentConnection;
use agent_client_protocol::schema as acp_schema;
use anyhow::Result;
use gpui::{App, AppContext, Entity, Task};
use settings::SettingsStore;
@@ -52,31 +53,31 @@ pub trait AgentServer: Send {
fn into_any(self: Rc<Self>) -> Rc<dyn Any>;
fn default_mode(&self, _cx: &App) -> Option<agent_client_protocol::SessionModeId> {
fn default_mode(&self, _cx: &App) -> Option<acp_schema::SessionModeId> {
None
}
fn set_default_mode(
&self,
_mode_id: Option<agent_client_protocol::SessionModeId>,
_mode_id: Option<acp_schema::SessionModeId>,
_fs: Arc<dyn Fs>,
_cx: &mut App,
) {
}
fn default_model(&self, _cx: &App) -> Option<agent_client_protocol::ModelId> {
fn default_model(&self, _cx: &App) -> Option<acp_schema::ModelId> {
None
}
fn set_default_model(
&self,
_model_id: Option<agent_client_protocol::ModelId>,
_model_id: Option<acp_schema::ModelId>,
_fs: Arc<dyn Fs>,
_cx: &mut App,
) {
}
fn favorite_model_ids(&self, _cx: &mut App) -> HashSet<agent_client_protocol::ModelId> {
fn favorite_model_ids(&self, _cx: &mut App) -> HashSet<acp_schema::ModelId> {
HashSet::default()
}
@@ -95,16 +96,16 @@ pub trait AgentServer: Send {
fn favorite_config_option_value_ids(
&self,
_config_id: &agent_client_protocol::SessionConfigId,
_config_id: &acp_schema::SessionConfigId,
_cx: &mut App,
) -> HashSet<agent_client_protocol::SessionConfigValueId> {
) -> HashSet<acp_schema::SessionConfigValueId> {
HashSet::default()
}
fn toggle_favorite_config_option_value(
&self,
_config_id: agent_client_protocol::SessionConfigId,
_value_id: agent_client_protocol::SessionConfigValueId,
_config_id: acp_schema::SessionConfigId,
_value_id: acp_schema::SessionConfigValueId,
_should_be_favorite: bool,
_fs: Arc<dyn Fs>,
_cx: &App,
@@ -113,7 +114,7 @@ pub trait AgentServer: Send {
fn toggle_favorite_model(
&self,
_model_id: agent_client_protocol::ModelId,
_model_id: acp_schema::ModelId,
_should_be_favorite: bool,
_fs: Arc<dyn Fs>,
_cx: &App,
+1 -1
View File
@@ -1,6 +1,6 @@
use crate::{AgentServer, AgentServerDelegate, load_proxy_env};
use acp_thread::AgentConnection;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::{Context as _, Result};
use collections::HashSet;
use fs::Fs;
+2 -2
View File
@@ -1,6 +1,6 @@
use crate::{AgentServer, AgentServerDelegate};
use acp_thread::{AcpThread, AgentThreadEntry, ToolCall, ToolCallStatus};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use client::RefreshLlmTokenListener;
use futures::{FutureExt, StreamExt, channel::mpsc, select};
use gpui::AppContext;
@@ -379,7 +379,7 @@ macro_rules! common_e2e_tests {
async fn tool_call_with_permission(cx: &mut ::gpui::TestAppContext) {
$crate::e2e_tests::test_tool_call_with_permission(
$server,
::agent_client_protocol::PermissionOptionId::new($allow_option_id),
::agent_client_protocol::schema::PermissionOptionId::new($allow_option_id),
cx,
)
.await;
+3 -3
View File
@@ -3,7 +3,7 @@ mod agent_profile;
use std::path::{Component, Path};
use std::sync::{Arc, LazyLock};
use agent_client_protocol::ModelId;
use agent_client_protocol::schema as acp;
use collections::{HashSet, IndexMap};
use fs::Fs;
use futures::channel::oneshot;
@@ -204,10 +204,10 @@ impl AgentSettings {
self.message_editor_min_lines * 2
}
pub fn favorite_model_ids(&self) -> HashSet<ModelId> {
pub fn favorite_model_ids(&self) -> HashSet<acp::ModelId> {
self.favorite_models
.iter()
.map(|sel| ModelId::new(format!("{}/{}", sel.provider.0, sel.model)))
.map(|sel| acp::ModelId::new(format!("{}/{}", sel.provider.0, sel.model)))
.collect()
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ use std::{
use acp_thread::{AcpThread, AcpThreadEvent, MentionUri, ThreadStatus};
use agent::{ContextServerRegistry, SharedThread, ThreadStore};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_servers::AgentServer;
use collections::HashSet;
use db::kvp::{Dismissable, KeyValueStore};
+3 -3
View File
@@ -38,7 +38,7 @@ use std::rc::Rc;
use std::sync::Arc;
use ::ui::IconName;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_settings::{AgentProfileId, AgentSettings};
use command_palette_hooks::CommandPaletteFilter;
use feature_flags::FeatureFlagAppExt as _;
@@ -255,7 +255,7 @@ pub struct NewExternalAgentThread {
#[action(namespace = agent)]
#[serde(deny_unknown_fields)]
pub struct NewNativeAgentThreadFromSummary {
from_session_id: agent_client_protocol::SessionId,
from_session_id: acp::SessionId,
}
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
@@ -339,7 +339,7 @@ pub enum AgentInitialContent {
title: Option<SharedString>,
},
ContentBlock {
blocks: Vec<agent_client_protocol::ContentBlock>,
blocks: Vec<acp::ContentBlock>,
auto_submit: bool,
},
FromExternalSource(ExternalSourcePrompt),
+1 -1
View File
@@ -7,7 +7,7 @@ use std::sync::atomic::AtomicBool;
use crate::DEFAULT_THREAD_TITLE;
use crate::thread_metadata_store::{ThreadMetadata, ThreadMetadataStore};
use acp_thread::MentionUri;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::Result;
use editor::{CompletionProvider, Editor, code_context_menus::COMPLETION_MENU_MAX_WIDTH};
use futures::FutureExt as _;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{cmp::Reverse, rc::Rc, sync::Arc};
use acp_thread::AgentSessionConfigOptions;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_servers::AgentServer;
use collections::HashSet;
+11 -12
View File
@@ -10,7 +10,7 @@ use action_log::{ActionLog, ActionLogTelemetry, DiffStats};
use agent::{
NativeAgentServer, NativeAgentSessionList, NoModelConfiguredError, SharedThread, ThreadStore,
};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
#[cfg(test)]
use agent_servers::AgentServerDelegate;
use agent_servers::{AgentServer, GEMINI_TERMINAL_AUTH_METHOD_ID};
@@ -2852,7 +2852,6 @@ pub(crate) mod tests {
use acp_thread::StubAgentConnection;
use action_log::ActionLog;
use agent::{AgentTool, EditFileTool, FetchTool, TerminalTool, ToolPermissionContext};
use agent_client_protocol::SessionId;
use agent_servers::FakeAcpAgentServer;
use editor::MultiBufferOffset;
use fs::FakeFs;
@@ -3034,7 +3033,7 @@ pub(crate) mod tests {
Rc::new(StubAgentServer::new(ResumeOnlyAgentConnection)),
connection_store,
Agent::Custom { id: "Test".into() },
Some(SessionId::new("resume-session")),
Some(acp::SessionId::new("resume-session")),
None,
None,
None,
@@ -3081,7 +3080,7 @@ pub(crate) mod tests {
self,
project,
"RestoredAvailableCommandsConnection",
SessionId::new("new-session"),
acp::SessionId::new("new-session"),
cx,
);
Task::ready(Ok(thread))
@@ -3171,7 +3170,7 @@ pub(crate) mod tests {
Rc::new(StubAgentServer::new(RestoredAvailableCommandsConnection)),
connection_store,
Agent::Custom { id: "Test".into() },
Some(SessionId::new("restored-session")),
Some(acp::SessionId::new("restored-session")),
None,
None,
None,
@@ -3253,7 +3252,7 @@ pub(crate) mod tests {
Rc::new(StubAgentServer::new(connection)),
connection_store,
Agent::Custom { id: "Test".into() },
Some(SessionId::new("session-1")),
Some(acp::SessionId::new("session-1")),
None,
Some(PathList::new(&[PathBuf::from("/project/subdir")])),
None,
@@ -3360,7 +3359,7 @@ pub(crate) mod tests {
cx.update(|_window, cx| cx.new(|cx| AgentConnectionStore::new(project.clone(), cx)));
// Simulate a previous run that persisted metadata for this session.
let resume_session_id = SessionId::new("persistent-session");
let resume_session_id = acp::SessionId::new("persistent-session");
let stored_title: SharedString = "Persistent chat".into();
cx.update(|_window, cx| {
ThreadMetadataStore::global(cx).update(cx, |store, cx| {
@@ -4320,7 +4319,7 @@ pub(crate) mod tests {
connection: Rc<dyn AgentConnection>,
project: Entity<Project>,
name: &'static str,
session_id: SessionId,
session_id: acp::SessionId,
cx: &mut App,
) -> Entity<AcpThread> {
let action_log = cx.new(|_| ActionLog::new(project.clone()));
@@ -4366,7 +4365,7 @@ pub(crate) mod tests {
self,
project,
"ResumeOnlyAgentConnection",
SessionId::new("new-session"),
acp::SessionId::new("new-session"),
cx,
);
Task::ready(Ok(thread))
@@ -4546,7 +4545,7 @@ pub(crate) mod tests {
self,
project,
action_log,
SessionId::new("test"),
acp::SessionId::new("test"),
watch::Receiver::constant(
acp::PromptCapabilities::new()
.image(true)
@@ -4626,7 +4625,7 @@ pub(crate) mod tests {
self.clone(),
project,
action_log,
SessionId::new("new-session"),
acp::SessionId::new("new-session"),
watch::Receiver::constant(
acp::PromptCapabilities::new()
.image(true)
@@ -7252,7 +7251,7 @@ pub(crate) mod tests {
self,
project,
action_log,
SessionId::new("close-capable-session"),
acp::SessionId::new("close-capable-session"),
watch::Receiver::constant(
acp::PromptCapabilities::new()
.image(true)
@@ -2,6 +2,7 @@ use crate::{
DEFAULT_THREAD_TITLE, SelectPermissionGranularity,
agent_configuration::configure_context_server_modal::default_markdown_style,
};
use agent_client_protocol::schema as acp;
use std::cell::RefCell;
use acp_thread::{ContentBlock, PlanEntry};
@@ -289,8 +290,8 @@ pub struct ThreadView {
pub session_capabilities: SharedSessionCapabilities,
/// Tracks which tool calls have their content/output expanded.
/// Used for showing/hiding tool call results, terminal output, etc.
pub expanded_tool_calls: HashSet<agent_client_protocol::ToolCallId>,
pub expanded_tool_call_raw_inputs: HashSet<agent_client_protocol::ToolCallId>,
pub expanded_tool_calls: HashSet<acp::ToolCallId>,
pub expanded_tool_call_raw_inputs: HashSet<acp::ToolCallId>,
pub expanded_thinking_blocks: HashSet<(usize, usize)>,
auto_expanded_thinking_block: Option<(usize, usize)>,
user_toggled_thinking_blocks: HashSet<(usize, usize)>,
@@ -306,12 +307,11 @@ pub struct ThreadView {
pub queued_message_editor_subscriptions: Vec<Subscription>,
pub last_synced_queue_length: usize,
pub turn_fields: TurnFields,
pub discarded_partial_edits: HashSet<agent_client_protocol::ToolCallId>,
pub discarded_partial_edits: HashSet<acp::ToolCallId>,
pub is_loading_contents: bool,
pub new_server_version_available: Option<SharedString>,
pub resumed_without_history: bool,
pub(crate) permission_selections:
HashMap<agent_client_protocol::ToolCallId, PermissionSelection>,
pub(crate) permission_selections: HashMap<acp::ToolCallId, PermissionSelection>,
pub resume_thread_metadata: Option<AgentSessionInfo>,
pub _cancel_task: Option<Task<()>>,
_save_task: Option<Task<()>>,
+5 -5
View File
@@ -2,7 +2,7 @@ use std::ops::Range;
use acp_thread::{AcpThread, AgentThreadEntry};
use agent::ThreadStore;
use agent_client_protocol::ToolCallId;
use agent_client_protocol::schema as acp;
use collections::HashMap;
use editor::{Editor, EditorEvent, EditorMode, MinimapVisibility, SizingBehavior};
use gpui::{
@@ -283,9 +283,9 @@ pub struct EntryViewEvent {
}
pub enum ViewEvent {
NewDiff(ToolCallId),
NewTerminal(ToolCallId),
TerminalMovedToBackground(ToolCallId),
NewDiff(acp::ToolCallId),
NewTerminal(acp::ToolCallId),
TerminalMovedToBackground(acp::ToolCallId),
MessageEditorEvent(Entity<MessageEditor>, MessageEditorEvent),
OpenDiffLocation {
path: String,
@@ -482,7 +482,7 @@ mod tests {
use std::sync::Arc;
use acp_thread::{AgentConnection, StubAgentConnection};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use buffer_diff::{DiffHunkStatus, DiffHunkStatusKind};
use editor::RowInfo;
use fs::FakeFs;
+1 -1
View File
@@ -1,7 +1,7 @@
use crate::diagnostics::{DiagnosticsOptions, codeblock_fence_for_path, collect_diagnostics};
use acp_thread::{MentionUri, selection_name};
use agent::{ThreadStore, outline};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_servers::{AgentServer, AgentServerDelegate};
use anyhow::{Context as _, Result, anyhow};
use collections::{HashMap, HashSet};
+2 -2
View File
@@ -10,7 +10,7 @@ use crate::{
};
use acp_thread::MentionUri;
use agent::ThreadStore;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::{Result, anyhow};
use editor::{
Addon, AnchorRangeExt, ContextMenuOptions, Editor, EditorElement, EditorEvent, EditorMode,
@@ -1907,7 +1907,7 @@ mod tests {
use acp_thread::MentionUri;
use agent::{ThreadStore, outline};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use base64::Engine as _;
use editor::{
AnchorRangeExt as _, Editor, EditorMode, MultiBufferOffset, SelectionEffects,
+1 -1
View File
@@ -1,5 +1,5 @@
use acp_thread::AgentSessionModes;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_servers::AgentServer;
use fs::Fs;
+6 -7
View File
@@ -1,7 +1,7 @@
use std::{cmp::Reverse, rc::Rc, sync::Arc};
use acp_thread::{AgentModelIcon, AgentModelInfo, AgentModelList, AgentModelSelector};
use agent_client_protocol::ModelId;
use agent_client_protocol::schema as acp;
use agent_servers::AgentServer;
use anyhow::Result;
@@ -57,7 +57,7 @@ pub struct ModelPickerDelegate {
selected_index: usize,
selected_description: Option<(usize, SharedString, bool)>,
selected_model: Option<AgentModelInfo>,
favorites: HashSet<ModelId>,
favorites: HashSet<acp::ModelId>,
_refresh_models_task: Task<()>,
_settings_subscription: Subscription,
focus_handle: FocusHandle,
@@ -424,7 +424,7 @@ impl PickerDelegate for ModelPickerDelegate {
fn info_list_to_picker_entries(
model_list: AgentModelList,
favorites: &HashSet<ModelId>,
favorites: &HashSet<acp::ModelId>,
) -> Vec<ModelPickerEntry> {
let mut entries = Vec::new();
@@ -530,7 +530,6 @@ async fn fuzzy_search(
#[cfg(test)]
mod tests {
use agent_client_protocol as acp;
use gpui::TestAppContext;
use super::*;
@@ -592,10 +591,10 @@ mod tests {
}
}
fn create_favorites(models: Vec<&str>) -> HashSet<ModelId> {
fn create_favorites(models: Vec<&str>) -> HashSet<acp::ModelId> {
models
.into_iter()
.map(|m| ModelId::new(m.to_string()))
.map(|m| acp::ModelId::new(m.to_string()))
.collect()
}
@@ -791,7 +790,7 @@ mod tests {
#[gpui::test]
fn test_favorites_count_returns_correct_count(_cx: &mut TestAppContext) {
let empty_favorites: HashSet<ModelId> = HashSet::default();
let empty_favorites: HashSet<acp::ModelId> = HashSet::default();
assert_eq!(empty_favorites.len(), 0);
let one_favorite = create_favorites(vec!["model-a"]);
+1 -1
View File
@@ -1,5 +1,5 @@
use acp_thread::{AgentConnection, StubAgentConnection};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_servers::{AgentServer, AgentServerDelegate};
use gpui::{Entity, Task, TestAppContext, VisualTestContext};
use project::AgentId;
+1 -1
View File
@@ -1,6 +1,6 @@
use acp_thread::AgentSessionListRequest;
use agent::ThreadStore;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use chrono::Utc;
use collections::HashSet;
use db::kvp::Dismissable;
+2 -3
View File
@@ -4,7 +4,7 @@ use std::{
};
use agent::{ThreadStore, ZED_AGENT_ID};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::Context as _;
use chrono::{DateTime, Utc};
use collections::{HashMap, HashSet};
@@ -1680,8 +1680,7 @@ mod tests {
use acp_thread::StubAgentConnection;
use action_log::ActionLog;
use agent::DbThread;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use gpui::{TestAppContext, VisualTestContext};
use project::FakeFs;
use project::Project;
+1 -1
View File
@@ -10,7 +10,7 @@ use crate::thread_metadata_store::{
use crate::{Agent, ArchiveSelectedThread, DEFAULT_THREAD_TITLE, RemoveSelectedThread};
use agent::ThreadStore;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use chrono::{DateTime, Datelike as _, Local, NaiveDate, TimeDelta, Utc};
use collections::HashMap;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{ops::RangeInclusive, path::PathBuf, time::Duration};
use acp_thread::MentionUri;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use editor::{Editor, SelectionEffects, scroll::Autoscroll};
use gpui::{
Animation, AnimationExt, AnyView, Context, IntoElement, WeakEntity, Window, pulsating_between,
+1 -1
View File
@@ -40,7 +40,7 @@ use std::time::{Duration, Instant};
use acp_thread::AgentConnection as _;
use agent::{NativeAgent, NativeAgentConnection, Templates, ThreadStore};
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use anyhow::{Context, Result};
use clap::Parser;
use feature_flags::FeatureFlagAppExt as _;
+1 -1
View File
@@ -2,7 +2,7 @@ mod thread_switcher;
use acp_thread::ThreadStatus;
use action_log::DiffStats;
use agent_client_protocol::{self as acp};
use agent_client_protocol::schema as acp;
use agent_settings::AgentSettings;
use agent_ui::thread_metadata_store::{
ThreadMetadata, ThreadMetadataStore, WorktreePaths, worktree_info_from_thread_paths,
+1 -1
View File
@@ -1,5 +1,5 @@
use action_log::DiffStats;
use agent_client_protocol as acp;
use agent_client_protocol::schema as acp;
use agent_ui::thread_metadata_store::ThreadMetadata;
use gpui::{
Action as _, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, Modifiers,
+2 -2
View File
@@ -5,7 +5,7 @@ mod reliability;
mod zed;
use agent::{SharedThread, ThreadStore};
use agent_client_protocol;
use agent_client_protocol::schema as acp;
use agent_ui::AgentPanel;
use anyhow::{Context as _, Result};
use clap::Parser;
@@ -990,7 +990,7 @@ fn handle_open_request(request: OpenRequest, app_state: Arc<AppState>, cx: &mut
let shared_thread = SharedThread::from_bytes(&response.thread_data)?;
let db_thread = shared_thread.to_db_thread();
let session_id = agent_client_protocol::SessionId::new(session_id);
let session_id = acp::SessionId::new(session_id);
let save_session_id = session_id.clone();
+1 -1
View File
@@ -95,7 +95,7 @@ fn main() {
#[cfg(target_os = "macos")]
use {
acp_thread::{AgentConnection, StubAgentConnection},
agent_client_protocol as acp,
agent_client_protocol::schema as acp,
agent_servers::{AgentServer, AgentServerDelegate},
anyhow::{Context as _, Result},
assets::Assets,