Skip to content

Sandboxes for the OpenAI Agents SDK

The SDK runs the agent loop. Each session's commands run on a VM of its own.

Deploy on exe.dev

Shelley handles the setup. About 5 minutes.

Prefer a terminal?
curl -fsSL https://exe-staging.dev/deploy/openai-agents-sdk/prompt.txt | ssh exe.dev new --prompt=/dev/stdin

The OpenAI Agents SDK runs sandbox agents: a SandboxAgent whose shell and file tools work in a sandbox, while the agent loop stays in your Python process. A sandbox client makes the sandbox. The SDK has clients for Docker and the local machine, and for hosted providers such as E2B, Daytona, Modal, Vercel, and Cloudflare.

This page adds one for exe.dev. exe_sandbox.py makes each sandbox session an exe.dev VM of its own: a whole Ubuntu machine with sudo and Docker, ready in a few seconds and private by default, made with exe.dev's Python SDK. agent.py is a command-line agent built on it. It runs on a small VM of its own, with GPT models from exe.dev's LLM integration, so no OpenAI API key is needed anywhere.

What you get#

  • agent.py and exe_sandbox.py in ~/openai-agents
  • exe.dev's API through the openai-agents integration, scoped to session VMs, with no exe.dev key on any VM
  • A first session that ran its commands on a new VM of its own, then was deleted with ./agent.py --rm
  • GPT models through exe.dev's LLM integration, with no OpenAI API key on any VM
What's running, and where
my-openai-agents.exe.xyz exe.dev VM
Your agent agent.py, OpenAI Agents SDK 0.24 run by uv ~/openai-agents/sessions
Sandbox client exe_sandbox.py, which makes a VM per session with exe.dev's Python SDK
exe.dev API The openai-agents integration, which holds the API key off the VM
Session VMs One exe.dev VM per session, the agent working in /workspace /workspace
GPT models OpenAI, through exe.dev's LLM integration

Deploy with Shelley#

Click Deploy and Shelley will set up OpenAI Agents SDK on a new VM, then check that it works. No config-file wrangling required.

Prefer a terminal?
curl -fsSL \
  https://exe-staging.dev/deploy/openai-agents-sdk/prompt.txt \
  | ssh exe.dev new --prompt=/dev/stdin
What Shelley is told
Set up OpenAI Agents SDK on this VM by following the exe.dev recipe at https://exe-staging.dev/deploy/openai-agents-sdk.md from top to bottom.

The recipe's example VM name is my-openai-agents. This VM's name is the output of `hostname`: use it wherever the recipe writes my-openai-agents. Skip the step that creates the VM; you are on it.

You are done when all of these are true. Check each one yourself:
- agent.py and exe_sandbox.py in ~/openai-agents
- exe.dev's API through the openai-agents integration, scoped to session VMs, with no exe.dev key on any VM
- A first session that ran its commands on a new VM of its own, then was deleted with `./agent.py --rm`
- GPT models through exe.dev's LLM integration, with no OpenAI API key on any VM

Run "Set up the agent VM by hand" from "On the VM", skipping VM creation
and SSH. Only the owner can create the integration, from their own
computer: give them the command in "Let it make VMs", with this VM's
name in it, and wait until they say they've run it. Never ask for an
exe.dev API key instead. Then run the check and the first task in that
section, and delete the session with ./agent.py --rm <name>, so it
leaves no VM behind. Skip "Or let OpenAI run the agent": it needs the
owner's OpenAI keys. Finish by pointing the owner to "Give it a task".

Finish with the URLs I should open.

Also at /deploy/openai-agents-sdk/prompt.txt. The recipe it follows is /deploy/openai-agents-sdk.md.

Set up the agent VM#

Deploy sets it up on a new VM. To do it yourself:

Set up the agent VM by hand

On your computer:

ssh exe.dev new --name=my-openai-agents
ssh my-openai-agents.exe.xyz

On the VM, download the two files:

mkdir -p ~/openai-agents && cd ~/openai-agents
curl -fsSLO https://exe-staging.dev/deploy/openai-agents-sdk/agent.py
curl -fsSLO https://exe-staging.dev/deploy/openai-agents-sdk/exe_sandbox.py
chmod +x agent.py

To update later, run the two curl lines again.

Let it make VMs#

The agent VM makes session VMs through exe.dev's API, by way of an integration that holds the API key: no key is ever on a VM. On your computer:

ssh exe.dev integrations add exe-dev --name openai-agents \
  --tag openai-sandbox --cmds new,ls,ssh,rm --attach vm:my-openai-agents

The integration can make, reach, and delete VMs tagged openai-sandbox, and nothing else; the VMs it makes get that tag. Only the agent VM can use it. ssh exe.dev integrations remove openai-agents revokes it.

On the agent VM, check it:

curl -s -X POST https://openai-agents.int.exe.xyz/exec -d ls

Expect {"vms":[]}. Then give it a first task, in ~/openai-agents. uv installs the SDK the first time:

./agent.py "Write the output of hostname to hello.txt, and show it to me."

Expect session <name>, on VM <name>, a line for each command or edit the agent makes, and a reply with the session VM's name, which is not this VM's.

Give it a task#

On the agent VM, in ~/openai-agents:

./agent.py "Make a small Flask to-do app, serve it on port 8080, and give me the link."

The agent gets a new VM, and each command it runs shows up as it runs. The link it gives, https://<session-vm>.exe.xyz:8080/, opens for you after exe.dev login, like any port from 3000 to 9999 through the HTTPS proxy.

Each session keeps its VM, its conversation, and its files. Continue it with the name it printed:

./agent.py -s <name> "Add a due date to each to-do."

./agent.py --ls lists sessions, and ./agent.py --rm <name> deletes one and its VM. You can also open a session's VM yourself, on your computer: ssh <name>.exe.xyz, then cd /workspace.

Warning

The agent runs commands with sudo, without asking. That's what the session VMs are for: they hold nothing else. Keep the agent VM, which can make VMs on your account, to yourself, and never attach the integration to the openai-sandbox tag, which would let sessions do the same.

Use it in your own code#

exe_sandbox.py works with any SandboxAgent. Put it beside your code on the agent VM, and pass the client in SandboxRunConfig. This agent starts with a repository checked out on its VM:

import asyncio

from agents import Runner, set_default_openai_client, set_tracing_disabled
from agents.run import RunConfig
from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig
from agents.sandbox.entries import GitRepo
from openai import AsyncOpenAI

from exe_sandbox import ExeSandboxClient, ExeSandboxClientOptions

# On an exe.dev VM, models come from the LLM integration; the key is a placeholder.
set_default_openai_client(AsyncOpenAI(base_url="https://llm.int.exe.xyz/v1", api_key="exe.dev"), use_for_tracing=False)
set_tracing_disabled(True)

agent = SandboxAgent(
    name="Reviewer",
    model="gpt-6.1-sol",
    instructions="Answer questions about the repository in repo/. Run commands to check.",
    default_manifest=Manifest(entries={"repo": GitRepo(repo="openai/openai-agents-python", ref="main")}),
)

async def main():
    result = await Runner.run(
        agent,
        "Which sandbox providers are under repo/src/agents/extensions?",
        run_config=RunConfig(sandbox=SandboxRunConfig(
            client=ExeSandboxClient(api="https://openai-agents.int.exe.xyz"),
            options=ExeSandboxClientOptions(cpu=2))),
    )
    print(result.final_output)

asyncio.run(main())

Run it with uv run --with 'openai-agents>=0.24,<0.25' --with 'exedev>=0.4,<0.5' review.py. When the run ends, the SDK closes the session and its VM is deleted. ExeSandboxClientOptions also takes memory, disk, image, egress, integrations, tags, comment, exposed_ports, and on_exit:

  • on_exit="keep" keeps the VM. Save the session's state with client.serialize_session_state(session.state), and client.resume(...) reconnects to the same VM later, with its files, packages, and running services. That's how agent.py keeps sessions.
  • If a kept VM is gone, resuming makes a new, empty one. To bring the files back too, create the session with a snapshot, such as snapshot=LocalSnapshotSpec(base_path=Path("snapshots")): the SDK saves /workspace when the session closes and restores it onto the new VM.
  • For work the SDK has no method for, session.vm is the exe.dev VM object (await session.vm.run("...")).

Off exe.dev, integrations aren't reachable. Use ExeSandboxClient(token=...) with an exe.dev API key from ssh exe.dev ssh-key generate-api-key --label=openai-agents --tag=openai-sandbox --cmds=new,ls,ssh,rm --exp=30d, leave out the two set_ lines, and set OPENAI_API_KEY.

Or let OpenAI run the agent#

OpenAI's Agents API (in beta) turns this around: OpenAI runs the agent loop, the Codex harness, and a self-hosted environment runs its tools wherever you start codex exec-server. Codex is already on every exe.dev VM, so a VM per session takes one more short program: agents_api.py creates a session, makes its VM through the same integration, and starts codex exec-server there under systemd.

It needs two OpenAI keys, which the LLM integration doesn't replace:

  • An OpenAI API key with api.agents.read, api.agents.write, and api.responses.write. Keep it off the VM in an HTTP proxy integration. On your computer:

    printf %s "$OPENAI_API_KEY" | ssh exe.dev integrations add http-proxy --name openai \
      --target https://api.openai.com --bearer=- --attach vm:my-openai-agents
    
  • An environment key, from the Agents tab of the OpenAI platform, with every other permission set to None. It can only connect environments, and each session VM gets a copy, as OpenAI's design has it.

On the agent VM, fill in the environment key:

cd ~/openai-agents
curl -fsSLO https://exe-staging.dev/deploy/openai-agents-sdk/agents_api.py
chmod +x agents_api.py
(umask 077; echo 'OPENAI_EXECUTOR_API_KEY=...' >> .env)
./agents_api.py "Write the output of hostname to hello.txt, and show it to me."

Expect session sess_..., on VM <name>, then the agent's reply with that VM's name. ./agents_api.py -s sess_... "..." continues a session on its VM, restarting the executor if the VM was rebooted, and ./agents_api.py --rm sess_... deletes the session and its VM. OpenAI bills the model at its API rates; MODEL in .env picks it (default gpt-6-astra).

Clean up#

./agent.py --rm <name> deletes a session. On your computer, ssh exe.dev ls lists session VMs with their task as the comment. To delete every VM tagged openai-sandbox, including any the agent VM's sessions still use (its first two lines alone list them):

ssh exe.dev ls --json |
  jq -r '.vms[] | select(.tags // [] | index("openai-sandbox")) | .vm_name' |
  xargs -r ssh exe.dev rm

Session history is in ~/openai-agents/sessions on the agent VM. When you're done with it all, ssh exe.dev integrations remove openai-agents.

Troubleshooting#

  • exe.dev API error (403) during new: integration not found or not attached to this VM: run the command in Let it make VMs with this VM's name, or ssh exe.dev integrations attach openai-agents vm:<this-vm>.
  • agents_api.py stops with 403 and integration not found: attach the openai integration to this VM, as in Or let OpenAI run the agent.
  • during new: ... otherwise: exe.dev refused a VM, often because the plan's VM limit is reached. Delete old sessions.
  • Connection error from the model: the LLM integration is reachable only from exe.dev VMs. Elsewhere, set OPENAI_API_KEY.
  • A command that starts a server with & and leaves it writing to the terminal holds the command open until it times out. Run servers under sudo systemd-run, as agent.py tells the model to.

Frequently asked questions#

What runs where?

The agent loop runs in your Python process: on the agent VM, or wherever you run your code. It calls the model, then runs the tools the model picks (shell commands, file edits, apply_patch) on the session's VM, over exe.dev's HTTPS API, through an integration that keeps the API key off every VM. The session VMs can't use that integration, and hold no model key either.

Do I need an OpenAI API key?

No. On an exe.dev VM, agent.py sends model requests to exe.dev's LLM integration, which bills them to your exe.dev account. To use your own key, or run the agent off exe.dev, add OPENAI_API_KEY=sk-... to ~/openai-agents/.env (mode 600); traces then appear in OpenAI's dashboard, too.

How is this different from the E2B, Daytona, or Modal clients?

It plugs into the same place: SandboxRunConfig(client=...). Each sandbox is a whole VM with sudo, Docker, and systemd, so a session can install packages, run databases, and serve web apps at a private HTTPS address, and a kept session is still there days later. It doesn't do PTY sessions (no write_stdin), mounts, or manifest users and groups.

What does it cost?

Session VMs share your exe.dev plan's CPU, memory, and disk rather than being billed one by one, but each counts toward the plan's VM limit (50 on Personal), so delete sessions you're done with. Model usage through the LLM integration is billed to your exe.dev account.

Can the agent show me a web app it built?

Yes. Anything it serves on 0.0.0.0, on a port from 3000 to 9999, is at https://<vm>.exe.xyz:<port>/, behind exe.dev login. agent.py tells the model so, and to run servers under systemd so they keep running between turns.

Can the agent work on my GitHub repositories?

Yes, with no GitHub token on any VM. Attach exe.dev's GitHub integration to every session VM by their tag, on your computer: ssh exe.dev integrations add github --name myapp --repository you/myapp --attach tag:openai-sandbox. The agent then clones https://github.int.exe.xyz/you/myapp.git.

Can sessions get bigger VMs, or no internet?

Yes, through ExeSandboxClientOptions: cpu=4, memory="16GB", disk="50GB", or egress="integrations", which leaves a VM only its integrations. See Internet access.

Updated Oct 29, 2026 · tested end to end Oct 29, 2026 · Markdown · manifest.json · Something wrong? Tell us