Skip to main content
Operating System

Filesystem

Read, write, mount, and manage files inside agentOS.

Every VM comes with a persistent filesystem out of the box. Files written anywhere in the VM are automatically saved to the Rivet Actor’s built-in storage and restored on wake. No configuration needed.

  • Persistent by default backed by Rivet Actor storage, up to 10 GB
  • Full POSIX filesystem with read, write, mkdir, stat, move, delete
  • Batch operations for reading and writing multiple files at once
  • Mount backends for additional storage like S3, host directories, and overlays

Mounting filesystems

The default filesystem persists automatically across sleep/wake cycles with no setup required (up to 10 GB). For larger storage or external data, mount additional filesystem drivers via the options.mounts config.

Each mount takes a path (where to mount inside the VM), a driver (the filesystem implementation), and an optional readOnly flag.

In-memory

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

const vm = agentOs({
  options: {
    software: [common, pi],
    mounts: [
      { path: "/mnt/scratch", driver: createInMemoryFileSystem() },
    ],
  },
});

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

Host directory

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

const vm = agentOs({
  options: {
    software: [common, pi],
    mounts: [
      { path: "/mnt/code", driver: createHostDirBackend({ hostPath: "/path/to/repo" }), readOnly: true },
    ],
  },
});

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

S3

Install @rivet-dev/agent-os-s3 for S3-compatible storage.

Use createS3BackendForAgent to automatically scope S3 storage by agent key. Each agent instance gets its own prefix (agents/{key}/) within the bucket, so you don’t need to manage prefixes manually.

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

function createVm(context: AgentOsContext) {
  return agentOs({
    options: {
      software: [common, pi],
      mounts: [
        {
          path: "/mnt/data",
          driver: createS3BackendForAgent(context, {
            bucket: "my-bucket",
            region: "us-east-1",
          }),
        },
      ],
    },
  });
}

The AgentOsContext object contains:

  • key — unique identifier for the agent instance (e.g. actor ID, user ID, session ID). Used as the S3 prefix.
  • metadata — optional key-value pairs with additional agent information.

Fixed prefix

For shared storage or custom prefix schemes, use createS3Backend with an explicit prefix.

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

const vm = agentOs({
  options: {
    software: [common, pi],
    mounts: [
      {
        path: "/mnt/data",
        driver: createS3Backend({
          bucket: "my-bucket",
          prefix: "agent-data/",
          region: "us-east-1",
        }),
      },
    ],
  },
});

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

Google Drive

Install @rivet-dev/agent-os-google-drive for Google Drive storage.

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

const vm = agentOs({
  options: {
    software: [common, pi],
    mounts: [
      {
        path: "/mnt/drive",
        driver: new GoogleDriveBlockStore({
          credentials: {
            clientEmail: process.env.GOOGLE_DRIVE_CLIENT_EMAIL!,
            privateKey: process.env.GOOGLE_DRIVE_PRIVATE_KEY!,
          },
          folderId: process.env.GOOGLE_DRIVE_FOLDER_ID!,
        }),
      },
    ],
  },
});

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

Filesystem operations

Read and write

// Write a file (string or Uint8Array)
await agent.writeFile("/home/user/hello.txt", "Hello, world!");

// Read a file (returns Uint8Array)
const content = await agent.readFile("/home/user/hello.txt");
console.log(new TextDecoder().decode(content));

Batch read and write

// Batch write (creates parent directories automatically)
const writeResults = await agent.writeFiles([
  { path: "/home/user/src/index.ts", content: "console.log('hello');" },
  { path: "/home/user/src/utils.ts", content: "export function add(a: number, b: number) { return a + b; }" },
]);

// Batch read
const readResults = await agent.readFiles([
  "/home/user/src/index.ts",
  "/home/user/src/utils.ts",
]);
for (const result of readResults) {
  console.log(result.path, new TextDecoder().decode(result.content));
}

Directories

// Create a directory
await agent.mkdir("/home/user/projects");

// List directory contents
const entries = await agent.readdir("/home/user/projects");

// Recursive listing with metadata
const tree = await agent.readdirRecursive("/home/user", {
  maxDepth: 3,
  exclude: ["node_modules"],
});
for (const entry of tree) {
  console.log(entry.type, entry.path, entry.size);
}

File metadata

// Check if a path exists
const fileExists = await agent.exists("/home/user/hello.txt");

// Get file metadata
const info = await agent.stat("/home/user/hello.txt");
console.log(info.size, info.isDirectory, info.mtimeMs);

Move and delete

// Move/rename
await agent.move("/home/user/old.txt", "/home/user/new.txt");

// Delete a file
await agent.deleteFile("/home/user/new.txt");

// Delete a directory recursively
await agent.deleteFile("/home/user/temp", { recursive: true });