@computesdk/e2b 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 computesdk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,242 @@
1
+ # @computesdk/e2b
2
+
3
+ E2B provider for ComputeSDK - Execute Python code in secure, isolated E2B sandboxes.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @computesdk/e2b
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ 1. Get your E2B API key from [e2b.dev](https://e2b.dev/)
14
+ 2. Set the environment variable:
15
+
16
+ ```bash
17
+ export E2B_API_KEY=e2b_your_api_key_here
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### Basic Usage
23
+
24
+ ```typescript
25
+ import { e2b } from '@computesdk/e2b';
26
+
27
+ const provider = e2b();
28
+
29
+ // Execute Python code
30
+ const result = await provider.doExecute('print("Hello from E2B!")');
31
+ console.log(result.stdout); // "Hello from E2B!"
32
+ ```
33
+
34
+ ### With ComputeSDK
35
+
36
+ ```typescript
37
+ import { executeSandbox } from 'computesdk';
38
+ import { e2b } from '@computesdk/e2b';
39
+
40
+ const result = await executeSandbox({
41
+ sandbox: e2b(),
42
+ code: 'print("Hello World")',
43
+ runtime: 'python'
44
+ });
45
+ ```
46
+
47
+ ### Configuration
48
+
49
+ ```typescript
50
+ import { e2b } from '@computesdk/e2b';
51
+
52
+ const provider = e2b({
53
+ timeout: 300000, // 5 minutes (default)
54
+ runtime: 'python' // Only Python is supported
55
+ });
56
+ ```
57
+
58
+ ## API Reference
59
+
60
+ ### `e2b(config?: SandboxConfig)`
61
+
62
+ Creates a new E2B provider instance.
63
+
64
+ #### Parameters
65
+
66
+ - `config` (optional): Configuration object
67
+ - `timeout`: Execution timeout in milliseconds (default: 300000)
68
+ - `runtime`: Runtime environment - only `'python'` is supported
69
+
70
+ #### Returns
71
+
72
+ `E2BProvider` instance implementing the `ComputeSpecification` interface.
73
+
74
+ ### Provider Methods
75
+
76
+ #### `doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult>`
77
+
78
+ Execute Python code in the E2B sandbox.
79
+
80
+ ```typescript
81
+ const result = await provider.doExecute('x = 1 + 1\nprint(x)');
82
+ // result.stdout: "2"
83
+ // result.stderr: ""
84
+ // result.exitCode: 0
85
+ ```
86
+
87
+ #### `doKill(): Promise<void>`
88
+
89
+ Terminates the E2B sandbox session.
90
+
91
+ ```typescript
92
+ await provider.doKill();
93
+ ```
94
+
95
+ #### `doGetInfo(): Promise<SandboxInfo>`
96
+
97
+ Get information about the sandbox.
98
+
99
+ ```typescript
100
+ const info = await provider.doGetInfo();
101
+ // info.provider: "e2b"
102
+ // info.runtime: "python"
103
+ // info.status: "running" | "stopped"
104
+ ```
105
+
106
+ ## Error Handling
107
+
108
+ The provider includes comprehensive error handling:
109
+
110
+ ### Authentication Errors
111
+
112
+ ```typescript
113
+ // Missing API key
114
+ Error: Missing E2B API key. Set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/
115
+
116
+ // Invalid API key format
117
+ Error: Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.
118
+
119
+ // Authentication failed
120
+ Error: E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/
121
+ ```
122
+
123
+ ### Runtime Errors
124
+
125
+ ```typescript
126
+ // Unsupported runtime
127
+ Error: E2B provider currently only supports Python runtime
128
+
129
+ // Execution timeout
130
+ Error: E2B execution timeout (300000ms). Consider increasing the timeout or optimizing your code.
131
+
132
+ // Memory limits
133
+ Error: E2B execution failed due to memory limits. Consider optimizing your code or using smaller data sets.
134
+ ```
135
+
136
+ ### Quota Errors
137
+
138
+ ```typescript
139
+ // Quota exceeded
140
+ Error: E2B quota exceeded. Please check your usage at https://e2b.dev/
141
+ ```
142
+
143
+ ## Examples
144
+
145
+ ### Data Analysis
146
+
147
+ ```typescript
148
+ import { e2b } from '@computesdk/e2b';
149
+
150
+ const provider = e2b();
151
+
152
+ const code = `
153
+ import pandas as pd
154
+ import numpy as np
155
+
156
+ # Create sample data
157
+ data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
158
+ df = pd.DataFrame(data)
159
+
160
+ print("DataFrame:")
161
+ print(df)
162
+ print(f"Sum of column A: {df['A'].sum()}")
163
+ `;
164
+
165
+ const result = await provider.doExecute(code);
166
+ console.log(result.stdout);
167
+ ```
168
+
169
+ ### Machine Learning
170
+
171
+ ```typescript
172
+ import { e2b } from '@computesdk/e2b';
173
+
174
+ const provider = e2b();
175
+
176
+ const code = `
177
+ from sklearn.linear_model import LinearRegression
178
+ import numpy as np
179
+
180
+ # Sample data
181
+ X = np.array([[1], [2], [3], [4]])
182
+ y = np.array([2, 4, 6, 8])
183
+
184
+ # Train model
185
+ model = LinearRegression()
186
+ model.fit(X, y)
187
+
188
+ # Make prediction
189
+ prediction = model.predict([[5]])
190
+ print(f"Prediction for x=5: {prediction[0]}")
191
+ `;
192
+
193
+ const result = await provider.doExecute(code);
194
+ console.log(result.stdout); // "Prediction for x=5: 10.0"
195
+ ```
196
+
197
+ ### File Operations
198
+
199
+ ```typescript
200
+ import { e2b } from '@computesdk/e2b';
201
+
202
+ const provider = e2b();
203
+
204
+ const code = `
205
+ # Write to file
206
+ with open('data.txt', 'w') as f:
207
+ f.write('Hello from E2B sandbox!')
208
+
209
+ # Read from file
210
+ with open('data.txt', 'r') as f:
211
+ content = f.read()
212
+ print(f"File content: {content}")
213
+ `;
214
+
215
+ const result = await provider.doExecute(code);
216
+ console.log(result.stdout);
217
+ ```
218
+
219
+ ## Limitations
220
+
221
+ - **Python Only**: E2B provider currently only supports Python runtime
222
+ - **Timeout**: Default 5-minute execution timeout
223
+ - **Memory**: Subject to E2B sandbox memory limits
224
+ - **Network**: Limited network access in sandboxes
225
+
226
+ ## Best Practices
227
+
228
+ 1. **Always handle errors**: Use try-catch blocks for robust error handling
229
+ 2. **Set appropriate timeouts**: Adjust timeout based on your use case
230
+ 3. **Clean up resources**: Call `doKill()` when done to free resources
231
+ 4. **Monitor usage**: Keep track of your E2B API usage and quotas
232
+ 5. **Optimize code**: Write efficient Python code to avoid timeout/memory issues
233
+
234
+ ## Support
235
+
236
+ - E2B Documentation: [e2b.dev/docs](https://e2b.dev/docs)
237
+ - ComputeSDK Issues: [GitHub Issues](https://github.com/computesdk/computesdk/issues)
238
+ - E2B Support: [E2B Support](https://e2b.dev/support)
239
+
240
+ ## License
241
+
242
+ MIT
@@ -0,0 +1,19 @@
1
+ import { ComputeSpecification, SandboxConfig, Runtime, ExecutionResult, SandboxInfo } from 'computesdk';
2
+
3
+ declare class E2BProvider implements ComputeSpecification {
4
+ readonly specificationVersion: "v1";
5
+ readonly provider = "e2b";
6
+ readonly sandboxId: string;
7
+ private session;
8
+ private readonly apiKey;
9
+ private readonly runtime;
10
+ private readonly timeout;
11
+ constructor(config: SandboxConfig);
12
+ private ensureSession;
13
+ doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult>;
14
+ doKill(): Promise<void>;
15
+ doGetInfo(): Promise<SandboxInfo>;
16
+ }
17
+ declare function e2b(config?: Partial<SandboxConfig>): E2BProvider;
18
+
19
+ export { E2BProvider, e2b };
@@ -0,0 +1,19 @@
1
+ import { ComputeSpecification, SandboxConfig, Runtime, ExecutionResult, SandboxInfo } from 'computesdk';
2
+
3
+ declare class E2BProvider implements ComputeSpecification {
4
+ readonly specificationVersion: "v1";
5
+ readonly provider = "e2b";
6
+ readonly sandboxId: string;
7
+ private session;
8
+ private readonly apiKey;
9
+ private readonly runtime;
10
+ private readonly timeout;
11
+ constructor(config: SandboxConfig);
12
+ private ensureSession;
13
+ doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult>;
14
+ doKill(): Promise<void>;
15
+ doGetInfo(): Promise<SandboxInfo>;
16
+ }
17
+ declare function e2b(config?: Partial<SandboxConfig>): E2BProvider;
18
+
19
+ export { E2BProvider, e2b };
package/dist/index.js ADDED
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ E2BProvider: () => E2BProvider,
24
+ e2b: () => e2b
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+ var import_code_interpreter = require("@e2b/code-interpreter");
28
+ var E2BProvider = class {
29
+ constructor(config) {
30
+ this.specificationVersion = "v1";
31
+ this.provider = "e2b";
32
+ this.session = null;
33
+ this.sandboxId = `e2b-${Date.now()}-${Math.random().toString(36).substring(7)}`;
34
+ this.timeout = config.timeout || 3e5;
35
+ this.apiKey = process.env.E2B_API_KEY || "";
36
+ if (!this.apiKey) {
37
+ throw new Error(
38
+ `Missing E2B API key. Set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`
39
+ );
40
+ }
41
+ if (!this.apiKey.startsWith("e2b_")) {
42
+ throw new Error(
43
+ `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`
44
+ );
45
+ }
46
+ this.runtime = config.runtime || "python";
47
+ }
48
+ async ensureSession() {
49
+ if (this.session) {
50
+ return this.session;
51
+ }
52
+ try {
53
+ this.session = await import_code_interpreter.Sandbox.create({
54
+ apiKey: this.apiKey,
55
+ timeoutMs: this.timeout
56
+ });
57
+ return this.session;
58
+ } catch (error) {
59
+ if (error instanceof Error) {
60
+ if (error.message.includes("unauthorized") || error.message.includes("API key")) {
61
+ throw new Error(
62
+ `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`
63
+ );
64
+ }
65
+ if (error.message.includes("quota") || error.message.includes("limit")) {
66
+ throw new Error(
67
+ `E2B quota exceeded. Please check your usage at https://e2b.dev/`
68
+ );
69
+ }
70
+ }
71
+ throw new Error(
72
+ `Failed to initialize E2B session: ${error instanceof Error ? error.message : String(error)}`
73
+ );
74
+ }
75
+ }
76
+ async doExecute(code, runtime) {
77
+ const startTime = Date.now();
78
+ try {
79
+ const session = await this.ensureSession();
80
+ const execution = await session.runCode(code);
81
+ return {
82
+ stdout: execution.logs.stdout.join("\n"),
83
+ stderr: execution.logs.stderr.join("\n"),
84
+ exitCode: execution.error ? 1 : 0,
85
+ executionTime: Date.now() - startTime,
86
+ sandboxId: this.sandboxId,
87
+ provider: this.provider
88
+ };
89
+ } catch (error) {
90
+ if (error instanceof Error) {
91
+ if (error.message.includes("timeout")) {
92
+ throw new Error(
93
+ `E2B execution timeout (${this.timeout}ms). Consider increasing the timeout or optimizing your code.`
94
+ );
95
+ }
96
+ if (error.message.includes("memory") || error.message.includes("Memory")) {
97
+ throw new Error(
98
+ `E2B execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`
99
+ );
100
+ }
101
+ }
102
+ throw new Error(
103
+ `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`
104
+ );
105
+ }
106
+ }
107
+ async doKill() {
108
+ if (!this.session) {
109
+ return;
110
+ }
111
+ try {
112
+ await this.session.kill();
113
+ this.session = null;
114
+ } catch (error) {
115
+ throw new Error(
116
+ `Failed to kill E2B session: ${error instanceof Error ? error.message : String(error)}`
117
+ );
118
+ }
119
+ }
120
+ async doGetInfo() {
121
+ await this.ensureSession();
122
+ return {
123
+ id: this.sandboxId,
124
+ provider: this.provider,
125
+ runtime: this.runtime,
126
+ status: this.session ? "running" : "stopped",
127
+ createdAt: /* @__PURE__ */ new Date(),
128
+ timeout: this.timeout,
129
+ metadata: {
130
+ e2bSessionId: this.sandboxId
131
+ }
132
+ };
133
+ }
134
+ };
135
+ function e2b(config) {
136
+ const fullConfig = {
137
+ provider: "e2b",
138
+ runtime: "python",
139
+ timeout: 3e5,
140
+ ...config
141
+ };
142
+ return new E2BProvider(fullConfig);
143
+ }
144
+ // Annotate the CommonJS export names for ESM import in node:
145
+ 0 && (module.exports = {
146
+ E2BProvider,
147
+ e2b
148
+ });
149
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Sandbox as E2BSandbox } from '@e2b/code-interpreter';\nimport type {\n ComputeSpecification,\n ExecutionResult,\n Runtime,\n SandboxInfo,\n SandboxConfig,\n} from 'computesdk';\n\nexport class E2BProvider implements ComputeSpecification {\n public readonly specificationVersion = 'v1' as const;\n public readonly provider = 'e2b';\n public readonly sandboxId: string;\n\n private session: E2BSandbox | null = null;\n private readonly apiKey: string;\n private readonly runtime: Runtime;\n private readonly timeout: number;\n\n constructor(config: SandboxConfig) {\n this.sandboxId = `e2b-${Date.now()}-${Math.random().toString(36).substring(7)}`;\n this.timeout = config.timeout || 300000;\n\n // Get API key from environment\n this.apiKey = process.env.E2B_API_KEY || '';\n\n if (!this.apiKey) {\n throw new Error(\n `Missing E2B API key. Set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!this.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 this.runtime = config.runtime || 'python';\n }\n\n private async ensureSession(): Promise<E2BSandbox> {\n if (this.session) {\n return this.session;\n }\n\n try {\n // Create new E2B session with configuration\n this.session = await E2BSandbox.create({\n apiKey: this.apiKey,\n timeoutMs: this.timeout,\n });\n\n return this.session;\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 initialize E2B session: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult> {\n const startTime = Date.now();\n\n try {\n const session = await this.ensureSession();\n\n // Execute code using E2B's runCode API\n const execution = await session.runCode(code);\n\n return {\n stdout: execution.logs.stdout.join('\\n'),\n stderr: execution.logs.stderr.join('\\n'),\n exitCode: execution.error ? 1 : 0,\n executionTime: Date.now() - startTime,\n sandboxId: this.sandboxId,\n provider: this.provider\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('timeout')) {\n throw new Error(\n `E2B execution timeout (${this.timeout}ms). Consider increasing the timeout or optimizing your code.`\n );\n }\n if (error.message.includes('memory') || error.message.includes('Memory')) {\n throw new Error(\n `E2B execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`\n );\n }\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async doKill(): Promise<void> {\n if (!this.session) {\n return;\n }\n\n try {\n await this.session.kill();\n this.session = null;\n } catch (error) {\n throw new Error(\n `Failed to kill E2B session: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async doGetInfo(): Promise<SandboxInfo> {\n await this.ensureSession();\n\n return {\n id: this.sandboxId,\n provider: this.provider,\n runtime: this.runtime,\n status: this.session ? 'running' : 'stopped',\n createdAt: new Date(),\n timeout: this.timeout,\n metadata: {\n e2bSessionId: this.sandboxId\n }\n };\n }\n}\n\nexport function e2b(config?: Partial<SandboxConfig>): E2BProvider {\n const fullConfig: SandboxConfig = {\n provider: 'e2b',\n runtime: 'python',\n timeout: 300000,\n ...config\n };\n\n return new E2BProvider(fullConfig);\n}\n"],"mappings":"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","names":["E2BSandbox"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,123 @@
1
+ // src/index.ts
2
+ import { Sandbox as E2BSandbox } from "@e2b/code-interpreter";
3
+ var E2BProvider = class {
4
+ constructor(config) {
5
+ this.specificationVersion = "v1";
6
+ this.provider = "e2b";
7
+ this.session = null;
8
+ this.sandboxId = `e2b-${Date.now()}-${Math.random().toString(36).substring(7)}`;
9
+ this.timeout = config.timeout || 3e5;
10
+ this.apiKey = process.env.E2B_API_KEY || "";
11
+ if (!this.apiKey) {
12
+ throw new Error(
13
+ `Missing E2B API key. Set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`
14
+ );
15
+ }
16
+ if (!this.apiKey.startsWith("e2b_")) {
17
+ throw new Error(
18
+ `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`
19
+ );
20
+ }
21
+ this.runtime = config.runtime || "python";
22
+ }
23
+ async ensureSession() {
24
+ if (this.session) {
25
+ return this.session;
26
+ }
27
+ try {
28
+ this.session = await E2BSandbox.create({
29
+ apiKey: this.apiKey,
30
+ timeoutMs: this.timeout
31
+ });
32
+ return this.session;
33
+ } catch (error) {
34
+ if (error instanceof Error) {
35
+ if (error.message.includes("unauthorized") || error.message.includes("API key")) {
36
+ throw new Error(
37
+ `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`
38
+ );
39
+ }
40
+ if (error.message.includes("quota") || error.message.includes("limit")) {
41
+ throw new Error(
42
+ `E2B quota exceeded. Please check your usage at https://e2b.dev/`
43
+ );
44
+ }
45
+ }
46
+ throw new Error(
47
+ `Failed to initialize E2B session: ${error instanceof Error ? error.message : String(error)}`
48
+ );
49
+ }
50
+ }
51
+ async doExecute(code, runtime) {
52
+ const startTime = Date.now();
53
+ try {
54
+ const session = await this.ensureSession();
55
+ const execution = await session.runCode(code);
56
+ return {
57
+ stdout: execution.logs.stdout.join("\n"),
58
+ stderr: execution.logs.stderr.join("\n"),
59
+ exitCode: execution.error ? 1 : 0,
60
+ executionTime: Date.now() - startTime,
61
+ sandboxId: this.sandboxId,
62
+ provider: this.provider
63
+ };
64
+ } catch (error) {
65
+ if (error instanceof Error) {
66
+ if (error.message.includes("timeout")) {
67
+ throw new Error(
68
+ `E2B execution timeout (${this.timeout}ms). Consider increasing the timeout or optimizing your code.`
69
+ );
70
+ }
71
+ if (error.message.includes("memory") || error.message.includes("Memory")) {
72
+ throw new Error(
73
+ `E2B execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`
74
+ );
75
+ }
76
+ }
77
+ throw new Error(
78
+ `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`
79
+ );
80
+ }
81
+ }
82
+ async doKill() {
83
+ if (!this.session) {
84
+ return;
85
+ }
86
+ try {
87
+ await this.session.kill();
88
+ this.session = null;
89
+ } catch (error) {
90
+ throw new Error(
91
+ `Failed to kill E2B session: ${error instanceof Error ? error.message : String(error)}`
92
+ );
93
+ }
94
+ }
95
+ async doGetInfo() {
96
+ await this.ensureSession();
97
+ return {
98
+ id: this.sandboxId,
99
+ provider: this.provider,
100
+ runtime: this.runtime,
101
+ status: this.session ? "running" : "stopped",
102
+ createdAt: /* @__PURE__ */ new Date(),
103
+ timeout: this.timeout,
104
+ metadata: {
105
+ e2bSessionId: this.sandboxId
106
+ }
107
+ };
108
+ }
109
+ };
110
+ function e2b(config) {
111
+ const fullConfig = {
112
+ provider: "e2b",
113
+ runtime: "python",
114
+ timeout: 3e5,
115
+ ...config
116
+ };
117
+ return new E2BProvider(fullConfig);
118
+ }
119
+ export {
120
+ E2BProvider,
121
+ e2b
122
+ };
123
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Sandbox as E2BSandbox } from '@e2b/code-interpreter';\nimport type {\n ComputeSpecification,\n ExecutionResult,\n Runtime,\n SandboxInfo,\n SandboxConfig,\n} from 'computesdk';\n\nexport class E2BProvider implements ComputeSpecification {\n public readonly specificationVersion = 'v1' as const;\n public readonly provider = 'e2b';\n public readonly sandboxId: string;\n\n private session: E2BSandbox | null = null;\n private readonly apiKey: string;\n private readonly runtime: Runtime;\n private readonly timeout: number;\n\n constructor(config: SandboxConfig) {\n this.sandboxId = `e2b-${Date.now()}-${Math.random().toString(36).substring(7)}`;\n this.timeout = config.timeout || 300000;\n\n // Get API key from environment\n this.apiKey = process.env.E2B_API_KEY || '';\n\n if (!this.apiKey) {\n throw new Error(\n `Missing E2B API key. Set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!this.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 this.runtime = config.runtime || 'python';\n }\n\n private async ensureSession(): Promise<E2BSandbox> {\n if (this.session) {\n return this.session;\n }\n\n try {\n // Create new E2B session with configuration\n this.session = await E2BSandbox.create({\n apiKey: this.apiKey,\n timeoutMs: this.timeout,\n });\n\n return this.session;\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 initialize E2B session: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult> {\n const startTime = Date.now();\n\n try {\n const session = await this.ensureSession();\n\n // Execute code using E2B's runCode API\n const execution = await session.runCode(code);\n\n return {\n stdout: execution.logs.stdout.join('\\n'),\n stderr: execution.logs.stderr.join('\\n'),\n exitCode: execution.error ? 1 : 0,\n executionTime: Date.now() - startTime,\n sandboxId: this.sandboxId,\n provider: this.provider\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('timeout')) {\n throw new Error(\n `E2B execution timeout (${this.timeout}ms). Consider increasing the timeout or optimizing your code.`\n );\n }\n if (error.message.includes('memory') || error.message.includes('Memory')) {\n throw new Error(\n `E2B execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`\n );\n }\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async doKill(): Promise<void> {\n if (!this.session) {\n return;\n }\n\n try {\n await this.session.kill();\n this.session = null;\n } catch (error) {\n throw new Error(\n `Failed to kill E2B session: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async doGetInfo(): Promise<SandboxInfo> {\n await this.ensureSession();\n\n return {\n id: this.sandboxId,\n provider: this.provider,\n runtime: this.runtime,\n status: this.session ? 'running' : 'stopped',\n createdAt: new Date(),\n timeout: this.timeout,\n metadata: {\n e2bSessionId: this.sandboxId\n }\n };\n }\n}\n\nexport function e2b(config?: Partial<SandboxConfig>): E2BProvider {\n const fullConfig: SandboxConfig = {\n provider: 'e2b',\n runtime: 'python',\n timeout: 300000,\n ...config\n };\n\n return new E2BProvider(fullConfig);\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@computesdk/e2b",
3
+ "version": "1.0.0",
4
+ "description": "E2B provider for ComputeSDK",
5
+ "author": "Garrison",
6
+ "license": "MIT",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "dependencies": {
21
+ "@e2b/code-interpreter": "^1.5.1"
22
+ },
23
+ "peerDependencies": {
24
+ "computesdk": "1.0.0"
25
+ },
26
+ "keywords": [
27
+ "e2b",
28
+ "sandbox",
29
+ "code-execution",
30
+ "python",
31
+ "cloud",
32
+ "compute"
33
+ ],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/computesdk/computesdk.git",
37
+ "directory": "packages/e2b"
38
+ },
39
+ "homepage": "https://github.com/computesdk/computesdk/tree/main/packages/e2b",
40
+ "bugs": {
41
+ "url": "https://github.com/computesdk/computesdk/issues"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^20.0.0",
45
+ "@vitest/coverage-v8": "^1.0.0",
46
+ "eslint": "^8.37.0",
47
+ "rimraf": "^5.0.0",
48
+ "tsup": "^8.0.0",
49
+ "typescript": "^5.0.0",
50
+ "vitest": "^1.0.0"
51
+ },
52
+ "scripts": {
53
+ "build": "tsup",
54
+ "clean": "rimraf dist",
55
+ "dev": "tsup --watch",
56
+ "test": "vitest",
57
+ "test:watch": "vitest watch",
58
+ "test:coverage": "vitest run --coverage",
59
+ "typecheck": "tsc --noEmit",
60
+ "lint": "eslint ."
61
+ }
62
+ }