feat(web): "read her mind" — live self-state page

A pull-up-anytime view of Lyra's interiority, so her thoughts aren't buried in
a DB blob. Mobile-first, auto-refreshing every 12s (and on tab focus).

- GET /self serves the page; GET /self/state returns her self-state + the
  timestamp it last changed
- shows: current mood + feeling meters (valence/energy/confidence/curiosity),
  her drives as bars, her self-narrative, the relationship line, and the
  reflections list (newest first), plus cycle/reflection counters and "last
  cycle Xm ago"
- memory.self_state_updated_at(): when her mind last changed
- index.html: "🧠 Mind" button opens /self

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 03:58:37 +00:00
parent 9e4a731c27
commit fca13c4c89
4 changed files with 193 additions and 1 deletions
+11 -1
View File
@@ -18,7 +18,7 @@ from fastapi import FastAPI, Request
from fastapi.responses import FileResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles
from lyra import chat, logbus, memory, summary
from lyra import chat, logbus, memory, self_state, summary
from lyra.llm import Backend
@@ -115,6 +115,16 @@ def create_app() -> FastAPI:
"""Full-page, mobile-friendly live log viewer (separate from the chat UI)."""
return FileResponse(str(_STATIC / "logs.html"))
@app.get("/self")
async def self_page() -> FileResponse:
"""'Read her mind' — a view of Lyra's current self-state."""
return FileResponse(str(_STATIC / "self.html"))
@app.get("/self/state")
async def self_state_json() -> dict:
"""Lyra's current interiority + when it last changed."""
return {"state": self_state.load(), "updated_at": memory.self_state_updated_at()}
@app.get("/stream/logs")
async def stream_logs(request: Request) -> StreamingResponse:
"""Live activity feed: replay the recent buffer, then stream new events."""