@@ -87,7 +87,8 @@ def create_agent_card(
8787 provided.
8888 """
8989 # pylint: disable=g-import-not-at-top
90- from a2a .types import AgentCard , AgentCapabilities , TransportProtocol
90+ from a2a .types import AgentCard , AgentCapabilities , AgentInterface
91+ from a2a .utils .constants import TransportProtocol , PROTOCOL_VERSION_CURRENT
9192
9293 # Check if a dictionary was provided.
9394 if agent_card :
@@ -98,14 +99,18 @@ def create_agent_card(
9899 return AgentCard (
99100 name = agent_name ,
100101 description = description ,
101- url = "http://localhost:9999/" ,
102102 version = "1.0.0" ,
103103 default_input_modes = default_input_modes or ["text/plain" ],
104104 default_output_modes = default_output_modes or ["application/json" ],
105- capabilities = AgentCapabilities (streaming = streaming ),
105+ capabilities = AgentCapabilities (streaming = streaming , extended_agent_card = True ),
106106 skills = skills ,
107- preferred_transport = TransportProtocol .http_json , # Http Only.
108- supports_authenticated_extended_card = True ,
107+ supported_interfaces = [
108+ AgentInterface (
109+ url = "http://localhost:9999/" ,
110+ protocol_binding = TransportProtocol .HTTP_JSON ,
111+ protocol_version = PROTOCOL_VERSION_CURRENT ,
112+ )
113+ ],
109114 )
110115
111116 # Raise an error if insufficient data is provided.
@@ -181,15 +186,18 @@ def __init__(
181186 """Initializes the A2A agent."""
182187 # pylint: disable=g-import-not-at-top
183188 from google .cloud .aiplatform import initializer
184- from a2a .types import TransportProtocol
185-
186- if (
187- agent_card .preferred_transport
188- and agent_card .preferred_transport != TransportProtocol .http_json
189- ):
190- raise ValueError (
191- "Only HTTP+JSON is supported for preferred transport on agent card "
192- )
189+ from a2a .utils .constants import TransportProtocol
190+
191+ if agent_card .supported_interfaces :
192+ has_http_transport = False
193+ for interface in agent_card .supported_interfaces :
194+ if interface .protocol_binding == TransportProtocol .HTTP_JSON :
195+ has_http_transport = True
196+ break
197+ if not has_http_transport :
198+ raise ValueError (
199+ "Only HTTP+JSON is supported for preferred transport on agent card "
200+ )
193201
194202 self ._tmpl_attrs : dict [str , Any ] = {
195203 "project" : initializer .global_config .project ,
@@ -244,7 +252,20 @@ def set_up(self):
244252 agent_engine_id = os .getenv ("GOOGLE_CLOUD_AGENT_ENGINE_ID" , "test-agent-engine" )
245253 version = "v1beta1"
246254
247- self .agent_card .url = f"https://{ location } -aiplatform.googleapis.com/{ version } /projects/{ project } /locations/{ location } /reasoningEngines/{ agent_engine_id } /a2a"
255+ new_url = f"https://{ location } -aiplatform.googleapis.com/{ version } /projects/{ project } /locations/{ location } /reasoningEngines/{ agent_engine_id } /a2a"
256+ if not self .agent_card .supported_interfaces :
257+ from a2a .types import AgentInterface
258+ from a2a .utils .constants import TransportProtocol , PROTOCOL_VERSION_CURRENT
259+
260+ self .agent_card .supported_interfaces .append (
261+ AgentInterface (
262+ url = new_url ,
263+ protocol_binding = TransportProtocol .HTTP_JSON ,
264+ protocol_version = PROTOCOL_VERSION_CURRENT ,
265+ )
266+ )
267+ else :
268+ self .agent_card .supported_interfaces [0 ].url = new_url
248269 self ._tmpl_attrs ["agent_card" ] = self .agent_card
249270
250271 # Create the agent executor if a builder is provided.
@@ -339,8 +360,8 @@ def register_operations(self) -> Dict[str, List[str]]:
339360 }
340361 if self .agent_card .capabilities and self .agent_card .capabilities .streaming :
341362 routes ["a2a_extension" ].append ("on_message_send_stream" )
342- routes ["a2a_extension" ].append ("on_resubscribe_to_task " )
343- if self .agent_card .supports_authenticated_extended_card :
363+ routes ["a2a_extension" ].append ("on_subscribe_to_task " )
364+ if self .agent_card .capabilities and self . agent_card . capabilities . extended_agent_card :
344365 routes ["a2a_extension" ].append ("handle_authenticated_agent_card" )
345366 return routes
346367
@@ -353,11 +374,52 @@ async def on_message_send_stream(
353374 async for chunk in self .rest_handler .on_message_send_stream (request , context ):
354375 yield chunk
355376
356- async def on_resubscribe_to_task (
377+ async def on_subscribe_to_task (
357378 self ,
358379 request : "Request" ,
359380 context : "ServerCallContext" ,
360381 ) -> AsyncIterator [str ]:
361382 """Handles A2A task resubscription requests via SSE."""
362- async for chunk in self .rest_handler .on_resubscribe_to_task (request , context ):
383+ async for chunk in self .rest_handler .on_subscribe_to_task (request , context ):
363384 yield chunk
385+
386+ def __getstate__ (self ):
387+ """Serializes the A2A agent for pickling."""
388+ from google .protobuf import json_format
389+ import json
390+
391+ state = self .__dict__ .copy ()
392+
393+ def _to_dict_if_proto (obj ):
394+ if hasattr (obj , "DESCRIPTOR" ):
395+ return {"__protobuf_AgentCard__" : json .loads (json_format .MessageToJson (obj ))}
396+ return obj
397+
398+ state ["agent_card" ] = _to_dict_if_proto (state .get ("agent_card" ))
399+ if "_tmpl_attrs" in state :
400+ tmpl_attrs = state ["_tmpl_attrs" ].copy ()
401+ tmpl_attrs ["agent_card" ] = _to_dict_if_proto (tmpl_attrs .get ("agent_card" ))
402+ tmpl_attrs ["extended_agent_card" ] = _to_dict_if_proto (tmpl_attrs .get ("extended_agent_card" ))
403+ state ["_tmpl_attrs" ] = tmpl_attrs
404+
405+ return state
406+
407+ def __setstate__ (self , state ):
408+ """Deserializes the A2A agent for unpickling."""
409+ from google .protobuf import json_format
410+ from a2a .types import AgentCard
411+
412+ def _from_dict_if_proto (obj ):
413+ if isinstance (obj , dict ) and "__protobuf_AgentCard__" in obj :
414+ agent_card = AgentCard ()
415+ json_format .ParseDict (obj ["__protobuf_AgentCard__" ], agent_card )
416+ return agent_card
417+ return obj
418+
419+ state ["agent_card" ] = _from_dict_if_proto (state .get ("agent_card" ))
420+ if "_tmpl_attrs" in state :
421+ state ["_tmpl_attrs" ]["agent_card" ] = _from_dict_if_proto (state ["_tmpl_attrs" ].get ("agent_card" ))
422+ state ["_tmpl_attrs" ]["extended_agent_card" ] = _from_dict_if_proto (state ["_tmpl_attrs" ].get ("extended_agent_card" ))
423+
424+ self .__dict__ .update (state )
425+
0 commit comments