@mastra/daytona 0.10.0-alpha.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +9 -343
  2. package/package.json +7 -7
package/README.md CHANGED
@@ -4,13 +4,10 @@ Daytona cloud sandbox provider for [Mastra](https://mastra.ai) workspaces.
4
4
 
5
5
  Implements the `WorkspaceSandbox` interface using [Daytona](https://www.daytona.io/) sandboxes. Supports multiple runtimes, resource configuration, volumes, snapshots, streaming output, sandbox reconnection, and filesystem mounting (S3, GCS, Azure Blob).
6
6
 
7
- ## Install
7
+ ## Installation
8
8
 
9
9
  ```bash
10
- pnpm add @mastra/daytona @mastra/core
11
-
12
- # For filesystem mounting (optional)
13
- pnpm add @mastra/s3 @mastra/gcs @mastra/azure
10
+ npm install @mastra/daytona
14
11
  ```
15
12
 
16
13
  ## Usage
@@ -35,346 +32,15 @@ console.log(result.stdout); // "Hello!"
35
32
  await workspace.destroy();
36
33
  ```
37
34
 
38
- ### Snapshot
39
-
40
- Use a pre-built snapshot to skip environment setup time:
41
-
42
- ```typescript
43
- const sandbox = new DaytonaSandbox({
44
- snapshot: 'my-snapshot-id',
45
- timeout: 60_000,
46
- });
47
- ```
48
-
49
- ### Custom image with resources
50
-
51
- Use a custom Docker image with specific resource allocation:
52
-
53
- ```typescript
54
- const sandbox = new DaytonaSandbox({
55
- image: 'node:20-slim',
56
- resources: { cpu: 2, memory: 4, disk: 6 },
57
- language: 'typescript',
58
- });
59
- ```
60
-
61
- ### Ephemeral sandbox
62
-
63
- For one-shot tasks — sandbox is deleted immediately on stop:
64
-
65
- ```typescript
66
- const sandbox = new DaytonaSandbox({
67
- ephemeral: true,
68
- language: 'python',
69
- });
70
- ```
71
-
72
- ### Streaming output
35
+ ## Documentation
73
36
 
74
- Stream command output in real time via callbacks:
75
-
76
- ```typescript
77
- await sandbox.executeCommand('bash', ['-c', 'for i in 1 2 3; do echo "line $i"; sleep 1; done'], {
78
- onStdout: chunk => process.stdout.write(chunk),
79
- onStderr: chunk => process.stderr.write(chunk),
80
- });
81
- ```
82
-
83
- ### Reconnection
84
-
85
- Reconnect to an existing sandbox by providing the same `id`. The sandbox resumes with its files and state intact:
86
-
87
- ```typescript
88
- const sandbox = new DaytonaSandbox({ id: 'my-persistent-sandbox' });
37
+ - [Daytona integration guide](https://mastra.ai/integrations/sandboxes/daytona)
38
+ - [Workspace documentation](https://mastra.ai/docs/mastra-platform/workspaces)
89
39
 
90
- // First session
91
- await sandbox._start();
92
- await sandbox.executeCommand('sh', ['-c', 'echo "session 1" > /tmp/state.txt']);
93
- await sandbox._stop();
40
+ ## Changelog
94
41
 
95
- // Later reconnects to the same sandbox
96
- const sandbox2 = new DaytonaSandbox({ id: 'my-persistent-sandbox' });
97
- await sandbox2._start();
98
- const result = await sandbox2.executeCommand('cat', ['/tmp/state.txt']);
99
- console.log(result.stdout); // "session 1"
100
- ```
101
-
102
- ### Filesystem mounting
103
-
104
- Mount S3, GCS, or Azure Blob containers as local directories inside the sandbox.
105
-
106
- #### Via workspace mounts config
107
-
108
- The simplest way — filesystems are mounted automatically when the sandbox starts:
109
-
110
- ```typescript
111
- import { Workspace } from '@mastra/core/workspace';
112
- import { DaytonaSandbox } from '@mastra/daytona';
113
- import { GCSFilesystem } from '@mastra/gcs';
114
- import { S3Filesystem } from '@mastra/s3';
115
- import { AzureBlobFilesystem } from '@mastra/azure/blob';
116
-
117
- const workspace = new Workspace({
118
- mounts: {
119
- '/s3-data': new S3Filesystem({
120
- bucket: process.env.S3_BUCKET!,
121
- region: 'auto',
122
- accessKeyId: process.env.S3_ACCESS_KEY_ID,
123
- secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
124
- endpoint: process.env.S3_ENDPOINT, // e.g. https://<account-id>.r2.cloudflarestorage.com
125
- }),
126
- '/gcs-data': new GCSFilesystem({
127
- bucket: process.env.GCS_BUCKET!,
128
- projectId: 'my-project-id',
129
- credentials: JSON.parse(process.env.GCS_SERVICE_ACCOUNT_KEY!),
130
- }),
131
- '/azure-data': new AzureBlobFilesystem({
132
- container: process.env.AZURE_STORAGE_CONTAINER!,
133
- connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING,
134
- prefix: 'workspace/data',
135
- }),
136
- },
137
- sandbox: new DaytonaSandbox({ language: 'python' }),
138
- });
139
- ```
140
-
141
- #### Via sandbox.mount()
142
-
143
- Mount manually at any point after the sandbox has started:
144
-
145
- #### S3
146
-
147
- ```typescript
148
- import { DaytonaSandbox } from '@mastra/daytona';
149
- import { S3Filesystem } from '@mastra/s3';
150
-
151
- const sandbox = new DaytonaSandbox({ language: 'python' });
152
- await sandbox._start();
153
-
154
- await sandbox.mount(
155
- new S3Filesystem({
156
- bucket: process.env.S3_BUCKET!,
157
- region: 'us-east-1',
158
- accessKeyId: process.env.S3_ACCESS_KEY_ID,
159
- secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
160
- }),
161
- '/data',
162
- );
163
-
164
- // Files in the bucket are now accessible at /data
165
- const result = await sandbox.executeCommand('ls', ['/data']);
166
- console.log(result.stdout);
167
-
168
- await sandbox._stop(); // Unmounts automatically before stopping
169
- ```
170
-
171
- #### S3-compatible (Cloudflare R2, MinIO)
172
-
173
- ```typescript
174
- import { S3Filesystem } from '@mastra/s3';
175
-
176
- await sandbox.mount(
177
- new S3Filesystem({
178
- bucket: process.env.S3_BUCKET!,
179
- region: 'auto',
180
- accessKeyId: process.env.S3_ACCESS_KEY_ID,
181
- secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
182
- endpoint: process.env.S3_ENDPOINT, // e.g. https://<account-id>.r2.cloudflarestorage.com
183
- }),
184
- '/data',
185
- );
186
- ```
187
-
188
- #### GCS
189
-
190
- ```typescript
191
- import { GCSFilesystem } from '@mastra/gcs';
192
-
193
- await sandbox.mount(
194
- new GCSFilesystem({
195
- bucket: process.env.GCS_BUCKET!,
196
- projectId: 'my-project-id',
197
- credentials: JSON.parse(process.env.GCS_SERVICE_ACCOUNT_KEY!),
198
- }),
199
- '/data',
200
- );
201
- ```
202
-
203
- #### Azure Blob
204
-
205
- ```typescript
206
- import { AzureBlobFilesystem } from '@mastra/azure/blob';
207
-
208
- await sandbox.mount(
209
- new AzureBlobFilesystem({
210
- container: process.env.AZURE_STORAGE_CONTAINER!,
211
- connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING,
212
- prefix: 'workspace/data',
213
- }),
214
- '/data',
215
- );
216
- ```
217
-
218
- ### Network isolation
219
-
220
- Restrict outbound network access:
221
-
222
- ```typescript
223
- const sandbox = new DaytonaSandbox({
224
- networkBlockAll: true,
225
- networkAllowList: '10.0.0.0/8,192.168.0.0/16',
226
- });
227
- ```
228
-
229
- ### With Agent
230
-
231
- Wire a Daytona sandbox into a Mastra agent to give it code execution in an isolated sandbox:
232
-
233
- ```typescript
234
- import { Agent } from '@mastra/core/agent';
235
- import { Workspace } from '@mastra/core/workspace';
236
- import { DaytonaSandbox } from '@mastra/daytona';
237
-
238
- const sandbox = new DaytonaSandbox({
239
- language: 'typescript',
240
- timeout: 120_000,
241
- });
242
-
243
- const workspace = new Workspace({ sandbox });
244
-
245
- const agent = new Agent({
246
- id: 'code-agent',
247
- name: 'Code Agent',
248
- instructions: 'You are a coding assistant working in this workspace.',
249
- model: 'anthropic/claude-sonnet-4-6',
250
- workspace,
251
- });
252
-
253
- const response = await agent.generate('Print "Hello, world!" and show the current working directory.');
254
-
255
- console.log(response.text);
256
- // I'll run both commands simultaneously!
257
- //
258
- // Here are the results:
259
- //
260
- // 1. **Hello, world!** — Successfully printed the message.
261
- // 2. **Current Working Directory** — `/home/daytona`
262
- //
263
- // Both commands ran in parallel and completed successfully!
264
- ```
265
-
266
- ## Configuration
267
-
268
- | Option | Type | Default | Description |
269
- | --------------------- | --------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
270
- | `id` | `string` | auto-generated | Sandbox identifier |
271
- | `apiKey` | `string` | `DAYTONA_API_KEY` env | API key |
272
- | `apiUrl` | `string` | `DAYTONA_API_URL` env | API endpoint |
273
- | `target` | `string` | `DAYTONA_TARGET` env | Runner region |
274
- | `timeout` | `number` | `300000` | Default execution timeout (ms) |
275
- | `language` | `string` | `'typescript'` | Runtime language |
276
- | `snapshot` | `string` | — | Pre-built snapshot ID. Takes precedence over `image`. |
277
- | `image` | `string` | — | Docker image for sandbox creation. Triggers image-based creation when set. Can be combined with `resources`. Ignored when `snapshot` is set. |
278
- | `resources` | `object` | SDK defaults | `{ cpu, memory, disk }`. Only used with `image`. |
279
- | `env` | `object` | `{}` | Environment variables |
280
- | `labels` | `object` | `{}` | Custom metadata labels |
281
- | `name` | `string` | sandbox `id` | Sandbox display name |
282
- | `user` | `string` | `daytona` | OS user to run commands as |
283
- | `public` | `boolean` | `false` | Make port previews public |
284
- | `ephemeral` | `boolean` | `false` | Delete sandbox immediately on stop |
285
- | `autoStopInterval` | `number` | `15` | Auto-stop interval in minutes (0 = disabled) |
286
- | `autoArchiveInterval` | `number` | `7 days` | Auto-archive interval in minutes (0 = 7 days) |
287
- | `autoDeleteInterval` | `number` | `disabled` | Auto-delete interval in minutes (negative = disabled, 0 = delete on stop) |
288
- | `volumes` | `array` | — | `[{ volumeId, mountPath }]` |
289
- | `networkBlockAll` | `boolean` | `false` | Block all network access |
290
- | `networkAllowList` | `string` | — | Comma-separated allowed CIDR addresses |
291
-
292
- ## Mount Configuration
293
-
294
- Pass `S3Filesystem`, `GCSFilesystem`, or `AzureBlobFilesystem` instances via the workspace `mounts` config or directly to `sandbox.mount()`.
295
-
296
- ### S3 environment variables
297
-
298
- | Variable | Description |
299
- | ---------------------- | --------------------------------- |
300
- | `S3_BUCKET` | Bucket name |
301
- | `S3_REGION` | AWS region or `auto` for R2/MinIO |
302
- | `S3_ACCESS_KEY_ID` | Access key ID |
303
- | `S3_SECRET_ACCESS_KEY` | Secret access key |
304
- | `S3_ENDPOINT` | Endpoint URL (S3-compatible only) |
305
-
306
- ### GCS environment variables
307
-
308
- | Variable | Description |
309
- | ------------------------- | ------------------------------------------------------- |
310
- | `GCS_BUCKET` | Bucket name |
311
- | `GCS_SERVICE_ACCOUNT_KEY` | Service account key JSON (full JSON string, not a path) |
312
-
313
- ### Azure Blob environment variables
314
-
315
- | Variable | Description |
316
- | --------------------------------- | ------------------------- |
317
- | `AZURE_STORAGE_CONTAINER` | Container name |
318
- | `AZURE_STORAGE_CONNECTION_STRING` | Storage connection string |
319
-
320
- ### Reducing cold start latency with a snapshot
321
-
322
- By default, `s3fs`, `gcsfuse`, and `blobfuse2` are installed at first mount, which adds startup time. To eliminate this, prebake them into a Daytona snapshot and pass the snapshot name via the `snapshot` option.
323
-
324
- Create the snapshot once:
325
-
326
- ```typescript
327
- import { Daytona, Image } from '@daytonaio/sdk';
328
-
329
- const template = Image.base('daytonaio/sandbox')
330
- .runCommands('sudo apt-get update -qq')
331
- .runCommands('sudo apt-get install -y s3fs')
332
- // gcsfuse requires the Google Cloud apt repository
333
- .runCommands(
334
- 'sudo mkdir -p /etc/apt/keyrings && ' +
335
- 'curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg -o /tmp/gcsfuse-key.gpg && ' +
336
- 'sudo gpg --batch --yes --dearmor -o /etc/apt/keyrings/gcsfuse.gpg /tmp/gcsfuse-key.gpg && ' +
337
- // Use gcsfuse-jammy for Ubuntu, gcsfuse-bookworm for Debian
338
- 'echo "deb [signed-by=/etc/apt/keyrings/gcsfuse.gpg] https://packages.cloud.google.com/apt gcsfuse-jammy main" | sudo tee /etc/apt/sources.list.d/gcsfuse.list',
339
- )
340
- .runCommands('sudo apt-get update -qq && sudo apt-get install -y gcsfuse');
341
-
342
- const daytona = new Daytona();
343
- await daytona.snapshot.create(
344
- {
345
- name: 'cloud-fs-mounting',
346
- image: template,
347
- },
348
- { onLogs: console.log },
349
- );
350
- ```
351
-
352
- If you use Azure Blob mounts, also pre-install `blobfuse2` in the snapshot using Azure's supported package for your base image. See Azure's [BlobFuse2 installation guide](https://learn.microsoft.com/en-us/azure/storage/blobs/blobfuse2-how-to-deploy) for supported install options.
353
-
354
- Then use the snapshot name in your sandbox config:
355
-
356
- ```typescript
357
- const workspace = new Workspace({
358
- mounts: {
359
- '/s3-data': new S3Filesystem({/* ... */}),
360
- '/gcs-data': new GCSFilesystem({/* ... */}),
361
- },
362
- sandbox: new DaytonaSandbox({ snapshot: 'cloud-fs-mounting' }),
363
- });
364
- ```
365
-
366
- ## Direct SDK Access
367
-
368
- Access the underlying Daytona `Sandbox` instance for filesystem, git, and other operations not exposed through WorkspaceSandbox:
369
-
370
- ```typescript
371
- const daytonaSandbox = sandbox.instance;
372
-
373
- await daytonaSandbox.fs.uploadFile(Buffer.from('data'), '/tmp/file.txt');
374
-
375
- await daytonaSandbox.git.clone('https://github.com/org/repo', '/workspace/repo');
376
- ```
42
+ See the [package changelog](https://github.com/mastra-ai/mastra/blob/main/workspaces/daytona/CHANGELOG.md) for version history and release notes.
377
43
 
378
- ## License
44
+ ## Support
379
45
 
380
- Apache-2.0
46
+ We have an [open community Discord](https://discord.gg/mastra-ai). Come and say hello and let us know if you have any questions or need any help getting things running.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/daytona",
3
- "version": "0.10.0-alpha.0",
3
+ "version": "0.10.0",
4
4
  "description": "Daytona cloud sandbox provider for Mastra workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,12 +31,12 @@
31
31
  "tsdown": "0.22.9",
32
32
  "typescript": "^7.0.2",
33
33
  "vitest": "4.1.10",
34
- "@internal/lint": "0.0.129",
35
- "@internal/types-builder": "0.0.104",
36
- "@internal/workspace-test-utils": "0.0.73",
37
- "@mastra/core": "1.64.0-alpha.2",
38
- "@mastra/gcs": "0.3.3-alpha.0",
39
- "@mastra/s3": "0.6.2-alpha.0"
34
+ "@internal/types-builder": "0.0.105",
35
+ "@internal/workspace-test-utils": "0.0.74",
36
+ "@mastra/core": "1.64.0",
37
+ "@mastra/gcs": "0.3.3",
38
+ "@internal/lint": "0.0.130",
39
+ "@mastra/s3": "0.6.2"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@mastra/core": ">=1.60.0-0 <2.0.0-0"