Ambient mode allows your bot to passively listen to all messages in configured channels and autonomously decide whether to respond. Unlike the default @mention mode, the bot observes the full conversation flow and only speaks up when it has something valuable to add.
- Messages in configured channels (that are not @mentions) are buffered per-channel.
- When a time trigger (
flush_interval_seconds) or count trigger (flush_max_messages) fires, the batch is sent to the LLM. - The LLM evaluates the conversation and either:
- Replies with a helpful response → posted to the channel.
- Returns
[NO_REPLY]→ silently suppressed, nothing is posted.
- If someone @mentions the bot in an ambient channel, the buffer is discarded and the mention is handled normally (immediate response).
[ambient]
enabled = true
flush_interval_seconds = 60 # Time trigger (±20% jitter applied)
flush_max_messages = 10 # Count trigger
flush_hard_cap = 50 # Safety cap on buffer size
max_concurrent_flushes = 3 # Global LLM concurrency limit
flush_timeout_seconds = 120 # Safety timeout per flush
instructions_file = "~/.openab/config/ambient.md" # Custom system prompt (optional)
debug = false # ⚠️ Only enable in test channels (exposes prompt + messages)
[ambient.discord]
channels = ["1234567890"] # Channel IDs to monitor (and their threads)
allow_bot_messages = true # Include other bots' messages in buffer (default)The instructions_file field points to a Markdown file whose content is used as the ambient system prompt. This works like a user-defined .cursorrules or CLAUDE.md — you control how the bot behaves in ambient mode by editing one file.
- Default path:
~/.openab/config/ambient.md - Max length: First 2000 characters are used; content beyond that is truncated.
- Fallback: If the file does not exist, the built-in default instructions are used.
- Restart required: The file is read once at startup. To apply changes, restart the bot.
Example ~/.openab/config/ambient.md:
You are passively observing a Discord channel.
- Reply EXACTLY `[NO_REPLY]` if you have nothing to add
- Only speak up for technical corrections or when directly asked
- Keep replies concise| Field | Default | Description |
|---|---|---|
enabled |
false |
Master switch. Must be explicitly enabled. |
debug |
false |
When true, posts system prompt + transcript to channel on each flush and lets [NO_REPLY] responses through (not suppressed). |
flush_interval_seconds |
60 |
Seconds between time-based flushes. ±20% jitter prevents thundering herd. Min: 1. |
flush_max_messages |
10 |
Flush when this many messages accumulate. Min: 1. |
flush_hard_cap |
50 |
Maximum buffer size. Messages beyond this are dropped. Min: 1. |
max_concurrent_flushes |
3 |
Max simultaneous LLM calls across all ambient channels. Min: 1. |
flush_timeout_seconds |
120 |
Safety timeout — resets flushing state if exceeded. Clamped to [5, 600]. |
instructions_file |
~/.openab/config/ambient.md |
Path to custom instructions file. First 2000 chars used as system prompt. Falls back to built-in default if missing. |
channels |
[] |
Explicit channel allowlist (required). Empty = ambient disabled. |
allow_bot_messages |
true |
Whether other bots' messages enter the ambient buffer. |
Threads are observed by default. Messages in threads whose parent is a configured channel are buffered too (most OpenAB conversation happens in auto-created threads, not the parent channel). Both bot-owned and non-owned threads are observed — the bot passively follows all thread conversation under an ambient channel. An @mention in any thread discards its buffer and triggers immediate dispatch, so there is no double-reply. Each thread batches independently (keyed by the thread ID).
[ambient.discord].channelsvs[discord].allowed_channels— these are independent allowlists with an OR relationship:
Config Purpose Effect [discord].allowed_channelsNormal dispatch Bot responds to @mentions and direct messages in these channels/threads [ambient.discord].channelsPassive observation Bot silently buffers messages (no @mention required) and decides whether to reply A channel can appear in one or both. Ambient observation does not require the channel to also be in
allowed_channels.@mention always works in ambient channels. Even if a channel is only in
[ambient.discord].channels(not inallowed_channels), an @mention still triggers immediate normal dispatch — the ambient buffer is discarded and the bot responds directly. The only difference between the two configs is behavior without a mention:allowed_channelsignores unmentioned messages entirely, whileambient.discord.channelspassively observes them.
| Field | Default | Description |
|---|---|---|
context_window |
20 |
Historical messages to fetch before each batch (not yet implemented). |
pool.max_sessions |
5 |
Max concurrent ambient sessions (not yet enforced). |
pool.session_ttl_minutes |
60 |
Session inactivity timeout (not yet enforced). |
pool.context_flushes |
3 |
Rolling flush history window (not yet enforced). |
When someone @mentions the bot in an ambient channel:
- The ambient buffer is immediately invalidated (current batch discarded).
- The mention is handled via normal dispatch (immediate response).
- After the mention is handled, ambient buffering resumes for new messages.
Buffered messages that arrived before the mention are not lost — they carry into the next ambient cycle.
The bot uses a system prompt that instructs it to respond with [NO_REPLY] when it has nothing to add. This sentinel is intercepted before delivery — it never appears in the channel. The filtering uses a capture adapter that forces non-streaming mode to ensure the full response is evaluated before any message is sent.
Ambient sessions use the namespace ambient:discord:<channel_id>, separate from normal dispatch sessions. There is no collision with @mention sessions.
- Jittered intervals prevent all channels from flushing simultaneously.
- Global semaphore caps concurrent LLM calls (default: 3).
[NO_REPLY]means most flushes produce no visible output (only one LLM call, no channel message).enabled = falsedefault means zero cost until explicitly opted in.
| Limitation | Description | Planned fix |
|---|---|---|
| Tool access | Ambient flushes have full tool access (same as @mention). | v2: restricted dispatch target |
| In-flight cancel | A @mention during LLM generation cannot stop the ambient response mid-stream. | v2: tokio::select! preemption |
| Consumer supervision | If a consumer task panics, that channel's ambient is permanently disabled until restart. | v2: health check + respawn |
| No history fetch | context_window (Discord API history before batch) is not yet implemented. |
v2 |
| No cooldown | No minimum interval between consecutive flushes for a single channel. | v2 |
Minimal config to enable ambient mode on one channel:
[ambient]
enabled = true
[ambient.discord]
channels = ["1490282656913559673"]This uses all defaults: 60s flush interval, max 10 messages per batch, 3 concurrent flushes.