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 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): 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 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 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.
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 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.
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.
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 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) |