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
260impl_v2_jsonrpc_notification!(v2::CancelNotification, "session/cancel");
261#[cfg(feature = "unstable_mcp_over_acp")]
262impl_v2_jsonrpc_notification!(v2::MessageMcpNotification, "mcp/message");
263
264impl_v2_jsonrpc_request!(
265 v2::RequestPermissionRequest,
266 v2::RequestPermissionResponse,
267 "session/request_permission"
268);
269#[cfg(feature = "unstable_elicitation")]
270impl_v2_jsonrpc_request!(
271 v2::CreateElicitationRequest,
272 v2::CreateElicitationResponse,
273 "elicitation/create"
274);
275#[cfg(feature = "unstable_mcp_over_acp")]
276impl_v2_jsonrpc_request!(v2::ConnectMcpRequest, v2::ConnectMcpResponse, "mcp/connect");
277#[cfg(feature = "unstable_mcp_over_acp")]
278impl_v2_jsonrpc_request!(
279 v2::DisconnectMcpRequest,
280 v2::DisconnectMcpResponse,
281 "mcp/disconnect"
282);
283
284impl_v2_jsonrpc_notification!(v2::SessionNotification, "session/update");
285#[cfg(feature = "unstable_elicitation")]
286impl_v2_jsonrpc_notification!(v2::CompleteElicitationNotification, "elicitation/complete");
287
288impl_v2_jsonrpc_request_enum!(v2::ClientRequest {
289 InitializeRequest => "initialize",
290 AuthenticateRequest => "authenticate",
291 LogoutRequest => "logout",
292 NewSessionRequest => "session/new",
293 LoadSessionRequest => "session/load",
294 ListSessionsRequest => "session/list",
295 DeleteSessionRequest => "session/delete",
296 #[cfg(feature = "unstable_session_fork")]
297 ForkSessionRequest => "session/fork",
298 ResumeSessionRequest => "session/resume",
299 CloseSessionRequest => "session/close",
300 SetSessionConfigOptionRequest => "session/set_config_option",
301 PromptRequest => "session/prompt",
302 #[cfg(feature = "unstable_mcp_over_acp")]
303 MessageMcpRequest => "mcp/message",
304 [ext] ExtMethodRequest,
305});
306
307impl_v2_jsonrpc_response_enum!(v2::AgentResponse {
308 InitializeResponse => "initialize",
309 AuthenticateResponse => "authenticate",
310 LogoutResponse => "logout",
311 NewSessionResponse => "session/new",
312 LoadSessionResponse => "session/load",
313 ListSessionsResponse => "session/list",
314 DeleteSessionResponse => "session/delete",
315 #[cfg(feature = "unstable_session_fork")]
316 ForkSessionResponse => "session/fork",
317 ResumeSessionResponse => "session/resume",
318 CloseSessionResponse => "session/close",
319 SetSessionConfigOptionResponse => "session/set_config_option",
320 PromptResponse => "session/prompt",
321 #[cfg(feature = "unstable_mcp_over_acp")]
322 MessageMcpResponse => "mcp/message",
323 [ext] ExtMethodResponse,
324});
325
326impl_v2_jsonrpc_notification_enum!(v2::ClientNotification {
327 CancelNotification => "session/cancel",
328 #[cfg(feature = "unstable_mcp_over_acp")]
329 MessageMcpNotification => "mcp/message",
330 [ext] ExtNotification,
331});
332
333impl_v2_jsonrpc_request_enum!(v2::AgentRequest {
334 RequestPermissionRequest => "session/request_permission",
335 #[cfg(feature = "unstable_elicitation")]
336 CreateElicitationRequest => "elicitation/create",
337 #[cfg(feature = "unstable_mcp_over_acp")]
338 ConnectMcpRequest => "mcp/connect",
339 #[cfg(feature = "unstable_mcp_over_acp")]
340 MessageMcpRequest => "mcp/message",
341 #[cfg(feature = "unstable_mcp_over_acp")]
342 DisconnectMcpRequest => "mcp/disconnect",
343 [ext] ExtMethodRequest,
344});
345
346impl_v2_jsonrpc_response_enum!(v2::ClientResponse {
347 RequestPermissionResponse => "session/request_permission",
348 #[cfg(feature = "unstable_elicitation")]
349 CreateElicitationResponse => "elicitation/create",
350 #[cfg(feature = "unstable_mcp_over_acp")]
351 ConnectMcpResponse => "mcp/connect",
352 #[cfg(feature = "unstable_mcp_over_acp")]
353 MessageMcpResponse => "mcp/message",
354 #[cfg(feature = "unstable_mcp_over_acp")]
355 DisconnectMcpResponse => "mcp/disconnect",
356 [ext] ExtMethodResponse,
357});
358
359impl_v2_jsonrpc_notification_enum!(v2::AgentNotification {
360 SessionNotification => "session/update",
361 #[cfg(feature = "unstable_elicitation")]
362 CompleteElicitationNotification => "elicitation/complete",
363 #[cfg(feature = "unstable_mcp_over_acp")]
364 MessageMcpNotification => "mcp/message",
365 [ext] ExtNotification,
366});