1111from a2a .client import A2AClient , A2ACardResolver
1212from a2a .utils import AGENT_CARD_WELL_KNOWN_PATH , PREV_AGENT_CARD_WELL_KNOWN_PATH
1313from a2a .server .apps import A2AStarletteApplication
14- from a2a .types import AgentCard , SendMessageRequest , SendMessageResponse
15-
14+ from a2a .types import (
15+ AgentCard ,
16+ SendMessageRequest ,
17+ SendMessageResponse ,
18+ JSONRPCSuccessResponse ,
19+ MessageSendParams ,
20+ )
1621from agntcy_app_sdk .protocols .protocol import BaseAgentProtocol
1722from agntcy_app_sdk .transports .transport import BaseTransport , ResponseMode
1823from agntcy_app_sdk .protocols .message import Message
2429logger = get_logger (__name__ )
2530
2631
27- async def get_client_from_agent_card_url (httpx_client : httpx .AsyncClient , base_url : str ,
32+ async def get_client_from_agent_card_url (
33+ httpx_client : httpx .AsyncClient ,
34+ base_url : str ,
2835 http_kwargs : dict [str , Any ] | None = None ,
2936) -> A2AClient :
3037 """
@@ -33,20 +40,25 @@ async def get_client_from_agent_card_url(httpx_client: httpx.AsyncClient, base_u
3340 """
3441 try :
3542 agent_card : AgentCard = await A2ACardResolver (
36- httpx_client , base_url = base_url ,
43+ httpx_client ,
44+ base_url = base_url ,
3745 agent_card_path = AGENT_CARD_WELL_KNOWN_PATH ,
3846 ).get_agent_card (http_kwargs = http_kwargs )
3947 except Exception as e :
40- logger .info (f"Failed to get client from agent card url with v3 path, "
41- f"falling back to v2 path: { e } " )
48+ logger .info (
49+ f"Failed to get client from agent card url with v3 path, "
50+ f"falling back to v2 path: { e } "
51+ )
4252 try :
43- agent_card : AgentCard = await (A2ACardResolver (
44- httpx_client , base_url = base_url ,
53+ agent_card : AgentCard = await A2ACardResolver (
54+ httpx_client ,
55+ base_url = base_url ,
4556 agent_card_path = PREV_AGENT_CARD_WELL_KNOWN_PATH ,
46- ).get_agent_card (http_kwargs = http_kwargs ))
57+ ).get_agent_card (http_kwargs = http_kwargs )
4758 except Exception as e :
48- logger .error (f"Failed to get client from agent card url with v2 "
49- f"path: { e } " )
59+ logger .error (
60+ f"Failed to get client from agent card url with v2 " f"path: { e } "
61+ )
5062 raise e
5163
5264 return A2AClient (httpx_client = httpx_client , agent_card = agent_card )
@@ -77,22 +89,28 @@ async def get_client_from_agent_card_topic(
7789 try :
7890 request = Message (
7991 type = "A2ARequest" ,
80- payload = json .dumps ({"path" : AGENT_CARD_WELL_KNOWN_PATH , "method" : method }),
92+ payload = json .dumps (
93+ {"path" : AGENT_CARD_WELL_KNOWN_PATH , "method" : method }
94+ ),
8195 route_path = AGENT_CARD_WELL_KNOWN_PATH ,
82- method = method
96+ method = method ,
8397 )
8498 response = await transport .request (topic , request , ResponseMode .FIRST )
8599
86100 response .payload = json .loads (response .payload .decode ("utf-8" ))
87101 card = AgentCard .model_validate (response .payload )
88102 except Exception as e :
89- logger .info (f"A2A v3 path failed or invalid payload, falling back to v2: { e } " )
103+ logger .info (
104+ f"A2A v3 path failed or invalid payload, falling back to v2: { e } "
105+ )
90106
91107 request = Message (
92108 type = "A2ARequest" ,
93- payload = json .dumps ({"path" : PREV_AGENT_CARD_WELL_KNOWN_PATH , "method" : method }),
109+ payload = json .dumps (
110+ {"path" : PREV_AGENT_CARD_WELL_KNOWN_PATH , "method" : method }
111+ ),
94112 route_path = PREV_AGENT_CARD_WELL_KNOWN_PATH ,
95- method = method
113+ method = method ,
96114 )
97115 response = await transport .request (topic , request , ResponseMode .FIRST )
98116
@@ -203,6 +221,8 @@ async def broadcast_message(
203221 recipients : List [str ] | None = None ,
204222 broadcast_topic : str = None ,
205223 timeout : float = 30.0 ,
224+ group_chat : bool = False ,
225+ end_message : str = "work-done" ,
206226 ) -> List [SendMessageResponse ]:
207227 """
208228 Broadcast a request using the provided transport.
@@ -217,12 +237,16 @@ async def broadcast_message(
217237 if not broadcast_topic :
218238 broadcast_topic = topic
219239
240+ # determine response mode, either collect len(recipients) or group chat
241+ resp_mode = ResponseMode .GROUP if group_chat else ResponseMode .COLLECT_ALL
242+
220243 try :
221244 responses = await transport .request (
222245 broadcast_topic ,
223246 msg ,
224- response_mode = ResponseMode . COLLECT_ALL ,
247+ response_mode = resp_mode ,
225248 recipients = recipients ,
249+ end_message = end_message ,
226250 timeout = timeout ,
227251 )
228252 except Exception as e :
@@ -305,6 +329,19 @@ async def handle_message(self, message: Message) -> Message:
305329 )
306330 method = message .method
307331
332+ # check if the body is a JSONRPCSuccessResponse, and if so, convert it to a SendMessageRequest
333+ try :
334+ inner = JSONRPCSuccessResponse .model_validate_json (body )
335+ msg_params = {"message" : inner .result }
336+ request = SendMessageRequest (
337+ id = str (uuid4 ()), params = MessageSendParams (** msg_params )
338+ )
339+ body = json .dumps (
340+ request .model_dump (mode = "json" , exclude_none = True )
341+ ).encode ("utf-8" )
342+ except Exception :
343+ pass
344+
308345 headers = []
309346 for key , value in message .headers .items ():
310347 if isinstance (value , str ):
0 commit comments