Skip to content

feat: Add GetExtendedAgentCard Support to RequestHandlers#919

Open
sokoliva wants to merge 18 commits intoa2aproject:1.0-devfrom
sokoliva:GetExtendedAgentCard
Open

feat: Add GetExtendedAgentCard Support to RequestHandlers#919
sokoliva wants to merge 18 commits intoa2aproject:1.0-devfrom
sokoliva:GetExtendedAgentCard

Conversation

@sokoliva
Copy link
Copy Markdown
Member

@sokoliva sokoliva commented Apr 1, 2026

Description

The GetExtendedAgentCard capability was defined in the spec but not implemented in the request_handler.py.

Changes

  • Added on_get_extended_agent_card to the base RequestHandler and its child class DefaultRequestHandler.
  • Removed GetExtendedAgentCard method implementations from the Transport layer and consequently moved AgentCard informations from the Transport layer to the RequestHandlers.
  • moved validate logic from the transport layer to the default request handler

Fixes #866 🦕

@sokoliva sokoliva requested a review from a team as a code owner April 1, 2026 10:11
@sokoliva sokoliva requested a review from guglielmo-san April 1, 2026 10:11
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

🧪 Code Coverage (vs 1.0-dev)

⬇️ Download Full Report

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

finally:
await inner.aclose()

return async_gen_wrapper
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might cause a FAIL-LATE error corrupting the code behaviour, let's discuss tomorrow what could be the best way to handle this

@sokoliva sokoliva requested a review from guglielmo-san April 2, 2026 14:28
@sokoliva
Copy link
Copy Markdown
Member Author

sokoliva commented Apr 2, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +381 to +399
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()
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment on lines 344 to 354
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)
Copy link
Copy Markdown
Member

@guglielmo-san guglielmo-san Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Member

@guglielmo-san guglielmo-san Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not needed anymore (card_modifier)

Comment on lines -190 to -193
if self.agent_card.capabilities.extended_agent_card:
routes[('/v1/card', 'GET')] = functools.partial(
self._handle_request, self.handle_authenticated_agent_card
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spec says "This endpoint is available only if AgentCard.supportsAuthenticatedExtendedCard is true."

Comment on lines +34 to +36
logger = logging.getLogger(__name__)


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be removed here

@guglielmo-san guglielmo-san self-requested a review April 3, 2026 07:49
Comment on lines +379 to +380
if final_message
else error_type
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final message is always defined

Comment on lines +400 to +401
if final_message
else error_type
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants