|
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 A2AClientHTTPError, A2AClientJSONError |
|
29 | 30 | TaskStatusUpdateEvent, |
30 | 31 | ) |
31 | 32 | from a2a.utils import proto_utils |
| 33 | +from a2a.utils.constants import DEFAULT_LIST_TASKS_PAGE_SIZE |
32 | 34 | from a2a.utils.telemetry import SpanKind, trace_class |
33 | 35 |
|
34 | 36 |
|
@@ -231,8 +233,20 @@ async def list_tasks( |
231 | 233 | context: ClientCallContext | None = None, |
232 | 234 | ) -> ListTasksResult: |
233 | 235 | """Retrieves tasks for an agent.""" |
234 | | - # TODO: #515 - Implement method |
235 | | - raise NotImplementedError('tasks/list not implemented') |
| 236 | + _, modified_kwargs = await self._apply_interceptors( |
| 237 | + request.model_dump(mode='json', exclude_none=True), |
| 238 | + self._get_http_args(context), |
| 239 | + context, |
| 240 | + ) |
| 241 | + response_data = await self._send_get_request( |
| 242 | + '/v1/tasks', |
| 243 | + _model_to_query_params(request), |
| 244 | + modified_kwargs, |
| 245 | + ) |
| 246 | + response = a2a_pb2.ListTasksResponse() |
| 247 | + ParseDict(response_data, response) |
| 248 | + page_size = request.page_size or DEFAULT_LIST_TASKS_PAGE_SIZE |
| 249 | + return proto_utils.FromProto.list_tasks_result(response, page_size) |
236 | 250 |
|
237 | 251 | async def cancel_task( |
238 | 252 | self, |
@@ -375,3 +389,21 @@ async def get_card( |
375 | 389 | async def close(self) -> None: |
376 | 390 | """Closes the httpx client.""" |
377 | 391 | await self.httpx_client.aclose() |
| 392 | + |
| 393 | + |
| 394 | +def _model_to_query_params(instance: BaseModel) -> dict[str, str]: |
| 395 | + data = instance.model_dump(mode='json', exclude_none=True) |
| 396 | + return _json_to_query_params(data) |
| 397 | + |
| 398 | + |
| 399 | +def _json_to_query_params(data: dict[str, Any]) -> dict[str, str]: |
| 400 | + query_dict = {} |
| 401 | + for key, value in data.items(): |
| 402 | + if isinstance(value, list): |
| 403 | + query_dict[key] = ','.join(map(str, value)) |
| 404 | + elif isinstance(value, bool): |
| 405 | + query_dict[key] = str(value).lower() |
| 406 | + else: |
| 407 | + query_dict[key] = str(value) |
| 408 | + |
| 409 | + return query_dict |
0 commit comments