Skip to content

Commit c3b1336

Browse files
benbrandtnerzhulart
authored andcommitted
Correctly treat capability-based methods as optional in SDKs (agentclientprotocol#123)
1 parent b8b36ae commit c3b1336

8 files changed

Lines changed: 113 additions & 71 deletions

File tree

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## 0.4.4 (2025-09-30)
4+
5+
### Protocol
6+
7+
- No changes
8+
9+
### Rust
10+
11+
- Provide default trait implementations for optional capability-based `Agent` and `Client` methods.
12+
13+
### Typescript
14+
15+
- Correctly mark capability-based `Agent` and `Client` methods as optional.
16+
317
## 0.4.3 (2025-09-25)
418

519
### Protocol

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "agent-client-protocol"
33
authors = ["Zed <hi@zed.dev>"]
4-
version = "0.4.3"
4+
version = "0.4.4"
55
edition = "2024"
66
license = "Apache-2.0"
77
description = "A protocol for standardizing communication between code editors and AI coding agents"

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zed-industries/agent-client-protocol",
3-
"version": "0.4.3",
3+
"version": "0.4.4",
44
"publishConfig": {
55
"access": "public"
66
},

rust/agent.rs

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,32 @@ pub trait Agent {
6060
/// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
6161
async fn new_session(&self, args: NewSessionRequest) -> Result<NewSessionResponse, Error>;
6262

63+
/// Processes a user prompt within a session.
64+
///
65+
/// This method handles the whole lifecycle of a prompt:
66+
/// - Receives user messages with optional context (files, images, etc.)
67+
/// - Processes the prompt using language models
68+
/// - Reports language model content and tool calls to the Clients
69+
/// - Requests permission to run tools
70+
/// - Executes any requested tool calls
71+
/// - Returns when the turn is complete with a stop reason
72+
///
73+
/// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
74+
async fn prompt(&self, args: PromptRequest) -> Result<PromptResponse, Error>;
75+
76+
/// Cancels ongoing operations for a session.
77+
///
78+
/// This is a notification sent by the client to cancel an ongoing prompt turn.
79+
///
80+
/// Upon receiving this notification, the Agent SHOULD:
81+
/// - Stop all language model requests as soon as possible
82+
/// - Abort all tool call invocations in progress
83+
/// - Send any pending `session/update` notifications
84+
/// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
85+
///
86+
/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
87+
async fn cancel(&self, args: CancelNotification) -> Result<(), Error>;
88+
6389
/// Loads an existing session to resume a previous conversation.
6490
///
6591
/// This method is only available if the agent advertises the `loadSession` capability.
@@ -70,7 +96,9 @@ pub trait Agent {
7096
/// - Stream the entire conversation history back to the client via notifications
7197
///
7298
/// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
73-
async fn load_session(&self, args: LoadSessionRequest) -> Result<LoadSessionResponse, Error>;
99+
async fn load_session(&self, _args: LoadSessionRequest) -> Result<LoadSessionResponse, Error> {
100+
Err(Error::method_not_found())
101+
}
74102

75103
/// Sets the current mode for a session.
76104
///
@@ -87,34 +115,10 @@ pub trait Agent {
87115
/// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
88116
async fn set_session_mode(
89117
&self,
90-
args: SetSessionModeRequest,
91-
) -> Result<SetSessionModeResponse, Error>;
92-
93-
/// Processes a user prompt within a session.
94-
///
95-
/// This method handles the whole lifecycle of a prompt:
96-
/// - Receives user messages with optional context (files, images, etc.)
97-
/// - Processes the prompt using language models
98-
/// - Reports language model content and tool calls to the Clients
99-
/// - Requests permission to run tools
100-
/// - Executes any requested tool calls
101-
/// - Returns when the turn is complete with a stop reason
102-
///
103-
/// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
104-
async fn prompt(&self, args: PromptRequest) -> Result<PromptResponse, Error>;
105-
106-
/// Cancels ongoing operations for a session.
107-
///
108-
/// This is a notification sent by the client to cancel an ongoing prompt turn.
109-
///
110-
/// Upon receiving this notification, the Agent SHOULD:
111-
/// - Stop all language model requests as soon as possible
112-
/// - Abort all tool call invocations in progress
113-
/// - Send any pending `session/update` notifications
114-
/// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
115-
///
116-
/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
117-
async fn cancel(&self, args: CancelNotification) -> Result<(), Error>;
118+
_args: SetSessionModeRequest,
119+
) -> Result<SetSessionModeResponse, Error> {
120+
Err(Error::method_not_found())
121+
}
118122

119123
/// **UNSTABLE**
120124
///
@@ -124,24 +128,30 @@ pub trait Agent {
124128
#[cfg(feature = "unstable")]
125129
async fn set_session_model(
126130
&self,
127-
args: SetSessionModelRequest,
128-
) -> Result<SetSessionModelResponse, Error>;
131+
_args: SetSessionModelRequest,
132+
) -> Result<SetSessionModelResponse, Error> {
133+
Err(Error::method_not_found())
134+
}
129135

130136
/// Handles extension method requests from the client.
131137
///
132138
/// Extension methods provide a way to add custom functionality while maintaining
133139
/// protocol compatibility.
134140
///
135141
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
136-
async fn ext_method(&self, args: ExtRequest) -> Result<ExtResponse, Error>;
142+
async fn ext_method(&self, _args: ExtRequest) -> Result<ExtResponse, Error> {
143+
Ok(RawValue::NULL.to_owned().into())
144+
}
137145

138146
/// Handles extension notifications from the client.
139147
///
140148
/// Extension notifications provide a way to send one-way messages for custom functionality
141149
/// while maintaining protocol compatibility.
142150
///
143151
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
144-
async fn ext_notification(&self, args: ExtNotification) -> Result<(), Error>;
152+
async fn ext_notification(&self, _args: ExtNotification) -> Result<(), Error> {
153+
Ok(())
154+
}
145155
}
146156

147157
#[async_trait::async_trait(?Send)]

rust/client.rs

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ pub trait Client {
3737
args: RequestPermissionRequest,
3838
) -> Result<RequestPermissionResponse, Error>;
3939

40+
/// Handles session update notifications from the agent.
41+
///
42+
/// This is a notification endpoint (no response expected) that receives
43+
/// real-time updates about session progress, including message chunks,
44+
/// tool calls, and execution plans.
45+
///
46+
/// Note: Clients SHOULD continue accepting tool call updates even after
47+
/// sending a `session/cancel` notification, as the agent may send final
48+
/// updates before responding with the cancelled stop reason.
49+
///
50+
/// See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)
51+
async fn session_notification(&self, args: SessionNotification) -> Result<(), Error>;
52+
4053
/// Writes content to a text file in the client's file system.
4154
///
4255
/// Only available if the client advertises the `fs.writeTextFile` capability.
@@ -45,8 +58,10 @@ pub trait Client {
4558
/// See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)
4659
async fn write_text_file(
4760
&self,
48-
args: WriteTextFileRequest,
49-
) -> Result<WriteTextFileResponse, Error>;
61+
_args: WriteTextFileRequest,
62+
) -> Result<WriteTextFileResponse, Error> {
63+
Err(Error::method_not_found())
64+
}
5065

5166
/// Reads content from a text file in the client's file system.
5267
///
@@ -56,21 +71,10 @@ pub trait Client {
5671
/// See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)
5772
async fn read_text_file(
5873
&self,
59-
args: ReadTextFileRequest,
60-
) -> Result<ReadTextFileResponse, Error>;
61-
62-
/// Handles session update notifications from the agent.
63-
///
64-
/// This is a notification endpoint (no response expected) that receives
65-
/// real-time updates about session progress, including message chunks,
66-
/// tool calls, and execution plans.
67-
///
68-
/// Note: Clients SHOULD continue accepting tool call updates even after
69-
/// sending a `session/cancel` notification, as the agent may send final
70-
/// updates before responding with the cancelled stop reason.
71-
///
72-
/// See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)
73-
async fn session_notification(&self, args: SessionNotification) -> Result<(), Error>;
74+
_args: ReadTextFileRequest,
75+
) -> Result<ReadTextFileResponse, Error> {
76+
Err(Error::method_not_found())
77+
}
7478

7579
/// Executes a command in a new terminal
7680
///
@@ -88,8 +92,10 @@ pub trait Client {
8892
/// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
8993
async fn create_terminal(
9094
&self,
91-
args: CreateTerminalRequest,
92-
) -> Result<CreateTerminalResponse, Error>;
95+
_args: CreateTerminalRequest,
96+
) -> Result<CreateTerminalResponse, Error> {
97+
Err(Error::method_not_found())
98+
}
9399

94100
/// Gets the terminal output and exit status
95101
///
@@ -99,8 +105,10 @@ pub trait Client {
99105
/// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
100106
async fn terminal_output(
101107
&self,
102-
args: TerminalOutputRequest,
103-
) -> Result<TerminalOutputResponse, Error>;
108+
_args: TerminalOutputRequest,
109+
) -> Result<TerminalOutputResponse, Error> {
110+
Err(Error::method_not_found())
111+
}
104112

105113
/// Releases a terminal
106114
///
@@ -116,16 +124,20 @@ pub trait Client {
116124
/// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
117125
async fn release_terminal(
118126
&self,
119-
args: ReleaseTerminalRequest,
120-
) -> Result<ReleaseTerminalResponse, Error>;
127+
_args: ReleaseTerminalRequest,
128+
) -> Result<ReleaseTerminalResponse, Error> {
129+
Err(Error::method_not_found())
130+
}
121131

122132
/// Waits for the terminal command to exit and return its exit status
123133
///
124134
/// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
125135
async fn wait_for_terminal_exit(
126136
&self,
127-
args: WaitForTerminalExitRequest,
128-
) -> Result<WaitForTerminalExitResponse, Error>;
137+
_args: WaitForTerminalExitRequest,
138+
) -> Result<WaitForTerminalExitResponse, Error> {
139+
Err(Error::method_not_found())
140+
}
129141

130142
/// Kills the terminal command without releasing the terminal
131143
///
@@ -141,8 +153,10 @@ pub trait Client {
141153
/// See protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)
142154
async fn kill_terminal_command(
143155
&self,
144-
args: KillTerminalCommandRequest,
145-
) -> Result<KillTerminalCommandResponse, Error>;
156+
_args: KillTerminalCommandRequest,
157+
) -> Result<KillTerminalCommandResponse, Error> {
158+
Err(Error::method_not_found())
159+
}
146160

147161
/// Handles extension method requests from the agent.
148162
///
@@ -151,7 +165,9 @@ pub trait Client {
151165
/// protocol compatibility.
152166
///
153167
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
154-
async fn ext_method(&self, args: ExtRequest) -> Result<ExtResponse, Error>;
168+
async fn ext_method(&self, _args: ExtRequest) -> Result<ExtResponse, Error> {
169+
Ok(RawValue::NULL.to_owned().into())
170+
}
155171

156172
/// Handles extension notifications from the agent.
157173
///
@@ -160,7 +176,9 @@ pub trait Client {
160176
/// while maintaining protocol compatibility.
161177
///
162178
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
163-
async fn ext_notification(&self, args: ExtNotification) -> Result<(), Error>;
179+
async fn ext_notification(&self, _args: ExtNotification) -> Result<(), Error> {
180+
Ok(())
181+
}
164182
}
165183

166184
#[async_trait::async_trait(?Send)]

typescript/acp.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,14 +399,14 @@ export class ClientSideConnection implements Agent {
399399
case schema.CLIENT_METHODS.fs_write_text_file: {
400400
const validatedParams =
401401
schema.writeTextFileRequestSchema.parse(params);
402-
return client.writeTextFile(
402+
return client.writeTextFile?.(
403403
validatedParams as schema.WriteTextFileRequest,
404404
);
405405
}
406406
case schema.CLIENT_METHODS.fs_read_text_file: {
407407
const validatedParams =
408408
schema.readTextFileRequestSchema.parse(params);
409-
return client.readTextFile(
409+
return client.readTextFile?.(
410410
validatedParams as schema.ReadTextFileRequest,
411411
);
412412
}
@@ -1034,7 +1034,7 @@ export interface Client {
10341034
*
10351035
* See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)
10361036
*/
1037-
writeTextFile(
1037+
writeTextFile?(
10381038
params: schema.WriteTextFileRequest,
10391039
): Promise<schema.WriteTextFileResponse>;
10401040
/**
@@ -1045,7 +1045,7 @@ export interface Client {
10451045
*
10461046
* See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)
10471047
*/
1048-
readTextFile(
1048+
readTextFile?(
10491049
params: schema.ReadTextFileRequest,
10501050
): Promise<schema.ReadTextFileResponse>;
10511051

0 commit comments

Comments
 (0)