computesdk 1.0.2 → 1.1.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.
- package/LICENSE +21 -0
- package/README.md +573 -185
- package/dist/index.d.mts +416 -340
- package/dist/index.d.ts +416 -340
- package/dist/index.js +910 -450
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +906 -436
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -33
package/dist/index.js
CHANGED
|
@@ -20,515 +20,975 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
ConfigurationError: () => ConfigurationError,
|
|
28
|
-
DEFAULT_TIMEOUT: () => DEFAULT_TIMEOUT,
|
|
29
|
-
ENV_KEYS: () => ENV_KEYS,
|
|
30
|
-
ExecutionError: () => ExecutionError,
|
|
31
|
-
ProviderError: () => ProviderError,
|
|
32
|
-
ProviderUnavailableError: () => ProviderUnavailableError,
|
|
33
|
-
TimeoutError: () => TimeoutError,
|
|
34
|
-
autoSelectProvider: () => autoSelectProvider,
|
|
35
|
-
createComputeRegistry: () => createComputeRegistry,
|
|
36
|
-
default: () => index_default,
|
|
37
|
-
detectAvailableProviders: () => detectAvailableProviders,
|
|
38
|
-
executeSandbox: () => executeSandbox,
|
|
39
|
-
getDefaultRuntime: () => getDefaultRuntime,
|
|
40
|
-
isCloudflareWorkers: () => isCloudflareWorkers,
|
|
41
|
-
normalizeContainerConfig: () => normalizeContainerConfig,
|
|
42
|
-
normalizeSandboxConfig: () => normalizeSandboxConfig,
|
|
43
|
-
retry: () => retry,
|
|
44
|
-
validateProviderApiKey: () => validateProviderApiKey
|
|
23
|
+
SandboxManager: () => SandboxManager,
|
|
24
|
+
compute: () => compute,
|
|
25
|
+
createProvider: () => createProvider,
|
|
26
|
+
handleComputeRequest: () => handleComputeRequest
|
|
45
27
|
});
|
|
46
28
|
module.exports = __toCommonJS(index_exports);
|
|
47
29
|
|
|
48
|
-
// src/
|
|
49
|
-
var
|
|
30
|
+
// src/sandbox.ts
|
|
31
|
+
var SandboxManager = class {
|
|
50
32
|
/**
|
|
51
|
-
* Create a
|
|
52
|
-
*
|
|
53
|
-
* @param message Error message
|
|
54
|
-
* @param provider Provider identifier
|
|
55
|
-
* @param sandboxId Optional sandbox identifier
|
|
33
|
+
* Create a sandbox from a provider
|
|
56
34
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this.name = this.constructor.name;
|
|
60
|
-
this.provider = provider;
|
|
61
|
-
this.sandboxId = sandboxId;
|
|
62
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
35
|
+
async create(provider, options) {
|
|
36
|
+
return await provider.sandbox.create(options);
|
|
63
37
|
}
|
|
64
|
-
};
|
|
65
|
-
var ExecutionError = class extends ComputeError {
|
|
66
38
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* @param message Error message
|
|
70
|
-
* @param provider Provider identifier
|
|
71
|
-
* @param exitCode Exit code from the execution
|
|
72
|
-
* @param sandboxId Optional sandbox identifier
|
|
39
|
+
* Get an existing sandbox by ID from a provider
|
|
73
40
|
*/
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
/** Error code */
|
|
77
|
-
this.code = "EXECUTION_ERROR";
|
|
78
|
-
/** Execution errors are generally not retryable */
|
|
79
|
-
this.isRetryable = false;
|
|
80
|
-
this.exitCode = exitCode;
|
|
41
|
+
async getById(provider, sandboxId) {
|
|
42
|
+
return await provider.sandbox.getById(sandboxId);
|
|
81
43
|
}
|
|
82
|
-
};
|
|
83
|
-
var TimeoutError = class extends ComputeError {
|
|
84
44
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* @param message Error message
|
|
88
|
-
* @param provider Provider identifier
|
|
89
|
-
* @param timeoutMs Timeout duration in milliseconds
|
|
90
|
-
* @param sandboxId Optional sandbox identifier
|
|
45
|
+
* List all active sandboxes from a provider
|
|
91
46
|
*/
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
/** Error code */
|
|
95
|
-
this.code = "TIMEOUT_ERROR";
|
|
96
|
-
/** Timeout errors may be retryable with a longer timeout */
|
|
97
|
-
this.isRetryable = true;
|
|
98
|
-
this.timeoutMs = timeoutMs;
|
|
47
|
+
async list(provider) {
|
|
48
|
+
return await provider.sandbox.list();
|
|
99
49
|
}
|
|
100
|
-
};
|
|
101
|
-
var ProviderError = class extends ComputeError {
|
|
102
50
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* @param message Error message
|
|
106
|
-
* @param provider Provider identifier
|
|
107
|
-
* @param originalError Optional original error from the provider
|
|
108
|
-
* @param sandboxId Optional sandbox identifier
|
|
51
|
+
* Destroy a sandbox via a provider
|
|
109
52
|
*/
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
/** Error code */
|
|
113
|
-
this.code = "PROVIDER_ERROR";
|
|
114
|
-
/** Provider errors may be retryable */
|
|
115
|
-
this.isRetryable = true;
|
|
116
|
-
this.originalError = originalError;
|
|
53
|
+
async destroy(provider, sandboxId) {
|
|
54
|
+
return await provider.sandbox.destroy(sandboxId);
|
|
117
55
|
}
|
|
118
56
|
};
|
|
119
|
-
|
|
57
|
+
|
|
58
|
+
// src/compute.ts
|
|
59
|
+
var ComputeManager = class {
|
|
60
|
+
constructor() {
|
|
61
|
+
this.sandboxManager = new SandboxManager();
|
|
62
|
+
this.config = null;
|
|
63
|
+
this.sandbox = {
|
|
64
|
+
/**
|
|
65
|
+
* Create a sandbox from a provider (or default provider if configured)
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* import { e2b } from '@computesdk/e2b'
|
|
70
|
+
* import { compute } from 'computesdk'
|
|
71
|
+
*
|
|
72
|
+
* // With explicit provider
|
|
73
|
+
* const sandbox = await compute.sandbox.create({
|
|
74
|
+
* provider: e2b({ apiKey: 'your-key' })
|
|
75
|
+
* })
|
|
76
|
+
*
|
|
77
|
+
* // With default provider
|
|
78
|
+
* compute.setConfig({ provider: e2b({ apiKey: 'your-key' }) })
|
|
79
|
+
* const sandbox = await compute.sandbox.create({})
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
create: async (params) => {
|
|
83
|
+
const provider = "provider" in params && params.provider ? params.provider : this.getDefaultProvider();
|
|
84
|
+
const options = params.options;
|
|
85
|
+
return await this.sandboxManager.create(provider, options);
|
|
86
|
+
},
|
|
87
|
+
/**
|
|
88
|
+
* Get an existing sandbox by ID from a provider (or default provider if configured)
|
|
89
|
+
*/
|
|
90
|
+
getById: async (providerOrSandboxId, sandboxId) => {
|
|
91
|
+
if (typeof providerOrSandboxId === "string") {
|
|
92
|
+
const provider = this.getDefaultProvider();
|
|
93
|
+
return await this.sandboxManager.getById(provider, providerOrSandboxId);
|
|
94
|
+
} else {
|
|
95
|
+
if (!sandboxId) {
|
|
96
|
+
throw new Error("sandboxId is required when provider is specified");
|
|
97
|
+
}
|
|
98
|
+
return await this.sandboxManager.getById(providerOrSandboxId, sandboxId);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
/**
|
|
102
|
+
* List all active sandboxes from a provider (or default provider if configured)
|
|
103
|
+
*/
|
|
104
|
+
list: async (provider) => {
|
|
105
|
+
const actualProvider = provider || this.getDefaultProvider();
|
|
106
|
+
return await this.sandboxManager.list(actualProvider);
|
|
107
|
+
},
|
|
108
|
+
/**
|
|
109
|
+
* Destroy a sandbox via a provider (or default provider if configured)
|
|
110
|
+
*/
|
|
111
|
+
destroy: async (providerOrSandboxId, sandboxId) => {
|
|
112
|
+
if (typeof providerOrSandboxId === "string") {
|
|
113
|
+
const provider = this.getDefaultProvider();
|
|
114
|
+
return await this.sandboxManager.destroy(provider, providerOrSandboxId);
|
|
115
|
+
} else {
|
|
116
|
+
if (!sandboxId) {
|
|
117
|
+
throw new Error("sandboxId is required when provider is specified");
|
|
118
|
+
}
|
|
119
|
+
return await this.sandboxManager.destroy(providerOrSandboxId, sandboxId);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
120
124
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* @param message Error message
|
|
124
|
-
* @param provider Provider identifier
|
|
125
|
-
* @param sandboxId Optional sandbox identifier
|
|
125
|
+
* Set default configuration
|
|
126
126
|
*/
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
/** Error code */
|
|
130
|
-
this.code = "CONFIGURATION_ERROR";
|
|
131
|
-
/** Configuration errors are not retryable without changes */
|
|
132
|
-
this.isRetryable = false;
|
|
127
|
+
setConfig(config) {
|
|
128
|
+
this.config = config;
|
|
133
129
|
}
|
|
134
|
-
};
|
|
135
|
-
var AuthenticationError = class extends ComputeError {
|
|
136
130
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* @param message Error message
|
|
140
|
-
* @param provider Provider identifier
|
|
141
|
-
* @param sandboxId Optional sandbox identifier
|
|
131
|
+
* Get current configuration
|
|
142
132
|
*/
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
/** Error code */
|
|
146
|
-
this.code = "AUTHENTICATION_ERROR";
|
|
147
|
-
/** Authentication errors are not retryable without new credentials */
|
|
148
|
-
this.isRetryable = false;
|
|
133
|
+
getConfig() {
|
|
134
|
+
return this.config;
|
|
149
135
|
}
|
|
150
|
-
};
|
|
151
|
-
var ProviderUnavailableError = class extends ComputeError {
|
|
152
136
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* @param message Error message
|
|
156
|
-
* @param provider Provider identifier
|
|
157
|
-
* @param sandboxId Optional sandbox identifier
|
|
137
|
+
* Clear current configuration
|
|
158
138
|
*/
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
139
|
+
clearConfig() {
|
|
140
|
+
this.config = null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get the default provider, throwing if not configured
|
|
144
|
+
*/
|
|
145
|
+
getDefaultProvider() {
|
|
146
|
+
if (!this.config?.provider) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
"No default provider configured. Either call compute.setConfig({ provider }) or pass provider explicitly."
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
return this.config.provider;
|
|
152
|
+
}
|
|
153
|
+
// Future: compute.blob.*, compute.database.*, compute.git.* will be added here
|
|
154
|
+
// blob = new BlobManager();
|
|
155
|
+
// database = new DatabaseManager();
|
|
156
|
+
// git = new GitManager();
|
|
157
|
+
/**
|
|
158
|
+
* Get the sandbox manager (useful for testing)
|
|
159
|
+
*/
|
|
160
|
+
getSandboxManager() {
|
|
161
|
+
return this.sandboxManager;
|
|
165
162
|
}
|
|
166
163
|
};
|
|
164
|
+
var compute = new ComputeManager();
|
|
167
165
|
|
|
168
|
-
// src/
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
166
|
+
// src/request-handler.ts
|
|
167
|
+
async function handleComputeRequest(params) {
|
|
168
|
+
const { request, provider } = params;
|
|
169
|
+
try {
|
|
170
|
+
const getSandbox = async (sandboxId) => {
|
|
171
|
+
if (sandboxId) {
|
|
172
|
+
const existingSandbox = await compute.sandbox.getById(provider, sandboxId);
|
|
173
|
+
if (!existingSandbox) {
|
|
174
|
+
throw new Error(`Sandbox with ID ${sandboxId} not found`);
|
|
175
|
+
}
|
|
176
|
+
return existingSandbox;
|
|
177
|
+
} else {
|
|
178
|
+
return await compute.sandbox.create({
|
|
179
|
+
provider,
|
|
180
|
+
options: request.options || { runtime: "python" }
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
switch (request.action) {
|
|
185
|
+
// Sandbox operations
|
|
186
|
+
case "compute.sandbox.create": {
|
|
187
|
+
const sandbox = await compute.sandbox.create({
|
|
188
|
+
provider,
|
|
189
|
+
options: request.options || { runtime: "python" }
|
|
190
|
+
});
|
|
191
|
+
return {
|
|
192
|
+
success: true,
|
|
193
|
+
sandboxId: sandbox.sandboxId,
|
|
194
|
+
provider: provider.name
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
case "compute.sandbox.destroy": {
|
|
198
|
+
if (!request.sandboxId) {
|
|
199
|
+
return {
|
|
200
|
+
success: false,
|
|
201
|
+
error: "Sandbox ID is required for destroy action",
|
|
202
|
+
sandboxId: "",
|
|
203
|
+
provider: provider.name
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
await compute.sandbox.destroy(provider, request.sandboxId);
|
|
207
|
+
return {
|
|
208
|
+
success: true,
|
|
209
|
+
sandboxId: request.sandboxId,
|
|
210
|
+
provider: provider.name
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
case "compute.sandbox.getInfo": {
|
|
214
|
+
if (!request.sandboxId) {
|
|
215
|
+
return {
|
|
216
|
+
success: false,
|
|
217
|
+
error: "Sandbox ID is required for getInfo action",
|
|
218
|
+
sandboxId: "",
|
|
219
|
+
provider: provider.name
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
223
|
+
const info = await sandbox.getInfo();
|
|
224
|
+
return {
|
|
225
|
+
success: true,
|
|
226
|
+
sandboxId: request.sandboxId,
|
|
227
|
+
provider: provider.name,
|
|
228
|
+
info: {
|
|
229
|
+
id: info.id,
|
|
230
|
+
provider: info.provider,
|
|
231
|
+
runtime: info.runtime,
|
|
232
|
+
status: info.status,
|
|
233
|
+
createdAt: info.createdAt.toISOString(),
|
|
234
|
+
timeout: info.timeout,
|
|
235
|
+
metadata: info.metadata
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
case "compute.sandbox.list": {
|
|
240
|
+
const sandboxes = await compute.sandbox.list(provider);
|
|
241
|
+
return {
|
|
242
|
+
success: true,
|
|
243
|
+
sandboxId: "",
|
|
244
|
+
provider: provider.name,
|
|
245
|
+
sandboxes: sandboxes.map((sandbox) => ({
|
|
246
|
+
sandboxId: sandbox.sandboxId,
|
|
247
|
+
provider: sandbox.provider
|
|
248
|
+
}))
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
// Code execution
|
|
252
|
+
case "compute.sandbox.runCode": {
|
|
253
|
+
if (!request.code) {
|
|
254
|
+
return {
|
|
255
|
+
success: false,
|
|
256
|
+
error: "Code is required for runCode action",
|
|
257
|
+
sandboxId: request.sandboxId || "",
|
|
258
|
+
provider: provider.name
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
262
|
+
const result = await sandbox.runCode(request.code, request.runtime);
|
|
263
|
+
return {
|
|
264
|
+
success: true,
|
|
265
|
+
sandboxId: sandbox.sandboxId,
|
|
266
|
+
provider: provider.name,
|
|
267
|
+
result: {
|
|
268
|
+
stdout: result.stdout,
|
|
269
|
+
stderr: result.stderr,
|
|
270
|
+
exitCode: result.exitCode,
|
|
271
|
+
executionTime: result.executionTime
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
case "compute.sandbox.runCommand": {
|
|
276
|
+
if (!request.command) {
|
|
277
|
+
return {
|
|
278
|
+
success: false,
|
|
279
|
+
error: "Command is required for runCommand action",
|
|
280
|
+
sandboxId: request.sandboxId || "",
|
|
281
|
+
provider: provider.name
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
285
|
+
const result = await sandbox.runCommand(request.command, request.args);
|
|
286
|
+
return {
|
|
287
|
+
success: true,
|
|
288
|
+
sandboxId: sandbox.sandboxId,
|
|
289
|
+
provider: provider.name,
|
|
290
|
+
result: {
|
|
291
|
+
stdout: result.stdout,
|
|
292
|
+
stderr: result.stderr,
|
|
293
|
+
exitCode: result.exitCode,
|
|
294
|
+
executionTime: result.executionTime
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
// Filesystem operations
|
|
299
|
+
case "compute.sandbox.filesystem.readFile": {
|
|
300
|
+
if (!request.sandboxId) {
|
|
301
|
+
return {
|
|
302
|
+
success: false,
|
|
303
|
+
error: "Sandbox ID is required for filesystem operations",
|
|
304
|
+
sandboxId: "",
|
|
305
|
+
provider: provider.name
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
if (!request.path) {
|
|
309
|
+
return {
|
|
310
|
+
success: false,
|
|
311
|
+
error: "File path is required for readFile action",
|
|
312
|
+
sandboxId: request.sandboxId,
|
|
313
|
+
provider: provider.name
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
317
|
+
const content = await sandbox.filesystem.readFile(request.path);
|
|
318
|
+
return {
|
|
319
|
+
success: true,
|
|
320
|
+
sandboxId: request.sandboxId,
|
|
321
|
+
provider: provider.name,
|
|
322
|
+
fileContent: content
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
case "compute.sandbox.filesystem.writeFile": {
|
|
326
|
+
if (!request.sandboxId) {
|
|
327
|
+
return {
|
|
328
|
+
success: false,
|
|
329
|
+
error: "Sandbox ID is required for filesystem operations",
|
|
330
|
+
sandboxId: "",
|
|
331
|
+
provider: provider.name
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (!request.path) {
|
|
335
|
+
return {
|
|
336
|
+
success: false,
|
|
337
|
+
error: "File path is required for writeFile action",
|
|
338
|
+
sandboxId: request.sandboxId,
|
|
339
|
+
provider: provider.name
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
if (request.content === void 0) {
|
|
343
|
+
return {
|
|
344
|
+
success: false,
|
|
345
|
+
error: "File content is required for writeFile action",
|
|
346
|
+
sandboxId: request.sandboxId,
|
|
347
|
+
provider: provider.name
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
351
|
+
await sandbox.filesystem.writeFile(request.path, request.content);
|
|
352
|
+
return {
|
|
353
|
+
success: true,
|
|
354
|
+
sandboxId: request.sandboxId,
|
|
355
|
+
provider: provider.name
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
case "compute.sandbox.filesystem.mkdir": {
|
|
359
|
+
if (!request.sandboxId) {
|
|
360
|
+
return {
|
|
361
|
+
success: false,
|
|
362
|
+
error: "Sandbox ID is required for filesystem operations",
|
|
363
|
+
sandboxId: "",
|
|
364
|
+
provider: provider.name
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
if (!request.path) {
|
|
368
|
+
return {
|
|
369
|
+
success: false,
|
|
370
|
+
error: "Directory path is required for mkdir action",
|
|
371
|
+
sandboxId: request.sandboxId,
|
|
372
|
+
provider: provider.name
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
376
|
+
await sandbox.filesystem.mkdir(request.path);
|
|
377
|
+
return {
|
|
378
|
+
success: true,
|
|
379
|
+
sandboxId: request.sandboxId,
|
|
380
|
+
provider: provider.name
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
case "compute.sandbox.filesystem.readdir": {
|
|
384
|
+
if (!request.sandboxId) {
|
|
385
|
+
return {
|
|
386
|
+
success: false,
|
|
387
|
+
error: "Sandbox ID is required for filesystem operations",
|
|
388
|
+
sandboxId: "",
|
|
389
|
+
provider: provider.name
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
if (!request.path) {
|
|
393
|
+
return {
|
|
394
|
+
success: false,
|
|
395
|
+
error: "Directory path is required for readdir action",
|
|
396
|
+
sandboxId: request.sandboxId,
|
|
397
|
+
provider: provider.name
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
401
|
+
const entries = await sandbox.filesystem.readdir(request.path);
|
|
402
|
+
return {
|
|
403
|
+
success: true,
|
|
404
|
+
sandboxId: request.sandboxId,
|
|
405
|
+
provider: provider.name,
|
|
406
|
+
files: entries.map((entry) => ({
|
|
407
|
+
name: entry.name,
|
|
408
|
+
path: entry.path,
|
|
409
|
+
isDirectory: entry.isDirectory,
|
|
410
|
+
size: entry.size,
|
|
411
|
+
lastModified: entry.lastModified.toISOString()
|
|
412
|
+
}))
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
case "compute.sandbox.filesystem.exists": {
|
|
416
|
+
if (!request.sandboxId) {
|
|
417
|
+
return {
|
|
418
|
+
success: false,
|
|
419
|
+
error: "Sandbox ID is required for filesystem operations",
|
|
420
|
+
sandboxId: "",
|
|
421
|
+
provider: provider.name
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
if (!request.path) {
|
|
425
|
+
return {
|
|
426
|
+
success: false,
|
|
427
|
+
error: "Path is required for exists action",
|
|
428
|
+
sandboxId: request.sandboxId,
|
|
429
|
+
provider: provider.name
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
433
|
+
const exists = await sandbox.filesystem.exists(request.path);
|
|
434
|
+
return {
|
|
435
|
+
success: true,
|
|
436
|
+
sandboxId: request.sandboxId,
|
|
437
|
+
provider: provider.name,
|
|
438
|
+
exists
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
case "compute.sandbox.filesystem.remove": {
|
|
442
|
+
if (!request.sandboxId) {
|
|
443
|
+
return {
|
|
444
|
+
success: false,
|
|
445
|
+
error: "Sandbox ID is required for filesystem operations",
|
|
446
|
+
sandboxId: "",
|
|
447
|
+
provider: provider.name
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
if (!request.path) {
|
|
451
|
+
return {
|
|
452
|
+
success: false,
|
|
453
|
+
error: "Path is required for remove action",
|
|
454
|
+
sandboxId: request.sandboxId,
|
|
455
|
+
provider: provider.name
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
459
|
+
await sandbox.filesystem.remove(request.path);
|
|
460
|
+
return {
|
|
461
|
+
success: true,
|
|
462
|
+
sandboxId: request.sandboxId,
|
|
463
|
+
provider: provider.name
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
// Terminal operations
|
|
467
|
+
case "compute.sandbox.terminal.create": {
|
|
468
|
+
if (!request.sandboxId) {
|
|
469
|
+
return {
|
|
470
|
+
success: false,
|
|
471
|
+
error: "Sandbox ID is required for terminal operations",
|
|
472
|
+
sandboxId: "",
|
|
473
|
+
provider: provider.name
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
477
|
+
const terminal = await sandbox.terminal.create(request.terminalOptions);
|
|
478
|
+
return {
|
|
479
|
+
success: true,
|
|
480
|
+
sandboxId: request.sandboxId,
|
|
481
|
+
provider: provider.name,
|
|
482
|
+
terminal: {
|
|
483
|
+
pid: terminal.pid,
|
|
484
|
+
command: terminal.command,
|
|
485
|
+
status: terminal.status,
|
|
486
|
+
cols: terminal.cols,
|
|
487
|
+
rows: terminal.rows
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
case "compute.sandbox.terminal.list": {
|
|
492
|
+
if (!request.sandboxId) {
|
|
493
|
+
return {
|
|
494
|
+
success: false,
|
|
495
|
+
error: "Sandbox ID is required for terminal operations",
|
|
496
|
+
sandboxId: "",
|
|
497
|
+
provider: provider.name
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
501
|
+
const terminals = await sandbox.terminal.list();
|
|
502
|
+
return {
|
|
503
|
+
success: true,
|
|
504
|
+
sandboxId: request.sandboxId,
|
|
505
|
+
provider: provider.name,
|
|
506
|
+
terminals: terminals.map((terminal) => ({
|
|
507
|
+
pid: terminal.pid,
|
|
508
|
+
command: terminal.command,
|
|
509
|
+
status: terminal.status,
|
|
510
|
+
cols: terminal.cols,
|
|
511
|
+
rows: terminal.rows
|
|
512
|
+
}))
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
case "compute.sandbox.terminal.getById": {
|
|
516
|
+
if (!request.sandboxId) {
|
|
517
|
+
return {
|
|
518
|
+
success: false,
|
|
519
|
+
error: "Sandbox ID is required for terminal operations",
|
|
520
|
+
sandboxId: "",
|
|
521
|
+
provider: provider.name
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
if (!request.terminalId) {
|
|
525
|
+
return {
|
|
526
|
+
success: false,
|
|
527
|
+
error: "Terminal ID is required for getById action",
|
|
528
|
+
sandboxId: request.sandboxId,
|
|
529
|
+
provider: provider.name
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
533
|
+
const terminal = await sandbox.terminal.getById(request.terminalId);
|
|
534
|
+
if (!terminal) {
|
|
535
|
+
return {
|
|
536
|
+
success: false,
|
|
537
|
+
error: `Terminal with ID ${request.terminalId} not found`,
|
|
538
|
+
sandboxId: request.sandboxId,
|
|
539
|
+
provider: provider.name
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
return {
|
|
543
|
+
success: true,
|
|
544
|
+
sandboxId: request.sandboxId,
|
|
545
|
+
provider: provider.name,
|
|
546
|
+
terminal: {
|
|
547
|
+
pid: terminal.pid,
|
|
548
|
+
command: terminal.command,
|
|
549
|
+
status: terminal.status,
|
|
550
|
+
cols: terminal.cols,
|
|
551
|
+
rows: terminal.rows
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
case "compute.sandbox.terminal.destroy": {
|
|
556
|
+
if (!request.sandboxId) {
|
|
557
|
+
return {
|
|
558
|
+
success: false,
|
|
559
|
+
error: "Sandbox ID is required for terminal operations",
|
|
560
|
+
sandboxId: "",
|
|
561
|
+
provider: provider.name
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
if (!request.terminalId) {
|
|
565
|
+
return {
|
|
566
|
+
success: false,
|
|
567
|
+
error: "Terminal ID is required for destroy action",
|
|
568
|
+
sandboxId: request.sandboxId,
|
|
569
|
+
provider: provider.name
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
573
|
+
await sandbox.terminal.destroy(request.terminalId);
|
|
574
|
+
return {
|
|
575
|
+
success: true,
|
|
576
|
+
sandboxId: request.sandboxId,
|
|
577
|
+
provider: provider.name
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
// Terminal I/O operations
|
|
581
|
+
case "compute.sandbox.terminal.write": {
|
|
582
|
+
if (!request.sandboxId) {
|
|
583
|
+
return {
|
|
584
|
+
success: false,
|
|
585
|
+
error: "Sandbox ID is required for terminal operations",
|
|
586
|
+
sandboxId: "",
|
|
587
|
+
provider: provider.name
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
if (!request.terminalId) {
|
|
591
|
+
return {
|
|
592
|
+
success: false,
|
|
593
|
+
error: "Terminal ID is required for write action",
|
|
594
|
+
sandboxId: request.sandboxId,
|
|
595
|
+
provider: provider.name
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
if (!request.data) {
|
|
599
|
+
return {
|
|
600
|
+
success: false,
|
|
601
|
+
error: "Data is required for write action",
|
|
602
|
+
sandboxId: request.sandboxId,
|
|
603
|
+
provider: provider.name
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
607
|
+
const terminal = await sandbox.terminal.getById(request.terminalId);
|
|
608
|
+
if (!terminal) {
|
|
609
|
+
return {
|
|
610
|
+
success: false,
|
|
611
|
+
error: `Terminal with ID ${request.terminalId} not found`,
|
|
612
|
+
sandboxId: request.sandboxId,
|
|
613
|
+
provider: provider.name
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
await terminal.write(request.data);
|
|
617
|
+
return {
|
|
618
|
+
success: true,
|
|
619
|
+
sandboxId: request.sandboxId,
|
|
620
|
+
provider: provider.name
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
case "compute.sandbox.terminal.resize": {
|
|
624
|
+
if (!request.sandboxId) {
|
|
625
|
+
return {
|
|
626
|
+
success: false,
|
|
627
|
+
error: "Sandbox ID is required for terminal operations",
|
|
628
|
+
sandboxId: "",
|
|
629
|
+
provider: provider.name
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
if (!request.terminalId) {
|
|
633
|
+
return {
|
|
634
|
+
success: false,
|
|
635
|
+
error: "Terminal ID is required for resize action",
|
|
636
|
+
sandboxId: request.sandboxId,
|
|
637
|
+
provider: provider.name
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
if (!request.cols || !request.rows) {
|
|
641
|
+
return {
|
|
642
|
+
success: false,
|
|
643
|
+
error: "Cols and rows are required for resize action",
|
|
644
|
+
sandboxId: request.sandboxId,
|
|
645
|
+
provider: provider.name
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
649
|
+
const terminal = await sandbox.terminal.getById(request.terminalId);
|
|
650
|
+
if (!terminal) {
|
|
651
|
+
return {
|
|
652
|
+
success: false,
|
|
653
|
+
error: `Terminal with ID ${request.terminalId} not found`,
|
|
654
|
+
sandboxId: request.sandboxId,
|
|
655
|
+
provider: provider.name
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
await terminal.resize(request.cols, request.rows);
|
|
659
|
+
return {
|
|
660
|
+
success: true,
|
|
661
|
+
sandboxId: request.sandboxId,
|
|
662
|
+
provider: provider.name
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
case "compute.sandbox.terminal.kill": {
|
|
666
|
+
if (!request.sandboxId) {
|
|
667
|
+
return {
|
|
668
|
+
success: false,
|
|
669
|
+
error: "Sandbox ID is required for terminal operations",
|
|
670
|
+
sandboxId: "",
|
|
671
|
+
provider: provider.name
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
if (!request.terminalId) {
|
|
675
|
+
return {
|
|
676
|
+
success: false,
|
|
677
|
+
error: "Terminal ID is required for kill action",
|
|
678
|
+
sandboxId: request.sandboxId,
|
|
679
|
+
provider: provider.name
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
const sandbox = await getSandbox(request.sandboxId);
|
|
683
|
+
const terminal = await sandbox.terminal.getById(request.terminalId);
|
|
684
|
+
if (!terminal) {
|
|
685
|
+
return {
|
|
686
|
+
success: false,
|
|
687
|
+
error: `Terminal with ID ${request.terminalId} not found`,
|
|
688
|
+
sandboxId: request.sandboxId,
|
|
689
|
+
provider: provider.name
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
await terminal.kill();
|
|
693
|
+
return {
|
|
694
|
+
success: true,
|
|
695
|
+
sandboxId: request.sandboxId,
|
|
696
|
+
provider: provider.name
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
default:
|
|
700
|
+
return {
|
|
701
|
+
success: false,
|
|
702
|
+
error: `Unknown action: ${request.action}`,
|
|
703
|
+
sandboxId: request.sandboxId || "",
|
|
704
|
+
provider: provider.name
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
} catch (error) {
|
|
708
|
+
return {
|
|
709
|
+
success: false,
|
|
710
|
+
error: error instanceof Error ? error.message : "Unknown error occurred",
|
|
711
|
+
sandboxId: request.sandboxId || "",
|
|
712
|
+
provider: provider.name
|
|
713
|
+
};
|
|
714
|
+
}
|
|
178
715
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
716
|
+
|
|
717
|
+
// src/factory.ts
|
|
718
|
+
var UnsupportedFileSystem = class {
|
|
719
|
+
constructor(providerName) {
|
|
720
|
+
this.providerName = providerName;
|
|
183
721
|
}
|
|
184
|
-
|
|
185
|
-
|
|
722
|
+
async readFile(_path) {
|
|
723
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
186
724
|
}
|
|
187
|
-
|
|
188
|
-
|
|
725
|
+
async writeFile(_path, _content) {
|
|
726
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
189
727
|
}
|
|
190
|
-
|
|
191
|
-
|
|
728
|
+
async mkdir(_path) {
|
|
729
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
192
730
|
}
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
function autoSelectProvider() {
|
|
196
|
-
const available = detectAvailableProviders();
|
|
197
|
-
return available.length > 0 ? available[0] : void 0;
|
|
198
|
-
}
|
|
199
|
-
function normalizeContainerConfig(container) {
|
|
200
|
-
if (!container) {
|
|
201
|
-
return void 0;
|
|
731
|
+
async readdir(_path) {
|
|
732
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
202
733
|
}
|
|
203
|
-
|
|
204
|
-
|
|
734
|
+
async exists(_path) {
|
|
735
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
205
736
|
}
|
|
206
|
-
|
|
207
|
-
throw new
|
|
737
|
+
async remove(_path) {
|
|
738
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
208
739
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return runtime;
|
|
214
|
-
}
|
|
215
|
-
switch (provider) {
|
|
216
|
-
case "e2b":
|
|
217
|
-
return "python";
|
|
218
|
-
case "vercel":
|
|
219
|
-
return "node";
|
|
220
|
-
case "cloudflare":
|
|
221
|
-
case "fly":
|
|
222
|
-
throw new ConfigurationError(
|
|
223
|
-
`Container-based provider '${provider}' requires explicit runtime or container configuration`,
|
|
224
|
-
provider
|
|
225
|
-
);
|
|
226
|
-
default:
|
|
227
|
-
return "node";
|
|
740
|
+
};
|
|
741
|
+
var UnsupportedTerminal = class {
|
|
742
|
+
constructor(providerName) {
|
|
743
|
+
this.providerName = providerName;
|
|
228
744
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
let envKey;
|
|
232
|
-
switch (provider) {
|
|
233
|
-
case "e2b":
|
|
234
|
-
envKey = ENV_KEYS.E2B;
|
|
235
|
-
break;
|
|
236
|
-
case "vercel":
|
|
237
|
-
envKey = ENV_KEYS.VERCEL;
|
|
238
|
-
break;
|
|
239
|
-
case "cloudflare":
|
|
240
|
-
if (isCloudflareWorkers()) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
envKey = ENV_KEYS.CLOUDFLARE;
|
|
244
|
-
break;
|
|
245
|
-
case "fly":
|
|
246
|
-
envKey = ENV_KEYS.FLY;
|
|
247
|
-
break;
|
|
248
|
-
case "auto":
|
|
249
|
-
return;
|
|
250
|
-
// Will be handled by auto-selection
|
|
251
|
-
default:
|
|
252
|
-
throw new ConfigurationError(`Unknown provider: ${provider}`, "config");
|
|
253
|
-
}
|
|
254
|
-
if (!process.env[envKey]) {
|
|
255
|
-
const available = detectAvailableProviders();
|
|
256
|
-
const suggestions = available.length > 0 ? `Available providers: ${available.join(", ")}` : `No provider API keys found. Set ${Object.values(ENV_KEYS).join(" or ")} environment variables.`;
|
|
257
|
-
throw new ConfigurationError(
|
|
258
|
-
`Missing API key for provider '${provider}'. ${suggestions}`,
|
|
259
|
-
provider
|
|
260
|
-
);
|
|
745
|
+
async create(_options) {
|
|
746
|
+
throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
261
747
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
const normalized = {
|
|
265
|
-
provider: config?.provider || "auto",
|
|
266
|
-
timeout: config?.timeout || DEFAULT_TIMEOUT
|
|
267
|
-
};
|
|
268
|
-
if (normalized.provider === "auto") {
|
|
269
|
-
const autoProvider = autoSelectProvider();
|
|
270
|
-
if (!autoProvider) {
|
|
271
|
-
throw new ConfigurationError(
|
|
272
|
-
`No provider API keys found. Set one of the following environment variables: ${Object.values(ENV_KEYS).join(", ")}`,
|
|
273
|
-
"config"
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
normalized.provider = autoProvider;
|
|
277
|
-
} else {
|
|
278
|
-
validateProviderApiKey(normalized.provider);
|
|
748
|
+
async getById(_terminalId) {
|
|
749
|
+
throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
279
750
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
} else if (!config?.container) {
|
|
283
|
-
normalized.runtime = getDefaultRuntime(normalized.provider);
|
|
751
|
+
async list() {
|
|
752
|
+
throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
284
753
|
}
|
|
285
|
-
|
|
286
|
-
|
|
754
|
+
async destroy(_terminalId) {
|
|
755
|
+
throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
287
756
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
757
|
+
};
|
|
758
|
+
var SupportedFileSystem = class {
|
|
759
|
+
constructor(sandbox, methods) {
|
|
760
|
+
this.sandbox = sandbox;
|
|
761
|
+
this.methods = methods;
|
|
762
|
+
}
|
|
763
|
+
async readFile(path) {
|
|
764
|
+
return this.methods.readFile(this.sandbox, path);
|
|
765
|
+
}
|
|
766
|
+
async writeFile(path, content) {
|
|
767
|
+
return this.methods.writeFile(this.sandbox, path, content);
|
|
768
|
+
}
|
|
769
|
+
async mkdir(path) {
|
|
770
|
+
return this.methods.mkdir(this.sandbox, path);
|
|
771
|
+
}
|
|
772
|
+
async readdir(path) {
|
|
773
|
+
return this.methods.readdir(this.sandbox, path);
|
|
774
|
+
}
|
|
775
|
+
async exists(path) {
|
|
776
|
+
return this.methods.exists(this.sandbox, path);
|
|
777
|
+
}
|
|
778
|
+
async remove(path) {
|
|
779
|
+
return this.methods.remove(this.sandbox, path);
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
var GeneratedTerminalSession = class {
|
|
783
|
+
constructor(terminal, sandbox, methods, terminalId, command, cols = 80, rows = 24) {
|
|
784
|
+
this.terminal = terminal;
|
|
785
|
+
this.sandbox = sandbox;
|
|
786
|
+
this.methods = methods;
|
|
787
|
+
this.pid = parseInt(terminalId);
|
|
788
|
+
this.command = command;
|
|
789
|
+
this.status = "running";
|
|
790
|
+
this.cols = cols;
|
|
791
|
+
this.rows = rows;
|
|
792
|
+
}
|
|
793
|
+
async write(data) {
|
|
794
|
+
return this.methods.write(this.sandbox, this.terminal, data);
|
|
795
|
+
}
|
|
796
|
+
async resize(cols, rows) {
|
|
797
|
+
return this.methods.resize(this.sandbox, this.terminal, cols, rows);
|
|
798
|
+
}
|
|
799
|
+
async kill() {
|
|
800
|
+
return this.methods.kill(this.sandbox, this.terminal);
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
var SupportedTerminal = class {
|
|
804
|
+
constructor(sandbox, methods) {
|
|
805
|
+
this.sandbox = sandbox;
|
|
806
|
+
this.methods = methods;
|
|
807
|
+
}
|
|
808
|
+
async create(options) {
|
|
809
|
+
let terminalSession;
|
|
810
|
+
const createOptions = {
|
|
811
|
+
...options,
|
|
812
|
+
onData: (data) => {
|
|
813
|
+
if (terminalSession?.onData) {
|
|
814
|
+
terminalSession.onData(data);
|
|
815
|
+
}
|
|
816
|
+
},
|
|
817
|
+
onExit: (exitCode) => {
|
|
818
|
+
if (terminalSession?.onExit) {
|
|
819
|
+
terminalSession.onExit(exitCode);
|
|
820
|
+
}
|
|
304
821
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
822
|
+
};
|
|
823
|
+
const result = await this.methods.create(this.sandbox, createOptions);
|
|
824
|
+
terminalSession = new GeneratedTerminalSession(
|
|
825
|
+
result.terminal,
|
|
826
|
+
this.sandbox,
|
|
827
|
+
this.methods,
|
|
828
|
+
result.terminalId,
|
|
829
|
+
options?.command || "bash",
|
|
830
|
+
options?.cols || 80,
|
|
831
|
+
options?.rows || 24
|
|
832
|
+
);
|
|
833
|
+
terminalSession.onData = options?.onData;
|
|
834
|
+
terminalSession.onExit = options?.onExit;
|
|
835
|
+
return terminalSession;
|
|
308
836
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
837
|
+
async getById(terminalId) {
|
|
838
|
+
const result = await this.methods.getById(this.sandbox, terminalId);
|
|
839
|
+
if (!result) return null;
|
|
840
|
+
return new GeneratedTerminalSession(
|
|
841
|
+
result.terminal,
|
|
842
|
+
this.sandbox,
|
|
843
|
+
this.methods,
|
|
844
|
+
result.terminalId,
|
|
845
|
+
"bash",
|
|
846
|
+
// Default command for existing terminals
|
|
847
|
+
80,
|
|
848
|
+
// Default cols
|
|
849
|
+
24
|
|
850
|
+
// Default rows
|
|
851
|
+
);
|
|
852
|
+
}
|
|
853
|
+
async list() {
|
|
854
|
+
const results = await this.methods.list(this.sandbox);
|
|
855
|
+
return results.map((result) => new GeneratedTerminalSession(
|
|
856
|
+
result.terminal,
|
|
857
|
+
this.sandbox,
|
|
858
|
+
this.methods,
|
|
859
|
+
result.terminalId,
|
|
860
|
+
"bash",
|
|
861
|
+
// Default command
|
|
862
|
+
80,
|
|
863
|
+
// Default cols
|
|
864
|
+
24
|
|
865
|
+
// Default rows
|
|
866
|
+
));
|
|
867
|
+
}
|
|
868
|
+
async destroy(terminalId) {
|
|
869
|
+
return this.methods.destroy(this.sandbox, terminalId);
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
var GeneratedSandbox = class {
|
|
873
|
+
constructor(sandbox, sandboxId, providerName, methods, config, destroyMethod) {
|
|
874
|
+
this.sandbox = sandbox;
|
|
875
|
+
this.methods = methods;
|
|
876
|
+
this.config = config;
|
|
877
|
+
this.destroyMethod = destroyMethod;
|
|
878
|
+
this.sandboxId = sandboxId;
|
|
879
|
+
this.provider = providerName;
|
|
880
|
+
if (methods.filesystem) {
|
|
881
|
+
this.filesystem = new SupportedFileSystem(sandbox, methods.filesystem);
|
|
882
|
+
} else {
|
|
883
|
+
this.filesystem = new UnsupportedFileSystem(providerName);
|
|
330
884
|
}
|
|
331
|
-
if (
|
|
332
|
-
|
|
333
|
-
} else if (parts.length === 2) {
|
|
334
|
-
const runtimeOrImage = parts[1];
|
|
335
|
-
if (isRuntime(runtimeOrImage)) {
|
|
336
|
-
return providerFactory({ runtime: runtimeOrImage });
|
|
337
|
-
}
|
|
338
|
-
return providerFactory({ container: { image: runtimeOrImage } });
|
|
885
|
+
if (methods.terminal) {
|
|
886
|
+
this.terminal = new SupportedTerminal(sandbox, methods.terminal);
|
|
339
887
|
} else {
|
|
340
|
-
|
|
341
|
-
return providerFactory({ container: { image: containerImage } });
|
|
888
|
+
this.terminal = new UnsupportedTerminal(providerName);
|
|
342
889
|
}
|
|
343
890
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
function isRuntime(value) {
|
|
347
|
-
return ["node", "python"].includes(value);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// src/providers/base.ts
|
|
351
|
-
var import_uuid = require("uuid");
|
|
352
|
-
var BaseProvider = class {
|
|
353
|
-
/**
|
|
354
|
-
* Create a new base provider
|
|
355
|
-
*
|
|
356
|
-
* @param provider Provider identifier
|
|
357
|
-
* @param timeout Execution timeout in milliseconds
|
|
358
|
-
*/
|
|
359
|
-
constructor(provider, timeout) {
|
|
360
|
-
/** Specification version */
|
|
361
|
-
this.specificationVersion = "v1";
|
|
362
|
-
this.provider = provider;
|
|
363
|
-
this.sandboxId = (0, import_uuid.v4)();
|
|
364
|
-
this.timeout = timeout;
|
|
891
|
+
async runCode(code, runtime) {
|
|
892
|
+
return await this.methods.runCode(this.sandbox, code, runtime, this.config);
|
|
365
893
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
* @returns Execution result
|
|
372
|
-
*/
|
|
373
|
-
async execute(code, runtime) {
|
|
374
|
-
const startTime = Date.now();
|
|
375
|
-
try {
|
|
376
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
377
|
-
setTimeout(() => {
|
|
378
|
-
reject(new TimeoutError(
|
|
379
|
-
`Execution timed out after ${this.timeout}ms`,
|
|
380
|
-
this.provider,
|
|
381
|
-
this.timeout,
|
|
382
|
-
this.sandboxId
|
|
383
|
-
));
|
|
384
|
-
}, this.timeout);
|
|
385
|
-
});
|
|
386
|
-
const result = await Promise.race([
|
|
387
|
-
this.doExecute(code, runtime),
|
|
388
|
-
timeoutPromise
|
|
389
|
-
]);
|
|
390
|
-
const executionTime = Date.now() - startTime;
|
|
391
|
-
return {
|
|
392
|
-
...result,
|
|
393
|
-
executionTime,
|
|
394
|
-
sandboxId: this.sandboxId,
|
|
395
|
-
provider: this.provider
|
|
396
|
-
};
|
|
397
|
-
} catch (error) {
|
|
398
|
-
if (error instanceof Error && error.name.includes("Error") && "code" in error) {
|
|
399
|
-
throw error;
|
|
400
|
-
}
|
|
401
|
-
throw new ProviderError(
|
|
402
|
-
`Execution failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
403
|
-
this.provider,
|
|
404
|
-
error instanceof Error ? error : void 0,
|
|
405
|
-
this.sandboxId
|
|
406
|
-
);
|
|
407
|
-
}
|
|
894
|
+
async runCommand(command, args) {
|
|
895
|
+
return await this.methods.runCommand(this.sandbox, command, args);
|
|
896
|
+
}
|
|
897
|
+
async getInfo() {
|
|
898
|
+
return await this.methods.getInfo(this.sandbox);
|
|
408
899
|
}
|
|
409
|
-
/**
|
|
410
|
-
* Kill the sandbox
|
|
411
|
-
*
|
|
412
|
-
* @returns Promise that resolves when the sandbox is killed
|
|
413
|
-
*/
|
|
414
900
|
async kill() {
|
|
415
|
-
|
|
416
|
-
await this.doKill();
|
|
417
|
-
} catch (error) {
|
|
418
|
-
throw new ProviderError(
|
|
419
|
-
`Failed to kill sandbox: ${error instanceof Error ? error.message : String(error)}`,
|
|
420
|
-
this.provider,
|
|
421
|
-
error instanceof Error ? error : void 0,
|
|
422
|
-
this.sandboxId
|
|
423
|
-
);
|
|
424
|
-
}
|
|
901
|
+
await this.destroy();
|
|
425
902
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
*
|
|
429
|
-
* @returns Sandbox information
|
|
430
|
-
*/
|
|
431
|
-
async getInfo() {
|
|
432
|
-
try {
|
|
433
|
-
return await this.doGetInfo();
|
|
434
|
-
} catch (error) {
|
|
435
|
-
throw new ProviderError(
|
|
436
|
-
`Failed to get sandbox info: ${error instanceof Error ? error.message : String(error)}`,
|
|
437
|
-
this.provider,
|
|
438
|
-
error instanceof Error ? error : void 0,
|
|
439
|
-
this.sandboxId
|
|
440
|
-
);
|
|
441
|
-
}
|
|
903
|
+
async destroy() {
|
|
904
|
+
await this.destroyMethod(this.config, this.sandboxId);
|
|
442
905
|
}
|
|
443
906
|
};
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
907
|
+
var GeneratedSandboxManager = class {
|
|
908
|
+
constructor(config, providerName, methods) {
|
|
909
|
+
this.config = config;
|
|
910
|
+
this.providerName = providerName;
|
|
911
|
+
this.methods = methods;
|
|
912
|
+
this.activeSandboxes = /* @__PURE__ */ new Map();
|
|
913
|
+
}
|
|
914
|
+
async create(options) {
|
|
915
|
+
const result = await this.methods.create(this.config, options);
|
|
916
|
+
const sandbox = new GeneratedSandbox(
|
|
917
|
+
result.sandbox,
|
|
918
|
+
result.sandboxId,
|
|
919
|
+
this.providerName,
|
|
920
|
+
this.methods,
|
|
921
|
+
this.config,
|
|
922
|
+
this.methods.destroy
|
|
923
|
+
);
|
|
924
|
+
this.activeSandboxes.set(result.sandboxId, sandbox);
|
|
925
|
+
return sandbox;
|
|
926
|
+
}
|
|
927
|
+
async getById(sandboxId) {
|
|
928
|
+
const existing = this.activeSandboxes.get(sandboxId);
|
|
929
|
+
if (existing) {
|
|
930
|
+
return existing;
|
|
931
|
+
}
|
|
932
|
+
const result = await this.methods.getById(this.config, sandboxId);
|
|
933
|
+
if (!result) {
|
|
934
|
+
return null;
|
|
935
|
+
}
|
|
936
|
+
const sandbox = new GeneratedSandbox(
|
|
937
|
+
result.sandbox,
|
|
938
|
+
result.sandboxId,
|
|
939
|
+
this.providerName,
|
|
940
|
+
this.methods,
|
|
941
|
+
this.config,
|
|
942
|
+
this.methods.destroy
|
|
943
|
+
);
|
|
944
|
+
this.activeSandboxes.set(result.sandboxId, sandbox);
|
|
945
|
+
return sandbox;
|
|
946
|
+
}
|
|
947
|
+
async list() {
|
|
948
|
+
const results = await this.methods.list(this.config);
|
|
949
|
+
const sandboxes = [];
|
|
950
|
+
for (const result of results) {
|
|
951
|
+
let sandbox = this.activeSandboxes.get(result.sandboxId);
|
|
952
|
+
if (!sandbox) {
|
|
953
|
+
sandbox = new GeneratedSandbox(
|
|
954
|
+
result.sandbox,
|
|
955
|
+
result.sandboxId,
|
|
956
|
+
this.providerName,
|
|
957
|
+
this.methods,
|
|
958
|
+
this.config,
|
|
959
|
+
this.methods.destroy
|
|
490
960
|
);
|
|
961
|
+
this.activeSandboxes.set(result.sandboxId, sandbox);
|
|
491
962
|
}
|
|
492
|
-
|
|
493
|
-
`Failed to load provider '${providerName}': ${error.message}`,
|
|
494
|
-
"sdk"
|
|
495
|
-
);
|
|
963
|
+
sandboxes.push(sandbox);
|
|
496
964
|
}
|
|
965
|
+
return sandboxes;
|
|
497
966
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
* @returns Array of available provider types
|
|
502
|
-
*/
|
|
503
|
-
static detectProviders() {
|
|
504
|
-
return detectAvailableProviders();
|
|
967
|
+
async destroy(sandboxId) {
|
|
968
|
+
await this.methods.destroy(this.config, sandboxId);
|
|
969
|
+
this.activeSandboxes.delete(sandboxId);
|
|
505
970
|
}
|
|
506
971
|
};
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
972
|
+
var GeneratedProvider = class {
|
|
973
|
+
constructor(config, providerConfig) {
|
|
974
|
+
this.name = providerConfig.name;
|
|
975
|
+
this.sandbox = new GeneratedSandboxManager(
|
|
976
|
+
config,
|
|
977
|
+
providerConfig.name,
|
|
978
|
+
providerConfig.methods.sandbox
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
};
|
|
982
|
+
function createProvider(providerConfig) {
|
|
983
|
+
return (config) => {
|
|
984
|
+
return new GeneratedProvider(config, providerConfig);
|
|
985
|
+
};
|
|
986
|
+
}
|
|
510
987
|
// Annotate the CommonJS export names for ESM import in node:
|
|
511
988
|
0 && (module.exports = {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
ConfigurationError,
|
|
517
|
-
DEFAULT_TIMEOUT,
|
|
518
|
-
ENV_KEYS,
|
|
519
|
-
ExecutionError,
|
|
520
|
-
ProviderError,
|
|
521
|
-
ProviderUnavailableError,
|
|
522
|
-
TimeoutError,
|
|
523
|
-
autoSelectProvider,
|
|
524
|
-
createComputeRegistry,
|
|
525
|
-
detectAvailableProviders,
|
|
526
|
-
executeSandbox,
|
|
527
|
-
getDefaultRuntime,
|
|
528
|
-
isCloudflareWorkers,
|
|
529
|
-
normalizeContainerConfig,
|
|
530
|
-
normalizeSandboxConfig,
|
|
531
|
-
retry,
|
|
532
|
-
validateProviderApiKey
|
|
989
|
+
SandboxManager,
|
|
990
|
+
compute,
|
|
991
|
+
createProvider,
|
|
992
|
+
handleComputeRequest
|
|
533
993
|
});
|
|
534
994
|
//# sourceMappingURL=index.js.map
|