# Google ADK code execution in a secure sandbox, with any model Give an ADK agent Runtime's sandbox functions as tools; ADK wraps plain functions, and the code runs in a Firecracker microVM. **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", and it 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, and each command runs in a microVM with its own Linux kernel. The median sandbox ran its first Python command 351 ms after the create request on 24 September 2026. google-adk 2.9.2 was the current PyPI release on 25 September 2026. ## ADK's code executors compared ADK attaches a `code_executor` to an `LlmAgent`, and runs code blocks the model writes. google-adk 2.9.2 ships these: | 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 gives 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 `FunctionTool`s, reading the name, docstring and type hints, so `sandbox_tools(sbx)` goes straight into `tools`. This is the agent from the [framework guide](/docs/frameworks#google-adk): ```bash no-run pip install google-adk withruntime ``` ```python check from google.adk.agents import Agent from withruntime import Sandbox from withruntime.tools import sandbox_tools def 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, which is enough for a script or a request handler: ```python check from google.adk.runners import InMemoryRunner from google.genai import types from withruntime import Sandbox async 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 answer ``` `coder` is the function above. The model decides when to call `runtime_exec`, reads the exit code and output, and can write a file with `runtime_write_file` before running it. This loop was run on 25 September 2026 against google-adk 2.9.2 with a scripted model, to check that the tool call reaches the sandbox and 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: ```python check from google.adk.agents import Agent from withruntime import Sandbox from withruntime.tools import sandbox_tools def 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 only one child the sandbox tools, which 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](/docs/security#secrets-sandboxes-never-see). The sandbox holds a placeholder; the host's proxy adds the real value only on HTTPS requests to the hosts 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:** `max_cost_micros` on each create, and a daily spending limit on the application's key that only a person can set ([read-only keys and daily limits](/docs/security#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, plus $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, and $0.08 with both CPUs busy. A thousand one-minute runs that each use 20 CPU-seconds cost $0.64 ([pricing](/docs/pricing)). See also [run untrusted LLM code](/use-cases/run-untrusted-llm-code) and, for the runtime behind the GKE executor's job mode, [Firecracker vs gVisor](/compare/firecracker-vs-gvisor). New accounts get 50 free sandbox hours, no card: ```bash no-run npx withruntime sandbox run --trial -- python3 -c 'print(6 * 7)' ``` ## Related - [LLM tool use in a sandbox](/use-cases/llm-tool-use-sandbox) - [Gemini API code execution in a sandbox](/integrations/gemini-api) - [What is tool calling?](/glossary/tool-calling) ## Sources - [ADK: Gemini API code execution tool](https://adk.dev/integrations/code-execution/), supported models and the single-tool limitation, read 25 September 2026 - [ADK: GKE code executor](https://adk.dev/integrations/gke-code-executor/), read 25 September 2026 - [google-adk on PyPI](https://pypi.org/project/google-adk/), version 2.9.2; the executor classes, their docstrings and `InMemoryRunner` were read from that release's source on 25 September 2026 Facts on this page were checked on 25 September 2026.