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:
parent
dc591fe7c7
commit
08ffd9884a
4 changed files with 59 additions and 37 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 } => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue