Update to acp 0.0.6 (#34159)

Release Notes:

- N/A

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Agus Zubiaga 2025-07-09 22:14:29 -03:00 committed by GitHub
parent dc591fe7c7
commit 08ffd9884a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 59 additions and 37 deletions

4
Cargo.lock generated
View file

@ -263,9 +263,9 @@ dependencies = [
[[package]] [[package]]
name = "agentic-coding-protocol" name = "agentic-coding-protocol"
version = "0.0.5" version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b962eee17ee3924870d9b9d28cc8b6dcb5421e4d4e81cd864226374a122ceed1" checksum = "d1ac0351749af7bf53c65042ef69fefb9351aa8b7efa0a813d6281377605c37d"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",

View file

@ -404,7 +404,7 @@ zlog_settings = { path = "crates/zlog_settings" }
# External crates # External crates
# #
agentic-coding-protocol = "0.0.5" agentic-coding-protocol = "0.0.6"
aho-corasick = "1.1" aho-corasick = "1.1"
alacritty_terminal = { git = "https://github.com/zed-industries/alacritty.git", branch = "add-hush-login-flag" } alacritty_terminal = { git = "https://github.com/zed-industries/alacritty.git", branch = "add-hush-login-flag" }
any_vec = "0.14" any_vec = "0.14"

View file

@ -28,15 +28,15 @@ pub struct UserMessage {
impl UserMessage { impl UserMessage {
pub fn from_acp( pub fn from_acp(
message: acp::UserMessage, message: &acp::SendUserMessageParams,
language_registry: Arc<LanguageRegistry>, language_registry: Arc<LanguageRegistry>,
cx: &mut App, cx: &mut App,
) -> Self { ) -> Self {
let mut md_source = String::new(); let mut md_source = String::new();
for chunk in message.chunks { for chunk in &message.chunks {
match chunk { match chunk {
UserMessageChunk::Text { chunk } => md_source.push_str(&chunk), UserMessageChunk::Text { text } => md_source.push_str(&text),
UserMessageChunk::Path { path } => { UserMessageChunk::Path { path } => {
write!(&mut md_source, "{}", MentionPath(&path)).unwrap() write!(&mut md_source, "{}", MentionPath(&path)).unwrap()
} }
@ -116,11 +116,12 @@ impl AssistantMessageChunk {
cx: &mut App, cx: &mut App,
) -> Self { ) -> Self {
match chunk { match chunk {
acp::AssistantMessageChunk::Text { chunk } => Self::Text { acp::AssistantMessageChunk::Text { text } => Self::Text {
chunk: cx.new(|cx| Markdown::new(chunk.into(), Some(language_registry), None, cx)), chunk: cx.new(|cx| Markdown::new(text.into(), Some(language_registry), None, cx)),
}, },
acp::AssistantMessageChunk::Thought { chunk } => Self::Thought { acp::AssistantMessageChunk::Thought { thought } => Self::Thought {
chunk: cx.new(|cx| Markdown::new(chunk.into(), Some(language_registry), None, cx)), chunk: cx
.new(|cx| Markdown::new(thought.into(), Some(language_registry), None, cx)),
}, },
} }
} }
@ -607,11 +608,11 @@ impl AcpThread {
match (chunks.last_mut(), &chunk) { match (chunks.last_mut(), &chunk) {
( (
Some(AssistantMessageChunk::Text { chunk: old_chunk }), Some(AssistantMessageChunk::Text { chunk: old_chunk }),
acp::AssistantMessageChunk::Text { chunk: new_chunk }, acp::AssistantMessageChunk::Text { text: new_chunk },
) )
| ( | (
Some(AssistantMessageChunk::Thought { chunk: old_chunk }), Some(AssistantMessageChunk::Thought { chunk: old_chunk }),
acp::AssistantMessageChunk::Thought { chunk: new_chunk }, acp::AssistantMessageChunk::Thought { thought: new_chunk },
) => { ) => {
old_chunk.update(cx, |old_chunk, cx| { old_chunk.update(cx, |old_chunk, cx| {
old_chunk.append(&new_chunk, cx); old_chunk.append(&new_chunk, cx);
@ -813,16 +814,31 @@ impl AcpThread {
async move { Ok(connection.request(acp::AuthenticateParams).await?) } async move { Ok(connection.request(acp::AuthenticateParams).await?) }
} }
#[cfg(test)]
pub fn send_raw(
&mut self,
message: &str,
cx: &mut Context<Self>,
) -> BoxFuture<'static, Result<()>> {
self.send(
acp::SendUserMessageParams {
chunks: vec![acp::UserMessageChunk::Text {
text: message.to_string(),
}],
},
cx,
)
}
pub fn send( pub fn send(
&mut self, &mut self,
message: impl Into<acp::UserMessage>, message: acp::SendUserMessageParams,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> BoxFuture<'static, Result<()>> { ) -> BoxFuture<'static, Result<()>> {
let agent = self.connection.clone(); let agent = self.connection.clone();
let message = message.into();
self.push_entry( self.push_entry(
AgentThreadEntry::UserMessage(UserMessage::from_acp( AgentThreadEntry::UserMessage(UserMessage::from_acp(
message.clone(), &message,
self.project.read(cx).languages().clone(), self.project.read(cx).languages().clone(),
cx, cx,
)), )),
@ -835,7 +851,7 @@ impl AcpThread {
self.send_task = Some(cx.spawn(async move |this, cx| { self.send_task = Some(cx.spawn(async move |this, cx| {
cancel.await.log_err(); cancel.await.log_err();
let result = agent.request(acp::SendUserMessageParams { message }).await; let result = agent.request(message).await;
tx.send(result).log_err(); tx.send(result).log_err();
this.update(cx, |this, _cx| this.send_task.take()).log_err(); this.update(cx, |this, _cx| this.send_task.take()).log_err();
})); }));
@ -1030,8 +1046,6 @@ mod tests {
async fn test_thinking_concatenation(cx: &mut TestAppContext) { async fn test_thinking_concatenation(cx: &mut TestAppContext) {
init_test(cx); init_test(cx);
cx.executor().allow_parking();
let fs = FakeFs::new(cx.executor()); let fs = FakeFs::new(cx.executor());
let project = Project::test(fs, [], cx).await; let project = Project::test(fs, [], cx).await;
let (thread, fake_server) = fake_acp_thread(project, cx); let (thread, fake_server) = fake_acp_thread(project, cx);
@ -1042,7 +1056,7 @@ mod tests {
.update(&mut cx, |server, _| { .update(&mut cx, |server, _| {
server.send_to_zed(acp::StreamAssistantMessageChunkParams { server.send_to_zed(acp::StreamAssistantMessageChunkParams {
chunk: acp::AssistantMessageChunk::Thought { chunk: acp::AssistantMessageChunk::Thought {
chunk: "Thinking ".into(), thought: "Thinking ".into(),
}, },
}) })
})? })?
@ -1052,7 +1066,7 @@ mod tests {
.update(&mut cx, |server, _| { .update(&mut cx, |server, _| {
server.send_to_zed(acp::StreamAssistantMessageChunkParams { server.send_to_zed(acp::StreamAssistantMessageChunkParams {
chunk: acp::AssistantMessageChunk::Thought { chunk: acp::AssistantMessageChunk::Thought {
chunk: "hard!".into(), thought: "hard!".into(),
}, },
}) })
})? })?
@ -1064,7 +1078,7 @@ mod tests {
}); });
thread thread
.update(cx, |thread, cx| thread.send("Hello from Zed!", cx)) .update(cx, |thread, cx| thread.send_raw("Hello from Zed!", cx))
.await .await
.unwrap(); .unwrap();
@ -1123,7 +1137,7 @@ mod tests {
}); });
let request = thread.update(cx, |thread, cx| { let request = thread.update(cx, |thread, cx| {
thread.send("Fetch https://example.com", cx) thread.send_raw("Fetch https://example.com", cx)
}); });
run_until_first_tool_call(&thread, cx).await; run_until_first_tool_call(&thread, cx).await;
@ -1197,7 +1211,7 @@ mod tests {
let project = Project::test(fs, [], cx).await; let project = Project::test(fs, [], cx).await;
let thread = gemini_acp_thread(project.clone(), "/private/tmp", cx).await; let thread = gemini_acp_thread(project.clone(), "/private/tmp", cx).await;
thread thread
.update(cx, |thread, cx| thread.send("Hello from Zed!", cx)) .update(cx, |thread, cx| thread.send_raw("Hello from Zed!", cx))
.await .await
.unwrap(); .unwrap();
@ -1235,11 +1249,17 @@ mod tests {
thread thread
.update(cx, |thread, cx| { .update(cx, |thread, cx| {
thread.send( thread.send(
acp::UserMessage { acp::SendUserMessageParams {
chunks: vec![ chunks: vec![
"Read the file ".into(), acp::UserMessageChunk::Text {
Path::new("foo.rs").into(), text: "Read the file ".into(),
" and tell me what the content of the println! is".into(), },
acp::UserMessageChunk::Path {
path: Path::new("foo.rs").into(),
},
acp::UserMessageChunk::Text {
text: " and tell me what the content of the println! is".into(),
},
], ],
}, },
cx, cx,
@ -1283,7 +1303,7 @@ mod tests {
let thread = gemini_acp_thread(project.clone(), "/private/tmp", cx).await; let thread = gemini_acp_thread(project.clone(), "/private/tmp", cx).await;
thread thread
.update(cx, |thread, cx| { .update(cx, |thread, cx| {
thread.send( thread.send_raw(
"Read the '/private/tmp/foo' file and tell me what you see.", "Read the '/private/tmp/foo' file and tell me what you see.",
cx, cx,
) )
@ -1317,7 +1337,7 @@ mod tests {
let project = Project::test(fs, [path!("/private/tmp").as_ref()], cx).await; let project = Project::test(fs, [path!("/private/tmp").as_ref()], cx).await;
let thread = gemini_acp_thread(project.clone(), "/private/tmp", cx).await; let thread = gemini_acp_thread(project.clone(), "/private/tmp", cx).await;
let full_turn = thread.update(cx, |thread, cx| { let full_turn = thread.update(cx, |thread, cx| {
thread.send(r#"Run `echo "Hello, world!"`"#, cx) thread.send_raw(r#"Run `echo "Hello, world!"`"#, cx)
}); });
run_until_first_tool_call(&thread, cx).await; run_until_first_tool_call(&thread, cx).await;
@ -1386,7 +1406,7 @@ mod tests {
let project = Project::test(fs, [path!("/private/tmp").as_ref()], cx).await; let project = Project::test(fs, [path!("/private/tmp").as_ref()], cx).await;
let thread = gemini_acp_thread(project.clone(), "/private/tmp", cx).await; let thread = gemini_acp_thread(project.clone(), "/private/tmp", cx).await;
let full_turn = thread.update(cx, |thread, cx| { let full_turn = thread.update(cx, |thread, cx| {
thread.send(r#"Run `echo "Hello, world!"`"#, cx) thread.send_raw(r#"Run `echo "Hello, world!"`"#, cx)
}); });
let first_tool_call_ix = run_until_first_tool_call(&thread, cx).await; let first_tool_call_ix = run_until_first_tool_call(&thread, cx).await;
@ -1427,7 +1447,7 @@ mod tests {
thread thread
.update(cx, |thread, cx| { .update(cx, |thread, cx| {
thread.send(r#"Stop running and say goodbye to me."#, cx) thread.send_raw(r#"Stop running and say goodbye to me."#, cx)
}) })
.await .await
.unwrap(); .unwrap();

View file

@ -53,7 +53,7 @@ pub struct AcpThreadView {
auth_task: Option<Task<()>>, auth_task: Option<Task<()>>,
expanded_tool_calls: HashSet<ToolCallId>, expanded_tool_calls: HashSet<ToolCallId>,
expanded_thinking_blocks: HashSet<(usize, usize)>, expanded_thinking_blocks: HashSet<(usize, usize)>,
message_history: MessageHistory<acp::UserMessage>, message_history: MessageHistory<acp::SendUserMessageParams>,
} }
enum ThreadState { enum ThreadState {
@ -294,7 +294,7 @@ impl AcpThreadView {
let crease_range = crease.range().to_offset(&snapshot.buffer_snapshot); let crease_range = crease.range().to_offset(&snapshot.buffer_snapshot);
if crease_range.start > ix { if crease_range.start > ix {
chunks.push(acp::UserMessageChunk::Text { chunks.push(acp::UserMessageChunk::Text {
chunk: text[ix..crease_range.start].to_string(), text: text[ix..crease_range.start].to_string(),
}); });
} }
if let Some(abs_path) = project.read(cx).absolute_path(&project_path, cx) { if let Some(abs_path) = project.read(cx).absolute_path(&project_path, cx) {
@ -307,7 +307,9 @@ impl AcpThreadView {
if ix < text.len() { if ix < text.len() {
let last_chunk = text[ix..].trim(); let last_chunk = text[ix..].trim();
if !last_chunk.is_empty() { if !last_chunk.is_empty() {
chunks.push(last_chunk.into()); chunks.push(acp::UserMessageChunk::Text {
text: last_chunk.into(),
});
} }
} }
}) })
@ -318,7 +320,7 @@ impl AcpThreadView {
} }
let Some(thread) = self.thread() else { return }; let Some(thread) = self.thread() else { return };
let message = acp::UserMessage { chunks }; let message = acp::SendUserMessageParams { chunks };
let task = thread.update(cx, |thread, cx| thread.send(message.clone(), cx)); let task = thread.update(cx, |thread, cx| thread.send(message.clone(), cx));
cx.spawn(async move |this, cx| { cx.spawn(async move |this, cx| {
@ -379,7 +381,7 @@ impl AcpThreadView {
message_editor: Entity<Editor>, message_editor: Entity<Editor>,
mention_set: Arc<Mutex<MentionSet>>, mention_set: Arc<Mutex<MentionSet>>,
project: Entity<Project>, project: Entity<Project>,
message: Option<&acp::UserMessage>, message: Option<&acp::SendUserMessageParams>,
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
@ -398,7 +400,7 @@ impl AcpThreadView {
for chunk in &message.chunks { for chunk in &message.chunks {
match chunk { match chunk {
acp::UserMessageChunk::Text { chunk } => { acp::UserMessageChunk::Text { text: chunk } => {
text.push_str(&chunk); text.push_str(&chunk);
} }
acp::UserMessageChunk::Path { path } => { acp::UserMessageChunk::Path { path } => {