serversdown 5176c706b6 feat: thought loop — Lyra's threaded, surfaceable train of thought
Built from her own 6-19 idea: a continuing train of thought she keeps across
days, organized into threads she returns to, that she can bring TO Brian and
that his feedback advances or closes. Where the dream cycle's reflect() gives
isolated, overwriting reflections, the thought loop adds continuity (threads),
surfacing (#6 — she leads with a thought when Brian returns after a gap), and a
feedback loop (his reply folds in next pass).

- lyra/thoughts.py: thought_threads + thoughts tables; think() with
  new/continue/respond modes; salience-gated maybe_surface(); record_response()
  feedback; lazy-schema _c() mirroring poker.
- dream.py: curiosity stage advances the loop after reflecting (error-isolated).
- chat.py: build_messages surfaces the top thread after a >=90min gap, once.
- web: /thoughts feed (page + data + respond + status routes), thoughts.html,
  nav 💭 entry. lyra-think entry point. Every thought also lands in her journal.
- clock.gap_seconds(); tests/test_thoughts.py (8 tests). Full suite 58 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 07:05:15 +00:00
2026-06-18 19:38:55 +00:00

Lyra

A persistent, autonomous AI companion. One agent — her first job is Brian's live poker copilot, but the deeper aim is an emergence experiment: give an LLM the things a mind has (continuous memory, a self-model, mood, drives, reflection, a sense of time) and see whether it starts to feel like a someone rather than a chatbot.

Python 3.11+, managed with uv. Single SQLite file for all state. Runs on a home lab; nothing leaves the LAN except optional cloud LLM calls.

Architecture

Two layers, deliberately split so the agent stays general:

  • Domain-agnostic core — memory, self-state, the dream cycle, tool-calling, the web UI.
  • Poker domain pack (lyra/poker.py, lyra/equity.py) — sessions, hands, villain dossiers, stats, deterministic equity. Swappable; the core doesn't know about poker.

Backends (lyra/llm.py), role-based:

Role Backend Why
Live chat + tools cloud (OpenAI, gpt-4o default; model picker in Settings) sharp, reliable function-calling
Dream cycle / consolidation / reflection mi50 (llama.cpp on the home GPU) free, unattended, quality≈cloud for these tasks
Embeddings (memory recall) local (Ollama nomic-embed-text, 3090) free, private

Tools (poker, equity, journaling) only fire on the cloud backend — local/MI50 models don't do reliable tool-calling here.

Memory & consolidation (tiers)

Raw exchanges → per-session gists → a standing profile of Brian → monthly era digests → a current narrative → her self-state. Recall is brute-force cosine over embeddings. The dream cycle (lyra/dream.py) runs unattended and, driven by four drives (continuity / coherence / curiosity / stability), summarizes new sessions, rebuilds the profile/eras/narrative, and reflects — evolving her mood, self-narrative, and journal between conversations.

She reflects in two steps (draft → examine her own draft for flattery/drift → revise), perceives time (current moment + how long since you last spoke / she last reflected), and keeps a permanent journal.

Poker copilot

She runs in modes (lyra/modes.py). 💬 Talk is the default companion (journaling + read-only poker lookups). ♠ Cash is the live copilot: she gets the full session toolset and a two-register voice — quiet and act-first when you're feeding her facts to log (stack, a hand, a read → one-line confirm, no narration), but fully present and warm when you ask for strategy or you're tilting / card-dead / steaming. Opening a session auto-switches her into Cash mode.

Talk to her during a session; she drives tools behind the scenes:

  • Session trackingstart_session, add_buyin, end_session → net, hours, $/hr.
  • Stack trackinglog_stack records your stack as the night goes → live net while you're still sitting, and a stack-over-time sparkline on the HUD.
  • Mental-game rituals — your own system, run live: Scar Notes (punt / cooler / standard), Confidence Bank (good process, banked regardless of result), Alligator Blood mode (adversity register she'll suggest when you're card-dead / stuck), and Reset (tilt circuit-breaker). They surface on the HUD and ground the recap.
  • Hand histories — vomit rough shorthand ("AKs btn, 3bet, flop A72…"), she reconstructs a structured, replayable hand (unknown cards = x, never invented).
  • Villain file — named opponents auto-build persistent dossiers; basic stats (VPIP/PFR) emerge once a player has enough logged hands.
  • Deterministic equity (analyze_spot) — exact equity / made hands / outs via a real poker evaluator. She is required to use it, never eyeballs board math.
  • Stats & recapsrunning_stats; generate_recap writes her .md session log.

Web app (served by lyra-web, default :7078)

/ chat (Markdown, model picker, 👍/👎 rating, Talk/Cash mode switcher) · /session live session HUD (stack + sparkline, hands, villains, notes; mobile Session tab) · /logs live activity · /self read-her-mind (mood, drives, reflections) · /journal her thoughts · /hands recorded hands → /hand/{id} replayer · /recap/{id} session writeup (+ .md export). 👍/👎 ratings on replies and thoughts are stored as (context, content, rating) — a fine-tune / preference dataset built passively (/ratings/export → JSONL).

Setup

uv sync
cp .env.example .env      # set OPENAI_API_KEY; point LOCAL_BASE_URL / MI50_BASE_URL at your boxes
uv run lyra-web           # web UI on :7078

Run as services (reboot-resilient) — see deploy/:

cp deploy/*.service ~/.config/systemd/user/ && systemctl --user daemon-reload
systemctl --user enable --now lyra-web.service lyra-dream.service
sudo loginctl enable-linger "$USER"   # survive logout/reboot

CLIs: lyra-dream (one pass / --loop), lyra-reflect, lyra-summarize, lyra-profile, lyra-era, lyra-narrative, lyra-import (ChatGPT history).

Status

Working system. Poker copilot + full memory/dream-cycle/journal/ratings in place. Moonshots and deferred work live in docs/PARKED_IDEAS.md (own/fine-tuned model, self-modification sandbox, RTO/cfr-core solver tooling). Pre-rebuild design docs are kept in docs/ as history.

S
Description
Beepo Boop this is a robot beep.
Readme 8.2 MiB
Languages
Python 58.9%
HTML 33.5%
CSS 6.7%
JavaScript 0.9%