Skip to main content

Daytona Sandbox Provider

@smthrs/daytona is a first-class Smithers SandboxProvider backed by the Daytona SDK. It runs a <Sandbox> child workflow’s request inside a Daytona sandbox: uploads the request JSON, runs the entry command, reads the result JSON back. The shared provider-kit owns the request/result protocol, egress, secret scrubbing, and cleanup; this package only maps the small SandboxSession seam onto Daytona. The provider id is daytona-sandbox (exported as DAYTONA_SANDBOX_PROVIDER_ID).

Credentials

@daytonaio/sdk is an optional dependency, imported lazily inside the session; install it to use the real provider:
Credentials come from factory options first, then the Daytona env chain, and are used only to build the local SDK client: never written into the request JSON, never forwarded into the remote sandbox env.
  • DAYTONA_API_KEY: API key (required for a real client).
  • DAYTONA_API_URL: API base url (optional).
  • DAYTONA_TARGET: target region (optional).
The same values may be passed as apiKey, apiUrl, and target factory options, or through clientOptions.

Usage

Pass the provider straight to <Sandbox>:
Or register it once and reference it by id:

Request/result contract

The kit writes the request JSON to .smithers/sandbox-request.json in the workdir and hands the entry command two env vars:
  • SMITHERS_SANDBOX_REQUEST_PATH: where to read the request JSON.
  • SMITHERS_SANDBOX_RESULT_PATH: where to write the result JSON.
The entry command either prints the result JSON to stdout or writes it to SMITHERS_SANDBOX_RESULT_PATH. The result is { bundlePath } or a structured { status, output|outputs, patches?, diffBundle?, runId? }. The kit fills remoteRunId/workspaceId from the Daytona sandbox id when the entry omits them.

Factory options

  • image or snapshot: the base for daytona.create (pass one, not both).
  • autoStopInterval: minutes idle before Daytona auto-stops (default 15).
  • ephemeral: delete the sandbox on disconnect (default true).
  • resources, labels, env: forwarded to daytona.create.
  • command: entry command (default node /workspace/run-smithers-sandbox.js).
  • workdir: default /workspace.
  • cleanup: "destroy" (default) or "keep".
  • client / clientOptions: inject an SDK client or its constructor options.
Per-run request.config may carry image, snapshot, resources, labels, or a workspace block (snapshotId, idleTimeoutSecs, persistence: "ephemeral"), mapped onto the create options.

SDK subset used

daytona.create({ image?|snapshot?, envVars, labels, ephemeral, autoStopInterval, resources }), sandbox.fs.uploadFile(Buffer, path), sandbox.fs.downloadFile(path), sandbox.process.executeCommand(command, cwd, env, timeoutSecs) (Daytona merges stderr into result), and daytona.delete(sandbox).

Cleanup and cost

cleanup: "destroy" (default) deletes the sandbox after the run; cleanup: "keep" leaves it running. ephemeral plus autoStopInterval bound idle cost even when cleanup is skipped, so a crashed orchestrator doesn’t leave a sandbox billing forever. You pay for Daytona sandbox time from create to teardown. createMockDaytonaSandboxEnvironment(handler, faults?) is an in-memory SDK double for tests: needs zero credentials, so unit tests run in CI without touching Daytona.