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.

at main 74 lines 2.4 kB view raw
1import type { Context, Session, TerminalSocket } from "context"; 2import { eq, or } from "drizzle-orm"; 3import schema from "schema"; 4import { consola } from "consola"; 5import { Sandbox } from "e2b"; 6import decrypt from "lib/decrypt"; 7import type { Message } from "pty/pty-tunnel/messages"; 8 9export async function createTerminalSession( 10 ctx: Context, 11 id: string, 12 key = id, 13): Promise<Session> { 14 const [record] = await ctx.db 15 .select() 16 .from(schema.sandboxes) 17 .leftJoin(schema.e2bAuth, eq(schema.e2bAuth.sandboxId, schema.sandboxes.id)) 18 .where(or(eq(schema.sandboxes.id, id), eq(schema.sandboxes.sandboxId, id))) 19 .execute(); 20 21 if (!record?.e2b_auth) { 22 consola.error("E2B auth not found for sandbox", { id }); 23 throw new Error("E2B auth not found for sandbox " + id); 24 } 25 26 if (!record.sandboxes.sandboxId) { 27 consola.error("Sandbox ID not found for sandbox", { id }); 28 throw new Error("Sandbox ID not found for sandbox " + id); 29 } 30 31 const sandbox = await Sandbox.connect(record.sandboxes.sandboxId, { 32 apiKey: decrypt(record.e2b_auth.apiKey), 33 }); 34 35 // pid is set after pty.create() resolves; sendMessage closes over it. 36 let pid = 0; 37 38 const socket: TerminalSocket = { 39 sendMessage(msg: Message) { 40 if (msg.type === "message") { 41 sandbox.pty 42 .sendInput(pid, new TextEncoder().encode(msg.message)) 43 .catch((err) => consola.error("E2B PTY sendInput error:", err)); 44 } else if (msg.type === "resize") { 45 sandbox.pty 46 .resize(pid, { cols: msg.cols, rows: msg.rows }) 47 .catch((err) => consola.error("E2B PTY resize error:", err)); 48 } 49 }, 50 }; 51 52 const session: Session = { socket, clients: new Set(), wsClients: new Set() }; 53 54 const terminal = await sandbox.pty.create({ 55 cols: process.stdout.columns ?? 80, 56 rows: process.stdout.rows ?? 24, 57 onData: (data) => { 58 const text = Buffer.from(data).toString("utf-8"); 59 for (const res of session.clients) { 60 res.write("event: output\n"); 61 res.write(`data: ${JSON.stringify({ data: text })}\n\n`); 62 } 63 for (const ws of session.wsClients) { 64 if (ws.readyState === ws.OPEN) ws.send(text); 65 } 66 }, 67 }); 68 69 pid = terminal.pid; 70 consola.info("E2B PTY session created", { id, pid }); 71 72 ctx.sessions.set(key, session); 73 return session; 74}