Sessions
- Create sessions with any supported agent type
- Stream responses in real time via
sessionEventsubscriptions - Replay events with sequence numbers for reconnection and history
- Persist transcripts automatically in SQLite across sleep/wake cycles
- Universal transcript format using the Agent Communication Protocol (ACP)
Create a session
Section titled “Create a session”Use createSession to launch an agent inside the VM. Returns session metadata including capabilities and agent info.
import { createClient } from "rivetkit/client";import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");const agent = client.vm.getOrCreate(["my-agent"]);
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },});console.log(session.sessionId);console.log(session.capabilities);console.log(session.agentInfo);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] },});
export const registry = setup({ use: { vm } });registry.start();Environment variables to pass to the agent process. The VM does not inherit from the host process.env, so API keys must be passed explicitly.
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },});Working directory for the agent session inside the VM. Defaults to /home/user.
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! }, cwd: "/home/user/project",});mcpServers
Section titled “mcpServers”Pass MCP servers to give the agent access to additional tools. MCP servers provide typed tool definitions that the agent’s LLM can discover and call natively.
Local MCP server
Section titled “Local MCP server”Run an MCP server as a child process inside the VM.
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! }, mcpServers: [ { type: "local", command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user"], env: {}, }, ],});Remote MCP server
Section titled “Remote MCP server”Connect to an MCP server running outside the VM.
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! }, mcpServers: [ { type: "remote", url: "https://mcp.example.com/sse", headers: { Authorization: "Bearer my-token", }, }, ],});additionalInstructions
Section titled “additionalInstructions”Append custom instructions to the agent’s system prompt.
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! }, additionalInstructions: "Always write tests before implementation.",});skipOsInstructions
Section titled “skipOsInstructions”Skip the base OS instructions injection. Tool documentation is still included even when this is true.
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! }, skipOsInstructions: true,});Send a prompt
Section titled “Send a prompt”Use sendPrompt to send a message to an active session. The response contains the agent’s reply.
import { createClient } from "rivetkit/client";import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");const agent = client.vm.getOrCreate(["my-agent"]);
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },});const response = await agent.sendPrompt( session.sessionId, "Create a TypeScript function that checks if a number is prime",);console.log(response);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] },});
export const registry = setup({ use: { vm } });registry.start();Stream responses
Section titled “Stream responses”Subscribe to sessionEvent to receive real-time streaming output from the agent.
import { createClient } from "rivetkit/client";import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");const agent = client.vm.getOrCreate(["my-agent"]);
// Subscribe to session events before sending the promptagent.on("sessionEvent", (data) => { console.log(`[${data.sessionId}]`, data.event.method, data.event.params);});
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },});await agent.sendPrompt(session.sessionId, "Explain how async/await works");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] },});
export const registry = setup({ use: { vm } });registry.start();Cancel a prompt
Section titled “Cancel a prompt”Use cancelPrompt to stop an in-progress prompt.
import { createClient } from "rivetkit/client";import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");const agent = client.vm.getOrCreate(["my-agent"]);
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },});
// Start a long-running promptconst promptPromise = agent.sendPrompt( session.sessionId, "Refactor the entire codebase to use TypeScript strict mode",);
// Cancel after 10 secondssetTimeout(async () => { await agent.cancelPrompt(session.sessionId);}, 10_000);
const response = await promptPromise;console.log(response);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] },});
export const registry = setup({ use: { vm } });registry.start();Resume, close, and destroy sessions
Section titled “Resume, close, and destroy sessions”resumeSessionreconnects to a session that was suspended (e.g. after sleep)closeSessiongracefully closes a sessiondestroySessionremoves the session and all persisted data
import { createClient } from "rivetkit/client";import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");const agent = client.vm.getOrCreate(["my-agent"]);
// Resume a previously created sessionconst resumed = await agent.resumeSession("session-id-from-earlier");
// Close without destroying persisted dataawait agent.closeSession(resumed.sessionId);
// Destroy session and all persisted eventsawait agent.destroySession(resumed.sessionId);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] },});
export const registry = setup({ use: { vm } });registry.start();Runtime configuration
Section titled “Runtime configuration”Change model, mode, and thought level on a live session.
import { createClient } from "rivetkit/client";import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");const agent = client.vm.getOrCreate(["my-agent"]);
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },});
// Change modelawait agent.setModel(session.sessionId, "claude-sonnet-4-6");
// Change mode (e.g. "plan", "auto")await agent.setMode(session.sessionId, "plan");
// Change thought levelawait agent.setThoughtLevel(session.sessionId, "high");
// Query available optionsconst modes = await agent.getModes(session.sessionId);console.log(modes);
const options = await agent.getConfigOptions(session.sessionId);console.log(options);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] },});
export const registry = setup({ use: { vm } });registry.start();Replay events
Section titled “Replay events”Use getSequencedEvents to replay in-memory session events (for live reconnection while the VM is running), or getSessionEvents to replay from persisted storage (for transcript history, including when the VM is not running). See Events for details on the difference.
import { createClient } from "rivetkit/client";import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");const agent = client.vm.getOrCreate(["my-agent"]);
const session = await agent.createSession("pi", { env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },});await agent.sendPrompt(session.sessionId, "Hello");
// Get all eventsconst events = await agent.getEvents(session.sessionId);console.log(events);
// Get events with sequence numbers (for pagination/reconnection)const sequenced = await agent.getSequencedEvents(session.sessionId, { since: 0,});console.log(sequenced);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] },});
export const registry = setup({ use: { vm } });registry.start();Persisted session history
Section titled “Persisted session history”Query session history from SQLite. Works even when the VM is not running.
import { createClient } from "rivetkit/client";import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");const agent = client.vm.getOrCreate(["my-agent"]);
// List all persisted sessionsconst sessions = await agent.listPersistedSessions();for (const s of sessions) { console.log(s.sessionId, s.agentType, s.createdAt);}
// Get full event history for a sessionconst events = await agent.getSessionEvents(sessions[0].sessionId);for (const e of events) { console.log(e.seq, e.event.method, e.createdAt);}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] },});
export const registry = setup({ use: { vm } });registry.start();Multiple sessions
Section titled “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 "rivetkit/client";import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");const agent = client.vm.getOrCreate(["my-agent"]);
// Create two sessions in the same VMconst 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 codeawait agent.sendPrompt(coder.sessionId, "Write a REST API at /home/user/api.ts");
// Reviewer reads and reviews the same fileawait agent.sendPrompt(reviewer.sessionId, "Review /home/user/api.ts for issues");
// Close each session independentlyawait agent.closeSession(coder.sessionId);await agent.closeSession(reviewer.sessionId);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] },});
export const registry = setup({ use: { vm } });registry.start();Recommendations
Section titled “Recommendations”- Subscribe to
sessionEventbefore callingsendPromptto avoid missing early events. - Use
getSequencedEventswithsincefor reconnection. Track the last sequence number you processed. - Use
listPersistedSessionsandgetSessionEventsto build transcript history UIs without requiring a running VM. - Call
closeSessionwhen done to release resources. UsedestroySessiononly when you want to permanently delete session data.