feat: pre-generated session-title suggestions (#23) #196

Merged
claude-bot merged 2 commits from feat/23-session-title-suggestions into main 2026-07-18 03:54:45 +00:00
Contributor

Closes #23. Fifth feature of v3.7.0 Table Tools.

When a GM schedules a session, offer 2–3 on-theme title suggestions generated from the campaign so far — instantly, with no LLM wait (pre-generated in the background).

Backend (09d19d4)

  • audio_service.generate_session_titles(context, …) — a context-agnostic LLM core (caller passes a pre-built "story so far" string, gets {title, description} pairs back, deduped/capped). Deliberately reusable by #191 (per-occurrence series titles from the previous session). Defensive: returns [] on any LLM/parse failure, never raises; logs counts only.
  • generate_session_title_suggestions Celery task: assembles bounded campaign context (name/desc/system + storyline + last 3 completed summaries), stores the list + generated_at on the campaign. No-op when no LLM configured.
  • Trigger: approve_audio enqueues it post-commit, so suggestions refresh on every transcript approval.
  • Storage: campaign.next_session_title_suggestions (JSONB) + …_generated_at (migration d7e8f9a0b1c2).
  • Endpoints: GET /campaigns/{id}/session-title-suggestions (member, instant) + POST …/generate (GM regenerate, 202).

Frontend (<head>)

  • TitleSuggestions component: instant clickable chips below the new-session title input (single-session case); clicking fills the title (still editable). GM-only "↻ Regenerate" with a non-blocking hint + manual refresh; renders nothing for a non-GM with no suggestions.

Tests

  • Backend: +test_session_title_suggestions.py (generator isolation incl. bad-LLM degradation, endpoint auth, task store + no-op). Full suite 502 pass; migration round-trip verified. Existing approve_audio tests mock the new .delay().
  • Frontend: +10 (campaigns api 3, TitleSuggestions 7). 249 pass, eslint clean, vite build green.

Notes

  • No bot/ changes → no BOT_CONTRACT_VERSION concern.
  • The generator core is intentionally standalone so #191 reuses the generator itself, not just the pattern.

🤖 Generated with Claude Code

Closes #23. Fifth feature of **v3.7.0 Table Tools**. When a GM schedules a session, offer 2–3 on-theme title suggestions generated from the campaign so far — instantly, with no LLM wait (pre-generated in the background). ## Backend (`09d19d4`) - `audio_service.generate_session_titles(context, …)` — a **context-agnostic** LLM core (caller passes a pre-built "story so far" string, gets `{title, description}` pairs back, deduped/capped). Deliberately reusable by **#191** (per-occurrence series titles from the previous session). Defensive: returns `[]` on any LLM/parse failure, never raises; logs counts only. - `generate_session_title_suggestions` Celery task: assembles bounded campaign context (name/desc/system + storyline + last 3 completed summaries), stores the list + `generated_at` on the campaign. No-op when no LLM configured. - Trigger: `approve_audio` enqueues it post-commit, so suggestions refresh on every transcript approval. - Storage: `campaign.next_session_title_suggestions` (JSONB) + `…_generated_at` (migration `d7e8f9a0b1c2`). - Endpoints: `GET /campaigns/{id}/session-title-suggestions` (member, instant) + `POST …/generate` (GM regenerate, 202). ## Frontend (`<head>`) - `TitleSuggestions` component: instant clickable chips below the new-session title input (single-session case); clicking fills the title (still editable). GM-only "↻ Regenerate" with a non-blocking hint + manual refresh; renders nothing for a non-GM with no suggestions. ## Tests - Backend: +`test_session_title_suggestions.py` (generator isolation incl. bad-LLM degradation, endpoint auth, task store + no-op). Full suite **502 pass**; migration round-trip verified. Existing `approve_audio` tests mock the new `.delay()`. - Frontend: +10 (campaigns api 3, TitleSuggestions 7). **249 pass**, eslint clean, vite build green. ## Notes - No `bot/` changes → no `BOT_CONTRACT_VERSION` concern. - The generator core is intentionally standalone so #191 reuses the generator itself, not just the pattern. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Background-generates 2-3 on-theme next-session title suggestions per
campaign so the schedule form can offer them instantly (no LLM wait).

- audio_service.generate_session_titles(context, ...): a context-AGNOSTIC
  LLM core — the caller passes a pre-built "story so far" string and gets
  back {title, description} pairs (deduped, capped). Designed for reuse by
  #191 (per-occurrence series titles from the previous session). Defensive:
  returns [] on any LLM/parse failure, never raises; logs counts only.
- generate_session_title_suggestions Celery task: assembles bounded campaign
  context (name/desc/system + storyline + last 3 completed summaries),
  calls the generator, stores the list + generated_at on the campaign.
  No-op when no LLM is configured.
- Trigger: approve_audio enqueues it post-commit (fire-and-forget), so
  suggestions refresh whenever a transcript is approved.
- Storage: campaign.next_session_title_suggestions (JSONB) +
  next_session_title_suggestions_generated_at (migration d7e8f9a0b1c2).
- Endpoints: GET /campaigns/{id}/session-title-suggestions (member, instant,
  no LLM) + POST .../generate (GM manual regenerate, 202).

Tests: +test_session_title_suggestions.py (generator isolation incl. bad-LLM
degradation, endpoint auth, task store + no-op). Existing approve_audio tests
mock the new .delay(). Full suite 502 pass; migration round-trip verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(frontend): thematic session-title suggestion chips (#23)
All checks were successful
CI / Backend lint (ruff) (pull_request) Successful in 1m1s
CI / Frontend tests, audit, and build (pull_request) Successful in 1m56s
CI / Bot tests and audit (pull_request) Successful in 2m19s
CI / Backend migration, tests, and audit (pull_request) Successful in 4m24s
CI / Docker image build (pull_request) Successful in 5m38s
0dfb771d1a
- api/campaigns.js: fetch/regenerate session-title-suggestion wrappers.
- TitleSuggestions component: instant clickable chips (from the stored,
  pre-generated set — no LLM wait) below the new-session title input,
  shown for the single-session case. Clicking a chip fills the title field
  (still freely editable). GM-only "↻ Regenerate" triggers background
  generation with a non-blocking "check back" hint + manual refresh; a GM
  sees it even at zero suggestions so they can bootstrap the first set.
  Renders nothing for a non-GM with no suggestions — field behaves as before.
- Wired into CampaignDetail's create-session form.

Tests: +10 (campaigns api 3, TitleSuggestions 7). 249 pass, eslint clean,
vite build succeeds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude-bot deleted branch feat/23-session-title-suggestions 2026-07-18 03:54:45 +00:00
Sign in to join this conversation.
No description provided.