Sandbox

Docker-backed sandbox sessions and agent tool helpers from @anvia/sandbox.

Import from @anvia/sandbox.

DockerSandbox

class DockerSandbox implements Sandbox {
  readonly provider: "docker";
  constructor(options?: DockerSandboxOptions);
  static node(options?: DockerSandboxOptions): DockerSandbox;
  static python(options?: DockerSandboxOptions): DockerSandbox;
  static deno(options?: DockerSandboxOptions): DockerSandbox;
  createSession(options?: SandboxCreateSessionOptions): Promise<SandboxSession>;
}

Purpose: create ephemeral Docker-backed workspace sessions for running untrusted or model-generated code outside the host process.

Return behavior: createSession(...) creates one container and one Docker volume mounted at the session workdir. Call destroy() on the returned SandboxSession to remove both resources.

Notable errors: throws SandboxDockerUnavailableError when the Docker CLI is missing, SandboxDockerCommandError when Docker setup fails, and SandboxPathError for unsafe manifest paths.

Sandbox Interfaces

interface Sandbox {
  readonly provider: string;
  createSession(options?: SandboxCreateSessionOptions): Promise<SandboxSession>;
}

interface SandboxSession {
  readonly id: string;
  readonly provider: string;
  readonly workdir: string;
  exec(options: SandboxExecOptions): Promise<SandboxExecResult>;
  execStream(options: SandboxExecOptions): AsyncIterable<SandboxExecStreamEvent>;
  readFile(path: string): Promise<Uint8Array>;
  readTextFile(path: string): Promise<string>;
  writeFile(path: string, data: string | Uint8Array): Promise<void>;
  writeTextFile(path: string, content: string): Promise<void>;
  listFiles(path?: string): Promise<SandboxFileEntry[]>;
  destroy(): Promise<void>;
}

Purpose: provider-neutral contracts for sandbox clients and live workspace sessions.

Return behavior: file paths are sandbox-relative; absolute paths and traversal outside the workspace are rejected.

Session Options

type SandboxCreateSessionOptions = {
  id?: string;
  workspace?: SandboxWorkspaceOptions;
  manifest?: SandboxManifest;
  metadata?: Record<string, string>;
};

type SandboxWorkspaceOptions =
  | { mode?: "ephemeral" }
  | {
      mode: "persistent";
      id: string;
      destroyOnSessionDestroy?: boolean;
    };

type SandboxManifest = {
  files?: Record<string, string | Uint8Array>;
  directories?: string[];
  env?: Record<string, string>;
};

type SandboxLimits = {
  timeoutMs?: number;
  maxOutputBytes?: number;
  maxFileBytes?: number;
  memoryMb?: number;
  cpus?: number;
  pidsLimit?: number;
};

type SandboxLifecycleOptions = {
  ttlMs?: number;
  idleTimeoutMs?: number;
  autoDestroy?: boolean;
};

Purpose: seed files, directories, environment, metadata, workspace mode, lifecycle cleanup, and runtime limits for a sandbox session.

Docker Options

type DockerSandboxOptions = {
  image?: string;
  pull?: "missing" | "always" | "never";
  workdir?: string;
  workspace?: SandboxWorkspaceOptions;
  lifecycle?: SandboxLifecycleOptions;
  network?: SandboxNetworkMode | DockerSandboxNetworkOptions;
  user?: string;
  dockerPath?: string;
  labels?: Record<string, string>;
  limits?: SandboxLimits;
  security?: DockerSandboxSecurityOptions;
  hooks?: SandboxHooks;
};

type DockerSandboxSecurityOptions = {
  readonlyRootfs?: boolean;
  noNewPrivileges?: boolean;
  dropCapabilities?: string[];
};

type DockerSandboxNetworkOptions = {
  mode: SandboxNetworkMode;
};

type SandboxNetworkMode = boolean | "none" | "host" | string;

Defaults: image is node:22-bookworm, pull is missing, workdir is /workspace, network access is disabled, noNewPrivileges is enabled, and Docker capabilities are dropped with ["ALL"].

Static presets: DockerSandbox.node(...), DockerSandbox.python(...), and DockerSandbox.deno(...) create sandboxes with language-specific default images.

Execution

type SandboxExecOptions = {
  command: string;
  args?: string[];
  cwd?: string;
  env?: Record<string, string>;
  timeoutMs?: number;
  input?: string | Uint8Array;
  signal?: AbortSignal;
  onStdout?: (chunk: Uint8Array) => void;
  onStderr?: (chunk: Uint8Array) => void;
};

type SandboxExecResult = {
  stdout: string;
  stderr: string;
  exitCode: number;
  durationMs: number;
  timedOut: boolean;
  aborted: boolean;
  stdoutTruncated: boolean;
  stderrTruncated: boolean;
};

type SandboxExecStreamEvent =
  | { type: "stdout"; chunk: Uint8Array; text: string }
  | { type: "stderr"; chunk: Uint8Array; text: string }
  | { type: "exit"; result: SandboxExecResult };

Return behavior: non-zero command exits are returned in SandboxExecResult; infrastructure failures throw. execStream(...) yields stdout and stderr chunks as they arrive, then yields one exit event with the final result.

Files

type SandboxFileType = "file" | "directory" | "symlink" | "other";

type SandboxFileEntry = {
  path: string;
  type: SandboxFileType;
  size?: number;
};

Purpose: typed file-listing results from SandboxSession.listFiles(...).

Agent Tools

function createSandboxTools(
  session: SandboxSession,
  options?: SandboxToolsOptions,
): AnyTool[];

type SandboxToolsOptions = {
  allow?: SandboxToolName[];
  include?: SandboxToolName[];
  execTimeoutMs?: number;
  exec?: SandboxExecToolPolicy;
  readFile?: SandboxFileToolPolicy;
  writeFile?: SandboxFileToolPolicy;
};

type SandboxToolName =
  | "exec_command"
  | "read_file"
  | "write_file"
  | "list_files";

type SandboxExecToolPolicy = {
  allowedCommands?: string[];
  blockedCommands?: string[];
  defaultTimeoutMs?: number;
  maxTimeoutMs?: number;
};

type SandboxFileToolPolicy = {
  maxBytes?: number;
};

type SandboxToolsFactory = (
  session: SandboxSession,
  options?: SandboxToolsOptions,
) => AnyTool[];

Purpose: expose a live sandbox session as Anvia tools. The default bundle includes exec_command, read_file, write_file, and list_files. Use allow or include to select tools and SandboxExecToolPolicy or SandboxFileToolPolicy to bound model-facing operations.

Hooks

type SandboxHooks = {
  onSessionCreate?: (event: SandboxSessionEvent) => void | Promise<void>;
  onExecStart?: (event: SandboxExecEvent) => void | Promise<void>;
  onExecEnd?: (event: SandboxExecEndEvent) => void | Promise<void>;
  onFileWrite?: (event: SandboxFileWriteEvent) => void | Promise<void>;
  onDestroy?: (event: SandboxSessionEvent) => void | Promise<void>;
};

type SandboxSessionEvent = {
  sessionId: string;
  provider: string;
  workdir: string;
};

type SandboxExecEvent = SandboxSessionEvent & {
  command: string;
  args: string[];
  cwd?: string;
};

type SandboxExecEndEvent = SandboxExecEvent & {
  result: SandboxExecResult;
};

type SandboxFileWriteEvent = SandboxSessionEvent & {
  path: string;
  size: number;
};

Purpose: observe session creation, command execution, file writes, and cleanup without exposing those details to the model.

For workflow guidance, see Sandbox and the tools:11 cookbook example.

Errors

class SandboxError extends Error {}
class SandboxDockerUnavailableError extends SandboxError {}
class SandboxDockerCommandError extends SandboxError {}
class SandboxSessionDestroyedError extends SandboxError {}
class SandboxPathError extends SandboxError {}
class SandboxTimeoutError extends SandboxError {}
class SandboxFileSizeError extends SandboxError {}
class SandboxToolPolicyError extends SandboxError {}

Purpose: typed failures for Docker setup, path validation, destroyed sessions, file size limits, tool policy limits, and sandbox operations.