Skip to main content

Overview

Run coding agents inside isolated VMs with full filesystem, process, and network control.

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.

Quickstart

Features

  • Isolated VMs: Each agent gets its own filesystem, processes, and networking. No shared state, no cross-contamination.
  • Multi-Agent Support: Run Amp, Claude Code, Codex, OpenCode, and PI with a unified API. Swap agents without changing your code.
  • Host Tools: Expose your JavaScript functions to agents as CLI commands. Direct binding with near-zero latency and automatic code mode for up to 80% token reduction.
  • Persistent State: Filesystem and transcripts survive sleep/wake cycles automatically. No external database needed.
  • Orchestration: Workflows, queues, cron jobs, and multi-agent coordination built on Rivet Actors.
  • Hybrid Sandboxes: Run agents in the lightweight VM by default. Spin up a full sandbox on demand for browsers, compilation, and desktop automation.

When to Use agentOS

  • Coding agents: Run any coding agent with full OS access, file editing, shell execution, and tool use.
  • Automated pipelines: CI-like workflows where agents clone repos, fix bugs, run tests, and open PRs.
  • Multi-agent systems: Coordinators dispatching to specialized agents, review pipelines, planning chains.
  • Scheduled maintenance: Cron-based agents that audit code, update dependencies, or generate reports.
  • Collaborative workspaces: Multiple users observing and interacting with the same agent session in realtime.

Minimal Project

After the quickstart, customize your agent with the Registry.

Quick Reference

Sessions & Transcripts

Create agent sessions, send prompts, and stream responses in realtime. Transcripts are persisted automatically across sleep/wake cycles.

Documentation

Permissions

Approve or deny agent tool use with human-in-the-loop patterns or auto-approve for trusted workloads.

Documentation

Tools

Expose your JavaScript functions to agents as CLI commands inside the VM. Agents call them as shell commands with auto-generated flags from Zod schemas.

import { toolKit, hostTool } from "@rivet-dev/agent-os-core";
import { z } from "zod";

const myTools = toolKit({
  name: "myapp",
  description: "Application tools",
  tools: {
    createTicket: hostTool({
      description: "Create a ticket in the issue tracker",
      inputSchema: z.object({
        title: z.string().describe("Ticket title"),
        priority: z.enum(["low", "medium", "high"]).describe("Priority level"),
      }),
      execute: async (input) => {
        const ticket = await db.tickets.create(input);
        return { id: ticket.id, url: ticket.url };
      },
    }),
  },
});

// Agent calls: agentos-myapp createTicket --title "Fix login" --priority high

Documentation

Filesystem

Read, write, and manage files inside the VM. The /home/user directory is persisted automatically across sleep/wake cycles.

Documentation

Processes & Shell

Execute commands, spawn long-running processes, and open interactive shells.

Documentation

Networking & Previews

Proxy HTTP requests into VMs with vmFetch. Create preview URLs for port forwarding VM services to shareable public URLs.

Documentation

Cron Jobs

Schedule recurring commands and agent sessions with cron expressions.

Documentation

Sandbox Extension

agentOS uses a hybrid model: agents run in a lightweight VM by default and spin up a full sandbox on demand for heavy workloads like browsers, compilation, and desktop automation.

import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";

const vm = agentOs({
  options: { software: [common, pi],
    sandbox: {
      enabled: true,
    },
  },
});

export const registry = setup({ use: { vm } });
registry.start();

Documentation

Multiplayer & Realtime

Connect multiple clients to the same agent VM. All subscribers see session output, process logs, and shell data in realtime.

Documentation

Agent-to-Agent

Compose specialized agents into pipelines. Each agent gets its own isolated VM and filesystem.

Documentation

Workflows

Orchestrate multi-step agent tasks with durable workflows that survive crashes and restarts.

import { agentOs } from "rivetkit/agent-os";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";
import { actor, setup, workflow } from "rivetkit";

const automator = actor({
  workflows: {
    fixBug: workflow<{ repo: string; issue: string }>(),
  },
  run: async (c) => {
    for await (const message of c.workflow.iter("fixBug")) {
      const { repo, issue } = message.body;
      const agentHandle = c.actors.vm.getOrCreate([`fix-${issue}`]);

      await c.step("clone-repo", async () => {
        return agentHandle.exec(`git clone ${repo} /home/user/repo`);
      });

      await c.step("fix-bug", async () => {
        const session = await agentHandle.createSession("pi", {
          env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
        });
        const response = await agentHandle.sendPrompt(
          session.sessionId,
          `Fix the bug described in issue: ${issue}`,
        );
        await agentHandle.closeSession(session.sessionId);
        return response;
      });

      await c.step("run-tests", async () => {
        return agentHandle.exec("cd /home/user/repo && npm test");
      });

      await message.complete();
    }
  },
});

const vm = agentOs({
  options: { software: [common, pi] },
});

export const registry = setup({ use: { automator, vm } });
registry.start();

Documentation

SQLite

Use actor-local SQLite as structured long-term memory that persists across sessions and sleep/wake cycles.

import { actor, setup } from "rivetkit";
import { db } from "rivetkit/db";

const memoryAgent = actor({
  db: db({
    onMigrate: async (db) => {
      await db.execute(`
        CREATE TABLE IF NOT EXISTS memories (
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          session_id TEXT NOT NULL,
          category TEXT NOT NULL,
          content TEXT NOT NULL,
          created_at INTEGER NOT NULL
        );
      `);
    },
  }),
  actions: {
    store: async (c, sessionId: string, category: string, content: string) => {
      await c.db.execute(
        "INSERT INTO memories (session_id, category, content, created_at) VALUES (?, ?, ?, ?)",
        sessionId, category, content, Date.now(),
      );
    },
    search: async (c, query: string) => {
      return c.db.execute(
        "SELECT category, content FROM memories WHERE content LIKE ? ORDER BY created_at DESC LIMIT 20",
        `%${query}%`,
      );
    },
  },
});

Documentation