Skip to main content
Advanced

Sessions & Persistence

How AgentOS stores exact ACP history and restores adapters through VM SQLite.

SQLite is the AgentOS source of truth for public session metadata, prompts, pending requests, and durable ACP events. Adapter-owned session files or databases remain private adapter state; AgentOS does not mirror them into the VFS or import adapter replay into public history.

One SQLite descriptor per VM

VM creation supplies exactly one trusted database descriptor:

  • actor_uds talks directly to Rivet actor SQLite through its authenticated Unix socket.
  • sqlite_file opens one local SQLite file for the logical VM on the sidecar’s bounded blocking executor.

The sidecar resolves the descriptor once and injects the same database handle into VFS metadata, VFS block storage, and the AgentOS core session store. Filesystem plugins receive only filesystem policy, not another SQLite path or UDS credential. One Rivet actor is one logical VM, so tables do not repeat a VM ID.

Each actor-UDS transaction generates a fresh UUID transaction key and attaches it to BEGIN, every statement, and COMMIT or ROLLBACK. Rivet owns transaction affinity and isolation. AgentOS adds no second UDS mux, pool, writer scheduler, or retry layer.

Independent schema owners

Three owners share the physical per-VM database without sharing a migration sequence:

OwnerVersion tableData tables
Native filesystemagentos_fs_schema_versionagentos_fs_*
Sidecar/core durable stateagentos_core_schema_versionagentos_core_*
TypeScript actor hosting metadataagentos_actor_schema_versionagentos_actor_*

Each version table is a STRICT singleton table. Its owner alone validates and advances its append-only migration ladder, updating the schema and version in the same transaction. A future version fails closed. There is no shared schema-version table, global AgentOS migration sequence, or AgentOS use of PRAGMA user_version; Rivet-owned schema metadata remains independent. Owners do not create cross-owner foreign keys.

Session event log

agentos_core_events keeps the durable envelope in scalar columns: public session ID, sequence, timestamp, negotiated ACP version, internal storage kind, correlation ID, payload byte length, and permission outcome fields. payload_json contains only the exact native ACP payload:

  • session_update stores an ACP SessionUpdate, including its sessionUpdate discriminator, optional fields, and _meta.
  • permission_request stores the ACP RequestPermissionRequest selected for public delivery.
  • permission_response stores the ACP RequestPermissionResponse.

The internal session_update storage kind is not a public event discriminator. On read, AgentOS exposes SessionUpdate.sessionUpdate as the event’s top-level type and places that ACP variant’s native fields directly beside it. Permission request and response fields are flattened the same way. The public AgentOS durability envelope is reconstructed from the scalar columns; it is not duplicated inside payload_json, and the row is not a raw JSON-RPC frame. This keeps event data ACP-native while giving AgentOS a stable sequence, timestamp, and public request correlation.

Complete user content is committed before prompt dispatch. Agent message and thought deltas are live and ephemeral; they receive no durable sequence and are coalesced into native ACP chunk updates only at a completed-message boundary. Other ACP updates are stored unchanged. Events are published only after their SQLite transaction commits. If an adapter emitted an event that never committed, SQLite wins, and AgentOS never automatically resends a prompt whose delivery is uncertain.

Trusted plaintext storage

The per-VM SQLite database is trusted runtime storage. Session environment values, MCP headers or credentials, prompts, message content, tool arguments and results, permission payloads, and cached adapter metadata may be stored as plaintext JSON or SQLite values so a session can restore after sleep. AgentOS does not currently encrypt, redact, or replace these values with secret references. Operators must protect database and backup access according to the sensitivity of the workload.

Retention and default bounds

Defaults are generous, VM-configurable limits.acp safeguards. AgentOS warns at 80% and returns a typed error naming the setting to raise when a hard-admission limit is reached.

Durable collectionDefaultContract
Sessions10,000 per VMHard admission limit; sessions are never evicted implicitly.
History1,000,000 events and 1 GiB per sessionOldest committed events are pruned in bounded batches; an older reconnect cursor returns history_cursor_expired.
Prompt/idempotency records100,000 per session; 1,000,000 per VMOldest unreferenced terminal records are pruned to admit new prompts. An idempotency key is authoritative only while its prompt record is retained.
Pending ask permissions1,000 per session; 10,000 per VMHard admission limit with no time-based expiry; lifecycle resolution is required.
Terminal permission outcomes10,000 per session; 100,000 per VMOldest outcomes are pruned. A late response gets its specific terminal reason while retained and request_not_found after pruning.

History counters and payload-byte totals are updated transactionally with insertion and pruning. Bootstrap reconciliation repairs counter drift from event rows. A single batch larger than the configured history event or byte bound fails atomically rather than partially committing.

Related request bounds default to 64 MiB and 16,384 blocks per prompt, 4 MiB of fallback continuation context, and 10,000 rows per session-list or history page.

Adapter restoration

Public session IDs do not depend on adapter IDs. When no live route exists, the sidecar starts the configured adapter and tries native ACP restoration in this order:

  1. session/resume when advertised by sessionCapabilities.resume.
  2. Stable session/load when loadSession is advertised.
  3. session/new plus bounded continuation context derived from recent SQLite history.

Notifications replayed by resume or load are discarded. This avoids duplicate public history and accommodates adapters whose restoration behavior differs despite ACP negotiation.

Actor lifecycle

Merely having durable sessions does not keep the actor awake. The prompt action uses actor keepAwake from dispatch through the terminal SQLite commit so the VM cannot sleep halfway through a turn. Read-only session operations never start an adapter and do not hold the actor awake.

Core tables

  • agentos_core_sessions: scalar session state and creation options, complex creation-option JSON, cached negotiation, retained-history counters, sequence bounds, and timestamps.
  • agentos_core_events: ordered exact ACP payloads with a scalar AgentOS envelope.
  • agentos_core_prompts: prompt idempotency hashes and terminal result or error; accepted input is represented by durable native ACP user updates rather than duplicate prompt JSON.
  • agentos_core_permission_records: actionable and terminal permission correlation.
  • agentos_core_permission_outcomes: bounded terminal outcomes used to answer late responses.

The filesystem’s agentos_fs_* and actor’s agentos_actor_* tables share the database handle but remain independently owned.