Messages
Message flow, sessions, queues, streaming, and reasoning visibility.
This page ties together how OpenClaw handles inbound messages, sessions, queues, streaming, and reasoning visibility.
Message Flow (High-Level)
Inbound message -> routing/bindings -> session key -> queue (if a run is active) -> agent run (streaming + tools) -> outbound replies (channel limits + chunking)
Key knobs are mostly in configuration:
- ''messages.*'': prefixes, queues, and group chat behavior.
- ''agents.defaults.*'': block streaming and chunking defaults.
- Channel overrides (''channels.whatsapp.*'', ''channels.telegram.*'', etc.): limits and streaming switches.
Full schema at ''Configuration''.
Inbound Dedupe
Channels may redeliver the same message after reconnect. OpenClaw maintains a short-lived cache (keyed by channel/account/peer/session/message id) to avoid duplicate delivery triggering a second agent run.
Inbound Debouncing
When the same sender sends multiple messages in quick succession, ''messages.inbound'' can merge them into a single agent turn. Debouncing is scoped by channel + session and uses the "latest message" as the source for reply threading/IDs.
Configuration (global default + per-channel overrides):
{
messages: {
inbound: {
debounceMs: 2000,
byChannel: {
whatsapp: 5000,
slack: 1500,
discord: 1500
}
}
}
}Notes:
- Debouncing only applies to plain text; media/attachments flush immediately.
- Control commands bypass debouncing and remain as separate messages.
Sessions and Devices
Sessions are held by the gateway, not the client.
- Private messages default to folding into the agent's main session key.
- Group chats/channels use independent session keys.
- Session store and transcripts live on the gateway host.
Multiple devices/channels can map to the same session, but history doesn't 100% sync back to all clients. Recommendation: use one primary device for long conversations to avoid context forking. Control UI and TUI always show gateway-backed transcripts, so they are the source of truth.
Details: ''/concepts/session''.
ReferenceConceptsMessagesPage step 04: P7
Inbound Body and History Context
OpenClaw distinguishes between prompt body and command body:
- ''Body'': prompt text sent to the agent, possibly containing channel envelope and optional history wrappers.
- ''CommandBody'': raw user text used for directive/command parsing.
- ''RawBody'': legacy alias for ''CommandBody'' (kept for compatibility).
When channels provide history context, a unified wrapper is used:
- ''[Chat messages since your last reply - for context]''
- ''[Current message - respond to this]''
For non-direct chats (groups/channels/rooms), the current message body includes a sender label (same style as history entries) to make real-time messages more consistent with queued/history messages in the prompt.
History buffer is pending-only: includes group messages that didn't trigger a run due to mention gating, and excludes messages already written to the session transcript.
Directive stripping only applies to the ''current message'' block, ensuring history content remains unchanged. Channels wrapping history should set ''CommandBody'' (or ''RawBody'') to the raw message text and ''Body'' to the combined prompt. History buffer can be configured via ''messages.groupChat.historyLimit'' (global default) and channel overrides (e.g., ''channels.slack.historyLimit'', ''channels.telegram.accounts.<id>.historyLimit''); set to ''0'' to disable.
ReferenceConceptsMessagesPage step 05: P11
Queues and Followups
When a run is active, new inbound messages can be queued, injected into the current run for steering, or collected for subsequent turns:
- Configured via ''messages.queue'' (and ''messages.queue.byChannel'').
- Modes: ''interrupt'', ''steer'', ''followup'', ''collect'', and backlog variants.
Details: ''/concepts/queue''.
ReferenceConceptsMessagesPage step 06: P5
ReferenceConceptsMessagesPage step 06: P6
Streaming, Chunking, and Batching
Block streaming sends partial replies as the model produces text blocks. Chunking respects channel text limits and tries to avoid breaking fenced code.
Key settings:
- ''agents.defaults.blockStreamingDefault'' (''on|off'', default off)
- ''agents.defaults.blockStreamingBreak'' (''text_end|message_end'')
- ''agents.defaults.blockStreamingChunk'' (''minChars|maxChars|breakPreference'')
- ''agents.defaults.blockStreamingCoalesce'' (idle-based coalescing)
- ''agents.defaults.humanDelay'' (human-like pauses)
- Channel overrides: ''*.blockStreaming'' and ''*.blockStreamingCoalesce'' (non-Telegram channels need explicit ''*.blockStreaming: true'')
Reasoning Visibility and Tokens
OpenClaw can show or hide model reasoning:
- ''/reasoning on|off|stream'' controls visibility.
- Reasoning content counts toward token usage whenever it's produced by the model.
- Telegram supports streaming reasoning into draft bubbles.
Details: ''/tools/thinking'', ''/token-use''.
Prefixes, Threading, and Replies
Outbound formatting is centralized in ''messages'':
- ''messages.responsePrefix'' (outbound prefix) and ''channels.whatsapp.messagePrefix'' (WhatsApp inbound prefix)
- Reply threading controlled via ''replyToMode'' and per-channel defaults
Details: ''/gateway/configuration#messages'' and per-channel documentation.