> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bumbleagi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Presence

> Always-on daemon, initiative, wake cycles, and multi-platform adapters.

Presence is how the entity shows up in the world. An always-on daemon ticks continuously — driving body state, memory consolidation, proactive behavior, and scheduled automations across every connected platform.

## Daemon

The daemon runs when you use `bumblebee run` (not `talk`). It manages two core loops via APScheduler:

<Columns>
  <div>
    ### Heartbeat (default 120s)

    * Tick soma bars, affects, and noise
    * Emit idle events after 60s silence
    * Check drives against thresholds
    * Refresh MCP server connections
    * Evaluate wake cycle conditions
  </div>

  <div>
    ### Consolidation (default 2h)

    * Process raw memories into durable episodes
    * Apply significance decay
    * Update relationship models
    * Trigger narrative synthesis (every 3rd cycle)
    * Run emergence analysis if enabled
  </div>
</Columns>

## Initiative and wake cycles

The entity can act on its own — not just respond to messages.

<Tabs>
  <Tab title="Drive-based initiative">
    This path runs when **`autonomy.enabled` is false** (legacy initiative in the daemon). When a drive exceeds its threshold (default 0.72) and enough time has passed since the last proactive message (`drives.initiative_cooldown` in entity YAML, default **1800** seconds if omitted), the entity composes and sends a message. The drive is then partially satisfied, dropping it below threshold.

    When **`autonomy.enabled` is true**, this legacy block is **not** used; instead, **drive** thresholds participate in [autonomous wake](/architecture/autonomous-wake) when `drive_wake` is enabled (full `perceive`, wake voice, rate limits, optional sustained sessions — not the same as this single-message path).

    To **disable full autonomous wakes** but keep the daemon, set `autonomy.enabled: false` and see [Autonomous wake → Disabling autonomous wake](/architecture/autonomous-wake#disabling-autonomous-wake) for what still can fire.
  </Tab>

  <Tab title="Autonomous wake cycles">
    When `autonomy.enabled` is true, the entity can wake itself. Wake conditions include soma **impulses**, **drive** thresholds, active **conflicts** (intensity > 0.4), optional **noise** salience (`noise_wake`), **desire pressure** (`desire_wake` + threshold), and a **randomized timer** between `base_wake_interval_min` and `base_wake_interval_max` minutes.

    Context includes platforms, desire summary, **wake voice** (`soma.wake_voice` — a reflex-composed first-person stirring), and optionally **poker prompts**: a YAML seed deck (`configs/poker_prompts/`) that biases cycles toward real-world exploration. With `ground_with_gen`, seeds are **woven** with GEN fragments and recent memory so disposition is grounded in perception, not only the file.

    One trigger can run **multiple** full perceive rounds (**sustained wake**), with worker logging, optional chat status lines, and Telegram typing during the session. Outbound `say` limits depend on single-round vs enhanced session settings. See [Autonomous wake & poker prompts](/architecture/autonomous-wake).
  </Tab>

  <Tab title="Summon">
    In group chats, after the entity posts, a short window opens where follow-ups without `@mention` are treated as relevant — based on participant tracking, entity name heuristics, and reply patterns. Configurable timeout (default 30s).
  </Tab>
</Tabs>

### Wake safeguards

| Setting                             | Default | Purpose                                                                  |
| ----------------------------------- | ------- | ------------------------------------------------------------------------ |
| `min_cycle_gap_seconds`             | 600     | Minimum time between autonomous cycles                                   |
| `max_cycles_per_hour`               | 4       | Hard cap on wake frequency                                               |
| `messages_per_cycle`                | 2       | Max `say()` per autonomous cycle when not using enhanced session budgets |
| `wake_session_say_budget_per_round` | 6       | Higher `say` cap per round when multi-round or wide wake is active       |
| `silence_threshold_seconds`         | 120     | Don't wake during active conversation                                    |

Additional keys (`wake_session_max_rounds`, `wake_session_wall_seconds`, `wake_wide_mode`, visibility toggles) are documented under [Autonomous wake](/architecture/autonomous-wake).

## Platform adapters

All adapters share the same entity instance. Memory, body state, and identity are consistent across platforms.

<AccordionGroup>
  <Accordion title="CLI" icon="terminal">
    **Rich** terminal REPL with a **prompt\_toolkit** input bar. Bottom toolbar shows current mood and dominant drive.

    **Startup banner**: entity name, mood, drive level, episode count, model, context size, tool count, uptime, relationship count.

    **Streaming**: character-by-character delivery with sentence-boundary chunking. Pauses between chunks simulate natural pacing.

    **Local commands**: `/self` (side panel with drives, inner voice, recent memories), `/status`, `/feelings`, `/memories`, `/tools`, `/bye` (graceful shutdown with session summary).

    **Tool activity**: whisper-styled indented lines showing what the entity is doing.
  </Accordion>

  <Accordion title="Telegram" icon="paper-plane">
    Full-featured bot via python-telegram-bot. 20+ slash commands, photo/vision support, voice message handling, HTML-formatted responses, privacy operator system, remote desktop sessions.

    **Media**: photos passed as vision input (up to 3), audio as base64 (8MB cap), image documents with mime detection.

    **Delivery**: plain replies use **`presence.message_chunk_max`** and **`chunk_delay`** (plus typing-speed–based jitter and compose delays) so answers often arrive as **several human-paced bubbles**, not one block. Telegram’s \~4096-character limit still applies per message; longer content is split safely. Typing indicator runs during perceive (\~4.5s loop) and again between chunk sends when applicable.

    **Dedup**: update\_id and (chat\_id, message\_id) deduplication with 8192-entry ring buffers.

    See [Telegram guide](/guides/telegram) for setup, commands, and pacing knobs.
  </Accordion>

  <Accordion title="Discord" icon="comment">
    Conversational bot via discord.py. Responds in DMs always; in guilds, when mentioned or in configured channels.

    **Media**: image attachments (12MB), audio (8MB), base64 passthrough.

    **Presence sync**: Discord status mapped to emotional state — online, idle, or DND based on primary emotion.

    **Delivery**: 2000-char cap with sentence-aware chunking at \~1900 chars.

    See [Discord guide](/guides/discord) for setup.
  </Accordion>
</AccordionGroup>

## Embodied expression

Responses are paced to feel natural, not instant. On **Telegram**, multi-part delivery uses **`send_plain_chunks`**: line-aware packing up to **`message_chunk_max`**, then between each bubble a delay of roughly **`chunk_delay`** with **variance jitter** (`typing_speed_variance`) plus an extra beat scaled by the **next** chunk’s length and **`typing_speed_base`** (capped). **Discord** uses similar line packing with its own length cap; **CLI** streams with sentence-aware chunking.

| Setting                 | Default | What it does                                                                      |
| ----------------------- | ------- | --------------------------------------------------------------------------------- |
| `typing_speed_base`     | 30      | Base typing speed simulation (also scales inter-bubble compose delay on Telegram) |
| `typing_speed_variance` | 0.3     | Randomization for typing simulation and chunk pause jitter                        |
| `message_chunk_max`     | 400     | Target characters per outbound chunk (Telegram: clamped 120–3900)                 |
| `chunk_delay`           | 2.0     | Base seconds between chunks / bubbles                                             |
| `tool_activity`         | true    | Show tool use status lines                                                        |

## Source files

| File                                                | Role                                             |
| --------------------------------------------------- | ------------------------------------------------ |
| `bumblebee/presence/daemon.py`                      | Main daemon loop and APScheduler                 |
| `bumblebee/presence/initiative.py`                  | Proactive message composition                    |
| `bumblebee/presence/wake_cycle.py`                  | Autonomous wake logic, wake voice, poker prompts |
| `bumblebee/cognition/poker_prompts.py`              | Deck load and selection                          |
| `bumblebee/cognition/poker_grounding.py`            | Optional GEN-grounded disposition                |
| `bumblebee/presence/embodiment.py`                  | Typing simulation and chunking                   |
| `bumblebee/presence/platforms/base.py`              | Platform adapter base class                      |
| `bumblebee/presence/platforms/cli.py`               | CLI REPL with Rich rendering                     |
| `bumblebee/presence/platforms/telegram_platform.py` | Telegram adapter (20+ commands)                  |
| `bumblebee/presence/platforms/discord_platform.py`  | Discord adapter with presence sync               |
| `bumblebee/presence/automations/engine.py`          | Automation scheduler and execution               |
| `bumblebee/presence/automations/emergence.py`       | Routine suggestion from memory/drives            |
