Skip to content

SandboxCodeTool

autogen.beta.tools.code.tool.SandboxCodeTool #

SandboxCodeTool(environment, *, languages=('python', 'bash'), runners=None, name='run_code', description='Execute code in a sandboxed environment. Supported languages: {languages}.', middleware=())

Bases: Tool

Exposes a single run_code(code, language) function that runs code inside an environment you choose — Docker, Daytona, or any custom backend.

The environment decides where code runs and carries all backend configuration; the tool decides which languages are accepted and how each maps to a runner. The same environment can back both a :class:SandboxCodeTool and a :class:~autogen.beta.tools.SandboxShellTool.

Unlike :class:~autogen.beta.tools.CodeExecutionTool (which delegates execution to the LLM provider's built-in sandbox), SandboxCodeTool runs client-side, so it works on every provider regardless of native code-execution support.

There is no default backend: environment is required. The class name is a contract — it executes whatever the model writes, so it must be wired to a backend that genuinely sandboxes execution. A :class:~autogen.beta.tools.LocalEnvironment is accepted but only when passed explicitly (it offers no isolation).

Examples::

from autogen.beta.tools import SandboxCodeTool
from autogen.beta.extensions.docker import DockerEnvironment

docker = DockerEnvironment(image="python:3.12-slim")
code = SandboxCodeTool(docker, languages=("python", "bash"))

# Advanced: pass a pre-built CodeAdapter (custom runners):
from autogen.beta.tools.sandbox import CodeAdapter, LocalEnvironment, LanguageRunner

code = SandboxCodeTool(
    CodeAdapter(
        LocalEnvironment(),
        languages=("typescript",),
        runners={"typescript": LanguageRunner(file_extension="ts", file_runner_argv=("tsx",))},
    )
)
PARAMETER DESCRIPTION
environment

What runs the code. Either a backend — a :class:~autogen.beta.tools.sandbox.SandboxFactory (DockerEnvironment / DaytonaEnvironment / LocalEnvironment), wrapped in a :class:CodeAdapter using languages / runners — or a ready :class:~autogen.beta.tools.code.CodeEnvironment (incl. a pre-built :class:CodeAdapter), used as-is. Required.

TYPE: SandboxFactory | CodeEnvironment

languages

Languages this tool accepts (backend form only).

TYPE: tuple[CodeLanguage, ...] DEFAULT: ('python', 'bash')

runners

Override / extend the default language→runner mapping (backend form only).

TYPE: dict[CodeLanguage, LanguageRunner] | None DEFAULT: None

name / description / middleware

Tool wiring.

Source code in autogen/beta/tools/code/tool.py
def __init__(
    self,
    environment: "SandboxFactory | CodeEnvironment",
    *,
    languages: tuple[CodeLanguage, ...] = ("python", "bash"),
    runners: "dict[CodeLanguage, LanguageRunner] | None" = None,
    name: str = "run_code",
    description: str = "Execute code in a sandboxed environment. Supported languages: {languages}.",
    middleware: Iterable[ToolMiddleware] = (),
) -> None:
    env: CodeEnvironment
    if isinstance(environment, SandboxFactory):
        env = CodeAdapter(environment, languages=languages, runners=runners)
    else:
        # Already a CodeEnvironment (incl. CodeAdapter) — use as-is.
        if runners is not None:
            raise ValueError(
                "`runners` only applies when `environment` is a backend "
                "(SandboxFactory); configure runners on your "
                "CodeAdapter / CodeEnvironment instead."
            )
        env = environment

    async def run_code(code: str, language: CodeLanguage, ctx: Context) -> str:
        result = await env.run(code, language, context=ctx)
        if result.exit_code != 0:
            suffix = f"[exit code: {result.exit_code}]"
            return f"{result.output}\n{suffix}" if result.output else suffix
        return result.output

    self._env = env
    self._tool: FunctionTool = tool(
        run_code,
        name=name,
        description=description.format(languages=", ".join(env.supported_languages)),
        middleware=middleware,
    )
    self.name = name

name instance-attribute #

name = name

environment property #

environment

The underlying code environment (a :class:CodeAdapter when a backend was passed, otherwise the object you supplied).

schemas async #

schemas(context)
Source code in autogen/beta/tools/code/tool.py
async def schemas(self, context: "Context") -> list:  # type: ignore[type-arg]
    return await self._tool.schemas(context)

register #

register(stack, context, *, middleware=())
Source code in autogen/beta/tools/code/tool.py
def register(
    self,
    stack: "ExitStack | AsyncExitStack",
    context: "Context",
    *,
    middleware: Iterable["BaseMiddleware"] = (),
) -> None:
    self._tool.register(stack, context, middleware=middleware)

set_provider #

set_provider(provider)
Source code in autogen/beta/tools/tool.py
def set_provider(self, provider: Provider) -> None:
    pass