feat: quote board & session highlights (#116) #194
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/116-session-highlights"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #116. Third feature of v3.7.0 Table Tools.
Extracts memorable quotes + key moments during audio processing and surfaces them as approval-gated highlights, plus a campaign-wide quote board.
Backend + bot (
86e6e66)SessionHighlightmodel (quote|moment, speaker, text, timestamp_ref, approved, edited_by) + migrationb4c5d6e7f8a9(round-trips). Campaign gainshighlights_max_quotes(5) +highlights_in_discord(true).extract_highlightsLLM pass hooked intoprocess_audio: verbatim-quote prompt, defensive JSON parsing, and a hallucination filter — a quote is dropped unless it substring-matches the diarized transcript (whitespace/case-normalised). Never raises; the pipeline hook is non-fatal (a highlight failure can't fail audio processing or change status) and idempotent (delete-then-reinsert).GET/POST/PATCH/DELETE /sessions/{id}/highlights(GM full CRUD; members see onlyapproved, GM sees drafts too),GET /campaigns/{id}/highlights?speaker=quote board (approved quotes across sessions, newest first).approve_audioflips the session's highlights to approved.highlights_in_discordis on, thesession_summary_approvedpayload carries an optionaltop_quote; the bot adds a "💬 Quote of the session" embed field. Absent/off → embed unchanged. Additive → noBOT_CONTRACT_VERSIONbump.Frontend (
<head>)SessionHighlightspanel on the session page: quotes/moments, GM add/edit/delete + a "Draft — not yet visible to players" badge on unapproved rows; members see approved-only, read-only (relies on the server's row filter).CampaignHighlightsquote-board page at/campaigns/:id/highlightswith a speaker filter + session links, and a "Quote Board" nav link.highlights_max_quotes+highlights_in_discord.Tests
test_highlights.py— 6 extraction/validator (hallucination filter, JSON-parse resilience, cap) + 6 API/integration (GM CRUD, GM-vs-member visibility gate, approve-flips-to-visible, quote board + speaker filter). Full suite 478 pass; migration round-trip verified.Notes
🤖 Generated with Claude Code
Extracts memorable quotes + key moments during audio processing and surfaces them as approval-gated highlights. Backend: - New SessionHighlight model (quote|moment, speaker, text, timestamp_ref, approved, edited_by) + HighlightKind enum; migration b4c5d6e7f8a9 (round-trips). Campaign gains highlights_max_quotes (5) and highlights_in_discord (true) settings. - audio_service.extract_highlights: LLM pass via generate_structured_text (json_mode) with a verbatim-quote prompt, defensive JSON parsing, and a hallucination filter — a quote is dropped unless it substring-matches the diarized transcript (whitespace/case-normalised). Never raises. - process_audio hook: best-effort (a highlight failure never fails audio processing or changes status) and idempotent (delete-then-reinsert). - Endpoints: GET/POST/PATCH/DELETE /sessions/{id}/highlights (GM full; members see approved only), GET /campaigns/{id}/highlights quote board (approved quotes across sessions, ?speaker= filter). approve_audio flips the session's highlights to approved. Bot (additive — no BOT_CONTRACT_VERSION bump): - When highlights_in_discord is on, the session_summary_approved payload carries an optional top_quote; the bot adds a "Quote of the session" embed field. Absent/off → embed unchanged. Tests: +12 in test_highlights.py — 6 extraction/validator (hallucination filter, JSON-parse resilience, cap) + 6 API (GM CRUD, GM-vs-member visibility gate, approve flips to visible, quote board + speaker filter). Full backend suite 478 pass; migration round-trip verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>