serversdown 50f460eeb2 feat(web): bottom tab bar navigation (M4)
- Mobile bottom tab bar: Chat · Hands · Mind · More. "More" opens the drawer
  for the long tail (Journal, Log, Settings, sessions); hamburger retired.
- Auto-hides while the keyboard is open (body.kb) so the input pins to the
  keyboard; mobile-only (desktop keeps its header nav).
- Removed now-redundant Mind/Hands from the drawer + their listeners.
- Bottom-fill fix: #chat uses 100dvh (the visible viewport) — 100vh/inset:0
  reach into the home-indicator zone iOS won't comfortably show, clipping the
  bar; dvh/svh exclude it. Tab bar is flex:none with a small fixed bottom
  padding (safe-area padding double-counts at dvh height), and the body bg
  matches the bar so any strip below #chat is seamless.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 04:36:08 +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

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

  • Session trackingstart_session, add_buyin, end_session → net, hours, $/hr.
  • 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) · /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 7.8 MiB
Languages
Python 60.4%
HTML 32.9%
CSS 6.7%