feat: Add GetExtendedAgentCard Support to RequestHandlers#919
feat: Add GetExtendedAgentCard Support to RequestHandlers#919sokoliva wants to merge 18 commits intoa2aproject:1.0-devfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the management of AgentCard and its modifiers by centralizing them within the RequestHandler architecture, removing the need to pass these objects individually to gRPC, REST, and JSON-RPC handlers. It also introduces centralized capability validation using an updated validate decorator and adds a specific error for missing push notification configurations. Feedback highlights a regression in the validate decorator which now fails to correctly wrap standard coroutine functions, as well as a violation of the style guide regarding the direct raising of exception classes.
🧪 Code Coverage (vs
|
| Base | PR | Delta | |
|---|---|---|---|
| src/a2a/client/transports/http_helpers.py | 94.44% | 90.28% | 🔴 -4.17% |
| src/a2a/compat/v0_3/grpc_handler.py | 97.01% | 97.08% | 🟢 +0.07% |
| src/a2a/compat/v0_3/jsonrpc_adapter.py | 47.01% | 52.73% | 🟢 +5.71% |
| src/a2a/compat/v0_3/request_handler.py | 96.77% | 96.97% | 🟢 +0.20% |
| src/a2a/compat/v0_3/rest_adapter.py | 51.43% | 76.47% | 🟢 +25.04% |
| src/a2a/compat/v0_3/rest_handler.py | 96.67% | 96.70% | 🟢 +0.04% |
| src/a2a/server/request_handlers/default_request_handler.py | 96.66% | 95.65% | 🔴 -1.00% |
| src/a2a/server/request_handlers/grpc_handler.py | 94.61% | 94.34% | 🔴 -0.27% |
| src/a2a/server/request_handlers/request_handler.py | 92.59% | 82.19% | 🔴 -10.40% |
| src/a2a/server/routes/jsonrpc_dispatcher.py | 86.32% | 86.84% | 🟢 +0.53% |
| src/a2a/server/routes/jsonrpc_routes.py | 66.67% | 70.00% | 🟢 +3.33% |
| src/a2a/server/routes/rest_dispatcher.py | 92.43% | 94.67% | 🟢 +2.24% |
| src/a2a/utils/helpers.py | 97.19% | 96.71% | 🔴 -0.48% |
| Total | 91.56% | 91.97% | 🟢 +0.41% |
Generated by coverage-comment.yml
src/a2a/utils/helpers.py
Outdated
| finally: | ||
| await inner.aclose() | ||
|
|
||
| return async_gen_wrapper |
There was a problem hiding this comment.
This might cause a FAIL-LATE error corrupting the code behaviour, let's discuss tomorrow what could be the best way to handle this
…andle_authenticated_agent_card
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request refactors the handling of AgentCard and related modifiers by centralizing them within the DefaultRequestHandler. This simplifies the constructors of GrpcHandler, JSONRPC03Adapter, REST03Adapter, JsonRpcDispatcher, and RestDispatcher, which now receive the RequestHandler directly. The validate decorator was also improved to allow specifying custom exception types. The review highlights an issue where exception classes are instantiated before being raised, which violates a repository rule, and suggests raising the class directly. It also points out a code duplication opportunity in itk/main.py when instantiating DefaultRequestHandler and DefaultRequestHandler_extended, suggesting using a common arguments dictionary for better maintainability.
| async def GetExtendedCard( | ||
| self, | ||
| request: a2a_v0_3_pb2.GetAgentCardRequest, | ||
| context: grpc.aio.ServicerContext, | ||
| ) -> a2a_v0_3_pb2.AgentCard: | ||
| """Get the authenticated extended agent card (v0.3).""" | ||
|
|
||
| async def _handler( | ||
| server_context: ServerCallContext, | ||
| ) -> a2a_v0_3_pb2.AgentCard: | ||
| req_v03 = types_v03.GetAuthenticatedExtendedCardRequest(id=0) | ||
| res_v03 = await self.handler03.on_get_extended_agent_card( | ||
| req_v03, server_context | ||
| ) | ||
| return proto_utils.ToProto.agent_card(res_v03) | ||
|
|
||
| return await self._handle_unary( | ||
| context, _handler, a2a_v0_3_pb2.AgentCard() | ||
| ) |
There was a problem hiding this comment.
a2a_v0_3.proto does not define this method, so it is ok for v0_3/handler to not support it. In this case it is getAgentCard that will return the extendedAgentCard
| async def GetAgentCard( | ||
| self, | ||
| request: a2a_v0_3_pb2.GetAgentCardRequest, | ||
| context: grpc.aio.ServicerContext, | ||
| ) -> a2a_v0_3_pb2.AgentCard: | ||
| """Get the agent card for the agent served (v0.3).""" | ||
| card_to_serve = self.agent_card | ||
| if self.card_modifier: | ||
| card_to_serve = await maybe_await(self.card_modifier(card_to_serve)) | ||
| return proto_utils.ToProto.agent_card( | ||
| conversions.to_compat_agent_card(card_to_serve) |
There was a problem hiding this comment.
This method should be responsible of returning the extendedAgentCard in v0_3
https://a2a-protocol.org/v0.3.0/specification/#710-agentgetauthenticatedextendedcard
Let's implement it in the same way as for other transports
| self._push_config_store = push_config_store | ||
| self._push_sender = push_sender | ||
| self.extended_agent_card = extended_agent_card | ||
| self.card_modifier = card_modifier |
There was a problem hiding this comment.
this is not needed anymore (card_modifier)
| if self.agent_card.capabilities.extended_agent_card: | ||
| routes[('/v1/card', 'GET')] = functools.partial( | ||
| self._handle_request, self.handle_authenticated_agent_card | ||
| ) |
There was a problem hiding this comment.
spec says "This endpoint is available only if AgentCard.supportsAuthenticatedExtendedCard is true."
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
| if final_message | ||
| else error_type |
There was a problem hiding this comment.
final message is always defined
| if final_message | ||
| else error_type |
Description
The
GetExtendedAgentCardcapability was defined in the spec but not implemented in therequest_handler.py.Changes
on_get_extended_agent_cardto the baseRequestHandlerand its child classDefaultRequestHandler.GetExtendedAgentCardmethod implementations from the Transport layer and consequently movedAgentCardinformations from the Transport layer to theRequestHandlers.validatelogic from the transport layer to the default request handlerFixes #866 🦕