mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Implements the full dream consolidation system across four areas: **1. Dispatch liveness (Thufir IMPORTANT #1)** Extracts `maybe_dispatch_dream()` helper, called at four state-transition points: after KIND_DREAM_DUE receipt, after heartbeat fires (idle gap), after prompt result + drain, after panic recovery + drain. Removes the old else-if chain that made dream reachable only when a heartbeat was already in flight — fixing both starvation modes: - Single-agent pool + fast heartbeat: dream now fires in the idle gap after heartbeat completes, not waiting for a concurrent heartbeat slot. - Heartbeat disabled: dream fires immediately on dream-due receipt. Guard: no flushable queue work, dream_pending, !dream_in_flight, !heartbeat_in_flight, idle agent. Preserves pending > heartbeat > dream priority. **2. Skill distribution via Nest scaffolder (Will's requirement)** Adds nest_dream_skill.md (include_str!'d as DREAM_SKILL_MD), written to .agents/skills/dream/SKILL.md at Nest init, mirroring the buzz-cli skill pattern (nest.rs:42-174). Includes NEST_DREAM_SKILL_VERSION=1 for refresh-on-bump, refresh_dream_skill_md_if_stale() with atomic tempfile write, and dream skill symlinks in ensure_skill_symlinks() for all known provider dirs (.goose/skills, .claude/skills, etc.). This makes load_dream_prompt()'s cwd-relative read correct — the Nest IS the cwd, and the scaffolder now guarantees the file. **3. Missing prompt is startup-visible error (Thufir IMPORTANT #2)** dispatch_dream() now logs tracing::error! (target: "dream") when the prompt is None, returns the claimed agent, clears dream_pending so it does not retry on every signal, and documents this as a configuration error (missing SKILL.md). No more silent drop. **4. Relay sweep + dream-due emission (Phase 3)** In buzz-relay: - Config: dream_memory_budget_bytes (default 65536, env BUZZ_DREAM_MEMORY_BUDGET_BYTES), dream_sweep_interval_secs (default 300, env BUZZ_DREAM_SWEEP_INTERVAL_SECS). Set budget to 0 to disable. - main.rs: spawns sweep task if budget > 0 and deployment_community is Some. Each interval: queries agents_over_memory_budget, idle-gates each via buzz_pubsub::presence::get_presence (no live Redis key = idle), builds KIND_DREAM_DUE ephemeral event tagged #p=[agent_pubkey], signs with relay keypair, publishes via pubsub. - Staleness ceiling satisfied: presence TTL is 90s, default sweep is 300s, so "no presence key" already implies > 90s silence. In buzz-db: agents_over_memory_budget() aggregates SUM(LENGTH(content)) for non-tombstone kind:30174 engrams per community, returns agents exceeding budget. **5. Tests (Phase 4)** Six unit tests in dream_dispatch_tests cover: - Guard: dream_pending=false → no dispatch, agent not consumed. - Guard: heartbeat_in_flight=true → blocked (priority order). - Regression: heartbeat disabled → dream still dispatches. - Guard: empty pool → pending preserved for next idle gap. - Fix 3: missing prompt → pending cleared, agent returned, no task. - Guard: dream_in_flight=true → no double dispatch. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Buzz
Desktop chat shell with:
- Tauri + React + TypeScript + Vite
- Tailwind CSS
- shadcn/ui-ready shared components
- Biome (lint/format/check)
- Feature-driven frontend structure
Scripts
pnpm dev- run the web frontendpnpm tauri dev- run the desktop apppnpm build- typecheck and build frontendpnpm typecheck- TypeScript checkspnpm lint- Biome lintpnpm format- Biome format (write)pnpm check- Biome check
Structure
src/shared- reusable app-wide code (ui,lib,styles)src/features- feature modules (vertical slices)src/app- top-level app composition