[Workbench] Session Prep sheet regurgitates the last session — no working channel for GM intent about the upcoming one #305
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?
Symptom
Session Prep suggestions are mostly restatements of what happened last session rather than proposals for the next one. Reported during real session prep: "pretty useless."
Cause
The prep prompt assembles four context blocks (generation_service.py:1636-1650):
_session_prep_notes_contextbeat_notes_session_prep_recent_contextrecent_sessions_context(n=2)— last 2 summarised sessions_session_prep_threads_context_session_prep_lore_contextThree of the four are retrospective or static. The only forward-looking input is
beat_notes— and that block drops out entirely when notes are empty (generation_service.py:1094-1105):Two active bugs mean it is almost always empty in practice:
With the one prospective block missing, the model is left with two session summaries — the newest of which gets the largest character budget (generation_service.py:251-259,
_RECENT_SUMMARY_CHARS_LATESTvs_RECENT_SUMMARY_CHARS_OLDER) — plus threads and lore. Recapping last session is the most probable output given that input. The system prompt's "do not invent major new facts" instruction (generation_service.py:1035-1054) pushes further in the same direction.To answer the question directly: yes, GM comments are already pulled in
beat_notesis the "notes for the AI" channel — it's fed straight into the prompt as "GM's existing beat notes for {title}". There is no second free-text field. It just hasn't been reaching the model.Proposed fix
beat_notes, so the steer is where the generate button is.beat_notes(which is durable prep the GM keeps); this is per-run direction like "they're heading to the capital, focus on the guild politics." Cheap: a new field onSessionPrepParamsplus one context builder.scenesandsecrets_and_cluesmust advance beyond what the summaries describe, and thatloose_endsis the only section meant to look backwards. Worth an eval pass against a real campaign after (1)–(3) land, since some of the current behaviour may simply be the empty-context failure mode.Related
Depends on the beat-notes round-trip and session-picker default issues filed alongside this.
Cluster cross-reference — all four came out of the same session-prep run on 2026-08-11:
Depends on #303 and #302. Re-evaluate the output quality after those land before investing in the prompt rebalance (step 4) — a good share of the current behaviour is probably just the empty-beat-notes failure mode.
Picking this up as v4.3.0 phase 3 (#514), after #302 and #303 unblock the notes channel. Then: an editable "Notes for this session" box in the Session Prep panel bound to the session's notes, a one-shot "What I want from this session" steer folded into the prompt as its own block, and the prompt rebalanced so recent summaries are what to build on rather than restate, with the loose-ends section the only one allowed to look back. The backend test asserts on the assembled prompt, not on a mocked generator.
Done in the phase 3 PR (auto-merging on green); ships with v4.3.0. Built after #302 and #303, which was the right order: the reason the prompt regurgitated was that its only forward-looking block was almost always empty.
Three changes:
buildParams. Notes get written where asking for the sheet happens, not behind a different palette entry.directiononSessionPrepParams: a one-shot steer, folded in by its own context builder registered last, so it lands next to the closing instruction instead of behind the wiki dump. Whitespace normalises toNone, so a blank box adds no empty block.scenesandsecrets_and_cluesmust advance past them, andloose_endsis named as the only backward-looking section.Per this project's testing feedback, a mocked
generate_structured_textcannot tell a good prompt from a bad one, so the tests assert on the assembled prompt and thesystem_promptkwarg. The framing sentence is exported asSESSION_PREP_FRAMINGand asserted by identity rather than a copied string, and the steer is checked both for presence and for being the last block. An eval pass against a real campaign, as the issue suggests, is worth doing after the release once the empty-context failure mode is out of the way.