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
Setautonomy.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). Raiseinitiative_cooldownunderdrives: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.
When wake fires
Withautonomy.enabled: true, the daemon evaluates conditions on each heartbeat (subject to silence and rate limits):
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().
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
Whenwake_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 whenwake_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
NoiseSeederhas recently produced aweb_venturingfragment (detected via_gen_has_web_venturing()), wide mode activates automatically. - Soma curiosity: If the
curiositybar is at or above 72% (detected via_soma_curiosity_high()), wide mode activates automatically.
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:
User-visible status (Telegram, Discord, CLI)
Whenwake_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_pathis set: absolute paths are used as-is; relative paths resolve underBUMBLEBEE_EXECUTION_WORKSPACE_DIRwhen set, otherwise under~/.bumblebee/entities/<name>/. - If
transcript_pathis empty: the file istranscript_filename(defaultautonomy_transcript.md) next tojournal.md— i.e. under the execution workspace when configured, otherwise under the entity directory.
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
Whenwake_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 lengthautonomous_wake_session_end— totals, elapsed time, full tool list
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.) whenallow_tool_calls_on_wakeis true
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.
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 withautonomy.poker_prompts.prompts_path(paths underconfigs/unless absolute). - Selection: one line per wake, with time-of-day weighting across
low/medium/highenergy bands (time_weighted). - Enable:
autonomy.poker_prompts.enabled: true.
Modes
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
ground_with_gen: false to use only the YAML line.
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 inconfigs/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.