> ## 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.

# Autonomous wake & poker prompts

> Self-initiated perceive cycles, sustained sessions, wake voice, YAML seed decks, GEN-grounded disposition, body-driven auto-escalation, and visibility.

Autonomous wake is how the entity runs a full `perceive` cycle **without** an inbound user message — initiative from body state, desire pressure, or a timer. It is **not** the same code path as **legacy drive-based initiative** (see [Presence → Initiative and wake cycles](/architecture/presence#initiative-and-wake-cycles)): when `autonomy.enabled` is true, the daemon uses the wake engine; when it is false, the daemon skips wake evaluation and may use the simpler initiative path instead.

Each wake trigger can run **one or many** full perceive rounds in a row (see **Sustained wake sessions**). The deliberate agent loop (tools, thinking, `say`, `end_turn`) is the same path as a normal chat turn, routed with `platform: autonomous`.

## Disabling autonomous wake

Set **`autonomy.enabled: false`** in **`configs/entities/<name>.yaml`** (merged onto harness defaults) or in **`configs/default.yaml`** if you want it off for every entity.

**What stops:** The daemon no longer evaluates autonomous wake conditions or runs `WakeCycleEngine` (`bumblebee/presence/wake_cycle.py`) on heartbeat — no timer wakes, no impulse / conflict / desire / `drive_wake` triggers, and no full autonomous `perceive` sessions. (Gated in `bumblebee/presence/daemon.py`.)

**What can still happen:**

* **Legacy initiative** — When autonomy is off, the daemon still checks whether internal **drives** have crossed their threshold. If so, and **`drives.initiative_cooldown`** (seconds between proactive messages, default **1800** if omitted) has elapsed, it may compose and send **one** proactive outbound message, then partially satisfy that drive. This is lighter than a full wake (no wake voice, poker, or sustained session). Raise **`initiative_cooldown`** under **`drives:`** in entity YAML to space those out; drives still grow during silence, so “never proactive” may require additional product behavior not covered by a single flag.
* **Automations** — Scheduled or triggered routines can still call messaging paths if [automations](/guides/automations) are enabled.
* **GEN / soma** — Inner voice and body ticks continue; only **autonomous wake** as a feature is gated off.

For the full trigger list when autonomy is on, see [When wake fires](#when-wake-fires) below.

## When wake fires

With `autonomy.enabled: true`, the daemon evaluates conditions on each heartbeat (subject to silence and rate limits):

| Source           | Harness keys                           | Idea                                                                                                               |
| ---------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Soma impulses    | `impulse_wake`                         | A labeled impulse is active and off cooldown                                                                       |
| Drive thresholds | `drive_wake`                           | A drive is at or above its threshold                                                                               |
| Conflicts        | `conflict_wake`                        | An active conflict has intensity above \~0.4                                                                       |
| Noise salience   | `noise_wake` (usually off)             | Experimental — inner-voice fragments that read as “open” (e.g. questions); gated by body salience and GEN maturity |
| Desire pressure  | `desire_wake`, `desire_wake_threshold` | Top synthesized urge (e.g. reach out, explore) exceeds urgency                                                     |
| Timer            | `base_wake_interval_min` / `max`       | Randomized fallback between cycles                                                                                 |

When **`noise_wake`** is enabled, the harness requires **`noise_wake_min_salience`** (body loud enough) and **`noise_wake_min_age_seconds`** (GEN idle long enough so fragments are “mature,” not a brand-new tick). Restored noise buffers without a fresh GEN tick in-session can still qualify.

Safeguards: `min_cycle_gap_seconds`, `max_cycles_per_hour`, and `silence_threshold_seconds`. Outbound `say()` volume during wake is controlled by `messages_per_cycle` (single-round) or `wake_session_say_budget_per_round` when the session is **enhanced** (multi-round or wide mode — see below).

## Sustained wake sessions

By default (`wake_session_max_rounds: 1`), one trigger runs **one** full perceive. Set **`wake_session_max_rounds`** greater than `1` to chain multiple perceive rounds on a **single** wake — same bodily reason, continuation prompts between rounds, until rounds run out, **`wake_session_wall_seconds`** elapses, or the model calls **`end_wake_session()`**.

| Harness key                         | Role                                                       |
| ----------------------------------- | ---------------------------------------------------------- |
| `wake_session_max_rounds`           | Max chained perceives per trigger (1 = legacy single pass) |
| `wake_session_wall_seconds`         | Hard wall-clock cap for the whole session                  |
| `wake_session_pause_seconds`        | Brief pause between rounds                                 |
| `wake_session_extra_tool_steps`     | Extra deliberate-loop steps per round (capped in code)     |
| `wake_session_say_budget_per_round` | Cap on `say()` per round when the session is enhanced      |

Continuation rounds receive a recap (tools touched so far, last reply snippet, desires, poker disposition). **`end_turn()`** ends the current perceive round; **`end_wake_session()`** asks the harness to stop scheduling further rounds in this wake. See [Tools — Agency](/guides/tools#agency-and-flow-control).

## Wide wake mode

When **`wake_wide_mode: true`**, the harness adds bonus tool steps (`wake_wide_bonus_steps`), injects **wide freedom** prompt text (breadth over politeness), and marks the turn as **wake-enhanced** so **`wake_session_say_budget_per_round`** applies even for a single round. Use this for long, exploratory autonomous stretches.

### Body-driven auto-escalation

Even when `wake_wide_mode` is `false` in config, the wake engine can **auto-escalate to wide mode** based on the agent's internal state:

* **GEN web venturing**: If the `NoiseSeeder` has recently produced a `web_venturing` fragment (detected via `_gen_has_web_venturing()`), wide mode activates automatically.
* **Soma curiosity**: If the `curiosity` bar is at or above **72%** (detected via `_soma_curiosity_high()`), wide mode activates automatically.

When auto-escalation fires, a `wake_auto_wide_escalation` log event is emitted with the trigger reason. This is the mechanism by which the agent's body drives it to **proactively explore the internet** — the curiosity builds internally, GEN seeds a venturing thought, and the wake engine gives the agent the tool budget to follow through.

### GEN salience bias in wake context

The `_noise_salience_bias_block()` function inspects recent GEN entries and injects **targeted encouragement** into the wake prompt based on what the inner voice is generating:

| GEN salience type                  | Prompt guidance                                                                        |
| ---------------------------------- | -------------------------------------------------------------------------------------- |
| **Curiosity** (2+ curious entries) | Use tools to verify or learn — search, fetch, read                                     |
| **Exploration** (1 curious entry)  | Prefer one outward move over re-explaining                                             |
| **Relational**                     | Consider reaching out if boundaries allow                                              |
| **Restless/creative**              | Journal, build, experiment — don't circle                                              |
| **Web venturing**                  | Follow the instinct: search the web, read Wikipedia, look up news, explore a new topic |
| **Counterfactual**                 | Use `think()` to genuinely re-evaluate a past action — inner growth engine             |
| **Dream state**                    | Follow the strange cross-domain connection, journal about it, let it color mood        |

## User-visible status (Telegram, Discord, CLI)

When **`wake_user_visible_status: true`** (default), the worker sends short **status lines** through the same path as tool activity — italic in Telegram/Discord, whisper-style on CLI — so whoever is in the active chat sees that an autonomous wake started: wake **reason**, **soma** bar snapshot, latest **GEN** fragment, optional **poker** disposition preview, and a line when wide mode is on. Between continuation rounds, an optional “still going” line may appear.

On **Telegram**, a **typing** indicator is pulsed for the duration of the wake session (wake does not go through the interactive CLI handler, so this mirrors the typing loop used for normal replies).

Disable chatter with `wake_user_visible_status: false` if you prefer logs only.

Wake status lines (reason, soma, GEN, poker preview, session limits) are also appended to the **on-disk transcript** when `transcript_enabled` is true — see [On-disk transcript](#on-disk-transcript-autonomy_transcriptmd) below.

## On-disk transcript (`autonomy_transcript.md`)

When **`transcript_enabled: true`** (default), the harness maintains an **append-only Markdown file** with full autonomous detail: wake banner lines (same substance as the worker banner), and **per-tool activity lines** during autonomous `perceive` (`platform: autonomous`). That keeps Telegram readable when **`wake_user_visible_status`** and **`wake_chat_tool_activity`** are off — operators still get a durable record on disk.

**Path resolution** (`EntityConfig.autonomy_transcript_path()` in `bumblebee/config.py`):

* If **`transcript_path`** is set: absolute paths are used as-is; relative paths resolve under **`BUMBLEBEE_EXECUTION_WORKSPACE_DIR`** when set, otherwise under `~/.bumblebee/entities/<name>/`.
* If **`transcript_path`** is empty: the file is **`transcript_filename`** (default `autonomy_transcript.md`) next to **`journal.md`** — i.e. under the execution workspace when configured, otherwise under the entity directory.

**Related flags:**

| Key                        | Role                                                                                                                 |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `wake_chat_tool_activity`  | When `true`, per-tool lines also go to Telegram during autonomous wake (in addition to the transcript when enabled). |
| `wake_user_visible_status` | When `true`, wake status lines mirror to Telegram; when `false`, transcript + logs still capture them if enabled.    |

Implementation: `bumblebee/presence/autonomy_transcript.py` (append helpers), `wake_cycle.py` (`_emit_user_wake_lines`), `entity.py` (tool activity during autonomous turns).

## Worker and file logging

When **`wake_verbose_worker_log: true`** (default), the process emits a multi-line **banner** log event (`autonomous_wake_worker_banner`) with human-readable context: entity name, reason, delivery platform and channel, poker settings and disposition preview, **soma** bars, **GEN** noise fragments, wake-voice stirring preview, and session limits.

Structured events also include:

* `autonomous_wake` — summary fields (reason, channel, rounds, wall, wide mode, extra steps, poker flags, soma line, GEN count)
* `autonomous_wake_round_done` — per-round tools and reply length
* `autonomous_wake_session_end` — totals, elapsed time, full tool list

These appear in **worker** and **`bumblebee run`** logs alike (JSON or text, depending on harness logging).

## What the entity sees

Wake assembles context that includes:

* Wake **reason** (string) and timestamp
* **Platforms / channels** the entity is present on
* **Top desire pressures** (when inferred)
* **\[Optional] Poker disposition** — see below
* **Wake voice** stirring — unless `poker_prompts.mode: replace_wake_voice`
* Instructions for tools (`think`, `say`, `end_turn`, etc.) when `allow_tool_calls_on_wake` is true

The main model then chooses observation only, internal thought, tool use, or a bounded number of outgoing messages.

## Wake voice (`soma.wake_voice`)

A **reflex** LLM pass that runs on wake (not on GEN’s timer). It reads body state, journal tail, conversation tail, relationships, and composes a **first-person stirring** — subconscious material the conscious model interprets.

```yaml theme={null}
soma:
  wake_voice:
    enabled: true
    model: ""           # empty = reflex model
    temperature: 0.8
    max_tokens: 300
```

## Poker prompts — seed decks

**Poker prompts** are optional YAML **seeds** that bias a wake cycle toward exploratory agency in the world: search, read, build, message, learn, try something new. They are **not** user-visible copy — they shape internal disposition.

* **Deck file**: default `configs/poker_prompts/default.yaml`; override with `autonomy.poker_prompts.prompts_path` (paths under `configs/` unless absolute).
* **Selection**: one line per wake, with **time-of-day weighting** across `low` / `medium` / `high` energy bands (`time_weighted`).
* **Enable**: `autonomy.poker_prompts.enabled: true`.

### Modes

| Mode                 | Behavior                                                                                  |
| -------------------- | ----------------------------------------------------------------------------------------- |
| `blend`              | Wake voice **and** the disposition block both appear (default).                           |
| `replace_wake_voice` | Skips the wake-voice LLM; only the (optionally grounded) disposition is used as stirring. |

## GEN-grounded emergence (`ground_with_gen`)

Raw deck lines are **directional taste**, not prescriptions. When **`ground_with_gen: true`** (default in harness YAML when you document the block), a short **reflex** call in `bumblebee/cognition/poker_grounding.py` **weaves** the selected seed with:

* **GEN** — current noise fragments from `soma.noise`
* **Bars and affects** — rendered body snapshot
* **Recent soma events** — appraisal, messages, idle, etc.
* **Journal tail**, **last conversation**, **relationship blurbs**

The output is a **few lines** of second-person disposition grounded in what the entity has actually been living. If the call fails or returns empty content, the implementation **falls back to the raw seed**. Set `ground_with_gen: false` to use only the YAML line.

```yaml theme={null}
autonomy:
  poker_prompts:
    enabled: true
    time_weighted: true
    mode: blend
    prompts_path: ""
    ground_with_gen: true
    grounding_model: ""       # empty = reflex model
    grounding_temperature: 0.72
    grounding_max_tokens: 300
```

## How this connects to GEN

[Generative Entropic Noise](/architecture/soma#generative-entropic-noise-gen) produces continuous associative fragments. Poker grounding **consumes** those fragments at wake time so the cycle’s nudge can resonate with inner noise and recent experience — not only a static file. Wake voice and GEN remain separate mechanisms; grounding is the **bridge** between deck intent and lived signal.

## Per-entity autonomy overrides

Harness defaults live in `configs/default.yaml` under `autonomy:`. You can also set a **top-level `autonomy:`** block in **`configs/entities/<name>.yaml`**: values are **merged** onto the harness `autonomy` object (including nested `summon` and `poker_prompts`). This is how shipped examples tune sustained sessions and wide mode without editing global defaults.

## Source files

| File                                        | Role                                                                                                                       |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `bumblebee/presence/autonomy_transcript.py` | Append-only `autonomy_transcript.md` (wake lines + autonomous tool activity)                                               |
| `bumblebee/presence/wake_cycle.py`          | Triggers, sustained session loop, context assembly, wake voice + poker pipeline, user status, typing pulse, worker banners |
| `bumblebee/cognition/poker_prompts.py`      | Deck load, time-weighted selection                                                                                         |
| `bumblebee/cognition/poker_grounding.py`    | Optional GEN + context weave                                                                                               |
| `bumblebee/cognition/deliberate.py`         | Extra tool steps from wake session metadata                                                                                |
| `bumblebee/entity.py`                       | Autonomous `say` budget when wake session metadata marks enhanced turns                                                    |
| `bumblebee/presence/tools/agency.py`        | `end_wake_session` and other agency tools                                                                                  |
| `bumblebee/config.py`                       | `autonomy` schema; merge of entity YAML `autonomy:`                                                                        |
| `bumblebee/identity/soma.py`                | Wake voice composer, noise buffer                                                                                          |
| `configs/poker_prompts/default.yaml`        | Bundled seed deck (editable)                                                                                               |
