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