Skip to content
GitHub Get Started
Reference

Software Definition

Software is anything you install into a VM: an agent, a command package, or a set of WASM commands. Every package, including the built-ins, is declared with defineSoftware() and passed to the software option.

import { agentOS, setup } from "@rivet-dev/agentos";
import pi from "@agentos-software/pi";
const vm = agentOS({ software: [pi /*, …more */] });
export const registry = setup({ use: { vm } });
registry.start();

defineSoftware() is a typed identity helper. It returns the descriptor unchanged but gives you full type-checking. The descriptor’s type field discriminates between the three kinds of software.

  • "agent": a coding agent runnable via createSession(id). Key fields: agent, requires, packageDir.
  • "tool": command-package software exposed inside the VM. Key fields: bins, requires, packageDir.
  • "wasm-commands": compiled WASM command binaries. Key fields: commandDir, aliases, permissions.

All descriptors share two base fields:

  • name (required). The software package name.
  • type (required). One of "agent", "tool", or "wasm-commands".

Registers a coding agent. See Custom Agents for the agent-focused guide; this is the full field reference.

  • packageDir (required). This package’s directory on the host. Resolves requires from its own node_modules/, mounted into the VM at /root/node_modules/<pkg>.
  • requires (required). npm packages that must be available inside the VM (must include the adapter and agent packages).
  • agent.id (required). The id passed to createSession(id). Reuse a built-in id to override it, or pick a new one.
  • agent.acpAdapter (required). npm package of the ACP adapter, spawned inside the VM. Must be in requires.
  • agent.agentPackage (required). npm package of the underlying agent SDK/CLI. Must be in requires.
  • agent.staticEnv (optional). Static env vars passed when spawning the adapter (merged under user env).
  • agent.env (optional). (ctx: SoftwareContext) => Record<string, string>; env computed at boot, e.g. to resolve a bin path.
  • agent.launchArgs (optional). Extra CLI args prepended when launching the adapter.
pi.ts
import { defineSoftware } from "@rivet-dev/agentos";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const packageDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
export default defineSoftware({
name: "pi",
type: "agent",
packageDir,
requires: ["@agentos-software/pi", "@mariozechner/pi-coding-agent"],
agent: {
id: "pi",
acpAdapter: "@agentos-software/pi",
agentPackage: "@mariozechner/pi-coding-agent",
},
});

Exposes one or more CLI commands inside the VM by mapping a command name to the npm package that provides its bin. The descriptor value is still "tool" because this is the software package type, separate from host bindings.

  • packageDir (required). This package’s directory on the host (resolves requires).
  • requires (required). npm packages that must be available inside the VM.
  • bins (required). Record<commandName, packageName>, mapping the command name as invoked in the VM to the npm package providing it.
my-tool.ts
import { defineSoftware } from "@rivet-dev/agentos";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const packageDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
export default defineSoftware({
name: "my-tool",
type: "tool",
packageDir,
requires: ["@my-org/my-cli"],
bins: { "my-cli": "@my-org/my-cli" },
});

Registers compiled WebAssembly command binaries (coreutils, ripgrep, jq, …). See Building Binaries for how to produce the binaries.

  • commandDir (required). Absolute host path to the directory of .wasm command binaries.
  • aliases (optional). Record<aliasName, targetCommandName>; symlink-style aliases.
  • permissions (optional). Permission-tier assignments: full, readWrite, readOnly (string[] or "*"), isolated.
my-commands.ts
import { defineSoftware } from "@rivet-dev/agentos";
export default defineSoftware({
name: "my-commands",
type: "wasm-commands",
commandDir: "/abs/path/to/wasm",
aliases: { ll: "ls" },
permissions: { readOnly: "*" },
});

The agent.env callback (and other dynamic config) receives a SoftwareContext for resolving VM-side paths:

interface SoftwareContext {
// Resolve a package's bin to its VM path, e.g.
// ctx.resolveBin("@mariozechner/pi-coding-agent", "pi")
// -> "/root/node_modules/@mariozechner/pi-coding-agent/dist/cli.js"
resolveBin(packageName: string, binName?: string): string;
// Resolve a package root to its VM path, e.g.
// ctx.resolvePackage("pi-acp") -> "/root/node_modules/pi-acp"
resolvePackage(packageName: string): string;
}
agent: {
id: "pi-cli",
acpAdapter: "pi-acp",
agentPackage: "@mariozechner/pi-coding-agent",
env: (ctx) => ({
PI_ACP_PI_COMMAND: ctx.resolveBin("@mariozechner/pi-coding-agent", "pi"),
}),
}

A software entry may be an array of descriptors, letting one package bundle several (e.g. a “build-essential” set). Pass arrays directly to software:

const vm = agentOS({
software: [pi, buildEssential /* = [coreutils, make, git, curl] */],
});