Suggest thematic session titles when scheduling a session #23
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?
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
Behaviour
Architecture: pre-generate in the background
Generate after the campaign state advances, store the result at campaign level, and serve it instantly.
Trigger
approve_audioinrouters/sessions.py(theready → trashedGM approval). That handler already does post-commit fire-and-forget work (bot notify), so addinggenerate_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)campaign_storylines), the last N completed session summaries, optionally a few salient lore entries. Keep it bounded (latest N only) for token/latency control.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 asaudio_service.extract_lore_from_chunk(...)and the lore/journal generators already inreminder_tasks.py. Ifllm_cfg is None, no-op (leave suggestions empty).Storage (new migration)
campaigns, e.g.next_session_title_suggestions(list of strings) plus a..._generated_attimestamp — consistent with existing JSONB/nullable columns likereminder_offsets_minutesandanalytics_share_token. (Alternative: a tiny dedicated table, but a campaign column is simplest since only the latest set matters.)Serving
GET /api/campaigns/{campaign_id}/session-title-suggestionsthat just returns the stored list (no LLM call). Fast either way.Frontend
frontend/src/api/. Gracefully render nothing when the list is empty.Edge cases / open questions
Acceptance criteria
Done — merged in PR #196 (backend
09d19d4+ frontend). CI green.Shipped:
audio_service.generate_session_titles(context, …)LLM core returning{title, description}pairs (deduped/capped, defensive[]on failure) — deliberately reusable by #191.generate_session_title_suggestionsCelery task assembling bounded campaign context (name/desc/system + storyline + last 3 completed summaries); stored on the campaign as JSONB +generated_at. No-op when no LLM configured.approve_audioenqueues it post-commit, so suggestions refresh on each transcript approval.d7e8f9a0b1c2(2 nullable campaign columns)./campaigns/{id}/session-title-suggestions(member, instant) + POST…/generate(GM regenerate).TitleSuggestions— instant clickable chips below the new-session title input (fills the field, still editable); GM-only regenerate with non-blocking hint; renders nothing for non-GM with no suggestions.Tests: backend 502 pass (+
test_session_title_suggestions.py); frontend 249 (+10).Acceptance criteria met: suggestions generated in the background after approval; schedule form shows them instantly with no LLM wait; clicking fills the title; graceful/absent when no LLM or no suggestions; generation + manual regenerate are GM-only.
Note for #191: the generator core is standalone and context-agnostic, so #191 (per-occurrence series titles from the previous session) reuses
generate_session_titlesdirectly — just build a "previous session" context string and call it.Closing.