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(Box::new(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(Box::new(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!(v2::LoginAuthRequest, v2::LoginAuthResponse, "auth/login");
214impl_v2_jsonrpc_request!(v2::LogoutAuthRequest, v2::LogoutAuthResponse, "auth/logout");
215#[cfg(feature = "unstable_llm_providers")]
216impl_v2_jsonrpc_request!(
217 v2::ListProvidersRequest,
218 v2::ListProvidersResponse,
219 "providers/list"
220);
221#[cfg(feature = "unstable_llm_providers")]
222impl_v2_jsonrpc_request!(
223 v2::SetProviderRequest,
224 v2::SetProviderResponse,
225 "providers/set"
226);
227#[cfg(feature = "unstable_llm_providers")]
228impl_v2_jsonrpc_request!(
229 v2::DisableProviderRequest,
230 v2::DisableProviderResponse,
231 "providers/disable"
232);
233impl_v2_jsonrpc_request!(v2::NewSessionRequest, v2::NewSessionResponse, "session/new");
234impl_v2_jsonrpc_request!(
235 v2::ListSessionsRequest,
236 v2::ListSessionsResponse,
237 "session/list"
238);
239impl_v2_jsonrpc_request!(
240 v2::DeleteSessionRequest,
241 v2::DeleteSessionResponse,
242 "session/delete"
243);
244#[cfg(feature = "unstable_session_fork")]
245impl_v2_jsonrpc_request!(
246 v2::ForkSessionRequest,
247 v2::ForkSessionResponse,
248 "session/fork"
249);
250impl_v2_jsonrpc_request!(
251 v2::ResumeSessionRequest,
252 v2::ResumeSessionResponse,
253 "session/resume"
254);
255impl_v2_jsonrpc_request!(
256 v2::CloseSessionRequest,
257 v2::CloseSessionResponse,
258 "session/close"
259);
260impl_v2_jsonrpc_request!(
261 v2::SetSessionConfigOptionRequest,
262 v2::SetSessionConfigOptionResponse,
263 "session/set_config_option"
264);
265impl_v2_jsonrpc_request!(v2::PromptRequest, v2::PromptResponse, "session/prompt");
266#[cfg(feature = "unstable_mcp_over_acp")]
267impl_v2_jsonrpc_request!(v2::MessageMcpRequest, v2::MessageMcpResponse, "mcp/message");
268
269impl_v2_jsonrpc_notification!(v2::CancelRequestNotification, "$/cancel_request");
270impl_v2_jsonrpc_notification!(v2::CancelSessionNotification, "session/cancel");
271#[cfg(feature = "unstable_mcp_over_acp")]
272impl_v2_jsonrpc_notification!(v2::MessageMcpNotification, "mcp/message");
273
274impl_v2_jsonrpc_request!(
275 v2::RequestPermissionRequest,
276 v2::RequestPermissionResponse,
277 "session/request_permission"
278);
279impl_v2_jsonrpc_request!(
280 v2::CreateElicitationRequest,
281 v2::CreateElicitationResponse,
282 "elicitation/create"
283);
284#[cfg(feature = "unstable_mcp_over_acp")]
285impl_v2_jsonrpc_request!(v2::ConnectMcpRequest, v2::ConnectMcpResponse, "mcp/connect");
286#[cfg(feature = "unstable_mcp_over_acp")]
287impl_v2_jsonrpc_request!(
288 v2::DisconnectMcpRequest,
289 v2::DisconnectMcpResponse,
290 "mcp/disconnect"
291);
292
293impl_v2_jsonrpc_notification!(v2::UpdateSessionNotification, "session/update");
294impl_v2_jsonrpc_notification!(v2::CompleteElicitationNotification, "elicitation/complete");
295
296impl_jsonrpc_protocol_level_notification_enum!(v2::ProtocolLevelNotification {
297 CancelRequestNotification => "$/cancel_request",
298});
299
300impl_v2_jsonrpc_request_enum!(v2::ClientRequest {
301 InitializeRequest => "initialize",
302 LoginAuthRequest => "auth/login",
303 LogoutAuthRequest => "auth/logout",
304 #[cfg(feature = "unstable_llm_providers")]
305 ListProvidersRequest => "providers/list",
306 #[cfg(feature = "unstable_llm_providers")]
307 SetProviderRequest => "providers/set",
308 #[cfg(feature = "unstable_llm_providers")]
309 DisableProviderRequest => "providers/disable",
310 NewSessionRequest => "session/new",
311 ListSessionsRequest => "session/list",
312 DeleteSessionRequest => "session/delete",
313 #[cfg(feature = "unstable_session_fork")]
314 ForkSessionRequest => "session/fork",
315 ResumeSessionRequest => "session/resume",
316 CloseSessionRequest => "session/close",
317 SetSessionConfigOptionRequest => "session/set_config_option",
318 PromptRequest => "session/prompt",
319 #[cfg(feature = "unstable_mcp_over_acp")]
320 MessageMcpRequest => "mcp/message",
321 [ext] ExtMethodRequest,
322});
323
324impl_v2_jsonrpc_response_enum!(v2::AgentResponse {
325 InitializeResponse => "initialize",
326 LoginAuthResponse => "auth/login",
327 LogoutAuthResponse => "auth/logout",
328 #[cfg(feature = "unstable_llm_providers")]
329 ListProvidersResponse => "providers/list",
330 #[cfg(feature = "unstable_llm_providers")]
331 SetProviderResponse => "providers/set",
332 #[cfg(feature = "unstable_llm_providers")]
333 DisableProviderResponse => "providers/disable",
334 NewSessionResponse => "session/new",
335 ListSessionsResponse => "session/list",
336 DeleteSessionResponse => "session/delete",
337 #[cfg(feature = "unstable_session_fork")]
338 ForkSessionResponse => "session/fork",
339 ResumeSessionResponse => "session/resume",
340 CloseSessionResponse => "session/close",
341 SetSessionConfigOptionResponse => "session/set_config_option",
342 PromptResponse => "session/prompt",
343 #[cfg(feature = "unstable_mcp_over_acp")]
344 MessageMcpResponse => "mcp/message",
345 [ext] ExtMethodResponse,
346});
347
348impl_v2_jsonrpc_notification_enum!(v2::ClientNotification {
349 CancelSessionNotification => "session/cancel",
350 #[cfg(feature = "unstable_mcp_over_acp")]
351 MessageMcpNotification => "mcp/message",
352 [ext] ExtNotification,
353});
354
355impl_v2_jsonrpc_request_enum!(v2::AgentRequest {
356 RequestPermissionRequest => "session/request_permission",
357 CreateElicitationRequest => "elicitation/create",
358 #[cfg(feature = "unstable_mcp_over_acp")]
359 ConnectMcpRequest => "mcp/connect",
360 #[cfg(feature = "unstable_mcp_over_acp")]
361 MessageMcpRequest => "mcp/message",
362 #[cfg(feature = "unstable_mcp_over_acp")]
363 DisconnectMcpRequest => "mcp/disconnect",
364 [ext] ExtMethodRequest,
365});
366
367impl_v2_jsonrpc_response_enum!(v2::ClientResponse {
368 RequestPermissionResponse => "session/request_permission",
369 CreateElicitationResponse => "elicitation/create",
370 #[cfg(feature = "unstable_mcp_over_acp")]
371 ConnectMcpResponse => "mcp/connect",
372 #[cfg(feature = "unstable_mcp_over_acp")]
373 MessageMcpResponse => "mcp/message",
374 #[cfg(feature = "unstable_mcp_over_acp")]
375 DisconnectMcpResponse => "mcp/disconnect",
376 [ext] ExtMethodResponse,
377});
378
379impl_v2_jsonrpc_notification_enum!(v2::AgentNotification {
380 UpdateSessionNotification => "session/update",
381 CompleteElicitationNotification => "elicitation/complete",
382 #[cfg(feature = "unstable_mcp_over_acp")]
383 MessageMcpNotification => "mcp/message",
384 [ext] ExtNotification,
385});