@sandagent/sandbox-e2b 0.1.0-beta.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/README.md ADDED
@@ -0,0 +1,228 @@
1
+ # @sandagent/sandbox-e2b
2
+
3
+ E2B sandbox adapter for SandAgent - run agents in secure cloud sandboxes.
4
+
5
+ ## Overview
6
+
7
+ `@sandagent/sandbox-e2b` provides an E2B-based sandbox implementation for SandAgent. E2B offers secure, isolated cloud environments with:
8
+
9
+ - Fast startup times
10
+ - Persistent storage (up to 30 days when paused)
11
+ - Sandbox reuse by name
12
+ - Support for custom templates
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @sandagent/sandbox-e2b @sandagent/manager
18
+ ```
19
+
20
+ You'll also need an E2B API key. Sign up at [e2b.dev](https://e2b.dev) to get one.
21
+
22
+ ## Quick Start
23
+
24
+ ```typescript
25
+ import { E2BSandbox } from '@sandagent/sandbox-e2b';
26
+ import { SandAgent } from '@sandagent/manager';
27
+
28
+ // Create sandbox adapter
29
+ // Runner is automatically downloaded from npm if runnerBundlePath is not provided
30
+ const sandbox = new E2BSandbox({
31
+ apiKey: process.env.E2B_API_KEY!,
32
+ template: 'base', // E2B template ID
33
+ env: {
34
+ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
35
+ },
36
+ });
37
+
38
+ // Use with SandAgent
39
+ const agent = new SandAgent({
40
+ sandbox,
41
+ runner: {
42
+ kind: 'claude-agent-sdk',
43
+ model: 'claude-sonnet-4-20250514',
44
+ outputFormat: 'stream',
45
+ },
46
+ env: {
47
+ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
48
+ },
49
+ });
50
+
51
+ const stream = await agent.stream({
52
+ messages: [{ role: 'user', content: 'Hello!' }],
53
+ workspace: { path: '/workspace' },
54
+ });
55
+ ```
56
+
57
+ ## Usage with AI Provider
58
+
59
+ ```typescript
60
+ import { createSandAgent } from '@sandagent/ai-provider';
61
+ import { E2BSandbox } from '@sandagent/sandbox-e2b';
62
+ import { generateText } from 'ai';
63
+
64
+ // Runner is automatically downloaded from npm
65
+ const sandagent = createSandAgent({
66
+ sandbox: new E2BSandbox({
67
+ apiKey: process.env.E2B_API_KEY!,
68
+ }),
69
+ env: {
70
+ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
71
+ },
72
+ });
73
+
74
+ const { text } = await generateText({
75
+ model: sandagent('sonnet'),
76
+ prompt: 'Create a hello world program',
77
+ });
78
+ ```
79
+
80
+ ## Configuration Options
81
+
82
+ ### E2BSandboxOptions
83
+
84
+ ```typescript
85
+ interface E2BSandboxOptions {
86
+ // Required: E2B API key (or set E2B_API_KEY env var)
87
+ apiKey?: string;
88
+
89
+ // E2B template to use (default: "base")
90
+ template?: string;
91
+
92
+ // Sandbox timeout in seconds (default: 3600 = 1 hour)
93
+ // Hobby tier: max 1 hour, Pro tier: max 24 hours
94
+ timeout?: number;
95
+
96
+ // Path to runner bundle.mjs (optional)
97
+ // If not provided, automatically downloads @sandagent/runner-cli from npm
98
+ runnerBundlePath?: string;
99
+
100
+ // Path to template directory to upload
101
+ templatesPath?: string;
102
+
103
+ // Sandbox name for reuse (optional)
104
+ // If provided, will try to find existing sandbox by name
105
+ name?: string;
106
+
107
+ // Environment variables for the sandbox
108
+ env?: Record<string, string>;
109
+
110
+ // Agent template (default, coder, analyst, researcher)
111
+ agentTemplate?: string;
112
+
113
+ // Working directory inside sandbox (default: '/workspace')
114
+ workdir?: string;
115
+ }
116
+ ```
117
+
118
+ ## Sandbox Reuse
119
+
120
+ E2B supports sandbox persistence and reuse:
121
+
122
+ ```typescript
123
+ const sandbox = new E2BSandbox({
124
+ apiKey: process.env.E2B_API_KEY!,
125
+ name: 'my-project-sandbox', // Unique name for this sandbox
126
+ // runnerBundlePath is optional - runner is auto-downloaded from npm
127
+ });
128
+
129
+ // First call: creates new sandbox
130
+ await sandbox.attach();
131
+
132
+ // Later calls: reuses existing sandbox by name
133
+ await sandbox.attach();
134
+ ```
135
+
136
+ **E2B Limitations (Beta):**
137
+ - Sandbox can be paused for up to 30 days
138
+ - Continuous runtime limits:
139
+ - Hobby tier: max 1 hour
140
+ - Pro tier: max 24 hours
141
+ - See: https://e2b.dev/docs/sandbox/persistence
142
+
143
+ ## Advanced Usage
144
+
145
+ ### Custom Templates
146
+
147
+ Upload your own templates to the sandbox:
148
+
149
+ ```typescript
150
+ const sandbox = new E2BSandbox({
151
+ apiKey: process.env.E2B_API_KEY!,
152
+ // runnerBundlePath is optional - runner is auto-downloaded from npm
153
+ templatesPath: './templates/coder', // Upload custom template files
154
+ agentTemplate: 'coder',
155
+ });
156
+ ```
157
+
158
+ ### Multiple Sandboxes
159
+
160
+ ```typescript
161
+ // Development sandbox
162
+ const devSandbox = new E2BSandbox({
163
+ apiKey: process.env.E2B_API_KEY!,
164
+ name: 'dev-sandbox',
165
+ });
166
+
167
+ // Production sandbox
168
+ const prodSandbox = new E2BSandbox({
169
+ apiKey: process.env.E2B_API_KEY!,
170
+ name: 'prod-sandbox',
171
+ timeout: 86400, // 24 hours (Pro tier)
172
+ });
173
+ ```
174
+
175
+ ## Environment Variables
176
+
177
+ The sandbox accepts environment variables that will be available to all commands:
178
+
179
+ ```typescript
180
+ const sandbox = new E2BSandbox({
181
+ apiKey: process.env.E2B_API_KEY!,
182
+ env: {
183
+ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
184
+ GITHUB_TOKEN: process.env.GITHUB_TOKEN,
185
+ DATABASE_URL: process.env.DATABASE_URL,
186
+ },
187
+ });
188
+ ```
189
+
190
+ ## Requirements
191
+
192
+ - Node.js 20+
193
+ - E2B API key (get one at [e2b.dev](https://e2b.dev))
194
+ - `@sandagent/manager` package
195
+
196
+ **Note:** `@sandagent/runner-cli` is automatically downloaded from npm when the sandbox initializes. You don't need to install it locally unless you want to use a custom bundle.
197
+
198
+ ## API Reference
199
+
200
+ ### E2BSandbox
201
+
202
+ Implements the `SandboxAdapter` interface from `@sandagent/manager`.
203
+
204
+ #### Methods
205
+
206
+ **attach(): Promise<SandboxHandle>**
207
+
208
+ Attaches to an E2B sandbox. If a name is provided and a sandbox with that name exists, connects to it. Otherwise, creates a new sandbox.
209
+
210
+ **getHandle(): SandboxHandle | null**
211
+
212
+ Returns the current sandbox handle if attached, null otherwise.
213
+
214
+ **getEnv(): Record<string, string>**
215
+
216
+ Returns the environment variables configured for this sandbox.
217
+
218
+ **getAgentTemplate(): string**
219
+
220
+ Returns the agent template name.
221
+
222
+ **getWorkdir(): string**
223
+
224
+ Returns the working directory path.
225
+
226
+ ## License
227
+
228
+ Apache-2.0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=e2b-sandbox.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e2b-sandbox.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/e2b-sandbox.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,262 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { E2BSandbox } from "../e2b-sandbox.js";
3
+ describe("E2BSandbox", () => {
4
+ const originalEnv = process.env;
5
+ beforeEach(() => {
6
+ process.env = { ...originalEnv };
7
+ vi.clearAllMocks();
8
+ });
9
+ afterEach(() => {
10
+ process.env = originalEnv;
11
+ });
12
+ describe("constructor", () => {
13
+ it("should create an instance with default options", () => {
14
+ const sandbox = new E2BSandbox();
15
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
16
+ });
17
+ it("should accept custom options", () => {
18
+ const sandbox = new E2BSandbox({
19
+ apiKey: "test-api-key",
20
+ template: "python",
21
+ timeout: 7200, // 2 hours in seconds
22
+ });
23
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
24
+ });
25
+ it("should use E2B_API_KEY from environment", () => {
26
+ process.env.E2B_API_KEY = "env-api-key";
27
+ const sandbox = new E2BSandbox();
28
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
29
+ });
30
+ it("should accept name option for sandbox reuse", () => {
31
+ const sandbox = new E2BSandbox({
32
+ apiKey: "test-api-key",
33
+ name: "my-sandbox",
34
+ template: "base",
35
+ });
36
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
37
+ });
38
+ });
39
+ describe("attach", () => {
40
+ it("should implement SandboxAdapter interface", () => {
41
+ const sandbox = new E2BSandbox();
42
+ expect(typeof sandbox.attach).toBe("function");
43
+ });
44
+ it("should throw error when E2B_API_KEY is not set", async () => {
45
+ // Remove API key to test error handling
46
+ delete process.env.E2B_API_KEY;
47
+ const sandbox = new E2BSandbox();
48
+ // Should throw an error about missing API key
49
+ await expect(sandbox.attach()).rejects.toThrow(/E2B API key not found/);
50
+ console.log("[Test Info] E2B_API_KEY not set - this test verifies proper error handling.\n" +
51
+ "To run integration tests with E2B, set E2B_API_KEY environment variable.");
52
+ });
53
+ it("should throw error when SDK is not installed (with API key set)", async () => {
54
+ // Set API key but SDK won't be installed in test environment
55
+ process.env.E2B_API_KEY = "test-api-key";
56
+ const sandbox = new E2BSandbox();
57
+ // Should throw an error (SDK not found or auth error)
58
+ try {
59
+ await sandbox.attach();
60
+ // If we get here, the SDK is installed - that's also valid
61
+ console.log("[Test Info] E2B SDK is installed. Integration tests would run with valid API key.");
62
+ }
63
+ catch (error) {
64
+ expect(error).toBeDefined();
65
+ const errorMessage = error instanceof Error ? error.message : String(error);
66
+ // Either SDK not found or API error is expected
67
+ console.log(`[Test Info] Expected error: ${errorMessage}\n` +
68
+ "Install e2b package to enable E2B sandbox: npm install e2b");
69
+ }
70
+ });
71
+ });
72
+ });
73
+ describe("E2BSandbox Configuration", () => {
74
+ it("should support different templates", () => {
75
+ const templates = ["base", "python", "nodejs", "code-interpreter"];
76
+ for (const template of templates) {
77
+ const sandbox = new E2BSandbox({ template });
78
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
79
+ }
80
+ });
81
+ it("should support custom timeouts in seconds", () => {
82
+ // E2B timeout is now in seconds (for API clarity)
83
+ const timeouts = [1800, 3600, 7200, 86400]; // 30min, 1hr, 2hr, 24hr
84
+ for (const timeout of timeouts) {
85
+ const sandbox = new E2BSandbox({ timeout });
86
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
87
+ }
88
+ });
89
+ it("should support name for sandbox reuse", () => {
90
+ const names = ["sandbox-1", "my-project-sandbox", "user-123-sandbox"];
91
+ for (const name of names) {
92
+ const sandbox = new E2BSandbox({ name });
93
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
94
+ }
95
+ });
96
+ it("should use name for sandbox identification (business-defined)", () => {
97
+ // Name is determined by business layer and can include template info if needed
98
+ const sandbox1 = new E2BSandbox({
99
+ name: "project-base-user123",
100
+ template: "base",
101
+ });
102
+ const sandbox2 = new E2BSandbox({
103
+ name: "project-python-user123",
104
+ template: "python",
105
+ });
106
+ expect(sandbox1).toBeInstanceOf(E2BSandbox);
107
+ expect(sandbox2).toBeInstanceOf(E2BSandbox);
108
+ // Different names means different sandboxes
109
+ });
110
+ });
111
+ describe("E2BSandbox Name-based Reuse", () => {
112
+ it("should support all options together", () => {
113
+ const sandbox = new E2BSandbox({
114
+ apiKey: "test-key",
115
+ template: "nodejs",
116
+ timeout: 3600,
117
+ name: "my-project",
118
+ runnerBundlePath: "/path/to/runner.js",
119
+ templatesPath: "/path/to/templates",
120
+ });
121
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
122
+ });
123
+ it("should create sandbox without name (no reuse)", () => {
124
+ // When no name is provided, a new sandbox is always created
125
+ const sandbox = new E2BSandbox({
126
+ apiKey: "test-key",
127
+ template: "base",
128
+ });
129
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
130
+ });
131
+ it("should support name with special characters", () => {
132
+ const sandbox = new E2BSandbox({
133
+ name: "project-user_123-dev",
134
+ });
135
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
136
+ });
137
+ });
138
+ describe("E2BSandbox Timeout Configuration", () => {
139
+ it("should default to 1 hour (3600 seconds)", () => {
140
+ // The default timeout aligns with E2B hobby tier limits
141
+ const sandbox = new E2BSandbox();
142
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
143
+ });
144
+ it("should accept timeout for pro tier (up to 24 hours)", () => {
145
+ // Pro tier supports up to 24 hours continuous runtime
146
+ const sandbox = new E2BSandbox({
147
+ timeout: 86400, // 24 hours in seconds
148
+ });
149
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
150
+ });
151
+ it("should handle short timeouts", () => {
152
+ const sandbox = new E2BSandbox({
153
+ timeout: 300, // 5 minutes
154
+ });
155
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
156
+ });
157
+ });
158
+ describe("E2BSandbox Metadata Usage", () => {
159
+ it("should document metadata fields used for querying", () => {
160
+ // The sandbox uses these metadata fields:
161
+ // - sandagentId: The session/agent ID
162
+ // - sandagentName: The sandbox name for reuse (if provided, business-defined)
163
+ const sandbox = new E2BSandbox({
164
+ name: "my-project-python-user123", // Name includes all info needed for identification
165
+ template: "python",
166
+ });
167
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
168
+ // When creating, metadata will include:
169
+ // { sandagentId: "...", sandagentName: "my-project-python-user123" }
170
+ // The name is used for sandbox reuse, determined by business layer
171
+ });
172
+ });
173
+ describe("E2BSandbox Reuse", () => {
174
+ beforeEach(() => {
175
+ process.env.E2B_API_KEY = "test-api-key";
176
+ });
177
+ it("should return same handle when attach() is called multiple times", async () => {
178
+ const sandbox = new E2BSandbox({
179
+ name: "test-reuse-sandbox",
180
+ });
181
+ try {
182
+ const handle1 = await sandbox.attach();
183
+ const handle2 = await sandbox.attach();
184
+ // Should return the same handle instance (cached in currentHandle)
185
+ expect(handle1).toBe(handle2);
186
+ expect(sandbox.getHandle()).toBe(handle1);
187
+ }
188
+ catch (error) {
189
+ // Expected in test environment without real API
190
+ expect(error).toBeDefined();
191
+ console.log("[Test Info] E2B API not available - test verifies reuse logic structure");
192
+ }
193
+ });
194
+ it("should skip initialization when reusing existing sandbox", async () => {
195
+ // This test verifies the reuse logic
196
+ // In a real scenario with E2B API, it would:
197
+ // 1. First call: create new sandbox, needsInit = true
198
+ // 2. Second call (different instance, same name): find existing, needsInit = false
199
+ const sandbox1 = new E2BSandbox({
200
+ name: "test-sandbox-reuse",
201
+ });
202
+ // First attach - would create new sandbox
203
+ try {
204
+ const handle1 = await sandbox1.attach();
205
+ expect(handle1).toBeDefined();
206
+ // If successful, sandbox was created
207
+ }
208
+ catch (error) {
209
+ // Expected in test environment without real API
210
+ expect(error).toBeDefined();
211
+ console.log("[Test Info] E2B API not available - test verifies reuse logic structure");
212
+ }
213
+ });
214
+ it("should create new sandbox when name is not provided", async () => {
215
+ const sandbox1 = new E2BSandbox({
216
+ // No name provided
217
+ });
218
+ const sandbox2 = new E2BSandbox({
219
+ // No name provided
220
+ });
221
+ // Both should be able to attach (would create different sandboxes)
222
+ // In test environment, this will fail without real API, but structure is correct
223
+ expect(sandbox1).toBeInstanceOf(E2BSandbox);
224
+ expect(sandbox2).toBeInstanceOf(E2BSandbox);
225
+ });
226
+ it("should use name for sandbox identification", () => {
227
+ const sandboxName = "my-project-sandbox";
228
+ const sandbox = new E2BSandbox({
229
+ name: sandboxName,
230
+ });
231
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
232
+ // The name is stored and used in attach() to find existing sandbox
233
+ });
234
+ it("should support template-based naming strategy", () => {
235
+ const template = "default";
236
+ const sandboxName = `sandagent-${template}`;
237
+ const sandbox = new E2BSandbox({
238
+ name: sandboxName,
239
+ template,
240
+ });
241
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
242
+ // This matches the pattern used in route.ts
243
+ });
244
+ it("should support user-session-based naming strategy", () => {
245
+ const userId = "user-123";
246
+ const sessionId = "session-456";
247
+ const sandboxName = `user-${userId}-session-${sessionId}`;
248
+ const sandbox = new E2BSandbox({
249
+ name: sandboxName,
250
+ });
251
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
252
+ });
253
+ it("should support project-based naming strategy", () => {
254
+ const projectId = "project-789";
255
+ const sandboxName = `project-${projectId}`;
256
+ const sandbox = new E2BSandbox({
257
+ name: sandboxName,
258
+ });
259
+ expect(sandbox).toBeInstanceOf(E2BSandbox);
260
+ });
261
+ });
262
+ //# sourceMappingURL=e2b-sandbox.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e2b-sandbox.test.js","sourceRoot":"","sources":["../../src/__tests__/e2b-sandbox.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ import type { SandboxAdapter, SandboxHandle } from "@sandagent/manager";
2
+ /**
3
+ * Options for creating an E2BSandbox instance
4
+ */
5
+ export interface E2BSandboxOptions {
6
+ /** E2B API key (defaults to E2B_API_KEY env var) */
7
+ apiKey?: string;
8
+ /** E2B template to use (default: "base") */
9
+ template?: string;
10
+ /**
11
+ * Timeout for sandbox in seconds.
12
+ * This is the maximum time the sandbox can run continuously.
13
+ * - Hobby tier: max 1 hour (3600s)
14
+ * - Pro tier: max 24 hours (86400s)
15
+ * Default: 3600 (1 hour)
16
+ *
17
+ * Note: Sandbox can be paused for up to 30 days with E2B's persistence feature.
18
+ */
19
+ timeout?: number;
20
+ /** Path to runner bundle.js (required for running sandagent) */
21
+ runnerBundlePath?: string;
22
+ /** Path to template directory to upload */
23
+ templatesPath?: string;
24
+ /**
25
+ * Sandbox name for reuse (similar to Daytona).
26
+ * If provided, will try to find an existing sandbox by name (via metadata) first.
27
+ * If not found, creates a new sandbox with this name stored in metadata.
28
+ * If not provided, a new sandbox is always created.
29
+ *
30
+ * The name should be determined by the business layer and can include
31
+ * template/user/project information as needed for differentiation.
32
+ */
33
+ name?: string;
34
+ /**
35
+ * Environment variables to set in the sandbox.
36
+ * These will be available to all commands executed in the sandbox.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * env: {
41
+ * ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
42
+ * GITHUB_TOKEN: process.env.GITHUB_TOKEN,
43
+ * }
44
+ * ```
45
+ */
46
+ env?: Record<string, string>;
47
+ /**
48
+ * Agent template to use (e.g., "default", "coder", "analyst", "researcher").
49
+ * This is different from the E2B sandbox template.
50
+ *
51
+ * @default 'default'
52
+ */
53
+ agentTemplate?: string;
54
+ /**
55
+ * Working directory for the agent inside the sandbox.
56
+ * Will be created if it doesn't exist.
57
+ *
58
+ * @default '/workspace'
59
+ */
60
+ workdir?: string;
61
+ }
62
+ /**
63
+ * E2B-based sandbox implementation.
64
+ *
65
+ * This adapter supports sandbox reuse based on sandbox name (similar to Daytona).
66
+ * When a name is provided, it will attempt to find an existing sandbox
67
+ * by that name (stored in metadata) first. If not found, creates a new sandbox
68
+ * with that name in metadata.
69
+ *
70
+ * If no name is provided, a new sandbox is always created.
71
+ *
72
+ * Note on E2B limitations (as of beta):
73
+ * - Sandbox can be paused for up to 30 days
74
+ * - Continuous runtime depends on tier:
75
+ * - Hobby: max 1 hour
76
+ * - Pro: max 24 hours
77
+ * - See: https://e2b.dev/docs/sandbox/persistence#limitations-while-in-beta
78
+ */
79
+ export declare class E2BSandbox implements SandboxAdapter {
80
+ private readonly apiKey?;
81
+ private readonly template;
82
+ private readonly timeout;
83
+ private readonly runnerBundlePath?;
84
+ private readonly templatesPath?;
85
+ private readonly name?;
86
+ private readonly env;
87
+ private readonly agentTemplate;
88
+ private readonly workdir;
89
+ /** Current handle for the sandbox instance */
90
+ private currentHandle;
91
+ /** Default timeout in seconds (1 hour for hobby tier) */
92
+ private static readonly DEFAULT_TIMEOUT_SEC;
93
+ /** Custom template prefix - templates starting with this have pre-installed dependencies */
94
+ private static readonly CUSTOM_TEMPLATE_PREFIX;
95
+ constructor(options?: E2BSandboxOptions);
96
+ /** Default E2B templates that don't have pre-installed dependencies */
97
+ private static readonly DEFAULT_TEMPLATES;
98
+ /**
99
+ * Check if using a custom sandagent template with pre-installed dependencies.
100
+ * Custom templates either:
101
+ * - Start with "sandagent" prefix (alias)
102
+ * - Are not in the default templates list (template ID)
103
+ */
104
+ private isCustomTemplate;
105
+ /**
106
+ * Get the environment variables configured for this sandbox.
107
+ */
108
+ getEnv(): Record<string, string>;
109
+ /**
110
+ * Get the agent template configured for this sandbox.
111
+ */
112
+ getAgentTemplate(): string;
113
+ /**
114
+ * Get the working directory configured for this sandbox.
115
+ */
116
+ getWorkdir(): string;
117
+ /**
118
+ * Get the runner command to execute in the sandbox.
119
+ * Returns different commands based on whether a local bundle or npm package is used.
120
+ */
121
+ getRunnerCommand(): string[];
122
+ /**
123
+ * Find an existing sandbox by name and connect to it.
124
+ * Sandbox.connect() will automatically resume if paused.
125
+ * See: https://e2b.dev/docs/sandbox/persistence
126
+ *
127
+ * @returns Connected sandbox instance if found, null otherwise
128
+ */
129
+ private findSandboxByName;
130
+ getHandle(): SandboxHandle | null;
131
+ attach(): Promise<SandboxHandle>;
132
+ /**
133
+ * Create a new sandbox with metadata for later querying
134
+ */
135
+ private createNewSandbox;
136
+ private initializeSandbox;
137
+ private collectFiles;
138
+ }
139
+ //# sourceMappingURL=e2b-sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e2b-sandbox.d.ts","sourceRoot":"","sources":["../src/e2b-sandbox.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EACd,aAAa,EACd,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,UAAW,YAAW,cAAc;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,8CAA8C;IAC9C,OAAO,CAAC,aAAa,CAA8B;IAEnD,yDAAyD;IACzD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAQ;IAEnD,4FAA4F;IAC5F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAe;gBAEjD,OAAO,GAAE,iBAAsB;IAa3C,uEAAuE;IACvE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAmC;IAE5E;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIhC;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;;OAGG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAa5B;;;;;;OAMG;YACW,iBAAiB;IAyC/B,SAAS,IAAI,aAAa,GAAG,IAAI;IAI3B,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;IAqDtC;;OAEG;YACW,gBAAgB;YAyBhB,iBAAiB;IAkH/B,OAAO,CAAC,YAAY;CA2BrB"}
@@ -0,0 +1,544 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { Sandbox } from "e2b";
4
+ /**
5
+ * E2B-based sandbox implementation.
6
+ *
7
+ * This adapter supports sandbox reuse based on sandbox name (similar to Daytona).
8
+ * When a name is provided, it will attempt to find an existing sandbox
9
+ * by that name (stored in metadata) first. If not found, creates a new sandbox
10
+ * with that name in metadata.
11
+ *
12
+ * If no name is provided, a new sandbox is always created.
13
+ *
14
+ * Note on E2B limitations (as of beta):
15
+ * - Sandbox can be paused for up to 30 days
16
+ * - Continuous runtime depends on tier:
17
+ * - Hobby: max 1 hour
18
+ * - Pro: max 24 hours
19
+ * - See: https://e2b.dev/docs/sandbox/persistence#limitations-while-in-beta
20
+ */
21
+ export class E2BSandbox {
22
+ apiKey;
23
+ template;
24
+ timeout;
25
+ runnerBundlePath;
26
+ templatesPath;
27
+ name;
28
+ env;
29
+ agentTemplate;
30
+ workdir;
31
+ /** Current handle for the sandbox instance */
32
+ currentHandle = null;
33
+ /** Default timeout in seconds (1 hour for hobby tier) */
34
+ static DEFAULT_TIMEOUT_SEC = 3600;
35
+ /** Custom template prefix - templates starting with this have pre-installed dependencies */
36
+ static CUSTOM_TEMPLATE_PREFIX = "sandagent";
37
+ constructor(options = {}) {
38
+ this.apiKey = options.apiKey ?? process.env.E2B_API_KEY;
39
+ this.template = options.template ?? "base";
40
+ // Default to 1 hour (hobby tier limit), convert to milliseconds for E2B SDK
41
+ this.timeout = (options.timeout ?? E2BSandbox.DEFAULT_TIMEOUT_SEC) * 1000;
42
+ this.runnerBundlePath = options.runnerBundlePath;
43
+ this.templatesPath = options.templatesPath;
44
+ this.name = options.name;
45
+ this.env = options.env ?? {};
46
+ this.agentTemplate = options.agentTemplate ?? "default";
47
+ this.workdir = options.workdir ?? "/workspace";
48
+ }
49
+ /** Default E2B templates that don't have pre-installed dependencies */
50
+ static DEFAULT_TEMPLATES = ["base", "code-interpreter-v1"];
51
+ /**
52
+ * Check if using a custom sandagent template with pre-installed dependencies.
53
+ * Custom templates either:
54
+ * - Start with "sandagent" prefix (alias)
55
+ * - Are not in the default templates list (template ID)
56
+ */
57
+ isCustomTemplate() {
58
+ // If starts with sandagent prefix, it's definitely custom
59
+ if (this.template.startsWith(E2BSandbox.CUSTOM_TEMPLATE_PREFIX)) {
60
+ return true;
61
+ }
62
+ // If not a known default template, assume it's a custom template ID
63
+ return !E2BSandbox.DEFAULT_TEMPLATES.includes(this.template);
64
+ }
65
+ /**
66
+ * Get the environment variables configured for this sandbox.
67
+ */
68
+ getEnv() {
69
+ return this.env;
70
+ }
71
+ /**
72
+ * Get the agent template configured for this sandbox.
73
+ */
74
+ getAgentTemplate() {
75
+ return this.agentTemplate;
76
+ }
77
+ /**
78
+ * Get the working directory configured for this sandbox.
79
+ */
80
+ getWorkdir() {
81
+ return this.workdir;
82
+ }
83
+ /**
84
+ * Get the runner command to execute in the sandbox.
85
+ * Returns different commands based on whether a local bundle or npm package is used.
86
+ */
87
+ getRunnerCommand() {
88
+ if (this.runnerBundlePath && fs.existsSync(this.runnerBundlePath)) {
89
+ // Local bundle is uploaded to ${workdir}/runner/bundle.mjs
90
+ return ["node", `${this.workdir}/runner/bundle.mjs`, "run"];
91
+ }
92
+ if (this.isCustomTemplate()) {
93
+ // Custom template has sandagent as system command in /usr/local/bin
94
+ return ["sandagent", "run"];
95
+ }
96
+ // npm installed runner-cli in workspace
97
+ return [`${this.workdir}/node_modules/.bin/sandagent`, "run"];
98
+ }
99
+ /**
100
+ * Find an existing sandbox by name and connect to it.
101
+ * Sandbox.connect() will automatically resume if paused.
102
+ * See: https://e2b.dev/docs/sandbox/persistence
103
+ *
104
+ * @returns Connected sandbox instance if found, null otherwise
105
+ */
106
+ async findSandboxByName(name) {
107
+ try {
108
+ // Use Sandbox.list() with metadata query
109
+ const paginator = Sandbox.list({
110
+ apiKey: this.apiKey,
111
+ query: {
112
+ metadata: {
113
+ sandagentName: name,
114
+ },
115
+ },
116
+ });
117
+ // Get the first page of results
118
+ const sandboxes = await paginator.nextItems();
119
+ if (sandboxes.length === 0) {
120
+ console.log(`[E2B] No existing sandbox found for name: ${name}`);
121
+ return null;
122
+ }
123
+ const sandboxInfo = sandboxes[0];
124
+ console.log(`[E2B] Found existing sandbox by name: ${name}, id: ${sandboxInfo.sandboxId}, state: ${sandboxInfo.state}`);
125
+ // Connect to sandbox (will auto-resume if paused)
126
+ const sandbox = await Sandbox.connect(sandboxInfo.sandboxId, {
127
+ apiKey: this.apiKey,
128
+ timeoutMs: this.timeout,
129
+ });
130
+ console.log(`[E2B] Successfully connected to sandbox: ${sandboxInfo.sandboxId}`);
131
+ return sandbox;
132
+ }
133
+ catch (error) {
134
+ console.warn(`[E2B] Failed to find/connect sandbox by name:`, error);
135
+ return null;
136
+ }
137
+ }
138
+ getHandle() {
139
+ return this.currentHandle;
140
+ }
141
+ async attach() {
142
+ if (!this.apiKey) {
143
+ throw new Error("E2B API key not found. Please set E2B_API_KEY environment variable or pass apiKey option.");
144
+ }
145
+ // Return existing handle if already attached
146
+ if (this.currentHandle) {
147
+ return this.currentHandle;
148
+ }
149
+ let instance;
150
+ let needsInit = false;
151
+ // Use this.name if provided
152
+ const sandboxName = this.name;
153
+ // If name is provided, try to find and connect to existing sandbox
154
+ if (sandboxName) {
155
+ console.log(`[E2B] Looking for existing sandbox with name: ${sandboxName}`);
156
+ const existingSandbox = await this.findSandboxByName(sandboxName);
157
+ if (existingSandbox) {
158
+ instance = existingSandbox;
159
+ }
160
+ else {
161
+ // No existing sandbox found or connection failed, create new one
162
+ instance = await this.createNewSandbox(sandboxName);
163
+ needsInit = true;
164
+ }
165
+ }
166
+ else {
167
+ // No name provided - always create new sandbox
168
+ console.log(`[E2B] No name provided, creating new sandbox`);
169
+ instance = await this.createNewSandbox();
170
+ needsInit = true;
171
+ }
172
+ const handle = new E2BHandle(instance, this.env);
173
+ // Initialize sandbox if it's new (upload files, install dependencies)
174
+ if (needsInit) {
175
+ await this.initializeSandbox(handle);
176
+ }
177
+ // Store the handle
178
+ this.currentHandle = handle;
179
+ return handle;
180
+ }
181
+ /**
182
+ * Create a new sandbox with metadata for later querying
183
+ */
184
+ async createNewSandbox(name) {
185
+ const metadata = {};
186
+ // Use provided name or fallback to this.name
187
+ const sandboxName = name || this.name;
188
+ // Add name to metadata if provided (for sandbox reuse)
189
+ if (sandboxName) {
190
+ metadata.sandagentName = sandboxName;
191
+ }
192
+ console.log(`[E2B] Creating new sandbox with template "${this.template}"${sandboxName ? `, name "${sandboxName}"` : ""}, timeout=${this.timeout / 1000}s`);
193
+ const instance = await Sandbox.create(this.template, {
194
+ apiKey: this.apiKey,
195
+ timeoutMs: this.timeout,
196
+ metadata,
197
+ });
198
+ console.log(`[E2B] Sandbox created: ${instance.sandboxId}`);
199
+ return instance;
200
+ }
201
+ async initializeSandbox(handle) {
202
+ // Step 0: Create workspace directory using E2B file API
203
+ console.log(`[E2B] Creating workspace directory: ${this.workdir}`);
204
+ try {
205
+ await handle.getInstance().files.makeDir(this.workdir);
206
+ }
207
+ catch (err) {
208
+ // Directory might already exist, ignore
209
+ console.log(`[E2B] mkdir warning (may already exist): ${err}`);
210
+ }
211
+ // If using custom template with pre-installed dependencies, skip npm installs
212
+ if (this.isCustomTemplate()) {
213
+ console.log(`[E2B] Using custom template "${this.template}", skipping dependency installs`);
214
+ // Ensure workspace has correct permissions
215
+ try {
216
+ await handle.runCommand(`chmod 777 ${this.workdir} 2>/dev/null || true`);
217
+ }
218
+ catch {
219
+ // Ignore permission errors
220
+ }
221
+ // Copy template files from /opt/sandagent/templates if exists (similar to Daytona)
222
+ try {
223
+ const copyTemplateResult = await handle.runCommand(`if [ -d "/opt/sandagent/templates" ]; then ` +
224
+ `cp -r /opt/sandagent/templates/. ${this.workdir}/ 2>&1 && ` +
225
+ `echo "Template files copied"; ` +
226
+ `else echo "No templates in image"; fi`);
227
+ if (copyTemplateResult.stdout) {
228
+ console.log(`[E2B] ${copyTemplateResult.stdout.trim()}`);
229
+ }
230
+ }
231
+ catch (err) {
232
+ const error = err;
233
+ console.log(`[E2B] Template copy warning: ${error.result?.stderr || error.result?.stdout || "unknown error"}`);
234
+ // Not fatal - templates might be uploaded via templatesPath instead
235
+ }
236
+ }
237
+ else {
238
+ // Step 1: Install claude-agent-sdk to workspace
239
+ console.log(`[E2B] Installing @anthropic-ai/claude-agent-sdk to ${this.workdir}`);
240
+ const sdkInstallResult = await handle.runCommand(`cd ${this.workdir} && npm install @anthropic-ai/claude-agent-sdk`);
241
+ if (sdkInstallResult.exitCode !== 0) {
242
+ console.error(`[E2B] Failed to install claude-agent-sdk: ${sdkInstallResult.stderr}`);
243
+ throw new Error(`Failed to install @anthropic-ai/claude-agent-sdk: ${sdkInstallResult.stderr}`);
244
+ }
245
+ }
246
+ // Step 2: Setup runner - either upload local bundle, use pre-installed, or install from npm
247
+ if (this.runnerBundlePath && fs.existsSync(this.runnerBundlePath)) {
248
+ // Option A: Upload local runner bundle to workspace
249
+ const bundleContent = fs.readFileSync(this.runnerBundlePath);
250
+ const bundleFileName = path.basename(this.runnerBundlePath);
251
+ const runnerFiles = [
252
+ {
253
+ path: `runner/${bundleFileName}`,
254
+ content: bundleContent,
255
+ },
256
+ ];
257
+ console.log(`[E2B] Uploading runner bundle (${bundleFileName}) to ${this.workdir}`);
258
+ await handle.upload(runnerFiles, this.workdir);
259
+ console.log(`[E2B] Runner bundle uploaded`);
260
+ }
261
+ else if (this.isCustomTemplate()) {
262
+ // Option B: Using custom template - runner-cli is pre-installed
263
+ console.log(`[E2B] Using pre-installed runner-cli from template`);
264
+ }
265
+ else {
266
+ // Option C: Install runner-cli to workspace from npm
267
+ console.log(`[E2B] No runnerBundlePath provided, installing @sandagent/runner-cli to ${this.workdir}`);
268
+ const installResult = await handle.runCommand(`cd ${this.workdir} && npm install @sandagent/runner-cli@beta`);
269
+ if (installResult.exitCode !== 0) {
270
+ console.error(`[E2B] Failed to install runner-cli: ${installResult.stderr}`);
271
+ throw new Error(`Failed to install @sandagent/runner-cli: ${installResult.stderr}`);
272
+ }
273
+ console.log(`[E2B] Successfully installed @sandagent/runner-cli to ${this.workdir}`);
274
+ }
275
+ // Upload template to workdir (where runner will execute)
276
+ if (this.templatesPath && fs.existsSync(this.templatesPath)) {
277
+ const templateFiles = this.collectFiles(this.templatesPath, "");
278
+ console.log(`[E2B] Uploading ${templateFiles.length} template files to ${this.workdir}`);
279
+ await handle.upload(templateFiles, this.workdir);
280
+ }
281
+ else if (this.templatesPath) {
282
+ console.warn(`[E2B] Template path not found: ${this.templatesPath}, skipping`);
283
+ }
284
+ }
285
+ collectFiles(dir, prefix) {
286
+ const files = [];
287
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
288
+ for (const entry of entries) {
289
+ const fullPath = path.join(dir, entry.name);
290
+ const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
291
+ if (entry.isDirectory()) {
292
+ // Skip node_modules and .git only
293
+ if (entry.name === "node_modules" || entry.name === ".git") {
294
+ continue;
295
+ }
296
+ files.push(...this.collectFiles(fullPath, relativePath));
297
+ }
298
+ else if (entry.isFile()) {
299
+ files.push({
300
+ path: relativePath,
301
+ content: fs.readFileSync(fullPath),
302
+ });
303
+ }
304
+ }
305
+ return files;
306
+ }
307
+ }
308
+ /**
309
+ * Handle for an active E2B sandbox
310
+ */
311
+ class E2BHandle {
312
+ instance;
313
+ sandboxEnv;
314
+ workdir;
315
+ constructor(instance, sandboxEnv = {}, workdir = "/workspace") {
316
+ this.instance = instance;
317
+ this.sandboxEnv = sandboxEnv;
318
+ this.workdir = workdir;
319
+ }
320
+ /**
321
+ * Get the sandbox ID (useful for external tracking)
322
+ */
323
+ getSandboxId() {
324
+ return this.instance.sandboxId;
325
+ }
326
+ /**
327
+ * Get the underlying E2B sandbox instance
328
+ */
329
+ getInstance() {
330
+ return this.instance;
331
+ }
332
+ /**
333
+ * Escape a string for safe use in shell commands
334
+ * Uses single quotes and escapes any single quotes within the string
335
+ */
336
+ shellEscape(arg) {
337
+ // If the argument contains no special characters, return as-is
338
+ if (/^[a-zA-Z0-9._\-\/=]+$/.test(arg)) {
339
+ return arg;
340
+ }
341
+ // Wrap in single quotes and escape any single quotes within
342
+ // Replace ' with '\'' (end quote, escaped quote, start quote)
343
+ return `'${arg.replace(/'/g, "'\\''")}'`;
344
+ }
345
+ /**
346
+ * Build a shell-safe command string from an array of arguments
347
+ */
348
+ buildShellCommand(command) {
349
+ return command.map((arg) => this.shellEscape(arg)).join(" ");
350
+ }
351
+ /**
352
+ * Run a command and wait for completion (used internally)
353
+ */
354
+ async runCommand(cmd) {
355
+ return this.instance.commands.run(cmd);
356
+ }
357
+ exec(command, opts) {
358
+ const self = this;
359
+ const signal = opts?.signal;
360
+ // Merge sandbox-level env with call-level env (call-level takes precedence)
361
+ // Add NODE_PATH so Node can find packages, and PATH to find bin commands
362
+ const envWithNodePath = {
363
+ ...this.sandboxEnv,
364
+ ...opts?.env,
365
+ NODE_PATH: `${this.workdir}/node_modules`,
366
+ PATH: `${this.workdir}/node_modules/.bin:/usr/local/bin:/usr/bin:/bin`,
367
+ };
368
+ // Build shell-safe command string with proper escaping
369
+ const baseCommand = this.buildShellCommand(command);
370
+ // Build export statements for all env vars
371
+ const envExports = Object.entries(envWithNodePath)
372
+ .filter(([key]) => key === "NODE_PATH" || key === "PATH")
373
+ .map(([key, value]) => `export ${key}="${value.replace(/"/g, '\\"')}"`)
374
+ .join(" && ");
375
+ // Wrap command to capture PID for potential termination
376
+ const pidFile = `/tmp/sandagent-${Date.now()}-${Math.random().toString(36).substring(7)}.pid`;
377
+ const shellCommand = `(${envExports} && ${baseCommand}) & echo $! > ${pidFile}; wait $!; EXIT_CODE=$?; rm -f ${pidFile}; exit $EXIT_CODE`;
378
+ // Debug: log environment variables being passed to sandbox
379
+ console.log("[E2B] Executing command:", baseCommand);
380
+ console.log("[E2B] PID file:", pidFile);
381
+ console.log("[E2B] Environment variables:", Object.keys(envWithNodePath));
382
+ console.log("[E2B] ANTHROPIC_API_KEY present:", !!envWithNodePath.ANTHROPIC_API_KEY);
383
+ if (envWithNodePath.ANTHROPIC_API_KEY) {
384
+ console.log("[E2B] ANTHROPIC_API_KEY prefix:", envWithNodePath.ANTHROPIC_API_KEY.substring(0, 10) + "...");
385
+ }
386
+ return {
387
+ [Symbol.asyncIterator]() {
388
+ const chunks = [];
389
+ let finished = false;
390
+ let error = null;
391
+ let resolveNext = null;
392
+ // Monitor abort signal and kill the process
393
+ const abortHandler = async () => {
394
+ console.log("[E2B] Abort signal received, terminating process...");
395
+ console.log("[E2B] PID file:", pidFile);
396
+ finished = true;
397
+ error = new Error("Operation aborted");
398
+ error.name = "AbortError";
399
+ // Try to kill the process using the PID file
400
+ try {
401
+ // Check if PID file exists and kill the process
402
+ const killCmd = `if [ -f ${pidFile} ]; then PID=$(cat ${pidFile}); echo "Killing PID: $PID"; kill -TERM $PID 2>&1 || echo "Kill failed"; rm -f ${pidFile}; else echo "No PID file found"; fi`;
403
+ // Execute kill command asynchronously (don't wait for result)
404
+ self.instance.commands
405
+ .run(killCmd, {
406
+ timeoutMs: 5000,
407
+ })
408
+ .then((result) => {
409
+ console.log("[E2B] Kill command output:", result.stdout);
410
+ if (result.stderr) {
411
+ console.log("[E2B] Kill command stderr:", result.stderr);
412
+ }
413
+ })
414
+ .catch((err) => {
415
+ console.error("[E2B] Failed to execute kill command:", err);
416
+ });
417
+ }
418
+ catch (err) {
419
+ console.error("[E2B] Failed to send termination signal:", err);
420
+ }
421
+ if (resolveNext) {
422
+ resolveNext();
423
+ resolveNext = null;
424
+ }
425
+ };
426
+ if (signal) {
427
+ console.log("[E2B] Adding abort signal listener");
428
+ signal.addEventListener("abort", abortHandler);
429
+ }
430
+ else {
431
+ console.log("[E2B] No signal provided");
432
+ }
433
+ const commandPromise = self.instance.commands.run(shellCommand, {
434
+ cwd: opts?.cwd,
435
+ envs: envWithNodePath,
436
+ timeoutMs: 0, // 0 = no timeout for LLM operations
437
+ onStdout: (data) => {
438
+ const chunk = new TextEncoder().encode(data);
439
+ chunks.push(chunk);
440
+ if (resolveNext) {
441
+ resolveNext();
442
+ resolveNext = null;
443
+ }
444
+ },
445
+ onStderr: (data) => {
446
+ console.error(`[E2B stderr] ${data}`);
447
+ },
448
+ });
449
+ commandPromise
450
+ .then((result) => {
451
+ console.log("[E2B] Command completed with exit code:", result.exitCode);
452
+ finished = true;
453
+ if (resolveNext) {
454
+ resolveNext();
455
+ resolveNext = null;
456
+ }
457
+ })
458
+ .catch((err) => {
459
+ error = err instanceof Error ? err : new Error(String(err));
460
+ // Log AbortError appropriately
461
+ if (error.name === "AbortError") {
462
+ console.log("[E2B] Command execution aborted by user");
463
+ }
464
+ else {
465
+ console.error("[E2B] Command execution error:", error.message);
466
+ }
467
+ if (resolveNext) {
468
+ resolveNext();
469
+ resolveNext = null;
470
+ }
471
+ })
472
+ .finally(() => {
473
+ // Remove event listener when iterator completes
474
+ if (signal) {
475
+ signal.removeEventListener("abort", abortHandler);
476
+ }
477
+ });
478
+ return {
479
+ async next() {
480
+ // Check if signal is aborted and no more chunks
481
+ if (signal?.aborted && chunks.length === 0) {
482
+ console.log("[E2B] Signal aborted, stopping iteration");
483
+ return { value: undefined, done: true };
484
+ }
485
+ if (chunks.length > 0) {
486
+ return { value: chunks.shift(), done: false };
487
+ }
488
+ if (finished && chunks.length === 0) {
489
+ return { value: undefined, done: true };
490
+ }
491
+ if (error) {
492
+ throw error;
493
+ }
494
+ await new Promise((resolve) => {
495
+ resolveNext = resolve;
496
+ });
497
+ if (chunks.length > 0) {
498
+ return { value: chunks.shift(), done: false };
499
+ }
500
+ if (error) {
501
+ throw error;
502
+ }
503
+ return { value: undefined, done: true };
504
+ },
505
+ };
506
+ },
507
+ };
508
+ }
509
+ async upload(files, targetDir) {
510
+ for (const file of files) {
511
+ const fullPath = `${targetDir}/${file.path}`;
512
+ const dirPath = fullPath.substring(0, fullPath.lastIndexOf("/"));
513
+ if (dirPath) {
514
+ try {
515
+ await this.instance.files.makeDir(dirPath);
516
+ }
517
+ catch {
518
+ // Directory might already exist
519
+ }
520
+ }
521
+ const content = file.content instanceof Uint8Array
522
+ ? file.content.buffer.slice(file.content.byteOffset, file.content.byteOffset + file.content.byteLength)
523
+ : file.content;
524
+ await this.instance.files.write(fullPath, content);
525
+ }
526
+ }
527
+ async readFile(filePath) {
528
+ const exists = await this.instance.files.exists(filePath);
529
+ if (!exists) {
530
+ console.error(`[E2B] File not found: ${filePath}`);
531
+ return "";
532
+ }
533
+ // E2B files.read() defaults to text format and returns Promise<string>
534
+ const content = await this.instance.files.read(filePath);
535
+ return content;
536
+ }
537
+ async destroy() {
538
+ // Note: We don't kill the sandbox here to allow reuse
539
+ // The sandbox will auto-terminate based on the configured timeout
540
+ // or can be paused for up to 30 days with E2B's persistence feature
541
+ console.log(`[E2B] Sandbox ${this.instance.sandboxId} handle destroyed (sandbox continues running for reuse)`);
542
+ }
543
+ }
544
+ //# sourceMappingURL=e2b-sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e2b-sandbox.js","sourceRoot":"","sources":["../src/e2b-sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { E2BSandbox, type E2BSandboxOptions } from "./e2b-sandbox.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { E2BSandbox } from "./e2b-sandbox.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA0B,MAAM,kBAAkB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@sandagent/sandbox-e2b",
3
+ "version": "0.1.0-beta.0",
4
+ "description": "E2B sandbox adapter for SandAgent",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "clean": "rm -rf dist",
22
+ "typecheck": "tsc --noEmit",
23
+ "lint": "echo 'no lint configured'",
24
+ "test": "vitest run --passWithNoTests"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/vikadata/sandagent.git",
29
+ "directory": "packages/sandbox-e2b"
30
+ },
31
+ "license": "Apache-2.0",
32
+ "publishConfig": {
33
+ "access": "public",
34
+ "tag": "beta"
35
+ },
36
+ "engines": {
37
+ "node": ">=20.0.0"
38
+ },
39
+ "keywords": [
40
+ "sandbox",
41
+ "e2b",
42
+ "sandagent",
43
+ "adapter"
44
+ ],
45
+ "dependencies": {
46
+ "@sandagent/manager": "workspace:*",
47
+ "e2b": "^2.9.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.10.0",
51
+ "typescript": "^5.3.0",
52
+ "vitest": "^1.6.1"
53
+ }
54
+ }