Daytona
Run Daytona workspaces through the normalized SDK API.
Daytona provides persistent workspaces with files, processes, authenticated previews, custom images, and native compute controls.
Installation
bun add @opencoredev/sandbox-sdk ai zod @daytona/sdkAuthentication
Set DAYTONA_API_KEY, or pass apiKey to daytona(). DAYTONA_API_URL and DAYTONA_TARGET select a custom endpoint or target.
Run a command
import { createSandbox } from "@opencoredev/sandbox-sdk";
import { daytona } from "@opencoredev/sandbox-sdk/daytona";
await using sandbox = await createSandbox({ provider: daytona() });
const result = await sandbox.run("node --version");
console.log(result.stdout);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.
import { ToolLoopAgent, type LanguageModel } from "ai";import { createSandbox } from "@opencoredev/sandbox-sdk";import { createSandboxToolApproval, createSandboxTools, toAISandboxSession,} from "@opencoredev/sandbox-sdk/ai";import { daytona } from "@opencoredev/sandbox-sdk/daytona";export async function runSandboxAgent(model: LanguageModel) { await using sandbox = await createSandbox({ provider: daytona(), }); 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.
Files and processes
await sandbox.files.write("index.mjs", `console.log("ready")`);
const process = await sandbox.processes.start("node index.mjs");
for await (const event of process.output()) {
console.log(event.stream, event.data);
}Daytona supports persistent files, background processes, stdin, cancellation, and separate background output streams.
Ports and snapshots
Private previews keep the Daytona token inside preview.request(). Daytona snapshot and fork operations create provider resources, so they remain on sandbox.raw instead of the normalized in-place snapshot API.
const preview = await sandbox.ports.expose(3000);
const response = preview.request ? await preview.request("/") : await fetch(preview.url);Options
| Option | Type | Default | Behavior |
|---|---|---|---|
apiKey | string | DAYTONA_API_KEY | Authenticates Daytona requests. |
apiUrl | string | DAYTONA_API_URL | Selects the API endpoint. |
target | string | DAYTONA_TARGET | Selects the execution target. |
image | string | Provider default | Creates the workspace from an image. |
language | string | Provider default | Selects the workspace language. |
name | string | Generated | Sets the sandbox name. |
public | boolean | Provider default | Controls whether preview URLs are public. |
Behavior
- Foreground command output is combined; background events retain separate stdout and stderr streams.
- The filesystem persists with the Daytona workspace.
- Custom images, PTY, network controls, and GPU configuration remain available through
sandbox.raw. - Some binary and streaming methods require a Node.js-compatible runtime.
Read next
See Processes, compare exact modes in Compatibility, or connect Daytona to HarnessAgent.