|
8 | 8 |
|
9 | 9 | from google.protobuf.json_format import MessageToDict, Parse, ParseDict |
10 | 10 | from httpx_sse import SSEError, aconnect_sse |
| 11 | +from pydantic import BaseModel |
11 | 12 |
|
12 | 13 | from a2a.client.card_resolver import A2ACardResolver |
13 | 14 | from a2a.client.errors import ( |
|
22 | 23 | from a2a.types import ( |
23 | 24 | AgentCard, |
24 | 25 | GetTaskPushNotificationConfigParams, |
| 26 | + ListTasksParams, |
| 27 | + ListTasksResult, |
25 | 28 | Message, |
26 | 29 | MessageSendParams, |
27 | 30 | Task, |
|
32 | 35 | TaskStatusUpdateEvent, |
33 | 36 | ) |
34 | 37 | from a2a.utils import proto_utils |
| 38 | +from a2a.utils.constants import DEFAULT_LIST_TASKS_PAGE_SIZE |
35 | 39 | from a2a.utils.telemetry import SpanKind, trace_class |
36 | 40 |
|
37 | 41 |
|
@@ -252,6 +256,28 @@ async def get_task( |
252 | 256 | ParseDict(response_data, task) |
253 | 257 | return proto_utils.FromProto.task(task) |
254 | 258 |
|
| 259 | + async def list_tasks( |
| 260 | + self, |
| 261 | + request: ListTasksParams, |
| 262 | + *, |
| 263 | + context: ClientCallContext | None = None, |
| 264 | + ) -> ListTasksResult: |
| 265 | + """Retrieves tasks for an agent.""" |
| 266 | + _, modified_kwargs = await self._apply_interceptors( |
| 267 | + request.model_dump(mode='json', exclude_none=True), |
| 268 | + self._get_http_args(context), |
| 269 | + context, |
| 270 | + ) |
| 271 | + response_data = await self._send_get_request( |
| 272 | + '/v1/tasks', |
| 273 | + _model_to_query_params(request), |
| 274 | + modified_kwargs, |
| 275 | + ) |
| 276 | + response = a2a_pb2.ListTasksResponse() |
| 277 | + ParseDict(response_data, response) |
| 278 | + page_size = request.page_size or DEFAULT_LIST_TASKS_PAGE_SIZE |
| 279 | + return proto_utils.FromProto.list_tasks_result(response, page_size) |
| 280 | + |
255 | 281 | async def cancel_task( |
256 | 282 | self, |
257 | 283 | request: TaskIdParams, |
@@ -425,3 +451,21 @@ async def get_card( |
425 | 451 | async def close(self) -> None: |
426 | 452 | """Closes the httpx client.""" |
427 | 453 | await self.httpx_client.aclose() |
| 454 | + |
| 455 | + |
| 456 | +def _model_to_query_params(instance: BaseModel) -> dict[str, str]: |
| 457 | + data = instance.model_dump(mode='json', exclude_none=True) |
| 458 | + return _json_to_query_params(data) |
| 459 | + |
| 460 | + |
| 461 | +def _json_to_query_params(data: dict[str, Any]) -> dict[str, str]: |
| 462 | + query_dict = {} |
| 463 | + for key, value in data.items(): |
| 464 | + if isinstance(value, list): |
| 465 | + query_dict[key] = ','.join(map(str, value)) |
| 466 | + elif isinstance(value, bool): |
| 467 | + query_dict[key] = str(value).lower() |
| 468 | + else: |
| 469 | + query_dict[key] = str(value) |
| 470 | + |
| 471 | + return query_dict |
0 commit comments