a2a_sdk/
lib.rs

1#![allow(clippy::redundant_closure_call)]
2#![allow(clippy::needless_lifetimes)]
3#![allow(clippy::match_single_binding)]
4#![allow(clippy::clone_on_copy)]
5
6mod jsonrpc;
7
8use std::borrow::Cow;
9use std::fmt::{Debug, Display, Formatter};
10
11use serde::{Deserialize, Serialize};
12
13use crate::jsonrpc::*;
14
15#[derive(Debug, Serialize, Deserialize, Clone)]
16#[serde(untagged)]
17pub enum JsonRpcMessage {
18	Request(JsonRpcRequest<A2aRequest>),
19	Response(JsonRpcResponse<A2aResponse>),
20	Error(JsonRpcError),
21}
22
23impl JsonRpcMessage {
24	pub fn response(&self) -> Option<&A2aResponse> {
25		match self {
26			JsonRpcMessage::Request(_) => None,
27			JsonRpcMessage::Response(resp) => Some(&resp.result),
28			JsonRpcMessage::Error(_) => None,
29		}
30	}
31}
32
33#[derive(Debug, Serialize, Deserialize, Clone)]
34pub struct JsonRpcError {
35	pub jsonrpc: JsonRpcVersion2_0,
36	pub id: RequestId,
37	pub error: ErrorData,
38}
39
40#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
41pub struct ErrorCode(pub i32);
42
43/// Error information for JSON-RPC error responses.
44#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
45pub struct ErrorData {
46	/// The error type that occurred.
47	pub code: ErrorCode,
48
49	/// A short description of the error. The message SHOULD be limited to a concise single sentence.
50	pub message: Cow<'static, str>,
51
52	/// Additional information about the error. The value of this member is defined by the
53	/// sender (e.g. detailed error information, nested errors etc.).
54	#[serde(skip_serializing_if = "Option::is_none")]
55	pub data: Option<serde_json::Value>,
56}
57
58// TODO: this is not complete, add the rest
59#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
60#[serde(untagged)]
61pub enum A2aRequest {
62	// Legacy request types (deprecated but kept for backward compatibility)
63	SendTaskRequest(SendTaskRequest),
64	SendSubscribeTaskRequest(SendSubscribeTaskRequest),
65	TaskPushNotificationGetRequest(TaskPushNotificationGetRequest),
66	TaskPushNotificationSetRequest(TaskPushNotificationSetRequest),
67	TaskResubscribeRequest(TaskResubscribeRequest),
68
69	// New request types (current version)
70	SendMessageRequest(SendMessageRequest),
71	SendStreamingMessageRequest(SendStreamingMessageRequest),
72	GetTaskRequest(GetTaskRequest),
73	CancelTaskRequest(CancelTaskRequest),
74	SetTaskPushNotificationConfigRequest(SetTaskPushNotificationConfigRequest),
75	GetTaskPushNotificationConfigRequest(GetTaskPushNotificationConfigRequest),
76	TaskResubscriptionRequest(TaskResubscriptionRequest),
77	ListTaskPushNotificationConfigRequest(ListTaskPushNotificationConfigRequest),
78	DeleteTaskPushNotificationConfigRequest(DeleteTaskPushNotificationConfigRequest),
79	GetAuthenticatedExtendedCardRequest(GetAuthenticatedExtendedCardRequest),
80}
81
82impl A2aRequest {
83	pub fn method(&self) -> &'static str {
84		match self {
85			A2aRequest::SendTaskRequest(i) => i.method.as_string(),
86			A2aRequest::SendSubscribeTaskRequest(i) => i.method.as_string(),
87			A2aRequest::GetTaskRequest(i) => i.method.as_string(),
88			A2aRequest::CancelTaskRequest(i) => i.method.as_string(),
89			A2aRequest::TaskPushNotificationGetRequest(i) => i.method.as_string(),
90			A2aRequest::TaskPushNotificationSetRequest(i) => i.method.as_string(),
91			A2aRequest::TaskResubscribeRequest(i) => i.method.as_string(),
92			A2aRequest::SendMessageRequest(i) => i.method.as_string(),
93			A2aRequest::SendStreamingMessageRequest(i) => i.method.as_string(),
94			A2aRequest::SetTaskPushNotificationConfigRequest(i) => i.method.as_string(),
95			A2aRequest::GetTaskPushNotificationConfigRequest(i) => i.method.as_string(),
96			A2aRequest::TaskResubscriptionRequest(i) => i.method.as_string(),
97			A2aRequest::ListTaskPushNotificationConfigRequest(i) => i.method.as_string(),
98			A2aRequest::DeleteTaskPushNotificationConfigRequest(i) => i.method.as_string(),
99			A2aRequest::GetAuthenticatedExtendedCardRequest(i) => i.method.as_string(),
100		}
101	}
102}
103
104// TODO: this is not complete, add the rest
105#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
106#[serde(untagged)]
107pub enum A2aResponse {
108	// Legacy response types (deprecated but kept for backward compatibility)
109	SendTaskResponse(Option<Task>),
110	SendTaskUpdateResponse(SendTaskStreamingResponseResult),
111
112	// New response types (current version)
113	SendMessageResponse(SendMessageResponse),
114	SendStreamingMessageResponse(SendStreamingMessageResponse),
115	GetTaskResponse(GetTaskResponse),
116	CancelTaskResponse(CancelTaskResponse),
117	SetTaskPushNotificationConfigResponse(SetTaskPushNotificationConfigResponse),
118	GetTaskPushNotificationConfigResponse(GetTaskPushNotificationConfigResponse),
119	TaskResubscriptionResponse(TaskResubscriptionResponse),
120	ListTaskPushNotificationConfigResponse(ListTaskPushNotificationConfigResponse),
121	DeleteTaskPushNotificationConfigResponse(DeleteTaskPushNotificationConfigResponse),
122}
123
124impl A2aResponse {
125	pub fn id(&self) -> Option<String> {
126		match self {
127			A2aResponse::SendTaskResponse(i) => i.as_ref().map(|i| i.id.clone()),
128			A2aResponse::SendTaskUpdateResponse(SendTaskStreamingResponseResult::Status(i)) => {
129				Some(i.id.clone())
130			},
131			A2aResponse::SendTaskUpdateResponse(SendTaskStreamingResponseResult::Artifact(i)) => {
132				Some(i.id.clone())
133			},
134			A2aResponse::SendTaskUpdateResponse(SendTaskStreamingResponseResult::None) => None,
135			A2aResponse::SendMessageResponse(i) => Some(i.id.to_string()),
136			A2aResponse::SendStreamingMessageResponse(i) => Some(i.id.to_string()),
137			A2aResponse::GetTaskResponse(i) => Some(i.id.to_string()),
138			A2aResponse::CancelTaskResponse(i) => Some(i.id.to_string()),
139			A2aResponse::SetTaskPushNotificationConfigResponse(i) => Some(i.id.to_string()),
140			A2aResponse::GetTaskPushNotificationConfigResponse(i) => Some(i.id.to_string()),
141			A2aResponse::TaskResubscriptionResponse(i) => Some(i.id.to_string()),
142			A2aResponse::ListTaskPushNotificationConfigResponse(i) => Some(i.id.to_string()),
143			A2aResponse::DeleteTaskPushNotificationConfigResponse(i) => Some(i.id.to_string()),
144		}
145	}
146}
147
148#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
149pub struct AgentAuthentication {
150	#[serde(default, skip_serializing_if = "Option::is_none")]
151	pub credentials: Option<String>,
152	pub schemes: Vec<String>,
153}
154
155#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, Default)]
156pub struct AgentCapabilities {
157	#[serde(
158		rename = "pushNotifications",
159		default,
160		skip_serializing_if = "Option::is_none"
161	)]
162	pub push_notifications: Option<bool>,
163	#[serde(
164		rename = "stateTransitionHistory",
165		default,
166		skip_serializing_if = "Option::is_none"
167	)]
168	pub state_transition_history: Option<bool>,
169	#[serde(default, skip_serializing_if = "Option::is_none")]
170	pub streaming: Option<bool>,
171	#[serde(default, skip_serializing_if = "Vec::is_empty")]
172	pub extensions: Vec<AgentExtension>,
173}
174
175#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
176pub struct AgentCard {
177	// Legacy fields (deprecated but kept for backward compatibility)
178	#[serde(default, skip_serializing_if = "Option::is_none")]
179	pub authentication: Option<AgentAuthentication>,
180
181	// Current fields
182	#[serde(
183		rename = "additionalInterfaces",
184		default,
185		skip_serializing_if = "Vec::is_empty"
186	)]
187	pub additional_interfaces: Vec<AgentInterface>,
188	pub capabilities: AgentCapabilities,
189	#[serde(rename = "defaultInputModes")]
190	pub default_input_modes: Vec<String>,
191	#[serde(rename = "defaultOutputModes")]
192	pub default_output_modes: Vec<String>,
193	pub description: String,
194	#[serde(
195		rename = "documentationUrl",
196		default,
197		skip_serializing_if = "Option::is_none"
198	)]
199	pub documentation_url: Option<String>,
200	#[serde(rename = "iconUrl", default, skip_serializing_if = "Option::is_none")]
201	pub icon_url: Option<String>,
202	pub name: String,
203	#[serde(
204		rename = "preferredTransport",
205		default,
206		skip_serializing_if = "Option::is_none"
207	)]
208	pub preferred_transport: Option<String>,
209	#[serde(rename = "protocolVersion")]
210	pub protocol_version: String,
211	#[serde(default, skip_serializing_if = "Option::is_none")]
212	pub provider: Option<AgentProvider>,
213	#[serde(default, skip_serializing_if = "Vec::is_empty")]
214	pub security: Vec<std::collections::HashMap<String, Vec<String>>>,
215	#[serde(
216		rename = "securitySchemes",
217		default,
218		skip_serializing_if = "std::collections::HashMap::is_empty"
219	)]
220	pub security_schemes: std::collections::HashMap<String, SecurityScheme>,
221	#[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")]
222	pub signatures: ::std::vec::Vec<AgentCardSignature>,
223	pub skills: Vec<AgentSkill>,
224	#[serde(
225		rename = "supportsAuthenticatedExtendedCard",
226		default,
227		skip_serializing_if = "Option::is_none"
228	)]
229	pub supports_authenticated_extended_card: Option<bool>,
230	pub url: String,
231	pub version: String,
232}
233
234#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
235pub struct AgentCardSignature {
236	#[serde(default, skip_serializing_if = "::serde_json::Map::is_empty")]
237	pub header: serde_json::Map<String, serde_json::Value>,
238	pub protected: String,
239	pub signature: String,
240}
241#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
242pub struct AgentProvider {
243	pub organization: String,
244	pub url: String,
245}
246
247// New types for current schema
248#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
249pub struct AgentInterface {
250	pub transport: String,
251	pub url: String,
252}
253
254#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
255pub struct AgentExtension {
256	#[serde(default, skip_serializing_if = "Option::is_none")]
257	pub description: Option<String>,
258	#[serde(default, skip_serializing_if = "serde_json::Map::is_empty")]
259	pub params: serde_json::Map<String, serde_json::Value>,
260	#[serde(default, skip_serializing_if = "Option::is_none")]
261	pub required: Option<bool>,
262	pub uri: String,
263}
264
265#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
266#[serde(tag = "type")]
267pub enum SecurityScheme {
268	#[serde(rename = "apiKey")]
269	ApiKey(ApiKeySecurityScheme),
270	#[serde(rename = "http")]
271	HttpAuth(HttpAuthSecurityScheme),
272	#[serde(rename = "oauth2")]
273	OAuth2(Box<OAuth2SecurityScheme>),
274	#[serde(rename = "openIdConnect")]
275	OpenIdConnect(OpenIdConnectSecurityScheme),
276}
277
278#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
279pub struct ApiKeySecurityScheme {
280	#[serde(default, skip_serializing_if = "Option::is_none")]
281	pub description: Option<String>,
282	#[serde(rename = "in")]
283	pub in_: ApiKeySecuritySchemeIn,
284	pub name: String,
285}
286
287#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
288pub enum ApiKeySecuritySchemeIn {
289	#[serde(rename = "cookie")]
290	Cookie,
291	#[serde(rename = "header")]
292	Header,
293	#[serde(rename = "query")]
294	Query,
295}
296
297#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
298pub struct HttpAuthSecurityScheme {
299	#[serde(
300		rename = "bearerFormat",
301		default,
302		skip_serializing_if = "Option::is_none"
303	)]
304	pub bearer_format: Option<String>,
305	#[serde(default, skip_serializing_if = "Option::is_none")]
306	pub description: Option<String>,
307	pub scheme: String,
308}
309
310#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
311pub struct OAuth2SecurityScheme {
312	#[serde(default, skip_serializing_if = "Option::is_none")]
313	pub description: Option<String>,
314	pub flows: OAuthFlows,
315}
316
317#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
318pub struct OAuthFlows {
319	#[serde(
320		rename = "authorizationCode",
321		default,
322		skip_serializing_if = "Option::is_none"
323	)]
324	pub authorization_code: Option<AuthorizationCodeOAuthFlow>,
325	#[serde(
326		rename = "clientCredentials",
327		default,
328		skip_serializing_if = "Option::is_none"
329	)]
330	pub client_credentials: Option<ClientCredentialsOAuthFlow>,
331	#[serde(default, skip_serializing_if = "Option::is_none")]
332	pub implicit: Option<ImplicitOAuthFlow>,
333	#[serde(default, skip_serializing_if = "Option::is_none")]
334	pub password: Option<PasswordOAuthFlow>,
335}
336
337#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
338pub struct AuthorizationCodeOAuthFlow {
339	#[serde(rename = "authorizationUrl")]
340	pub authorization_url: String,
341	#[serde(
342		rename = "refreshUrl",
343		default,
344		skip_serializing_if = "Option::is_none"
345	)]
346	pub refresh_url: Option<String>,
347	pub scopes: std::collections::HashMap<String, String>,
348	#[serde(rename = "tokenUrl")]
349	pub token_url: String,
350}
351
352#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
353pub struct ClientCredentialsOAuthFlow {
354	#[serde(
355		rename = "refreshUrl",
356		default,
357		skip_serializing_if = "Option::is_none"
358	)]
359	pub refresh_url: Option<String>,
360	pub scopes: std::collections::HashMap<String, String>,
361	#[serde(rename = "tokenUrl")]
362	pub token_url: String,
363}
364
365#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
366pub struct ImplicitOAuthFlow {
367	#[serde(rename = "authorizationUrl")]
368	pub authorization_url: String,
369	#[serde(
370		rename = "refreshUrl",
371		default,
372		skip_serializing_if = "Option::is_none"
373	)]
374	pub refresh_url: Option<String>,
375	pub scopes: std::collections::HashMap<String, String>,
376}
377
378#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
379pub struct PasswordOAuthFlow {
380	#[serde(
381		rename = "refreshUrl",
382		default,
383		skip_serializing_if = "Option::is_none"
384	)]
385	pub refresh_url: Option<String>,
386	pub scopes: std::collections::HashMap<String, String>,
387	#[serde(rename = "tokenUrl")]
388	pub token_url: String,
389}
390
391#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
392pub struct OpenIdConnectSecurityScheme {
393	#[serde(default, skip_serializing_if = "Option::is_none")]
394	pub description: Option<String>,
395	#[serde(rename = "openIdConnectUrl")]
396	pub open_id_connect_url: String,
397	#[serde(rename = "type")]
398	pub type_: String,
399}
400
401#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
402pub struct AgentSkill {
403	// Current fields (new schema)
404	pub id: String,
405	pub name: String,
406	#[serde(default, skip_serializing_if = "String::is_empty")]
407	pub description: String, // Now required in new schema
408	#[serde(default, skip_serializing_if = "Vec::is_empty")]
409	pub examples: Vec<String>,
410	#[serde(rename = "inputModes", default, skip_serializing_if = "Vec::is_empty")]
411	pub input_modes: Vec<String>,
412	#[serde(rename = "outputModes", default, skip_serializing_if = "Vec::is_empty")]
413	pub output_modes: Vec<String>,
414	#[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")]
415	pub security: Vec<std::collections::HashMap<String, Vec<String>>>,
416	pub tags: Vec<String>,
417}
418
419#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
420pub struct Artifact {
421	#[serde(rename = "artifactId")]
422	pub artifact_id: String,
423	#[serde(default, skip_serializing_if = "Option::is_none")]
424	pub description: Option<String>,
425	#[serde(default, skip_serializing_if = "Vec::is_empty")]
426	pub extensions: Vec<String>,
427	#[serde(default, skip_serializing_if = "Option::is_none")]
428	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
429	#[serde(default, skip_serializing_if = "Option::is_none")]
430	pub name: Option<String>,
431	pub parts: Vec<Part>,
432}
433#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
434pub struct AuthenticationInfo {
435	#[serde(default, skip_serializing_if = "Option::is_none")]
436	pub credentials: Option<String>,
437	pub schemes: Vec<String>,
438}
439
440#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
441pub struct DataPart {
442	pub data: serde_json::Map<String, serde_json::Value>,
443}
444#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, Default)]
445pub struct FileContent {
446	#[serde(default, skip_serializing_if = "Option::is_none")]
447	pub bytes: Option<String>,
448	#[serde(rename = "mimeType", default, skip_serializing_if = "Option::is_none")]
449	pub mime_type: Option<String>,
450	#[serde(default, skip_serializing_if = "Option::is_none")]
451	pub name: Option<String>,
452	#[serde(default, skip_serializing_if = "Option::is_none")]
453	pub uri: Option<String>,
454}
455#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
456pub struct FilePart {
457	pub file: FileContent,
458}
459
460#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
461#[serde(untagged)]
462pub enum Id {
463	Variant0(i64),
464	Variant1(String),
465	Variant2,
466}
467impl From<i64> for Id {
468	fn from(value: i64) -> Self {
469		Self::Variant0(value)
470	}
471}
472#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
473pub struct InternalError {
474	pub code: i64,
475	#[serde(default, skip_serializing_if = "Option::is_none")]
476	pub data: Option<serde_json::Value>,
477	pub message: String,
478}
479#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
480pub struct InvalidParamsError {
481	pub code: i64,
482	#[serde(default, skip_serializing_if = "Option::is_none")]
483	pub data: Option<serde_json::Value>,
484	pub message: String,
485}
486#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
487pub struct InvalidRequestError {
488	pub code: i64,
489	#[serde(default, skip_serializing_if = "Option::is_none")]
490	pub data: Option<serde_json::Value>,
491	pub message: String,
492}
493
494#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
495pub struct Message {
496	// Legacy fields (deprecated but kept for backward compatibility)
497	#[serde(default, skip_serializing_if = "Option::is_none")]
498	pub content_legacy: Option<Vec<Part>>,
499	#[serde(default, skip_serializing_if = "Option::is_none")]
500	pub role_legacy: Option<String>,
501	#[serde(default, skip_serializing_if = "Option::is_none")]
502	pub timestamp_legacy: Option<chrono::NaiveDateTime>,
503
504	// Current fields (new schema)
505	#[serde(default, skip_serializing_if = "Vec::is_empty")]
506	pub content: Vec<Part>,
507	#[serde(default, skip_serializing_if = "String::is_empty")]
508	pub role: String,
509	#[serde(default, skip_serializing_if = "Option::is_none")]
510	pub timestamp: Option<String>, // Changed from chrono::NaiveDateTime to String in new schema
511	#[serde(default, skip_serializing_if = "Option::is_none")]
512	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
513}
514#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
515pub struct MethodNotFoundError {
516	pub code: i64,
517	pub data: serde_json::Value,
518	pub message: String,
519}
520
521#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
522#[serde(tag = "kind")]
523pub enum Part {
524	Text(TextPart),
525	File(FilePart),
526	Data(DataPart),
527}
528
529#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
530pub struct PushNotificationConfig {
531	#[serde(default, skip_serializing_if = "Option::is_none")]
532	pub authentication: Option<AuthenticationInfo>,
533	#[serde(default, skip_serializing_if = "Option::is_none")]
534	pub token: Option<String>,
535	pub url: String,
536}
537#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
538pub struct PushNotificationNotSupportedError {
539	pub code: i64,
540	pub data: serde_json::Value,
541	pub message: String,
542}
543#[derive(
544	serde::Deserialize, serde::Serialize, Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd,
545)]
546pub enum Role {
547	#[serde(rename = "user")]
548	User,
549	#[serde(rename = "agent")]
550	Agent,
551}
552impl Display for Role {
553	fn fmt(&self, f: &mut Formatter<'_>) -> ::std::fmt::Result {
554		match *self {
555			Self::User => write!(f, "user"),
556			Self::Agent => write!(f, "agent"),
557		}
558	}
559}
560impl ::std::str::FromStr for Role {
561	type Err = self::error::ConversionError;
562	fn from_str(value: &str) -> Result<Self, self::error::ConversionError> {
563		match value {
564			"user" => Ok(Self::User),
565			"agent" => Ok(Self::Agent),
566			_ => Err("invalid value".into()),
567		}
568	}
569}
570impl TryFrom<&str> for Role {
571	type Error = self::error::ConversionError;
572	fn try_from(value: &str) -> Result<Self, self::error::ConversionError> {
573		value.parse()
574	}
575}
576impl TryFrom<&String> for Role {
577	type Error = self::error::ConversionError;
578	fn try_from(value: &String) -> Result<Self, self::error::ConversionError> {
579		value.parse()
580	}
581}
582impl TryFrom<String> for Role {
583	type Error = self::error::ConversionError;
584	fn try_from(value: String) -> Result<Self, self::error::ConversionError> {
585		value.parse()
586	}
587}
588
589const_string!(CancelTaskRequestMethod = "tasks/cancel");
590pub type CancelTaskRequest = Request<CancelTaskRequestMethod, TaskIdParams>;
591
592const_string!(GetTaskRequestMethod = "tasks/get");
593pub type GetTaskRequest = Request<GetTaskRequestMethod, TaskQueryParams>;
594
595const_string!(SendTaskRequestMethod = "tasks/send");
596pub type SendTaskRequest = Request<SendTaskRequestMethod, TaskSendParams>;
597
598const_string!(SendSubscribeTaskRequestMethod = "tasks/sendSubscribe");
599pub type SendSubscribeTaskRequest = Request<SendSubscribeTaskRequestMethod, TaskSendParams>;
600
601const_string!(TaskResubscribeRequestMethod = "tasks/resubscribe");
602pub type TaskResubscribeRequest = Request<TaskResubscribeRequestMethod, TaskQueryParams>;
603
604const_string!(TaskPushNotificationGetRequestMethod = "tasks/pushNotification/get");
605pub type TaskPushNotificationGetRequest =
606	Request<TaskPushNotificationGetRequestMethod, TaskIdParams>;
607
608const_string!(TaskPushNotificationSetRequestMethod = "tasks/pushNotification/set");
609pub type TaskPushNotificationSetRequest =
610	Request<TaskPushNotificationSetRequestMethod, TaskPushNotificationConfig>;
611
612// New request types (current version)
613const_string!(SendMessageRequestMethod = "message/send");
614pub type SendMessageRequest = Request<SendMessageRequestMethod, MessageSendParams>;
615
616const_string!(SendStreamingMessageRequestMethod = "message/stream");
617pub type SendStreamingMessageRequest =
618	Request<SendStreamingMessageRequestMethod, MessageSendParams>;
619
620const_string!(SetTaskPushNotificationConfigRequestMethod = "tasks/pushNotificationConfig/set");
621pub type SetTaskPushNotificationConfigRequest =
622	Request<SetTaskPushNotificationConfigRequestMethod, TaskPushNotificationConfig>;
623
624const_string!(GetTaskPushNotificationConfigRequestMethod = "tasks/pushNotificationConfig/get");
625pub type GetTaskPushNotificationConfigRequest =
626	Request<GetTaskPushNotificationConfigRequestMethod, GetTaskPushNotificationConfigParams>;
627
628const_string!(TaskResubscriptionRequestMethod = "tasks/resubscribe");
629pub type TaskResubscriptionRequest = Request<TaskResubscriptionRequestMethod, TaskIdParams>;
630
631const_string!(ListTaskPushNotificationConfigRequestMethod = "tasks/pushNotificationConfig/list");
632pub type ListTaskPushNotificationConfigRequest =
633	Request<ListTaskPushNotificationConfigRequestMethod, TaskIdParams>;
634
635const_string!(
636	DeleteTaskPushNotificationConfigRequestMethod = "tasks/pushNotificationConfig/delete"
637);
638pub type DeleteTaskPushNotificationConfigRequest =
639	Request<DeleteTaskPushNotificationConfigRequestMethod, DeleteTaskPushNotificationConfigParams>;
640
641const_string!(GetAuthenticatedExtendedCardRequestMethod = "agent/getAuthenticatedExtendedCard");
642pub type GetAuthenticatedExtendedCardRequest =
643	Request<GetAuthenticatedExtendedCardRequestMethod, ()>;
644
645#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
646#[serde(untagged)]
647#[derive(Default)]
648pub enum SendTaskStreamingResponseResult {
649	Status(TaskStatusUpdateEvent),
650	Artifact(TaskArtifactUpdateEvent),
651	#[default]
652	None,
653}
654
655#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
656pub struct Task {
657	// Legacy fields (deprecated but kept for backward compatibility)
658	#[serde(default, skip_serializing_if = "Option::is_none")]
659	pub artifacts_legacy: Option<Vec<Artifact>>,
660	#[serde(rename = "sessionId", default, skip_serializing_if = "Option::is_none")]
661	pub session_id: Option<String>,
662	#[serde(default, skip_serializing_if = "Option::is_none")]
663	pub history_legacy: Option<Vec<Message>>,
664
665	// Current fields (new schema)
666	#[serde(default, skip_serializing_if = "Vec::is_empty")]
667	pub artifacts: Vec<Artifact>,
668	#[serde(rename = "contextId")]
669	pub context_id: String,
670	#[serde(default, skip_serializing_if = "Vec::is_empty")]
671	pub history: Vec<Message>,
672	pub id: String,
673	#[serde(default, skip_serializing_if = "String::is_empty")]
674	pub kind: String,
675	#[serde(default, skip_serializing_if = "Option::is_none")]
676	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
677	pub status: TaskStatus,
678}
679
680#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
681pub struct TaskArtifactUpdateEvent {
682	pub artifact: Artifact,
683	pub id: String,
684	#[serde(default, skip_serializing_if = "Option::is_none")]
685	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
686}
687#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
688pub struct TaskIdParams {
689	pub id: String,
690	#[serde(default, skip_serializing_if = "Option::is_none")]
691	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
692}
693#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
694pub struct DeleteTaskPushNotificationConfigParams {
695	pub id: String,
696	#[serde(default, skip_serializing_if = "Option::is_none")]
697	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
698	#[serde(rename = "pushNotificationConfigId")]
699	pub push_notification_config_id: String,
700}
701#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
702pub struct GetTaskPushNotificationConfigParams {
703	pub id: String,
704	#[serde(default, skip_serializing_if = "Option::is_none")]
705	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
706	#[serde(rename = "pushNotificationConfigId", skip_serializing_if = "Option::is_none")]
707	pub push_notification_config_id: Option<String>,
708}
709#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
710pub struct TaskNotCancelableError {
711	pub code: i64,
712	pub data: serde_json::Value,
713	pub message: String,
714}
715#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
716pub struct TaskNotFoundError {
717	pub code: i64,
718	pub data: serde_json::Value,
719	pub message: String,
720}
721#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
722pub struct TaskPushNotificationConfig {
723	pub id: String,
724	#[serde(rename = "pushNotificationConfig")]
725	pub push_notification_config: PushNotificationConfig,
726}
727#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
728pub struct TaskQueryParams {
729	#[serde(
730		rename = "historyLength",
731		default,
732		skip_serializing_if = "Option::is_none"
733	)]
734	pub history_length: Option<i64>,
735	pub id: String,
736	#[serde(default, skip_serializing_if = "Option::is_none")]
737	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
738}
739
740#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
741pub struct TaskSendParams {
742	#[serde(
743		rename = "historyLength",
744		default,
745		skip_serializing_if = "Option::is_none"
746	)]
747	pub history_length: Option<i64>,
748	pub id: String,
749	pub message: Message,
750	#[serde(default, skip_serializing_if = "Option::is_none")]
751	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
752	#[serde(
753		rename = "pushNotification",
754		default,
755		skip_serializing_if = "Option::is_none"
756	)]
757	pub push_notification: Option<PushNotificationConfig>,
758	#[serde(rename = "sessionId", default, skip_serializing_if = "Option::is_none")]
759	pub session_id: Option<String>,
760}
761
762#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
763pub struct MessageSendParams {
764	#[serde(default, skip_serializing_if = "Option::is_none")]
765	pub configuration: Option<MessageSendConfiguration>,
766	pub message: Message,
767	#[serde(default, skip_serializing_if = "serde_json::Map::is_empty")]
768	pub metadata: serde_json::Map<String, serde_json::Value>,
769}
770
771#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
772pub struct MessageSendConfiguration {
773	#[serde(rename = "acceptedOutputModes")]
774	pub accepted_output_modes: Vec<String>,
775	#[serde(default, skip_serializing_if = "Option::is_none")]
776	pub blocking: Option<bool>,
777	#[serde(
778		rename = "historyLength",
779		default,
780		skip_serializing_if = "Option::is_none"
781	)]
782	pub history_length: Option<i64>,
783	#[serde(
784		rename = "pushNotificationConfig",
785		default,
786		skip_serializing_if = "Option::is_none"
787	)]
788	pub push_notification_config: Option<PushNotificationConfig>,
789}
790
791#[derive(
792	serde::Deserialize, serde::Serialize, Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd,
793)]
794pub enum TaskState {
795	#[serde(rename = "submitted")]
796	Submitted,
797	#[serde(rename = "working")]
798	Working,
799	#[serde(rename = "input-required")]
800	InputRequired,
801	#[serde(rename = "completed")]
802	Completed,
803	#[serde(rename = "canceled")]
804	Canceled,
805	#[serde(rename = "failed")]
806	Failed,
807	#[serde(rename = "unknown")]
808	Unknown,
809	// New states from current schema
810	#[serde(rename = "rejected")]
811	Rejected,
812	#[serde(rename = "auth-required")]
813	AuthRequired,
814}
815impl Display for TaskState {
816	fn fmt(&self, f: &mut Formatter<'_>) -> ::std::fmt::Result {
817		match *self {
818			Self::Submitted => write!(f, "submitted"),
819			Self::Working => write!(f, "working"),
820			Self::InputRequired => write!(f, "input-required"),
821			Self::Completed => write!(f, "completed"),
822			Self::Canceled => write!(f, "canceled"),
823			Self::Failed => write!(f, "failed"),
824			Self::Unknown => write!(f, "unknown"),
825			Self::Rejected => write!(f, "rejected"),
826			Self::AuthRequired => write!(f, "auth-required"),
827		}
828	}
829}
830impl ::std::str::FromStr for TaskState {
831	type Err = self::error::ConversionError;
832	fn from_str(value: &str) -> Result<Self, self::error::ConversionError> {
833		match value {
834			"submitted" => Ok(Self::Submitted),
835			"working" => Ok(Self::Working),
836			"input-required" => Ok(Self::InputRequired),
837			"completed" => Ok(Self::Completed),
838			"canceled" => Ok(Self::Canceled),
839			"failed" => Ok(Self::Failed),
840			"unknown" => Ok(Self::Unknown),
841			"rejected" => Ok(Self::Rejected),
842			"auth-required" => Ok(Self::AuthRequired),
843			_ => Err("invalid value".into()),
844		}
845	}
846}
847impl TryFrom<&str> for TaskState {
848	type Error = self::error::ConversionError;
849	fn try_from(value: &str) -> Result<Self, self::error::ConversionError> {
850		value.parse()
851	}
852}
853impl TryFrom<&String> for TaskState {
854	type Error = self::error::ConversionError;
855	fn try_from(value: &String) -> Result<Self, self::error::ConversionError> {
856		value.parse()
857	}
858}
859impl TryFrom<String> for TaskState {
860	type Error = self::error::ConversionError;
861	fn try_from(value: String) -> Result<Self, self::error::ConversionError> {
862		value.parse()
863	}
864}
865#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
866pub struct TaskStatus {
867	#[serde(default, skip_serializing_if = "Option::is_none")]
868	pub message: Option<Message>,
869	pub state: TaskState,
870	#[serde(default, skip_serializing_if = "Option::is_none")]
871	pub timestamp: Option<String>,
872}
873#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
874pub struct TaskStatusUpdateEvent {
875	#[serde(rename = "final", default)]
876	pub final_: bool,
877	pub id: String,
878	#[serde(default, skip_serializing_if = "Option::is_none")]
879	pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
880	pub status: TaskStatus,
881}
882
883#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
884pub struct TextPart {
885	pub text: String,
886}
887#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
888pub struct UnsupportedOperationError {
889	pub code: i64,
890	pub data: serde_json::Value,
891	pub message: String,
892}
893
894pub mod error {
895	use std::fmt::{Debug, Display, Formatter};
896	pub struct ConversionError(::std::borrow::Cow<'static, str>);
897	impl ::std::error::Error for ConversionError {}
898	impl Display for ConversionError {
899		fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), ::std::fmt::Error> {
900			Display::fmt(&self.0, f)
901		}
902	}
903	impl Debug for ConversionError {
904		fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), ::std::fmt::Error> {
905			Debug::fmt(&self.0, f)
906		}
907	}
908	impl From<&'static str> for ConversionError {
909		fn from(value: &'static str) -> Self {
910			Self(value.into())
911		}
912	}
913	impl From<String> for ConversionError {
914		fn from(value: String) -> Self {
915			Self(value.into())
916		}
917	}
918}
919
920#[cfg(test)]
921mod tests {
922
923	#[test]
924	fn test_serde() {
925		let js = serde_json::json! {
926		{
927			"jsonrpc": "2.0",
928			"id": "d1306567eb364c7ba9e7a7b922dba672",
929			"result": {
930				"id": "8b34914c735a464986e1d5ce5b6ec478",
931				"status": {
932					"state": "completed",
933					"message": {
934						"role": "agent",
935						"parts": [
936							{
937								"type": "text",
938								"text": "Hello!"
939							}
940						]
941					},
942					"timestamp": "2025-04-10T15:07:15.833777"
943				},
944				"final": false
945			}
946		}
947		};
948		let _: crate::JsonRpcMessage = serde_json::from_value(js).unwrap();
949	}
950}
951
952// New response types (current version)
953pub type SendMessageResponse = JsonRpcResponse<SendMessageSuccessResponse>;
954pub type SendStreamingMessageResponse = JsonRpcResponse<SendStreamingMessageSuccessResponse>;
955pub type GetTaskResponse = JsonRpcResponse<GetTaskSuccessResponse>;
956pub type CancelTaskResponse = JsonRpcResponse<CancelTaskSuccessResponse>;
957pub type SetTaskPushNotificationConfigResponse =
958	JsonRpcResponse<SetTaskPushNotificationConfigSuccessResponse>;
959pub type GetTaskPushNotificationConfigResponse =
960	JsonRpcResponse<GetTaskPushNotificationConfigSuccessResponse>;
961pub type TaskResubscriptionResponse = JsonRpcResponse<TaskResubscriptionSuccessResponse>;
962pub type ListTaskPushNotificationConfigResponse =
963	JsonRpcResponse<ListTaskPushNotificationConfigSuccessResponse>;
964pub type DeleteTaskPushNotificationConfigResponse =
965	JsonRpcResponse<DeleteTaskPushNotificationConfigSuccessResponse>;
966
967// Success response types
968#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
969pub struct SendMessageSuccessResponse {
970	pub id: NumberOrString,
971	pub jsonrpc: String,
972	pub result: SendMessageSuccessResponseResult,
973}
974
975#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
976pub struct SendStreamingMessageSuccessResponse {
977	pub id: NumberOrString,
978	pub jsonrpc: String,
979	pub result: SendStreamingMessageSuccessResponseResult,
980}
981
982#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
983pub struct GetTaskSuccessResponse {
984	pub id: NumberOrString,
985	pub jsonrpc: String,
986	pub result: Task,
987}
988
989#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
990pub struct CancelTaskSuccessResponse {
991	pub id: NumberOrString,
992	pub jsonrpc: String,
993	pub result: Task,
994}
995
996#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
997pub struct SetTaskPushNotificationConfigSuccessResponse {
998	pub id: NumberOrString,
999	pub jsonrpc: String,
1000	pub result: TaskPushNotificationConfig,
1001}
1002
1003#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
1004pub struct GetTaskPushNotificationConfigSuccessResponse {
1005	pub id: NumberOrString,
1006	pub jsonrpc: String,
1007	pub result: TaskPushNotificationConfig,
1008}
1009
1010#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
1011pub struct TaskResubscriptionSuccessResponse {
1012	pub id: NumberOrString,
1013	pub jsonrpc: String,
1014	pub result: (),
1015}
1016
1017#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
1018pub struct ListTaskPushNotificationConfigSuccessResponse {
1019	pub id: NumberOrString,
1020	pub jsonrpc: String,
1021	pub result: Vec<TaskPushNotificationConfig>,
1022}
1023
1024#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
1025pub struct DeleteTaskPushNotificationConfigSuccessResponse {
1026	pub id: NumberOrString,
1027	pub jsonrpc: String,
1028	pub result: (),
1029}
1030
1031// Result types for success responses
1032#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
1033#[serde(untagged)]
1034pub enum SendMessageSuccessResponseResult {
1035	Task(Box<Task>),
1036	Message(Message),
1037}
1038
1039#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
1040#[serde(untagged)]
1041pub enum SendStreamingMessageSuccessResponseResult {
1042	Task(Task),
1043	Message(Message),
1044	TaskStatusUpdateEvent(TaskStatusUpdateEvent),
1045	TaskArtifactUpdateEvent(TaskArtifactUpdateEvent),
1046}