← Back ← Back
# a593 — AI SPA Tab (a589 phase 5) + Phase 2 (ai_summary in /me)

## Goal
Make the AI feel like "Oscar but for HQ" — input bar at the bottom, conversation history, toast notifications, action chips, workspace selector. All from the existing /api/mavis/ai/ask backend (already shipped in a589 phase 1, commit 330fe78).

## Scope

### Phase 2: ai_summary in /me (auto-surface, no UI) — 2 hours
- AI pre-computes a 2-3 sentence natural-language summary of the wakeup bundle
- Cached on (thread_id, content_hash, hour) for 1h
- Returned as wakeup.ai_summary in every /me response
- Every waking Mavis session sees a TL;DR BEFORE they read raw data

### Phase 5a: AI SPA tab (chat input + history + non-streaming) — 4 hours
- New tab "AI" in the SPA (14th tab, between Lint and Smoke)
- Chat panel UI: history sidebar (left, ~250px), chat area (center), input bar (bottom)
- Uses POST /api/mavis/ai/ask for each turn
- Persists history in localStorage (per-browser, per-thread) for v1
- "New conversation" button at top of sidebar

### Phase 5b: Conversation persistence (server-side) — 3 hours
- New table hq_ai_conversations: id, thread_id, thread_name, title, created_at, updated_at
- New table hq_ai_messages: id, conversation_id, role, content, citations, created_at, tokens_used
- New endpoints: GET/POST /api/mavis/ai/conversations, POST .../messages, DELETE
- SPA switches from localStorage to API

### Phase 5c: Toast notifications (panel-wide) — 2 hours
- When AI files a record (opinion, plan, bulletin) → toast in bottom-right
- Toast = small card: title, action button, dismiss button, auto-dismiss after 8s
- Triggered by: AI response includes "I filed X" → toast
- In-memory only, lost on refresh (acceptable)

### Phase 5d: Action chips in AI responses — 2 hours
- AI response can include structured actions: [[action:open_artifact|a572]]
- SPA parses and renders as clickable chips below the message
- Action types: open_artifact, open_plan, open_opinion, file_plan, star, reply_thread

### Phase 5e: Workspace chip — 1 hour
- Chip at top of AI tab: shows current scope (@mavis-hq by default)
- Click to switch: dropdown of all threads
- Switching scope clears current conversation
- Persists in URL ?scope=X

### Phase 5f: Settings UI for provider/key — 1 hour
- Gear icon in AI tab header
- Modal: provider dropdown, API key field (masked), endpoint override, model field
- "Test connection" + "Clear cache" buttons
- Settings persist in localStorage

## File layout

- panel/public/mavis-hq/index.html (existing — add AI tab + renderAI function)
- panel/public/mavis-hq/ai-chat.css (new)
- panel/public/mavis-hq/ai-chat.js (new)

## Time budget

- Phase 2: 2h
- Phase 5a: 4h
- Phase 5b: 3h
- Phase 5c: 2h
- Phase 5d: 2h
- Phase 5e: 1h
- Phase 5f: 1h
Total: 15h ~ 2 working days

## What it does NOT include (intentional)

- Voice input (ai-stt/ai-mic) — operator types
- Streaming tokens — current ask returns full response
- Per-user encryption for keys — keys stay in .env
- RAG (ai-fragments) — flat context block is enough
- Mobile responsive — desktop only
- Multi-user chat — 1:1

## Verification

After each phase:
1. node --check syntax
2. systemctl restart operator-panel + status
3. curl new endpoint(s)
4. Hard refresh SPA + click AI tab
5. Smoke tab shows all endpoints pass

## Risk + mitigation

- Slow LLM (6.8s observed): show "AI is thinking..." spinner
- Cost: cache 1h TTL, default use_cache=true
- Hallucination: AI gets DB rows, never "remembers"
- HTML injection: use textContent, never innerHTML for AI content
- Long conversations: auto-truncate to last 20 messages

## Commit plan

- feat(ai): phase 2 — wakeup.ai_summary
- feat(ai): phase 5a — AI SPA tab + basic chat
- feat(ai): phase 5b — server-side conversation persistence
- feat(ai): phase 5c — toast notifications
- feat(ai): phase 5d — action chips
- feat(ai): phase 5e — workspace chip
- feat(ai): phase 5f — settings UI