@hasna/sandboxes 0.1.7 → 0.1.9
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/cli/index.js +126 -8
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/sandboxes.d.ts +1 -1
- package/dist/db/sandboxes.d.ts.map +1 -1
- package/dist/db/snapshots.d.ts +29 -0
- package/dist/db/snapshots.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +168 -7
- package/dist/lib/agent-runner.d.ts +3 -0
- package/dist/lib/agent-runner.d.ts.map +1 -1
- package/dist/lib/images.d.ts +13 -0
- package/dist/lib/images.d.ts.map +1 -0
- package/dist/mcp/index.js +447 -32
- package/dist/providers/daytona.d.ts +1 -0
- package/dist/providers/daytona.d.ts.map +1 -1
- package/dist/providers/e2b.d.ts +10 -2
- package/dist/providers/e2b.d.ts.map +1 -1
- package/dist/providers/modal.d.ts +1 -0
- package/dist/providers/modal.d.ts.map +1 -1
- package/dist/providers/types.d.ts +12 -2
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/server/index.js +80 -7
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -2263,6 +2263,24 @@ ALTER TABLE sandbox_sessions_new RENAME TO sandbox_sessions;
|
|
|
2263
2263
|
CREATE INDEX IF NOT EXISTS idx_sessions_sandbox ON sandbox_sessions(sandbox_id);
|
|
2264
2264
|
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sandbox_sessions(status);
|
|
2265
2265
|
INSERT OR IGNORE INTO _migrations (id) VALUES (3);
|
|
2266
|
+
`,
|
|
2267
|
+
`
|
|
2268
|
+
CREATE TABLE IF NOT EXISTS snapshots (
|
|
2269
|
+
id TEXT PRIMARY KEY,
|
|
2270
|
+
sandbox_id TEXT NOT NULL,
|
|
2271
|
+
provider_sandbox_id TEXT NOT NULL,
|
|
2272
|
+
provider TEXT NOT NULL,
|
|
2273
|
+
name TEXT,
|
|
2274
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
2275
|
+
);
|
|
2276
|
+
CREATE INDEX IF NOT EXISTS idx_snapshots_sandbox ON snapshots(sandbox_id);
|
|
2277
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (4);
|
|
2278
|
+
`,
|
|
2279
|
+
`
|
|
2280
|
+
ALTER TABLE sandboxes ADD COLUMN budget_limit_usd REAL;
|
|
2281
|
+
ALTER TABLE sandboxes ADD COLUMN on_budget_exceeded TEXT NOT NULL DEFAULT 'terminate' CHECK(on_budget_exceeded IN ('terminate', 'pause', 'notify'));
|
|
2282
|
+
ALTER TABLE sandboxes ADD COLUMN started_at TEXT;
|
|
2283
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (5);
|
|
2266
2284
|
`
|
|
2267
2285
|
];
|
|
2268
2286
|
});
|
|
@@ -2314,6 +2332,9 @@ function rowToSandbox(row) {
|
|
|
2314
2332
|
project_id: row.project_id,
|
|
2315
2333
|
on_timeout: row.on_timeout ?? "terminate",
|
|
2316
2334
|
auto_resume: row.auto_resume === 1,
|
|
2335
|
+
budget_limit_usd: row.budget_limit_usd ?? null,
|
|
2336
|
+
on_budget_exceeded: row.on_budget_exceeded ?? "terminate",
|
|
2337
|
+
started_at: row.started_at ?? null,
|
|
2317
2338
|
created_at: row.created_at,
|
|
2318
2339
|
updated_at: row.updated_at
|
|
2319
2340
|
};
|
|
@@ -2331,8 +2352,10 @@ function createSandbox(input) {
|
|
|
2331
2352
|
const project_id = input.project_id ?? null;
|
|
2332
2353
|
const on_timeout = input.on_timeout ?? "terminate";
|
|
2333
2354
|
const auto_resume = input.auto_resume ? 1 : 0;
|
|
2334
|
-
|
|
2335
|
-
|
|
2355
|
+
const budget_limit_usd = input.budget_limit_usd ?? null;
|
|
2356
|
+
const on_budget_exceeded = input.on_budget_exceeded ?? "terminate";
|
|
2357
|
+
db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, created_at, updated_at)
|
|
2358
|
+
VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, timestamp, timestamp);
|
|
2336
2359
|
return getSandbox(id);
|
|
2337
2360
|
}
|
|
2338
2361
|
function getSandbox(id) {
|
|
@@ -2404,6 +2427,10 @@ function updateSandbox(id, updates) {
|
|
|
2404
2427
|
setClauses.push("keep_alive_until = ?");
|
|
2405
2428
|
params.push(updates.keep_alive_until);
|
|
2406
2429
|
}
|
|
2430
|
+
if (updates.started_at !== undefined) {
|
|
2431
|
+
setClauses.push("started_at = ?");
|
|
2432
|
+
params.push(updates.started_at);
|
|
2433
|
+
}
|
|
2407
2434
|
if (setClauses.length === 0) {
|
|
2408
2435
|
return getSandbox(resolvedId);
|
|
2409
2436
|
}
|
|
@@ -2682,10 +2709,11 @@ class E2BProvider {
|
|
|
2682
2709
|
onStderr: opts?.onStderr ? (data) => opts.onStderr(data) : undefined,
|
|
2683
2710
|
envs: opts?.env,
|
|
2684
2711
|
cwd: opts?.cwd,
|
|
2685
|
-
timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined
|
|
2712
|
+
timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined,
|
|
2713
|
+
...opts?.stdin !== undefined ? { stdin: opts.stdin } : {}
|
|
2686
2714
|
});
|
|
2687
2715
|
return {
|
|
2688
|
-
exit_code: result.exitCode,
|
|
2716
|
+
exit_code: result.exitCode ?? 0,
|
|
2689
2717
|
stdout: result.stdout,
|
|
2690
2718
|
stderr: result.stderr
|
|
2691
2719
|
};
|
|
@@ -2693,10 +2721,28 @@ class E2BProvider {
|
|
|
2693
2721
|
throw new ProviderError("e2b", `Failed to exec command: ${err.message}`);
|
|
2694
2722
|
}
|
|
2695
2723
|
}
|
|
2696
|
-
async readFile(sandboxId, path) {
|
|
2724
|
+
async readFile(sandboxId, path, opts) {
|
|
2697
2725
|
const sandbox = await this.getInstance(sandboxId);
|
|
2698
2726
|
try {
|
|
2699
|
-
|
|
2727
|
+
if (opts?.encoding === "base64") {
|
|
2728
|
+
const bytes = await sandbox.files.read(path, { format: "bytes" });
|
|
2729
|
+
const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
|
|
2730
|
+
return Buffer.from(sliced).toString("base64");
|
|
2731
|
+
} else if (opts?.encoding === "hex") {
|
|
2732
|
+
const bytes = await sandbox.files.read(path, { format: "bytes" });
|
|
2733
|
+
const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
|
|
2734
|
+
return Buffer.from(sliced).toString("hex");
|
|
2735
|
+
} else {
|
|
2736
|
+
const content = await sandbox.files.read(path, { format: "text" });
|
|
2737
|
+
if (opts?.offset !== undefined || opts?.limit !== undefined) {
|
|
2738
|
+
const lines = content.split(`
|
|
2739
|
+
`);
|
|
2740
|
+
const sliced = lines.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined);
|
|
2741
|
+
return sliced.join(`
|
|
2742
|
+
`);
|
|
2743
|
+
}
|
|
2744
|
+
return content;
|
|
2745
|
+
}
|
|
2700
2746
|
} catch (err) {
|
|
2701
2747
|
throw new ProviderError("e2b", `Failed to read file ${path}: ${err.message}`);
|
|
2702
2748
|
}
|
|
@@ -2709,9 +2755,21 @@ class E2BProvider {
|
|
|
2709
2755
|
throw new ProviderError("e2b", `Failed to write file ${path}: ${err.message}`);
|
|
2710
2756
|
}
|
|
2711
2757
|
}
|
|
2712
|
-
async listFiles(sandboxId, path) {
|
|
2758
|
+
async listFiles(sandboxId, path, opts) {
|
|
2713
2759
|
const sandbox = await this.getInstance(sandboxId);
|
|
2714
2760
|
try {
|
|
2761
|
+
if (opts?.recursive || opts?.glob) {
|
|
2762
|
+
const pattern = opts.glob ? opts.glob : "*";
|
|
2763
|
+
const cmd = opts.recursive ? `find ${JSON.stringify(path)} -name ${JSON.stringify(pattern)} 2>/dev/null | head -500` : `ls -la ${JSON.stringify(path)}/${pattern} 2>/dev/null`;
|
|
2764
|
+
const result = await sandbox.commands.run(cmd);
|
|
2765
|
+
return result.stdout.trim().split(`
|
|
2766
|
+
`).filter(Boolean).map((p) => ({
|
|
2767
|
+
path: p.trim(),
|
|
2768
|
+
name: p.trim().split("/").pop() || p.trim(),
|
|
2769
|
+
is_dir: false,
|
|
2770
|
+
size: 0
|
|
2771
|
+
}));
|
|
2772
|
+
}
|
|
2715
2773
|
const entries = await sandbox.files.list(path);
|
|
2716
2774
|
return entries.map((e) => ({
|
|
2717
2775
|
path: e.path,
|
|
@@ -2752,6 +2810,15 @@ class E2BProvider {
|
|
|
2752
2810
|
throw new ProviderError("e2b", `Failed to resume sandbox: ${err.message}`);
|
|
2753
2811
|
}
|
|
2754
2812
|
}
|
|
2813
|
+
async getPublicUrl(sandboxId, port, _protocol) {
|
|
2814
|
+
const sandbox = await this.getInstance(sandboxId);
|
|
2815
|
+
try {
|
|
2816
|
+
const host = sandbox.getHost(port);
|
|
2817
|
+
return `https://${host}`;
|
|
2818
|
+
} catch (err) {
|
|
2819
|
+
throw new ProviderError("e2b", `Failed to get public URL for port ${port}: ${err.message}`);
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2755
2822
|
async keepAlive(sandboxId, durationMs) {
|
|
2756
2823
|
const sandbox = await this.getInstance(sandboxId);
|
|
2757
2824
|
try {
|
|
@@ -2912,6 +2979,9 @@ class DaytonaProvider {
|
|
|
2912
2979
|
throw new ProviderError("daytona", `Failed to delete sandbox: ${err.message}`);
|
|
2913
2980
|
}
|
|
2914
2981
|
}
|
|
2982
|
+
async getPublicUrl(_sandboxId, _port, _protocol) {
|
|
2983
|
+
throw new ProviderError("daytona", "Port forwarding not supported by Daytona provider");
|
|
2984
|
+
}
|
|
2915
2985
|
async pause(_sandboxId) {
|
|
2916
2986
|
throw new ProviderError("daytona", "Pause/resume not supported by Daytona provider");
|
|
2917
2987
|
}
|
|
@@ -3140,6 +3210,9 @@ class ModalProvider {
|
|
|
3140
3210
|
async delete(sandboxId) {
|
|
3141
3211
|
await this.stop(sandboxId);
|
|
3142
3212
|
}
|
|
3213
|
+
async getPublicUrl(_sandboxId, _port, _protocol) {
|
|
3214
|
+
throw new ProviderError("modal", "Port forwarding not supported by Modal provider");
|
|
3215
|
+
}
|
|
3143
3216
|
async pause(_sandboxId) {
|
|
3144
3217
|
throw new ProviderError("modal", "Pause/resume not supported by Modal provider");
|
|
3145
3218
|
}
|
|
@@ -3409,13 +3482,23 @@ __export(exports_agent_runner, {
|
|
|
3409
3482
|
stopAgent: () => stopAgent,
|
|
3410
3483
|
runAgent: () => runAgent
|
|
3411
3484
|
});
|
|
3485
|
+
async function fireWebhook(url, payload) {
|
|
3486
|
+
try {
|
|
3487
|
+
await fetch(url, {
|
|
3488
|
+
method: "POST",
|
|
3489
|
+
headers: { "Content-Type": "application/json" },
|
|
3490
|
+
body: JSON.stringify(payload)
|
|
3491
|
+
});
|
|
3492
|
+
} catch {}
|
|
3493
|
+
}
|
|
3412
3494
|
async function runAgent(sandboxId, opts) {
|
|
3413
3495
|
const sandbox = getSandbox(sandboxId);
|
|
3414
3496
|
if (!sandbox.provider_sandbox_id) {
|
|
3415
3497
|
throw new Error("Sandbox has no provider instance");
|
|
3416
3498
|
}
|
|
3417
3499
|
const provider = await getProvider(sandbox.provider);
|
|
3418
|
-
const
|
|
3500
|
+
const mergedEnv = { ...sandbox.env_vars, ...opts.callEnvVars };
|
|
3501
|
+
const env = Object.keys(mergedEnv).length > 0 ? mergedEnv : undefined;
|
|
3419
3502
|
let cmd;
|
|
3420
3503
|
const driver = opts.agentType !== "custom" ? getAgentDriver(opts.agentType) : undefined;
|
|
3421
3504
|
if (opts.command) {
|
|
@@ -3434,6 +3517,18 @@ async function runAgent(sandboxId, opts) {
|
|
|
3434
3517
|
command: cmd
|
|
3435
3518
|
});
|
|
3436
3519
|
emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} started: ${opts.prompt.slice(0, 100)}`);
|
|
3520
|
+
const startedAt = Date.now();
|
|
3521
|
+
const webhookEvents = opts.webhookEvents ?? ["start", "complete", "error"];
|
|
3522
|
+
if (opts.webhookUrl && webhookEvents.includes("start")) {
|
|
3523
|
+
fireWebhook(opts.webhookUrl, {
|
|
3524
|
+
event: "start",
|
|
3525
|
+
session_id: session.id,
|
|
3526
|
+
sandbox_id: sandbox.id,
|
|
3527
|
+
agent_type: opts.agentType,
|
|
3528
|
+
status: "running",
|
|
3529
|
+
timestamp: new Date().toISOString()
|
|
3530
|
+
});
|
|
3531
|
+
}
|
|
3437
3532
|
const collector = createStreamCollector(sandbox.id, session.id);
|
|
3438
3533
|
provider.exec(sandbox.provider_sandbox_id, cmd, {
|
|
3439
3534
|
onStdout: (data) => {
|
|
@@ -3450,9 +3545,32 @@ async function runAgent(sandboxId, opts) {
|
|
|
3450
3545
|
const status = exitResult.exit_code === 0 ? "completed" : "failed";
|
|
3451
3546
|
endSession(session.id, exitResult.exit_code ?? 0, status);
|
|
3452
3547
|
emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} finished with exit code ${exitResult.exit_code}`);
|
|
3548
|
+
if (opts.webhookUrl && webhookEvents.includes("complete")) {
|
|
3549
|
+
fireWebhook(opts.webhookUrl, {
|
|
3550
|
+
event: "complete",
|
|
3551
|
+
session_id: session.id,
|
|
3552
|
+
sandbox_id: sandbox.id,
|
|
3553
|
+
agent_type: opts.agentType,
|
|
3554
|
+
status,
|
|
3555
|
+
exit_code: exitResult.exit_code,
|
|
3556
|
+
duration_ms: Date.now() - startedAt,
|
|
3557
|
+
timestamp: new Date().toISOString()
|
|
3558
|
+
});
|
|
3559
|
+
}
|
|
3453
3560
|
}).catch((err) => {
|
|
3454
3561
|
endSession(session.id, 1, "failed");
|
|
3455
3562
|
emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} failed: ${err.message}`);
|
|
3563
|
+
if (opts.webhookUrl && webhookEvents.includes("error")) {
|
|
3564
|
+
fireWebhook(opts.webhookUrl, {
|
|
3565
|
+
event: "error",
|
|
3566
|
+
session_id: session.id,
|
|
3567
|
+
sandbox_id: sandbox.id,
|
|
3568
|
+
agent_type: opts.agentType,
|
|
3569
|
+
status: "failed",
|
|
3570
|
+
duration_ms: Date.now() - startedAt,
|
|
3571
|
+
timestamp: new Date().toISOString()
|
|
3572
|
+
});
|
|
3573
|
+
}
|
|
3456
3574
|
});
|
|
3457
3575
|
return session;
|
|
3458
3576
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmNtC,wBAAgB,WAAW,IAAI,QAAQ,CAYtC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAcf"}
|
package/dist/db/sandboxes.d.ts
CHANGED
|
@@ -7,6 +7,6 @@ export declare function listSandboxes(opts?: {
|
|
|
7
7
|
provider?: SandboxProviderName;
|
|
8
8
|
project_id?: string;
|
|
9
9
|
}): Sandbox[];
|
|
10
|
-
export declare function updateSandbox(id: string, updates: Partial<Pick<Sandbox, "status" | "provider_sandbox_id" | "name" | "image" | "timeout" | "config" | "env_vars" | "keep_alive_until">>): Sandbox;
|
|
10
|
+
export declare function updateSandbox(id: string, updates: Partial<Pick<Sandbox, "status" | "provider_sandbox_id" | "name" | "image" | "timeout" | "config" | "env_vars" | "keep_alive_until" | "started_at">>): Sandbox;
|
|
11
11
|
export declare function deleteSandbox(id: string): void;
|
|
12
12
|
//# sourceMappingURL=sandboxes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandboxes.d.ts","sourceRoot":"","sources":["../../src/db/sandboxes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAKxB,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"sandboxes.d.ts","sourceRoot":"","sources":["../../src/db/sandboxes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAKxB,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAqBrD;AAID,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAsChE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAY9C;AAED,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE;IACnC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,EAAE,CAwBZ;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CACd,IAAI,CACF,OAAO,EACL,QAAQ,GACR,qBAAqB,GACrB,MAAM,GACN,OAAO,GACP,SAAS,GACT,QAAQ,GACR,UAAU,GACV,kBAAkB,GAClB,YAAY,CACf,CACF,GACA,OAAO,CA2DT;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAO9C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface Snapshot {
|
|
2
|
+
id: string;
|
|
3
|
+
sandbox_id: string;
|
|
4
|
+
provider_sandbox_id: string;
|
|
5
|
+
provider: string;
|
|
6
|
+
name: string | null;
|
|
7
|
+
created_at: string;
|
|
8
|
+
}
|
|
9
|
+
export interface SnapshotRow {
|
|
10
|
+
id: string;
|
|
11
|
+
sandbox_id: string;
|
|
12
|
+
provider_sandbox_id: string;
|
|
13
|
+
provider: string;
|
|
14
|
+
name: string | null;
|
|
15
|
+
created_at: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class SnapshotNotFoundError extends Error {
|
|
18
|
+
constructor(id: string);
|
|
19
|
+
}
|
|
20
|
+
export declare function createSnapshot(input: {
|
|
21
|
+
sandbox_id: string;
|
|
22
|
+
provider_sandbox_id: string;
|
|
23
|
+
provider: string;
|
|
24
|
+
name?: string;
|
|
25
|
+
}): Snapshot;
|
|
26
|
+
export declare function getSnapshot(id: string): Snapshot;
|
|
27
|
+
export declare function listSnapshots(sandboxId?: string): Snapshot[];
|
|
28
|
+
export declare function deleteSnapshot(id: string): void;
|
|
29
|
+
//# sourceMappingURL=snapshots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshots.d.ts","sourceRoot":"","sources":["../../src/db/snapshots.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,EAAE,EAAE,MAAM;CAIvB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,QAAQ,CASX;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAOhD;AAED,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAM5D;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAK/C"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,11 @@ export { registerAgent, getAgent, getAgentByName, listAgents, deleteAgent } from
|
|
|
7
7
|
export { createProject, getProject, getProjectByPath, listProjects, ensureProject, deleteProject } from "./db/projects.js";
|
|
8
8
|
export { createWebhook, getWebhook, listWebhooks, deleteWebhook } from "./db/webhooks.js";
|
|
9
9
|
export { createTemplate, getTemplate, getTemplateByName, listTemplates, deleteTemplate } from "./db/templates.js";
|
|
10
|
+
export { createSnapshot, getSnapshot, listSnapshots, deleteSnapshot } from "./db/snapshots.js";
|
|
11
|
+
export type { Snapshot, SnapshotRow } from "./db/snapshots.js";
|
|
12
|
+
export { SnapshotNotFoundError } from "./db/snapshots.js";
|
|
10
13
|
export { loadConfig, saveConfig, getDefaultProvider, getDefaultTimeout, getDefaultImage, getProviderApiKey, setConfigValue, getConfigValue } from "./lib/config.js";
|
|
14
|
+
export { BUILTIN_IMAGES, resolveImage, getBuiltinImageSetupScript } from "./lib/images.js";
|
|
11
15
|
export { getProvider } from "./providers/index.js";
|
|
12
16
|
export type { SandboxProvider, ProviderSandbox, CreateSandboxOpts, ExecOptions } from "./providers/types.js";
|
|
13
17
|
export { createStreamCollector, addStreamListener, emitLifecycleEvent } from "./lib/stream.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtG,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3H,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtG,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3H,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/F,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpK,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAG3F,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAG7G,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG/F,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -174,10 +174,11 @@ class E2BProvider {
|
|
|
174
174
|
onStderr: opts?.onStderr ? (data) => opts.onStderr(data) : undefined,
|
|
175
175
|
envs: opts?.env,
|
|
176
176
|
cwd: opts?.cwd,
|
|
177
|
-
timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined
|
|
177
|
+
timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined,
|
|
178
|
+
...opts?.stdin !== undefined ? { stdin: opts.stdin } : {}
|
|
178
179
|
});
|
|
179
180
|
return {
|
|
180
|
-
exit_code: result.exitCode,
|
|
181
|
+
exit_code: result.exitCode ?? 0,
|
|
181
182
|
stdout: result.stdout,
|
|
182
183
|
stderr: result.stderr
|
|
183
184
|
};
|
|
@@ -185,10 +186,28 @@ class E2BProvider {
|
|
|
185
186
|
throw new ProviderError("e2b", `Failed to exec command: ${err.message}`);
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
|
-
async readFile(sandboxId, path) {
|
|
189
|
+
async readFile(sandboxId, path, opts) {
|
|
189
190
|
const sandbox = await this.getInstance(sandboxId);
|
|
190
191
|
try {
|
|
191
|
-
|
|
192
|
+
if (opts?.encoding === "base64") {
|
|
193
|
+
const bytes = await sandbox.files.read(path, { format: "bytes" });
|
|
194
|
+
const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
|
|
195
|
+
return Buffer.from(sliced).toString("base64");
|
|
196
|
+
} else if (opts?.encoding === "hex") {
|
|
197
|
+
const bytes = await sandbox.files.read(path, { format: "bytes" });
|
|
198
|
+
const sliced = opts.offset !== undefined || opts.limit !== undefined ? bytes.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined) : bytes;
|
|
199
|
+
return Buffer.from(sliced).toString("hex");
|
|
200
|
+
} else {
|
|
201
|
+
const content = await sandbox.files.read(path, { format: "text" });
|
|
202
|
+
if (opts?.offset !== undefined || opts?.limit !== undefined) {
|
|
203
|
+
const lines = content.split(`
|
|
204
|
+
`);
|
|
205
|
+
const sliced = lines.slice(opts.offset ?? 0, opts.limit !== undefined ? (opts.offset ?? 0) + opts.limit : undefined);
|
|
206
|
+
return sliced.join(`
|
|
207
|
+
`);
|
|
208
|
+
}
|
|
209
|
+
return content;
|
|
210
|
+
}
|
|
192
211
|
} catch (err) {
|
|
193
212
|
throw new ProviderError("e2b", `Failed to read file ${path}: ${err.message}`);
|
|
194
213
|
}
|
|
@@ -201,9 +220,21 @@ class E2BProvider {
|
|
|
201
220
|
throw new ProviderError("e2b", `Failed to write file ${path}: ${err.message}`);
|
|
202
221
|
}
|
|
203
222
|
}
|
|
204
|
-
async listFiles(sandboxId, path) {
|
|
223
|
+
async listFiles(sandboxId, path, opts) {
|
|
205
224
|
const sandbox = await this.getInstance(sandboxId);
|
|
206
225
|
try {
|
|
226
|
+
if (opts?.recursive || opts?.glob) {
|
|
227
|
+
const pattern = opts.glob ? opts.glob : "*";
|
|
228
|
+
const cmd = opts.recursive ? `find ${JSON.stringify(path)} -name ${JSON.stringify(pattern)} 2>/dev/null | head -500` : `ls -la ${JSON.stringify(path)}/${pattern} 2>/dev/null`;
|
|
229
|
+
const result = await sandbox.commands.run(cmd);
|
|
230
|
+
return result.stdout.trim().split(`
|
|
231
|
+
`).filter(Boolean).map((p) => ({
|
|
232
|
+
path: p.trim(),
|
|
233
|
+
name: p.trim().split("/").pop() || p.trim(),
|
|
234
|
+
is_dir: false,
|
|
235
|
+
size: 0
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
207
238
|
const entries = await sandbox.files.list(path);
|
|
208
239
|
return entries.map((e) => ({
|
|
209
240
|
path: e.path,
|
|
@@ -244,6 +275,15 @@ class E2BProvider {
|
|
|
244
275
|
throw new ProviderError("e2b", `Failed to resume sandbox: ${err.message}`);
|
|
245
276
|
}
|
|
246
277
|
}
|
|
278
|
+
async getPublicUrl(sandboxId, port, _protocol) {
|
|
279
|
+
const sandbox = await this.getInstance(sandboxId);
|
|
280
|
+
try {
|
|
281
|
+
const host = sandbox.getHost(port);
|
|
282
|
+
return `https://${host}`;
|
|
283
|
+
} catch (err) {
|
|
284
|
+
throw new ProviderError("e2b", `Failed to get public URL for port ${port}: ${err.message}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
247
287
|
async keepAlive(sandboxId, durationMs) {
|
|
248
288
|
const sandbox = await this.getInstance(sandboxId);
|
|
249
289
|
try {
|
|
@@ -404,6 +444,9 @@ class DaytonaProvider {
|
|
|
404
444
|
throw new ProviderError("daytona", `Failed to delete sandbox: ${err.message}`);
|
|
405
445
|
}
|
|
406
446
|
}
|
|
447
|
+
async getPublicUrl(_sandboxId, _port, _protocol) {
|
|
448
|
+
throw new ProviderError("daytona", "Port forwarding not supported by Daytona provider");
|
|
449
|
+
}
|
|
407
450
|
async pause(_sandboxId) {
|
|
408
451
|
throw new ProviderError("daytona", "Pause/resume not supported by Daytona provider");
|
|
409
452
|
}
|
|
@@ -632,6 +675,9 @@ class ModalProvider {
|
|
|
632
675
|
async delete(sandboxId) {
|
|
633
676
|
await this.stop(sandboxId);
|
|
634
677
|
}
|
|
678
|
+
async getPublicUrl(_sandboxId, _port, _protocol) {
|
|
679
|
+
throw new ProviderError("modal", "Port forwarding not supported by Modal provider");
|
|
680
|
+
}
|
|
635
681
|
async pause(_sandboxId) {
|
|
636
682
|
throw new ProviderError("modal", "Pause/resume not supported by Modal provider");
|
|
637
683
|
}
|
|
@@ -848,6 +894,24 @@ ALTER TABLE sandbox_sessions_new RENAME TO sandbox_sessions;
|
|
|
848
894
|
CREATE INDEX IF NOT EXISTS idx_sessions_sandbox ON sandbox_sessions(sandbox_id);
|
|
849
895
|
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sandbox_sessions(status);
|
|
850
896
|
INSERT OR IGNORE INTO _migrations (id) VALUES (3);
|
|
897
|
+
`,
|
|
898
|
+
`
|
|
899
|
+
CREATE TABLE IF NOT EXISTS snapshots (
|
|
900
|
+
id TEXT PRIMARY KEY,
|
|
901
|
+
sandbox_id TEXT NOT NULL,
|
|
902
|
+
provider_sandbox_id TEXT NOT NULL,
|
|
903
|
+
provider TEXT NOT NULL,
|
|
904
|
+
name TEXT,
|
|
905
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
906
|
+
);
|
|
907
|
+
CREATE INDEX IF NOT EXISTS idx_snapshots_sandbox ON snapshots(sandbox_id);
|
|
908
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (4);
|
|
909
|
+
`,
|
|
910
|
+
`
|
|
911
|
+
ALTER TABLE sandboxes ADD COLUMN budget_limit_usd REAL;
|
|
912
|
+
ALTER TABLE sandboxes ADD COLUMN on_budget_exceeded TEXT NOT NULL DEFAULT 'terminate' CHECK(on_budget_exceeded IN ('terminate', 'pause', 'notify'));
|
|
913
|
+
ALTER TABLE sandboxes ADD COLUMN started_at TEXT;
|
|
914
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (5);
|
|
851
915
|
`
|
|
852
916
|
];
|
|
853
917
|
var db = null;
|
|
@@ -922,6 +986,9 @@ function rowToSandbox(row) {
|
|
|
922
986
|
project_id: row.project_id,
|
|
923
987
|
on_timeout: row.on_timeout ?? "terminate",
|
|
924
988
|
auto_resume: row.auto_resume === 1,
|
|
989
|
+
budget_limit_usd: row.budget_limit_usd ?? null,
|
|
990
|
+
on_budget_exceeded: row.on_budget_exceeded ?? "terminate",
|
|
991
|
+
started_at: row.started_at ?? null,
|
|
925
992
|
created_at: row.created_at,
|
|
926
993
|
updated_at: row.updated_at
|
|
927
994
|
};
|
|
@@ -939,8 +1006,10 @@ function createSandbox(input) {
|
|
|
939
1006
|
const project_id = input.project_id ?? null;
|
|
940
1007
|
const on_timeout = input.on_timeout ?? "terminate";
|
|
941
1008
|
const auto_resume = input.auto_resume ? 1 : 0;
|
|
942
|
-
|
|
943
|
-
|
|
1009
|
+
const budget_limit_usd = input.budget_limit_usd ?? null;
|
|
1010
|
+
const on_budget_exceeded = input.on_budget_exceeded ?? "terminate";
|
|
1011
|
+
db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, created_at, updated_at)
|
|
1012
|
+
VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, on_timeout, auto_resume, budget_limit_usd, on_budget_exceeded, timestamp, timestamp);
|
|
944
1013
|
return getSandbox(id);
|
|
945
1014
|
}
|
|
946
1015
|
function getSandbox(id) {
|
|
@@ -1012,6 +1081,10 @@ function updateSandbox(id, updates) {
|
|
|
1012
1081
|
setClauses.push("keep_alive_until = ?");
|
|
1013
1082
|
params.push(updates.keep_alive_until);
|
|
1014
1083
|
}
|
|
1084
|
+
if (updates.started_at !== undefined) {
|
|
1085
|
+
setClauses.push("started_at = ?");
|
|
1086
|
+
params.push(updates.started_at);
|
|
1087
|
+
}
|
|
1015
1088
|
if (setClauses.length === 0) {
|
|
1016
1089
|
return getSandbox(resolvedId);
|
|
1017
1090
|
}
|
|
@@ -1343,6 +1416,45 @@ function deleteTemplate(id) {
|
|
|
1343
1416
|
throw new TemplateNotFoundError(id);
|
|
1344
1417
|
db2.query("DELETE FROM templates WHERE id = ?").run(resolvedId);
|
|
1345
1418
|
}
|
|
1419
|
+
// src/db/snapshots.ts
|
|
1420
|
+
class SnapshotNotFoundError extends Error {
|
|
1421
|
+
constructor(id) {
|
|
1422
|
+
super(`Snapshot not found: ${id}`);
|
|
1423
|
+
this.name = "SnapshotNotFoundError";
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
function createSnapshot(input) {
|
|
1427
|
+
const db2 = getDatabase();
|
|
1428
|
+
const id = uuid();
|
|
1429
|
+
const timestamp = now();
|
|
1430
|
+
db2.query(`INSERT INTO snapshots (id, sandbox_id, provider_sandbox_id, provider, name, created_at)
|
|
1431
|
+
VALUES (?, ?, ?, ?, ?, ?)`).run(id, input.sandbox_id, input.provider_sandbox_id, input.provider, input.name ?? null, timestamp);
|
|
1432
|
+
return getSnapshot(id);
|
|
1433
|
+
}
|
|
1434
|
+
function getSnapshot(id) {
|
|
1435
|
+
const db2 = getDatabase();
|
|
1436
|
+
const resolvedId = resolvePartialId("snapshots", id);
|
|
1437
|
+
if (!resolvedId)
|
|
1438
|
+
throw new SnapshotNotFoundError(id);
|
|
1439
|
+
const row = db2.query("SELECT * FROM snapshots WHERE id = ?").get(resolvedId);
|
|
1440
|
+
if (!row)
|
|
1441
|
+
throw new SnapshotNotFoundError(id);
|
|
1442
|
+
return row;
|
|
1443
|
+
}
|
|
1444
|
+
function listSnapshots(sandboxId) {
|
|
1445
|
+
const db2 = getDatabase();
|
|
1446
|
+
if (sandboxId) {
|
|
1447
|
+
return db2.query("SELECT * FROM snapshots WHERE sandbox_id = ? ORDER BY created_at DESC").all(sandboxId);
|
|
1448
|
+
}
|
|
1449
|
+
return db2.query("SELECT * FROM snapshots ORDER BY created_at DESC").all();
|
|
1450
|
+
}
|
|
1451
|
+
function deleteSnapshot(id) {
|
|
1452
|
+
const db2 = getDatabase();
|
|
1453
|
+
const resolvedId = resolvePartialId("snapshots", id);
|
|
1454
|
+
if (!resolvedId)
|
|
1455
|
+
throw new SnapshotNotFoundError(id);
|
|
1456
|
+
db2.query("DELETE FROM snapshots WHERE id = ?").run(resolvedId);
|
|
1457
|
+
}
|
|
1346
1458
|
// src/lib/config.ts
|
|
1347
1459
|
import { existsSync as existsSync2, readFileSync, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
1348
1460
|
import { dirname as dirname2, join as join2 } from "path";
|
|
@@ -1438,6 +1550,47 @@ function getConfigValue(key) {
|
|
|
1438
1550
|
}
|
|
1439
1551
|
return;
|
|
1440
1552
|
}
|
|
1553
|
+
// src/lib/images.ts
|
|
1554
|
+
var BUILTIN_IMAGES = {
|
|
1555
|
+
node20: {
|
|
1556
|
+
e2b: "e2bdev/base:latest",
|
|
1557
|
+
description: "Node 20 + npm + pnpm + yarn",
|
|
1558
|
+
setup_script: "curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g pnpm yarn"
|
|
1559
|
+
},
|
|
1560
|
+
"node20-claude": {
|
|
1561
|
+
e2b: "e2bdev/base:latest",
|
|
1562
|
+
description: "Node 20 + Claude Code CLI pre-installed",
|
|
1563
|
+
setup_script: `curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g @anthropic-ai/claude-code && mkdir -p ~/.claude && echo '{"hasCompletedOnboarding":true,"hasTrustDialogAccepted":true,"hasAcknowledgedCostThreshold":true}' > ~/.claude.json`
|
|
1564
|
+
},
|
|
1565
|
+
"node20-codex": {
|
|
1566
|
+
e2b: "e2bdev/base:latest",
|
|
1567
|
+
description: "Node 20 + Codex CLI pre-installed",
|
|
1568
|
+
setup_script: `curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g @openai/codex && mkdir -p ~/.codex && echo '[core]
|
|
1569
|
+
approvalMode = "full-auto"
|
|
1570
|
+
' > ~/.codex/config.toml`
|
|
1571
|
+
},
|
|
1572
|
+
python312: {
|
|
1573
|
+
e2b: "e2bdev/base:latest",
|
|
1574
|
+
description: "Python 3.12 + uv + pip",
|
|
1575
|
+
setup_script: "apt-get update && apt-get install -y python3.12 python3-pip && pip3 install uv"
|
|
1576
|
+
},
|
|
1577
|
+
"python312-agents": {
|
|
1578
|
+
e2b: "e2bdev/base:latest",
|
|
1579
|
+
description: "Python 3.12 + uv + common AI libs",
|
|
1580
|
+
setup_script: "apt-get update && apt-get install -y python3.12 python3-pip && pip3 install uv anthropic openai langchain"
|
|
1581
|
+
},
|
|
1582
|
+
fullstack: {
|
|
1583
|
+
e2b: "e2bdev/base:latest",
|
|
1584
|
+
description: "Node 20 + Python 3.12 + git + build tools",
|
|
1585
|
+
setup_script: "apt-get update && apt-get install -y git build-essential python3.12 python3-pip && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && npm install -g pnpm"
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1588
|
+
function resolveImage(image) {
|
|
1589
|
+
return BUILTIN_IMAGES[image]?.e2b ?? image;
|
|
1590
|
+
}
|
|
1591
|
+
function getBuiltinImageSetupScript(image) {
|
|
1592
|
+
return BUILTIN_IMAGES[image]?.setup_script;
|
|
1593
|
+
}
|
|
1441
1594
|
// src/providers/index.ts
|
|
1442
1595
|
init_types();
|
|
1443
1596
|
var providerCache = new Map;
|
|
@@ -1656,12 +1809,14 @@ export {
|
|
|
1656
1809
|
setConfigValue,
|
|
1657
1810
|
saveConfig,
|
|
1658
1811
|
resolvePartialId,
|
|
1812
|
+
resolveImage,
|
|
1659
1813
|
resetDatabase,
|
|
1660
1814
|
registerAgent,
|
|
1661
1815
|
now,
|
|
1662
1816
|
loadConfig,
|
|
1663
1817
|
listWebhooks,
|
|
1664
1818
|
listTemplates,
|
|
1819
|
+
listSnapshots,
|
|
1665
1820
|
listSessions,
|
|
1666
1821
|
listSandboxes,
|
|
1667
1822
|
listProjects,
|
|
@@ -1671,6 +1826,7 @@ export {
|
|
|
1671
1826
|
getWebhook,
|
|
1672
1827
|
getTemplateByName,
|
|
1673
1828
|
getTemplate,
|
|
1829
|
+
getSnapshot,
|
|
1674
1830
|
getSession,
|
|
1675
1831
|
getSandbox,
|
|
1676
1832
|
getProviderApiKey,
|
|
@@ -1682,6 +1838,7 @@ export {
|
|
|
1682
1838
|
getDefaultImage,
|
|
1683
1839
|
getDatabase,
|
|
1684
1840
|
getConfigValue,
|
|
1841
|
+
getBuiltinImageSetupScript,
|
|
1685
1842
|
getAgentDriver,
|
|
1686
1843
|
getAgentByName,
|
|
1687
1844
|
getAgent,
|
|
@@ -1690,12 +1847,14 @@ export {
|
|
|
1690
1847
|
emitLifecycleEvent,
|
|
1691
1848
|
deleteWebhook,
|
|
1692
1849
|
deleteTemplate,
|
|
1850
|
+
deleteSnapshot,
|
|
1693
1851
|
deleteSandbox,
|
|
1694
1852
|
deleteProject,
|
|
1695
1853
|
deleteAgent,
|
|
1696
1854
|
createWebhook,
|
|
1697
1855
|
createTemplate,
|
|
1698
1856
|
createStreamCollector,
|
|
1857
|
+
createSnapshot,
|
|
1699
1858
|
createSession,
|
|
1700
1859
|
createSandbox,
|
|
1701
1860
|
createProject,
|
|
@@ -1704,6 +1863,7 @@ export {
|
|
|
1704
1863
|
addEvent,
|
|
1705
1864
|
WebhookNotFoundError,
|
|
1706
1865
|
TemplateNotFoundError,
|
|
1866
|
+
SnapshotNotFoundError,
|
|
1707
1867
|
SessionNotFoundError,
|
|
1708
1868
|
SandboxNotFoundError,
|
|
1709
1869
|
SESSION_STATUSES,
|
|
@@ -1712,6 +1872,7 @@ export {
|
|
|
1712
1872
|
ProviderError,
|
|
1713
1873
|
ProjectNotFoundError,
|
|
1714
1874
|
EVENT_TYPES,
|
|
1875
|
+
BUILTIN_IMAGES,
|
|
1715
1876
|
AgentNotFoundError,
|
|
1716
1877
|
AGENT_TYPES
|
|
1717
1878
|
};
|
|
@@ -6,6 +6,9 @@ export interface RunAgentOpts {
|
|
|
6
6
|
command?: string;
|
|
7
7
|
onStdout?: (data: string) => void;
|
|
8
8
|
onStderr?: (data: string) => void;
|
|
9
|
+
callEnvVars?: Record<string, string>;
|
|
10
|
+
webhookUrl?: string;
|
|
11
|
+
webhookEvents?: ('start' | 'complete' | 'error')[];
|
|
9
12
|
}
|
|
10
13
|
export declare function runAgent(sandboxId: string, opts: RunAgentOpts): Promise<SandboxSession>;
|
|
11
14
|
export declare function stopAgent(sandboxId: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../../src/lib/agent-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../../src/lib/agent-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC,EAAE,CAAC;CACpD;AAcD,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,cAAc,CAAC,CAyGzB;AAED,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in sandbox image aliases.
|
|
3
|
+
* Maps a short name to the provider-specific image identifier.
|
|
4
|
+
* For E2B, these are custom images or base images with setup scripts.
|
|
5
|
+
*/
|
|
6
|
+
export declare const BUILTIN_IMAGES: Record<string, {
|
|
7
|
+
e2b: string;
|
|
8
|
+
description: string;
|
|
9
|
+
setup_script?: string;
|
|
10
|
+
}>;
|
|
11
|
+
export declare function resolveImage(image: string): string;
|
|
12
|
+
export declare function getBuiltinImageSetupScript(image: string): string | undefined;
|
|
13
|
+
//# sourceMappingURL=images.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/lib/images.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CA+BtG,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE5E"}
|