4594f07ebc70d4f7de0216f0d9089c048977dc96
Rework calibration.py into a fixed 10-question battery:
- 4 critical questions (language, name, persona name, gender)
- 6 random probes drawn from the 12-item pool (all AI/tech-unrelated)
Theme inference (palette × typography × density × labels):
- Palette: warmth × contrast × energy → default|rose|morning|evening|
sage|paper|ink; all choices verified WCAG AA ≥4.5:1.
- Typography: elaborate+warm → serif-warm; cool+ink → mono;
high-contrast+cool → serif-formal; energetic+warm → mixed-modern;
otherwise sans.
- Density: elaborate cadence → airy; terse → dense; else normal.
- Labels: serif-warm/mixed-modern → cursive; mono → prefix; else block.
Voice selection:
- Removed VOICE_POOL (lang × gender heuristic).
- Added _load_persona_voices(): reads [voices.<lang>].id from a
cart.toml persona file at PCART_CONFIG_PATH or app/conf/persona.toml.
Falls back to FALLBACK_VOICES when no file is present.
- _pick_voice(lang) selects by language key only — no gender heuristic.
cart_store.Cart changes:
- Added calibration_version: int = 1 (new carts emit 2)
- Bumped version: 3 → 4
- Removed unused import
No changes to app/main.py — calibration wiring was already correct.
chat.saiden.dev
A quiet channel. Spike Jonze's Her (2013) as a chat UI.
chat.saiden.dev
→ Caddy reverse-proxy (TLS via Let's Encrypt)
→ FastAPI on marauder.saiden.dev:8765
├─ Google OAuth (authlib) + email whitelist
└─ WebSocket → Anthropic API streaming
Status
Phase 3 — Her-aesthetic. UI plan in UI-PLAN.md. Phase 1 (ttyd + CF Tunnel)
archived in _archive-ttyd/.
Local dev
cd ~/Projects/chat-saiden
uv sync
cp .env.example .env
# fill in ANTHROPIC_API_KEY, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, COOKIE_SECURE=false
uv run python -m app.main
# → http://127.0.0.1:8765
Google OAuth redirect URI for local dev (add to your Google Cloud Console
OAuth client): http://127.0.0.1:8765/auth/callback
Files
| Path | What |
|---|---|
app/main.py |
FastAPI: OAuth, session, WS streaming, Anthropic client |
app/templates/chat.html |
Single-page UI (chat + operator prompt) |
app/templates/denied.html |
Whitelist-rejection page, Her-styled |
app/static/chat.css |
Design system: warm pastels, Cormorant + Caveat |
app/static/chat.js |
WebSocket, typewriter queue, label dedup, smooth scroll |
pyproject.toml |
uv deps |
.env.example |
env scaffold |
UI-PLAN.md |
Design doctrine (Her aesthetic translated to chat) |
_archive-ttyd/ |
Phase 1 (ttyd + CF Tunnel + CF Access) — kept for reference |
Deployment
Not deployed yet. Stages remaining:
- Caddyfile on marauder.saiden.dev (reverse proxy chat.saiden.dev → :8765)
- systemd unit for the FastAPI app
- DNS swap:
chat.saiden.devCNAME →marauder.saiden.dev(currently broken — points to deleted CF tunnel from Phase 1) - Google OAuth client production redirect URI:
https://chat.saiden.dev/auth/callback - Smoke test live
Persona
System prompt currently hardcoded as BT-7274 (placeholder). Will swap to a
dedicated Samantha cart when authored — see EEMS subject project.samantha-cart.
Description
Web chat interface with persona calibration, SSE streaming, and real-time TTS playback.
Languages
Python
65.5%
JavaScript
12.3%
CSS
12.1%
Shell
6.2%
HTML
3.9%