KODE SDK supports OpenSandbox as a sandbox backend for isolated command execution and file operations.
| Feature | Description |
|---|---|
| Deployment | Self-hosted OpenSandbox server |
| Runtime | Container-based isolated execution environment |
| Lifecycle | Create/connect/dispose by sandboxId |
| Compatibility | Works with existing bash_* and fs_* tools |
| Scenario | Recommended |
|---|---|
| You need self-hosted control in your own infra | OpenSandbox |
| You want fully managed cloud sandbox | E2B |
| Local development and offline debugging | Local Sandbox |
- Docker daemon is running and can pull required images.
- OpenSandbox server is running (for example on
http://127.0.0.1:8080). - If your server enables auth, prepare an API key.
Optional environment variables:
export OPEN_SANDBOX_API_KEY=... # optional, only when auth is enabled
export OPEN_SANDBOX_ENDPOINT=http://127.0.0.1:8080 # optional
export OPEN_SANDBOX_IMAGE=ubuntu # optionalimport { OpenSandbox } from '@shareai-lab/kode-sdk';
const sandbox = new OpenSandbox({
kind: 'opensandbox',
apiKey: process.env.OPEN_SANDBOX_API_KEY,
endpoint: process.env.OPEN_SANDBOX_ENDPOINT,
image: process.env.OPEN_SANDBOX_IMAGE || 'ubuntu',
timeoutMs: 600_000,
execTimeoutMs: 120_000,
useServerProxy: false,
watch: { mode: 'polling', pollIntervalMs: 1000 },
lifecycle: { disposeAction: 'kill' },
});
await sandbox.init();
console.log('sandboxId:', sandbox.getSandboxId());
const result = await sandbox.exec('echo "hello opensandbox"');
console.log(result.code, result.stdout.trim());
await sandbox.fs.write('demo.txt', 'hello from opensandbox');
const content = await sandbox.fs.read('demo.txt');
console.log(content.trim());
await sandbox.dispose();interface OpenSandboxOptions {
kind: 'opensandbox';
apiKey?: string;
endpoint?: string;
domain?: string;
protocol?: 'http' | 'https';
sandboxId?: string;
image?: string;
template?: string; // alias of image in current implementation
workDir?: string; // default '/workspace'
timeoutMs?: number;
execTimeoutMs?: number;
requestTimeoutSeconds?: number;
useServerProxy?: boolean; // default false
env?: Record<string, string>;
metadata?: Record<string, string>;
resource?: Record<string, string>;
networkPolicy?: Record<string, any>;
skipHealthCheck?: boolean;
readyTimeoutSeconds?: number;
healthCheckPollingInterval?: number;
watch?: {
mode?: 'native' | 'polling' | 'off'; // default 'polling'
pollIntervalMs?: number; // default 1000
};
lifecycle?: {
disposeAction?: 'close' | 'kill'; // default 'kill'
};
}| Variable | Description |
|---|---|
OPEN_SANDBOX_API_KEY |
Optional API key (required only when server auth is enabled) |
OPEN_SANDBOX_ENDPOINT |
OpenSandbox server endpoint |
OPEN_SANDBOX_IMAGE |
Default image when creating a new sandbox |
const agent = await Agent.create({
templateId: 'coder',
sandbox: {
kind: 'opensandbox',
endpoint: process.env.OPEN_SANDBOX_ENDPOINT,
apiKey: process.env.OPEN_SANDBOX_API_KEY,
image: 'debian:latest',
lifecycle: { disposeAction: 'kill' },
},
}, deps);When you pass sandbox config, SandboxFactory.createAsync() initializes OpenSandbox automatically.
const sandbox = new OpenSandbox({ kind: 'opensandbox', endpoint: 'http://127.0.0.1:8080' });
await sandbox.init();
const agent = await Agent.create({ templateId: 'coder', sandbox }, deps);When you pass sandbox instance directly, call sandbox.init() yourself before Agent.create().
const sandbox = new OpenSandbox({ kind: 'opensandbox', endpoint: 'http://127.0.0.1:8080' });
await sandbox.init();
const id = sandbox.getSandboxId();
const restored = new OpenSandbox({
kind: 'opensandbox',
endpoint: 'http://127.0.0.1:8080',
sandboxId: id,
});
await restored.init();watch.mode='native'usesinotifywaitin the sandbox container.- If
inotifywaitis unavailable or native stream exits unexpectedly, the SDK auto-falls back to polling mode. watch.mode='off'disables file watch registration.disposeAction='kill'performskill()first, thenclose().disposeAction='close'only closes the connection.- Polling watch is level-triggered by mtime delta and may coalesce multiple writes within one polling interval.
- Polling watch does not guarantee one callback per write operation; treat events as "file changed" hints.
DOCKER::SANDBOX_IMAGE_PULL_FAILEDorDOCKER::SANDBOX_EXECD_START_FAILED: Docker cannot pull required images (imageandopensandbox/execd).- Verify OpenSandbox server endpoint is reachable from the SDK process.
- If you use a proxy, verify Docker daemon proxy and OpenSandbox server network settings separately.