Sessions and transcripts#
Sessions are the core routing and persistence unit. They isolate conversations, control scoping for DMs and threads, manage agent assignment, store transcripts, and drive delivery.
dmScope#
session.dmScope determines how direct messages are grouped into sessions:
main: all DMs share a single session (default for single-user setups).per-peer: one session per remote peer.per-channel-peer: one session per (channel, peer) pair (recommended for multi-user).per-account-channel-peer: one session per (account, channel, peer) triple.
Set via session.dmScope or per-channel overrides. The Gateway uses this when resolving inbound routes and when creating or looking up session keys.
Example:
{
session: {
dmScope: "per-channel-peer",
},
}
threadBindings#
session.threadBindings enables thread-aware session routing for channels that support threads (e.g. Discord).
{
session: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
},
},
}
enabled: turns on thread binding lookup.idleHours: time after which an idle thread binding may be cleaned.maxAgeHours: hard maximum age for bindings (0 = no limit).
Discord surfaces commands such as /focus, /unfocus, /agents, /session idle, and /session max-age to manage bindings at runtime. Bindings are stored as session binding records and consulted during outbound session key resolution.
Agent scoping and multi-agent routing#
Sessions are scoped to agents via:
agents.list[](id, workspace, defaults, sandbox, etc.).bindings[]array that matches(channel, accountId, peer)patterns to anagentId.agents.defaultsfor baseline model, workspace, skills, sandbox, heartbeat, etc.
Inbound events and outbound sends resolve the effective agent and session key using these rules. Sub-agents can be spawned; they carry spawnedBy, spawnDepth, parentSessionKey, and subagent* fields.
Global vs. agent-scoped keys: the literal key "global" is treated specially; agent-scoped globals use the form agent:<id>:global.
See Agents for agent and binding configuration.
Transcripts and storage#
Each session owns a transcript (messages, tool calls, lifecycle markers). Storage is file-based under the session store directory.
Key surfaces include sessions.list, sessions.get, sessions.preview, sessions.describe, chat.history, sessions.history, and sessions.messages.*. Transcripts are the source of truth for compaction, context, and delivery mirroring.
Compaction#
Compaction reduces transcript size while preserving essential history.
- Operator:
/compact,sessions.compact. - Automatic: agent runtime triggers on context pressure.
- Checkpoints: compaction checkpoints are persisted alongside transcripts.
- Safety: compaction runs under a timeout and can be aborted; failed compactions leave the original transcript intact.
After successful compaction the session transcript is replaced by the compacted version and a checkpoint record is written.
Manage from the CLI:
openclaw sessions compact <key>
Lifecycle events#
Sessions emit lifecycle events that are recorded in the transcript and projected to subscribers:
started,ended,abortedLastRun.- Runtime metadata:
runtimeMs,status,startedAt,endedAt.
Subscribers (chat, nodes, Control UI) receive session.operation and sessions.changed events. Restart recovery logic uses lifecycle markers to decide whether a prior run should be treated as aborted.
Session bindings#
Bindings link external conversations/threads to internal session keys:
- Thread bindings (per-channel thread routing).
- Conversation bindings (generic).
APIs and tools create, resolve, list, unbind, and touch binding records. Bindings store the mapping, last-used timestamps, and capabilities. They are consulted when resolving outbound session routes and when deciding whether a new inbound message should reuse an existing session.
Delivery mirroring#
Outbound delivery is mirrored into the session transcript so that sent messages, media, and rich content appear in history and context.
outbound/deliveranddelivery-queuewrite mirrored entries.delivery mirroringrecords the final sent payload (text, media, presentation, interactive blocks, channel data).- Session delivery queue persists pending deliveries across restarts; on recovery they are re-dispatched and mirrored.
Mirroring guarantees that sessions.history and agent context contain both inbound and the corresponding outbound turns.