Skip to content

Commit 5afa9db

Browse files
google-genai-botcopybara-github
authored andcommitted
fix: Derive sandbox reasoning engine from template or snapshot name
PiperOrigin-RevId: 940679014
1 parent c922b08 commit 5afa9db

2 files changed

Lines changed: 90 additions & 6 deletions

File tree

src/google/adk/integrations/vmaas/sandbox_computer.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,26 @@ def __init__(
133133
self._search_engine_url = search_engine_url
134134
self._screen_size = (1280, 720)
135135

136-
# Extract agent engine name from sandbox_name if provided
136+
# Determine the agent engine to use. The backend requires that a sandbox
137+
# is created under the same reasoning engine that owns the
138+
# template/snapshot, so we derive the engine from whichever resource name
139+
# is provided rather than creating a new (mismatched) engine. This lets
140+
# users supply only a template or snapshot name without also pre-creating
141+
# a sandbox (BYOS). All sandbox resource names embed the engine:
142+
# projects/.../reasoningEngines/{engine}/{sandboxEnvironments|
143+
# sandboxEnvironmentTemplates|sandboxEnvironmentSnapshots}/...
137144
self._agent_engine_name = None
138-
if sandbox_name:
139-
# Format: projects/.../reasoningEngines/.../sandboxEnvironments/...
140-
parts = sandbox_name.split("/sandboxEnvironments/")
141-
if len(parts) == 2:
142-
self._agent_engine_name = parts[0]
145+
for resource_name in (
146+
sandbox_name,
147+
sandbox_template_name,
148+
sandbox_snapshot_name,
149+
):
150+
if not resource_name:
151+
continue
152+
engine_name = resource_name.split("/sandboxEnvironment")[0]
153+
if engine_name != resource_name and "/reasoningEngines/" in engine_name:
154+
self._agent_engine_name = engine_name
155+
break
143156

144157
# Vertex client (lazy-initialized if not provided)
145158
self._client = vertexai_client

tests/unittests/integrations/vmaas/test_sandbox_computer.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,77 @@ def test_init_with_byos(self):
6767
self.assertEqual(computer._agent_engine_name, agent_engine_name)
6868
self.assertEqual(computer._sandbox_name, sandbox_name)
6969

70+
def test_init_with_template_derives_agent_engine(self):
71+
"""Test agent engine is derived from sandbox_template_name."""
72+
agent_engine_name = (
73+
"projects/test/locations/us-central1/reasoningEngines/123"
74+
)
75+
template_name = f"{agent_engine_name}/sandboxEnvironmentTemplates/789"
76+
77+
computer = AgentEngineSandboxComputer(
78+
project_id=self.project_id,
79+
sandbox_template_name=template_name,
80+
)
81+
82+
# Agent engine name should be derived from the template name so the
83+
# sandbox is created under the template's reasoning engine (no BYOS).
84+
self.assertEqual(computer._agent_engine_name, agent_engine_name)
85+
self.assertEqual(computer._sandbox_template_name, template_name)
86+
87+
def test_init_with_snapshot_derives_agent_engine(self):
88+
"""Test agent engine is derived from sandbox_snapshot_name."""
89+
agent_engine_name = (
90+
"projects/test/locations/us-central1/reasoningEngines/123"
91+
)
92+
snapshot_name = f"{agent_engine_name}/sandboxEnvironmentSnapshots/789"
93+
94+
computer = AgentEngineSandboxComputer(
95+
project_id=self.project_id,
96+
sandbox_snapshot_name=snapshot_name,
97+
)
98+
99+
self.assertEqual(computer._agent_engine_name, agent_engine_name)
100+
self.assertEqual(computer._sandbox_snapshot_name, snapshot_name)
101+
102+
def test_init_sandbox_name_takes_precedence_over_template(self):
103+
"""Test sandbox_name wins when both sandbox_name and template are set."""
104+
sandbox_engine = (
105+
"projects/test/locations/us-central1/reasoningEngines/sandbox"
106+
)
107+
sandbox_name = f"{sandbox_engine}/sandboxEnvironments/456"
108+
template_name = (
109+
"projects/test/locations/us-central1/reasoningEngines/template"
110+
"/sandboxEnvironmentTemplates/789"
111+
)
112+
113+
computer = AgentEngineSandboxComputer(
114+
project_id=self.project_id,
115+
sandbox_name=sandbox_name,
116+
sandbox_template_name=template_name,
117+
)
118+
119+
self.assertEqual(computer._agent_engine_name, sandbox_engine)
120+
121+
def test_init_without_sandbox_source_has_no_agent_engine(self):
122+
"""Test agent engine is None when no sandbox source is provided."""
123+
computer = AgentEngineSandboxComputer(project_id=self.project_id)
124+
self.assertIsNone(computer._agent_engine_name)
125+
126+
async def test_ensure_agent_engine_with_template_name(self):
127+
"""Test _ensure_agent_engine reuses the template's reasoning engine."""
128+
agent_engine_name = (
129+
"projects/test/locations/us-central1/reasoningEngines/123"
130+
)
131+
template_name = f"{agent_engine_name}/sandboxEnvironmentTemplates/789"
132+
computer = AgentEngineSandboxComputer(sandbox_template_name=template_name)
133+
computer._session_state = {}
134+
135+
result = await computer._ensure_agent_engine()
136+
137+
self.assertEqual(result, agent_engine_name)
138+
# Should not have created or stored a new engine.
139+
self.assertNotIn(_STATE_KEY_AGENT_ENGINE_NAME, computer._session_state)
140+
70141
def test_init_with_vertexai_client(self):
71142
"""Test initialization with provided vertexai client."""
72143
mock_client = MagicMock()

0 commit comments

Comments
 (0)