podflare
v0.0.23
Published
Podflare TypeScript SDK — cloud sandbox for AI agents with 100ms fork() and persistent REPL.
Maintainers
Readme
Podflare — TypeScript SDK
Cloud sandbox for AI agents. Fork in 100 ms, persistent Python REPL, runCode, upload/download, mergeInto, interactive PTY sessions (pty.create / attach / sendInput / resize / kill).
- Docs: https://docs.podflare.ai
- Dashboard: https://dashboard.podflare.ai — mint an API key in seconds
- GitHub: https://github.com/PodFlare-ai/podflare
Install
npm install podflareQuickstart
import { Sandbox } from "podflare";
// Create a sandbox (persistent Python REPL)
const sbx = await Sandbox.create({ template: "python-datasci" });
// Execute code — state persists across calls
await sbx.runCode("x = 42");
const r = await sbx.runCode("print(x * 2)");
console.log(r.stdout); // "84"
// Fork — spawn N copies of the running sandbox
const children = await sbx.fork(5);
await children[0].runCode("x = 100");
// Merge a branch back into the parent
await sbx.mergeInto(children[0]);
// Upload + download files
await sbx.upload("data.csv", new TextEncoder().encode("a,b\n1,2"));
const csv = await sbx.download("data.csv");
// Destroy
await sbx.close();Configuration
| Env var | Default | What it does |
|----------------------|-------------------------------|--------------|
| PODFLARE_API_KEY | (none — required) | Bearer token from the dashboard (pf_live_...). |
| PODFLARE_HOSTD_URL | https://api.podflare.ai | Override for self-hosted or staging. |
You can also pass them in the constructor:
import { Sandbox } from "podflare";
const sbx = await Sandbox.create({
host: "https://api.podflare.ai",
apiKey: "pf_live_...",
template: "default",
});Streaming
for await (const ev of sbx.runCodeStream("for i in range(3): print(i)")) {
if (ev.type === "stdout") process.stdout.write(ev.data + "\n");
}Interactive PTY — sandbox.pty.*
For programs that demand a real tty (interactive installers, REPLs,
npm init, apt install, TUIs), use the PTY namespace. Sessions
survive client disconnects via a 1 MiB server-side ring buffer —
reconnect with sandbox.pty.attach(ptyId) from any later process.
import { Sandbox } from "podflare";
const sbx = await Sandbox.create({ region: "eu" });
// Spawn a real pseudo-terminal. timeoutMs: 0 = keep alive.
const pty = await sbx.pty.create({
cmd: "npm init",
cols: 120, rows: 40,
onData: (chunk) => process.stdout.write(chunk),
onExit: (code) => console.log(`exited ${code}`),
timeoutMs: 0,
});
// Send keystrokes — strings UTF-8, Uint8Array for control codes
await pty.sendInput("\r"); // Enter
await pty.sendInput(new Uint8Array([0x03])); // Ctrl-C
await pty.resize(200, 50); // child gets SIGWINCH
const exitCode = await pty.wait(); // resolves on pty_exitReconnect across processes / network blips
// Turn 1 — start a long-running shell
const pty = await sbx.pty.create({ cmd: "bash", timeoutMs: 0 });
await pty.sendInput("./build.sh 2>&1 | tee /tmp/build.log\n");
const ptyId = pty.id; // persist this across your agent's turns
// Turn 2 — different process, same running bash
const pty2 = await sbx.pty.attach(ptyId, {
onData: (chunk) => writeToUser(chunk),
});
// Replays the last 1 MiB of output, then streams live.
// pty2.sendInput / resize / kill all work.Full API: https://docs.podflare.ai/concepts/pty
Vercel AI SDK adapter
Drop-in tool for the Vercel AI SDK:
import { Sandbox } from "podflare";
import { sandboxTool } from "podflare/ai-sdk";
const sbx = await Sandbox.create();
const tools = { sandbox: sandboxTool(sbx) };
// pass `tools` to streamText / generateTextLinks
License
Proprietary.
