Skip to content

Commit cbd14eb

Browse files
Emily FengGWeale
authored andcommitted
feat: Add support for creating sandboxes from templates and snapshots
This change allows AgentEngineSandboxComputer to create new sandboxes using either a specified sandbox template or a sandbox snapshot. The environment variables VMAAS_SANDBOX_TEMPLATE_NAME and VMAAS_SANDBOX_SNAPSHOT_NAME are introduced to configure this behavior. Co-authored-by: Emily Feng <emilyfeng@google.com> Change-Id: Iebdd980a16966ba765cacbce6d63d0d5b691650a
1 parent db06416 commit cbd14eb

3 files changed

Lines changed: 54 additions & 16 deletions

File tree

contributing/samples/integrations/sandbox_computer_use/agent.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
- GOOGLE_CLOUD_PROJECT: Your GCP project ID
2525
- VMAAS_SERVICE_ACCOUNT: Your service account email
2626
- VMAAS_SANDBOX_NAME: (Optional) Existing sandbox resource name for BYOS mode
27+
- VMAAS_SANDBOX_TEMPLATE_NAME: (Optional) Sandbox template name to create a new sandbox (mutually exclusive with VMAAS_SANDBOX_NAME)
28+
- VMAAS_SANDBOX_SNAPSHOT_NAME: (Optional) Sandbox snapshot name to create a new sandbox (mutually exclusive with VMAAS_SANDBOX_NAME)
2729
2830
Usage:
2931
# Run via ADK web UI
@@ -53,12 +55,17 @@
5355
SANDBOX_NAME = os.environ.get("SANDBOX_NAME") or os.environ.get(
5456
"VMAAS_SANDBOX_NAME"
5557
)
58+
SANDBOX_TEMPLATE_NAME = os.environ.get("VMAAS_SANDBOX_TEMPLATE_NAME")
59+
SANDBOX_SNAPSHOT_NAME = os.environ.get("VMAAS_SANDBOX_SNAPSHOT_NAME")
60+
5661

5762
# Create the sandbox computer
5863
sandbox_computer = AgentEngineSandboxComputer(
5964
project_id=PROJECT_ID,
6065
service_account_email=SERVICE_ACCOUNT,
6166
sandbox_name=SANDBOX_NAME,
67+
sandbox_template_name=SANDBOX_TEMPLATE_NAME,
68+
sandbox_snapshot_name=SANDBOX_SNAPSHOT_NAME,
6269
search_engine_url="https://www.google.com",
6370
)
6471

contributing/samples/integrations/sandbox_computer_use/main.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
- GOOGLE_CLOUD_PROJECT: Your GCP project ID
2323
- VMAAS_SERVICE_ACCOUNT: Your service account email with
2424
roles/iam.serviceAccountTokenCreator permission
25+
- VMAAS_SANDBOX_NAME: (Optional) Existing sandbox resource name for BYOS mode
26+
- VMAAS_SANDBOX_TEMPLATE_NAME: (Optional) Sandbox template name to create a new sandbox (mutually exclusive with VMAAS_SANDBOX_NAME)
27+
- VMAAS_SANDBOX_SNAPSHOT_NAME: (Optional) Sandbox snapshot name to create a new sandbox (mutually exclusive with VMAAS_SANDBOX_NAME)
2528
2629
Usage:
2730
cd contributing/samples

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

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -90,32 +90,45 @@ def __init__(
9090
location: str = "us-central1",
9191
service_account_email: str | None = None,
9292
sandbox_name: str | None = None,
93+
sandbox_template_name: str | None = None,
94+
sandbox_snapshot_name: str | None = None,
9395
sandbox_ttl_seconds: int = 3600,
9496
search_engine_url: str = "https://www.google.com",
9597
vertexai_client: "vertexai.Client | None" = None,
9698
):
9799
"""Initialize the sandbox computer.
98100
99101
Args:
100-
project_id: GCP project ID. If None, uses Application Default
101-
Credentials project.
102+
project_id: GCP project ID. If None, uses Application Default Credentials
103+
project.
102104
location: Vertex AI location (default: us-central1).
103-
service_account_email: Service account email for token generation.
104-
Must have roles/iam.serviceAccountTokenCreator permission.
105-
If None, attempts to use ADC service account.
106-
sandbox_name: Existing sandbox resource name (BYOS mode). If provided,
107-
the agent engine name is extracted from it. If None, creates new
108-
agent engine and sandbox on demand.
109-
Format: projects/{project}/locations/{location}/reasoningEngines/{id}/sandboxEnvironments/{id}
105+
service_account_email: Service account email for token generation. Must
106+
have roles/iam.serviceAccountTokenCreator permission. If None, attempts
107+
to use ADC service account.
108+
sandbox_name: Existing sandbox resource name (BYOS mode). If provided, the
109+
agent engine name is extracted from it. If None, creates new agent
110+
engine and sandbox on demand.
111+
Format:
112+
projects/{project}/locations/{location}/reasoningEngines/{id}/sandboxEnvironments/{id}
113+
sandbox_template_name: Sandbox template resource name to use for creating
114+
new sandboxes. Templates allow faster creation and custom environments.
115+
Format:
116+
projects/{project}/locations/{location}/sandboxEnvironmentTemplates/{id}
117+
sandbox_snapshot_name: Sandbox snapshot resource name to use for restoring
118+
sandbox state, enabling faster startup.
119+
Format:
120+
projects/{project}/locations/{location}/reasoningEngines/{id}/sandboxEnvironmentSnapshots/{id}
110121
sandbox_ttl_seconds: TTL for auto-created sandboxes (default: 1 hour).
111122
search_engine_url: URL to navigate to for search() method.
112-
vertexai_client: Optional Vertex AI client instance. If None, creates
113-
one lazily using project_id and location.
123+
vertexai_client: Optional Vertex AI client instance. If None, creates one
124+
lazily using project_id and location.
114125
"""
115126
self._project_id = project_id
116127
self._location = location
117128
self._service_account_email = service_account_email
118129
self._sandbox_name = sandbox_name
130+
self._sandbox_template_name = sandbox_template_name
131+
self._sandbox_snapshot_name = sandbox_snapshot_name
119132
self._sandbox_ttl_seconds = sandbox_ttl_seconds
120133
self._search_engine_url = search_engine_url
121134
self._screen_size = (1280, 720)
@@ -210,13 +223,29 @@ async def _get_sandbox(self) -> tuple[str, Any]:
210223

211224
from vertexai import types
212225

226+
config = {
227+
"display_name": "adk_computer_use_sandbox",
228+
}
229+
spec = None
230+
if self._sandbox_template_name:
231+
config["sandbox_environment_template"] = self._sandbox_template_name
232+
logger.info(
233+
"Creating sandbox from template: %s", self._sandbox_template_name
234+
)
235+
elif self._sandbox_snapshot_name:
236+
config["sandbox_environment_snapshot"] = self._sandbox_snapshot_name
237+
logger.info(
238+
"Creating sandbox from snapshot: %s", self._sandbox_snapshot_name
239+
)
240+
else:
241+
spec = {"computer_use_environment": {}}
242+
logger.info("Creating sandbox with computer use environment spec")
243+
213244
operation = await asyncio.to_thread(
214245
client.agent_engines.sandboxes.create,
215-
spec={"computer_use_environment": {}},
246+
spec=spec,
216247
name=agent_engine_name,
217-
config=types.CreateAgentEngineSandboxConfig(
218-
display_name="adk_computer_use_sandbox"
219-
),
248+
config=config,
220249
)
221250

222251
sandbox_name = operation.response.name
@@ -249,7 +278,6 @@ async def _get_access_token(self, sandbox_name: str) -> str:
249278
token = await asyncio.to_thread(
250279
client.agent_engines.sandboxes.generate_access_token,
251280
service_account_email=self._service_account_email,
252-
sandbox_id=sandbox_name,
253281
timeout=_DEFAULT_TOKEN_TIMEOUT,
254282
)
255283

0 commit comments

Comments
 (0)