the universal sandbox runtime for agents and humans. pocketenv.io
sandbox openclaw agent claude-code vercel-sandbox deno-sandbox cloudflare-sandbox atproto sprites daytona
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

Create sandbox if missing when starting

When a sandbox record has no sandboxId, create a new sandbox using
decrypted credentials and persist the sandboxId to the database.

Also catch errors when fetching a Daytona sandbox and fall back to
creating a new sandbox

+29 -4
+16
apps/sandbox/src/index.ts
··· 261 261 .execute(), 262 262 ]); 263 263 264 + if (!record.sandboxId) { 265 + sandbox = await createSandbox(record.provider as Provider, { 266 + id: record.id, 267 + daytonaApiKey: decrypt(daytonaAuthParams?.apiKey), 268 + organizationId: daytonaAuthParams?.organizationId, 269 + spriteToken: decrypt(spriteAuthParams?.spriteToken), 270 + }); 271 + const sandboxId = await sandbox.id(); 272 + await c.var.db 273 + .update(sandboxes) 274 + .set({ sandboxId }) 275 + .where(eq(sandboxes.id, record.id)) 276 + .execute(); 277 + record.sandboxId = sandboxId; 278 + } 279 + 264 280 sandbox = await getSandboxById( 265 281 record.provider as Provider, 266 282 record.sandboxId!,
+13 -4
apps/sandbox/src/providers/mod.ts
··· 84 84 organizationId?: string, 85 85 ): Promise<BaseSandbox> { 86 86 switch (provider) { 87 - case "daytona": 88 - return import("./daytona/mod.ts").then((module) => 89 - new module.default().get(id, token, organizationId), 90 - ); 87 + case "daytona": { 88 + const module = await import("./daytona/mod.ts"); 89 + try { 90 + return new module.default().get(id, token, organizationId); 91 + } catch (err) { 92 + console.error(`Error getting Daytona sandbox with ID ${id}:`, err); 93 + return createSandbox("daytona", { 94 + id, 95 + daytonaApiKey: token, 96 + organizationId, 97 + }); 98 + } 99 + } 91 100 case "deno": { 92 101 const module = await import("./deno/mod.ts"); 93 102 try {