Quickstart
Create an agentOS actor, launch an isolated VM session, run a coding agent, send a prompt, and inspect the durable result.
Quick Start
Install
- @rivet-dev/agentos — Actor framework with built-in persistence and orchestration
- @agentos-software/pi — Pi coding agent. Claude Code, Codex, and OpenCode install the same way.
npm install @rivet-dev/agentos @agentos-software/pi
Create the server
import { agentOS, setup } from "@rivet-dev/agentos";
import pi from "@agentos-software/pi";
const vm = agentOS({
software: [pi],
});
export const registry = setup({ use: { vm } });
registry.start();
Create the client
The client can be any public frontend or another backend. The same vm actor is reachable from a plain Node script, a browser/React app, or a separate server.
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({
endpoint: "http://localhost:6420",
});
const handle = client.vm.getOrCreate("my-agent");
// Subscribe to streaming events. The payload is inferred from the event schema.
const conn = handle.connect();
conn.on("sessionEvent", (event) => {
console.log(event);
});
// Open a durable session and send a prompt.
await handle.sessions.open({
agent: "pi",
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
await handle.sessions.prompt({
content: [
{ type: "text", text: "Write a hello world script to /workspace/hello.js" },
],
});
// Read the file the agent created
const content = await handle.filesystem.readFile("/workspace/hello.js");
console.log(new TextDecoder().decode(content));
import { createRivetKit } from "@rivet-dev/agentos/react";
import { useState } from "react";
import type { registry } from "./server";
const { useActor } = createRivetKit<typeof registry>("http://localhost:6420");
export function Agent() {
const [log, setLog] = useState("");
const agent = useActor({ name: "vm", key: "my-agent" });
// Stream agent events into component state
agent.useEvent("sessionEvent", (event) => {
setLog((prev) => prev + JSON.stringify(event) + "\n");
});
async function run() {
// In production, inject credentials on the server (see /docs/models-and-credentials)
const connection = agent.connection;
if (!connection) return;
await connection.sessions.open({
agent: "pi",
env: { ANTHROPIC_API_KEY: process.env.VITE_ANTHROPIC_API_KEY! },
});
await connection.sessions.prompt({
content: [
{
type: "text",
text: "Write a hello world script to /workspace/hello.js",
},
],
});
}
return (
<div>
<button onClick={run}>Run agent</button>
<pre>{log}</pre>
</div>
);
}
Run it
Start the server, then run the client in a second terminal:
# Terminal 1: start the server
npx tsx server.ts
# Terminal 2: run the client
npx tsx client.ts
With the server running, open http://localhost:6420/ui to watch the VM in the actor inspector: the live transcript, the filesystem, and its processes.
Customize
Now that you have a working agent, customize it to fit your needs:
- Software — Install software packages inside the VM
- Filesystem — Read, write, and manage files inside the VM
- Permissions & Resource Limits — Gate what the agent can do and cap its resource usage
- Bindings — Expose your JavaScript functions to agents as CLI commands
Deploy
By default, agentOS runs locally with npx rivetkit dev — no infrastructure needed. To run in production, deploy to any of these targets:
By default, Rivet stores actor state on the local file system.
To scale Rivet in production, pick how much of it you want to run yourself:
Fully managed
Bring your own compute
Full self-hosting
If you are running your own workers, follow the guide for your hosting provider:
agentOS is in preview and the API is subject to change. If you run into issues, please report them on GitHub or join our Discord.
Embedded API
The @rivet-dev/agentos-core package exports AgentOs.create() for embedded VM
control without the actor lifecycle, multiplayer, or orchestration layer.
Read more in the embedded API quickstart.