Files
clawdbot/docs/concepts/messages.md
juanpablodlc 4a99b9b651 feat(whatsapp): add debounceMs for batching rapid messages (#971)
* feat(whatsapp): add debounceMs for batching rapid messages

Add a `debounceMs` configuration option to WhatsApp channel settings
that batches rapid consecutive messages from the same sender into a
single response. This prevents triggering separate agent runs for
each message when a user sends multiple short messages in quick
succession (e.g., "Hey!", "how are you?", "I was wondering...").

Changes:
- Add `debounceMs` config to WhatsAppConfig and WhatsAppAccountConfig
- Implement message buffering in `monitorWebInbox` with:
  - Map-based buffer keyed by sender (DM) or chat ID (groups)
  - Debounce timer that resets on each new message
  - Message combination with newline separator
  - Single message optimization (no modification if only one message)
- Wire `debounceMs` through account resolution and monitor tuning
- Add UI hints and schema documentation

Usage example:
{
  "channels": {
    "whatsapp": {
      "debounceMs": 5000  // 5 second window
    }
  }
}

Default behavior: `debounceMs: 0` (disabled by default)

Verified: All existing tests pass (3204 tests), TypeScript compilation
succeeds with no errors.

Implemented with assistance from AI coding tools.

Closes #967

* chore: wip inbound debounce

* fix: debounce inbound messages across channels (#971) (thanks @juanpablodlc)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-01-15 23:07:19 +00:00

4.8 KiB

summary, read_when
summary read_when
Message flow, sessions, queueing, and reasoning visibility
Explaining how inbound messages become replies
Clarifying sessions, queueing modes, or streaming behavior
Documenting reasoning visibility and usage implications

Messages

This page ties together how Clawdbot handles inbound messages, sessions, queueing, 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 live in configuration:

  • messages.* for prefixes, queueing, and group behavior.
  • agents.defaults.* for block streaming and chunking defaults.
  • Channel overrides (channels.whatsapp.*, channels.telegram.*, etc.) for caps and streaming toggles.

See Configuration for full schema.

Inbound dedupe

Channels can redeliver the same message after reconnects. Clawdbot keeps a short-lived cache keyed by channel/account/peer/session/message id so duplicate deliveries do not trigger another agent run.

Inbound debouncing

Rapid consecutive messages from the same sender can be batched into a single agent turn via messages.inbound. Debouncing is scoped per channel + conversation and uses the most recent message for reply threading/IDs.

Notes:

  • Debounce applies to text-only messages; media/attachments flush immediately.
  • Control commands bypass debouncing so they remain standalone.

Sessions and devices

Sessions are owned by the gateway, not by clients.

  • Direct chats collapse into the agent main session key.
  • Groups/channels get their own session keys.
  • The session store and transcripts live on the gateway host.

Multiple devices/channels can map to the same session, but history is not fully synced back to every client. Recommendation: use one primary device for long conversations to avoid divergent context. The Control UI and TUI always show the gateway-backed session transcript, so they are the source of truth.

Details: Session management.

Inbound bodies and history context

Clawdbot separates the prompt body from the command body:

  • Body: prompt text sent to the agent. This may include channel envelopes and optional history wrappers.
  • CommandBody: raw user text for directive/command parsing.
  • RawBody: legacy alias for CommandBody (kept for compatibility).

When a channel supplies history, it uses a shared wrapper:

  • [Chat messages since your last reply - for context]
  • [Current message - respond to this]

Directive stripping only applies to the current message section so history remains intact. Channels that wrap history should set CommandBody (or RawBody) to the original message text and keep Body as the combined prompt. History buffers are configurable via messages.groupChat.historyLimit (global default) and per-channel overrides like channels.slack.historyLimit or channels.telegram.accounts.<id>.historyLimit (set 0 to disable).

Queueing and followups

If a run is already active, inbound messages can be queued, steered into the current run, or collected for a followup turn.

  • Configure via messages.queue (and messages.queue.byChannel).
  • Modes: interrupt, steer, followup, collect, plus backlog variants.

Details: Queueing.

Streaming, chunking, and batching

Block streaming sends partial replies as the model produces text blocks. Chunking respects channel text limits and avoids splitting 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 batching)
  • agents.defaults.humanDelay (human-like pause between block replies)
  • Channel overrides: *.blockStreaming and *.blockStreamingCoalesce (non-Telegram channels require explicit *.blockStreaming: true)

Details: Streaming + chunking.

Reasoning visibility and tokens

Clawdbot can expose or hide model reasoning:

  • /reasoning on|off|stream controls visibility.
  • Reasoning content still counts toward token usage when produced by the model.
  • Telegram supports reasoning stream into the draft bubble.

Details: Thinking + reasoning directives and Token use.

Prefixes, threading, and replies

Outbound message formatting is centralized in messages:

  • messages.responsePrefix (outbound prefix) and channels.whatsapp.messagePrefix (WhatsApp inbound prefix)
  • Reply threading via replyToMode and per-channel defaults

Details: Configuration and channel docs.