a2a docsreferencesandbox

a2a_pack.sandbox

Code-execution sandbox surface available to agents via ctx.sandbox.

The abstract :class:SandboxClient is what agent code programs against. The runtime layer (host-side microsandbox + FUSE-mounted MinIO, in-cluster DaemonSet, hosted SaaS) supplies a concrete implementation.

The sandbox is general-purpose code execution, not Python-only. Agents can:

  • run arbitrary shell pipelines: await ctx.sandbox.run_shell("git clone … && cargo build")
  • exec a binary with explicit args (no shell parsing): await sb.exec("/usr/bin/git", ["clone", url])
  • pick any OCI image: run_shell("npx @openai/codex …", image="node:20-slim")

run_python is just a convenience for the common Python-snippet case.

Why an abstract here when microsandbox itself already has a Python SDK? The platform owns the policy layer — bucket selection, network egress, write-path restrictions, resource caps, audit logging. Agents must depend on the policy-respecting surface, not on the raw SDK, so the same agent code runs unchanged across local dev / cluster / hosted environments.

ExecResult (class)

ExecResult(stdout: 'str', stderr: 'str' = '', exit_code: 'int' = 0, truncated: 'bool' = False) -> None

Result of a command run inside a sandbox.

__init__ (method)

__init__(self, stdout: 'str', stderr: 'str' = '', exit_code: 'int' = 0, truncated: 'bool' = False) -> None

Initialize self. See help(type(self)) for accurate signature.

SandboxClient (class)

SandboxClient()

Negotiation surface handed to agents via ctx.sandbox.

create (method)

create(self, spec: 'SandboxSpec') -> 'SandboxHandle'

(no docstring)

get (method)

get(self, name: 'str') -> 'SandboxHandle'

(no docstring)

list (method)

list(self) -> 'list[str]'

(no docstring)

remove (method)

remove(self, name: 'str') -> 'None'

(no docstring)

run_python (method)

run_python(self, code: 'str', *, image: 'str' = 'python:3.11-slim', **kwargs: 'Any') -> 'ExecResult'

Convenience: spin a one-shot sandbox, run inline Python, tear down.

Equivalent to create(SandboxSpec(image=image)).exec("python", ["-c", code]). Use the lower-level surface when you need persistence, multiple commands, or non-Python tools.

run_shell (method)

run_shell(self, script: 'str', *, image: 'str' = 'python:3.11-slim', **kwargs: 'Any') -> 'ExecResult'

Convenience: spin a one-shot sandbox, run an arbitrary shell script, tear down.

Pass image= to pick the toolchain (e.g. "node:20-slim" for npm-based tools like codex, "rust:1-slim" for cargo, "alpine/git" for plain git ops). The default python:3.11-slim already has bash/coreutils/curl/git so most one-liners just work.

SandboxHandle (class)

SandboxHandle()

Live handle to a running sandbox VM.

exec (method)

exec(self, cmd: 'str', args: 'Sequence[str] | None' = None, *, timeout: 'float | None' = None) -> 'ExecResult'

(no docstring)

kill (method)

kill(self) -> 'None'

(no docstring)

logs (method)

logs(self, *, tail: 'int | None' = None) -> 'str'

(no docstring)

shell (method)

shell(self, script: 'str', *, timeout: 'float | None' = None) -> 'ExecResult'

(no docstring)

stop (method)

stop(self) -> 'None'

(no docstring)

SandboxSpec (class)

SandboxSpec(name: 'str', image: 'str' = 'python:3.11-slim', memory_mib: 'int' = 512, cpus: 'int' = 1, workspace: 'str | None' = None, secrets: 'tuple[str, ...]' = (), egress: 'tuple[str, ...]' = (), labels: 'dict[str, str]' = <factory>) -> None

Caller request shape for :meth:SandboxClient.create.

__init__ (method)

__init__(self, name: 'str', image: 'str' = 'python:3.11-slim', memory_mib: 'int' = 512, cpus: 'int' = 1, workspace: 'str | None' = None, secrets: 'tuple[str, ...]' = (), egress: 'tuple[str, ...]' = (), labels: 'dict[str, str]' = <factory>) -> None

Initialize self. See help(type(self)) for accurate signature.

SandboxUnavailable (class)

Raised when ctx.sandbox is accessed but no runtime is attached.

Source: apps/a2a/a2a_pack/sandbox.py