Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.celesto.ai/llms.txt

Use this file to discover all available pages before exploring further.

The Celesto SDK ships with two ready-made sandbox providers for the OpenAI Agents SDK. With one of them plugged in, an OpenAI SandboxAgent can read files, run shell commands, and create artifacts in an isolated computer instead of on your laptop or server. You get to pick where that computer lives:
  • Hosted Celesto computer for cloud runs you can share, persist, and resume from any machine.
  • Local SmolVM sandbox for fast, private runs that stay on your own hardware.
Both options expose the exact same OpenAI primitives (SandboxAgent, SandboxRunConfig, Runner), so you can swap providers without changing the rest of your agent code.

When to use this

Reach for these integrations when you want an OpenAI agent to:
  • Run untrusted or model-generated commands without touching your machine.
  • Inspect, edit, or build files in a clean, throwaway workspace.
  • Pause a session, save it, and resume it later from a different process.
If you only need to call a single shell command from an OpenAI tool, the simpler function tool example on the SmolVM page may be enough.

Installation

Install the Celesto SDK with the openai-agents extra. This pulls in the OpenAI Agents SDK and SmolVM alongside Celesto:
pip install "celesto[openai-agents]"
The hosted provider needs a Celesto API key. Set CELESTO_API_KEY or pass api_key= when you create the client. The SmolVM provider runs locally and does not need an API key.

Hosted Celesto sandboxes

Use CelestoSandboxClient when you want OpenAI to spin up a fresh Celesto computer for the agent’s session. The client creates the computer on create(), runs every shell command and file operation against it, and tears it down on delete().
1

Import the provider and OpenAI primitives

from agents import Runner
from agents.run import RunConfig
from agents.sandbox import SandboxAgent, SandboxRunConfig
from celesto.integrations.openai_agents import (
    CelestoSandboxClient,
    CelestoSandboxClientOptions,
)
2

Define your SandboxAgent

A SandboxAgent is an OpenAI agent that always works inside a sandbox you provide.
agent = SandboxAgent(
    name="Workspace analyst",
    instructions="Inspect the sandbox workspace before answering.",
)
3

Create a session and run the agent

import asyncio

async def main():
    client = CelestoSandboxClient()
    session = await client.create(
        options=CelestoSandboxClientOptions(cpus=2, memory=2048),
    )
    try:
        async with session:
            result = await Runner.run(
                agent,
                "Run `uname -a` in the sandbox and summarize the result.",
                run_config=RunConfig(sandbox=SandboxRunConfig(session=session)),
            )
            print(result.final_output)
    finally:
        await client.delete(session)

asyncio.run(main())
The agent prints a one-line summary of uname -a output from a fresh Celesto computer.

Client options

Pass a CelestoSandboxClientOptions to control how the computer is created.
cpus
integer
default:"1"
Number of virtual CPUs for the new computer. Range: 1-16.
memory
integer
default:"1024"
Memory in MB for the new computer. Range: 512-32768.
image
string
default:"ubuntu-desktop-24.04"
OS image to boot. Match this to the Computers API images.
computer_id
string
Reuse an existing Celesto computer instead of creating a new one. When set, the session attaches to that computer and starts it if needed.
delete_on_close
boolean
Whether to delete the computer when the session closes. Defaults to true if the client created the computer, and false if you passed in an existing computer_id.

Authenticate the client

By default CelestoSandboxClient uses your CELESTO_API_KEY environment variable. You can also pass credentials directly or share an existing Celesto instance:
from celesto import Celesto
from celesto.integrations.openai_agents import CelestoSandboxClient

client = CelestoSandboxClient(api_key="your-api-key")
# or
client = CelestoSandboxClient(client=Celesto(api_key="your-api-key"))

Resume a session later

Save the session state when your process exits and resume it on the next run. This keeps the same computer attached to the same agent identity:
state = session.state.model_dump()
# ... persist `state` to disk or a database

resumed = await client.resume(
    CelestoSandboxClient().deserialize_session_state(state)
)
Use delete_on_close=False when you plan to resume. Otherwise the computer is deleted when the original session ends.

Local SmolVM sandboxes

SmolVMSandboxClient runs the agent in a SmolVM on your own machine. It is a drop-in replacement for CelestoSandboxClient and uses the same SandboxAgent, SandboxRunConfig, and Runner flow.
from agents import Runner
from agents.run import RunConfig
from agents.sandbox import SandboxAgent, SandboxRunConfig
from celesto.integrations.openai_agents import (
    SmolVMSandboxClient,
    SmolVMSandboxClientOptions,
)

agent = SandboxAgent(
    name="Local workspace analyst",
    instructions="Inspect the sandbox workspace before answering.",
)

async def main():
    client = SmolVMSandboxClient()
    session = await client.create(
        options=SmolVMSandboxClientOptions(memory=2048),
    )
    try:
        async with session:
            result = await Runner.run(
                agent,
                "List the files in the workspace and describe them.",
                run_config=RunConfig(sandbox=SandboxRunConfig(session=session)),
            )
            print(result.final_output)
    finally:
        await client.delete(session)

Client options

os
string
OS image to boot inside SmolVM (for example, ubuntu-24.04). Defaults to SmolVM’s default image.
backend
string
Which SmolVM backend to use (such as firecracker or qemu). Defaults to SmolVM’s auto-selected backend for your platform.
memory
integer
Memory in MB for the local sandbox.
disk_size
integer
Disk size in MB for the local sandbox.
exposed_ports
tuple[int, ...]
default:"()"
Guest ports to expose to your host. Use this when the agent runs a server (for example, a dev server or web app) you want to reach from your machine.
vm_id
string
Reuse an existing SmolVM instead of creating a new one. The session attaches to that VM and starts it if needed.
delete_on_close
boolean
Whether to delete the VM when the session closes. Defaults to true if the client created the VM, and false if you passed in an existing vm_id.

Choosing between hosted and local

Hosted Celesto

Use when you want managed infrastructure, shared computers, longer-lived sessions, or runs that originate from servers without local virtualization.

Local SmolVM

Use when you want fast iteration, private runs, no API key, or development on a single workstation.
Both providers implement OpenAI’s sandbox session interface, so the rest of your agent code (instructions, tools, runners) stays the same when you switch.

Common patterns

Read and write files in the sandbox

SandboxAgent operations call read() and write() on the session. The Celesto and SmolVM providers map those calls to the underlying computer or VM:
from pathlib import Path

async with session:
    await session.write(Path("notes/plan.md"), io.BytesIO(b"# Plan\n"))
    handle = await session.read(Path("notes/plan.md"))
    print(handle.read().decode())

Save and restore the workspace

Both providers can snapshot the sandbox workspace as a tarball and rehydrate it later:
async with session:
    archive = await session.persist_workspace()
    # store `archive.read()` somewhere durable

# later, in a new session:
async with new_session:
    await new_session.hydrate_workspace(archive)
This is useful when you want to keep the agent’s working files across runs without keeping the computer alive.

Troubleshooting

The integration is an optional extra. Install it with pip install "celesto[openai-agents]". This adds the openai-agents and smolvm packages alongside Celesto.
Files written through session.write() land inside the sandbox workspace, not on your host. Use session.read() or session.persist_workspace() to pull them out.
Long-running commands need a longer timeout. Pass timeout= when calling sandbox operations, or split the work into shorter steps in the agent’s instructions.
Last modified on May 6, 2026