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:
1 parent
7107fdc008
commit
e77b071c39
62 files changed
+1861
-897
No files matched your search
Generated
+276
-116
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -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"
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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,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,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};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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,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,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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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,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};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,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,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;
|
||||
|
||||
@@ -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,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,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(
|
||||
|
||||
@@ -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,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,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,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,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};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
+1110
-584
File diff suppressed because it is too large.
Load diff
@@ -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,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;
|
||||
|
||||
@@ -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,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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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<()>>,
|
||||
|
||||
@@ -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,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};
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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,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,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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
@@ -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 _;
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user