computesdk 2.0.0 → 2.0.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 +512 -546
- package/dist/index.d.mts +4031 -551
- package/dist/index.d.ts +4031 -551
- package/dist/index.js +4368 -598
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4337 -580
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -8
package/README.md
CHANGED
|
@@ -1,746 +1,712 @@
|
|
|
1
|
-
#
|
|
1
|
+
# computesdk
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Similar to how Vercel's AI SDK abstracts different LLM providers, ComputeSDK abstracts different compute sandbox providers into a single, consistent TypeScript interface.
|
|
6
|
-
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- 🚀 **Multi-provider support** - E2B, Vercel, Daytona
|
|
10
|
-
- 📁 **Filesystem operations** - Read, write, create directories across providers
|
|
11
|
-
- 🖥️ **Terminal support** - Interactive PTY terminals (E2B)
|
|
12
|
-
- ⚡ **Command execution** - Run shell commands directly
|
|
13
|
-
- 🔄 **Auto-detection** - Automatically selects providers based on environment variables
|
|
14
|
-
- 🛡️ **Type-safe** - Full TypeScript support with comprehensive error handling
|
|
15
|
-
- 📦 **Modular** - Install only the providers you need
|
|
16
|
-
- 🔧 **Extensible** - Easy to add custom providers
|
|
17
|
-
|
|
18
|
-
## Supported Providers
|
|
19
|
-
|
|
20
|
-
| Provider | Code Execution | Filesystem | Terminal | Use Cases |
|
|
21
|
-
|----------|----------------|------------|----------|-----------|
|
|
22
|
-
| **E2B** | Python | ✅ Full | ✅ PTY | Data science, AI/ML, interactive development |
|
|
23
|
-
| **Vercel** | Node.js, Python | ✅ Full | ❌ | Web apps, APIs, serverless functions |
|
|
24
|
-
| **Daytona** | Python, Node.js | ✅ Full | ❌ | Development workspaces, custom environments |
|
|
3
|
+
The gateway SDK for running code in remote sandboxes. Zero-config auto-detection with support for E2B, Modal, Railway, Daytona, Vercel, and more.
|
|
25
4
|
|
|
26
5
|
## Installation
|
|
27
6
|
|
|
28
7
|
```bash
|
|
29
|
-
# Core SDK
|
|
30
8
|
npm install computesdk
|
|
31
|
-
|
|
32
|
-
# Provider packages (install only what you need)
|
|
33
|
-
npm install @computesdk/e2b # E2B provider
|
|
34
|
-
npm install @computesdk/vercel # Vercel provider
|
|
35
|
-
npm install @computesdk/daytona # Daytona provider
|
|
36
9
|
```
|
|
37
10
|
|
|
38
11
|
## Quick Start
|
|
39
12
|
|
|
40
|
-
###
|
|
13
|
+
### Zero-Config Mode (Recommended)
|
|
41
14
|
|
|
42
|
-
ComputeSDK automatically detects
|
|
15
|
+
Set your provider credentials as environment variables and ComputeSDK automatically detects and configures everything:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
export E2B_API_KEY=your_e2b_api_key
|
|
19
|
+
```
|
|
43
20
|
|
|
44
21
|
```typescript
|
|
45
|
-
import {
|
|
22
|
+
import { compute } from 'computesdk';
|
|
46
23
|
|
|
47
|
-
//
|
|
48
|
-
const sandbox =
|
|
24
|
+
// Auto-detects E2B from environment
|
|
25
|
+
const sandbox = await compute.sandbox.create();
|
|
49
26
|
|
|
50
|
-
|
|
51
|
-
|
|
27
|
+
// Execute code
|
|
28
|
+
const result = await sandbox.runCode('print("Hello World!")');
|
|
29
|
+
console.log(result.output); // "Hello World!"
|
|
52
30
|
|
|
53
|
-
|
|
31
|
+
// Clean up
|
|
32
|
+
await sandbox.destroy();
|
|
54
33
|
```
|
|
55
34
|
|
|
56
|
-
###
|
|
35
|
+
### Explicit Configuration
|
|
36
|
+
|
|
37
|
+
For more control, use `setConfig()` to explicitly configure the provider:
|
|
57
38
|
|
|
58
39
|
```typescript
|
|
59
|
-
import {
|
|
60
|
-
import { e2b } from '@computesdk/e2b';
|
|
40
|
+
import { compute } from 'computesdk';
|
|
61
41
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
42
|
+
compute.setConfig({
|
|
43
|
+
provider: 'your-provider',
|
|
44
|
+
apiKey: process.env.COMPUTESDK_API_KEY,
|
|
45
|
+
'your-provider': {
|
|
46
|
+
apiKey: process.env.YOUR_PROVIDER_API_KEY
|
|
47
|
+
}
|
|
67
48
|
});
|
|
68
49
|
|
|
69
|
-
|
|
50
|
+
const sandbox = await compute.sandbox.create();
|
|
70
51
|
```
|
|
71
52
|
|
|
72
|
-
|
|
53
|
+
## Supported Providers
|
|
73
54
|
|
|
74
|
-
ComputeSDK
|
|
55
|
+
ComputeSDK automatically detects providers based on environment variables:
|
|
75
56
|
|
|
76
|
-
|
|
77
|
-
|
|
57
|
+
| Provider | Environment Variables | Use Cases |
|
|
58
|
+
|----------|----------------------|-----------|
|
|
59
|
+
| **E2B** | `E2B_API_KEY` | Data science, Python/Node.js, interactive terminals |
|
|
60
|
+
| **Modal** | `MODAL_TOKEN_ID`, `MODAL_TOKEN_SECRET` | GPU computing, ML inference, Python workloads |
|
|
61
|
+
| **Railway** | `RAILWAY_TOKEN` | Full-stack deployments, persistent storage |
|
|
62
|
+
| **Daytona** | `DAYTONA_API_KEY` | Development workspaces, custom environments |
|
|
63
|
+
| **Runloop** | `RUNLOOP_API_KEY` | Code execution, automation |
|
|
64
|
+
| **Vercel** | `VERCEL_TOKEN` or `VERCEL_OIDC_TOKEN` | Serverless functions, web apps |
|
|
65
|
+
| **Cloudflare** | `CLOUDFLARE_API_TOKEN` | Edge computing |
|
|
66
|
+
| **CodeSandbox** | `CODESANDBOX_TOKEN` | Collaborative development |
|
|
78
67
|
|
|
79
|
-
|
|
68
|
+
### Provider Detection Order
|
|
80
69
|
|
|
81
|
-
|
|
82
|
-
if ('filesystem' in sandbox) {
|
|
83
|
-
const fsSandbox = sandbox as FilesystemComputeSandbox;
|
|
84
|
-
|
|
85
|
-
// Use filesystem operations
|
|
86
|
-
await fsSandbox.filesystem.writeFile('/tmp/data.txt', 'Hello World!');
|
|
87
|
-
const content = await fsSandbox.filesystem.readFile('/tmp/data.txt');
|
|
88
|
-
console.log(content); // "Hello World!"
|
|
89
|
-
}
|
|
70
|
+
When using zero-config mode, ComputeSDK detects providers in this order:
|
|
90
71
|
|
|
91
|
-
|
|
92
|
-
const termSandbox = sandbox as TerminalComputeSandbox;
|
|
93
|
-
|
|
94
|
-
// Create interactive terminal (E2B only)
|
|
95
|
-
const terminal = await termSandbox.terminal.create({
|
|
96
|
-
command: 'bash',
|
|
97
|
-
cols: 80,
|
|
98
|
-
rows: 24
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
await terminal.write('echo "Interactive terminal!"\n');
|
|
102
|
-
await terminal.kill();
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Environment Setup
|
|
72
|
+
**E2B → Railway → Daytona → Modal → Runloop → Vercel → Cloudflare → CodeSandbox**
|
|
107
73
|
|
|
108
|
-
|
|
74
|
+
You can force a specific provider:
|
|
109
75
|
|
|
110
|
-
### E2B (Full Features)
|
|
111
76
|
```bash
|
|
112
|
-
export
|
|
77
|
+
export COMPUTESDK_PROVIDER=modal
|
|
113
78
|
```
|
|
114
|
-
Get your API key from [e2b.dev](https://e2b.dev/)
|
|
115
79
|
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
export VERCEL_TOKEN=your_vercel_token_here
|
|
119
|
-
export VERCEL_TEAM_ID=your_team_id_here
|
|
120
|
-
export VERCEL_PROJECT_ID=your_project_id_here
|
|
121
|
-
```
|
|
122
|
-
Get your token from [Vercel Account Tokens](https://vercel.com/account/tokens)
|
|
80
|
+
## API Reference
|
|
123
81
|
|
|
124
|
-
###
|
|
125
|
-
|
|
126
|
-
|
|
82
|
+
### Configuration
|
|
83
|
+
|
|
84
|
+
#### `compute.setConfig(config)`
|
|
85
|
+
|
|
86
|
+
Configure the gateway with explicit provider settings.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
compute.setConfig({
|
|
90
|
+
provider: 'your-provider',
|
|
91
|
+
apiKey: process.env.COMPUTESDK_API_KEY,
|
|
92
|
+
'your-provider': {
|
|
93
|
+
apiKey: process.env.YOUR_PROVIDER_API_KEY
|
|
94
|
+
}
|
|
95
|
+
});
|
|
127
96
|
```
|
|
128
97
|
|
|
98
|
+
**Provider-specific configs:**
|
|
129
99
|
|
|
100
|
+
```typescript
|
|
101
|
+
// E2B
|
|
102
|
+
compute.setConfig({
|
|
103
|
+
provider: 'e2b',
|
|
104
|
+
apiKey: process.env.COMPUTESDK_API_KEY,
|
|
105
|
+
e2b: {
|
|
106
|
+
apiKey: 'e2b_xxx',
|
|
107
|
+
templateId: 'optional_template'
|
|
108
|
+
}
|
|
109
|
+
});
|
|
130
110
|
|
|
131
|
-
|
|
111
|
+
// Modal
|
|
112
|
+
compute.setConfig({
|
|
113
|
+
provider: 'modal',
|
|
114
|
+
apiKey: process.env.COMPUTESDK_API_KEY,
|
|
115
|
+
modal: {
|
|
116
|
+
tokenId: 'ak-xxx',
|
|
117
|
+
tokenSecret: 'as-xxx'
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Railway
|
|
122
|
+
compute.setConfig({
|
|
123
|
+
provider: 'railway',
|
|
124
|
+
apiKey: process.env.COMPUTESDK_API_KEY,
|
|
125
|
+
railway: {
|
|
126
|
+
apiToken: 'your_token',
|
|
127
|
+
projectId: 'project_id',
|
|
128
|
+
environmentId: 'env_id'
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Daytona
|
|
133
|
+
compute.setConfig({
|
|
134
|
+
provider: 'daytona',
|
|
135
|
+
apiKey: process.env.COMPUTESDK_API_KEY,
|
|
136
|
+
daytona: { apiKey: 'your_api_key' }
|
|
137
|
+
});
|
|
132
138
|
|
|
133
|
-
|
|
139
|
+
// Vercel
|
|
140
|
+
compute.setConfig({
|
|
141
|
+
provider: 'vercel',
|
|
142
|
+
apiKey: process.env.COMPUTESDK_API_KEY,
|
|
143
|
+
vercel: {
|
|
144
|
+
token: 'your_token',
|
|
145
|
+
teamId: 'team_xxx',
|
|
146
|
+
projectId: 'prj_xxx'
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
```
|
|
134
150
|
|
|
135
|
-
|
|
151
|
+
### Sandbox Management
|
|
136
152
|
|
|
137
|
-
|
|
153
|
+
#### `compute.sandbox.create(options?)`
|
|
138
154
|
|
|
139
|
-
|
|
140
|
-
// Auto-detection
|
|
141
|
-
const sandbox = ComputeSDK.createSandbox();
|
|
155
|
+
Create a new sandbox.
|
|
142
156
|
|
|
143
|
-
|
|
144
|
-
const sandbox =
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
157
|
+
```typescript
|
|
158
|
+
const sandbox = await compute.sandbox.create();
|
|
159
|
+
|
|
160
|
+
// With options
|
|
161
|
+
const sandbox = await compute.sandbox.create({
|
|
162
|
+
timeout: 300000, // 5 minutes
|
|
163
|
+
metadata: { userId: '123' },
|
|
164
|
+
namespace: 'my-org',
|
|
165
|
+
name: 'my-sandbox',
|
|
148
166
|
});
|
|
149
167
|
```
|
|
150
168
|
|
|
151
|
-
**
|
|
152
|
-
- `
|
|
169
|
+
**Options:**
|
|
170
|
+
- `timeout?: number` - Timeout in milliseconds
|
|
171
|
+
- `metadata?: Record<string, any>` - Custom metadata
|
|
172
|
+
- `envs?: Record<string, string>` - Environment variables
|
|
173
|
+
- `namespace?: string` - Namespace for organizing sandboxes
|
|
174
|
+
- `name?: string` - Name for the sandbox (enables findOrCreate)
|
|
175
|
+
- `overlays?: SetupOverlayConfig[]` - Template overlays to apply
|
|
176
|
+
- `servers?: ServerStartOptions[]` - Servers to start automatically
|
|
177
|
+
|
|
178
|
+
#### `compute.sandbox.getById(sandboxId)`
|
|
153
179
|
|
|
154
|
-
|
|
180
|
+
Get an existing sandbox by ID.
|
|
155
181
|
|
|
156
|
-
|
|
182
|
+
```typescript
|
|
183
|
+
const sandbox = await compute.sandbox.getById('sandbox-id');
|
|
184
|
+
```
|
|
157
185
|
|
|
158
|
-
|
|
186
|
+
#### `compute.sandbox.findOrCreate(options)`
|
|
187
|
+
|
|
188
|
+
Find an existing sandbox by namespace and name, or create a new one.
|
|
159
189
|
|
|
160
190
|
```typescript
|
|
161
|
-
const
|
|
162
|
-
|
|
191
|
+
const sandbox = await compute.sandbox.findOrCreate({
|
|
192
|
+
namespace: 'my-org',
|
|
193
|
+
name: 'my-project',
|
|
194
|
+
});
|
|
163
195
|
```
|
|
164
196
|
|
|
165
|
-
|
|
197
|
+
#### `compute.sandbox.find(options)`
|
|
166
198
|
|
|
167
|
-
|
|
199
|
+
Find an existing sandbox by namespace and name (returns null if not found).
|
|
168
200
|
|
|
169
|
-
|
|
201
|
+
```typescript
|
|
202
|
+
const sandbox = await compute.sandbox.find({
|
|
203
|
+
namespace: 'my-org',
|
|
204
|
+
name: 'my-project',
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Sandbox Operations
|
|
170
209
|
|
|
171
|
-
|
|
210
|
+
#### `sandbox.runCode(code, language?)`
|
|
211
|
+
|
|
212
|
+
Execute code in the sandbox.
|
|
172
213
|
|
|
173
214
|
```typescript
|
|
174
|
-
|
|
175
|
-
|
|
215
|
+
const result = await sandbox.runCode('print("Hello")', 'python');
|
|
216
|
+
console.log(result.output); // "Hello"
|
|
217
|
+
console.log(result.exitCode);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### `sandbox.runCommand(command, options?)`
|
|
176
221
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
222
|
+
Run a shell command.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
const result = await sandbox.runCommand('npm install express');
|
|
226
|
+
console.log(result.stdout);
|
|
227
|
+
console.log(result.exitCode);
|
|
228
|
+
|
|
229
|
+
// With options
|
|
230
|
+
const result = await sandbox.runCommand('npm install', {
|
|
231
|
+
cwd: '/app',
|
|
232
|
+
env: { NODE_ENV: 'production' },
|
|
233
|
+
background: true,
|
|
181
234
|
});
|
|
182
235
|
```
|
|
183
236
|
|
|
184
|
-
|
|
237
|
+
#### `sandbox.destroy()`
|
|
238
|
+
|
|
239
|
+
Destroy the sandbox and clean up resources.
|
|
240
|
+
|
|
185
241
|
```typescript
|
|
186
|
-
|
|
187
|
-
sandbox: ComputeSandbox;
|
|
188
|
-
code: string;
|
|
189
|
-
runtime?: Runtime;
|
|
190
|
-
}
|
|
242
|
+
await sandbox.destroy();
|
|
191
243
|
```
|
|
192
244
|
|
|
193
|
-
###
|
|
245
|
+
### Filesystem Operations
|
|
194
246
|
|
|
195
|
-
|
|
247
|
+
The sandbox provides full filesystem access:
|
|
196
248
|
|
|
197
|
-
#### `
|
|
249
|
+
#### `sandbox.filesystem.writeFile(path, content)`
|
|
198
250
|
|
|
199
|
-
|
|
251
|
+
Write a file to the sandbox.
|
|
200
252
|
|
|
201
253
|
```typescript
|
|
202
|
-
|
|
203
|
-
provider: string;
|
|
204
|
-
sandboxId: string;
|
|
205
|
-
|
|
206
|
-
execute(code: string, runtime?: Runtime): Promise<ExecutionResult>;
|
|
207
|
-
runCode(code: string, runtime?: Runtime): Promise<ExecutionResult>;
|
|
208
|
-
runCommand(command: string, args?: string[]): Promise<ExecutionResult>;
|
|
209
|
-
kill(): Promise<void>;
|
|
210
|
-
getInfo(): Promise<SandboxInfo>;
|
|
211
|
-
}
|
|
254
|
+
await sandbox.filesystem.writeFile('/tmp/hello.py', 'print("Hello World")');
|
|
212
255
|
```
|
|
213
256
|
|
|
214
|
-
#### `
|
|
257
|
+
#### `sandbox.filesystem.readFile(path)`
|
|
215
258
|
|
|
216
|
-
|
|
259
|
+
Read a file from the sandbox.
|
|
217
260
|
|
|
218
261
|
```typescript
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
262
|
+
const content = await sandbox.filesystem.readFile('/tmp/hello.py');
|
|
263
|
+
console.log(content); // 'print("Hello World")'
|
|
264
|
+
```
|
|
222
265
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
remove(path: string): Promise<void>;
|
|
230
|
-
}
|
|
266
|
+
#### `sandbox.filesystem.mkdir(path)`
|
|
267
|
+
|
|
268
|
+
Create a directory.
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
await sandbox.filesystem.mkdir('/tmp/mydir');
|
|
231
272
|
```
|
|
232
273
|
|
|
233
|
-
#### `
|
|
274
|
+
#### `sandbox.filesystem.readdir(path)`
|
|
234
275
|
|
|
235
|
-
|
|
276
|
+
List directory contents.
|
|
236
277
|
|
|
237
278
|
```typescript
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
279
|
+
const files = await sandbox.filesystem.readdir('/tmp');
|
|
280
|
+
console.log(files); // [{ name: 'hello.py', type: 'file', size: 123 }, ...]
|
|
281
|
+
```
|
|
241
282
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
283
|
+
#### `sandbox.filesystem.exists(path)`
|
|
284
|
+
|
|
285
|
+
Check if a file or directory exists.
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
const exists = await sandbox.filesystem.exists('/tmp/hello.py');
|
|
289
|
+
console.log(exists); // true
|
|
246
290
|
```
|
|
247
291
|
|
|
248
|
-
#### `
|
|
292
|
+
#### `sandbox.filesystem.remove(path)`
|
|
249
293
|
|
|
250
|
-
|
|
294
|
+
Remove a file or directory.
|
|
251
295
|
|
|
252
296
|
```typescript
|
|
253
|
-
|
|
297
|
+
await sandbox.filesystem.remove('/tmp/hello.py');
|
|
254
298
|
```
|
|
255
299
|
|
|
256
|
-
###
|
|
300
|
+
### Terminal Operations
|
|
257
301
|
|
|
258
|
-
|
|
302
|
+
The sandbox provides terminal access in two modes: **PTY mode** (interactive shell) and **Exec mode** (command tracking).
|
|
259
303
|
|
|
260
|
-
|
|
304
|
+
#### `sandbox.terminal.create(options?)`
|
|
305
|
+
|
|
306
|
+
Create a new terminal session.
|
|
261
307
|
|
|
262
308
|
```typescript
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
sandboxId: string;
|
|
269
|
-
provider: string;
|
|
270
|
-
}
|
|
309
|
+
// PTY mode - Interactive shell
|
|
310
|
+
const pty = await sandbox.terminal.create({ pty: true, shell: '/bin/bash' });
|
|
311
|
+
|
|
312
|
+
// Exec mode - Command tracking (default)
|
|
313
|
+
const exec = await sandbox.terminal.create({ pty: false });
|
|
271
314
|
```
|
|
272
315
|
|
|
273
|
-
|
|
316
|
+
**Options:**
|
|
317
|
+
- `pty?: boolean` - Terminal mode: `true` = PTY (interactive), `false` = exec (command tracking). Default: `false`
|
|
318
|
+
- `shell?: string` - Shell to use (e.g., '/bin/bash'). PTY mode only
|
|
319
|
+
- `encoding?: 'raw' | 'base64'` - Output encoding. Default: `'raw'`
|
|
274
320
|
|
|
275
|
-
|
|
321
|
+
**Returns:** `TerminalInstance`
|
|
322
|
+
|
|
323
|
+
#### `sandbox.terminal.list()`
|
|
324
|
+
|
|
325
|
+
List all active terminals.
|
|
276
326
|
|
|
277
327
|
```typescript
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
provider: string;
|
|
281
|
-
runtime: Runtime;
|
|
282
|
-
status: 'running' | 'stopped' | 'error';
|
|
283
|
-
createdAt: Date;
|
|
284
|
-
timeout: number;
|
|
285
|
-
metadata?: Record<string, any>;
|
|
286
|
-
}
|
|
328
|
+
const terminals = await sandbox.terminal.list();
|
|
329
|
+
console.log(terminals); // [{ id: 'term-1', pty: true, status: 'running', ... }]
|
|
287
330
|
```
|
|
288
331
|
|
|
289
|
-
#### `
|
|
332
|
+
#### `sandbox.terminal.retrieve(id)`
|
|
290
333
|
|
|
291
|
-
|
|
334
|
+
Retrieve a specific terminal by ID.
|
|
292
335
|
|
|
293
336
|
```typescript
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
path: string;
|
|
297
|
-
isDirectory: boolean;
|
|
298
|
-
size: number;
|
|
299
|
-
lastModified: Date;
|
|
300
|
-
}
|
|
337
|
+
const terminal = await sandbox.terminal.retrieve('term-123');
|
|
338
|
+
console.log(terminal.id, terminal.status);
|
|
301
339
|
```
|
|
302
340
|
|
|
303
|
-
|
|
341
|
+
#### `sandbox.terminal.destroy(id)`
|
|
304
342
|
|
|
305
|
-
|
|
343
|
+
Destroy a terminal by ID.
|
|
306
344
|
|
|
307
345
|
```typescript
|
|
308
|
-
|
|
346
|
+
await sandbox.terminal.destroy('term-123');
|
|
347
|
+
```
|
|
309
348
|
|
|
310
|
-
|
|
311
|
-
// Auto-detect best available provider
|
|
312
|
-
const sandbox = ComputeSDK.createSandbox();
|
|
313
|
-
|
|
314
|
-
if ('filesystem' in sandbox) {
|
|
315
|
-
const fsSandbox = sandbox as FilesystemComputeSandbox;
|
|
316
|
-
|
|
317
|
-
// Create project structure
|
|
318
|
-
await fsSandbox.filesystem.mkdir('/project/data');
|
|
319
|
-
await fsSandbox.filesystem.mkdir('/project/output');
|
|
320
|
-
|
|
321
|
-
// Write input data
|
|
322
|
-
const data = JSON.stringify([
|
|
323
|
-
{ name: 'Alice', sales: 1000 },
|
|
324
|
-
{ name: 'Bob', sales: 1500 },
|
|
325
|
-
{ name: 'Charlie', sales: 800 }
|
|
326
|
-
]);
|
|
327
|
-
|
|
328
|
-
await fsSandbox.filesystem.writeFile('/project/data/sales.json', data);
|
|
329
|
-
|
|
330
|
-
// Process data based on provider
|
|
331
|
-
let code: string;
|
|
332
|
-
if (sandbox.provider === 'e2b') {
|
|
333
|
-
// Python processing for E2B
|
|
334
|
-
code = `
|
|
335
|
-
import json
|
|
336
|
-
import pandas as pd
|
|
337
|
-
|
|
338
|
-
# Read data
|
|
339
|
-
with open('/project/data/sales.json', 'r') as f:
|
|
340
|
-
data = json.load(f)
|
|
341
|
-
|
|
342
|
-
# Process with pandas
|
|
343
|
-
df = pd.DataFrame(data)
|
|
344
|
-
total_sales = df['sales'].sum()
|
|
345
|
-
avg_sales = df['sales'].mean()
|
|
346
|
-
|
|
347
|
-
# Write results
|
|
348
|
-
results = {
|
|
349
|
-
'total_sales': total_sales,
|
|
350
|
-
'average_sales': avg_sales,
|
|
351
|
-
'top_performer': df.loc[df['sales'].idxmax(), 'name']
|
|
352
|
-
}
|
|
349
|
+
### PTY Mode (Interactive Shell)
|
|
353
350
|
|
|
354
|
-
with
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
print(f"Total Sales: ${total_sales}")
|
|
358
|
-
print(f"Average Sales: ${avg_sales:.2f}")
|
|
359
|
-
print(f"Top Performer: {results['top_performer']}")
|
|
360
|
-
`;
|
|
361
|
-
} else {
|
|
362
|
-
// JavaScript processing for Vercel/Daytona
|
|
363
|
-
code = `
|
|
364
|
-
const fs = require('fs');
|
|
365
|
-
|
|
366
|
-
// Read data
|
|
367
|
-
const data = JSON.parse(fs.readFileSync('/project/data/sales.json', 'utf8'));
|
|
368
|
-
|
|
369
|
-
// Process data
|
|
370
|
-
const totalSales = data.reduce((sum, person) => sum + person.sales, 0);
|
|
371
|
-
const avgSales = totalSales / data.length;
|
|
372
|
-
const topPerformer = data.reduce((top, person) =>
|
|
373
|
-
person.sales > top.sales ? person : top
|
|
374
|
-
);
|
|
375
|
-
|
|
376
|
-
// Write results
|
|
377
|
-
const results = {
|
|
378
|
-
total_sales: totalSales,
|
|
379
|
-
average_sales: avgSales,
|
|
380
|
-
top_performer: topPerformer.name
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
fs.writeFileSync('/project/output/results.json', JSON.stringify(results, null, 2));
|
|
384
|
-
|
|
385
|
-
console.log(\`Total Sales: $\${totalSales}\`);
|
|
386
|
-
console.log(\`Average Sales: $\${avgSales.toFixed(2)}\`);
|
|
387
|
-
console.log(\`Top Performer: \${results.top_performer}\`);
|
|
388
|
-
`;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// Execute processing
|
|
392
|
-
const result = await fsSandbox.execute(code);
|
|
393
|
-
console.log('Processing Output:', result.stdout);
|
|
394
|
-
|
|
395
|
-
// Read results
|
|
396
|
-
const results = await fsSandbox.filesystem.readFile('/project/output/results.json');
|
|
397
|
-
console.log('Results:', JSON.parse(results));
|
|
398
|
-
|
|
399
|
-
// List generated files
|
|
400
|
-
const outputFiles = await fsSandbox.filesystem.readdir('/project/output');
|
|
401
|
-
console.log('Generated files:', outputFiles.map(f => f.name));
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
await sandbox.kill();
|
|
405
|
-
}
|
|
351
|
+
PTY mode creates an interactive shell session with real-time input/output over WebSocket.
|
|
352
|
+
|
|
353
|
+
#### `terminal.write(input)`
|
|
406
354
|
|
|
407
|
-
|
|
355
|
+
Send input to the terminal shell.
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
const pty = await sandbox.terminal.create({ pty: true });
|
|
359
|
+
pty.on('output', (data) => console.log(data));
|
|
360
|
+
pty.write('ls -la\n');
|
|
361
|
+
pty.write('pwd\n');
|
|
362
|
+
await pty.destroy();
|
|
408
363
|
```
|
|
409
364
|
|
|
410
|
-
|
|
365
|
+
#### `terminal.resize(cols, rows)`
|
|
366
|
+
|
|
367
|
+
Resize the terminal window.
|
|
411
368
|
|
|
412
369
|
```typescript
|
|
413
|
-
|
|
414
|
-
|
|
370
|
+
pty.resize(120, 40);
|
|
371
|
+
```
|
|
415
372
|
|
|
416
|
-
|
|
417
|
-
const sandbox = e2b() as TerminalComputeSandbox & FilesystemComputeSandbox;
|
|
418
|
-
|
|
419
|
-
// Set up development environment
|
|
420
|
-
await sandbox.filesystem.mkdir('/workspace');
|
|
421
|
-
await sandbox.filesystem.writeFile('/workspace/requirements.txt',
|
|
422
|
-
'pandas\nnumpy\nmatplotlib\nscikit-learn'
|
|
423
|
-
);
|
|
424
|
-
|
|
425
|
-
// Create interactive terminal
|
|
426
|
-
const terminal = await sandbox.terminal.create({
|
|
427
|
-
command: 'bash',
|
|
428
|
-
cols: 120,
|
|
429
|
-
rows: 30
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
// Set up output handler
|
|
433
|
-
terminal.onData = (data: Uint8Array) => {
|
|
434
|
-
const output = new TextDecoder().decode(data);
|
|
435
|
-
console.log('Terminal:', output);
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
// Install dependencies
|
|
439
|
-
await terminal.write('cd /workspace\n');
|
|
440
|
-
await terminal.write('pip install -r requirements.txt\n');
|
|
441
|
-
|
|
442
|
-
// Start interactive Python session
|
|
443
|
-
await terminal.write('python3\n');
|
|
444
|
-
await terminal.write('import pandas as pd\n');
|
|
445
|
-
await terminal.write('import numpy as np\n');
|
|
446
|
-
await terminal.write('print("Development environment ready!")\n');
|
|
447
|
-
|
|
448
|
-
// Simulate interactive development
|
|
449
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
450
|
-
|
|
451
|
-
// Clean up
|
|
452
|
-
await terminal.kill();
|
|
453
|
-
await sandbox.kill();
|
|
454
|
-
}
|
|
373
|
+
#### `terminal.on(event, handler)`
|
|
455
374
|
|
|
456
|
-
|
|
375
|
+
Register an event handler. Events: `'output'`, `'error'`, `'destroyed'`.
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
pty.on('output', (data) => console.log('Output:', data));
|
|
379
|
+
pty.on('error', (error) => console.error('Error:', error));
|
|
380
|
+
pty.on('destroyed', () => console.log('Terminal destroyed'));
|
|
457
381
|
```
|
|
458
382
|
|
|
459
|
-
|
|
383
|
+
#### `terminal.off(event, handler)`
|
|
384
|
+
|
|
385
|
+
Unregister an event handler.
|
|
460
386
|
|
|
461
387
|
```typescript
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
async function compareProviders() {
|
|
468
|
-
const testCode = `
|
|
469
|
-
import json
|
|
470
|
-
import time
|
|
471
|
-
start = time.time()
|
|
472
|
-
|
|
473
|
-
# Simple computation
|
|
474
|
-
result = sum(range(1000))
|
|
475
|
-
elapsed = time.time() - start
|
|
476
|
-
|
|
477
|
-
output = {
|
|
478
|
-
"result": result,
|
|
479
|
-
"elapsed_ms": round(elapsed * 1000, 2),
|
|
480
|
-
"provider": "will_be_set"
|
|
481
|
-
}
|
|
388
|
+
const handler = (data) => console.log(data);
|
|
389
|
+
pty.on('output', handler);
|
|
390
|
+
pty.off('output', handler);
|
|
391
|
+
```
|
|
482
392
|
|
|
483
|
-
|
|
484
|
-
`;
|
|
485
|
-
|
|
486
|
-
const providers = [
|
|
487
|
-
{ name: 'E2B', factory: () => e2b() },
|
|
488
|
-
{ name: 'Vercel', factory: () => vercel({ runtime: 'python' }) },
|
|
489
|
-
{ name: 'Daytona', factory: () => daytona({ runtime: 'python' }) },
|
|
490
|
-
];
|
|
491
|
-
|
|
492
|
-
console.log('Performance Comparison:');
|
|
493
|
-
console.log('='.repeat(50));
|
|
494
|
-
|
|
495
|
-
for (const { name, factory } of providers) {
|
|
496
|
-
try {
|
|
497
|
-
const start = Date.now();
|
|
498
|
-
const result = await executeSandbox({
|
|
499
|
-
sandbox: factory(),
|
|
500
|
-
code: testCode,
|
|
501
|
-
runtime: 'python'
|
|
502
|
-
});
|
|
503
|
-
const totalTime = Date.now() - start;
|
|
504
|
-
|
|
505
|
-
const output = JSON.parse(result.stdout);
|
|
506
|
-
console.log(`${name}:`);
|
|
507
|
-
console.log(` Computation: ${output.result}`);
|
|
508
|
-
console.log(` Execution time: ${output.elapsed_ms}ms`);
|
|
509
|
-
console.log(` Total time: ${totalTime}ms`);
|
|
510
|
-
console.log(` Provider overhead: ${totalTime - output.elapsed_ms}ms`);
|
|
511
|
-
console.log();
|
|
512
|
-
|
|
513
|
-
} catch (error) {
|
|
514
|
-
console.log(`${name}: Failed - ${error.message}`);
|
|
515
|
-
console.log();
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
}
|
|
393
|
+
#### Terminal Properties
|
|
519
394
|
|
|
520
|
-
|
|
395
|
+
```typescript
|
|
396
|
+
console.log(pty.id); // Terminal ID
|
|
397
|
+
console.log(pty.status); // 'running' | 'stopped' | 'active' | 'ready'
|
|
398
|
+
console.log(pty.channel); // WebSocket channel (PTY only)
|
|
399
|
+
console.log(pty.pty); // true for PTY mode
|
|
521
400
|
```
|
|
522
401
|
|
|
523
|
-
|
|
402
|
+
### Exec Mode (Command Tracking)
|
|
524
403
|
|
|
525
|
-
|
|
404
|
+
Exec mode executes commands with structured result tracking, suitable for automation.
|
|
526
405
|
|
|
527
|
-
|
|
528
|
-
import { ComputeSDK } from 'computesdk';
|
|
406
|
+
#### `terminal.command.run(command, options?)`
|
|
529
407
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
547
|
-
}
|
|
408
|
+
Execute a command in the terminal.
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
const exec = await sandbox.terminal.create({ pty: false });
|
|
412
|
+
|
|
413
|
+
// Foreground execution (waits for completion)
|
|
414
|
+
const cmd = await exec.command.run('npm test');
|
|
415
|
+
console.log(cmd.stdout);
|
|
416
|
+
console.log(cmd.stderr);
|
|
417
|
+
console.log(cmd.exitCode);
|
|
418
|
+
|
|
419
|
+
// Background execution (returns immediately)
|
|
420
|
+
const bgCmd = await exec.command.run('npm install', { background: true });
|
|
421
|
+
console.log(bgCmd.status); // 'running'
|
|
422
|
+
await bgCmd.wait(); // Wait for completion
|
|
423
|
+
console.log(bgCmd.exitCode);
|
|
548
424
|
```
|
|
549
425
|
|
|
550
|
-
|
|
426
|
+
**Parameters:**
|
|
427
|
+
- `command: string` - The command to execute
|
|
428
|
+
- `options?: { background?: boolean }` - Execution options
|
|
429
|
+
|
|
430
|
+
**Returns:** `Command` object
|
|
551
431
|
|
|
552
|
-
|
|
432
|
+
#### `terminal.command.list()`
|
|
553
433
|
|
|
554
|
-
|
|
434
|
+
List all commands executed in this terminal.
|
|
555
435
|
|
|
556
436
|
```typescript
|
|
557
|
-
|
|
437
|
+
const commands = await exec.command.list();
|
|
438
|
+
commands.forEach(cmd => {
|
|
439
|
+
console.log(cmd.id, cmd.command, cmd.status, cmd.exitCode);
|
|
440
|
+
});
|
|
441
|
+
```
|
|
558
442
|
|
|
559
|
-
|
|
443
|
+
#### `terminal.command.retrieve(cmdId)`
|
|
560
444
|
|
|
561
|
-
|
|
562
|
-
const result = await sandbox.execute(`
|
|
563
|
-
import pandas as pd
|
|
564
|
-
import matplotlib.pyplot as plt
|
|
565
|
-
import numpy as np
|
|
445
|
+
Retrieve a specific command by ID.
|
|
566
446
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
447
|
+
```typescript
|
|
448
|
+
const cmd = await exec.command.retrieve('cmd-123');
|
|
449
|
+
console.log(cmd.stdout);
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Command Object
|
|
453
|
+
|
|
454
|
+
The `Command` object represents a command execution result.
|
|
455
|
+
|
|
456
|
+
#### Command Properties
|
|
573
457
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
console.log(
|
|
458
|
+
```typescript
|
|
459
|
+
console.log(cmd.id); // Command ID
|
|
460
|
+
console.log(cmd.terminalId); // Parent terminal ID
|
|
461
|
+
console.log(cmd.command); // Executed command
|
|
462
|
+
console.log(cmd.status); // 'running' | 'completed' | 'failed'
|
|
463
|
+
console.log(cmd.stdout); // Standard output
|
|
464
|
+
console.log(cmd.stderr); // Standard error
|
|
465
|
+
console.log(cmd.exitCode); // Exit code (undefined if running)
|
|
466
|
+
console.log(cmd.durationMs); // Execution time in milliseconds
|
|
467
|
+
console.log(cmd.startedAt); // Start timestamp
|
|
468
|
+
console.log(cmd.finishedAt); // Finish timestamp (undefined if running)
|
|
577
469
|
```
|
|
578
470
|
|
|
579
|
-
|
|
471
|
+
#### `command.wait(timeout?)`
|
|
580
472
|
|
|
581
|
-
|
|
473
|
+
Wait for a background command to complete.
|
|
582
474
|
|
|
583
475
|
```typescript
|
|
584
|
-
|
|
476
|
+
const cmd = await exec.command.run('sleep 5', { background: true });
|
|
477
|
+
await cmd.wait(); // Waits up to default timeout
|
|
478
|
+
console.log(cmd.exitCode);
|
|
479
|
+
|
|
480
|
+
// With custom timeout (in seconds, 0 = no timeout)
|
|
481
|
+
await cmd.wait(10);
|
|
482
|
+
```
|
|
585
483
|
|
|
586
|
-
|
|
484
|
+
#### `command.refresh()`
|
|
587
485
|
|
|
588
|
-
|
|
589
|
-
const result = await sandbox.execute(`
|
|
590
|
-
const fs = require('fs');
|
|
591
|
-
const path = require('path');
|
|
486
|
+
Refresh the command status from the server.
|
|
592
487
|
|
|
593
|
-
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
488
|
+
```typescript
|
|
489
|
+
const cmd = await exec.command.run('npm build', { background: true });
|
|
490
|
+
// ... later ...
|
|
491
|
+
await cmd.refresh();
|
|
492
|
+
console.log(cmd.status, cmd.exitCode);
|
|
493
|
+
```
|
|
599
494
|
|
|
600
|
-
|
|
601
|
-
fs.writeFileSync('/tmp/api-data.json', JSON.stringify(apiData, null, 2));
|
|
495
|
+
#### `terminal.destroy()`
|
|
602
496
|
|
|
603
|
-
|
|
604
|
-
console.log('Active users:', apiData.active);
|
|
605
|
-
`);
|
|
497
|
+
Destroy the terminal and clean up resources.
|
|
606
498
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
console.log('Generated data:', JSON.parse(data));
|
|
499
|
+
```typescript
|
|
500
|
+
await exec.destroy();
|
|
610
501
|
```
|
|
611
502
|
|
|
612
|
-
|
|
503
|
+
## Examples
|
|
613
504
|
|
|
614
|
-
|
|
505
|
+
### Multi-Step Build Process
|
|
615
506
|
|
|
616
507
|
```typescript
|
|
617
|
-
import {
|
|
508
|
+
import { compute } from 'computesdk';
|
|
618
509
|
|
|
619
|
-
const sandbox =
|
|
510
|
+
const sandbox = await compute.sandbox.create();
|
|
620
511
|
|
|
621
|
-
//
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
512
|
+
// Create project structure
|
|
513
|
+
await sandbox.filesystem.mkdir('/app');
|
|
514
|
+
await sandbox.filesystem.mkdir('/app/src');
|
|
515
|
+
|
|
516
|
+
// Write package.json
|
|
517
|
+
await sandbox.filesystem.writeFile('/app/package.json', JSON.stringify({
|
|
518
|
+
name: 'my-app',
|
|
519
|
+
version: '1.0.0',
|
|
520
|
+
dependencies: {
|
|
521
|
+
'express': '^4.18.0'
|
|
522
|
+
}
|
|
523
|
+
}, null, 2));
|
|
625
524
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
525
|
+
// Write source code
|
|
526
|
+
await sandbox.filesystem.writeFile('/app/src/index.js', `
|
|
527
|
+
const express = require('express');
|
|
528
|
+
const app = express();
|
|
629
529
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
530
|
+
app.get('/', (req, res) => {
|
|
531
|
+
res.json({ message: 'Hello World!' });
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
console.log('Server ready!');
|
|
535
|
+
`);
|
|
633
536
|
|
|
634
|
-
|
|
635
|
-
|
|
537
|
+
// Install dependencies
|
|
538
|
+
const installResult = await sandbox.runCommand('npm install', { cwd: '/app' });
|
|
539
|
+
console.log('Install:', installResult.stdout);
|
|
636
540
|
|
|
637
|
-
|
|
638
|
-
|
|
541
|
+
// Run the app
|
|
542
|
+
const runResult = await sandbox.runCode(`
|
|
543
|
+
const { spawn } = require('child_process');
|
|
544
|
+
const proc = spawn('node', ['src/index.js'], { cwd: '/app' });
|
|
545
|
+
proc.stdout.on('data', (data) => console.log(data.toString()));
|
|
639
546
|
`);
|
|
640
547
|
|
|
641
|
-
|
|
642
|
-
const files = await sandbox.filesystem.readdir('/workspace');
|
|
643
|
-
console.log('Workspace files:', files.map(f => f.name));
|
|
548
|
+
console.log(runResult.output);
|
|
644
549
|
|
|
645
|
-
|
|
646
|
-
const mainPy = await sandbox.filesystem.readFile('/workspace/src/main.py');
|
|
647
|
-
console.log('main.py content:', mainPy);
|
|
550
|
+
await sandbox.destroy();
|
|
648
551
|
```
|
|
649
552
|
|
|
553
|
+
### Terminal Command Execution
|
|
650
554
|
|
|
555
|
+
```typescript
|
|
556
|
+
import { compute } from 'computesdk';
|
|
651
557
|
|
|
652
|
-
|
|
558
|
+
const sandbox = await compute.sandbox.create();
|
|
653
559
|
|
|
654
|
-
|
|
560
|
+
// Create exec mode terminal for command tracking
|
|
561
|
+
const terminal = await sandbox.terminal.create({ pty: false });
|
|
655
562
|
|
|
656
|
-
|
|
563
|
+
// Run build commands with tracking
|
|
564
|
+
const install = await terminal.command.run('npm install');
|
|
565
|
+
console.log('Install exit code:', install.exitCode);
|
|
657
566
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
- **Daytona**: Development workspaces, custom environments, team collaboration
|
|
567
|
+
const build = await terminal.command.run('npm run build');
|
|
568
|
+
console.log('Build output:', build.stdout);
|
|
661
569
|
|
|
662
|
-
|
|
570
|
+
// Run tests in background
|
|
571
|
+
const tests = await terminal.command.run('npm test', { background: true });
|
|
572
|
+
console.log('Tests started:', tests.status);
|
|
663
573
|
|
|
664
|
-
|
|
574
|
+
// Wait for tests to complete
|
|
575
|
+
await tests.wait(60); // 60 second timeout
|
|
576
|
+
console.log('Tests completed:', tests.exitCode === 0 ? 'PASSED' : 'FAILED');
|
|
577
|
+
console.log('Test output:', tests.stdout);
|
|
665
578
|
|
|
666
|
-
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
// Your code here
|
|
670
|
-
const result = await sandbox.execute('print("Hello")');
|
|
671
|
-
} finally {
|
|
672
|
-
// Always clean up
|
|
673
|
-
await sandbox.kill();
|
|
674
|
-
}
|
|
675
|
-
```
|
|
579
|
+
// List all commands
|
|
580
|
+
const commands = await terminal.command.list();
|
|
581
|
+
console.log(`Executed ${commands.length} commands`);
|
|
676
582
|
|
|
677
|
-
|
|
583
|
+
await terminal.destroy();
|
|
584
|
+
await sandbox.destroy();
|
|
585
|
+
```
|
|
678
586
|
|
|
679
|
-
|
|
587
|
+
### Interactive Terminal Session
|
|
680
588
|
|
|
681
589
|
```typescript
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
590
|
+
import { compute } from 'computesdk';
|
|
591
|
+
|
|
592
|
+
const sandbox = await compute.sandbox.create();
|
|
593
|
+
|
|
594
|
+
// Create PTY terminal for interactive shell
|
|
595
|
+
const pty = await sandbox.terminal.create({
|
|
596
|
+
pty: true,
|
|
597
|
+
shell: '/bin/bash'
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
// Collect all output
|
|
601
|
+
let output = '';
|
|
602
|
+
pty.on('output', (data) => {
|
|
603
|
+
output += data;
|
|
604
|
+
console.log(data);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
pty.on('error', (error) => {
|
|
608
|
+
console.error('Terminal error:', error);
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
// Execute interactive commands
|
|
612
|
+
pty.write('echo "Starting project setup"\n');
|
|
613
|
+
pty.write('mkdir -p /workspace/myproject\n');
|
|
614
|
+
pty.write('cd /workspace/myproject\n');
|
|
615
|
+
pty.write('npm init -y\n');
|
|
616
|
+
pty.write('npm install express\n');
|
|
617
|
+
pty.write('echo "Setup complete"\n');
|
|
618
|
+
|
|
619
|
+
// Wait for operations to complete
|
|
620
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
697
621
|
|
|
698
|
-
|
|
622
|
+
// Clean up
|
|
623
|
+
await pty.destroy();
|
|
624
|
+
await sandbox.destroy();
|
|
699
625
|
|
|
700
|
-
|
|
626
|
+
console.log('Complete output:', output);
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
### Using Different Providers
|
|
701
630
|
|
|
702
631
|
```typescript
|
|
703
|
-
import {
|
|
632
|
+
import { compute } from 'computesdk';
|
|
704
633
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
}
|
|
634
|
+
// Use E2B for data science
|
|
635
|
+
compute.setConfig({
|
|
636
|
+
provider: 'e2b',
|
|
637
|
+
e2b: { apiKey: process.env.E2B_API_KEY }
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
const e2bSandbox = await compute.sandbox.create();
|
|
641
|
+
await e2bSandbox.runCode('import pandas as pd; print(pd.__version__)');
|
|
642
|
+
await e2bSandbox.destroy();
|
|
643
|
+
|
|
644
|
+
// Switch to Modal for GPU workloads
|
|
645
|
+
compute.setConfig({
|
|
646
|
+
provider: 'modal',
|
|
647
|
+
modal: {
|
|
648
|
+
tokenId: process.env.MODAL_TOKEN_ID,
|
|
649
|
+
tokenSecret: process.env.MODAL_TOKEN_SECRET
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
const modalSandbox = await compute.sandbox.create();
|
|
654
|
+
await modalSandbox.runCode('import torch; print(torch.cuda.is_available())');
|
|
655
|
+
await modalSandbox.destroy();
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
## Error Handling
|
|
709
659
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
660
|
+
```typescript
|
|
661
|
+
try {
|
|
662
|
+
const sandbox = await compute.sandbox.create();
|
|
663
|
+
const result = await sandbox.runCode('invalid python code');
|
|
664
|
+
} catch (error) {
|
|
665
|
+
console.error('Execution failed:', error.message);
|
|
666
|
+
|
|
667
|
+
// Check for specific error types
|
|
668
|
+
if (error.message.includes('No provider detected')) {
|
|
669
|
+
console.error('Set provider credentials in environment variables');
|
|
670
|
+
}
|
|
713
671
|
}
|
|
714
672
|
```
|
|
715
673
|
|
|
716
|
-
##
|
|
674
|
+
## Direct Mode (Advanced)
|
|
717
675
|
|
|
718
|
-
|
|
676
|
+
For advanced use cases where you want to bypass the gateway and use provider SDKs directly, see individual provider packages:
|
|
719
677
|
|
|
720
|
-
|
|
678
|
+
- **[@computesdk/e2b](../e2b)** - E2B provider
|
|
679
|
+
- **[@computesdk/modal](../modal)** - Modal provider
|
|
680
|
+
- **[@computesdk/railway](../railway)** - Railway provider
|
|
681
|
+
- **[@computesdk/daytona](../daytona)** - Daytona provider
|
|
721
682
|
|
|
722
|
-
|
|
723
|
-
- `BaseComputeSpecification` for basic execution
|
|
724
|
-
- `FilesystemComputeSpecification` for filesystem support
|
|
725
|
-
- `TerminalComputeSpecification` for terminal support
|
|
726
|
-
- `FullComputeSpecification` for complete functionality
|
|
683
|
+
Example direct mode usage:
|
|
727
684
|
|
|
728
|
-
|
|
685
|
+
```typescript
|
|
686
|
+
import { e2b } from '@computesdk/e2b';
|
|
729
687
|
|
|
730
|
-
|
|
688
|
+
const compute = e2b({ apiKey: 'your_api_key' });
|
|
689
|
+
const sandbox = await compute.sandbox.create();
|
|
690
|
+
```
|
|
731
691
|
|
|
732
|
-
|
|
692
|
+
## Building Custom Providers
|
|
733
693
|
|
|
734
|
-
|
|
694
|
+
Want to add support for a new compute provider? See **[@computesdk/provider](../provider)** for the provider framework and documentation on building custom providers.
|
|
735
695
|
|
|
736
|
-
|
|
696
|
+
## TypeScript Support
|
|
737
697
|
|
|
738
|
-
|
|
698
|
+
Full TypeScript support with comprehensive type definitions:
|
|
739
699
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
700
|
+
```typescript
|
|
701
|
+
import type {
|
|
702
|
+
Sandbox,
|
|
703
|
+
SandboxInfo,
|
|
704
|
+
CodeResult,
|
|
705
|
+
CommandResult,
|
|
706
|
+
CreateSandboxOptions
|
|
707
|
+
} from 'computesdk';
|
|
708
|
+
```
|
|
743
709
|
|
|
744
|
-
|
|
710
|
+
## License
|
|
745
711
|
|
|
746
|
-
|
|
712
|
+
MIT
|