[Table Tools] Quote board and session highlights #116
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Context / Motivation
Transcripts are diarized with speaker attribution (
process_audiomerges per-speaker segments{start, end, text, speaker}into[HH:MM:SS] Speaker: textlines viamerge_attributed_transcript,webapp/backend/app/services/audio_service.py:401; speaker labels are rewritten to character names attasks/reminder_tasks.py:1584), and a summarization LLM pass already runs in the same task. "Quote of the session" is therefore nearly free — and it's the delight feature competitors without recording can't copy.Spec
Extraction — extend the summarization step inside
process_audio(webapp/backend/app/tasks/reminder_tasks.py:1461, success path:1631-1646) to also extract:{speaker, quote, timestamp_ref}wheretimestamp_refis the[HH:MM:SS]transcript markerPrompt-engineering note: instruct the model to prefer verbatim lines with speaker attribution lifted from the diarized transcript (the
[HH:MM:SS] Speaker: textformat makes this checkable — validate that returned quotes substring-match the transcript and drop hallucinated ones).Storage — judged against existing summary storage:
Session.summaryis a flat Text column (models/session.py:115), but quotes need per-row GM edit/delete and a campaign-wide query surface, so use a new tableSessionHighlightrather than a JSON column:id,session_id(FK CASCADE, indexed),campaign_id(denormalized FK, indexed for the Highlights page),kind:quote|moment,speaker(nullable for moments),text,timestamp_ref(nullable),approvedbool default false,created_at,edited_by_id(nullable). (A JSONB column on sessions was considered and rejected: no per-row edit history, awkward cross-session listing.)Approval gate — same gate as the summary: highlights stay GM-only while
audio_processing_statusisready; they become player-visible when the GM approves viaapprove_audio(routers/sessions.py:436-504; enumAudioProcessingStatus,models/session.py:27-34). GM can edit text/speaker, delete rows, or add manual quotes on the session page before approving.Surfaces:
session_summary_approvedembed the bot already posts (event published inapprove_audio; handled inbot/questboard_bot/cogs/notifications.py).Out of scope
Acceptance criteria
References
webapp/backend/app/tasks/reminder_tasks.py:1461(process_audio),:1584(_apply_character_names),:1631-1646(success path)webapp/backend/app/services/audio_service.py:274/:329(segment shape),:401(merge_attributed_transcript)webapp/backend/app/models/session.py:115(summary),:27-34(AudioProcessingStatus),:161(summary_discord_message_id)webapp/backend/app/routers/sessions.py:436(approve_audio— approval gate +session_summary_approvedevent)bot/questboard_bot/cogs/notifications.py(summary-approved embed)Filed from the July 2026 full-project review.
Done — merged in PR #194 (backend+bot
86e6e66, frontend). CI green.Shipped:
SessionHighlightmodel (quote/moment, speaker, text, timestamp_ref, approved, edited_by) + migrationb4c5d6e7f8a9(round-trips). Campaign settingshighlights_max_quotes(5) +highlights_in_discord(true).extract_highlightsLLM pass inprocess_audio: verbatim-quote prompt, defensive JSON parsing, and the hallucination filter — a quote is dropped unless it substring-matches the diarized transcript (whitespace/case-normalised). Non-fatal (a failure never fails audio processing) and idempotent (delete-then-reinsert). Never logs transcript/quote text.?speaker=filter);approve_audioflips highlights to approved.BOT_CONTRACT_VERSIONbump.SessionHighlightspanel (GM edit + draft badges),CampaignHighlightsquote board page + nav link, the two campaign settings.Tests: backend 478 pass (+12
test_highlights.py: 6 extraction/validator + 6 API covering the visibility gate, approval flip, and quote board); frontend 229 (+23).Acceptance criteria met: ≤N structured quotes + moments per transcript with hallucinated (non-substring) quotes dropped; highlights invisible to players until approval; GM edit/delete/manual-add work; campaign quote board lists approved quotes with a speaker filter; the bot flag adds the top quote to the approved-summary embed (off restores the prior embed).
Closing.