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.
SmolVM gives your AI agents a safe place to run code. Instead of executing LLM-generated commands directly on your machine, SmolVM spins up an isolated microVM in milliseconds, runs the code inside it, and tears it down when finished.
Install the agent framework extras before following these examples:pip install "smolvm[examples]"
This adds PydanticAI, OpenAI Agents SDK, LangChain, and Playwright as dependencies. See installation for details.
Agentor
Agentor is Celesto’s own agent framework. It has built-in SmolVM support through SmolVMRuntime, so your agent’s shell commands run inside a sandbox automatically.
from agentor import Agentor
from agentor.runtime import SmolVMRuntime
from agentor.tools import ShellTool
def main() -> None:
runtime = SmolVMRuntime(memory=1024, disk_size=2048)
try:
agent = Agentor(
name="SmolVM Shell Agent",
model="gpt-5",
tools=[ShellTool(executor=runtime)],
instructions="Use shell commands to inspect files inside the SmolVM sandbox.",
)
result = agent.run(
"Install uv and use the Python interpreter to print 'Hello, World!'. Return both outputs."
)
print(result)
finally:
runtime.close()
if __name__ == "__main__":
main()
See the full working example in main.py.
PydanticAI
Register SmolVM as a PydanticAI tool. Each call spins up a fresh VM, runs the command, and tears it down automatically.
from smolvm import SmolVM
from pydantic_ai import Agent
def run_in_smolvm(command: str, timeout: int = 30) -> str:
"""Run a shell command inside an ephemeral SmolVM sandbox.
Args:
command: Shell command to execute inside the sandbox guest.
timeout: Maximum number of seconds to wait for the command.
"""
with SmolVM() as vm:
result = vm.run(command, timeout=timeout)
return (
f"exit_code: {result.exit_code}\n"
f"stdout:\n{result.stdout.strip() or '<empty>'}\n"
f"stderr:\n{result.stderr.strip() or '<empty>'}"
)
agent = Agent(
"openai:gpt-4.1",
instructions=(
"You are a coding assistant with access to a secure SmolVM sandbox. "
"For shell or Python inspection requests, call run_in_smolvm exactly "
"once and then summarize the result."
),
)
agent.tool_plain(docstring_format="google", require_parameter_descriptions=True)(
run_in_smolvm
)
result = agent.run_sync("Run `uname -a && python3 --version` in the sandbox.")
print(result.output)
Reusable sandbox across turns
If your agent needs to maintain state between tool calls, keep the VM alive across invocations:
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
from smolvm import SmolVM
@dataclass
class SandboxDeps:
vm_id: str | None = None
def _connect_vm(deps: SandboxDeps) -> SmolVM:
"""Return the active sandbox, creating it on first use."""
if deps.vm_id is None:
vm = SmolVM()
vm.start()
deps.vm_id = vm.vm_id
return vm
return SmolVM.from_id(deps.vm_id)
def _cleanup_vm(vm_id: str | None) -> None:
"""Delete the reusable sandbox if one was created."""
if vm_id is None:
return
vm = SmolVM.from_id(vm_id)
try:
vm.delete()
finally:
vm.close()
def run_in_reusable_smolvm(
ctx: RunContext[SandboxDeps], command: str, timeout: int = 30
) -> str:
"""Run a shell command inside a reusable SmolVM sandbox.
Args:
command: Shell command to execute inside the sandbox guest.
timeout: Maximum number of seconds to wait for the command.
"""
vm = _connect_vm(ctx.deps)
try:
result = vm.run(command, timeout=timeout)
return (
f"exit_code: {result.exit_code}\n"
f"stdout:\n{result.stdout.strip() or '<empty>'}\n"
f"stderr:\n{result.stderr.strip() or '<empty>'}"
)
finally:
vm.close()
agent = Agent(
"openai:gpt-4.1",
deps_type=SandboxDeps,
instructions="You have access to a persistent SmolVM sandbox.",
)
agent.tool(docstring_format="google", require_parameter_descriptions=True)(
run_in_reusable_smolvm
)
deps = SandboxDeps()
try:
agent.run_sync("Write 'hello' to /tmp/note.txt", deps=deps)
agent.run_sync("Read /tmp/note.txt and confirm the contents", deps=deps)
finally:
_cleanup_vm(deps.vm_id)
OpenAI Agents SDK
Use SmolVM as a function tool in the OpenAI Agents SDK:
import asyncio
from agents import Agent, Runner, function_tool
from smolvm import SmolVM
def run_in_smolvm(command: str, timeout: int = 30) -> str:
"""Run a shell command inside an ephemeral SmolVM sandbox.
Args:
command: Shell command to execute inside the sandbox guest.
timeout: Maximum number of seconds to wait for the command.
"""
with SmolVM() as vm:
result = vm.run(command, timeout=timeout)
return (
f"exit_code: {result.exit_code}\n"
f"stdout:\n{result.stdout.strip() or '<empty>'}\n"
f"stderr:\n{result.stderr.strip() or '<empty>'}"
)
agent = Agent(
name="SmolVM Assistant",
model="gpt-4.1",
instructions=(
"You are a coding assistant with access to a secure SmolVM sandbox. "
"For shell or Python inspection requests, call run_in_smolvm exactly "
"once and then summarize the result."
),
tools=[function_tool(run_in_smolvm)],
)
async def main():
result = await Runner.run(
agent, "Run `uname -a && python3 --version` in the sandbox."
)
print(result.final_output)
asyncio.run(main())
Use SmolVM as a SandboxAgent provider
If you want OpenAI’s SandboxAgent to treat SmolVM as its full working computer (not just a one-shot tool), use the ready-made provider in the Celesto SDK. It plugs into Runner and SandboxRunConfig directly, and ships alongside a hosted Celesto option you can swap in without changing your agent code. See OpenAI Agents SDK sandboxes for the full guide.
LangChain
Wrap SmolVM as a LangChain tool:
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from smolvm import SmolVM
@tool
def run_in_smolvm(command: str, timeout: int = 30) -> str:
"""Run a shell command inside an ephemeral SmolVM sandbox.
Args:
command: Shell command to execute inside the sandbox guest.
timeout: Maximum number of seconds to wait for the command.
"""
with SmolVM() as vm:
result = vm.run(command, timeout=timeout)
return (
f"exit_code: {result.exit_code}\n"
f"stdout:\n{result.stdout.strip() or '<empty>'}\n"
f"stderr:\n{result.stderr.strip() or '<empty>'}"
)
llm = ChatOpenAI(model="gpt-4.1")
agent = create_react_agent(llm, [run_in_smolvm])
result = agent.invoke({
"messages": [{"role": "user", "content": "Run uname -a in the sandbox"}]
})
print(result["messages"][-1].content)
Browser sessions
SmolVM includes a built-in BrowserSession class that launches a Chromium browser inside a microVM. Use it for web scraping, testing, and computer-use agents.
from smolvm import BrowserSession, BrowserSessionConfig
with BrowserSession(
BrowserSessionConfig(
mode="live",
record_video=True,
viewport={"width": 1440, "height": 900},
)
) as session:
print(f"Session: {session.session_id}")
print(f"CDP URL: {session.cdp_url}")
print(f"Live URL: {session.live_url}")
browser = session.connect_playwright()
context = browser.contexts[0] if browser.contexts else browser.new_context()
page = context.pages[0] if context.pages else context.new_page()
page.goto("https://example.com", wait_until="networkidle")
session.screenshot("screenshot.png")
Browser session modes
| Mode | Description |
|---|
headless | No visual output. Good for automated scraping and testing. |
live | Exposes a noVNC live-view URL so you can watch the browser in real time. |
Computer-use with OpenAI
Combine BrowserSession with OpenAI’s computer-use API for autonomous web browsing agents. The model sees the browser through screenshots and sends back click, type, and scroll instructions.
from openai import OpenAI
from smolvm import BrowserSession, BrowserSessionConfig
client = OpenAI()
with BrowserSession(
BrowserSessionConfig(mode="live", viewport={"width": 1440, "height": 900})
) as session:
browser = session.connect_playwright()
context = browser.contexts[0] if browser.contexts else browser.new_context()
page = context.pages[0] if context.pages else context.new_page()
page.goto("https://example.com", wait_until="domcontentloaded")
response = client.responses.create(
model="gpt-5.4",
tools=[{"type": "computer"}],
input="Find the main heading on the page.",
)
for item in response.output:
if item.type == "computer_call":
# Execute browser actions based on the model's instructions
pass
If you use a framework not listed above, the core pattern is the same:
from smolvm import SmolVM
def run_in_smolvm(command: str, timeout: int = 30) -> str:
"""Run a shell command inside an ephemeral SmolVM sandbox."""
with SmolVM() as vm:
result = vm.run(command, timeout=timeout)
if result.ok:
return result.stdout
return f"Error (exit {result.exit_code}): {result.stderr}"
Register this function as a tool in whatever framework you use.