Skip to content

Commit ddac0ed

Browse files
vertex-sdk-botcopybara-github
authored andcommitted
feat: update sdk to support python-a2a sdk 1.0.
fix: disable streaming check that should have already been disabled. BREAKING CHANGE: drop support for previous versions of python-a2a sdk. PiperOrigin-RevId: 890388363
1 parent 8710b02 commit ddac0ed

File tree

4 files changed

+207
-61
lines changed

4 files changed

+207
-61
lines changed

vertexai/_genai/_agent_engines_utils.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -632,9 +632,9 @@ def _generate_class_methods_spec_or_raise(
632632
class_method = _to_proto(schema_dict)
633633
class_method[_MODE_KEY_IN_SCHEMA] = mode
634634
if hasattr(agent, "agent_card"):
635-
class_method[_A2A_AGENT_CARD] = getattr(
636-
agent, "agent_card"
637-
).model_dump_json()
635+
class_method[_A2A_AGENT_CARD] = json_format.MessageToJson(
636+
getattr(agent, "agent_card")
637+
)
638638
class_methods_spec.append(class_method)
639639

640640
return class_methods_spec
@@ -1233,9 +1233,16 @@ def _upload_agent_engine(
12331233
cloudpickle.dump(agent, f)
12341234
except Exception as e:
12351235
url = "https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/develop/custom#deployment-considerations"
1236-
raise TypeError(
1237-
f"Failed to serialize agent engine. Visit {url} for details."
1238-
) from e
1236+
error_msg = f"Failed to serialize agent engine. Visit {url} for details."
1237+
if "google._upb._message" in str(e) or "Descriptor" in str(e):
1238+
error_msg += (
1239+
" This is often caused by protobuf objects (like Part, AgentCard) "
1240+
"being imported at the global module level. Please move these "
1241+
"imports inside the functions or methods where they are used. "
1242+
"Alternatively, you can import the entire module: "
1243+
"`from a2a import types`."
1244+
)
1245+
raise TypeError(error_msg) from e
12391246
with blob.open("rb") as f:
12401247
try:
12411248
_ = cloudpickle.load(f)
@@ -1795,13 +1802,6 @@ async def _method(self, **kwargs) -> Any: # type: ignore[no-untyped-def]
17951802
if not hasattr(a2a_agent_card, "preferred_transport"):
17961803
a2a_agent_card.preferred_transport = TransportProtocol.http_json
17971804

1798-
# AE cannot support streaming yet. Turn off streaming for now.
1799-
if a2a_agent_card.capabilities and a2a_agent_card.capabilities.streaming:
1800-
raise ValueError(
1801-
"Streaming is not supported in Agent Engine, please change "
1802-
"a2a_agent_card.capabilities.streaming to False."
1803-
)
1804-
18051805
if not hasattr(a2a_agent_card.capabilities, "streaming"):
18061806
a2a_agent_card.capabilities.streaming = False
18071807

vertexai/_genai/agent_engines.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,10 +1834,13 @@ def _create_config(
18341834
agent_card = getattr(agent, "agent_card")
18351835
if agent_card:
18361836
try:
1837-
agent_engine_spec["agent_card"] = agent_card.model_dump(
1838-
exclude_none=True
1837+
from google.protobuf import json_format
1838+
import json
1839+
1840+
agent_engine_spec["agent_card"] = json.loads(
1841+
json_format.MessageToJson(agent_card)
18391842
)
1840-
except TypeError as e:
1843+
except Exception as e:
18411844
raise ValueError(
18421845
f"Failed to convert agent card to dict (serialization error): {e}"
18431846
) from e

vertexai/agent_engines/_agent_engines.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -119,23 +119,28 @@
119119
try:
120120
from a2a.types import (
121121
AgentCard,
122-
TransportProtocol,
122+
AgentInterface,
123123
Message,
124124
TaskIdParams,
125125
TaskQueryParams,
126126
)
127+
from a2a.utils.constants import TransportProtocol, PROTOCOL_VERSION_CURRENT
127128
from a2a.client import ClientConfig, ClientFactory
128129

129130
AgentCard = AgentCard
131+
AgentInterface = AgentInterface
130132
TransportProtocol = TransportProtocol
133+
PROTOCOL_VERSION_CURRENT = PROTOCOL_VERSION_CURRENT
131134
Message = Message
132135
ClientConfig = ClientConfig
133136
ClientFactory = ClientFactory
134137
TaskIdParams = TaskIdParams
135138
TaskQueryParams = TaskQueryParams
136139
except (ImportError, AttributeError):
137140
AgentCard = None
141+
AgentInterface = None
138142
TransportProtocol = None
143+
PROTOCOL_VERSION_CURRENT = None
139144
Message = None
140145
ClientConfig = None
141146
ClientFactory = None
@@ -1216,9 +1221,16 @@ def _upload_agent_engine(
12161221
cloudpickle.dump(agent_engine, f)
12171222
except Exception as e:
12181223
url = "https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/develop/custom#deployment-considerations"
1219-
raise TypeError(
1220-
f"Failed to serialize agent engine. Visit {url} for details."
1221-
) from e
1224+
error_msg = f"Failed to serialize agent engine. Visit {url} for details."
1225+
if "google._upb._message" in str(e) or "Descriptor" in str(e):
1226+
error_msg += (
1227+
" This is often caused by protobuf objects (like Part, AgentCard) "
1228+
"being imported at the global module level. Please move these "
1229+
"imports inside the functions or methods where they are used. "
1230+
"Alternatively, you can import the entire module: "
1231+
"`from a2a import types as a2a_types`."
1232+
)
1233+
raise TypeError(error_msg) from e
12221234
with blob.open("rb") as f:
12231235
try:
12241236
_ = cloudpickle.load(f)
@@ -1736,16 +1748,23 @@ async def _method(self, **kwargs) -> Any:
17361748

17371749
# A2A + AE integration currently only supports Rest API.
17381750
if (
1739-
a2a_agent_card.preferred_transport
1740-
and a2a_agent_card.preferred_transport != TransportProtocol.http_json
1751+
a2a_agent_card.supported_interfaces
1752+
and a2a_agent_card.supported_interfaces[0].protocol_binding
1753+
!= TransportProtocol.HTTP_JSON
17411754
):
17421755
raise ValueError(
1743-
"Only HTTP+JSON is supported for preferred transport on agent card "
1756+
"Only HTTP+JSON is supported for primary interface on agent card "
17441757
)
17451758

1746-
# Set preferred transport to HTTP+JSON if not set.
1747-
if not hasattr(a2a_agent_card, "preferred_transport"):
1748-
a2a_agent_card.preferred_transport = TransportProtocol.http_json
1759+
# Set primary interface to HTTP+JSON if not set.
1760+
if not a2a_agent_card.supported_interfaces:
1761+
a2a_agent_card.supported_interfaces = []
1762+
a2a_agent_card.supported_interfaces.append(
1763+
AgentInterface(
1764+
protocol_binding=TransportProtocol.HTTP_JSON,
1765+
protocol_version=PROTOCOL_VERSION_CURRENT,
1766+
)
1767+
)
17491768

17501769
# AE cannot support streaming yet. Turn off streaming for now.
17511770
if a2a_agent_card.capabilities and a2a_agent_card.capabilities.streaming:
@@ -1759,12 +1778,13 @@ async def _method(self, **kwargs) -> Any:
17591778

17601779
# agent_card is set on the class_methods before set_up is invoked.
17611780
# Ensure that the agent_card url is set correctly before the client is created.
1762-
a2a_agent_card.url = f"https://{initializer.global_config.api_endpoint}/v1beta1/{self.resource_name}/a2a"
1781+
url = f"https://{initializer.global_config.api_endpoint}/v1beta1/{self.resource_name}/a2a"
1782+
a2a_agent_card.supported_interfaces[0].url = url
17631783

17641784
# Using a2a client, inject the auth token from the global config.
17651785
config = ClientConfig(
17661786
supported_transports=[
1767-
TransportProtocol.http_json,
1787+
TransportProtocol.HTTP_JSON,
17681788
],
17691789
use_client_preference=True,
17701790
httpx_client=httpx.AsyncClient(
@@ -1977,9 +1997,11 @@ def _generate_class_methods_spec_or_raise(
19771997
class_method[_MODE_KEY_IN_SCHEMA] = mode
19781998
# A2A agent card is a special case, when running in A2A mode,
19791999
if hasattr(agent_engine, "agent_card"):
1980-
class_method[_A2A_AGENT_CARD] = getattr(
1981-
agent_engine, "agent_card"
1982-
).model_dump_json()
2000+
from google.protobuf import json_format
2001+
2002+
class_method[_A2A_AGENT_CARD] = json_format.MessageToJson(
2003+
getattr(agent_engine, "agent_card")
2004+
)
19832005
class_methods_spec.append(class_method)
19842006

19852007
return class_methods_spec

0 commit comments

Comments
 (0)