Detailed changes
@@ -216,9 +216,9 @@ dependencies = [
[[package]]
name = "agent-client-protocol"
-version = "0.8.0"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e639d6b544ad39f5b4e05802db5eb04e1518284eb05fda1839931003e0244c8"
+checksum = "c2ffe7d502c1e451aafc5aff655000f84d09c9af681354ac0012527009b1af13"
dependencies = [
"agent-client-protocol-schema",
"anyhow",
@@ -233,15 +233,16 @@ dependencies = [
[[package]]
name = "agent-client-protocol-schema"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f182f5e14bef8232b239719bd99166bb11e986c08fc211f28e392f880d3093ba"
+checksum = "8af81cc2d5c3f9c04f73db452efd058333735ba9d51c2cf7ef33c9fee038e7e6"
dependencies = [
"anyhow",
"derive_more 2.0.1",
"schemars",
"serde",
"serde_json",
+ "strum 0.27.2",
]
[[package]]
@@ -8147,7 +8148,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
dependencies = [
"equivalent",
- "hashbrown 0.15.5",
+ "hashbrown 0.16.1",
"serde",
"serde_core",
]
@@ -443,7 +443,7 @@ ztracing_macro = { path = "crates/ztracing_macro" }
# External crates
#
-agent-client-protocol = { version = "=0.8.0", features = ["unstable"] }
+agent-client-protocol = { version = "=0.9.0", features = ["unstable"] }
aho-corasick = "1.1"
alacritty_terminal = "0.25.1-rc1"
any_vec = "0.14"
@@ -2929,7 +2929,7 @@ mod tests {
.await
.unwrap_err();
- assert_eq!(err.code, acp::ErrorCode::RESOURCE_NOT_FOUND.code);
+ assert_eq!(err.code, acp::ErrorCode::ResourceNotFound);
}
#[gpui::test]
@@ -75,15 +75,9 @@ impl Terminal {
let exit_status = exit_status.map(portable_pty::ExitStatus::from);
- let mut status = acp::TerminalExitStatus::new();
-
- if let Some(exit_status) = exit_status.as_ref() {
- status = status.exit_code(exit_status.exit_code());
- if let Some(signal) = exit_status.signal() {
- status = status.signal(signal);
- }
- }
- status
+ acp::TerminalExitStatus::new()
+ .exit_code(exit_status.as_ref().map(|e| e.exit_code()))
+ .signal(exit_status.and_then(|e| e.signal().map(ToOwned::to_owned)))
})
.shared(),
}
@@ -105,19 +99,17 @@ impl Terminal {
pub fn current_output(&self, cx: &App) -> acp::TerminalOutputResponse {
if let Some(output) = self.output.as_ref() {
- let mut exit_status = acp::TerminalExitStatus::new();
- if let Some(status) = output.exit_status.map(portable_pty::ExitStatus::from) {
- exit_status = exit_status.exit_code(status.exit_code());
- if let Some(signal) = status.signal() {
- exit_status = exit_status.signal(signal);
- }
- }
+ let exit_status = output.exit_status.map(portable_pty::ExitStatus::from);
acp::TerminalOutputResponse::new(
output.content.clone(),
output.original_content_len > output.content.len(),
)
- .exit_status(exit_status)
+ .exit_status(
+ acp::TerminalExitStatus::new()
+ .exit_code(exit_status.as_ref().map(|e| e.exit_code()))
+ .signal(exit_status.and_then(|e| e.signal().map(ToOwned::to_owned))),
+ )
} else {
let (current_content, original_len) = self.truncated_output(cx);
let truncated = current_content.len() < original_len;
@@ -2094,7 +2094,7 @@ async fn test_tool_updates_to_completion(cx: &mut TestAppContext) {
"1",
acp::ToolCallUpdateFields::new()
.status(acp::ToolCallStatus::Completed)
- .raw_output("Finished thinking.".into())
+ .raw_output("Finished thinking.")
)
);
}
@@ -766,20 +766,22 @@ impl Thread {
.log_err();
}
- let mut fields = acp::ToolCallUpdateFields::new().status(tool_result.as_ref().map_or(
- acp::ToolCallStatus::Failed,
- |result| {
- if result.is_error {
- acp::ToolCallStatus::Failed
- } else {
- acp::ToolCallStatus::Completed
- }
- },
- ));
- if let Some(output) = output {
- fields = fields.raw_output(output);
- }
- stream.update_tool_call_fields(&tool_use.id, fields);
+ stream.update_tool_call_fields(
+ &tool_use.id,
+ acp::ToolCallUpdateFields::new()
+ .status(
+ tool_result
+ .as_ref()
+ .map_or(acp::ToolCallStatus::Failed, |result| {
+ if result.is_error {
+ acp::ToolCallStatus::Failed
+ } else {
+ acp::ToolCallStatus::Completed
+ }
+ }),
+ )
+ .raw_output(output),
+ );
}
pub fn from_db(
@@ -1259,15 +1261,16 @@ impl Thread {
while let Some(tool_result) = tool_results.next().await {
log::debug!("Tool finished {:?}", tool_result);
- let mut fields = acp::ToolCallUpdateFields::new().status(if tool_result.is_error {
- acp::ToolCallStatus::Failed
- } else {
- acp::ToolCallStatus::Completed
- });
- if let Some(output) = &tool_result.output {
- fields = fields.raw_output(output.clone());
- }
- event_stream.update_tool_call_fields(&tool_result.tool_use_id, fields);
+ event_stream.update_tool_call_fields(
+ &tool_result.tool_use_id,
+ acp::ToolCallUpdateFields::new()
+ .status(if tool_result.is_error {
+ acp::ToolCallStatus::Failed
+ } else {
+ acp::ToolCallStatus::Completed
+ })
+ .raw_output(tool_result.output.clone()),
+ );
this.update(cx, |this, _cx| {
this.pending_message()
.tool_results
@@ -1545,7 +1548,7 @@ impl Thread {
event_stream.update_tool_call_fields(
&tool_use.id,
acp::ToolCallUpdateFields::new()
- .title(title)
+ .title(title.as_str())
.kind(kind)
.raw_input(tool_use.input.clone()),
);
@@ -2461,7 +2464,7 @@ impl ToolCallEventStream {
ToolCallAuthorization {
tool_call: acp::ToolCallUpdate::new(
self.tool_use_id.to_string(),
- acp::ToolCallUpdateFields::new().title(title),
+ acp::ToolCallUpdateFields::new().title(title.into()),
),
options: vec![
acp::PermissionOption::new(
@@ -384,11 +384,7 @@ impl AgentTool for EditFileTool {
range.start.to_point(&buffer.snapshot()).row
}).ok();
if let Some(abs_path) = abs_path.clone() {
- let mut location = ToolCallLocation::new(abs_path);
- if let Some(line) = line {
- location = location.line(line);
- }
- event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![location]));
+ event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![ToolCallLocation::new(abs_path).line(line)]));
}
emitted_location = true;
}
@@ -138,7 +138,7 @@ impl AgentTool for FindPathTool {
)),
))
})
- .collect(),
+ .collect::<Vec<_>>(),
),
);
@@ -152,12 +152,11 @@ impl AgentTool for ReadFileTool {
}
let file_path = input.path.clone();
- let mut location = acp::ToolCallLocation::new(&abs_path);
- if let Some(line) = input.start_line {
- location = location.line(line.saturating_sub(1));
- }
- event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![location]));
+ event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![
+ acp::ToolCallLocation::new(&abs_path)
+ .line(input.start_line.map(|line| line.saturating_sub(1))),
+ ]));
if image_store::is_image_file(&self.project, &project_path, cx) {
return cx.spawn(async move |cx| {
@@ -121,7 +121,7 @@ fn emit_update(response: &WebSearchResponse, event_stream: &ToolCallEventStream)
),
))
})
- .collect(),
+ .collect::<Vec<_>>(),
),
);
}
@@ -173,10 +173,6 @@ impl AcpConnection {
});
})?;
- let mut client_info = acp::Implementation::new("zed", version);
- if let Some(release_channel) = release_channel {
- client_info = client_info.title(release_channel);
- }
let response = connection
.initialize(
acp::InitializeRequest::new(acp::ProtocolVersion::V1)
@@ -192,7 +188,10 @@ impl AcpConnection {
("terminal-auth".into(), true.into()),
])),
)
- .client_info(client_info),
+ .client_info(
+ acp::Implementation::new("zed", version)
+ .title(release_channel.map(ToOwned::to_owned)),
+ ),
)
.await?;
@@ -302,10 +301,10 @@ impl AgentConnection for AcpConnection {
.new_session(acp::NewSessionRequest::new(cwd).mcp_servers(mcp_servers))
.await
.map_err(|err| {
- if err.code == acp::ErrorCode::AUTH_REQUIRED.code {
+ if err.code == acp::ErrorCode::AuthRequired {
let mut error = AuthRequired::new();
- if err.message != acp::ErrorCode::AUTH_REQUIRED.message {
+ if err.message != acp::ErrorCode::AuthRequired.to_string() {
error = error.with_description(err.message);
}
@@ -467,11 +466,11 @@ impl AgentConnection for AcpConnection {
match result {
Ok(response) => Ok(response),
Err(err) => {
- if err.code == acp::ErrorCode::AUTH_REQUIRED.code {
+ if err.code == acp::ErrorCode::AuthRequired {
return Err(anyhow!(acp::Error::auth_required()));
}
- if err.code != ErrorCode::INTERNAL_ERROR.code {
+ if err.code != ErrorCode::InternalError {
anyhow::bail!(err)
}
@@ -838,13 +837,18 @@ impl acp::Client for ClientDelegate {
if let Some(term_exit) = meta.get("terminal_exit") {
if let Some(id_str) = term_exit.get("terminal_id").and_then(|v| v.as_str()) {
let terminal_id = acp::TerminalId::new(id_str);
- let mut status = acp::TerminalExitStatus::new();
- if let Some(code) = term_exit.get("exit_code").and_then(|v| v.as_u64()) {
- status = status.exit_code(code as u32)
- }
- if let Some(signal) = term_exit.get("signal").and_then(|v| v.as_str()) {
- status = status.signal(signal);
- }
+ let status = acp::TerminalExitStatus::new()
+ .exit_code(
+ term_exit
+ .get("exit_code")
+ .and_then(|v| v.as_u64())
+ .map(|i| i as u32),
+ )
+ .signal(
+ term_exit
+ .get("signal")
+ .and_then(|v| v.as_str().map(|s| s.to_string())),
+ );
let _ = session.thread.update(&mut self.cx.clone(), |thread, cx| {
thread.on_terminal_provider_event(
@@ -417,13 +417,12 @@ impl MessageEditor {
))
}
}
- Mention::Image(mention_image) => {
- let mut image = acp::ImageContent::new(
+ Mention::Image(mention_image) => acp::ContentBlock::Image(
+ acp::ImageContent::new(
mention_image.data.clone(),
mention_image.format.mime_type(),
- );
-
- if let Some(uri) = match uri {
+ )
+ .uri(match uri {
MentionUri::File { .. } => Some(uri.to_uri().to_string()),
MentionUri::PastedImage => None,
other => {
@@ -433,11 +432,8 @@ impl MessageEditor {
);
None
}
- } {
- image = image.uri(uri)
- };
- acp::ContentBlock::Image(image)
- }
+ }),
+ ),
Mention::Link => acp::ContentBlock::ResourceLink(
acp::ResourceLink::new(uri.name(), uri.to_uri().to_string()),
),
@@ -100,7 +100,7 @@ impl ThreadError {
{
Self::ModelRequestLimitReached(error.plan)
} else if let Some(acp_error) = error.downcast_ref::<acp::Error>()
- && acp_error.code == acp::ErrorCode::AUTH_REQUIRED.code
+ && acp_error.code == acp::ErrorCode::AuthRequired
{
Self::AuthenticationRequired(acp_error.message.clone().into())
} else {
@@ -6243,7 +6243,7 @@ pub(crate) mod tests {
StubAgentConnection::new().with_permission_requests(HashMap::from_iter([(
tool_call_id,
vec![acp::PermissionOption::new(
- "1".into(),
+ "1",
"Allow",
acp::PermissionOptionKind::AllowOnce,
)],