@computesdk/e2b 1.2.0 → 1.3.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/dist/index.js CHANGED
@@ -104,10 +104,19 @@ var e2b = (0, import_computesdk.createProvider)({
104
104
  return null;
105
105
  }
106
106
  },
107
- list: async (_config) => {
108
- throw new Error(
109
- `E2B provider does not support listing sandboxes. E2B sandboxes are managed individually and don't have a native list API. Consider using a provider with persistent sandbox management or implement your own tracking system.`
110
- );
107
+ list: async (config) => {
108
+ const apiKey = config.apiKey || process.env.E2B_API_KEY;
109
+ try {
110
+ const sandboxes = await import_code_interpreter.Sandbox.list({
111
+ apiKey
112
+ });
113
+ return sandboxes.map((sandbox) => ({
114
+ sandbox,
115
+ sandboxId: sandbox.id
116
+ }));
117
+ } catch (error) {
118
+ return [];
119
+ }
111
120
  },
112
121
  destroy: async (config, sandboxId) => {
113
122
  const apiKey = config.apiKey || process.env.E2B_API_KEY;
@@ -248,6 +257,10 @@ var e2b = (0, import_computesdk.createProvider)({
248
257
  remove: async (sandbox, path) => {
249
258
  await sandbox.files.remove(path);
250
259
  }
260
+ },
261
+ // Provider-specific typed getInstance method
262
+ getInstance: (sandbox) => {
263
+ return sandbox;
251
264
  }
252
265
  }
253
266
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * E2B Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Sandbox as E2BSandbox } from '@e2b/code-interpreter';\nimport { createProvider } from 'computesdk';\nimport type { \n ExecutionResult, \n SandboxInfo, \n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n/**\n * E2B-specific configuration options\n */\nexport interface E2BConfig {\n /** E2B API key - if not provided, will fallback to E2B_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n\n\n/**\n * Create an E2B provider instance using the factory pattern\n */\nexport const e2b = createProvider<E2BSandbox, E2BConfig>({\n name: 'e2b',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: E2BConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.E2B_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing E2B API key. Provide 'apiKey' in config or set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!apiKey.startsWith('e2b_')) {\n throw new Error(\n `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`\n );\n }\n\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: E2BSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing E2B session\n sandbox = await E2BSandbox.connect(options.sandboxId, {\n apiKey: apiKey,\n domain: options.domain,\n });\n sandboxId = options.sandboxId;\n } else {\n // Create new E2B session\n if (options?.templateId) {\n sandbox = await E2BSandbox.create(options.templateId, {\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options.domain,\n });\n } else {\n sandbox = await E2BSandbox.create({\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n });\n }\n sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `E2B quota exceeded. Please check your usage at https://e2b.dev/`\n );\n }\n }\n throw new Error(\n `Failed to create E2B sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: E2BConfig) => {\n throw new Error(\n `E2B provider does not support listing sandboxes. E2B sandboxes are managed individually and don't have a native list API. Consider using a provider with persistent sandbox management or implement your own tracking system.`\n );\n },\n\n destroy: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n await sandbox.kill();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: E2BSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n \n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') || \n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\")\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n \n // Use runCommand for consistent execution across all providers\n let result;\n \n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n \n if (effectiveRuntime === 'python') {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (result.exitCode !== 0 && result.stderr) {\n // Check for common syntax error patterns\n if (result.stderr.includes('SyntaxError') || \n result.stderr.includes('invalid syntax') ||\n result.stderr.includes('Unexpected token') ||\n result.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${result.stderr.trim()}`);\n }\n }\n\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // Handle E2B's CommandExitError - check if it contains actual error details\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n \n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n stdout: '',\n stderr: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n }\n \n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: E2BSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments\n const fullCommand = args.length > 0 ? `${command} ${args.join(' ')}` : command;\n\n // Execute command using E2B's bash execution via Python subprocess\n const execution = await sandbox.commands.run(fullCommand);\n\n return {\n stdout: execution.stdout,\n stderr: execution.stderr,\n exitCode: execution.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // For command failures, return error info instead of throwing\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127, // Command not found exit code\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n },\n\n getInfo: async (sandbox: E2BSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n runtime: 'python', // E2B default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n e2bSessionId: sandbox.sandboxId\n }\n };\n },\n\n getUrl: async (sandbox: E2BSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use E2B's built-in getHost method for accurate host information\n const host = sandbox.getHost(options.port);\n const protocol = options.protocol || 'https';\n return `${protocol}://${host}`;\n } catch (error) {\n throw new Error(\n `Failed to get E2B host for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - E2B has full filesystem support\n filesystem: {\n readFile: async (sandbox: E2BSandbox, path: string): Promise<string> => {\n return await sandbox.files.read(path);\n },\n\n writeFile: async (sandbox: E2BSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n\n mkdir: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n\n readdir: async (sandbox: E2BSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: Boolean(entry.isDir || entry.isDirectory),\n size: entry.size || 0,\n lastModified: new Date(entry.lastModified || Date.now())\n }));\n },\n\n exists: async (sandbox: E2BSandbox, path: string): Promise<boolean> => {\n return await sandbox.files.exists(path);\n },\n\n remove: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n }\n },\n\n\n }\n }\n});\n"],"mappings":"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","names":["E2BSandbox"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * E2B Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Sandbox as E2BSandbox } from '@e2b/code-interpreter';\nimport { createProvider } from 'computesdk';\nimport type {\n ExecutionResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n/**\n * E2B-specific configuration options\n */\nexport interface E2BConfig {\n /** E2B API key - if not provided, will fallback to E2B_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n\n\n/**\n * Create an E2B provider instance using the factory pattern\n */\nexport const e2b = createProvider<E2BSandbox, E2BConfig>({\n name: 'e2b',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: E2BConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.E2B_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing E2B API key. Provide 'apiKey' in config or set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!apiKey.startsWith('e2b_')) {\n throw new Error(\n `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`\n );\n }\n\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: E2BSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing E2B session\n sandbox = await E2BSandbox.connect(options.sandboxId, {\n apiKey: apiKey,\n domain: options.domain,\n });\n sandboxId = options.sandboxId;\n } else {\n // Create new E2B session\n if (options?.templateId) {\n sandbox = await E2BSandbox.create(options.templateId, {\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options.domain,\n });\n } else {\n sandbox = await E2BSandbox.create({\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n });\n }\n sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `E2B quota exceeded. Please check your usage at https://e2b.dev/`\n );\n }\n }\n throw new Error(\n `Failed to create E2B sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: E2BConfig) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandboxes = await E2BSandbox.list({\n apiKey: apiKey,\n });\n return sandboxes.map((sandbox: any) => ({\n sandbox,\n sandboxId: sandbox.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n await sandbox.kill();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: E2BSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\")\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use runCommand for consistent execution across all providers\n let result;\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n\n if (effectiveRuntime === 'python') {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (result.exitCode !== 0 && result.stderr) {\n // Check for common syntax error patterns\n if (result.stderr.includes('SyntaxError') ||\n result.stderr.includes('invalid syntax') ||\n result.stderr.includes('Unexpected token') ||\n result.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${result.stderr.trim()}`);\n }\n }\n\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // Handle E2B's CommandExitError - check if it contains actual error details\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n\n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n stdout: '',\n stderr: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n }\n\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: E2BSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments\n const fullCommand = args.length > 0 ? `${command} ${args.join(' ')}` : command;\n\n // Execute command using E2B's bash execution via Python subprocess\n const execution = await sandbox.commands.run(fullCommand);\n\n return {\n stdout: execution.stdout,\n stderr: execution.stderr,\n exitCode: execution.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // For command failures, return error info instead of throwing\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127, // Command not found exit code\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n },\n\n getInfo: async (sandbox: E2BSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n runtime: 'python', // E2B default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n e2bSessionId: sandbox.sandboxId\n }\n };\n },\n\n getUrl: async (sandbox: E2BSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use E2B's built-in getHost method for accurate host information\n const host = sandbox.getHost(options.port);\n const protocol = options.protocol || 'https';\n return `${protocol}://${host}`;\n } catch (error) {\n throw new Error(\n `Failed to get E2B host for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - E2B has full filesystem support\n filesystem: {\n readFile: async (sandbox: E2BSandbox, path: string): Promise<string> => {\n return await sandbox.files.read(path);\n },\n\n writeFile: async (sandbox: E2BSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n\n mkdir: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n\n readdir: async (sandbox: E2BSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: Boolean(entry.isDir || entry.isDirectory),\n size: entry.size || 0,\n lastModified: new Date(entry.lastModified || Date.now())\n }));\n },\n\n exists: async (sandbox: E2BSandbox, path: string): Promise<boolean> => {\n return await sandbox.files.exists(path);\n },\n\n remove: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: E2BSandbox): E2BSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n"],"mappings":"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","names":["E2BSandbox"]}
package/dist/index.mjs CHANGED
@@ -80,10 +80,19 @@ var e2b = createProvider({
80
80
  return null;
81
81
  }
82
82
  },
83
- list: async (_config) => {
84
- throw new Error(
85
- `E2B provider does not support listing sandboxes. E2B sandboxes are managed individually and don't have a native list API. Consider using a provider with persistent sandbox management or implement your own tracking system.`
86
- );
83
+ list: async (config) => {
84
+ const apiKey = config.apiKey || process.env.E2B_API_KEY;
85
+ try {
86
+ const sandboxes = await E2BSandbox.list({
87
+ apiKey
88
+ });
89
+ return sandboxes.map((sandbox) => ({
90
+ sandbox,
91
+ sandboxId: sandbox.id
92
+ }));
93
+ } catch (error) {
94
+ return [];
95
+ }
87
96
  },
88
97
  destroy: async (config, sandboxId) => {
89
98
  const apiKey = config.apiKey || process.env.E2B_API_KEY;
@@ -224,6 +233,10 @@ var e2b = createProvider({
224
233
  remove: async (sandbox, path) => {
225
234
  await sandbox.files.remove(path);
226
235
  }
236
+ },
237
+ // Provider-specific typed getInstance method
238
+ getInstance: (sandbox) => {
239
+ return sandbox;
227
240
  }
228
241
  }
229
242
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * E2B Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Sandbox as E2BSandbox } from '@e2b/code-interpreter';\nimport { createProvider } from 'computesdk';\nimport type { \n ExecutionResult, \n SandboxInfo, \n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n/**\n * E2B-specific configuration options\n */\nexport interface E2BConfig {\n /** E2B API key - if not provided, will fallback to E2B_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n\n\n/**\n * Create an E2B provider instance using the factory pattern\n */\nexport const e2b = createProvider<E2BSandbox, E2BConfig>({\n name: 'e2b',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: E2BConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.E2B_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing E2B API key. Provide 'apiKey' in config or set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!apiKey.startsWith('e2b_')) {\n throw new Error(\n `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`\n );\n }\n\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: E2BSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing E2B session\n sandbox = await E2BSandbox.connect(options.sandboxId, {\n apiKey: apiKey,\n domain: options.domain,\n });\n sandboxId = options.sandboxId;\n } else {\n // Create new E2B session\n if (options?.templateId) {\n sandbox = await E2BSandbox.create(options.templateId, {\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options.domain,\n });\n } else {\n sandbox = await E2BSandbox.create({\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n });\n }\n sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `E2B quota exceeded. Please check your usage at https://e2b.dev/`\n );\n }\n }\n throw new Error(\n `Failed to create E2B sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: E2BConfig) => {\n throw new Error(\n `E2B provider does not support listing sandboxes. E2B sandboxes are managed individually and don't have a native list API. Consider using a provider with persistent sandbox management or implement your own tracking system.`\n );\n },\n\n destroy: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n await sandbox.kill();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: E2BSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n \n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') || \n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\")\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n \n // Use runCommand for consistent execution across all providers\n let result;\n \n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n \n if (effectiveRuntime === 'python') {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (result.exitCode !== 0 && result.stderr) {\n // Check for common syntax error patterns\n if (result.stderr.includes('SyntaxError') || \n result.stderr.includes('invalid syntax') ||\n result.stderr.includes('Unexpected token') ||\n result.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${result.stderr.trim()}`);\n }\n }\n\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // Handle E2B's CommandExitError - check if it contains actual error details\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n \n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n stdout: '',\n stderr: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n }\n \n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: E2BSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments\n const fullCommand = args.length > 0 ? `${command} ${args.join(' ')}` : command;\n\n // Execute command using E2B's bash execution via Python subprocess\n const execution = await sandbox.commands.run(fullCommand);\n\n return {\n stdout: execution.stdout,\n stderr: execution.stderr,\n exitCode: execution.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // For command failures, return error info instead of throwing\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127, // Command not found exit code\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n },\n\n getInfo: async (sandbox: E2BSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n runtime: 'python', // E2B default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n e2bSessionId: sandbox.sandboxId\n }\n };\n },\n\n getUrl: async (sandbox: E2BSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use E2B's built-in getHost method for accurate host information\n const host = sandbox.getHost(options.port);\n const protocol = options.protocol || 'https';\n return `${protocol}://${host}`;\n } catch (error) {\n throw new Error(\n `Failed to get E2B host for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - E2B has full filesystem support\n filesystem: {\n readFile: async (sandbox: E2BSandbox, path: string): Promise<string> => {\n return await sandbox.files.read(path);\n },\n\n writeFile: async (sandbox: E2BSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n\n mkdir: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n\n readdir: async (sandbox: E2BSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: Boolean(entry.isDir || entry.isDirectory),\n size: entry.size || 0,\n lastModified: new Date(entry.lastModified || Date.now())\n }));\n },\n\n exists: async (sandbox: E2BSandbox, path: string): Promise<boolean> => {\n return await sandbox.files.exists(path);\n },\n\n remove: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n }\n },\n\n\n }\n }\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * E2B Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Sandbox as E2BSandbox } from '@e2b/code-interpreter';\nimport { createProvider } from 'computesdk';\nimport type {\n ExecutionResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n/**\n * E2B-specific configuration options\n */\nexport interface E2BConfig {\n /** E2B API key - if not provided, will fallback to E2B_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n\n\n/**\n * Create an E2B provider instance using the factory pattern\n */\nexport const e2b = createProvider<E2BSandbox, E2BConfig>({\n name: 'e2b',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: E2BConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.E2B_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing E2B API key. Provide 'apiKey' in config or set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!apiKey.startsWith('e2b_')) {\n throw new Error(\n `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`\n );\n }\n\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: E2BSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing E2B session\n sandbox = await E2BSandbox.connect(options.sandboxId, {\n apiKey: apiKey,\n domain: options.domain,\n });\n sandboxId = options.sandboxId;\n } else {\n // Create new E2B session\n if (options?.templateId) {\n sandbox = await E2BSandbox.create(options.templateId, {\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options.domain,\n });\n } else {\n sandbox = await E2BSandbox.create({\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n });\n }\n sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `E2B quota exceeded. Please check your usage at https://e2b.dev/`\n );\n }\n }\n throw new Error(\n `Failed to create E2B sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: E2BConfig) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandboxes = await E2BSandbox.list({\n apiKey: apiKey,\n });\n return sandboxes.map((sandbox: any) => ({\n sandbox,\n sandboxId: sandbox.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n await sandbox.kill();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: E2BSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\")\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use runCommand for consistent execution across all providers\n let result;\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n\n if (effectiveRuntime === 'python') {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (result.exitCode !== 0 && result.stderr) {\n // Check for common syntax error patterns\n if (result.stderr.includes('SyntaxError') ||\n result.stderr.includes('invalid syntax') ||\n result.stderr.includes('Unexpected token') ||\n result.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${result.stderr.trim()}`);\n }\n }\n\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // Handle E2B's CommandExitError - check if it contains actual error details\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n\n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n stdout: '',\n stderr: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n }\n\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: E2BSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments\n const fullCommand = args.length > 0 ? `${command} ${args.join(' ')}` : command;\n\n // Execute command using E2B's bash execution via Python subprocess\n const execution = await sandbox.commands.run(fullCommand);\n\n return {\n stdout: execution.stdout,\n stderr: execution.stderr,\n exitCode: execution.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // For command failures, return error info instead of throwing\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127, // Command not found exit code\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n },\n\n getInfo: async (sandbox: E2BSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n runtime: 'python', // E2B default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n e2bSessionId: sandbox.sandboxId\n }\n };\n },\n\n getUrl: async (sandbox: E2BSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use E2B's built-in getHost method for accurate host information\n const host = sandbox.getHost(options.port);\n const protocol = options.protocol || 'https';\n return `${protocol}://${host}`;\n } catch (error) {\n throw new Error(\n `Failed to get E2B host for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - E2B has full filesystem support\n filesystem: {\n readFile: async (sandbox: E2BSandbox, path: string): Promise<string> => {\n return await sandbox.files.read(path);\n },\n\n writeFile: async (sandbox: E2BSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n\n mkdir: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n\n readdir: async (sandbox: E2BSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: Boolean(entry.isDir || entry.isDirectory),\n size: entry.size || 0,\n lastModified: new Date(entry.lastModified || Date.now())\n }));\n },\n\n exists: async (sandbox: E2BSandbox, path: string): Promise<boolean> => {\n return await sandbox.files.exists(path);\n },\n\n remove: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: E2BSandbox): E2BSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/e2b",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "E2B provider for ComputeSDK",
5
5
  "author": "Garrison",
6
6
  "license": "MIT",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "@e2b/code-interpreter": "^1.5.1",
22
- "computesdk": "1.2.0"
22
+ "computesdk": "1.3.1"
23
23
  },
24
24
  "keywords": [
25
25
  "e2b",
@@ -46,7 +46,7 @@
46
46
  "tsup": "^8.0.0",
47
47
  "typescript": "^5.0.0",
48
48
  "vitest": "^1.0.0",
49
- "@computesdk/test-utils": "1.2.0"
49
+ "@computesdk/test-utils": "1.3.0"
50
50
  },
51
51
  "scripts": {
52
52
  "build": "tsup",