multi-stage Dockerfile + player recap styles
Dockerfile: split into whisperx-base and runtime stages so app-only changes skip the 10min pip install on rebuild. Example compose updated. Player recap: replace hardcoded 'story so far' prompt with selectable styles (story/diary/bullets/custom) via dropdown in Setup and Settings. Settings: add NAT20_ONBOARDING_COMPLETED env var; fix merge logic so env vars properly override defaults (not just empty DB values).
This commit is contained in:
@@ -52,12 +52,29 @@ Chunk summaries:
|
||||
{summaries}
|
||||
"""
|
||||
|
||||
PLAYER_FINAL_PROMPT = """Combine these chunk summaries into a single "previously on" style recap for the players, in-character perspective only.
|
||||
PLAYER_FINAL_PROMPTS = {
|
||||
"story": """Combine these chunk summaries into a single "previously on" style recap for the players, in-character perspective only.
|
||||
Write it like a story recap they could reread before the next session. No GM secrets, no OOC content. Keep it engaging but concise.
|
||||
|
||||
Chunk summaries:
|
||||
{summaries}
|
||||
"""
|
||||
""",
|
||||
"diary": """Combine these chunk summaries into a "dear diary" style entry written from the collective party's first-person ("we") perspective.
|
||||
Focus on the party's emotions, reactions, and personal reflections alongside the events.
|
||||
No GM secrets, no OOC content.
|
||||
|
||||
Chunk summaries:
|
||||
{summaries}
|
||||
""",
|
||||
"bullets": """Combine these chunk summaries into clean, scannable bullet points for the players.
|
||||
Group related items under headers (Exploration, Combat, NPCs, Loot, Decisions).
|
||||
Each bullet is one concise fact — no narrative fluff or transitions. No GM secrets, no OOC content.
|
||||
|
||||
Chunk summaries:
|
||||
{summaries}
|
||||
""",
|
||||
}
|
||||
|
||||
|
||||
|
||||
def _call_ollama(host: str, model: str, prompt: str) -> str:
|
||||
@@ -125,7 +142,9 @@ def make_llm_caller(settings: dict):
|
||||
return lambda prompt: _call_ollama(host, model, prompt)
|
||||
|
||||
|
||||
def summarize_session(turns: list[dict], settings: dict, progress_cb=None) -> tuple[str, str]:
|
||||
def summarize_session(turns: list[dict], settings: dict, progress_cb=None,
|
||||
player_recap_style: str | None = None,
|
||||
player_recap_custom_prompt: str | None = None) -> tuple[str, str]:
|
||||
call = make_llm_caller(settings)
|
||||
ctx_path = settings.get("world_context_path") or ""
|
||||
if ctx_path and Path(ctx_path).exists():
|
||||
@@ -148,5 +167,13 @@ def summarize_session(turns: list[dict], settings: dict, progress_cb=None) -> tu
|
||||
if progress_cb:
|
||||
progress_cb("Writing final notes...")
|
||||
dm_final = call(DM_FINAL_PROMPT.format(summaries="\n\n".join(dm_summaries)))
|
||||
player_final = call(PLAYER_FINAL_PROMPT.format(summaries="\n\n".join(player_summaries)))
|
||||
|
||||
# Select player recap prompt based on style setting
|
||||
style = (player_recap_style or settings.get("player_recap_style") or "story")
|
||||
if style == "custom":
|
||||
raw = (player_recap_custom_prompt or settings.get("player_recap_custom_prompt") or "").strip()
|
||||
player_template = raw if raw else PLAYER_FINAL_PROMPTS["story"]
|
||||
else:
|
||||
player_template = PLAYER_FINAL_PROMPTS.get(style, PLAYER_FINAL_PROMPTS["story"])
|
||||
player_final = call(player_template.format(summaries="\n\n".join(player_summaries)))
|
||||
return dm_final, player_final
|
||||
|
||||
Reference in New Issue
Block a user