Sandbox SDK
Providers

Ascii Box

Run Ascii Box cloud VMs through the normalized SDK API.

Provider docs

Ascii Box provides persistent Linux VMs with files, bounded commands, HTTPS previews, desktop access, and stop/resume snapshots.

Installation

Terminal
bun add @opencoredev/sandbox-sdk ai zod @asciidev/box-sdk

Authentication

Create an API key in the Box dashboard, then set BOX_API_KEY on the server that creates sandboxes.

.env
BOX_API_KEY=box_your_key

Pass apiKey to box() only when environment-based configuration is not available.

Run a command

box.ts
import { createSandbox } from "@opencoredev/sandbox-sdk";
import { box } from "@opencoredev/sandbox-sdk/box";

await using sandbox = await createSandbox({ provider: box() });
await sandbox.files.write("hello.txt", "hello from Box");
console.log((await sandbox.run("cat hello.txt")).stdout);

The Box command API separates stdout and stderr. Commands default to 30 seconds and support at most 60 seconds. The API does not expose a streaming or background-process handle, so sandbox.processes.start() returns an unsupported error.

Run an AI SDK agent

This provider works with AI SDK ToolLoopAgent through the normalized sandbox session. Pass the language model from your existing AI SDK provider or AI Gateway setup.

sandbox-agent.ts
import { ToolLoopAgent, type LanguageModel } from "ai";import { createSandbox } from "@opencoredev/sandbox-sdk";import {  createSandboxToolApproval,  createSandboxTools,  toAISandboxSession,} from "@opencoredev/sandbox-sdk/ai";import { box } from "@opencoredev/sandbox-sdk/box";export async function runSandboxAgent(model: LanguageModel) {  await using sandbox = await createSandbox({    provider: box({ ttlSeconds: 900 }),  });  const aiSandbox = toAISandboxSession(sandbox);  const agent = new ToolLoopAgent({    model,    instructions: `Work only in the provided sandbox.\n\n${aiSandbox.description}`,    tools: createSandboxTools(),    toolApproval: createSandboxToolApproval(),  });  return await agent.generate({    prompt: "Inspect the repository, run its tests, and summarize the result.",    experimental_sandbox: aiSandbox,  });}

See the AI SDK guide for approval flows, direct session access, and HarnessAgent alternatives.

Expose a preview

Start the server in the Box, bind it to 0.0.0.0, then expose its port.

preview.ts
const preview = await sandbox.ports.expose(3000);
const response = await preview.request!("/health");

The adapter requests a public Box URL by default because that mode passed end-to-end live validation. Pass box({ public: false }) to request Box's native token-gated mode; the adapter removes _token from preview.url and keeps it inside request().

Managed lifecycle

The managed provider surface maps stop() to Box archive/snapshot, resume() to native resume, and destroy() to deletion. Normal sandbox.stop() performs full cleanup: it archives a running Box when required, waits for that transition, then deletes it.

Use sandbox.raw.client for native prompts, events, desktop streaming, forks, and snapshot inspection. The current native Box model is available at sandbox.raw.box.

Options

OptionTypeDefaultBehavior
apiKeystringBOX_API_KEYAuthenticates Box API requests.
baseUrlstringBOX_BASE_URL or public v1 URLOverrides the Box API endpoint.
ttlSecondsnumber | nullBox service defaultSets auto-archive; null disables it.
noEnvbooleanfalseWithholds account-level secrets from the Box.
namestringGenerated by BoxApplies a friendly name after provisioning.
publicbooleantrueReturns ungated hosted URLs when true.
readyTimeoutnumber600000Limits the provisioning wait in milliseconds.

Per-sandbox values passed to createSandbox({ env }) are sent through Box's native env field. Box accepts at most 100 variables and 64 KB total.

See Ports, compare exact modes in Compatibility, or open the Box SDK guide.

On this page