serversdown fb6b44a82e fix: color-match the iOS home-indicator strip to the bottom bar
iOS won't render interactive content in the bottom ~59px (home-indicator
zone) and underreports innerHeight by the top inset, so the bar can't be
pushed lower. Instead, keep the shell at 100dvh (no clipping) and paint
the strip below it the same color as the tab bar (html/body bg + a
lighter --bg-line bar + matched theme-color) so it reads as the bar
continuing to the edge rather than an empty gap. Cache-bust the
stylesheet so the PWA picks it up.

Tried the boolinator innerHeight-correction approach (adding the top
inset back via --actual-vh); it clipped the icons on-device, so reverted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G796GsLCvJQKVN7hwV2cDx
2026-06-30 05:27:44 +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 9.6 MiB
Languages
Python 70%
HTML 24.6%
CSS 4.1%
JavaScript 0.8%
Shell 0.5%