a2a_protocol_server/dispatch/grpc/
service.rs1use std::sync::Arc;
10
11use tonic::{Request, Response, Status};
12
13use super::helpers::{
14 decode_json, encode_json, reader_to_grpc_stream, server_error_to_status, validated_metadata,
15 GrpcStream,
16};
17use super::proto::a2a_service_server::A2aService;
18use super::proto::JsonPayload;
19use super::GrpcConfig;
20use crate::handler::{RequestHandler, SendMessageResult};
21
22pub struct GrpcServiceImpl {
27 pub(super) handler: Arc<RequestHandler>,
28 pub(super) config: GrpcConfig,
29}
30
31#[tonic::async_trait]
32impl A2aService for GrpcServiceImpl {
33 async fn send_message(
36 &self,
37 request: Request<JsonPayload>,
38 ) -> Result<Response<JsonPayload>, Status> {
39 let headers = validated_metadata(request.metadata())?;
40 let params = decode_json(request.get_ref())?;
41 match self
42 .handler
43 .on_send_message(params, false, Some(&headers))
44 .await
45 {
46 Ok(SendMessageResult::Response(resp)) => Ok(Response::new(encode_json(&resp)?)),
47 Ok(SendMessageResult::Stream(_)) => Err(Status::internal(
48 "unexpected stream response for unary call",
49 )),
50 Err(e) => Err(server_error_to_status(&e)),
51 }
52 }
53
54 type SendStreamingMessageStream = GrpcStream;
55
56 async fn send_streaming_message(
57 &self,
58 request: Request<JsonPayload>,
59 ) -> Result<Response<Self::SendStreamingMessageStream>, Status> {
60 let headers = validated_metadata(request.metadata())?;
61 let params = decode_json(request.get_ref())?;
62 match self
63 .handler
64 .on_send_message(params, true, Some(&headers))
65 .await
66 {
67 Ok(SendMessageResult::Stream(reader)) => {
68 let stream = reader_to_grpc_stream(reader, self.config.stream_channel_capacity);
69 Ok(Response::new(stream))
70 }
71 Ok(SendMessageResult::Response(resp)) => {
72 let payload = encode_json(&resp)?;
74 let stream = Box::pin(tokio_stream::once(Ok(payload)));
75 Ok(Response::new(stream as GrpcStream))
76 }
77 Err(e) => Err(server_error_to_status(&e)),
78 }
79 }
80
81 async fn get_task(
84 &self,
85 request: Request<JsonPayload>,
86 ) -> Result<Response<JsonPayload>, Status> {
87 let headers = validated_metadata(request.metadata())?;
88 let params = decode_json(request.get_ref())?;
89 match self.handler.on_get_task(params, Some(&headers)).await {
90 Ok(task) => Ok(Response::new(encode_json(&task)?)),
91 Err(e) => Err(server_error_to_status(&e)),
92 }
93 }
94
95 async fn list_tasks(
96 &self,
97 request: Request<JsonPayload>,
98 ) -> Result<Response<JsonPayload>, Status> {
99 let headers = validated_metadata(request.metadata())?;
100 let params = decode_json(request.get_ref())?;
101 match self.handler.on_list_tasks(params, Some(&headers)).await {
102 Ok(resp) => Ok(Response::new(encode_json(&resp)?)),
103 Err(e) => Err(server_error_to_status(&e)),
104 }
105 }
106
107 async fn cancel_task(
108 &self,
109 request: Request<JsonPayload>,
110 ) -> Result<Response<JsonPayload>, Status> {
111 let headers = validated_metadata(request.metadata())?;
112 let params = decode_json(request.get_ref())?;
113 match self.handler.on_cancel_task(params, Some(&headers)).await {
114 Ok(task) => Ok(Response::new(encode_json(&task)?)),
115 Err(e) => Err(server_error_to_status(&e)),
116 }
117 }
118
119 type SubscribeToTaskStream = GrpcStream;
120
121 async fn subscribe_to_task(
122 &self,
123 request: Request<JsonPayload>,
124 ) -> Result<Response<Self::SubscribeToTaskStream>, Status> {
125 let headers = validated_metadata(request.metadata())?;
126 let params = decode_json(request.get_ref())?;
127 match self.handler.on_resubscribe(params, Some(&headers)).await {
128 Ok(reader) => {
129 let stream = reader_to_grpc_stream(reader, self.config.stream_channel_capacity);
130 Ok(Response::new(stream))
131 }
132 Err(e) => Err(server_error_to_status(&e)),
133 }
134 }
135
136 async fn create_task_push_notification_config(
139 &self,
140 request: Request<JsonPayload>,
141 ) -> Result<Response<JsonPayload>, Status> {
142 let headers = validated_metadata(request.metadata())?;
143 let config = decode_json(request.get_ref())?;
144 match self
145 .handler
146 .on_set_push_config(config, Some(&headers))
147 .await
148 {
149 Ok(cfg) => Ok(Response::new(encode_json(&cfg)?)),
150 Err(e) => Err(server_error_to_status(&e)),
151 }
152 }
153
154 async fn get_task_push_notification_config(
155 &self,
156 request: Request<JsonPayload>,
157 ) -> Result<Response<JsonPayload>, Status> {
158 let headers = validated_metadata(request.metadata())?;
159 let params = decode_json(request.get_ref())?;
160 match self
161 .handler
162 .on_get_push_config(params, Some(&headers))
163 .await
164 {
165 Ok(cfg) => Ok(Response::new(encode_json(&cfg)?)),
166 Err(e) => Err(server_error_to_status(&e)),
167 }
168 }
169
170 async fn list_task_push_notification_configs(
171 &self,
172 request: Request<JsonPayload>,
173 ) -> Result<Response<JsonPayload>, Status> {
174 let headers = validated_metadata(request.metadata())?;
175 let params: a2a_protocol_types::params::ListPushConfigsParams =
176 decode_json(request.get_ref())?;
177 match self
178 .handler
179 .on_list_push_configs(¶ms.task_id, params.tenant.as_deref(), Some(&headers))
180 .await
181 {
182 Ok(configs) => {
183 let resp = a2a_protocol_types::responses::ListPushConfigsResponse {
184 configs,
185 next_page_token: None,
186 };
187 Ok(Response::new(encode_json(&resp)?))
188 }
189 Err(e) => Err(server_error_to_status(&e)),
190 }
191 }
192
193 async fn delete_task_push_notification_config(
194 &self,
195 request: Request<JsonPayload>,
196 ) -> Result<Response<JsonPayload>, Status> {
197 let headers = validated_metadata(request.metadata())?;
198 let params = decode_json(request.get_ref())?;
199 match self
200 .handler
201 .on_delete_push_config(params, Some(&headers))
202 .await
203 {
204 Ok(()) => Ok(Response::new(encode_json(&serde_json::json!({}))?)),
205 Err(e) => Err(server_error_to_status(&e)),
206 }
207 }
208
209 async fn get_extended_agent_card(
212 &self,
213 request: Request<JsonPayload>,
214 ) -> Result<Response<JsonPayload>, Status> {
215 let headers = validated_metadata(request.metadata())?;
216 match self
217 .handler
218 .on_get_extended_agent_card(Some(&headers))
219 .await
220 {
221 Ok(card) => Ok(Response::new(encode_json(&card)?)),
222 Err(e) => Err(server_error_to_status(&e)),
223 }
224 }
225}