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