Skip to content

Commit 13a092f

Browse files
authored
feat: add GetExtendedAgentCardRequest as input parameter to GetExtendedAgentCard method (#767)
[Spec](https://a2a-protocol.org/latest/specification/#103-service-definition) defines `rpc GetExtendedAgentCard(GetExtendedAgentCardRequest) returns (AgentCard)`. Currently `GetExtendedAgentCard` does not take `GetExtendedAgentCardRequest` as input parameter. Fixes #766 🦕
1 parent 627ae0b commit 13a092f

9 files changed

Lines changed: 33 additions & 12 deletions

File tree

src/a2a/client/base_client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
CancelTaskRequest,
1717
CreateTaskPushNotificationConfigRequest,
1818
DeleteTaskPushNotificationConfigRequest,
19+
GetExtendedAgentCardRequest,
1920
GetTaskPushNotificationConfigRequest,
2021
GetTaskRequest,
2122
ListTaskPushNotificationConfigsRequest,
@@ -311,6 +312,7 @@ async def subscribe(
311312

312313
async def get_extended_agent_card(
313314
self,
315+
request: GetExtendedAgentCardRequest,
314316
*,
315317
context: ClientCallContext | None = None,
316318
extensions: list[str] | None = None,
@@ -322,6 +324,7 @@ async def get_extended_agent_card(
322324
client's internal state with the new card.
323325
324326
Args:
327+
request: The `GetExtendedAgentCardRequest` object specifying the request.
325328
context: The client call context.
326329
extensions: List of extensions to be activated.
327330
signature_verifier: A callable used to verify the agent card's signatures.
@@ -330,6 +333,7 @@ async def get_extended_agent_card(
330333
The `AgentCard` for the agent.
331334
"""
332335
card = await self._transport.get_extended_agent_card(
336+
request,
333337
context=context,
334338
extensions=extensions,
335339
signature_verifier=signature_verifier,

src/a2a/client/client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
CancelTaskRequest,
1818
CreateTaskPushNotificationConfigRequest,
1919
DeleteTaskPushNotificationConfigRequest,
20+
GetExtendedAgentCardRequest,
2021
GetTaskPushNotificationConfigRequest,
2122
GetTaskRequest,
2223
ListTaskPushNotificationConfigsRequest,
@@ -231,6 +232,7 @@ async def subscribe(
231232
@abstractmethod
232233
async def get_extended_agent_card(
233234
self,
235+
request: GetExtendedAgentCardRequest,
234236
*,
235237
context: ClientCallContext | None = None,
236238
extensions: list[str] | None = None,

src/a2a/client/transports/base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
CancelTaskRequest,
1111
CreateTaskPushNotificationConfigRequest,
1212
DeleteTaskPushNotificationConfigRequest,
13+
GetExtendedAgentCardRequest,
1314
GetTaskPushNotificationConfigRequest,
1415
GetTaskRequest,
1516
ListTaskPushNotificationConfigsRequest,
@@ -148,6 +149,7 @@ async def subscribe(
148149
@abstractmethod
149150
async def get_extended_agent_card(
150151
self,
152+
request: GetExtendedAgentCardRequest,
151153
*,
152154
context: ClientCallContext | None = None,
153155
extensions: list[str] | None = None,

src/a2a/client/transports/grpc.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@
2323
from a2a.client.optionals import Channel
2424
from a2a.client.transports.base import ClientTransport
2525
from a2a.extensions.common import HTTP_EXTENSION_HEADER
26-
from a2a.types import a2a_pb2, a2a_pb2_grpc
26+
from a2a.types import a2a_pb2_grpc
2727
from a2a.types.a2a_pb2 import (
2828
AgentCard,
2929
CancelTaskRequest,
3030
CreateTaskPushNotificationConfigRequest,
3131
DeleteTaskPushNotificationConfigRequest,
32+
GetExtendedAgentCardRequest,
3233
GetTaskPushNotificationConfigRequest,
3334
GetTaskRequest,
3435
ListTaskPushNotificationConfigsRequest,
@@ -276,14 +277,15 @@ async def delete_task_push_notification_config(
276277
@_handle_grpc_exception
277278
async def get_extended_agent_card(
278279
self,
280+
request: GetExtendedAgentCardRequest,
279281
*,
280282
context: ClientCallContext | None = None,
281283
extensions: list[str] | None = None,
282284
signature_verifier: Callable[[AgentCard], None] | None = None,
283285
) -> AgentCard:
284286
"""Retrieves the agent's card."""
285287
card = await self.stub.GetExtendedAgentCard(
286-
a2a_pb2.GetExtendedAgentCardRequest(),
288+
request,
287289
metadata=self._get_grpc_metadata(extensions),
288290
)
289291

src/a2a/client/transports/jsonrpc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ async def subscribe(
378378

379379
async def get_extended_agent_card(
380380
self,
381+
request: GetExtendedAgentCardRequest,
381382
*,
382383
context: ClientCallContext | None = None,
383384
extensions: list[str] | None = None,
@@ -394,7 +395,6 @@ async def get_extended_agent_card(
394395
if not card.capabilities.extended_agent_card:
395396
return card
396397

397-
request = GetExtendedAgentCardRequest()
398398
rpc_request = JSONRPC20Request(
399399
method='GetExtendedAgentCard',
400400
params=json_format.MessageToDict(request),

src/a2a/client/transports/rest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
CancelTaskRequest,
2323
CreateTaskPushNotificationConfigRequest,
2424
DeleteTaskPushNotificationConfigRequest,
25+
GetExtendedAgentCardRequest,
2526
GetTaskPushNotificationConfigRequest,
2627
GetTaskRequest,
2728
ListTaskPushNotificationConfigsRequest,
@@ -324,6 +325,7 @@ async def subscribe(
324325

325326
async def get_extended_agent_card(
326327
self,
328+
request: GetExtendedAgentCardRequest,
327329
*,
328330
context: ClientCallContext | None = None,
329331
extensions: list[str] | None = None,
@@ -340,7 +342,7 @@ async def get_extended_agent_card(
340342
if not card.capabilities.extended_agent_card:
341343
return card
342344
_, modified_kwargs = await self._apply_interceptors(
343-
{},
345+
MessageToDict(request, preserving_proto_field_name=True),
344346
modified_kwargs,
345347
context,
346348
)

tests/client/transports/test_jsonrpc_client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
AgentInterface,
2020
CancelTaskRequest,
2121
DeleteTaskPushNotificationConfigRequest,
22+
GetExtendedAgentCardRequest,
2223
GetTaskPushNotificationConfigRequest,
2324
GetTaskRequest,
2425
ListTaskPushNotificationConfigsRequest,
@@ -647,6 +648,7 @@ async def test_get_card_with_extended_card_support_with_extensions(
647648
extended_card.CopyFrom(agent_card)
648649
extended_card.name = 'Extended'
649650

651+
request = GetExtendedAgentCardRequest()
650652
rpc_response = {
651653
'id': '123',
652654
'jsonrpc': '2.0',
@@ -656,7 +658,7 @@ async def test_get_card_with_extended_card_support_with_extensions(
656658
client, '_send_request', new_callable=AsyncMock
657659
) as mock_send_request:
658660
mock_send_request.return_value = rpc_response
659-
await client.get_extended_agent_card(extensions=extensions)
661+
await client.get_extended_agent_card(request, extensions=extensions)
660662

661663
mock_send_request.assert_called_once()
662664
_, mock_kwargs = mock_send_request.call_args[0]

tests/client/transports/test_rest_client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
AgentCard,
1717
AgentInterface,
1818
DeleteTaskPushNotificationConfigRequest,
19+
GetExtendedAgentCardRequest,
1920
ListTaskPushNotificationConfigsRequest,
2021
SendMessageRequest,
2122
)
@@ -299,13 +300,14 @@ async def test_get_card_with_extended_card_support_with_extensions(
299300
) # Extended card same for mock
300301
mock_httpx_client.send.return_value = mock_response
301302

303+
request = GetExtendedAgentCardRequest()
302304
with patch.object(
303305
client, '_send_get_request', new_callable=AsyncMock
304306
) as mock_send_get_request:
305307
mock_send_get_request.return_value = json_format.MessageToDict(
306308
agent_card
307309
)
308-
await client.get_extended_agent_card(extensions=extensions)
310+
await client.get_extended_agent_card(request, extensions=extensions)
309311

310312
mock_send_get_request.assert_called_once()
311313
_, _, mock_kwargs = mock_send_get_request.call_args[0]

tests/integration/test_client_server_integration.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
AgentCard,
3131
AgentInterface,
3232
CancelTaskRequest,
33+
GetExtendedAgentCardRequest,
3334
GetTaskPushNotificationConfigRequest,
3435
GetTaskRequest,
3536
Message,
@@ -950,7 +951,9 @@ async def test_http_transport_get_authenticated_card(
950951
agent_card=agent_card,
951952
url=agent_card.supported_interfaces[0].url,
952953
)
953-
result = await transport.get_extended_agent_card()
954+
result = await transport.get_extended_agent_card(
955+
GetExtendedAgentCardRequest()
956+
)
954957
assert result.name == extended_agent_card.name
955958
assert transport.agent_card is not None
956959
assert transport.agent_card.name == extended_agent_card.name
@@ -976,7 +979,9 @@ def channel_factory(address: str) -> Channel:
976979
# The transport starts with a minimal card, get_extended_agent_card() fetches the full one
977980
assert transport.agent_card is not None
978981
transport.agent_card.capabilities.extended_agent_card = True
979-
result = await transport.get_extended_agent_card()
982+
result = await transport.get_extended_agent_card(
983+
GetExtendedAgentCardRequest()
984+
)
980985

981986
assert result.name == agent_card.name
982987
assert transport.agent_card.name == agent_card.name
@@ -1160,7 +1165,7 @@ async def test_json_transport_get_signed_extended_card(
11601165
create_key_provider(public_key), ['HS384', 'ES256']
11611166
)
11621167
result = await transport.get_extended_agent_card(
1163-
signature_verifier=signature_verifier
1168+
GetExtendedAgentCardRequest(), signature_verifier=signature_verifier
11641169
)
11651170
assert result.name == extended_agent_card.name
11661171
assert result.signatures is not None
@@ -1239,7 +1244,7 @@ async def test_json_transport_get_signed_base_and_extended_cards(
12391244

12401245
# 3. Fetch extended card via transport
12411246
result = await transport.get_extended_agent_card(
1242-
signature_verifier=signature_verifier
1247+
GetExtendedAgentCardRequest(), signature_verifier=signature_verifier
12431248
)
12441249
assert result.name == extended_agent_card.name
12451250
assert len(result.signatures) == 1
@@ -1316,7 +1321,7 @@ async def test_rest_transport_get_signed_card(
13161321

13171322
# 3. Fetch extended card
13181323
result = await transport.get_extended_agent_card(
1319-
signature_verifier=signature_verifier
1324+
GetExtendedAgentCardRequest(), signature_verifier=signature_verifier
13201325
)
13211326
assert result.name == extended_agent_card.name
13221327
assert result.signatures is not None
@@ -1378,7 +1383,7 @@ def channel_factory(address: str) -> Channel:
13781383
create_key_provider(public_key), ['HS384', 'ES256', 'RS256']
13791384
)
13801385
result = await transport.get_extended_agent_card(
1381-
signature_verifier=signature_verifier
1386+
GetExtendedAgentCardRequest(), signature_verifier=signature_verifier
13821387
)
13831388
assert result.signatures is not None
13841389
assert len(result.signatures) == 1

0 commit comments

Comments
 (0)