agent_client_protocol/schema/
v2_impls.rs1use crate::schema::v2;
4use crate::{JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse, UntypedMessage};
5
6macro_rules! impl_v2_jsonrpc_request {
7 ($req:ty, $resp:ty, $method:literal) => {
8 impl JsonRpcMessage for $req {
9 fn matches_method(method: &str) -> bool {
10 method == $method
11 }
12
13 fn method(&self) -> &str {
14 $method
15 }
16
17 fn to_untyped_message(&self) -> Result<UntypedMessage, crate::Error> {
18 UntypedMessage::new($method, self)
19 }
20
21 fn parse_message(
22 method: &str,
23 params: &impl serde::Serialize,
24 ) -> Result<Self, crate::Error> {
25 if method != $method {
26 return Err(crate::Error::method_not_found());
27 }
28 crate::util::json_cast_params(params)
29 }
30 }
31
32 impl JsonRpcRequest for $req {
33 type Response = $resp;
34 }
35
36 impl JsonRpcResponse for $resp {
37 fn into_json(self, _method: &str) -> Result<serde_json::Value, crate::Error> {
38 serde_json::to_value(self).map_err(crate::Error::into_internal_error)
39 }
40
41 fn from_value(_method: &str, value: serde_json::Value) -> Result<Self, crate::Error> {
42 crate::util::json_cast(value)
43 }
44 }
45 };
46}
47
48macro_rules! impl_v2_jsonrpc_notification {
49 ($notif:ty, $method:literal) => {
50 impl JsonRpcMessage for $notif {
51 fn matches_method(method: &str) -> bool {
52 method == $method
53 }
54
55 fn method(&self) -> &str {
56 $method
57 }
58
59 fn to_untyped_message(&self) -> Result<UntypedMessage, crate::Error> {
60 UntypedMessage::new($method, self)
61 }
62
63 fn parse_message(
64 method: &str,
65 params: &impl serde::Serialize,
66 ) -> Result<Self, crate::Error> {
67 if method != $method {
68 return Err(crate::Error::method_not_found());
69 }
70 crate::util::json_cast_params(params)
71 }
72 }
73
74 impl JsonRpcNotification for $notif {}
75 };
76}
77
78macro_rules! impl_v2_jsonrpc_request_enum {
79 ($enum:ty {
80 $( $(#[$meta:meta])* $variant:ident => $method:literal, )*
81 [ext] $ext_variant:ident,
82 }) => {
83 impl JsonRpcMessage for $enum {
84 fn matches_method(_method: &str) -> bool {
85 true
86 }
87
88 fn method(&self) -> &str {
89 match self {
90 $( $(#[$meta])* Self::$variant(_) => $method, )*
91 Self::$ext_variant(ext) => &ext.method,
92 _ => "_unknown",
93 }
94 }
95
96 fn to_untyped_message(&self) -> Result<UntypedMessage, crate::Error> {
97 UntypedMessage::new(self.method(), self)
98 }
99
100 fn parse_message(
101 method: &str,
102 params: &impl serde::Serialize,
103 ) -> Result<Self, crate::Error> {
104 match method {
105 $( $(#[$meta])* $method => crate::util::json_cast_params(params).map(Self::$variant), )*
106 _ => {
107 if method.starts_with('_') {
108 crate::util::json_cast_params(params).map(
109 |ext_req: v2::ExtRequest| {
110 Self::$ext_variant(v2::ExtRequest::new(
111 method.to_string(),
112 ext_req.params,
113 ))
114 },
115 )
116 } else {
117 Err(crate::Error::method_not_found())
118 }
119 }
120 }
121 }
122 }
123
124 impl JsonRpcRequest for $enum {
125 type Response = serde_json::Value;
126 }
127 };
128}
129
130macro_rules! impl_v2_jsonrpc_notification_enum {
131 ($enum:ty {
132 $( $(#[$meta:meta])* $variant:ident => $method:literal, )*
133 [ext] $ext_variant:ident,
134 }) => {
135 impl JsonRpcMessage for $enum {
136 fn matches_method(_method: &str) -> bool {
137 true
138 }
139
140 fn method(&self) -> &str {
141 match self {
142 $( $(#[$meta])* Self::$variant(_) => $method, )*
143 Self::$ext_variant(ext) => &ext.method,
144 _ => "_unknown",
145 }
146 }
147
148 fn to_untyped_message(&self) -> Result<UntypedMessage, crate::Error> {
149 UntypedMessage::new(self.method(), self)
150 }
151
152 fn parse_message(
153 method: &str,
154 params: &impl serde::Serialize,
155 ) -> Result<Self, crate::Error> {
156 match method {
157 $( $(#[$meta])* $method => crate::util::json_cast_params(params).map(Self::$variant), )*
158 _ => {
159 if method.starts_with('_') {
160 crate::util::json_cast_params(params).map(
161 |ext_notif: v2::ExtNotification| {
162 Self::$ext_variant(v2::ExtNotification::new(
163 method.to_string(),
164 ext_notif.params,
165 ))
166 },
167 )
168 } else {
169 Err(crate::Error::method_not_found())
170 }
171 }
172 }
173 }
174 }
175
176 impl JsonRpcNotification for $enum {}
177 };
178}
179
180macro_rules! impl_v2_jsonrpc_response_enum {
181 ($enum:ty {
182 $( $(#[$meta:meta])* $variant:ident => $method:literal, )*
183 [ext] $ext_variant:ident,
184 }) => {
185 impl JsonRpcResponse for $enum {
186 fn into_json(
187 self,
188 _method: &str,
189 ) -> Result<serde_json::Value, crate::Error> {
190 serde_json::to_value(self).map_err(crate::Error::into_internal_error)
191 }
192
193 fn from_value(
194 method: &str,
195 value: serde_json::Value,
196 ) -> Result<Self, crate::Error> {
197 match method {
198 $( $(#[$meta])* $method => crate::util::json_cast(value).map(Self::$variant), )*
199 _ => {
200 if method.starts_with('_') {
201 crate::util::json_cast(value).map(Self::$ext_variant)
202 } else {
203 Err(crate::Error::method_not_found())
204 }
205 }
206 }
207 }
208 }
209 };
210}
211
212impl_v2_jsonrpc_request!(v2::InitializeRequest, v2::InitializeResponse, "initialize");
213impl_v2_jsonrpc_request!(
214 v2::AuthenticateRequest,
215 v2::AuthenticateResponse,
216 "authenticate"
217);
218impl_v2_jsonrpc_request!(v2::LogoutRequest, v2::LogoutResponse, "logout");
219impl_v2_jsonrpc_request!(v2::NewSessionRequest, v2::NewSessionResponse, "session/new");
220impl_v2_jsonrpc_request!(
221 v2::LoadSessionRequest,
222 v2::LoadSessionResponse,
223 "session/load"
224);
225impl_v2_jsonrpc_request!(
226 v2::ListSessionsRequest,
227 v2::ListSessionsResponse,
228 "session/list"
229);
230impl_v2_jsonrpc_request!(
231 v2::DeleteSessionRequest,
232 v2::DeleteSessionResponse,
233 "session/delete"
234);
235#[cfg(feature = "unstable_session_fork")]
236impl_v2_jsonrpc_request!(
237 v2::ForkSessionRequest,
238 v2::ForkSessionResponse,
239 "session/fork"
240);
241impl_v2_jsonrpc_request!(
242 v2::ResumeSessionRequest,
243 v2::ResumeSessionResponse,
244 "session/resume"
245);
246impl_v2_jsonrpc_request!(
247 v2::CloseSessionRequest,
248 v2::CloseSessionResponse,
249 "session/close"
250);
251impl_v2_jsonrpc_request!(
252 v2::SetSessionConfigOptionRequest,
253 v2::SetSessionConfigOptionResponse,
254 "session/set_config_option"
255);
256impl_v2_jsonrpc_request!(v2::PromptRequest, v2::PromptResponse, "session/prompt");
257#[cfg(feature = "unstable_mcp_over_acp")]
258impl_v2_jsonrpc_request!(v2::MessageMcpRequest, v2::MessageMcpResponse, "mcp/message");
259
260#[cfg(feature = "unstable_cancel_request")]
261impl_v2_jsonrpc_notification!(v2::CancelRequestNotification, "$/cancel_request");
262impl_v2_jsonrpc_notification!(v2::CancelNotification, "session/cancel");
263#[cfg(feature = "unstable_mcp_over_acp")]
264impl_v2_jsonrpc_notification!(v2::MessageMcpNotification, "mcp/message");
265
266impl_v2_jsonrpc_request!(
267 v2::RequestPermissionRequest,
268 v2::RequestPermissionResponse,
269 "session/request_permission"
270);
271#[cfg(feature = "unstable_elicitation")]
272impl_v2_jsonrpc_request!(
273 v2::CreateElicitationRequest,
274 v2::CreateElicitationResponse,
275 "elicitation/create"
276);
277#[cfg(feature = "unstable_mcp_over_acp")]
278impl_v2_jsonrpc_request!(v2::ConnectMcpRequest, v2::ConnectMcpResponse, "mcp/connect");
279#[cfg(feature = "unstable_mcp_over_acp")]
280impl_v2_jsonrpc_request!(
281 v2::DisconnectMcpRequest,
282 v2::DisconnectMcpResponse,
283 "mcp/disconnect"
284);
285
286impl_v2_jsonrpc_notification!(v2::SessionNotification, "session/update");
287#[cfg(feature = "unstable_elicitation")]
288impl_v2_jsonrpc_notification!(v2::CompleteElicitationNotification, "elicitation/complete");
289
290#[cfg(feature = "unstable_cancel_request")]
291impl_jsonrpc_protocol_level_notification_enum!(v2::ProtocolLevelNotification {
292 CancelRequestNotification => "$/cancel_request",
293});
294
295impl_v2_jsonrpc_request_enum!(v2::ClientRequest {
296 InitializeRequest => "initialize",
297 AuthenticateRequest => "authenticate",
298 LogoutRequest => "logout",
299 NewSessionRequest => "session/new",
300 LoadSessionRequest => "session/load",
301 ListSessionsRequest => "session/list",
302 DeleteSessionRequest => "session/delete",
303 #[cfg(feature = "unstable_session_fork")]
304 ForkSessionRequest => "session/fork",
305 ResumeSessionRequest => "session/resume",
306 CloseSessionRequest => "session/close",
307 SetSessionConfigOptionRequest => "session/set_config_option",
308 PromptRequest => "session/prompt",
309 #[cfg(feature = "unstable_mcp_over_acp")]
310 MessageMcpRequest => "mcp/message",
311 [ext] ExtMethodRequest,
312});
313
314impl_v2_jsonrpc_response_enum!(v2::AgentResponse {
315 InitializeResponse => "initialize",
316 AuthenticateResponse => "authenticate",
317 LogoutResponse => "logout",
318 NewSessionResponse => "session/new",
319 LoadSessionResponse => "session/load",
320 ListSessionsResponse => "session/list",
321 DeleteSessionResponse => "session/delete",
322 #[cfg(feature = "unstable_session_fork")]
323 ForkSessionResponse => "session/fork",
324 ResumeSessionResponse => "session/resume",
325 CloseSessionResponse => "session/close",
326 SetSessionConfigOptionResponse => "session/set_config_option",
327 PromptResponse => "session/prompt",
328 #[cfg(feature = "unstable_mcp_over_acp")]
329 MessageMcpResponse => "mcp/message",
330 [ext] ExtMethodResponse,
331});
332
333impl_v2_jsonrpc_notification_enum!(v2::ClientNotification {
334 CancelNotification => "session/cancel",
335 #[cfg(feature = "unstable_mcp_over_acp")]
336 MessageMcpNotification => "mcp/message",
337 [ext] ExtNotification,
338});
339
340impl_v2_jsonrpc_request_enum!(v2::AgentRequest {
341 RequestPermissionRequest => "session/request_permission",
342 #[cfg(feature = "unstable_elicitation")]
343 CreateElicitationRequest => "elicitation/create",
344 #[cfg(feature = "unstable_mcp_over_acp")]
345 ConnectMcpRequest => "mcp/connect",
346 #[cfg(feature = "unstable_mcp_over_acp")]
347 MessageMcpRequest => "mcp/message",
348 #[cfg(feature = "unstable_mcp_over_acp")]
349 DisconnectMcpRequest => "mcp/disconnect",
350 [ext] ExtMethodRequest,
351});
352
353impl_v2_jsonrpc_response_enum!(v2::ClientResponse {
354 RequestPermissionResponse => "session/request_permission",
355 #[cfg(feature = "unstable_elicitation")]
356 CreateElicitationResponse => "elicitation/create",
357 #[cfg(feature = "unstable_mcp_over_acp")]
358 ConnectMcpResponse => "mcp/connect",
359 #[cfg(feature = "unstable_mcp_over_acp")]
360 MessageMcpResponse => "mcp/message",
361 #[cfg(feature = "unstable_mcp_over_acp")]
362 DisconnectMcpResponse => "mcp/disconnect",
363 [ext] ExtMethodResponse,
364});
365
366impl_v2_jsonrpc_notification_enum!(v2::AgentNotification {
367 SessionNotification => "session/update",
368 #[cfg(feature = "unstable_elicitation")]
369 CompleteElicitationNotification => "elicitation/complete",
370 #[cfg(feature = "unstable_mcp_over_acp")]
371 MessageMcpNotification => "mcp/message",
372 [ext] ExtNotification,
373});