1use super::push_notification::{
2 DeleteTaskPushNotificationConfigRequest, GetTaskPushNotificationConfigRequest,
3 ListTaskPushNotificationConfigRequest, PushNotificationConfig,
4 SetTaskPushNotificationConfigRequest, TaskResubscriptionRequest,
5};
6use crate::models::a2a::jsonrpc::{JsonRpcResponse, RequestId};
7use crate::models::a2a::{AgentCard, Task, TaskState};
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
11pub struct MessageSendParams {
12 pub message: crate::models::a2a::Message,
13 pub configuration: Option<MessageSendConfiguration>,
14 pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
15}
16
17#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
18#[serde(rename_all = "camelCase")]
19pub struct MessageSendConfiguration {
20 pub accepted_output_modes: Option<Vec<String>>,
21 pub history_length: Option<u32>,
22 pub push_notification_config: Option<PushNotificationConfig>,
23 pub blocking: Option<bool>,
24}
25
26#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
27pub struct TaskQueryParams {
28 pub id: String,
29 pub history_length: Option<u32>,
30}
31
32#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
33pub struct TaskIdParams {
34 pub id: String,
35}
36
37#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
38pub struct A2aRequest {
39 pub method: String,
40 pub params: serde_json::Value,
41}
42
43#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
44#[serde(untagged)]
45pub enum A2aResponse {
46 SendMessage(SendMessageResponse),
47 GetTask(GetTaskResponse),
48 CancelTask(CancelTaskResponse),
49 GetAuthenticatedExtendedCard(GetAuthenticatedExtendedCardResponse),
50 SendStreamingMessage(SendStreamingMessageResponse),
51}
52
53pub type SendMessageResponse = JsonRpcResponse<Task>;
54pub type GetTaskResponse = JsonRpcResponse<Task>;
55pub type CancelTaskResponse = JsonRpcResponse<Task>;
56pub type GetAuthenticatedExtendedCardResponse = JsonRpcResponse<AgentCard>;
57pub type SendStreamingMessageResponse = JsonRpcResponse<Task>;
58
59#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
60pub struct A2aJsonRpcRequest {
61 pub jsonrpc: String,
62 pub method: String,
63 pub params: serde_json::Value,
64 pub id: RequestId,
65}
66
67impl A2aJsonRpcRequest {
68 pub fn parse_request(&self) -> Result<A2aRequestParams, A2aParseError> {
69 match self.method.as_str() {
70 "message/send" => {
71 let params: MessageSendParams = serde_json::from_value(self.params.clone())
72 .map_err(|e| A2aParseError::InvalidParams {
73 method: self.method.clone(),
74 error: e.to_string(),
75 })?;
76 Ok(A2aRequestParams::SendMessage(params))
77 },
78 "tasks/get" => {
79 let params: TaskQueryParams =
80 serde_json::from_value(self.params.clone()).map_err(|e| {
81 A2aParseError::InvalidParams {
82 method: self.method.clone(),
83 error: e.to_string(),
84 }
85 })?;
86 Ok(A2aRequestParams::GetTask(params))
87 },
88 "tasks/cancel" => {
89 let params: TaskIdParams =
90 serde_json::from_value(self.params.clone()).map_err(|e| {
91 A2aParseError::InvalidParams {
92 method: self.method.clone(),
93 error: e.to_string(),
94 }
95 })?;
96 Ok(A2aRequestParams::CancelTask(params))
97 },
98 "agent/getAuthenticatedExtendedCard" => {
99 let params: serde_json::Value = serde_json::from_value(self.params.clone())
100 .map_err(|e| A2aParseError::InvalidParams {
101 method: self.method.clone(),
102 error: e.to_string(),
103 })?;
104 Ok(A2aRequestParams::GetAuthenticatedExtendedCard(params))
105 },
106 "message/stream" => {
107 let params: MessageSendParams = serde_json::from_value(self.params.clone())
108 .map_err(|e| A2aParseError::InvalidParams {
109 method: self.method.clone(),
110 error: e.to_string(),
111 })?;
112 Ok(A2aRequestParams::SendStreamingMessage(params))
113 },
114 "tasks/resubscribe" => {
115 let params: TaskResubscriptionRequest = serde_json::from_value(self.params.clone())
116 .map_err(|e| A2aParseError::InvalidParams {
117 method: self.method.clone(),
118 error: e.to_string(),
119 })?;
120 Ok(A2aRequestParams::TaskResubscription(params))
121 },
122 "tasks/pushNotificationConfig/set" => {
123 let params: SetTaskPushNotificationConfigRequest =
124 serde_json::from_value(self.params.clone()).map_err(|e| {
125 A2aParseError::InvalidParams {
126 method: self.method.clone(),
127 error: e.to_string(),
128 }
129 })?;
130 Ok(A2aRequestParams::SetTaskPushNotificationConfig(params))
131 },
132 "tasks/pushNotificationConfig/get" => {
133 let params: GetTaskPushNotificationConfigRequest =
134 serde_json::from_value(self.params.clone()).map_err(|e| {
135 A2aParseError::InvalidParams {
136 method: self.method.clone(),
137 error: e.to_string(),
138 }
139 })?;
140 Ok(A2aRequestParams::GetTaskPushNotificationConfig(params))
141 },
142 "tasks/pushNotificationConfig/list" => {
143 let params: ListTaskPushNotificationConfigRequest =
144 serde_json::from_value(self.params.clone()).map_err(|e| {
145 A2aParseError::InvalidParams {
146 method: self.method.clone(),
147 error: e.to_string(),
148 }
149 })?;
150 Ok(A2aRequestParams::ListTaskPushNotificationConfig(params))
151 },
152 "tasks/pushNotificationConfig/delete" => {
153 let params: DeleteTaskPushNotificationConfigRequest =
154 serde_json::from_value(self.params.clone()).map_err(|e| {
155 A2aParseError::InvalidParams {
156 method: self.method.clone(),
157 error: e.to_string(),
158 }
159 })?;
160 Ok(A2aRequestParams::DeleteTaskPushNotificationConfig(params))
161 },
162 _ => Err(A2aParseError::UnsupportedMethod {
163 method: self.method.clone(),
164 }),
165 }
166 }
167}
168
169#[derive(Debug, Clone, PartialEq)]
170pub enum A2aRequestParams {
171 SendMessage(MessageSendParams),
172 GetTask(TaskQueryParams),
173 CancelTask(TaskIdParams),
174 GetAuthenticatedExtendedCard(serde_json::Value),
175 SendStreamingMessage(MessageSendParams),
176 TaskResubscription(TaskResubscriptionRequest),
177 SetTaskPushNotificationConfig(SetTaskPushNotificationConfigRequest),
178 GetTaskPushNotificationConfig(GetTaskPushNotificationConfigRequest),
179 ListTaskPushNotificationConfig(ListTaskPushNotificationConfigRequest),
180 DeleteTaskPushNotificationConfig(DeleteTaskPushNotificationConfigRequest),
181}
182
183#[derive(Debug, thiserror::Error, Clone, PartialEq, Eq)]
184pub enum A2aParseError {
185 #[error("Unsupported method: {method}")]
186 UnsupportedMethod { method: String },
187
188 #[error("Invalid parameters for method '{method}': {error}")]
189 InvalidParams { method: String, error: String },
190}
191
192impl A2aResponse {
193 pub fn send_message(task: Task, id: RequestId) -> Self {
194 Self::SendMessage(JsonRpcResponse {
195 jsonrpc: "2.0".to_string(),
196 id,
197 result: Some(task),
198 error: None,
199 })
200 }
201
202 pub fn get_task(task: Task, id: RequestId) -> Self {
203 Self::GetTask(JsonRpcResponse {
204 jsonrpc: "2.0".to_string(),
205 id,
206 result: Some(task),
207 error: None,
208 })
209 }
210
211 pub fn cancel_task(task: Task, id: RequestId) -> Self {
212 Self::CancelTask(JsonRpcResponse {
213 jsonrpc: "2.0".to_string(),
214 id,
215 result: Some(task),
216 error: None,
217 })
218 }
219}
220
221#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
222pub struct TaskNotFoundError {
223 pub task_id: String,
224 pub message: String,
225 pub code: i32,
226 pub data: serde_json::Value,
227}
228
229#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
230pub struct TaskNotCancelableError {
231 pub task_id: String,
232 pub state: TaskState,
233 pub message: String,
234 pub code: i32,
235 pub data: serde_json::Value,
236}
237
238#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
239pub struct UnsupportedOperationError {
240 pub operation: String,
241 pub message: String,
242 pub code: i32,
243 pub data: serde_json::Value,
244}