computesdk 1.10.1 → 1.10.2
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.
- package/README.md +253 -541
- package/dist/index.d.mts +24 -56
- package/dist/index.d.ts +24 -56
- package/dist/index.js +29 -189
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +29 -188
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,99 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
<img src="https://www.computesdk.com/_astro/hv_main_logo_light.CpYMD9-V.svg" alt="ComputeSDK" width="300" />
|
|
3
|
-
</div>
|
|
1
|
+
# computesdk
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
<strong>A free and open-source toolkit for running other people's code in your applications.</strong>
|
|
7
|
-
</div>
|
|
3
|
+
The gateway SDK for running code in remote sandboxes. Zero-config auto-detection with support for E2B, Modal, Railway, Daytona, Vercel, and more.
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
[](https://badge.fury.io/js/computesdk)
|
|
12
|
-
[](https://www.typescriptlang.org/)
|
|
13
|
-
[](https://opensource.org/licenses/MIT)
|
|
14
|
-
[](https://computesdk.com)
|
|
15
|
-
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## What is ComputeSDK?
|
|
21
|
-
|
|
22
|
-
ComputeSDK is a free and open-source toolkit for running other people's code in your applications. Think of it as the "AI SDK for compute" - providing a consistent TypeScript interface whether you're using Blaxel, E2B, Vercel, or Daytona.
|
|
23
|
-
|
|
24
|
-
**Why ComputeSDK?**
|
|
25
|
-
- 🔄 **Provider-agnostic** - Switch between Blaxel, E2B, Vercel, Daytona, Modal, CodeSandbox and more without code changes
|
|
26
|
-
- ⚡ **Zero-config mode** - Auto-detect provider from environment variables
|
|
27
|
-
- 🛡️ **Security-first** - Isolated sandboxes protect your infrastructure
|
|
28
|
-
- ⚡ **Developer experience** - Simple, TypeScript-native API
|
|
29
|
-
- 🌍 **Production-ready** - Used by teams building the next generation of developer tools
|
|
30
|
-
|
|
31
|
-
**Perfect for building:**
|
|
32
|
-
- **Code execution platforms** - Run user-submitted code safely
|
|
33
|
-
- **Educational tools** - Interactive coding environments
|
|
34
|
-
- **Data analysis applications** - Process code with full filesystem access
|
|
35
|
-
- **AI-powered development tools** - Let AI agents write and execute code
|
|
36
|
-
- **Testing & CI/CD systems** - Isolated test environments
|
|
37
|
-
|
|
38
|
-
## Features
|
|
39
|
-
|
|
40
|
-
- 🚀 **Multi-provider support** - Blaxel, E2B, Vercel, Daytona, Modal, CodeSandbox
|
|
41
|
-
- ⚡ **Zero-config mode** - Auto-detect provider from environment variables
|
|
42
|
-
- 📁 **Filesystem operations** - Read, write, create directories across providers
|
|
43
|
-
- 🖥️ **Terminal support** - Interactive PTY terminals with exec mode
|
|
44
|
-
- ⚡ **Command execution** - Run shell commands with PTY or exec mode
|
|
45
|
-
- 🔧 **Type-safe commands** - Build shell commands with `@computesdk/cmd`
|
|
46
|
-
- 🛡️ **Type-safe** - Full TypeScript support with comprehensive error handling
|
|
47
|
-
- 📦 **Modular** - Install only the providers you need
|
|
48
|
-
- 🔧 **Extensible** - Easy to add custom providers
|
|
49
|
-
- 🌐 **Web Framework Integration** - Built-in request handlers for Next.js, Nuxt, SvelteKit, etc.
|
|
50
|
-
- 🎨 **Frontend Integration** - Client-side hooks and utilities via @computesdk/ui
|
|
51
|
-
|
|
52
|
-
## Get Started in 30 Seconds
|
|
5
|
+
## Installation
|
|
53
6
|
|
|
54
7
|
```bash
|
|
55
|
-
# Install the core SDK
|
|
56
8
|
npm install computesdk
|
|
9
|
+
```
|
|
57
10
|
|
|
58
|
-
|
|
59
|
-
npm install @computesdk/blaxel # For AI-powered code execution
|
|
60
|
-
npm install @computesdk/e2b # For data science and Python
|
|
61
|
-
npm install @computesdk/vercel # For web-scale Node.js/Python
|
|
62
|
-
npm install @computesdk/daytona # For development workspaces
|
|
63
|
-
npm install @computesdk/modal # For GPU-accelerated Python workloads
|
|
64
|
-
npm install @computesdk/codesandbox # For collaborative sandboxes
|
|
11
|
+
## Quick Start
|
|
65
12
|
|
|
66
|
-
|
|
67
|
-
npm install @computesdk/ui # React hooks and utilities
|
|
68
|
-
```
|
|
13
|
+
### Zero-Config Mode (Recommended)
|
|
69
14
|
|
|
70
|
-
Set your environment variables and
|
|
15
|
+
Set your provider credentials as environment variables and ComputeSDK automatically detects and configures everything:
|
|
71
16
|
|
|
72
17
|
```bash
|
|
73
|
-
export
|
|
74
|
-
export BLAXEL_WORKSPACE=your_workspace
|
|
75
|
-
# or E2B_API_KEY=your_api_key
|
|
76
|
-
# or VERCEL_TOKEN=your_token
|
|
77
|
-
# or DAYTONA_API_KEY=your_key
|
|
78
|
-
# or MODAL_TOKEN_ID=your_token_id and MODAL_TOKEN_SECRET=your_token_secret
|
|
79
|
-
# or CODESANDBOX_TOKEN=your_token
|
|
18
|
+
export E2B_API_KEY=your_e2b_api_key
|
|
80
19
|
```
|
|
81
20
|
|
|
82
|
-
## Quick Start
|
|
83
|
-
|
|
84
21
|
```typescript
|
|
85
22
|
import { compute } from 'computesdk';
|
|
86
|
-
import { blaxel } from '@computesdk/blaxel';
|
|
87
|
-
|
|
88
|
-
// Set default provider
|
|
89
|
-
compute.setConfig({
|
|
90
|
-
provider: blaxel({
|
|
91
|
-
apiKey: process.env.BLAXEL_API_KEY,
|
|
92
|
-
workspace: process.env.BLAXEL_WORKSPACE
|
|
93
|
-
})
|
|
94
|
-
});
|
|
95
23
|
|
|
96
|
-
//
|
|
24
|
+
// Auto-detects E2B from environment
|
|
97
25
|
const sandbox = await compute.sandbox.create();
|
|
98
26
|
|
|
99
27
|
// Execute code
|
|
@@ -101,385 +29,258 @@ const result = await sandbox.runCode('print("Hello World!")');
|
|
|
101
29
|
console.log(result.stdout); // "Hello World!"
|
|
102
30
|
|
|
103
31
|
// Clean up
|
|
104
|
-
await
|
|
32
|
+
await sandbox.destroy();
|
|
105
33
|
```
|
|
106
34
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
ComputeSDK can automatically detect and configure your provider from environment variables:
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
# Set your ComputeSDK API key
|
|
113
|
-
export COMPUTESDK_API_KEY=your_computesdk_api_key
|
|
35
|
+
### Explicit Configuration
|
|
114
36
|
|
|
115
|
-
|
|
116
|
-
export E2B_API_KEY=your_e2b_key
|
|
117
|
-
# or export DAYTONA_API_KEY=your_daytona_key
|
|
118
|
-
# or export MODAL_TOKEN_ID=xxx MODAL_TOKEN_SECRET=xxx
|
|
119
|
-
```
|
|
37
|
+
For more control, use `setConfig()` to explicitly configure the provider:
|
|
120
38
|
|
|
121
39
|
```typescript
|
|
122
40
|
import { compute } from 'computesdk';
|
|
123
41
|
|
|
124
|
-
|
|
42
|
+
compute.setConfig({
|
|
43
|
+
provider: 'e2b',
|
|
44
|
+
e2b: { apiKey: 'your_api_key' }
|
|
45
|
+
});
|
|
46
|
+
|
|
125
47
|
const sandbox = await compute.sandbox.create();
|
|
126
|
-
const result = await sandbox.runCode('print("Hello World!")');
|
|
127
|
-
console.log(result.stdout);
|
|
128
48
|
```
|
|
129
49
|
|
|
130
|
-
|
|
50
|
+
## Supported Providers
|
|
131
51
|
|
|
132
|
-
|
|
52
|
+
ComputeSDK automatically detects providers based on environment variables:
|
|
133
53
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
54
|
+
| Provider | Environment Variables | Use Cases |
|
|
55
|
+
|----------|----------------------|-----------|
|
|
56
|
+
| **E2B** | `E2B_API_KEY` | Data science, Python/Node.js, interactive terminals |
|
|
57
|
+
| **Modal** | `MODAL_TOKEN_ID`, `MODAL_TOKEN_SECRET` | GPU computing, ML inference, Python workloads |
|
|
58
|
+
| **Railway** | `RAILWAY_TOKEN` | Full-stack deployments, persistent storage |
|
|
59
|
+
| **Daytona** | `DAYTONA_API_KEY` | Development workspaces, custom environments |
|
|
60
|
+
| **Runloop** | `RUNLOOP_API_KEY` | Code execution, automation |
|
|
61
|
+
| **Vercel** | `VERCEL_TOKEN` or `VERCEL_OIDC_TOKEN` | Serverless functions, web apps |
|
|
62
|
+
| **Cloudflare** | `CLOUDFLARE_API_TOKEN` | Edge computing |
|
|
63
|
+
| **CodeSandbox** | `CODESANDBOX_TOKEN` | Collaborative development |
|
|
64
|
+
|
|
65
|
+
### Provider Detection Order
|
|
137
66
|
|
|
138
|
-
|
|
67
|
+
When using zero-config mode, ComputeSDK detects providers in this order:
|
|
139
68
|
|
|
140
|
-
|
|
69
|
+
**E2B → Railway → Daytona → Modal → Runloop → Vercel → Cloudflare → CodeSandbox**
|
|
141
70
|
|
|
142
|
-
|
|
71
|
+
You can force a specific provider:
|
|
143
72
|
|
|
144
73
|
```bash
|
|
145
|
-
export
|
|
146
|
-
export BLAXEL_WORKSPACE=your_workspace_here
|
|
74
|
+
export COMPUTESDK_PROVIDER=modal
|
|
147
75
|
```
|
|
148
76
|
|
|
149
|
-
|
|
150
|
-
import { compute } from 'computesdk';
|
|
151
|
-
import { blaxel } from '@computesdk/blaxel';
|
|
77
|
+
## API Reference
|
|
152
78
|
|
|
153
|
-
|
|
154
|
-
provider: blaxel({
|
|
155
|
-
apiKey: process.env.BLAXEL_API_KEY,
|
|
156
|
-
workspace: process.env.BLAXEL_WORKSPACE
|
|
157
|
-
})
|
|
158
|
-
});
|
|
79
|
+
### Configuration
|
|
159
80
|
|
|
160
|
-
|
|
81
|
+
#### `compute.setConfig(config)`
|
|
161
82
|
|
|
162
|
-
|
|
163
|
-
const result = await sandbox.runCode(`
|
|
164
|
-
print("Hello from Blaxel!")
|
|
165
|
-
# Your code can leverage AI capabilities
|
|
166
|
-
import json
|
|
167
|
-
data = {"message": "AI-powered execution"}
|
|
168
|
-
print(json.dumps(data, indent=2))
|
|
169
|
-
`);
|
|
83
|
+
Configure the gateway with explicit provider settings.
|
|
170
84
|
|
|
171
|
-
|
|
85
|
+
```typescript
|
|
86
|
+
compute.setConfig({
|
|
87
|
+
provider: 'e2b',
|
|
88
|
+
e2b: { apiKey: 'your_api_key' }
|
|
89
|
+
});
|
|
172
90
|
```
|
|
173
91
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
E2B provides full filesystem and terminal support:
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
export E2B_API_KEY=e2b_your_api_key_here
|
|
180
|
-
```
|
|
92
|
+
**Provider-specific configs:**
|
|
181
93
|
|
|
182
94
|
```typescript
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
95
|
+
// E2B
|
|
96
|
+
compute.setConfig({
|
|
97
|
+
provider: 'e2b',
|
|
98
|
+
e2b: {
|
|
99
|
+
apiKey: 'e2b_xxx',
|
|
100
|
+
templateId: 'optional_template'
|
|
101
|
+
}
|
|
188
102
|
});
|
|
189
103
|
|
|
190
|
-
|
|
104
|
+
// Modal
|
|
105
|
+
compute.setConfig({
|
|
106
|
+
provider: 'modal',
|
|
107
|
+
modal: {
|
|
108
|
+
tokenId: 'ak-xxx',
|
|
109
|
+
tokenSecret: 'as-xxx'
|
|
110
|
+
}
|
|
111
|
+
});
|
|
191
112
|
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
113
|
+
// Railway
|
|
114
|
+
compute.setConfig({
|
|
115
|
+
provider: 'railway',
|
|
116
|
+
railway: {
|
|
117
|
+
apiToken: 'your_token',
|
|
118
|
+
projectId: 'project_id',
|
|
119
|
+
environmentId: 'env_id'
|
|
120
|
+
}
|
|
121
|
+
});
|
|
196
122
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
123
|
+
// Daytona
|
|
124
|
+
compute.setConfig({
|
|
125
|
+
provider: 'daytona',
|
|
126
|
+
daytona: { apiKey: 'your_api_key' }
|
|
127
|
+
});
|
|
202
128
|
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
129
|
+
// Vercel
|
|
130
|
+
compute.setConfig({
|
|
131
|
+
provider: 'vercel',
|
|
132
|
+
vercel: {
|
|
133
|
+
token: 'your_token',
|
|
134
|
+
teamId: 'team_xxx',
|
|
135
|
+
projectId: 'prj_xxx'
|
|
136
|
+
}
|
|
208
137
|
});
|
|
209
138
|
```
|
|
210
139
|
|
|
211
|
-
###
|
|
212
|
-
|
|
213
|
-
Vercel provides reliable execution with filesystem support:
|
|
140
|
+
### Sandbox Management
|
|
214
141
|
|
|
215
|
-
|
|
216
|
-
# Method 1: OIDC Token (Recommended)
|
|
217
|
-
vercel env pull # Downloads VERCEL_OIDC_TOKEN
|
|
142
|
+
#### `compute.sandbox.create(options?)`
|
|
218
143
|
|
|
219
|
-
|
|
220
|
-
export VERCEL_TOKEN=your_vercel_token_here
|
|
221
|
-
export VERCEL_TEAM_ID=your_team_id_here
|
|
222
|
-
export VERCEL_PROJECT_ID=your_project_id_here
|
|
223
|
-
```
|
|
144
|
+
Create a new sandbox.
|
|
224
145
|
|
|
225
146
|
```typescript
|
|
226
|
-
import { compute } from 'computesdk';
|
|
227
|
-
import { vercel } from '@computesdk/vercel';
|
|
228
|
-
|
|
229
|
-
compute.setConfig({
|
|
230
|
-
provider: vercel({ runtime: 'node' })
|
|
231
|
-
});
|
|
232
|
-
|
|
233
147
|
const sandbox = await compute.sandbox.create();
|
|
234
148
|
|
|
235
|
-
//
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
// Up to 45 minutes execution time
|
|
242
|
-
// Global infrastructure deployment
|
|
149
|
+
// With options
|
|
150
|
+
const sandbox = await compute.sandbox.create({
|
|
151
|
+
runtime: 'python',
|
|
152
|
+
timeout: 300000, // 5 minutes
|
|
153
|
+
metadata: { userId: '123' }
|
|
154
|
+
});
|
|
243
155
|
```
|
|
244
156
|
|
|
245
|
-
|
|
157
|
+
**Options:**
|
|
158
|
+
- `runtime?: 'node' | 'python'` - Runtime environment (default: 'node')
|
|
159
|
+
- `timeout?: number` - Timeout in milliseconds
|
|
160
|
+
- `metadata?: Record<string, any>` - Custom metadata
|
|
161
|
+
- `envs?: Record<string, string>` - Environment variables
|
|
246
162
|
|
|
247
|
-
|
|
163
|
+
#### `compute.sandbox.getById(sandboxId)`
|
|
248
164
|
|
|
249
|
-
|
|
250
|
-
export DAYTONA_API_KEY=your_daytona_api_key_here
|
|
251
|
-
```
|
|
165
|
+
Get an existing sandbox by ID.
|
|
252
166
|
|
|
253
167
|
```typescript
|
|
254
|
-
|
|
255
|
-
import { daytona } from '@computesdk/daytona';
|
|
256
|
-
|
|
257
|
-
compute.setConfig({
|
|
258
|
-
provider: daytona({ apiKey: process.env.DAYTONA_API_KEY })
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
const sandbox = await compute.sandbox.create();
|
|
262
|
-
|
|
263
|
-
// Execute in development workspace
|
|
264
|
-
const result = await sandbox.runCode(`
|
|
265
|
-
print('Hello from Daytona!')
|
|
266
|
-
import sys
|
|
267
|
-
print(f'Python version: {sys.version}')
|
|
268
|
-
`);
|
|
168
|
+
const sandbox = await compute.sandbox.getById('sandbox-id');
|
|
269
169
|
```
|
|
270
170
|
|
|
271
|
-
|
|
171
|
+
#### `compute.sandbox.list()`
|
|
272
172
|
|
|
273
|
-
|
|
173
|
+
List all active sandboxes.
|
|
274
174
|
|
|
275
175
|
```typescript
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
// Set default provider
|
|
279
|
-
compute.setConfig({ provider: myProvider });
|
|
176
|
+
const sandboxes = await compute.sandbox.list();
|
|
177
|
+
```
|
|
280
178
|
|
|
281
|
-
|
|
282
|
-
const config = compute.getConfig();
|
|
179
|
+
### Sandbox Operations
|
|
283
180
|
|
|
284
|
-
|
|
285
|
-
compute.clearConfig();
|
|
286
|
-
```
|
|
181
|
+
#### `sandbox.runCode(code, runtime?)`
|
|
287
182
|
|
|
288
|
-
|
|
183
|
+
Execute code in the sandbox.
|
|
289
184
|
|
|
290
185
|
```typescript
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
// Create sandbox with default provider
|
|
298
|
-
const sandbox = await compute.sandbox.create({
|
|
299
|
-
options: { runtime: 'python' }
|
|
300
|
-
});
|
|
186
|
+
const result = await sandbox.runCode('print("Hello")', 'python');
|
|
187
|
+
console.log(result.stdout); // "Hello"
|
|
188
|
+
console.log(result.stderr);
|
|
189
|
+
console.log(result.exitCode);
|
|
190
|
+
```
|
|
301
191
|
|
|
302
|
-
|
|
303
|
-
const sandbox = await compute.sandbox.getById('sandbox-id');
|
|
192
|
+
#### `sandbox.runCommand(command, args?)`
|
|
304
193
|
|
|
305
|
-
|
|
306
|
-
const sandboxes = await compute.sandbox.list();
|
|
194
|
+
Run a shell command.
|
|
307
195
|
|
|
308
|
-
|
|
309
|
-
await
|
|
196
|
+
```typescript
|
|
197
|
+
const result = await sandbox.runCommand('npm', ['install', 'express']);
|
|
198
|
+
console.log(result.stdout);
|
|
310
199
|
```
|
|
311
200
|
|
|
312
|
-
|
|
201
|
+
#### `sandbox.getInfo()`
|
|
313
202
|
|
|
314
|
-
|
|
315
|
-
// Run code
|
|
316
|
-
const result = await sandbox.runCode('print("Hello")', 'python');
|
|
203
|
+
Get sandbox information.
|
|
317
204
|
|
|
318
|
-
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
//
|
|
322
|
-
|
|
323
|
-
stdout: string;
|
|
324
|
-
stderr: string;
|
|
325
|
-
exitCode: number;
|
|
326
|
-
executionTime: number;
|
|
327
|
-
sandboxId: string;
|
|
328
|
-
provider: string;
|
|
329
|
-
}
|
|
205
|
+
```typescript
|
|
206
|
+
const info = await sandbox.getInfo();
|
|
207
|
+
console.log(info.id);
|
|
208
|
+
console.log(info.status); // 'running' | 'stopped' | 'error'
|
|
209
|
+
console.log(info.createdAt);
|
|
330
210
|
```
|
|
331
211
|
|
|
332
|
-
|
|
212
|
+
#### `sandbox.destroy()`
|
|
333
213
|
|
|
334
|
-
|
|
335
|
-
// Write file
|
|
336
|
-
await sandbox.filesystem.writeFile('/tmp/hello.py', 'print("Hello")');
|
|
214
|
+
Destroy the sandbox and clean up resources.
|
|
337
215
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
// Create directory
|
|
342
|
-
await sandbox.filesystem.mkdir('/tmp/mydir');
|
|
216
|
+
```typescript
|
|
217
|
+
await sandbox.destroy();
|
|
218
|
+
```
|
|
343
219
|
|
|
344
|
-
|
|
345
|
-
const files = await sandbox.filesystem.readdir('/tmp');
|
|
220
|
+
### Filesystem Operations
|
|
346
221
|
|
|
347
|
-
|
|
348
|
-
const exists = await sandbox.filesystem.exists('/tmp/hello.py');
|
|
222
|
+
The sandbox provides full filesystem access:
|
|
349
223
|
|
|
350
|
-
|
|
351
|
-
await sandbox.filesystem.remove('/tmp/hello.py');
|
|
352
|
-
```
|
|
224
|
+
#### `sandbox.filesystem.writeFile(path, content)`
|
|
353
225
|
|
|
354
|
-
|
|
226
|
+
Write a file to the sandbox.
|
|
355
227
|
|
|
356
228
|
```typescript
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
command: 'bash',
|
|
360
|
-
cols: 80,
|
|
361
|
-
rows: 24
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
// Write to terminal
|
|
365
|
-
await terminal.write('ls -la\n');
|
|
366
|
-
|
|
367
|
-
// Resize terminal
|
|
368
|
-
await terminal.resize(120, 30);
|
|
229
|
+
await sandbox.filesystem.writeFile('/tmp/hello.py', 'print("Hello World")');
|
|
230
|
+
```
|
|
369
231
|
|
|
370
|
-
|
|
371
|
-
await terminal.kill();
|
|
232
|
+
#### `sandbox.filesystem.readFile(path)`
|
|
372
233
|
|
|
373
|
-
|
|
374
|
-
const terminals = await sandbox.terminal.list();
|
|
234
|
+
Read a file from the sandbox.
|
|
375
235
|
|
|
376
|
-
|
|
377
|
-
const
|
|
236
|
+
```typescript
|
|
237
|
+
const content = await sandbox.filesystem.readFile('/tmp/hello.py');
|
|
238
|
+
console.log(content); // 'print("Hello World")'
|
|
378
239
|
```
|
|
379
240
|
|
|
380
|
-
|
|
241
|
+
#### `sandbox.filesystem.mkdir(path)`
|
|
381
242
|
|
|
382
|
-
|
|
243
|
+
Create a directory.
|
|
383
244
|
|
|
384
245
|
```typescript
|
|
385
|
-
|
|
386
|
-
|
|
246
|
+
await sandbox.filesystem.mkdir('/tmp/mydir');
|
|
247
|
+
```
|
|
387
248
|
|
|
388
|
-
|
|
389
|
-
export async function POST(request: Request) {
|
|
390
|
-
return handleComputeRequest({
|
|
391
|
-
request,
|
|
392
|
-
provider: e2b({ apiKey: process.env.E2B_API_KEY })
|
|
393
|
-
});
|
|
394
|
-
}
|
|
249
|
+
#### `sandbox.filesystem.readdir(path)`
|
|
395
250
|
|
|
396
|
-
|
|
397
|
-
const response = await fetch('/api/compute', {
|
|
398
|
-
method: 'POST',
|
|
399
|
-
headers: { 'Content-Type': 'application/json' },
|
|
400
|
-
body: JSON.stringify({
|
|
401
|
-
action: 'compute.sandbox.runCode',
|
|
402
|
-
code: 'print("Hello from web!")',
|
|
403
|
-
runtime: 'python'
|
|
404
|
-
})
|
|
405
|
-
});
|
|
251
|
+
List directory contents.
|
|
406
252
|
|
|
407
|
-
|
|
408
|
-
|
|
253
|
+
```typescript
|
|
254
|
+
const files = await sandbox.filesystem.readdir('/tmp');
|
|
255
|
+
console.log(files); // [{ name: 'hello.py', type: 'file', size: 123 }, ...]
|
|
409
256
|
```
|
|
410
257
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
- `compute.sandbox.create` - Create new sandbox
|
|
414
|
-
- `compute.sandbox.destroy` - Destroy sandbox
|
|
415
|
-
- `compute.sandbox.getInfo` - Get sandbox information
|
|
416
|
-
- `compute.sandbox.list` - List all sandboxes
|
|
417
|
-
- `compute.sandbox.runCode` - Execute code
|
|
418
|
-
- `compute.sandbox.runCommand` - Run shell command
|
|
419
|
-
- `compute.sandbox.filesystem.readFile` - Read file
|
|
420
|
-
- `compute.sandbox.filesystem.writeFile` - Write file
|
|
421
|
-
- `compute.sandbox.filesystem.mkdir` - Create directory
|
|
422
|
-
- `compute.sandbox.filesystem.readdir` - List directory
|
|
423
|
-
- `compute.sandbox.filesystem.exists` - Check if path exists
|
|
424
|
-
- `compute.sandbox.filesystem.remove` - Remove file/directory
|
|
425
|
-
- `compute.sandbox.terminal.create` - Create terminal
|
|
426
|
-
- `compute.sandbox.terminal.list` - List terminals
|
|
427
|
-
- `compute.sandbox.terminal.getById` - Get terminal by ID
|
|
428
|
-
- `compute.sandbox.terminal.destroy` - Destroy terminal
|
|
429
|
-
- `compute.sandbox.terminal.write` - Write to terminal
|
|
430
|
-
- `compute.sandbox.terminal.resize` - Resize terminal
|
|
431
|
-
- `compute.sandbox.terminal.kill` - Kill terminal
|
|
432
|
-
|
|
433
|
-
## Frontend Integration
|
|
434
|
-
|
|
435
|
-
Use `@computesdk/ui` for framework-agnostic factory functions:
|
|
258
|
+
#### `sandbox.filesystem.exists(path)`
|
|
436
259
|
|
|
437
|
-
|
|
438
|
-
import { createCompute, createSandboxConsole } from '@computesdk/ui';
|
|
260
|
+
Check if a file or directory exists.
|
|
439
261
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
defaultRuntime: 'python'
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
const executeCode = async () => {
|
|
447
|
-
const sandbox = await compute.sandbox.create();
|
|
448
|
-
const result = await sandbox.runCode('print("Hello World!")');
|
|
449
|
-
console.log(result.result?.stdout);
|
|
450
|
-
await sandbox.destroy();
|
|
451
|
-
};
|
|
452
|
-
|
|
453
|
-
return (
|
|
454
|
-
<button onClick={executeCode}>
|
|
455
|
-
Execute Code
|
|
456
|
-
</button>
|
|
457
|
-
);
|
|
458
|
-
}
|
|
262
|
+
```typescript
|
|
263
|
+
const exists = await sandbox.filesystem.exists('/tmp/hello.py');
|
|
264
|
+
console.log(exists); // true
|
|
459
265
|
```
|
|
460
266
|
|
|
461
|
-
|
|
267
|
+
#### `sandbox.filesystem.remove(path)`
|
|
268
|
+
|
|
269
|
+
Remove a file or directory.
|
|
462
270
|
|
|
463
271
|
```typescript
|
|
464
|
-
|
|
465
|
-
const sandbox = await compute.sandbox.create();
|
|
466
|
-
const result = await sandbox.runCode('invalid code');
|
|
467
|
-
} catch (error) {
|
|
468
|
-
console.error('Execution failed:', error.message);
|
|
469
|
-
}
|
|
272
|
+
await sandbox.filesystem.remove('/tmp/hello.py');
|
|
470
273
|
```
|
|
471
274
|
|
|
472
275
|
## Examples
|
|
473
276
|
|
|
474
|
-
### Data Science
|
|
277
|
+
### Data Science Workflow
|
|
475
278
|
|
|
476
279
|
```typescript
|
|
477
280
|
import { compute } from 'computesdk';
|
|
478
|
-
import { e2b } from '@computesdk/e2b';
|
|
479
|
-
|
|
480
|
-
compute.setConfig({ provider: e2b({ apiKey: process.env.E2B_API_KEY }) });
|
|
481
281
|
|
|
482
|
-
|
|
282
|
+
// Assumes E2B_API_KEY is set in environment
|
|
283
|
+
const sandbox = await compute.sandbox.create({ runtime: 'python' });
|
|
483
284
|
|
|
484
285
|
// Create project structure
|
|
485
286
|
await sandbox.filesystem.mkdir('/analysis');
|
|
@@ -508,23 +309,14 @@ print(df)
|
|
|
508
309
|
avg_age = df['age'].mean()
|
|
509
310
|
print(f"\\nAverage age: {avg_age}")
|
|
510
311
|
|
|
511
|
-
# Create visualization
|
|
512
|
-
plt.figure(figsize=(8, 6))
|
|
513
|
-
plt.bar(df['name'], df['age'])
|
|
514
|
-
plt.title('Age by Person')
|
|
515
|
-
plt.xlabel('Name')
|
|
516
|
-
plt.ylabel('Age')
|
|
517
|
-
plt.savefig('/analysis/output/age_chart.png')
|
|
518
|
-
print("\\nChart saved to /analysis/output/age_chart.png")
|
|
519
|
-
|
|
520
312
|
# Save results
|
|
313
|
+
import json
|
|
521
314
|
results = {
|
|
522
315
|
'total_people': len(df),
|
|
523
316
|
'average_age': avg_age,
|
|
524
317
|
'cities': df['city'].unique().tolist()
|
|
525
318
|
}
|
|
526
319
|
|
|
527
|
-
import json
|
|
528
320
|
with open('/analysis/output/results.json', 'w') as f:
|
|
529
321
|
json.dump(results, f, indent=2)
|
|
530
322
|
|
|
@@ -537,218 +329,138 @@ console.log(result.stdout);
|
|
|
537
329
|
const results = await sandbox.filesystem.readFile('/analysis/output/results.json');
|
|
538
330
|
console.log('Analysis results:', JSON.parse(results));
|
|
539
331
|
|
|
540
|
-
await
|
|
332
|
+
await sandbox.destroy();
|
|
541
333
|
```
|
|
542
334
|
|
|
543
|
-
###
|
|
335
|
+
### Multi-Step Build Process
|
|
544
336
|
|
|
545
337
|
```typescript
|
|
546
338
|
import { compute } from 'computesdk';
|
|
547
|
-
import { vercel } from '@computesdk/vercel';
|
|
548
|
-
import { daytona } from '@computesdk/daytona';
|
|
549
|
-
|
|
550
|
-
async function processData(provider: any) {
|
|
551
|
-
compute.setConfig({ provider });
|
|
552
|
-
|
|
553
|
-
const sandbox = await compute.sandbox.create();
|
|
554
|
-
|
|
555
|
-
// Create workspace
|
|
556
|
-
await sandbox.filesystem.mkdir('/workspace');
|
|
557
|
-
|
|
558
|
-
// Write input data
|
|
559
|
-
await sandbox.filesystem.writeFile('/workspace/input.json',
|
|
560
|
-
JSON.stringify({ numbers: [1, 2, 3, 4, 5] })
|
|
561
|
-
);
|
|
562
|
-
|
|
563
|
-
// Process with code execution
|
|
564
|
-
const result = await sandbox.runCode(`
|
|
565
|
-
import json
|
|
566
339
|
|
|
567
|
-
|
|
568
|
-
with open('/workspace/input.json', 'r') as f:
|
|
569
|
-
data = json.load(f)
|
|
340
|
+
const sandbox = await compute.sandbox.create({ runtime: 'node' });
|
|
570
341
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
342
|
+
// Create project structure
|
|
343
|
+
await sandbox.filesystem.mkdir('/app');
|
|
344
|
+
await sandbox.filesystem.mkdir('/app/src');
|
|
345
|
+
|
|
346
|
+
// Write package.json
|
|
347
|
+
await sandbox.filesystem.writeFile('/app/package.json', JSON.stringify({
|
|
348
|
+
name: 'my-app',
|
|
349
|
+
version: '1.0.0',
|
|
350
|
+
dependencies: {
|
|
351
|
+
'express': '^4.18.0'
|
|
352
|
+
}
|
|
353
|
+
}, null, 2));
|
|
578
354
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
355
|
+
// Write source code
|
|
356
|
+
await sandbox.filesystem.writeFile('/app/src/index.js', `
|
|
357
|
+
const express = require('express');
|
|
358
|
+
const app = express();
|
|
582
359
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
// Read results
|
|
587
|
-
const output = await sandbox.filesystem.readFile('/workspace/output.json');
|
|
588
|
-
await compute.sandbox.destroy(sandbox.sandboxId);
|
|
589
|
-
|
|
590
|
-
return JSON.parse(output);
|
|
591
|
-
}
|
|
360
|
+
app.get('/', (req, res) => {
|
|
361
|
+
res.json({ message: 'Hello World!' });
|
|
362
|
+
});
|
|
592
363
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
console.log('Vercel result:', vercelResult);
|
|
364
|
+
console.log('Server ready!');
|
|
365
|
+
`);
|
|
596
366
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
367
|
+
// Install dependencies
|
|
368
|
+
const installResult = await sandbox.runCommand('npm', ['install'], { cwd: '/app' });
|
|
369
|
+
console.log('Install:', installResult.stdout);
|
|
600
370
|
|
|
601
|
-
|
|
371
|
+
// Run the app
|
|
372
|
+
const runResult = await sandbox.runCode(`
|
|
373
|
+
const { spawn } = require('child_process');
|
|
374
|
+
const proc = spawn('node', ['src/index.js'], { cwd: '/app' });
|
|
375
|
+
proc.stdout.on('data', (data) => console.log(data.toString()));
|
|
376
|
+
`);
|
|
602
377
|
|
|
603
|
-
|
|
378
|
+
console.log(runResult.stdout);
|
|
604
379
|
|
|
605
|
-
|
|
606
|
-
npm install @computesdk/blaxel # Blaxel provider
|
|
607
|
-
npm install @computesdk/e2b # E2B provider
|
|
608
|
-
npm install @computesdk/vercel # Vercel provider
|
|
609
|
-
npm install @computesdk/daytona # Daytona provider
|
|
610
|
-
npm install @computesdk/modal # Modal provider
|
|
611
|
-
npm install @computesdk/codesandbox # CodeSandbox provider
|
|
380
|
+
await sandbox.destroy();
|
|
612
381
|
```
|
|
613
382
|
|
|
614
|
-
|
|
383
|
+
### Using Different Providers
|
|
615
384
|
|
|
616
|
-
|
|
385
|
+
```typescript
|
|
386
|
+
import { compute } from 'computesdk';
|
|
617
387
|
|
|
618
|
-
|
|
388
|
+
// Use E2B for data science
|
|
389
|
+
compute.setConfig({
|
|
390
|
+
provider: 'e2b',
|
|
391
|
+
e2b: { apiKey: process.env.E2B_API_KEY }
|
|
392
|
+
});
|
|
619
393
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
npm install @computesdk/events # Event storage and real-time streaming
|
|
624
|
-
npm install @computesdk/workbench # Interactive REPL for sandbox testing
|
|
625
|
-
```
|
|
394
|
+
const e2bSandbox = await compute.sandbox.create();
|
|
395
|
+
await e2bSandbox.runCode('import pandas as pd; print(pd.__version__)');
|
|
396
|
+
await e2bSandbox.destroy();
|
|
626
397
|
|
|
627
|
-
|
|
398
|
+
// Switch to Modal for GPU workloads
|
|
399
|
+
compute.setConfig({
|
|
400
|
+
provider: 'modal',
|
|
401
|
+
modal: {
|
|
402
|
+
tokenId: process.env.MODAL_TOKEN_ID,
|
|
403
|
+
tokenSecret: process.env.MODAL_TOKEN_SECRET
|
|
404
|
+
}
|
|
405
|
+
});
|
|
628
406
|
|
|
629
|
-
|
|
407
|
+
const modalSandbox = await compute.sandbox.create();
|
|
408
|
+
await modalSandbox.runCode('import torch; print(torch.cuda.is_available())');
|
|
409
|
+
await modalSandbox.destroy();
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Error Handling
|
|
630
413
|
|
|
631
414
|
```typescript
|
|
632
|
-
|
|
415
|
+
try {
|
|
416
|
+
const sandbox = await compute.sandbox.create();
|
|
417
|
+
const result = await sandbox.runCode('invalid python code');
|
|
418
|
+
} catch (error) {
|
|
419
|
+
console.error('Execution failed:', error.message);
|
|
420
|
+
|
|
421
|
+
// Check for specific error types
|
|
422
|
+
if (error.message.includes('No provider detected')) {
|
|
423
|
+
console.error('Set provider credentials in environment variables');
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
```
|
|
633
427
|
|
|
634
|
-
|
|
635
|
-
await sandbox.runCommand(npm.install('express'));
|
|
636
|
-
await sandbox.runCommand(git.clone('https://github.com/user/repo'));
|
|
637
|
-
await sandbox.runCommand(mkdir('/app/src'));
|
|
428
|
+
## Direct Mode (Advanced)
|
|
638
429
|
|
|
639
|
-
|
|
640
|
-
await sandbox.runCommand(cmd(npm.run('dev'), { cwd: '/app', background: true }));
|
|
641
|
-
```
|
|
430
|
+
For advanced use cases where you want to bypass the gateway and use provider SDKs directly, see individual provider packages:
|
|
642
431
|
|
|
643
|
-
|
|
432
|
+
- **[@computesdk/e2b](../e2b)** - E2B provider
|
|
433
|
+
- **[@computesdk/modal](../modal)** - Modal provider
|
|
434
|
+
- **[@computesdk/railway](../railway)** - Railway provider
|
|
435
|
+
- **[@computesdk/daytona](../daytona)** - Daytona provider
|
|
644
436
|
|
|
645
|
-
|
|
437
|
+
Example direct mode usage:
|
|
646
438
|
|
|
647
|
-
```
|
|
648
|
-
|
|
439
|
+
```typescript
|
|
440
|
+
import { e2b } from '@computesdk/e2b';
|
|
649
441
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
workbench> git.clone('https://github.com/user/repo')
|
|
653
|
-
workbench> ls('/home')
|
|
442
|
+
const compute = e2b({ apiKey: 'your_api_key' });
|
|
443
|
+
const sandbox = await compute.sandbox.create();
|
|
654
444
|
```
|
|
655
445
|
|
|
656
|
-
## Custom Providers
|
|
657
|
-
|
|
658
|
-
Create custom providers using the factory:
|
|
446
|
+
## Building Custom Providers
|
|
659
447
|
|
|
660
|
-
|
|
661
|
-
import { createProvider } from 'computesdk';
|
|
662
|
-
|
|
663
|
-
const myProvider = createProvider({
|
|
664
|
-
name: 'my-provider',
|
|
665
|
-
methods: {
|
|
666
|
-
sandbox: {
|
|
667
|
-
create: async (config, options) => {
|
|
668
|
-
// Implementation
|
|
669
|
-
},
|
|
670
|
-
getById: async (config, id) => {
|
|
671
|
-
// Implementation
|
|
672
|
-
},
|
|
673
|
-
list: async (config) => {
|
|
674
|
-
// Implementation
|
|
675
|
-
},
|
|
676
|
-
destroy: async (config, id) => {
|
|
677
|
-
// Implementation
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
});
|
|
682
|
-
```
|
|
448
|
+
Want to add support for a new compute provider? See **[@computesdk/provider](../provider)** for the provider framework and documentation on building custom providers.
|
|
683
449
|
|
|
684
450
|
## TypeScript Support
|
|
685
451
|
|
|
686
|
-
|
|
452
|
+
Full TypeScript support with comprehensive type definitions:
|
|
687
453
|
|
|
688
454
|
```typescript
|
|
689
455
|
import type {
|
|
690
|
-
Sandbox,
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
456
|
+
Sandbox,
|
|
457
|
+
SandboxInfo,
|
|
458
|
+
CodeResult,
|
|
459
|
+
CommandResult,
|
|
460
|
+
CreateSandboxOptions
|
|
695
461
|
} from 'computesdk';
|
|
696
462
|
```
|
|
697
463
|
|
|
698
|
-
## Provider Comparison
|
|
699
|
-
|
|
700
|
-
| Provider | Code Execution | Filesystem | Terminal | Use Cases |
|
|
701
|
-
|----------|----------------|------------|----------|-----------|
|
|
702
|
-
| **E2B** | Python, Node.js | ✅ Full | ✅ PTY | Data science, AI/ML, interactive development |
|
|
703
|
-
| **Vercel** | Node.js, Python | ✅ Full | ❌ | Web apps, APIs, serverless functions |
|
|
704
|
-
| **Daytona** | Python, Node.js | ✅ Full | ❌ | Development workspaces, custom environments |
|
|
705
|
-
|
|
706
|
-
### Key Differences
|
|
707
|
-
|
|
708
|
-
- **E2B**: Full development environment with data science libraries and interactive terminals
|
|
709
|
-
- **Vercel**: Ephemeral sandboxes optimized for serverless execution (up to 45 minutes)
|
|
710
|
-
- **Daytona**: Development workspaces with persistent environments
|
|
711
|
-
|
|
712
|
-
## Examples
|
|
713
|
-
|
|
714
|
-
Check out the [examples directory](./examples) for complete implementations with different web frameworks:
|
|
715
|
-
|
|
716
|
-
- [Next.js](./examples/nextjs)
|
|
717
|
-
- [Nuxt](./examples/nuxt)
|
|
718
|
-
- [SvelteKit](./examples/sveltekit)
|
|
719
|
-
- [Remix](./examples/remix)
|
|
720
|
-
- [Astro](./examples/astro)
|
|
721
|
-
|
|
722
|
-
## Resources
|
|
723
|
-
|
|
724
|
-
- 📖 **[Full Documentation](https://computesdk.com)** - Complete guides and API reference
|
|
725
|
-
- 🚀 **[Getting Started](https://computesdk.com/getting-started)** - Quick setup guide
|
|
726
|
-
- 💡 **[Examples](./examples)** - Real-world usage examples
|
|
727
|
-
- 🎯 **[Providers](https://computesdk.com/providers)** - Provider-specific guides
|
|
728
|
-
|
|
729
|
-
## Contributing
|
|
730
|
-
|
|
731
|
-
ComputeSDK is open source and welcomes contributions! Whether you're fixing bugs, adding features, or improving documentation, we'd love your help.
|
|
732
|
-
|
|
733
|
-
1. Fork the repository
|
|
734
|
-
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
735
|
-
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
736
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
737
|
-
5. Open a Pull Request
|
|
738
|
-
|
|
739
|
-
## Community & Support
|
|
740
|
-
|
|
741
|
-
- 💬 **[GitHub Discussions](https://github.com/computesdk/computesdk/discussions)** - Ask questions and share ideas
|
|
742
|
-
- 🐛 **[GitHub Issues](https://github.com/computesdk/computesdk/issues)** - Report bugs and request features
|
|
743
|
-
- 📧 **[Contact Us](https://computesdk.com/contact)** - Get in touch with the team
|
|
744
|
-
|
|
745
464
|
## License
|
|
746
465
|
|
|
747
|
-
MIT
|
|
748
|
-
|
|
749
|
-
---
|
|
750
|
-
|
|
751
|
-
<div align="center">
|
|
752
|
-
<strong>Built with ❤️ by the ComputeSDK team</strong><br>
|
|
753
|
-
<a href="https://computesdk.com">computesdk.com</a>
|
|
754
|
-
</div>
|
|
466
|
+
MIT
|