a2a_types/
lib.rs

1//! # A2A (Agent2Agent) Protocol Types
2//!
3//! This crate provides the Rust data structures for the Agent2Agent (A2A) protocol,
4//! a standard for interoperability between AI agents. The types are derived from the
5//! official A2A JSON Schema for that specific release
6//! and are designed for serialization and deserialization with `serde`.
7//!
8//! The primary goal of A2A is to enable agents to:
9//! - Discover each other's capabilities via the `AgentCard`.
10//! - Negotiate interaction modalities (text, files, structured data).
11//! - Manage collaborative `Task`s.
12//! - Securely exchange information as `Message`s.
13
14use serde::{Deserialize, Serialize};
15use std::collections::HashMap;
16
17// ============================================================================
18// JSON-RPC 2.0 Base Types (from schema)
19// ============================================================================
20
21/// Defines the base structure for any JSON-RPC 2.0 request, response, or notification.
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct JSONRPCMessage {
24    /// The version of the JSON-RPC protocol. MUST be exactly "2.0".
25    pub jsonrpc: String,
26    /// A unique identifier established by the client. It must be a String, a Number, or null.
27    /// The server must reply with the same value in the response. This property is omitted for notifications.
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub id: Option<JSONRPCId>,
30}
31
32/// Represents a JSON-RPC 2.0 identifier, which can be a string, number, or null.
33#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
34#[serde(untagged)]
35pub enum JSONRPCId {
36    String(String),
37    Integer(i64),
38    Null,
39}
40
41/// Represents a JSON-RPC 2.0 Request object.
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct JSONRPCRequest {
44    /// The version of the JSON-RPC protocol. MUST be exactly "2.0".
45    pub jsonrpc: String,
46    /// A string containing the name of the method to be invoked.
47    pub method: String,
48    /// A structured value holding the parameter values to be used during the method invocation.
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub params: Option<serde_json::Value>,
51}
52
53/// Represents a successful JSON-RPC 2.0 Response object.
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct JSONRPCSuccessResponse {
56    /// The version of the JSON-RPC protocol. MUST be exactly "2.0".
57    pub jsonrpc: String,
58    /// The value of this member is determined by the method invoked on the Server.
59    pub result: serde_json::Value,
60    /// The identifier established by the client.
61    pub id: Option<JSONRPCId>,
62}
63
64/// Represents a JSON-RPC 2.0 Error Response object.
65#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct JSONRPCErrorResponse {
67    /// The version of the JSON-RPC protocol. MUST be exactly "2.0".
68    pub jsonrpc: String,
69    /// An object describing the error that occurred.
70    pub error: JSONRPCError,
71    /// The identifier established by the client.
72    pub id: Option<JSONRPCId>,
73}
74
75/// Represents a JSON-RPC 2.0 Error object, included in an error response.
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct JSONRPCError {
78    /// A number that indicates the error type that occurred.
79    pub code: i32,
80    /// A string providing a short description of the error.
81    pub message: String,
82    /// A primitive or structured value containing additional information about the error.
83    /// This may be omitted.
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub data: Option<serde_json::Value>,
86}
87
88/// A discriminated union representing all possible JSON-RPC 2.0 responses
89/// for the A2A specification methods.
90#[derive(Debug, Clone, Serialize, Deserialize)]
91#[serde(untagged)]
92pub enum JSONRPCResponse {
93    SendMessage(SendMessageResponse),
94    SendStreamingMessage(SendStreamingMessageResponse),
95    GetTask(GetTaskResponse),
96    CancelTask(CancelTaskResponse),
97    SetTaskPushNotificationConfig(SetTaskPushNotificationConfigResponse),
98    GetTaskPushNotificationConfig(GetTaskPushNotificationConfigResponse),
99    ListTaskPushNotificationConfig(ListTaskPushNotificationConfigResponse),
100    DeleteTaskPushNotificationConfig(DeleteTaskPushNotificationConfigResponse),
101    GetAuthenticatedExtendedCard(GetAuthenticatedExtendedCardResponse),
102    Error(JSONRPCErrorResponse),
103}
104
105// ============================================================================
106// A2A Error Types (from schema definitions)
107// ============================================================================
108
109/// An error indicating that the server received invalid JSON.
110#[derive(Debug, Clone, Serialize, Deserialize)]
111#[serde(default)]
112pub struct JSONParseError {
113    /// The error code for a JSON parse error.
114    pub code: i32, // -32700
115    /// The error message.
116    pub message: String,
117    /// A primitive or structured value containing additional information about the error.
118    #[serde(skip_serializing_if = "Option::is_none")]
119    pub data: Option<serde_json::Value>,
120}
121
122impl Default for JSONParseError {
123    fn default() -> Self {
124        Self {
125            code: JSON_PARSE_ERROR_CODE,
126            message: JSON_PARSE_ERROR_MESSAGE.to_string(),
127            data: None,
128        }
129    }
130}
131
132/// An error indicating that the JSON sent is not a valid Request object.
133#[derive(Debug, Clone, Serialize, Deserialize)]
134#[serde(default)]
135pub struct InvalidRequestError {
136    /// The error code for an invalid request.
137    pub code: i32, // -32600
138    /// The error message.
139    pub message: String,
140    /// A primitive or structured value containing additional information about the error.
141    #[serde(skip_serializing_if = "Option::is_none")]
142    pub data: Option<serde_json::Value>,
143}
144
145impl Default for InvalidRequestError {
146    fn default() -> Self {
147        Self {
148            code: INVALID_REQUEST_ERROR_CODE,
149            message: INVALID_REQUEST_ERROR_MESSAGE.to_string(),
150            data: None,
151        }
152    }
153}
154
155/// An error indicating that the requested method does not exist or is not available.
156#[derive(Debug, Clone, Serialize, Deserialize)]
157#[serde(default)]
158pub struct MethodNotFoundError {
159    /// The error code for a method not found error.
160    pub code: i32, // -32601
161    /// The error message.
162    pub message: String,
163    /// A primitive or structured value containing additional information about the error.
164    #[serde(skip_serializing_if = "Option::is_none")]
165    pub data: Option<serde_json::Value>,
166}
167
168impl Default for MethodNotFoundError {
169    fn default() -> Self {
170        Self {
171            code: METHOD_NOT_FOUND_ERROR_CODE,
172            message: METHOD_NOT_FOUND_ERROR_MESSAGE.to_string(),
173            data: None,
174        }
175    }
176}
177
178/// An error indicating that the method parameters are invalid.
179#[derive(Debug, Clone, Serialize, Deserialize)]
180#[serde(default)]
181pub struct InvalidParamsError {
182    /// The error code for an invalid parameters error.
183    pub code: i32, // -32602
184    /// The error message.
185    pub message: String,
186    /// A primitive or structured value containing additional information about the error.
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub data: Option<serde_json::Value>,
189}
190
191impl Default for InvalidParamsError {
192    fn default() -> Self {
193        Self {
194            code: INVALID_PARAMS_ERROR_CODE,
195            message: INVALID_PARAMS_ERROR_MESSAGE.to_string(),
196            data: None,
197        }
198    }
199}
200
201/// An error indicating an internal error on the server.
202#[derive(Debug, Clone, Serialize, Deserialize)]
203#[serde(default)]
204pub struct InternalError {
205    /// The error code for an internal server error.
206    pub code: i32, // -32603
207    /// The error message.
208    pub message: String,
209    /// A primitive or structured value containing additional information about the error.
210    #[serde(skip_serializing_if = "Option::is_none")]
211    pub data: Option<serde_json::Value>,
212}
213
214impl Default for InternalError {
215    fn default() -> Self {
216        Self {
217            code: INTERNAL_ERROR_CODE,
218            message: INTERNAL_ERROR_MESSAGE.to_string(),
219            data: None,
220        }
221    }
222}
223
224/// An A2A-specific error indicating that the requested task ID was not found.
225#[derive(Debug, Clone, Serialize, Deserialize)]
226#[serde(default)]
227pub struct TaskNotFoundError {
228    /// The error code for a task not found error.
229    pub code: i32, // -32001
230    /// The error message.
231    pub message: String,
232    /// A primitive or structured value containing additional information about the error.
233    #[serde(skip_serializing_if = "Option::is_none")]
234    pub data: Option<serde_json::Value>,
235}
236
237impl Default for TaskNotFoundError {
238    fn default() -> Self {
239        Self {
240            code: TASK_NOT_FOUND_ERROR_CODE,
241            message: TASK_NOT_FOUND_ERROR_MESSAGE.to_string(),
242            data: None,
243        }
244    }
245}
246
247/// An A2A-specific error indicating that the task is in a state where it cannot be canceled.
248#[derive(Debug, Clone, Serialize, Deserialize)]
249#[serde(default)]
250pub struct TaskNotCancelableError {
251    /// The error code for a task that cannot be canceled.
252    pub code: i32, // -32002
253    /// The error message.
254    pub message: String,
255    /// A primitive or structured value containing additional information about the error.
256    #[serde(skip_serializing_if = "Option::is_none")]
257    pub data: Option<serde_json::Value>,
258}
259
260impl Default for TaskNotCancelableError {
261    fn default() -> Self {
262        Self {
263            code: TASK_NOT_CANCELABLE_ERROR_CODE,
264            message: TASK_NOT_CANCELABLE_ERROR_MESSAGE.to_string(),
265            data: None,
266        }
267    }
268}
269
270/// An A2A-specific error indicating that the agent does not support push notifications.
271#[derive(Debug, Clone, Serialize, Deserialize)]
272#[serde(default)]
273pub struct PushNotificationNotSupportedError {
274    /// The error code for when push notifications are not supported.
275    pub code: i32, // -32003
276    /// The error message.
277    pub message: String,
278    /// A primitive or structured value containing additional information about the error.
279    #[serde(skip_serializing_if = "Option::is_none")]
280    pub data: Option<serde_json::Value>,
281}
282
283impl Default for PushNotificationNotSupportedError {
284    fn default() -> Self {
285        Self {
286            code: PUSH_NOTIFICATION_NOT_SUPPORTED_ERROR_CODE,
287            message: PUSH_NOTIFICATION_NOT_SUPPORTED_ERROR_MESSAGE.to_string(),
288            data: None,
289        }
290    }
291}
292
293/// An A2A-specific error indicating that the requested operation is not supported by the agent.
294#[derive(Debug, Clone, Serialize, Deserialize)]
295#[serde(default)]
296pub struct UnsupportedOperationError {
297    /// The error code for an unsupported operation.
298    pub code: i32, // -32004
299    /// The error message.
300    pub message: String,
301    /// A primitive or structured value containing additional information about the error.
302    #[serde(skip_serializing_if = "Option::is_none")]
303    pub data: Option<serde_json::Value>,
304}
305
306impl Default for UnsupportedOperationError {
307    fn default() -> Self {
308        Self {
309            code: UNSUPPORTED_OPERATION_ERROR_CODE,
310            message: UNSUPPORTED_OPERATION_ERROR_MESSAGE.to_string(),
311            data: None,
312        }
313    }
314}
315
316/// An A2A-specific error indicating an incompatibility between the requested
317/// content types and the agent's capabilities.
318#[derive(Debug, Clone, Serialize, Deserialize)]
319#[serde(default)]
320pub struct ContentTypeNotSupportedError {
321    /// The error code for an unsupported content type.
322    pub code: i32, // -32005
323    /// The error message.
324    pub message: String,
325    /// A primitive or structured value containing additional information about the error.
326    #[serde(skip_serializing_if = "Option::is_none")]
327    pub data: Option<serde_json::Value>,
328}
329
330impl Default for ContentTypeNotSupportedError {
331    fn default() -> Self {
332        Self {
333            code: CONTENT_TYPE_NOT_SUPPORTED_ERROR_CODE,
334            message: CONTENT_TYPE_NOT_SUPPORTED_ERROR_MESSAGE.to_string(),
335            data: None,
336        }
337    }
338}
339
340/// An A2A-specific error indicating that the agent returned a response that
341/// does not conform to the specification for the current method.
342#[derive(Debug, Clone, Serialize, Deserialize)]
343#[serde(default)]
344pub struct InvalidAgentResponseError {
345    /// The error code for an invalid agent response.
346    pub code: i32, // -32006
347    /// The error message.
348    pub message: String,
349    /// A primitive or structured value containing additional information about the error.
350    #[serde(skip_serializing_if = "Option::is_none")]
351    pub data: Option<serde_json::Value>,
352}
353
354impl Default for InvalidAgentResponseError {
355    fn default() -> Self {
356        Self {
357            code: INVALID_AGENT_RESPONSE_ERROR_CODE,
358            message: INVALID_AGENT_RESPONSE_ERROR_MESSAGE.to_string(),
359            data: None,
360        }
361    }
362}
363
364/// An A2A-specific error indicating that the agent does not have an Authenticated Extended Card configured.
365#[derive(Debug, Clone, Serialize, Deserialize)]
366#[serde(default)]
367pub struct AuthenticatedExtendedCardNotConfiguredError {
368    /// The error code for when an authenticated extended card is not configured.
369    pub code: i32, // -32007
370    /// The error message.
371    pub message: String,
372    /// A primitive or structured value containing additional information about the error.
373    #[serde(skip_serializing_if = "Option::is_none")]
374    pub data: Option<serde_json::Value>,
375}
376
377impl Default for AuthenticatedExtendedCardNotConfiguredError {
378    fn default() -> Self {
379        Self {
380            code: AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED_ERROR_CODE,
381            message: AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED_ERROR_MESSAGE.to_string(),
382            data: None,
383        }
384    }
385}
386
387/// A discriminated union of all standard JSON-RPC and A2A-specific error types.
388#[derive(Debug, Clone, Serialize, Deserialize)]
389#[serde(untagged)]
390pub enum A2AError {
391    JSONParse(JSONParseError),
392    InvalidRequest(InvalidRequestError),
393    MethodNotFound(MethodNotFoundError),
394    InvalidParams(InvalidParamsError),
395    Internal(InternalError),
396    TaskNotFound(TaskNotFoundError),
397    TaskNotCancelable(TaskNotCancelableError),
398    PushNotificationNotSupported(PushNotificationNotSupportedError),
399    UnsupportedOperation(UnsupportedOperationError),
400    ContentTypeNotSupported(ContentTypeNotSupportedError),
401    InvalidAgentResponse(InvalidAgentResponseError),
402    AuthenticatedExtendedCardNotConfigured(AuthenticatedExtendedCardNotConfiguredError),
403}
404
405// Error code and message constants
406const JSON_PARSE_ERROR_CODE: i32 = -32700;
407const JSON_PARSE_ERROR_MESSAGE: &str = "Invalid JSON payload";
408const INVALID_REQUEST_ERROR_CODE: i32 = -32600;
409const INVALID_REQUEST_ERROR_MESSAGE: &str = "Request payload validation error";
410const METHOD_NOT_FOUND_ERROR_CODE: i32 = -32601;
411const METHOD_NOT_FOUND_ERROR_MESSAGE: &str = "Method not found";
412const INVALID_PARAMS_ERROR_CODE: i32 = -32602;
413const INVALID_PARAMS_ERROR_MESSAGE: &str = "Invalid parameters";
414const INTERNAL_ERROR_CODE: i32 = -32603;
415const INTERNAL_ERROR_MESSAGE: &str = "Internal error";
416const TASK_NOT_FOUND_ERROR_CODE: i32 = -32001;
417const TASK_NOT_FOUND_ERROR_MESSAGE: &str = "Task not found";
418const TASK_NOT_CANCELABLE_ERROR_CODE: i32 = -32002;
419const TASK_NOT_CANCELABLE_ERROR_MESSAGE: &str = "Task cannot be canceled";
420const PUSH_NOTIFICATION_NOT_SUPPORTED_ERROR_CODE: i32 = -32003;
421const PUSH_NOTIFICATION_NOT_SUPPORTED_ERROR_MESSAGE: &str = "Push Notification is not supported";
422const UNSUPPORTED_OPERATION_ERROR_CODE: i32 = -32004;
423const UNSUPPORTED_OPERATION_ERROR_MESSAGE: &str = "This operation is not supported";
424const CONTENT_TYPE_NOT_SUPPORTED_ERROR_CODE: i32 = -32005;
425const CONTENT_TYPE_NOT_SUPPORTED_ERROR_MESSAGE: &str = "Incompatible content types";
426const INVALID_AGENT_RESPONSE_ERROR_CODE: i32 = -32006;
427const INVALID_AGENT_RESPONSE_ERROR_MESSAGE: &str = "Invalid agent response";
428const AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED_ERROR_CODE: i32 = -32007;
429const AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED_ERROR_MESSAGE: &str =
430    "Authenticated Extended Card is not configured";
431
432// ============================================================================
433// A2A Core Protocol Types (from schema)
434// ============================================================================
435
436/// Defines the lifecycle states of a Task.
437#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
438#[serde(rename_all = "kebab-case")]
439pub enum TaskState {
440    /// The task has been submitted and is awaiting execution.
441    Submitted,
442    /// The agent is actively working on the task.
443    Working,
444    /// The task is paused and waiting for input from the user.
445    InputRequired,
446    /// The task has been successfully completed.
447    Completed,
448    /// The task has been canceled by the user.
449    Canceled,
450    /// The task failed due to an error during execution.
451    Failed,
452    /// The task was rejected by the agent and was not started.
453    Rejected,
454    /// The task requires authentication to proceed.
455    AuthRequired,
456    /// The task is in an unknown or indeterminate state.
457    Unknown,
458}
459
460/// Represents the status of a task at a specific point in time.
461#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
462pub struct TaskStatus {
463    /// The current state of the task's lifecycle.
464    pub state: TaskState,
465    /// An ISO 8601 datetime string indicating when this status was recorded.
466    #[serde(skip_serializing_if = "Option::is_none")]
467    pub timestamp: Option<String>,
468    /// An optional, human-readable message providing more details about the current status.
469    #[serde(skip_serializing_if = "Option::is_none")]
470    pub message: Option<Message>,
471}
472
473/// Represents a single, stateful operation or conversation between a client and an agent.
474#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
475pub struct Task {
476    /// The type of this object, used as a discriminator. Always 'task'.
477    #[serde(default = "default_task_kind")]
478    pub kind: String,
479    /// A unique identifier for the task, generated by the server for a new task.
480    pub id: String,
481    /// A server-generated identifier for maintaining context across multiple related tasks or interactions.
482    #[serde(rename = "contextId")]
483    pub context_id: String,
484    /// The current status of the task, including its state and a descriptive message.
485    pub status: TaskStatus,
486    /// An array of messages exchanged during the task, representing the conversation history.
487    #[serde(skip_serializing_if = "Vec::is_empty", default)]
488    pub history: Vec<Message>,
489    /// A collection of artifacts generated by the agent during the execution of the task.
490    #[serde(skip_serializing_if = "Vec::is_empty", default)]
491    pub artifacts: Vec<Artifact>,
492    /// Optional metadata for extensions. The key is an extension-specific identifier.
493    #[serde(skip_serializing_if = "Option::is_none")]
494    pub metadata: Option<HashMap<String, serde_json::Value>>,
495}
496
497fn default_task_kind() -> String {
498    TASK_KIND.to_string()
499}
500
501/// Identifies the sender of a message.
502#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
503#[serde(rename_all = "lowercase")]
504pub enum MessageRole {
505    /// For messages sent by the client/user.
506    User,
507    /// For messages sent by the agent/service.
508    Agent,
509}
510
511impl PartialEq<&str> for MessageRole {
512    fn eq(&self, other: &&str) -> bool {
513        matches!(
514            (self, *other),
515            (MessageRole::User, "user")
516                | (MessageRole::Agent, "agent")
517                | (MessageRole::Agent, "assistant")
518        )
519    }
520}
521
522/// Represents a single message in the conversation between a user and an agent.
523#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
524pub struct Message {
525    /// The type of this object, used as a discriminator. Always 'message'.
526    #[serde(default = "default_message_kind")]
527    pub kind: String,
528    /// A unique identifier for the message, typically a UUID, generated by the sender.
529    #[serde(rename = "messageId")]
530    pub message_id: String,
531    /// Identifies the sender of the message. `user` for the client, `agent` for the service.
532    pub role: MessageRole,
533    /// An array of content parts that form the message body.
534    pub parts: Vec<Part>,
535    /// The context identifier for this message, used to group related interactions.
536    #[serde(skip_serializing_if = "Option::is_none", rename = "contextId")]
537    pub context_id: Option<String>,
538    /// The identifier of the task this message is part of. Can be omitted for the first message of a new task.
539    #[serde(skip_serializing_if = "Option::is_none", rename = "taskId")]
540    pub task_id: Option<String>,
541    /// A list of other task IDs that this message references for additional context.
542    #[serde(
543        skip_serializing_if = "Vec::is_empty",
544        rename = "referenceTaskIds",
545        default
546    )]
547    pub reference_task_ids: Vec<String>,
548    /// The URIs of extensions that are relevant to this message.
549    #[serde(skip_serializing_if = "Vec::is_empty", default)]
550    pub extensions: Vec<String>,
551    /// Optional metadata for extensions. The key is an extension-specific identifier.
552    #[serde(skip_serializing_if = "Option::is_none")]
553    pub metadata: Option<HashMap<String, serde_json::Value>>,
554}
555
556fn default_message_kind() -> String {
557    MESSAGE_KIND.to_string()
558}
559
560/// A discriminated union representing a part of a message or artifact.
561#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
562#[serde(tag = "kind", rename_all = "lowercase")]
563pub enum Part {
564    /// Represents a text segment.
565    Text {
566        /// The string content of the text part.
567        text: String,
568        /// Optional metadata associated with this part.
569        #[serde(skip_serializing_if = "Option::is_none")]
570        metadata: Option<HashMap<String, serde_json::Value>>,
571    },
572    /// Represents a file segment.
573    File {
574        /// The file content, represented as either a URI or as base64-encoded bytes.
575        file: FileContent,
576        /// Optional metadata associated with this part.
577        #[serde(skip_serializing_if = "Option::is_none")]
578        metadata: Option<HashMap<String, serde_json::Value>>,
579    },
580    /// Represents a structured data segment (e.g., JSON).
581    Data {
582        /// The structured data content.
583        data: serde_json::Value,
584        /// Optional metadata associated with this part.
585        #[serde(skip_serializing_if = "Option::is_none")]
586        metadata: Option<HashMap<String, serde_json::Value>>,
587    },
588}
589
590impl Part {
591    pub fn as_data(&self) -> Option<&serde_json::Value> {
592        match self {
593            Part::Data { data, .. } => Some(data),
594            _ => None,
595        }
596    }
597}
598
599/// Represents file content, which can be provided either directly as bytes or as a URI.
600#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
601#[serde(untagged)]
602pub enum FileContent {
603    WithBytes(FileWithBytes),
604    WithUri(FileWithUri),
605}
606
607/// Represents a file with its content provided directly as a base64-encoded string.
608#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
609pub struct FileWithBytes {
610    /// The base64-encoded content of the file.
611    pub bytes: String,
612    /// The MIME type of the file (e.g., "application/pdf").
613    #[serde(skip_serializing_if = "Option::is_none", rename = "mimeType")]
614    pub mime_type: Option<String>,
615    /// An optional name for the file (e.g., "document.pdf").
616    #[serde(skip_serializing_if = "Option::is_none")]
617    pub name: Option<String>,
618}
619
620/// Represents a file with its content located at a specific URI.
621#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
622pub struct FileWithUri {
623    /// A URL pointing to the file's content.
624    pub uri: String,
625    /// The MIME type of the file (e.g., "application/pdf").
626    #[serde(skip_serializing_if = "Option::is_none", rename = "mimeType")]
627    pub mime_type: Option<String>,
628    /// An optional name for the file (e.g., "document.pdf").
629    #[serde(skip_serializing_if = "Option::is_none")]
630    pub name: Option<String>,
631}
632
633/// Represents a file, data structure, or other resource generated by an agent during a task.
634#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
635pub struct Artifact {
636    /// A unique identifier for the artifact within the scope of the task.
637    #[serde(rename = "artifactId")]
638    pub artifact_id: String,
639    /// An array of content parts that make up the artifact.
640    pub parts: Vec<Part>,
641    /// An optional, human-readable name for the artifact.
642    #[serde(skip_serializing_if = "Option::is_none")]
643    pub name: Option<String>,
644    /// An optional, human-readable description of the artifact.
645    #[serde(skip_serializing_if = "Option::is_none")]
646    pub description: Option<String>,
647    /// The URIs of extensions that are relevant to this artifact.
648    #[serde(skip_serializing_if = "Vec::is_empty", default)]
649    pub extensions: Vec<String>,
650    /// Optional metadata for extensions. The key is an extension-specific identifier.
651    #[serde(skip_serializing_if = "Option::is_none")]
652    pub metadata: Option<HashMap<String, serde_json::Value>>,
653}
654
655// ============================================================================
656// A2A Method Parameter Types (from schema)
657// ============================================================================
658
659/// Defines the parameters for a request to send a message to an agent.
660#[derive(Debug, Clone, Serialize, Deserialize)]
661pub struct MessageSendParams {
662    /// The message object being sent to the agent.
663    pub message: Message,
664    /// Optional configuration for the send request.
665    #[serde(skip_serializing_if = "Option::is_none")]
666    pub configuration: Option<MessageSendConfiguration>,
667    /// Optional metadata for extensions.
668    #[serde(skip_serializing_if = "Option::is_none")]
669    pub metadata: Option<HashMap<String, serde_json::Value>>,
670}
671
672/// Defines configuration options for a `message/send` or `message/stream` request.
673#[derive(Debug, Clone, Serialize, Deserialize, Default)]
674pub struct MessageSendConfiguration {
675    /// If true, the client will wait for the task to complete. The server may reject this if the task is long-running.
676    #[serde(skip_serializing_if = "Option::is_none")]
677    pub blocking: Option<bool>,
678    /// The number of most recent messages from the task's history to retrieve in the response.
679    #[serde(skip_serializing_if = "Option::is_none", rename = "historyLength")]
680    pub history_length: Option<i32>,
681    /// A list of output MIME types the client is prepared to accept in the response.
682    #[serde(
683        skip_serializing_if = "Vec::is_empty",
684        rename = "acceptedOutputModes",
685        default
686    )]
687    pub accepted_output_modes: Vec<String>,
688    /// Configuration for the agent to send push notifications for updates after the initial response.
689    #[serde(
690        skip_serializing_if = "Option::is_none",
691        rename = "pushNotificationConfig"
692    )]
693    pub push_notification_config: Option<PushNotificationConfig>,
694}
695
696/// Defines the configuration for setting up push notifications for task updates.
697#[derive(Debug, Clone, Serialize, Deserialize)]
698pub struct PushNotificationConfig {
699    /// The callback URL where the agent should send push notifications.
700    pub url: String,
701    /// A unique ID for the push notification configuration, set by the client.
702    #[serde(skip_serializing_if = "Option::is_none")]
703    pub id: Option<String>,
704    /// A unique token for this task or session to validate incoming push notifications.
705    #[serde(skip_serializing_if = "Option::is_none")]
706    pub token: Option<String>,
707    /// Optional authentication details for the agent to use when calling the notification URL.
708    #[serde(skip_serializing_if = "Option::is_none")]
709    pub authentication: Option<PushNotificationAuthenticationInfo>,
710}
711
712/// Defines authentication details for a push notification endpoint.
713#[derive(Debug, Clone, Serialize, Deserialize)]
714pub struct PushNotificationAuthenticationInfo {
715    /// A list of supported authentication schemes (e.g., 'Basic', 'Bearer').
716    pub schemes: Vec<String>,
717    /// Optional credentials required by the push notification endpoint.
718    #[serde(skip_serializing_if = "Option::is_none")]
719    pub credentials: Option<String>,
720}
721
722/// Defines parameters containing a task ID, used for simple task operations.
723#[derive(Debug, Clone, Serialize, Deserialize)]
724pub struct TaskIdParams {
725    /// The unique identifier of the task.
726    pub id: String,
727    /// Optional metadata associated with the request.
728    #[serde(skip_serializing_if = "Option::is_none")]
729    pub metadata: Option<HashMap<String, serde_json::Value>>,
730}
731
732/// Defines parameters for querying a task, with an option to limit history length.
733#[derive(Debug, Clone, Serialize, Deserialize)]
734pub struct TaskQueryParams {
735    /// The unique identifier of the task.
736    pub id: String,
737    /// The number of most recent messages from the task's history to retrieve.
738    #[serde(skip_serializing_if = "Option::is_none", rename = "historyLength")]
739    pub history_length: Option<i32>,
740    /// Optional metadata associated with the request.
741    #[serde(skip_serializing_if = "Option::is_none")]
742    pub metadata: Option<HashMap<String, serde_json::Value>>,
743}
744
745/// A container associating a push notification configuration with a specific task.
746#[derive(Debug, Clone, Serialize, Deserialize)]
747pub struct TaskPushNotificationConfig {
748    /// The ID of the task.
749    #[serde(rename = "taskId")]
750    pub task_id: String,
751    /// The push notification configuration for this task.
752    #[serde(rename = "pushNotificationConfig")]
753    pub push_notification_config: PushNotificationConfig,
754}
755
756/// Defines parameters for fetching a specific push notification configuration for a task.
757#[derive(Debug, Clone, Serialize, Deserialize)]
758#[serde(untagged)]
759pub enum GetTaskPushNotificationConfigParams {
760    TaskIdOnly(TaskIdParams),
761    WithConfigId(GetTaskPushNotificationConfigParamsWithId),
762}
763
764/// Parameters for fetching a push notification configuration with a specific config ID.
765#[derive(Debug, Clone, Serialize, Deserialize)]
766pub struct GetTaskPushNotificationConfigParamsWithId {
767    /// The unique identifier of the task.
768    pub id: String,
769    /// The ID of the push notification configuration to retrieve.
770    #[serde(rename = "pushNotificationConfigId")]
771    pub push_notification_config_id: String,
772    /// Optional metadata associated with the request.
773    #[serde(skip_serializing_if = "Option::is_none")]
774    pub metadata: Option<HashMap<String, serde_json::Value>>,
775}
776
777/// Defines parameters for listing all push notification configurations associated with a task.
778#[derive(Debug, Clone, Serialize, Deserialize)]
779pub struct ListTaskPushNotificationConfigParams {
780    /// The unique identifier of the task.
781    pub id: String,
782    /// Optional metadata associated with the request.
783    #[serde(skip_serializing_if = "Option::is_none")]
784    pub metadata: Option<HashMap<String, serde_json::Value>>,
785}
786
787/// Defines parameters for deleting a specific push notification configuration for a task.
788#[derive(Debug, Clone, Serialize, Deserialize)]
789pub struct DeleteTaskPushNotificationConfigParams {
790    /// The unique identifier of the task.
791    pub id: String,
792    /// The ID of the push notification configuration to delete.
793    #[serde(rename = "pushNotificationConfigId")]
794    pub push_notification_config_id: String,
795    /// Optional metadata associated with the request.
796    #[serde(skip_serializing_if = "Option::is_none")]
797    pub metadata: Option<HashMap<String, serde_json::Value>>,
798}
799
800// ============================================================================
801// A2A Request Types (from schema)
802// ============================================================================
803
804fn default_jsonrpc_version() -> String {
805    "2.0".to_string()
806}
807
808/// Represents a complete A2A JSON-RPC request, wrapping the payload with common fields.
809#[derive(Debug, Clone, Serialize, Deserialize)]
810pub struct A2ARequest {
811    /// The JSON-RPC version. Always "2.0".
812    #[serde(default = "default_jsonrpc_version")]
813    pub jsonrpc: String,
814    /// The request identifier.
815    #[serde(skip_serializing_if = "Option::is_none")]
816    pub id: Option<JSONRPCId>,
817    /// The specific A2A method and its parameters.
818    #[serde(flatten)]
819    pub payload: A2ARequestPayload,
820}
821
822/// A discriminated union of all possible A2A request payloads, tagged by the `method` field.
823#[derive(Debug, Clone, Serialize, Deserialize)]
824#[serde(tag = "method")]
825pub enum A2ARequestPayload {
826    /// Payload for the `message/send` method.
827    #[serde(rename = "message/send")]
828    SendMessage { params: MessageSendParams },
829    /// Payload for the `message/stream` method.
830    #[serde(rename = "message/stream")]
831    SendStreamingMessage { params: MessageSendParams },
832    /// Payload for the `tasks/get` method.
833    #[serde(rename = "tasks/get")]
834    GetTask { params: TaskQueryParams },
835    /// Payload for the `tasks/cancel` method.
836    #[serde(rename = "tasks/cancel")]
837    CancelTask { params: TaskIdParams },
838    /// Payload for the `tasks/pushNotificationConfig/set` method.
839    #[serde(rename = "tasks/pushNotificationConfig/set")]
840    SetTaskPushNotificationConfig { params: TaskPushNotificationConfig },
841    /// Payload for the `tasks/pushNotificationConfig/get` method.
842    #[serde(rename = "tasks/pushNotificationConfig/get")]
843    GetTaskPushNotificationConfig {
844        params: GetTaskPushNotificationConfigParams,
845    },
846    /// Payload for the `tasks/resubscribe` method.
847    #[serde(rename = "tasks/resubscribe")]
848    TaskResubscription { params: TaskIdParams },
849    /// Payload for the `tasks/pushNotificationConfig/list` method.
850    #[serde(rename = "tasks/pushNotificationConfig/list")]
851    ListTaskPushNotificationConfig {
852        params: ListTaskPushNotificationConfigParams,
853    },
854    /// Payload for the `tasks/pushNotificationConfig/delete` method.
855    #[serde(rename = "tasks/pushNotificationConfig/delete")]
856    DeleteTaskPushNotificationConfig {
857        params: DeleteTaskPushNotificationConfigParams,
858    },
859    /// Payload for the `agent/getAuthenticatedExtendedCard` method.
860    #[serde(rename = "agent/getAuthenticatedExtendedCard")]
861    GetAuthenticatedExtendedCard,
862}
863
864// ============================================================================
865// A2A Response Types (from schema)
866// ============================================================================
867
868/// The result of a `message/send` call, which can be a direct reply or a task object.
869#[derive(Debug, Clone, Serialize, Deserialize)]
870#[serde(untagged)]
871pub enum SendMessageResult {
872    Task(Task),
873    Message(Message),
874}
875
876/// Represents a successful JSON-RPC response for the `message/send` method.
877#[derive(Debug, Clone, Serialize, Deserialize)]
878pub struct SendMessageSuccessResponse {
879    pub jsonrpc: String, // Always "2.0"
880    pub result: SendMessageResult,
881    pub id: Option<JSONRPCId>,
882}
883
884/// Represents a JSON-RPC response for the `message/send` method.
885#[derive(Debug, Clone, Serialize, Deserialize)]
886#[serde(untagged)]
887pub enum SendMessageResponse {
888    Success(Box<SendMessageSuccessResponse>),
889    Error(JSONRPCErrorResponse),
890}
891
892/// The result of a `message/stream` call, which can be an initial object or a streaming event.
893#[derive(Debug, Clone, Serialize, Deserialize)]
894#[serde(untagged)]
895pub enum SendStreamingMessageResult {
896    Task(Task),
897    Message(Message),
898    TaskStatusUpdate(TaskStatusUpdateEvent),
899    TaskArtifactUpdate(TaskArtifactUpdateEvent),
900}
901
902/// Represents a successful JSON-RPC response for the `message/stream` method.
903#[derive(Debug, Clone, Serialize, Deserialize)]
904pub struct SendStreamingMessageSuccessResponse {
905    pub jsonrpc: String, // Always "2.0"
906    pub result: SendStreamingMessageResult,
907    pub id: Option<JSONRPCId>,
908}
909
910/// Represents a JSON-RPC response for the `message/stream` method.
911#[derive(Debug, Clone, Serialize, Deserialize)]
912#[serde(untagged)]
913pub enum SendStreamingMessageResponse {
914    Success(Box<SendStreamingMessageSuccessResponse>),
915    Error(JSONRPCErrorResponse),
916}
917
918/// Represents a successful JSON-RPC response for the `tasks/get` method.
919#[derive(Debug, Clone, Serialize, Deserialize)]
920pub struct GetTaskSuccessResponse {
921    pub jsonrpc: String, // Always "2.0"
922    pub result: Task,
923    pub id: Option<JSONRPCId>,
924}
925
926/// Represents a JSON-RPC response for the `tasks/get` method.
927#[derive(Debug, Clone, Serialize, Deserialize)]
928#[serde(untagged)]
929pub enum GetTaskResponse {
930    Success(Box<GetTaskSuccessResponse>),
931    Error(JSONRPCErrorResponse),
932}
933
934/// Represents a successful JSON-RPC response for the `tasks/cancel` method.
935#[derive(Debug, Clone, Serialize, Deserialize)]
936pub struct CancelTaskSuccessResponse {
937    pub jsonrpc: String, // Always "2.0"
938    pub result: Task,
939    pub id: Option<JSONRPCId>,
940}
941
942/// Represents a JSON-RPC response for the `tasks/cancel` method.
943#[derive(Debug, Clone, Serialize, Deserialize)]
944#[serde(untagged)]
945pub enum CancelTaskResponse {
946    Success(Box<CancelTaskSuccessResponse>),
947    Error(JSONRPCErrorResponse),
948}
949
950/// Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/set` method.
951#[derive(Debug, Clone, Serialize, Deserialize)]
952pub struct SetTaskPushNotificationConfigSuccessResponse {
953    pub jsonrpc: String, // Always "2.0"
954    pub result: TaskPushNotificationConfig,
955    pub id: Option<JSONRPCId>,
956}
957
958/// Represents a JSON-RPC response for the `tasks/pushNotificationConfig/set` method.
959#[derive(Debug, Clone, Serialize, Deserialize)]
960#[serde(untagged)]
961pub enum SetTaskPushNotificationConfigResponse {
962    Success(Box<SetTaskPushNotificationConfigSuccessResponse>),
963    Error(JSONRPCErrorResponse),
964}
965
966/// Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/get` method.
967#[derive(Debug, Clone, Serialize, Deserialize)]
968pub struct GetTaskPushNotificationConfigSuccessResponse {
969    pub jsonrpc: String, // Always "2.0"
970    pub result: TaskPushNotificationConfig,
971    pub id: Option<JSONRPCId>,
972}
973
974/// Represents a JSON-RPC response for the `tasks/pushNotificationConfig/get` method.
975#[derive(Debug, Clone, Serialize, Deserialize)]
976#[serde(untagged)]
977pub enum GetTaskPushNotificationConfigResponse {
978    Success(Box<GetTaskPushNotificationConfigSuccessResponse>),
979    Error(JSONRPCErrorResponse),
980}
981
982/// Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/list` method.
983#[derive(Debug, Clone, Serialize, Deserialize)]
984pub struct ListTaskPushNotificationConfigSuccessResponse {
985    pub jsonrpc: String, // Always "2.0"
986    pub result: Vec<TaskPushNotificationConfig>,
987    pub id: Option<JSONRPCId>,
988}
989
990/// Represents a JSON-RPC response for the `tasks/pushNotificationConfig/list` method.
991#[derive(Debug, Clone, Serialize, Deserialize)]
992#[serde(untagged)]
993pub enum ListTaskPushNotificationConfigResponse {
994    Success(Box<ListTaskPushNotificationConfigSuccessResponse>),
995    Error(JSONRPCErrorResponse),
996}
997
998/// Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/delete` method.
999#[derive(Debug, Clone, Serialize, Deserialize)]
1000pub struct DeleteTaskPushNotificationConfigSuccessResponse {
1001    pub jsonrpc: String, // Always "2.0"
1002    /// The result is null on successful deletion.
1003    pub result: (),
1004    pub id: Option<JSONRPCId>,
1005}
1006
1007/// Represents a JSON-RPC response for the `tasks/pushNotificationConfig/delete` method.
1008#[derive(Debug, Clone, Serialize, Deserialize)]
1009#[serde(untagged)]
1010pub enum DeleteTaskPushNotificationConfigResponse {
1011    Success(Box<DeleteTaskPushNotificationConfigSuccessResponse>),
1012    Error(JSONRPCErrorResponse),
1013}
1014
1015/// Represents a successful JSON-RPC response for the `agent/getAuthenticatedExtendedCard` method.
1016#[derive(Debug, Clone, Serialize, Deserialize)]
1017pub struct GetAuthenticatedExtendedCardSuccessResponse {
1018    pub jsonrpc: String, // Always "2.0"
1019    pub result: AgentCard,
1020    pub id: Option<JSONRPCId>,
1021}
1022
1023/// Represents a JSON-RPC response for the `agent/getAuthenticatedExtendedCard` method.
1024#[derive(Debug, Clone, Serialize, Deserialize)]
1025#[serde(untagged)]
1026pub enum GetAuthenticatedExtendedCardResponse {
1027    Success(Box<GetAuthenticatedExtendedCardSuccessResponse>),
1028    Error(JSONRPCErrorResponse),
1029}
1030
1031// ============================================================================
1032// A2A Agent Card and Discovery Types (from schema)
1033// ============================================================================
1034
1035/// Supported A2A transport protocols.
1036#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1037pub enum TransportProtocol {
1038    /// JSON-RPC 2.0 over HTTP
1039    #[serde(rename = "JSONRPC")]
1040    JsonRpc,
1041    /// gRPC over HTTP/2
1042    #[serde(rename = "GRPC")]
1043    Grpc,
1044    /// REST-style HTTP with JSON
1045    #[serde(rename = "HTTP+JSON")]
1046    HttpJson,
1047}
1048
1049impl Default for TransportProtocol {
1050    fn default() -> Self {
1051        TransportProtocol::JsonRpc
1052    }
1053}
1054
1055/// Declares a combination of a target URL and a transport protocol for interacting with the agent.
1056#[derive(Debug, Clone, Serialize, Deserialize)]
1057pub struct AgentInterface {
1058    /// The transport protocol supported at this URL.
1059    pub transport: TransportProtocol,
1060    /// The URL where this interface is available.
1061    pub url: String,
1062}
1063
1064/// A declaration of a protocol extension supported by an Agent.
1065#[derive(Debug, Clone, Serialize, Deserialize)]
1066pub struct AgentExtension {
1067    /// The unique URI identifying the extension.
1068    pub uri: String,
1069    /// A human-readable description of how this agent uses the extension.
1070    #[serde(skip_serializing_if = "Option::is_none")]
1071    pub description: Option<String>,
1072    /// If true, the client must understand and comply with the extension's requirements.
1073    #[serde(skip_serializing_if = "Option::is_none")]
1074    pub required: Option<bool>,
1075    /// Optional, extension-specific configuration parameters.
1076    #[serde(skip_serializing_if = "Option::is_none")]
1077    pub params: Option<HashMap<String, serde_json::Value>>,
1078}
1079
1080/// Defines optional capabilities supported by an agent.
1081#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1082pub struct AgentCapabilities {
1083    /// Indicates if the agent supports Server-Sent Events (SSE) for streaming responses.
1084    #[serde(skip_serializing_if = "Option::is_none")]
1085    pub streaming: Option<bool>,
1086    /// Indicates if the agent supports sending push notifications for asynchronous task updates.
1087    #[serde(skip_serializing_if = "Option::is_none", rename = "pushNotifications")]
1088    pub push_notifications: Option<bool>,
1089    /// Indicates if the agent provides a history of state transitions for a task.
1090    #[serde(
1091        skip_serializing_if = "Option::is_none",
1092        rename = "stateTransitionHistory"
1093    )]
1094    pub state_transition_history: Option<bool>,
1095    /// A list of protocol extensions supported by the agent.
1096    #[serde(skip_serializing_if = "Vec::is_empty", default)]
1097    pub extensions: Vec<AgentExtension>,
1098}
1099
1100/// Represents the service provider of an agent.
1101#[derive(Debug, Clone, Serialize, Deserialize)]
1102pub struct AgentProvider {
1103    /// The name of the agent provider's organization.
1104    pub organization: String,
1105    /// A URL for the agent provider's website or relevant documentation.
1106    pub url: String,
1107}
1108
1109/// Represents a distinct capability or function that an agent can perform.
1110#[derive(Debug, Clone, Serialize, Deserialize)]
1111pub struct AgentSkill {
1112    /// A unique identifier for the agent's skill.
1113    pub id: String,
1114    /// A human-readable name for the skill.
1115    pub name: String,
1116    /// A detailed description of the skill.
1117    pub description: String,
1118    /// A set of keywords describing the skill's capabilities.
1119    pub tags: Vec<String>,
1120    /// Example prompts or scenarios that this skill can handle.
1121    #[serde(skip_serializing_if = "Vec::is_empty", default)]
1122    pub examples: Vec<String>,
1123    /// The set of supported input MIME types for this skill, overriding the agent's defaults.
1124    #[serde(skip_serializing_if = "Vec::is_empty", rename = "inputModes", default)]
1125    pub input_modes: Vec<String>,
1126    /// The set of supported output MIME types for this skill, overriding the agent's defaults.
1127    #[serde(skip_serializing_if = "Vec::is_empty", rename = "outputModes", default)]
1128    pub output_modes: Vec<String>,
1129    /// Security schemes necessary for the agent to leverage this skill.
1130    #[serde(skip_serializing_if = "Vec::is_empty", default)]
1131    pub security: Vec<HashMap<String, Vec<String>>>,
1132}
1133
1134/// Represents a JWS signature of an AgentCard.
1135#[derive(Debug, Clone, Serialize, Deserialize)]
1136pub struct AgentCardSignature {
1137    /// The protected JWS header for the signature (Base64url-encoded).
1138    #[serde(rename = "protected")]
1139    pub protected_header: String,
1140    /// The computed signature (Base64url-encoded).
1141    pub signature: String,
1142    /// The unprotected JWS header values.
1143    #[serde(skip_serializing_if = "Option::is_none")]
1144    pub header: Option<HashMap<String, serde_json::Value>>,
1145}
1146
1147/// The AgentCard is a self-describing manifest for an agent.
1148#[derive(Debug, Clone, Serialize, Deserialize)]
1149pub struct AgentCard {
1150    /// A human-readable name for the agent.
1151    pub name: String,
1152    /// A human-readable description of the agent.
1153    pub description: String,
1154    /// The agent's own version number.
1155    pub version: String,
1156    /// The version of the A2A protocol this agent supports.
1157    #[serde(rename = "protocolVersion", default = "default_protocol_version")]
1158    pub protocol_version: String,
1159    /// The preferred endpoint URL for interacting with the agent.
1160    pub url: String,
1161    /// The transport protocol for the preferred endpoint.
1162    #[serde(rename = "preferredTransport", default)]
1163    pub preferred_transport: TransportProtocol,
1164    /// A declaration of optional capabilities supported by the agent.
1165    pub capabilities: AgentCapabilities,
1166    /// Default set of supported input MIME types for all skills.
1167    #[serde(rename = "defaultInputModes")]
1168    pub default_input_modes: Vec<String>,
1169    /// Default set of supported output MIME types for all skills.
1170    #[serde(rename = "defaultOutputModes")]
1171    pub default_output_modes: Vec<String>,
1172    /// The set of skills that the agent can perform.
1173    pub skills: Vec<AgentSkill>,
1174    /// Information about the agent's service provider.
1175    #[serde(skip_serializing_if = "Option::is_none")]
1176    pub provider: Option<AgentProvider>,
1177    /// A list of additional supported interfaces (transport and URL combinations).
1178    #[serde(
1179        skip_serializing_if = "Vec::is_empty",
1180        rename = "additionalInterfaces",
1181        default
1182    )]
1183    pub additional_interfaces: Vec<AgentInterface>,
1184    /// An optional URL to the agent's documentation.
1185    #[serde(skip_serializing_if = "Option::is_none", rename = "documentationUrl")]
1186    pub documentation_url: Option<String>,
1187    /// An optional URL to an icon for the agent.
1188    #[serde(skip_serializing_if = "Option::is_none", rename = "iconUrl")]
1189    pub icon_url: Option<String>,
1190    /// A list of security requirement objects that apply to all agent interactions.
1191    #[serde(skip_serializing_if = "Vec::is_empty", default)]
1192    pub security: Vec<HashMap<String, Vec<String>>>,
1193    /// A declaration of the security schemes available to authorize requests.
1194    #[serde(skip_serializing_if = "Option::is_none", rename = "securitySchemes")]
1195    pub security_schemes: Option<HashMap<String, SecurityScheme>>,
1196    /// JSON Web Signatures computed for this AgentCard.
1197    #[serde(skip_serializing_if = "Vec::is_empty", default)]
1198    pub signatures: Vec<AgentCardSignature>,
1199    /// If true, the agent can provide an extended agent card to authenticated users.
1200    #[serde(
1201        skip_serializing_if = "Option::is_none",
1202        rename = "supportsAuthenticatedExtendedCard"
1203    )]
1204    pub supports_authenticated_extended_card: Option<bool>,
1205}
1206
1207// Constants for type values
1208pub const PROTOCOL_VERSION: &str = "0.3.0";
1209pub const API_KEY_TYPE: &str = "apiKey";
1210pub const HTTP_TYPE: &str = "http";
1211pub const OAUTH2_TYPE: &str = "oauth2";
1212pub const OPENID_TYPE: &str = "openIdConnect";
1213pub const MUTUAL_TLS_TYPE: &str = "mutualTLS";
1214pub const TASK_KIND: &str = "task";
1215pub const MESSAGE_KIND: &str = "message";
1216pub const STATUS_UPDATE_KIND: &str = "status-update";
1217pub const ARTIFACT_UPDATE_KIND: &str = "artifact-update";
1218
1219fn default_protocol_version() -> String {
1220    PROTOCOL_VERSION.to_string()
1221}
1222
1223// ============================================================================
1224// Security and Authentication Types (from schema)
1225// ============================================================================
1226
1227/// Defines a security scheme that can be used to secure an agent's endpoints.
1228#[derive(Debug, Clone, Serialize, Deserialize)]
1229#[serde(untagged)]
1230pub enum SecurityScheme {
1231    ApiKey(APIKeySecurityScheme),
1232    Http(HTTPAuthSecurityScheme),
1233    OAuth2(Box<OAuth2SecurityScheme>),
1234    OpenIdConnect(OpenIdConnectSecurityScheme),
1235    MutualTLS(MutualTLSSecurityScheme),
1236}
1237
1238/// Defines a security scheme using an API key.
1239#[derive(Debug, Clone, Serialize, Deserialize)]
1240pub struct APIKeySecurityScheme {
1241    /// The type of the security scheme. Must be 'apiKey'.
1242    #[serde(rename = "type", default = "default_api_key_type")]
1243    pub scheme_type: String,
1244    /// The name of the header, query, or cookie parameter to be used.
1245    pub name: String,
1246    /// The location of the API key.
1247    #[serde(rename = "in")]
1248    pub location: APIKeyLocation,
1249    /// An optional description for the security scheme.
1250    #[serde(skip_serializing_if = "Option::is_none")]
1251    pub description: Option<String>,
1252}
1253
1254fn default_api_key_type() -> String {
1255    API_KEY_TYPE.to_string()
1256}
1257
1258/// The location of an API key.
1259#[derive(Debug, Clone, Serialize, Deserialize)]
1260#[serde(rename_all = "lowercase")]
1261pub enum APIKeyLocation {
1262    Query,
1263    Header,
1264    Cookie,
1265}
1266
1267/// Defines a security scheme using HTTP authentication.
1268#[derive(Debug, Clone, Serialize, Deserialize)]
1269pub struct HTTPAuthSecurityScheme {
1270    /// The type of the security scheme. Must be 'http'.
1271    #[serde(rename = "type", default = "default_http_type")]
1272    pub scheme_type: String,
1273    /// The name of the HTTP Authentication scheme to be used.
1274    pub scheme: String,
1275    /// An optional description for the security scheme.
1276    #[serde(skip_serializing_if = "Option::is_none")]
1277    pub description: Option<String>,
1278    /// A hint to the client to identify how the bearer token is formatted.
1279    #[serde(skip_serializing_if = "Option::is_none", rename = "bearerFormat")]
1280    pub bearer_format: Option<String>,
1281}
1282
1283fn default_http_type() -> String {
1284    HTTP_TYPE.to_string()
1285}
1286
1287/// Defines a security scheme using OAuth 2.0.
1288#[derive(Debug, Clone, Serialize, Deserialize)]
1289pub struct OAuth2SecurityScheme {
1290    /// The type of the security scheme. Must be 'oauth2'.
1291    #[serde(rename = "type", default = "default_oauth2_type")]
1292    pub scheme_type: String,
1293    /// Configuration information for the supported OAuth 2.0 flows.
1294    pub flows: OAuthFlows,
1295    /// An optional description for the security scheme.
1296    #[serde(skip_serializing_if = "Option::is_none")]
1297    pub description: Option<String>,
1298    /// URL to the oauth2 authorization server metadata.
1299    #[serde(skip_serializing_if = "Option::is_none", rename = "oauth2MetadataUrl")]
1300    pub oauth2_metadata_url: Option<String>,
1301}
1302
1303fn default_oauth2_type() -> String {
1304    OAUTH2_TYPE.to_string()
1305}
1306
1307/// Defines a security scheme using OpenID Connect.
1308#[derive(Debug, Clone, Serialize, Deserialize)]
1309pub struct OpenIdConnectSecurityScheme {
1310    /// The type of the security scheme. Must be 'openIdConnect'.
1311    #[serde(rename = "type", default = "default_openid_type")]
1312    pub scheme_type: String,
1313    /// The OpenID Connect Discovery URL.
1314    #[serde(rename = "openIdConnectUrl")]
1315    pub open_id_connect_url: String,
1316    /// An optional description for the security scheme.
1317    #[serde(skip_serializing_if = "Option::is_none")]
1318    pub description: Option<String>,
1319}
1320
1321fn default_openid_type() -> String {
1322    OPENID_TYPE.to_string()
1323}
1324
1325/// Defines a security scheme using mTLS authentication.
1326#[derive(Debug, Clone, Serialize, Deserialize)]
1327pub struct MutualTLSSecurityScheme {
1328    /// The type of the security scheme. Must be 'mutualTLS'.
1329    #[serde(rename = "type", default = "default_mutual_tls_type")]
1330    pub scheme_type: String,
1331    /// An optional description for the security scheme.
1332    #[serde(skip_serializing_if = "Option::is_none")]
1333    pub description: Option<String>,
1334}
1335
1336fn default_mutual_tls_type() -> String {
1337    MUTUAL_TLS_TYPE.to_string()
1338}
1339
1340/// Defines the configuration for the supported OAuth 2.0 flows.
1341#[derive(Debug, Clone, Serialize, Deserialize)]
1342pub struct OAuthFlows {
1343    /// Configuration for the OAuth Authorization Code flow.
1344    #[serde(skip_serializing_if = "Option::is_none", rename = "authorizationCode")]
1345    pub authorization_code: Option<AuthorizationCodeOAuthFlow>,
1346    /// Configuration for the OAuth Implicit flow.
1347    #[serde(skip_serializing_if = "Option::is_none")]
1348    pub implicit: Option<ImplicitOAuthFlow>,
1349    /// Configuration for the OAuth Resource Owner Password flow.
1350    #[serde(skip_serializing_if = "Option::is_none")]
1351    pub password: Option<PasswordOAuthFlow>,
1352    /// Configuration for the OAuth Client Credentials flow.
1353    #[serde(skip_serializing_if = "Option::is_none", rename = "clientCredentials")]
1354    pub client_credentials: Option<ClientCredentialsOAuthFlow>,
1355}
1356
1357/// Defines configuration details for the OAuth 2.0 Authorization Code flow.
1358#[derive(Debug, Clone, Serialize, Deserialize)]
1359pub struct AuthorizationCodeOAuthFlow {
1360    /// The authorization URL to be used for this flow.
1361    #[serde(rename = "authorizationUrl")]
1362    pub authorization_url: String,
1363    /// The token URL to be used for this flow.
1364    #[serde(rename = "tokenUrl")]
1365    pub token_url: String,
1366    /// The available scopes for the OAuth2 security scheme.
1367    pub scopes: HashMap<String, String>,
1368    /// The URL to be used for obtaining refresh tokens.
1369    #[serde(skip_serializing_if = "Option::is_none", rename = "refreshUrl")]
1370    pub refresh_url: Option<String>,
1371}
1372
1373/// Defines configuration details for the OAuth 2.0 Implicit flow.
1374#[derive(Debug, Clone, Serialize, Deserialize)]
1375pub struct ImplicitOAuthFlow {
1376    /// The authorization URL to be used for this flow.
1377    #[serde(rename = "authorizationUrl")]
1378    pub authorization_url: String,
1379    /// The available scopes for the OAuth2 security scheme.
1380    pub scopes: HashMap<String, String>,
1381    /// The URL to be used for obtaining refresh tokens.
1382    #[serde(skip_serializing_if = "Option::is_none", rename = "refreshUrl")]
1383    pub refresh_url: Option<String>,
1384}
1385
1386/// Defines configuration details for the OAuth 2.0 Resource Owner Password flow.
1387#[derive(Debug, Clone, Serialize, Deserialize)]
1388pub struct PasswordOAuthFlow {
1389    /// The token URL to be used for this flow.
1390    #[serde(rename = "tokenUrl")]
1391    pub token_url: String,
1392    /// The available scopes for the OAuth2 security scheme.
1393    pub scopes: HashMap<String, String>,
1394    /// The URL to be used for obtaining refresh tokens.
1395    #[serde(skip_serializing_if = "Option::is_none", rename = "refreshUrl")]
1396    pub refresh_url: Option<String>,
1397}
1398
1399/// Defines configuration details for the OAuth 2.0 Client Credentials flow.
1400#[derive(Debug, Clone, Serialize, Deserialize)]
1401pub struct ClientCredentialsOAuthFlow {
1402    /// The token URL to be used for this flow.
1403    #[serde(rename = "tokenUrl")]
1404    pub token_url: String,
1405    /// The available scopes for the OAuth2 security scheme.
1406    pub scopes: HashMap<String, String>,
1407    /// The URL to be used for obtaining refresh tokens.
1408    #[serde(skip_serializing_if = "Option::is_none", rename = "refreshUrl")]
1409    pub refresh_url: Option<String>,
1410}
1411
1412// ============================================================================
1413// Convenience Types
1414// ============================================================================
1415
1416/// Main agent response type that can be either a Task or Message.
1417#[derive(Debug, Clone, Serialize, Deserialize)]
1418#[serde(untagged)]
1419pub enum AgentResponse {
1420    Task(Task),
1421    Message(Message),
1422}
1423
1424// ============================================================================
1425// Streaming Event Types (from schema)
1426// ============================================================================
1427
1428/// An event sent by the agent to notify the client of a change in a task's status.
1429#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1430pub struct TaskStatusUpdateEvent {
1431    /// The type of this event. Always "status-update".
1432    #[serde(default = "default_status_update_kind")]
1433    pub kind: String,
1434    /// The ID of the task that was updated.
1435    #[serde(rename = "taskId")]
1436    pub task_id: String,
1437    /// The context ID associated with the task.
1438    #[serde(rename = "contextId")]
1439    pub context_id: String,
1440    /// The new status of the task.
1441    pub status: TaskStatus,
1442    /// If true, this is the final event in the stream for this interaction.
1443    #[serde(rename = "final")]
1444    pub is_final: bool,
1445    /// Optional metadata for extensions.
1446    #[serde(skip_serializing_if = "Option::is_none")]
1447    pub metadata: Option<HashMap<String, serde_json::Value>>,
1448}
1449
1450fn default_status_update_kind() -> String {
1451    STATUS_UPDATE_KIND.to_string()
1452}
1453
1454/// An event sent by the agent to notify the client that an artifact has been generated or updated.
1455#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1456pub struct TaskArtifactUpdateEvent {
1457    /// The type of this event. Always "artifact-update".
1458    #[serde(default = "default_artifact_update_kind")]
1459    pub kind: String,
1460    /// The ID of the task this artifact belongs to.
1461    #[serde(rename = "taskId")]
1462    pub task_id: String,
1463    /// The context ID associated with the task.
1464    #[serde(rename = "contextId")]
1465    pub context_id: String,
1466    /// The artifact that was generated or updated.
1467    pub artifact: Artifact,
1468    /// If true, the content of this artifact should be appended to a previously sent artifact with the same ID.
1469    #[serde(skip_serializing_if = "Option::is_none")]
1470    pub append: Option<bool>,
1471    /// If true, this is the final chunk of the artifact.
1472    #[serde(skip_serializing_if = "Option::is_none", rename = "lastChunk")]
1473    pub last_chunk: Option<bool>,
1474    /// Optional metadata for extensions.
1475    #[serde(skip_serializing_if = "Option::is_none")]
1476    pub metadata: Option<HashMap<String, serde_json::Value>>,
1477}
1478
1479fn default_artifact_update_kind() -> String {
1480    ARTIFACT_UPDATE_KIND.to_string()
1481}