@intella/sdk 0.0.1
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 +492 -0
- package/examples/claude-code/README.md +178 -0
- package/examples/claude-code/advanced-config.ts +55 -0
- package/examples/claude-code/basic-usage.ts +56 -0
- package/examples/claude-code/model-comparison.ts +50 -0
- package/examples/claude-code/orchestration.ts +70 -0
- package/examples/claude-code/streaming.ts +69 -0
- package/examples/claude-code/tsconfig.json +19 -0
- package/examples/code-extractor/README.md +77 -0
- package/examples/code-extractor/example.ts +145 -0
- package/examples/filesystem/basic-usage.ts +84 -0
- package/examples/integrated-task/README.md +68 -0
- package/examples/integrated-task/integrated-usage.ts +193 -0
- package/examples/integrated-task/simple-example.ts +51 -0
- package/examples/integrated-task/tsconfig.json +19 -0
- package/examples/sandbox/basic-usage.ts +173 -0
- package/package.json +56 -0
- package/src/agent-manager.ts +104 -0
- package/src/agents/base-agent.ts +166 -0
- package/src/agents/claude-agent.ts +77 -0
- package/src/agents/codex-agent.ts +72 -0
- package/src/agents/intella-lite-agent.ts +55 -0
- package/src/agents/opencode-agent.ts +45 -0
- package/src/filesystem/agentfs-provider.ts +328 -0
- package/src/filesystem/base-provider.ts +98 -0
- package/src/filesystem/index.ts +5 -0
- package/src/filesystem/memory-provider.ts +267 -0
- package/src/filesystem-manager.ts +213 -0
- package/src/index.ts +66 -0
- package/src/orchestrator.ts +177 -0
- package/src/sandbox/base-provider.ts +184 -0
- package/src/sandbox/daytona-provider.ts +462 -0
- package/src/sandbox/e2b-provider.ts +419 -0
- package/src/sandbox/modal-provider.ts +597 -0
- package/src/sandbox-manager.ts +175 -0
- package/src/sdk.ts +401 -0
- package/src/types.ts +451 -0
- package/src/utils/code-extractor.ts +194 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import { BaseSandboxProvider } from './base-provider.js';
|
|
2
|
+
import type { SandboxConfig, CommandResult, CodeExecutionResult, SandboxInfo } from '../types.js';
|
|
3
|
+
import { Sandbox } from '@e2b/code-interpreter';
|
|
4
|
+
import 'dotenv/config';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* E2B Sandbox Provider
|
|
8
|
+
* Provides sandbox execution capabilities using E2B Code Interpreter SDK
|
|
9
|
+
*/
|
|
10
|
+
export class E2BSandboxProvider extends BaseSandboxProvider {
|
|
11
|
+
private sandboxInstance: Sandbox | null = null;
|
|
12
|
+
protected client: Record<string, any> | null = null;
|
|
13
|
+
|
|
14
|
+
constructor(config?: SandboxConfig) {
|
|
15
|
+
super('e2b');
|
|
16
|
+
if (config) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
getClient(): Record<string, any> {
|
|
23
|
+
if (!this.client) {
|
|
24
|
+
const apiKey = this.config.apiKey || process.env.E2B_API_KEY;
|
|
25
|
+
if (!apiKey) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
'E2B API key is required. Set E2B_API_KEY environment variable or provide apiKey in config.'
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
this.client = {
|
|
31
|
+
apiKey: apiKey,
|
|
32
|
+
...this.config,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
if (this.config.apiKey) {
|
|
36
|
+
process.env['E2B_API_KEY'] = this.config.apiKey;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return this.client;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Initialize/create an E2B sandbox
|
|
44
|
+
*/
|
|
45
|
+
protected async initializeSandbox(config?: SandboxConfig): Promise<void> {
|
|
46
|
+
if (config) {
|
|
47
|
+
this.config = { ...this.config, ...config };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
// Dynamic import to handle optional dependency
|
|
52
|
+
const client = this.getClient();
|
|
53
|
+
|
|
54
|
+
const envs = this.config.env || {};
|
|
55
|
+
|
|
56
|
+
// Create sandbox instance using @e2b/code-interpreter
|
|
57
|
+
// The code-interpreter SDK uses 'envs' instead of 'env'
|
|
58
|
+
const sandboxOpts: any = {
|
|
59
|
+
apiKey: client.apiKey,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
if (Object.keys(envs).length > 0) {
|
|
63
|
+
sandboxOpts.envs = envs;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.sandboxInstance = await Sandbox.create(sandboxOpts);
|
|
67
|
+
|
|
68
|
+
this.sandboxId = this.sandboxInstance.sandboxId;
|
|
69
|
+
this.initialized = true;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`Failed to initialize E2B sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Connect to an existing E2B sandbox by ID
|
|
79
|
+
*/
|
|
80
|
+
async fromSandbox(sandboxId: string, config?: SandboxConfig): Promise<Sandbox> {
|
|
81
|
+
if (config) {
|
|
82
|
+
this.config = { ...this.config, ...config };
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
|
|
86
|
+
const client = this.getClient();
|
|
87
|
+
|
|
88
|
+
const sandbox = await Sandbox.connect(sandboxId, {
|
|
89
|
+
apiKey: client.apiKey,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
this.sandboxInstance = sandbox;
|
|
93
|
+
this.sandboxId = sandbox.sandboxId;
|
|
94
|
+
this.initialized = true;
|
|
95
|
+
return this.sandboxInstance;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
|
|
98
|
+
throw new Error(
|
|
99
|
+
`Failed to connect to E2B sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Close/cleanup the E2B sandbox
|
|
106
|
+
*/
|
|
107
|
+
async close(): Promise<void> {
|
|
108
|
+
if (this.sandboxInstance) {
|
|
109
|
+
try {
|
|
110
|
+
await this.sandboxInstance.kill();
|
|
111
|
+
} catch (error) {
|
|
112
|
+
// Ignore errors during cleanup
|
|
113
|
+
console.warn('Error closing E2B sandbox:', error);
|
|
114
|
+
}
|
|
115
|
+
this.sandboxInstance = null;
|
|
116
|
+
this.sandboxId = null;
|
|
117
|
+
this.initialized = false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Execute a command in the E2B sandbox
|
|
123
|
+
*/
|
|
124
|
+
async executeCommand(
|
|
125
|
+
command: string,
|
|
126
|
+
options?: {
|
|
127
|
+
cwd?: string;
|
|
128
|
+
env?: Record<string, string>;
|
|
129
|
+
timeout?: number;
|
|
130
|
+
}
|
|
131
|
+
): Promise<CommandResult> {
|
|
132
|
+
this.ensureInitialized();
|
|
133
|
+
|
|
134
|
+
const startTime = Date.now();
|
|
135
|
+
try {
|
|
136
|
+
// Use commands.run() which takes the command string directly
|
|
137
|
+
// and options as the second parameter
|
|
138
|
+
const commandOpts: any = {};
|
|
139
|
+
if (options?.cwd) {
|
|
140
|
+
commandOpts.cwd = options.cwd;
|
|
141
|
+
}
|
|
142
|
+
if (options?.env) {
|
|
143
|
+
commandOpts.envs = options.env; // E2B uses 'envs' not 'env'
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const timeout = options?.timeout || this.config.timeout || 60000;
|
|
147
|
+
const result = await Promise.race([
|
|
148
|
+
this.sandboxInstance!.commands.run(command, commandOpts),
|
|
149
|
+
new Promise<CommandResult>((_, reject) =>
|
|
150
|
+
setTimeout(() => reject(new Error('Command timeout')), timeout)
|
|
151
|
+
),
|
|
152
|
+
]);
|
|
153
|
+
|
|
154
|
+
const executionTime = Date.now() - startTime;
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
exitCode: result.exitCode || 0,
|
|
158
|
+
stdout: result.stdout || '',
|
|
159
|
+
stderr: result.stderr || '',
|
|
160
|
+
executionTime,
|
|
161
|
+
};
|
|
162
|
+
} catch (error) {
|
|
163
|
+
const executionTime = Date.now() - startTime;
|
|
164
|
+
return {
|
|
165
|
+
exitCode: 1,
|
|
166
|
+
stdout: '',
|
|
167
|
+
stderr: error instanceof Error ? error.message : String(error),
|
|
168
|
+
executionTime,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Run code (e.g., Python, JavaScript) in the E2B sandbox
|
|
175
|
+
*/
|
|
176
|
+
async runCode(
|
|
177
|
+
code: string,
|
|
178
|
+
options?: {
|
|
179
|
+
language?: string;
|
|
180
|
+
env?: Record<string, string>;
|
|
181
|
+
timeout?: number;
|
|
182
|
+
onStdout?: (data: string) => void;
|
|
183
|
+
onStderr?: (data: string) => void;
|
|
184
|
+
}
|
|
185
|
+
): Promise<CodeExecutionResult> {
|
|
186
|
+
this.ensureInitialized();
|
|
187
|
+
|
|
188
|
+
const startTime = Date.now();
|
|
189
|
+
try {
|
|
190
|
+
const runCodeOpts: any = {};
|
|
191
|
+
|
|
192
|
+
if (options?.language) {
|
|
193
|
+
runCodeOpts.language = options.language;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (options?.env) {
|
|
197
|
+
runCodeOpts.envs = options.env; // E2B uses 'envs' not 'env'
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (options?.timeout) {
|
|
201
|
+
runCodeOpts.timeoutMs = options.timeout;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Handle streaming callbacks for stdout/stderr
|
|
205
|
+
if (options?.onStdout) {
|
|
206
|
+
runCodeOpts.onStdout = (output: { line: string }) => {
|
|
207
|
+
options.onStdout!(output.line);
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (options?.onStderr) {
|
|
212
|
+
runCodeOpts.onStderr = (output: { line: string }) => {
|
|
213
|
+
options.onStderr!(output.line);
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const execution = await this.sandboxInstance!.runCode(code, runCodeOpts);
|
|
218
|
+
const executionTime = Date.now() - startTime;
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
text: execution.text,
|
|
222
|
+
results: execution.results.map((result) => result.toJSON()),
|
|
223
|
+
stdout: execution.logs.stdout,
|
|
224
|
+
stderr: execution.logs.stderr,
|
|
225
|
+
error: execution.error
|
|
226
|
+
? {
|
|
227
|
+
name: execution.error.name,
|
|
228
|
+
value: execution.error.value,
|
|
229
|
+
traceback: execution.error.traceback,
|
|
230
|
+
}
|
|
231
|
+
: undefined,
|
|
232
|
+
executionTime,
|
|
233
|
+
};
|
|
234
|
+
} catch (error) {
|
|
235
|
+
const executionTime = Date.now() - startTime;
|
|
236
|
+
return {
|
|
237
|
+
text: undefined,
|
|
238
|
+
results: [],
|
|
239
|
+
stdout: [],
|
|
240
|
+
stderr: [],
|
|
241
|
+
error: {
|
|
242
|
+
name: 'ExecutionError',
|
|
243
|
+
value: error instanceof Error ? error.message : String(error),
|
|
244
|
+
traceback: error instanceof Error ? error.stack || '' : '',
|
|
245
|
+
},
|
|
246
|
+
executionTime,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Upload a file to the E2B sandbox
|
|
253
|
+
*/
|
|
254
|
+
async uploadFile(localPath: string, remotePath: string): Promise<void> {
|
|
255
|
+
this.ensureInitialized();
|
|
256
|
+
|
|
257
|
+
try {
|
|
258
|
+
const fs = await import('fs/promises');
|
|
259
|
+
const content = await fs.readFile(localPath);
|
|
260
|
+
// Convert Buffer to Uint8Array for E2B filesystem
|
|
261
|
+
const uint8Array = new Uint8Array(content);
|
|
262
|
+
await this.sandboxInstance!.files.write(remotePath, uint8Array.buffer);
|
|
263
|
+
} catch (error) {
|
|
264
|
+
throw new Error(
|
|
265
|
+
`Failed to upload file to E2B sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Download a file from the E2B sandbox
|
|
272
|
+
*/
|
|
273
|
+
async downloadFile(remotePath: string, localPath: string): Promise<void> {
|
|
274
|
+
this.ensureInitialized();
|
|
275
|
+
|
|
276
|
+
try {
|
|
277
|
+
const content = await this.sandboxInstance!.files.read(remotePath, { format: 'bytes' });
|
|
278
|
+
const fs = await import('fs/promises');
|
|
279
|
+
await fs.writeFile(localPath, Buffer.from(content));
|
|
280
|
+
} catch (error) {
|
|
281
|
+
throw new Error(
|
|
282
|
+
`Failed to download file from E2B sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Read a file from the E2B sandbox
|
|
289
|
+
*/
|
|
290
|
+
async readFile(path: string): Promise<string> {
|
|
291
|
+
this.ensureInitialized();
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
const content = await this.sandboxInstance!.files.read(path);
|
|
295
|
+
return content;
|
|
296
|
+
} catch (error) {
|
|
297
|
+
throw new Error(
|
|
298
|
+
`Failed to read file from E2B sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Write a file to the E2B sandbox
|
|
305
|
+
*/
|
|
306
|
+
async writeFile(path: string, content: string): Promise<void> {
|
|
307
|
+
this.ensureInitialized();
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
await this.sandboxInstance!.files.write(path, content);
|
|
311
|
+
} catch (error) {
|
|
312
|
+
throw new Error(
|
|
313
|
+
`Failed to write file to E2B sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* List files in a directory
|
|
320
|
+
*/
|
|
321
|
+
async listFiles(path: string): Promise<string[]> {
|
|
322
|
+
this.ensureInitialized();
|
|
323
|
+
|
|
324
|
+
try {
|
|
325
|
+
const entries = await this.sandboxInstance!.files.list(path);
|
|
326
|
+
return entries.map((entry) => entry.name || entry.path);
|
|
327
|
+
} catch (error) {
|
|
328
|
+
throw new Error(
|
|
329
|
+
`Failed to list files in E2B sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Check if a file exists
|
|
336
|
+
*/
|
|
337
|
+
async fileExists(path: string): Promise<boolean> {
|
|
338
|
+
this.ensureInitialized();
|
|
339
|
+
|
|
340
|
+
try {
|
|
341
|
+
return await this.sandboxInstance!.files.exists(path);
|
|
342
|
+
} catch {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Delete a file
|
|
349
|
+
*/
|
|
350
|
+
async deleteFile(path: string): Promise<void> {
|
|
351
|
+
this.ensureInitialized();
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
await this.sandboxInstance!.files.remove(path);
|
|
355
|
+
} catch (error) {
|
|
356
|
+
throw new Error(
|
|
357
|
+
`Failed to delete file in E2B sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Get sandbox status
|
|
364
|
+
*/
|
|
365
|
+
async getStatus(): Promise<{
|
|
366
|
+
isRunning: boolean;
|
|
367
|
+
createdAt?: number;
|
|
368
|
+
[key: string]: unknown;
|
|
369
|
+
}> {
|
|
370
|
+
this.ensureInitialized();
|
|
371
|
+
|
|
372
|
+
try {
|
|
373
|
+
// E2B doesn't expose a direct status endpoint, but we can check if sandbox is accessible
|
|
374
|
+
return {
|
|
375
|
+
isRunning: this.initialized && this.sandboxInstance !== null,
|
|
376
|
+
sandboxId: this.sandboxId,
|
|
377
|
+
};
|
|
378
|
+
} catch {
|
|
379
|
+
return {
|
|
380
|
+
isRunning: false,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Get detailed sandbox information
|
|
387
|
+
*/
|
|
388
|
+
async getInfo(sandboxId?: string): Promise<SandboxInfo> {
|
|
389
|
+
|
|
390
|
+
if (!sandboxId && this.sandboxInstance) {
|
|
391
|
+
|
|
392
|
+
const info = await this.sandboxInstance.getInfo();
|
|
393
|
+
return {
|
|
394
|
+
sandboxId: info.sandboxId,
|
|
395
|
+
provider: this.type,
|
|
396
|
+
isRunning: info.state === 'running',
|
|
397
|
+
isInitialized: this.initialized,
|
|
398
|
+
createdAt: info.startedAt,
|
|
399
|
+
metadata: info.metadata,
|
|
400
|
+
info: info,
|
|
401
|
+
};
|
|
402
|
+
} else if (sandboxId) {
|
|
403
|
+
const sandbox = await this.fromSandbox(sandboxId);
|
|
404
|
+
const info = await sandbox.getInfo();
|
|
405
|
+
return {
|
|
406
|
+
sandboxId: sandbox.sandboxId,
|
|
407
|
+
provider: this.type,
|
|
408
|
+
isRunning: info.state === 'running',
|
|
409
|
+
isInitialized: this.initialized,
|
|
410
|
+
createdAt: info.startedAt,
|
|
411
|
+
metadata: info.metadata,
|
|
412
|
+
info: info,
|
|
413
|
+
};
|
|
414
|
+
} else {
|
|
415
|
+
throw new Error('Sandbox ID or active instance is required to get sandbox info');
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|