Sandbox Atomic API
context.sandbox.* provides a view for developers to call directly. They can encapsulate their own tools based on the sandbox atomic API.
commands
Execute a one-time shell command in the sandbox. Each invocation is an independent new process (process state is not retained, the current working directory is not retained, and environment variable changes are not retained. To retain variables across invocations, use
runCode).commands.run(cmd, opts?) — Executes a shell command. The opts parameter supports cwd / env / user / timeout (in seconds). It returns { stdout, stderr, exitCode }.TS example:
const { stdout, exitCode } = await context.sandbox.commands.run('pip install requests && python -c "import requests; print(requests.__version__)"',{ timeout: 60 },)
Python example:
result = await context.sandbox.commands.run('pip install requests && python -c "import requests; print(requests.__version__)"',timeout=60,)
files
Read from and write to the file system within the sandbox instance. For text scenarios, use it directly. For binary assets (such as
.png), it is recommended to first download or decode them within the sandbox using commands, and then read them out through other channels (for example, by uploading them to object storage and providing a URL to the frontend).files.read(path) — Reads the content of a text file.files.write(path, content) — Writes content to a text file. If the file does not exist, it is created. If the file exists, it is overwritten.files.list(path) — Lists the directory and returns EntryInfo[] ({ name, type, path }).files.makeDir(path) / files.make_dir(path) — Creates a directory.files.exists(path) — Checks whether a file or directory exists.files.remove(path) — Deletes a file or directory.TS example:
await context.sandbox.files.makeDir('/work/output')await context.sandbox.files.write('/work/output/result.json', JSON.stringify(data))const entries = await context.sandbox.files.list('/work/output')
Python example:
await context.sandbox.files.make_dir('/work/output')await context.sandbox.files.write('/work/output/result.json', json.dumps(data))entries = await context.sandbox.files.list('/work/output')
browser
Connect to the sandbox's built-in Chromium (underlying Playwright) via CDP. This approach is suitable for multi-step browser workflows that require state persistence, such as post-login operations, form interactions, and dynamic page screenshots.
browser.cdpUrl — The CDP connection URL, which can be directly connected to by an external Playwright.browser.liveUrl — The NoVNC visualization URL, which allows for manual, real-time page viewing.browser.goto(url) — Navigates to the target URL and returns { url, title, status }.browser.screenshot(fullPage?) — Takes a screenshot and returns { base64Image }.browser.click(selector) — Clicks an element.browser.type(selector, text) — Types text into an input field.browser.evaluate(script) — Executes JavaScript within the page context.browser.getContent() / browser.get_content() — Obtains the HTML of the current page and returns { content }.browser.close() — Closes the browser connection.TS example:
// Take a screenshot after logging in. (The LLM tool cannot call browser_screenshot independently.)await context.sandbox.browser.goto('https://example.com/login')await context.sandbox.browser.type('input[name=user]', 'alice')await context.sandbox.browser.type('input[name=pass]', 'secret')await context.sandbox.browser.click('button[type=submit]')await context.sandbox.browser.goto('https://example.com/dashboard')const { base64Image } = await context.sandbox.browser.screenshot({fullPage: true})
Python example:
await context.sandbox.browser.goto('https://example.com/login')await context.sandbox.browser.type('input[name=user]', 'alice')await context.sandbox.browser.type('input[name=pass]', 'secret')await context.sandbox.browser.click('button[type=submit]')await context.sandbox.browser.goto('https://example.com/dashboard')shot = await context.sandbox.browser.screenshot(full_page=True)
runCode
Execute code within the sandbox's built-in Jupyter kernel. Variables are retained across invocations.
runCode(code, opts?) / run_code(...) — Executes code. The opts parameter supports language (defaults to python, also supports javascript / r / bash) and timeout (in seconds). It returns Execution { results, logs, error }.TS example:
// Process CSV and generate images using Python.const exec = await context.sandbox.runCode(`import pandas as pddf = pd.read_csv('/work/data.csv')df.plot().get_figure().savefig('/work/out.png')print('done')`, { language: 'python' })
python example:
exec = await context.sandbox.run_code("""import pandas as pddf = pd.read_csv('/work/data.csv')df.plot().get_figure().savefig('/work/out.png')print('done')""",language='python',)
persist(options)
Save the content in the specified project directory as a persistent checkpoint for the current project. The archive size limit is 25 MiB. Dependencies, build outputs, version control, and cache directories are excluded by default. You can also use
exclude to add directory names to exclude.Parameters
Parameter | Type | Required | Description |
path | string | Yes | Non-root project directory that needs to be persisted. |
exclude | string[] | No | Additional directory names to exclude. By default, node_modules, .next, .git, dist, build, out, coverage, .cache, .turbo, .vite, .parcel-cache, __pycache__, .venv, venv, and .edgeone are excluded. |
timeout | number | No | Timeout for the entire persistence operation, in seconds. Defaults to 180 seconds. Must be a positive integer. |
Return value:
{size: number;sha256: string;etag: string;persistedAt: string;}
TypeScript Example
const projectPath = 'projects/<conversation_id>/app';const persisted = await context.sandbox.persist({path: projectPath,timeout: 180,});console.log(persisted.size, persisted.persistedAt);
restore(options)
Attempts to restore the persisted project content to a specified non-root project directory. Before restoration, the archive is downloaded and verified. After a successful restoration, the target directory is replaced with the project content from the checkpoint.
Parameters
Parameter | Type | Required | Description |
path | string | Yes | Non-root target directory for restoring project content. |
timeout | number | No | Timeout for the entire restore operation, in seconds. Defaults to 180 seconds. Must be a positive integer. |
Returns when no checkpoint is available:
{restored: false;reason: 'not_found';}
Returned on successful restoration:
{restored: true;size: number;sha256: string;etag: string;persistedAt: string;}
TypeScript Example
const projectPath = 'projects/<conversation_id>/app';const restored = await context.sandbox.restore({path: projectPath,timeout: 180,});if (!restored.restored) {// If no checkpoint is available, initialize a new project workspace.await context.sandbox.files.makeDir(projectPath);// Initialize project files.}await context.sandbox.persist({path: projectPath,timeout: 180,});
The Node SDK uses object parameters, while the Python SDK uses keyword parameters. For example:
await sandbox.persist(path='/home/user/project',exclude=['tmp'],timeout=180,)restored = await sandbox.restore(path='/home/user/project',timeout=180,)
It is recommended to call
restore() when the project workspace is initialized, and to wait for persist() to complete after important files are modified or tasks are stopped, or before the sandbox instance is released.persist() and restore() only process the project content in the specified directory. Running processes, browser state, temporary environment state, and preview URLs are not guaranteed to be persisted. After restoring a project, if a preview is required, restart the service and obtain a new preview URL. Archived content does not pass through Agent Runtime memory. Storage and request traffic are counted toward the Blob quota of the current project.Persistence-Related Error Codes
Error Code | Description |
SANDBOX_LIMIT_EXCEEDED | The archive exceeds 25 MiB or triggers other sandbox resource quota limits. |
SANDBOX_CONFLICT | Another persistence operation is already in progress in the same conversation, or a conflict occurs in the ownership of the uploaded checkpoint. |
SANDBOX_DATA_CORRUPTED | The size, hash, or content verification of the persistent archive fails. |
SANDBOX_FAILED_OPERATION | A command, upload, download, or service operation fails during persistence or restoration. |
