from pathlib import Path from fastapi import APIRouter, HTTPException, Request from .. import database as db, jobs from ..config import merge_campaign_settings_with_env from ..pipeline.turns import load_turns from ..pipeline.summarize import summarize_session router = APIRouter(prefix="/api/sessions/{session_id}/notes", tags=["notes"]) @router.post("/generate") async def generate_notes(session_id: str, request: Request): body = await request.json() if request.headers.get("content-type") else {} session = db.get_conn().execute("SELECT * FROM sessions WHERE id = ?", (session_id,)).fetchone() if not session: raise HTTPException(404, "Session not found") if not session["transcript_path"]: raise HTTPException(400, "Session hasn't been transcribed yet") cid = session["campaign_id"] or "default" settings = merge_campaign_settings_with_env(db.get_campaign_settings(cid)) speaker_map = {r["raw_label"]: r["display_name"] for r in db.get_conn().execute("SELECT raw_label, display_name FROM speakers WHERE session_id = ?", (session_id,)) if r["display_name"]} # Per-request style overrides the campaign setting style = body.get("player_recap_style") or settings.get("player_recap_style") or "story" custom = body.get("player_recap_custom_prompt") or settings.get("player_recap_custom_prompt") or "" job_id = db.create_job(session_id, "summarize") def run(progress_cb): turns = load_turns(Path(session["transcript_path"]), speaker_map) dm_notes, player_recap, used_template = summarize_session( turns, settings, progress_cb=progress_cb, player_recap_style=style, player_recap_custom_prompt=custom, ) with db.tx() as conn: conn.execute( "INSERT INTO notes (session_id, dm_notes, player_recap, player_recap_prompt, generated_at) VALUES (?, ?, ?, ?, ?) " "ON CONFLICT(session_id) DO UPDATE SET dm_notes=excluded.dm_notes, " "player_recap=excluded.player_recap, player_recap_prompt=excluded.player_recap_prompt, generated_at=excluded.generated_at", (session_id, dm_notes, player_recap, used_template, db.now()), ) conn.execute("UPDATE sessions SET status = 'complete' WHERE id = ?", (session_id,)) jobs.submit(job_id, run) return {"job_id": job_id} @router.get("") def get_notes(session_id: str): row = db.get_conn().execute("SELECT * FROM notes WHERE session_id = ?", (session_id,)).fetchone() if not row: raise HTTPException(404, "Notes not generated yet") return dict(row)