On Runtime, code execution is one more set of tools, so it combines with the rest of your agent. ADK's documentation says its Gemini code execution tool "can only be used by itself within an agent instance". That tool serves Gemini 2 and later models only. Runtime's four tools sit beside your search, database and custom tools, on any model ADK can call. Each command runs in a microVM with its own Linux kernel. google-adk 2.13.0 was the current PyPI release on 25 October 2026.
ADK's code executors compared
ADK attaches a code_executor to an LlmAgent. The executor runs the code
blocks that the model writes. google-adk 2.13.0 ships these executors:
| Executor | Where code runs | Fits |
|---|---|---|
BuiltInCodeExecutor |
Gemini's own code execution; Gemini models only | Gemini agents that need nothing else |
UnsafeLocalCodeExecutor |
Your own Python process | Trusted code in development |
ContainerCodeExecutor |
A Docker container, network off and capabilities dropped by default | A host with a Docker daemon |
GkeCodeExecutor |
A Kubernetes Job per run with gVisor, or an Agent Sandbox pod | Teams already operating GKE |
VertexAiCodeExecutor |
Vertex AI's Code Interpreter Extension | Google Cloud projects |
AgentEngineSandboxCodeExecutor |
An Agent Engine code execution sandbox | Vertex AI Agent Engine deployments |
| Runtime tools (this page) | A Runtime Firecracker microVM | Any model, any host, mixed with tools |
ContainerCodeExecutor's own docstring advises that "for stronger,
kernel-level isolation of untrusted code" you prefer the GKE or Vertex
executors. A Runtime sandbox provides that kernel-level boundary without a
cluster or a Google Cloud project. Each sandbox is a virtual machine.
Add the tools
ADK wraps plain Python functions as FunctionTools. It reads the name,
docstring and type hints. So sandbox_tools(sbx) goes straight into tools.
This is the agent from the framework guide:
Terminalpip install google-adk withruntimePythonfrom google.adk.agents import Agentfrom withruntime import Sandboxfrom withruntime.tools import sandbox_toolsdef coder(model: str, sbx: Sandbox) -> Agent: return Agent( name="coder", model=model, instruction="Run code in the sandbox to answer.", tools=sandbox_tools(sbx), )Run it end to end
ADK agents run through a Runner with a session service. InMemoryRunner
provides one. It is enough for a script or a request handler:
Pythonfrom google.adk.runners import InMemoryRunnerfrom google.genai import typesfrom withruntime import Sandboxasync def solve(model: str, task: str) -> str: with Sandbox.create(timeout_seconds=900, on_lease_end="stop") as sbx: runner = InMemoryRunner(agent=coder(model, sbx), app_name="coder") session = await runner.session_service.create_session(app_name="coder", user_id="me") message = types.Content(role="user", parts=[types.Part(text=task)]) answer = "" async for event in runner.run_async(user_id="me", session_id=session.id, new_message=message): if event.is_final_response() and event.content and event.content.parts: answer = event.content.parts[0].text or "" return answercoder is the function above. The model decides when to call runtime_exec.
It reads the exit code and output. It can also write a file with
runtime_write_file before running it. On 25 September 2026, this loop ran
against google-adk 2.9.2 with a scripted model. The check confirmed that the
tool call reaches the sandbox and that its result reaches the final answer.
Mixing tools, which the built-in executor cannot do
Because the sandbox tools are ordinary function tools, one agent can hold them next to anything else:
Pythonfrom google.adk.agents import Agentfrom withruntime import Sandboxfrom withruntime.tools import sandbox_toolsdef lookup_order(order_id: str) -> dict: """Fetch an order from the shop database. Args: order_id: The order's id. """ return {"order_id": order_id, "items": 3}def support_agent(model: str, sbx: Sandbox) -> Agent: return Agent( name="support", model=model, instruction="Look orders up, then compute refunds with Python in the sandbox.", tools=[lookup_order, *sandbox_tools(sbx)], )For the ADK multi-agent patterns, a SequentialAgent or a parent with
sub_agents can give the sandbox tools to only one child. This keeps code
execution in the agent you intend.
Keys, network and spend
- Model keys stay in your process. The agent loop, and so the Gemini or other model key, runs in your application. The sandbox receives commands, not credentials.
- Tokens the code needs go in as Runtime secrets. The sandbox holds a placeholder. The host's proxy adds the real value only to HTTPS requests to the hosts that the secret names.
- Outbound traffic follows the sandbox's rules:
network={"internet": False}for pure computation, or an allow-list such as["pypi.org", "*.pythonhosted.org"]for installs. Root inside the sandbox cannot change them. - Cost ceilings: set
max_total_cost_microson each sandbox. Set a daily spending limit on the application's key, which only a person can set (read-only keys and daily limits).
Cost of a run
Runtime bills the CPU the commands use, at $0.025 per vCPU-hour, with a floor of a twentieth of a vCPU. It also bills $0.0075 per GiB-hour of memory. The default 2 vCPU, 4 GiB sandbox costs $0.03125 an hour while the agent waits on Gemini. With both CPUs busy, it costs $0.08 an hour. A thousand one-minute runs that each use 20 CPU-seconds cost $0.64 (pricing).
See also run untrusted LLM code. For the runtime behind the GKE executor's job mode, see Firecracker vs gVisor. A new account gets 100 free hours of a 1 GB machine in its first 30 days, without a card:
Terminalprintf '%s\n' 'print(sum([125, 250, 375]))' > invoice.pynpx withruntime sandboxes run -- python3 - < invoice.pyRelated
Sources
- ADK: Gemini API code execution tool, supported models and the single-tool limitation, read 25 October 2026
- ADK: GKE code executor, read 25 October 2026
- google-adk on PyPI, version 2.13.0; the executor classes, their docstrings and
InMemoryRunnerwere read from that release's source on 25 October 2026
Facts on this page were checked on 25 October 2026.