Sandboxes
Give agents an isolated remote filesystem and shell with E2B or Daytona sandbox backends — attach via SandboxConfig or drive the sandbox directly.
The dynamiq.sandboxes package provides isolated remote environments where agents can write files, run shell commands, and serve apps — without touching your host. Attach a sandbox to an Agent and it automatically gains shell, file, and sandbox-info tools; or drive the sandbox object directly from your own code. This is the SDK counterpart of the platform's Agent Sandbox.
Backends
All backends subclass Sandbox (dynamiq/sandboxes/base.py) and share base_path, file operations, and shell execution.
| Backend | Import | Connection | Notes |
|---|---|---|---|
E2BSandbox | dynamiq.sandboxes | dynamiq.connections.E2B (E2B_API_KEY) | Default base_path="/home/user", session timeout=3600s; supports custom template, envs, metadata, and reconnecting via sandbox_id. |
DaytonaSandbox | dynamiq.sandboxes | dynamiq.connections.Daytona (DAYTONA_API_KEY, DAYTONA_API_URL) | Default base_path="/home/daytona"; supports image or snapshot, envs, labels, auto_stop_interval, and reconnecting via sandbox_id. |
E2BDesktopSandbox | dynamiq.sandboxes | dynamiq.connections.E2B | E2B desktop environment for computer-use scenarios. |
Both E2B and Daytona create the remote sandbox lazily on first use, retry creation on rate limits with exponential backoff (creation_error_handling), and can reattach to a still-running sandbox by passing its sandbox_id.
Attach a sandbox to an Agent
Pass a SandboxConfig to the agent's sandbox field. The agent then extends its tool list with the sandbox's tools automatically:
import os
from dynamiq import Workflow
from dynamiq.connections import E2B as E2BConnection
from dynamiq.connections import OpenAI as OpenAIConnection
from dynamiq.flows import Flow
from dynamiq.nodes.agents import Agent
from dynamiq.nodes.llms import OpenAI
from dynamiq.sandboxes import SandboxConfig
from dynamiq.sandboxes.e2b import E2BSandbox
llm = OpenAI(connection=OpenAIConnection(), model="gpt-4o", temperature=0.2)
sandbox = E2BSandbox(
connection=E2BConnection(api_key=os.environ["E2B_API_KEY"]),
timeout=3600,
base_path="/home/user",
)
agent = Agent(
id="sandbox-agent",
name="SandboxAgent",
llm=llm,
sandbox=SandboxConfig(enabled=True, backend=sandbox),
role="You are a coding assistant that writes and runs scripts in the sandbox.",
max_loops=10,
)
wf = Workflow(flow=Flow(nodes=[agent]))
result = wf.run(
input_data={
"input": "Create hello.py that prints 'Hello from E2B!', run it with python, and show the output."
}
)
print(result.output["sandbox-agent"]["output"]["content"])
sandbox.close()For Daytona, swap the connection and backend (DaytonaSandbox(connection=Daytona(api_key=...))) — everything else is identical. Full scripts: agent_e2b_sandbox.py and agent_daytona_sandbox.py.
Tools the agent gains
backend.get_tools(llm=...) adds these nodes to the agent's tool list:
| Tool | What the agent uses it for |
|---|---|
sandbox-shell (SandboxShellTool) | Execute shell commands with a timeout (default 60s) or in the background; supports a blocked_commands denylist. |
| File write / file read | Read and edit files in the sandbox filesystem (read requires the agent's LLM for large-file handling). |
| Todo write | Maintain a task list file for long multi-step jobs. |
sandbox-info (SandboxInfoTool) | Get base_path, sandbox_id, and — given a port — the public HTTPS URL of a service the agent started (for example a dev server). |
File conventions baked into the tool prompts: input files uploaded with the run land under {base_path}/input, and anything the agent writes to {base_path}/output is collected and returned after the run.
An agent cannot enable both files (file store) and sandbox at the same time — the sandbox already provides file storage, and the SDK raises a validation error if both are set.
Driving a sandbox directly
The Sandbox interface is useful on its own — for fixtures, cleanups, or custom tooling:
import os
from dynamiq.connections import E2B as E2BConnection
from dynamiq.sandboxes.e2b import E2BSandbox
with E2BSandbox(connection=E2BConnection(api_key=os.environ["E2B_API_KEY"])) as sandbox:
sandbox.upload_file("data.csv", b"name,score\nada,1\n", destination_path="/home/user/input/data.csv")
result = sandbox.run_command_shell("wc -l /home/user/input/data.csv", timeout=30)
print(result.stdout, result.exit_code)
print(sandbox.list_files("/home/user/input"))
print(sandbox.retrieve("/home/user/input/data.csv"))
info = sandbox.get_sandbox_info(port=8000)
print(info.sandbox_id, info.public_url)Key methods on every backend:
run_command_shell(command, timeout=60, run_in_background_enabled=False)→ShellCommandResultwithstdout,stderr,exit_code, andis_success.upload_file(file_name, content, destination_path=None)/list_files(target_dir=None)/exists(path)/retrieve(path)for the filesystem.get_sandbox_info(port=None)→SandboxInfowithbase_path,sandbox_id, andpublic_urlfor an exposed port.close(kill=False)— disconnect;kill=Truealso terminates the remote sandbox. The context-manager form closes automatically.
Reconnect to a long-lived sandbox across processes by persisting sandbox.current_sandbox_id and constructing the backend later with sandbox_id=<saved id>.
YAML workflows
Sandbox-backed agents serialize like any other node, so you can define the sandbox in a workflow YAML and load it with WorkflowYAMLLoader — see the YAML sandbox example and YAML Workflows.
Next steps
Evaluations
Score workflow outputs in code with ready-made RAG metrics, the LLMEvaluator for custom judged metrics, and the PythonEvaluator for programmatic checks.
Examples
A categorized catalog of the runnable examples in the dynamiq repository — agents, orchestrators, RAG, tools, checkpoints, streaming, evaluations, and full use-case apps.