systemprompt_agent/models/a2a/protocol/
requests.rs1use super::push_notification::{
9 DeleteTaskPushNotificationConfigRequest, GetTaskPushNotificationConfigRequest,
10 ListTaskPushNotificationConfigRequest, PushNotificationConfig,
11 SetTaskPushNotificationConfigRequest, TaskResubscriptionRequest,
12};
13use crate::models::a2a::jsonrpc::{JsonRpcResponse, RequestId};
14use crate::models::a2a::{AgentCard, Task, TaskState};
15use serde::{Deserialize, Serialize};
16use systemprompt_identifiers::TaskId;
17use systemprompt_models::a2a::methods;
18
19#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
20pub struct MessageSendParams {
21 pub message: crate::models::a2a::Message,
22 pub configuration: Option<MessageSendConfiguration>,
23 pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
24}
25
26#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
27#[serde(rename_all = "camelCase")]
28pub struct MessageSendConfiguration {
29 pub accepted_output_modes: Option<Vec<String>>,
30 pub history_length: Option<u32>,
31 pub push_notification_config: Option<PushNotificationConfig>,
32 pub blocking: Option<bool>,
33}
34
35#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
36pub struct TaskQueryParams {
37 pub id: TaskId,
38 pub history_length: Option<u32>,
39}
40
41#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
42pub struct TaskIdParams {
43 pub id: TaskId,
44}
45
46#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
47pub struct A2aRequest {
48 pub method: String,
49 pub params: serde_json::Value,
50}
51
52#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
53#[serde(untagged)]
54pub enum A2aResponse {
55 SendMessage(SendMessageResponse),
56 GetTask(GetTaskResponse),
57 CancelTask(CancelTaskResponse),
58 GetAuthenticatedExtendedCard(GetAuthenticatedExtendedCardResponse),
59 SendStreamingMessage(SendStreamingMessageResponse),
60}
61
62pub type SendMessageResponse = JsonRpcResponse<Task>;
63pub type GetTaskResponse = JsonRpcResponse<Task>;
64pub type CancelTaskResponse = JsonRpcResponse<Task>;
65pub type GetAuthenticatedExtendedCardResponse = JsonRpcResponse<AgentCard>;
66pub type SendStreamingMessageResponse = JsonRpcResponse<Task>;
67
68#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
69pub struct A2aJsonRpcRequest {
70 pub jsonrpc: String,
71 pub method: String,
72 pub params: serde_json::Value,
73 pub id: RequestId,
74}
75
76impl A2aJsonRpcRequest {
77 pub fn parse_request(&self) -> Result<A2aRequestParams, A2aParseError> {
78 match self.method.as_str() {
79 methods::SEND_MESSAGE => Ok(A2aRequestParams::SendMessage(self.parse_params()?)),
80 methods::GET_TASK => Ok(A2aRequestParams::GetTask(self.parse_params()?)),
81 methods::CANCEL_TASK => Ok(A2aRequestParams::CancelTask(self.parse_params()?)),
82 methods::GET_EXTENDED_AGENT_CARD => Ok(A2aRequestParams::GetAuthenticatedExtendedCard(
83 self.parse_params()?,
84 )),
85 methods::SEND_STREAMING_MESSAGE => {
86 Ok(A2aRequestParams::SendStreamingMessage(self.parse_params()?))
87 },
88 methods::SUBSCRIBE_TO_TASK => {
89 Ok(A2aRequestParams::TaskResubscription(self.parse_params()?))
90 },
91 methods::CREATE_TASK_PUSH_NOTIFICATION_CONFIG => Ok(
92 A2aRequestParams::SetTaskPushNotificationConfig(self.parse_params()?),
93 ),
94 methods::GET_TASK_PUSH_NOTIFICATION_CONFIG => Ok(
95 A2aRequestParams::GetTaskPushNotificationConfig(self.parse_params()?),
96 ),
97 methods::LIST_TASK_PUSH_NOTIFICATION_CONFIGS => Ok(
98 A2aRequestParams::ListTaskPushNotificationConfig(self.parse_params()?),
99 ),
100 methods::DELETE_TASK_PUSH_NOTIFICATION_CONFIG => Ok(
101 A2aRequestParams::DeleteTaskPushNotificationConfig(self.parse_params()?),
102 ),
103 _ => Err(A2aParseError::UnsupportedMethod {
104 method: self.method.clone(),
105 }),
106 }
107 }
108
109 fn parse_params<T: serde::de::DeserializeOwned>(&self) -> Result<T, A2aParseError> {
110 serde_json::from_value(self.params.clone()).map_err(|e| A2aParseError::InvalidParams {
111 method: self.method.clone(),
112 error: e.to_string(),
113 })
114 }
115}
116
117#[derive(Debug, Clone, PartialEq)]
118pub enum A2aRequestParams {
119 SendMessage(MessageSendParams),
120 GetTask(TaskQueryParams),
121 CancelTask(TaskIdParams),
122 GetAuthenticatedExtendedCard(serde_json::Value),
123 SendStreamingMessage(MessageSendParams),
124 TaskResubscription(TaskResubscriptionRequest),
125 SetTaskPushNotificationConfig(SetTaskPushNotificationConfigRequest),
126 GetTaskPushNotificationConfig(GetTaskPushNotificationConfigRequest),
127 ListTaskPushNotificationConfig(ListTaskPushNotificationConfigRequest),
128 DeleteTaskPushNotificationConfig(DeleteTaskPushNotificationConfigRequest),
129}
130
131#[derive(Debug, thiserror::Error, Clone, PartialEq, Eq)]
132pub enum A2aParseError {
133 #[error("Unsupported method: {method}")]
134 UnsupportedMethod { method: String },
135
136 #[error("Invalid parameters for method '{method}': {error}")]
137 InvalidParams { method: String, error: String },
138}
139
140impl A2aResponse {
141 pub fn send_message(task: Task, id: RequestId) -> Self {
142 Self::SendMessage(JsonRpcResponse {
143 jsonrpc: "2.0".to_owned(),
144 id,
145 result: Some(task),
146 error: None,
147 })
148 }
149
150 pub fn get_task(task: Task, id: RequestId) -> Self {
151 Self::GetTask(JsonRpcResponse {
152 jsonrpc: "2.0".to_owned(),
153 id,
154 result: Some(task),
155 error: None,
156 })
157 }
158
159 pub fn cancel_task(task: Task, id: RequestId) -> Self {
160 Self::CancelTask(JsonRpcResponse {
161 jsonrpc: "2.0".to_owned(),
162 id,
163 result: Some(task),
164 error: None,
165 })
166 }
167}
168
169#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
170pub struct TaskNotFoundError {
171 pub task_id: TaskId,
172 pub message: String,
173 pub code: i32,
174 pub data: serde_json::Value,
175}
176
177#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
178pub struct TaskNotCancelableError {
179 pub task_id: TaskId,
180 pub state: TaskState,
181 pub message: String,
182 pub code: i32,
183 pub data: serde_json::Value,
184}
185
186#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
187pub struct UnsupportedOperationError {
188 pub operation: String,
189 pub message: String,
190 pub code: i32,
191 pub data: serde_json::Value,
192}