A box for your agents
Give an AI agent a real computer — filesystem, shell, and npm — to run its own code and commands, safely.
An AI agent that can only talk is limited; one that can run things is useful. Lifo gives an agent a real computer — a filesystem, a bash-like shell, Node, and npm — that boots instantly and is safe to hand generated commands to. It runs server-side in Node (alongside your agent) or client-side in the browser.
A minimal tool the agent can call
Expose two primitives — run a command, read/write files — and your agent has a workspace:
import { Sandbox } from "@lifo-sh/core";
const box = await Sandbox.create({ cwd: "/workspace" });
// The tool your agent calls to execute a shell command.
async function run(command: string) {
const { stdout, stderr, exitCode } = await box.commands.run(command, {
cwd: "/workspace",
timeout: 30_000,
});
return { stdout, stderr, exitCode };
}
// File tools.
const writeFile = (path: string, content: string) => box.fs.writeFile(path, content);
const readFile = (path: string) => box.fs.readFile(path);Now the agent can scaffold a project, install packages, run tests, and read the results — a full edit-run-observe loop:
await writeFile("/workspace/fib.js", agentGeneratedCode);
const result = await run("node fib.js");
// feed result.stdout / result.exitCode back to the modelHeadless in Node (no browser needed)
Server-side, a box is just an object — perfect for an agent backend. No TTY means
no interactive prompts fire unless you feed stdin, and outbound fetch works
directly:
const box = await Sandbox.create(); // no terminal → headless
const { stdout } = await box.commands.run("npm init -y && npm install lodash && node -e \"console.log(require('lodash').VERSION)\"");Give each agent (or task) its own box
Spin up a box per agent, per session, or per task, and tear it down after — they share no state:
const boxes = new Map<string, Sandbox>();
async function boxFor(sessionId: string) {
if (!boxes.has(sessionId)) boxes.set(sessionId, await Sandbox.create());
return boxes.get(sessionId)!;
}Checkpoint and resume the agent's workspace
Snapshot the box between turns so an agent can pause and resume with its files intact — or branch a workspace by restoring the same image into two boxes:
const checkpoint = await box.fs.exportSnapshot(); // Uint8Array (tar.gz)
// later / elsewhere:
const resumed = await Sandbox.create();
await resumed.fs.importSnapshot(checkpoint);Keeping it safe
The box has no access to your host by default — see Run untrusted code for timeouts, cancellation, and the isolation model. Treat agent output as untrusted and bound every run.
Next
- Run untrusted code — timeouts, cancellation, isolation.
- Commands — add custom tools the agent can call.
- The Node runtime — how the box runs code.