|
18 | 18 | from a2a.server.agent_execution.active_task_registry import ActiveTaskRegistry |
19 | 19 | from a2a.server.request_handlers.request_handler import ( |
20 | 20 | RequestHandler, |
| 21 | + validate, |
21 | 22 | validate_request_params, |
22 | 23 | ) |
23 | 24 | from a2a.types.a2a_pb2 import ( |
| 25 | + AgentCard, |
24 | 26 | CancelTaskRequest, |
25 | 27 | DeleteTaskPushNotificationConfigRequest, |
| 28 | + GetExtendedAgentCardRequest, |
26 | 29 | GetTaskPushNotificationConfigRequest, |
27 | 30 | GetTaskRequest, |
28 | 31 | ListTaskPushNotificationConfigsRequest, |
|
37 | 40 | TaskStatusUpdateEvent, |
38 | 41 | ) |
39 | 42 | from a2a.utils.errors import ( |
| 43 | + ExtendedAgentCardNotConfiguredError, |
40 | 44 | InternalError, |
41 | 45 | InvalidParamsError, |
42 | 46 | TaskNotCancelableError, |
43 | 47 | TaskNotFoundError, |
44 | 48 | UnsupportedOperationError, |
45 | 49 | ) |
| 50 | +from a2a.utils.helpers import maybe_await |
46 | 51 | from a2a.utils.task import ( |
47 | 52 | apply_history_length, |
48 | 53 | validate_history_length, |
|
52 | 57 |
|
53 | 58 |
|
54 | 59 | if TYPE_CHECKING: |
55 | | - from collections.abc import AsyncGenerator |
| 60 | + from collections.abc import AsyncGenerator, Awaitable, Callable |
56 | 61 |
|
57 | 62 | from a2a.server.agent_execution.active_task import ActiveTask |
58 | 63 | from a2a.server.context import ServerCallContext |
@@ -80,16 +85,25 @@ def __init__( # noqa: PLR0913 |
80 | 85 | self, |
81 | 86 | agent_executor: AgentExecutor, |
82 | 87 | task_store: TaskStore, |
| 88 | + agent_card: AgentCard, |
83 | 89 | queue_manager: Any |
84 | 90 | | None = None, # Kept for backward compat in signature |
85 | 91 | push_config_store: PushNotificationConfigStore | None = None, |
86 | 92 | push_sender: PushNotificationSender | None = None, |
87 | 93 | request_context_builder: RequestContextBuilder | None = None, |
| 94 | + extended_agent_card: AgentCard | None = None, |
| 95 | + extended_card_modifier: Callable[ |
| 96 | + [AgentCard, ServerCallContext], Awaitable[AgentCard] | AgentCard |
| 97 | + ] |
| 98 | + | None = None, |
88 | 99 | ) -> None: |
89 | 100 | self.agent_executor = agent_executor |
90 | 101 | self.task_store = task_store |
| 102 | + self._agent_card = agent_card |
91 | 103 | self._push_config_store = push_config_store |
92 | 104 | self._push_sender = push_sender |
| 105 | + self.extended_agent_card = extended_agent_card |
| 106 | + self.extended_card_modifier = extended_card_modifier |
93 | 107 | self._request_context_builder = ( |
94 | 108 | request_context_builder |
95 | 109 | or SimpleRequestContextBuilder( |
@@ -411,3 +425,28 @@ async def on_delete_task_push_notification_config( # noqa: D102 |
411 | 425 | raise TaskNotFoundError |
412 | 426 |
|
413 | 427 | await self._push_config_store.delete_info(task_id, context, config_id) |
| 428 | + |
| 429 | + @validate_request_params |
| 430 | + @validate( |
| 431 | + lambda self: self._agent_card.capabilities.extended_agent_card, |
| 432 | + error_message='The agent does not support authenticated extended cards', |
| 433 | + ) |
| 434 | + async def on_get_extended_agent_card( |
| 435 | + self, |
| 436 | + params: GetExtendedAgentCardRequest, |
| 437 | + context: ServerCallContext, |
| 438 | + ) -> AgentCard: |
| 439 | + """Default handler for 'GetExtendedAgentCard'. |
| 440 | +
|
| 441 | + Requires `capabilities.extended_agent_card` to be true. |
| 442 | + """ |
| 443 | + extended_card = self.extended_agent_card |
| 444 | + if not extended_card: |
| 445 | + raise ExtendedAgentCardNotConfiguredError |
| 446 | + |
| 447 | + if self.extended_card_modifier: |
| 448 | + return await maybe_await( |
| 449 | + self.extended_card_modifier(extended_card, context) |
| 450 | + ) |
| 451 | + |
| 452 | + return extended_card |
0 commit comments