Suggest thematic session titles when scheduling a session #23

Open
opened 2026-06-24 03:22:00 +00:00 by rbrooks · 0 comments
Owner

Summary

When a GM is scheduling the next session, Quest Board should offer 2–3 suggested titles generated from the campaign so far, so the GM can pick one (or use it as a starting point) instead of inventing a title from scratch. Suggestions should be thematically consistent with the campaign's tone and recent events.

Key requirement: suggestions must be pre-generated and instantly available when the scheduling page opens — the GM should never wait on an LLM call. Generation happens ahead of time in the background; the scheduling page just reads the stored result.

User story

As a GM scheduling the next session, I want a few thematically appropriate titles already waiting for me — based on what's happened in the campaign — so naming sessions is instant and stays consistent with the story.

Behaviour

  • Opening the session create/schedule form shows 2–3 ready-made title suggestions immediately (no spinner, no generation wait).
  • The GM can click a suggestion to fill the title field, edit it, or ignore them and type their own.
  • Suggestions reflect the campaign's themes and its recent arc — not generic fantasy filler.
  • Purely optional and additive: the title field works exactly as today if no suggestions exist or the feature is unavailable.

Architecture: pre-generate in the background

Generate after the campaign state advances, store the result at campaign level, and serve it instantly.

Trigger

  • Enqueue a Celery task to (re)generate the campaign's next-session title suggestions immediately after a transcript is approvedapprove_audio in routers/sessions.py (the ready → trashed GM approval). That handler already does post-commit fire-and-forget work (bot notify), so adding generate_session_title_suggestions.delay(campaign_id) after the commit fits the existing pattern. At approval time the new session summary is finalized, so it's the right moment to refresh.

Generation task (new task in tasks/reminder_tasks.py)

  1. Gather compact "campaign so far" context — campaign name + description/theme, the storyline (campaign_storylines), the last N completed session summaries, optionally a few salient lore entries. Keep it bounded (latest N only) for token/latency control.
  2. Resolve the LLM via the established pattern: llm_cfg = await settings_service.get_llm_config(db), then call the model with (llm_cfg.endpoint_url, llm_cfg.api_key, llm_cfg.model) — same shape as audio_service.extract_lore_from_chunk(...) and the lore/journal generators already in reminder_tasks.py. If llm_cfg is None, no-op (leave suggestions empty).
  3. Parse into 2–3 short titles and persist them on the campaign.

Storage (new migration)

  • A nullable JSONB column on campaigns, e.g. next_session_title_suggestions (list of strings) plus a ..._generated_at timestamp — consistent with existing JSONB/nullable columns like reminder_offsets_minutes and analytics_share_token. (Alternative: a tiny dedicated table, but a campaign column is simplest since only the latest set matters.)

Serving

  • The scheduling page reads the stored suggestions — either inlined into the existing campaign/session-planning payload, or a cheap GET /api/campaigns/{campaign_id}/session-title-suggestions that just returns the stored list (no LLM call). Fast either way.

Frontend

  • Render the stored suggestions as clickable chips next to the title field in the session create form (campaign planning / session pages), via a fetch wrapper in frontend/src/api/. Gracefully render nothing when the list is empty.

Edge cases / open questions

  • No suggestions yet (brand-new campaign, or no transcript approved since the feature shipped): show none. Optionally offer a manual "Generate suggestions" button that enqueues the same task (and/or a one-time backfill that generates for existing campaigns).
  • Staleness: suggestions refresh on every transcript approval. Consider also offering a manual "regenerate" so a GM can get a fresh set on demand.
  • Consumed suggestions: decide whether to clear/replace the stored set once a session is created from one, or just let the next approval overwrite them (simplest).
  • Campaigns without recording/transcripts: if a group never approves transcripts, this trigger never fires. A manual generate button covers that case; consider whether another lifecycle event (e.g. session completed) should also trigger generation.

Acceptance criteria

  • After a transcript is approved, the campaign has fresh title suggestions generated in the background.
  • Opening the schedule form shows 2–3 relevant, on-theme suggestions instantly, with no LLM wait.
  • Clicking a suggestion fills the title field; the GM can still type freely.
  • With no LLM configured or no suggestions available, the form behaves exactly as today (no errors, suggestions simply absent).
  • Generation and any manual regenerate are GM-only.
## Summary When a GM is scheduling the next session, Quest Board should offer **2–3 suggested titles** generated from the campaign so far, so the GM can pick one (or use it as a starting point) instead of inventing a title from scratch. Suggestions should be thematically consistent with the campaign's tone and recent events. **Key requirement: suggestions must be pre-generated and instantly available** when the scheduling page opens — the GM should never wait on an LLM call. Generation happens ahead of time in the background; the scheduling page just reads the stored result. ## User story > As a GM scheduling the next session, I want a few thematically appropriate titles already waiting for me — based on what's happened in the campaign — so naming sessions is instant and stays consistent with the story. ## Behaviour - Opening the session create/schedule form shows 2–3 ready-made title suggestions immediately (no spinner, no generation wait). - The GM can click a suggestion to fill the title field, edit it, or ignore them and type their own. - Suggestions reflect the campaign's themes and its recent arc — not generic fantasy filler. - Purely optional and additive: the title field works exactly as today if no suggestions exist or the feature is unavailable. ## Architecture: pre-generate in the background Generate after the campaign state advances, store the result at campaign level, and serve it instantly. **Trigger** - Enqueue a Celery task to (re)generate the campaign's next-session title suggestions **immediately after a transcript is approved** — `approve_audio` in `routers/sessions.py` (the `ready → trashed` GM approval). That handler already does post-commit fire-and-forget work (bot notify), so adding `generate_session_title_suggestions.delay(campaign_id)` after the commit fits the existing pattern. At approval time the new session summary is finalized, so it's the right moment to refresh. **Generation task** (new task in `tasks/reminder_tasks.py`) 1. Gather compact "campaign so far" context — campaign name + description/theme, the storyline (`campaign_storylines`), the last N completed session summaries, optionally a few salient lore entries. Keep it bounded (latest N only) for token/latency control. 2. Resolve the LLM via the established pattern: `llm_cfg = await settings_service.get_llm_config(db)`, then call the model with `(llm_cfg.endpoint_url, llm_cfg.api_key, llm_cfg.model)` — same shape as `audio_service.extract_lore_from_chunk(...)` and the lore/journal generators already in `reminder_tasks.py`. If `llm_cfg is None`, no-op (leave suggestions empty). 3. Parse into 2–3 short titles and persist them on the campaign. **Storage** (new migration) - A nullable JSONB column on `campaigns`, e.g. `next_session_title_suggestions` (list of strings) plus a `..._generated_at` timestamp — consistent with existing JSONB/nullable columns like `reminder_offsets_minutes` and `analytics_share_token`. (Alternative: a tiny dedicated table, but a campaign column is simplest since only the latest set matters.) **Serving** - The scheduling page reads the stored suggestions — either inlined into the existing campaign/session-planning payload, or a cheap `GET /api/campaigns/{campaign_id}/session-title-suggestions` that just returns the stored list (no LLM call). Fast either way. **Frontend** - Render the stored suggestions as clickable chips next to the title field in the session create form (campaign planning / session pages), via a fetch wrapper in `frontend/src/api/`. Gracefully render nothing when the list is empty. ## Edge cases / open questions - **No suggestions yet** (brand-new campaign, or no transcript approved since the feature shipped): show none. Optionally offer a manual "Generate suggestions" button that enqueues the same task (and/or a one-time backfill that generates for existing campaigns). - **Staleness:** suggestions refresh on every transcript approval. Consider also offering a manual "regenerate" so a GM can get a fresh set on demand. - **Consumed suggestions:** decide whether to clear/replace the stored set once a session is created from one, or just let the next approval overwrite them (simplest). - **Campaigns without recording/transcripts:** if a group never approves transcripts, this trigger never fires. A manual generate button covers that case; consider whether another lifecycle event (e.g. session completed) should also trigger generation. ## Acceptance criteria - After a transcript is approved, the campaign has fresh title suggestions generated in the background. - Opening the schedule form shows 2–3 relevant, on-theme suggestions **instantly**, with no LLM wait. - Clicking a suggestion fills the title field; the GM can still type freely. - With no LLM configured or no suggestions available, the form behaves exactly as today (no errors, suggestions simply absent). - Generation and any manual regenerate are GM-only.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rbrooks/Quest-Board#23
No description provided.