Sessions
Create agent sessions, send prompts, stream responses, and subscribe to events.
Sessions launch an agent inside the VM, stream its responses in real time over sessionEvent, and persist a replayable ACP transcript that survives sleep/wake.
Create a session
Use createSession to launch an agent inside the VM. Returns session metadata including capabilities and agent info. The agent starts in /home/agentos by default; override it with the cwd option below.
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
// createSession returns the session ID.
const sessionId = await agent.createSession("pi", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
console.log(sessionId);
createSession options
The second argument to createSession accepts:
env: environment variables for the agent process (e.g. API keys). Not inherited from the host.cwd: working directory inside the VM. Defaults to/home/agentos.mcpServers: MCP servers (local child processes or remote URLs) exposing extra tools.additionalInstructions: text appended to the agent’s system prompt.skipOsInstructions: skip the base OS instructions injection. Tool documentation is still included.
Send a prompt
Use sendPrompt to send a message to an active session. The response contains the agent’s reply.
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
const sessionId = await agent.createSession("pi", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
const response = await agent.sendPrompt(
sessionId,
"Create a TypeScript function that checks if a number is prime",
);
console.log(response.text);
Stream responses
Subscribe to sessionEvent to receive real-time streaming output from the agent.
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
const conn = agent.connect();
// Subscribe to session events before sending the prompt
conn.on("sessionEvent", (data) => {
console.log(`[${data.sessionId}]`, data.event.method, data.event.params);
});
const sessionId = await agent.createSession("pi", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
await agent.sendPrompt(sessionId, "Explain how async/await works");
Cancel a prompt
Use cancelPrompt to stop an in-progress prompt.
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
const sessionId = await agent.createSession("pi", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
// Start a long-running prompt
const promptPromise = agent.sendPrompt(
sessionId,
"Refactor the entire codebase to use TypeScript strict mode",
);
// Closing the session cancels the in-flight prompt and releases its resources.
setTimeout(async () => {
await agent.closeSession(sessionId);
}, 10_000);
const response = await promptPromise;
console.log(response.text);
Close and destroy sessions
closeSessiongracefully closes a session without removing persisted datadestroySessionremoves the session and all persisted data- To reconnect to a previously created session and replay its history, see Replay events and Resuming a suspended session
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
const sessionId = await agent.createSession("pi", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
// Close the live session. Persisted events remain available via
// getSessionEvents() / listPersistedSessions().
await agent.closeSession(sessionId);
Runtime configuration
Change model, mode, and thought level on a live session.
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
// Model, mode, and thought level are configured per session at creation time
// through createSession options and the agent's own configuration. There is no
// runtime mutation API on the VM handle.
const sessionId = await agent.createSession("pi", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
additionalInstructions: "Prefer a plan-first workflow and explain your reasoning.",
});
await agent.sendPrompt(sessionId, "Outline a plan before writing any code.");
Replay events
Use getSessionEvents to replay a session’s persisted events, including for VMs that are not currently running. Pair it with listPersistedSessions to find earlier sessions.
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
const sessionId = await agent.createSession("pi", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
await agent.sendPrompt(sessionId, "Hello");
// Replay persisted events
const events = await agent.getSessionEvents(sessionId);
console.log(events);
Persisted session history
Query session history from SQLite. Works even when the VM is not running.
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
// List all persisted sessions
const sessions = await agent.listPersistedSessions();
for (const s of sessions) {
console.log(s.sessionId, s.agentType, s.createdAt);
}
// Get full event history for a session
const events = await agent.getSessionEvents(sessions[0].sessionId);
for (const e of events) {
console.log(e.seq, e.event.method, e.createdAt);
}
Multiple sessions
A single VM can run multiple sessions simultaneously. Each session has its own agent process but shares the same filesystem. Use different session IDs to manage them independently.
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
// Create two sessions in the same VM
const coder = await agent.createSession("pi", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
const reviewer = await agent.createSession("pi", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
// Coder writes code
await agent.sendPrompt(coder, "Write a REST API at /home/agentos/api.ts");
// Reviewer reads and reviews the same file
await agent.sendPrompt(reviewer, "Review /home/agentos/api.ts for issues");
// Close each session independently
await agent.closeSession(coder);
await agent.closeSession(reviewer);
Agent logs
The agent (ACP adapter) runs as a process inside the VM. It uses stdout for ACP protocol traffic, so its stderr is the channel for logs, warnings, and crash diagnostics. Pass onAgentStderr to the VM to capture it, and route it to your own logger to see exactly what the agent is doing (or why it exited).
onAgentStderr is a VM-level option, so it covers every session’s agent process. It’s the fastest way to diagnose an agent that exits unexpectedly mid-turn; the crash reason surfaces here. If you omit it, chunks are written to the host process.stderr by default.
import { agentOS, setup } from "@rivet-dev/agentos";
// In a real app: import pi from "@agentos-software/pi";
import pi from "./software/pi";
// Swap in your own structured logger.
const logger = console;
const vm = agentOS({
software: [pi],
onAgentStderr(event) {
// event: { sessionId, agentType, processId, pid, chunk: Uint8Array }
const line = new TextDecoder().decode(event.chunk);
logger.info(`[agent:${event.agentType} session:${event.sessionId}] ${line}`);
},
});
export const registry = setup({ use: { vm } });
registry.start();