Skip to main content
General

Quickstart (Library)

Run agentOS VMs directly inside a Node.js application with @rivet-dev/agentos-core.

Use agentOS as a library to run VMs inside your own Node.js process. To create durable VMs by ID and control them over HTTP instead, see the hosted quickstart.

Which one should I use?

HostedLibrary
RunsAs a durable instance on Rivet Cloud or a self-hosted Docker imageEmbedded inside your process as a library
LifecycleDurable, sleeps when idle unless a process is running; see actor lifecycleEphemeral, runs until dispose() or process exit
Package@rivet-dev/agentos, or plain HTTP@rivet-dev/agentos-core
VM identityA durable VM you create by key and reach by IDA handle your process owns until dispose()
ConfigurationStored with the VM and versionedPassed to AgentOs.create()
ClientsYour backend, or browsers with a scoped JWTYour backend
Host accessNoneHost functions, host mounts, external sandboxes
PreviewsExpiring preview URLsNone
Best forLong-lived VMs shared across clientsEmbedding VMs in an existing backend

Create a VM

Install the library

npm install @rivet-dev/agentos-core

Create a VM

import { AgentOs } from "@rivet-dev/agentos-core";

// `AgentOs.create()` boots a VM inside this process and returns a handle to it.
const vm = await AgentOs.create();

The VM runs until dispose() is called or your process exits.

Show me the code

Run Bash Commands

const result = await vm.process.exec("echo hello && ls /home/agentos", {
	output: { capture: "all" },
});

console.log(result.stdout);

Work With the Filesystem

await vm.filesystem.writeFile("/home/agentos/hello.txt", "Hello, world!");

const file = await vm.filesystem.readFile("/home/agentos/hello.txt");

Run a Dev Server

Start a Node.js server in the VM, then send it a request from your process. The listener is not exposed on the host network.

await vm.filesystem.writeFile(
	"/home/agentos/server.js",
	`require("node:http")
		.createServer((req, res) => res.end("hello"))
		.listen(3000);`,
);

await vm.process.spawn("node", ["/home/agentos/server.js"]);

// The listener stays inside the VM. Send it a request from the host.
const response = await vm.network.httpRequest({ port: 3000, path: "/" });
console.log(new TextDecoder().decode(response.body));

Use the Language Runtimes

Run JavaScript, TypeScript, and Python directly, with npm and pip installs built in.

await vm.javascript.execute("console.log(1 + 2)");
await vm.typescript.execute("const n: number = 3; console.log(n)");

const answer = await vm.python.evaluate<number>("21 * 2");

Schedule Cron Jobs

vm.cron.schedule({
	id: "cleanup",
	schedule: "0 * * * *",
	action: { type: "exec", command: "rm", args: ["-rf", "/tmp/cache"] },
});

Install Software

Install tools from the software registry while the VM is running. Packages are verified against their digest before their commands appear on /opt/agentos/bin.

// Registry packages are published next to a manifest with each release.
const base = "https://releases.rivet.dev/agent-os/latest/software/";
const manifest = (await (await fetch(`${base}manifest.json`)).json()) as {
	artifacts: { name: string; digest: string; path: string }[];
};
const ripgrep = manifest.artifacts.find((artifact) => artifact.name === "ripgrep");
if (!ripgrep) throw new Error("ripgrep is not in the manifest");

await vm.software.install({
	type: "url",
	url: new URL(ripgrep.path, base).href,
	expectedDigest: ripgrep.digest,
});

Persist Files

The filesystem is in memory by default. Store the root filesystem in SQLite to keep files across VM recreation.

import { mkdirSync } from "node:fs";
import { resolve } from "node:path";
import { AgentOs, type AgentOsOptions } from "@rivet-dev/agentos-core";

mkdirSync(".agentos", { recursive: true });
const options = {
	// The SQLite file that stores the VM's durable state.
	database: {
		type: "sqlite_file",
		path: resolve(".agentos/agentos.sqlite"),
	},
	// Store the root filesystem in that database instead of in memory.
	rootFilesystem: {
		type: "native",
		plugin: { id: "chunked_sqlite", config: {} },
	},
} satisfies AgentOsOptions;

let vm = await AgentOs.create(options);
await vm.filesystem.writeFile("/home/agentos/result.txt", "persistent");
await vm.dispose();

vm = await AgentOs.create(options);
const result = await vm.filesystem.readFile("/home/agentos/result.txt");
console.log(new TextDecoder().decode(result));
await vm.dispose();

Next steps