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 an agentId.
  • agents.defaults for 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/deliver and delivery-queue write mirrored entries.
  • delivery mirroring records 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.