Files
ai-podcast/tests/test_caller_prompt.py
T
lukeandClaude Opus 5 b85e1c6ea7 Fix caller lineup never loading and add Wellspring cult callers
The lineup fix and the new characters both land in main.py, so they share a
commit rather than being split artificially.

Lineup fix — populate_backgrounds() was reachable only through
POST /api/session/reset, so taking calls without hitting reset left
session.caller_backgrounds empty for a whole show. Every caller got a hollow
prompt, collapsed into generic relationship filler, and Silas lost his lore.
Now start_call populates on demand, get_caller_prompt raises
EmptyCallerBackgroundError instead of emitting an empty prompt, /api/callers
reports lineup readiness to a header badge, and cross-episode topic dedup
widened from 2 shows to 10.

Wellspring callers — Doyle as the anchor defector plus a six-member pool,
grouped by new frontmatter fields (group, group_lead, group_weight, register,
explicitness). A faction is capped at one caller per show, with a 15% roll for
two pairing the lead with one other member. group_weight lets an anchor carrying
an arc get slots faster than texture characters.

Also detects model refusals, which arrive as ordinary 200s and previously
reached air as broken-character text or dead silence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 03:33:08 -05:00

79 lines
3.1 KiB
Python

import pytest
from backend.main import EmptyCallerBackgroundError, get_caller_prompt
def test_empty_background_raises_instead_of_hollow_prompt():
"""A hollow prompt still generates dialog — the model invents generic
relationship filler and regulars lose their lore. Fail loudly instead."""
with pytest.raises(EmptyCallerBackgroundError):
get_caller_prompt({})
def test_background_missing_every_identity_field_raises():
caller = {"voice": "Sebastian", "age": 52, "location": "Terlingua"}
with pytest.raises(EmptyCallerBackgroundError):
get_caller_prompt(caller)
def test_partial_background_still_builds():
"""A name alone is enough to reach the regulars lookup, so don't block it."""
prompt = get_caller_prompt({"name": "Silas"})
assert "Silas" in prompt
def test_prompt_includes_identity_and_situation():
caller = {
"name": "Danny",
"identity": "A plumber who inherited a taxidermy shop",
"situation": "Getting strange calls about taxidermy",
"reason_calling": "Someone left a note",
"secret_want": "Permission to throw it all away",
"specific_details": ["elk head in basement", "note said she forgot"],
}
prompt = get_caller_prompt(caller)
assert "Danny" in prompt
assert "taxidermy shop" in prompt
assert "strange calls" in prompt
assert "elk head" in prompt
assert "she forgot" in prompt
assert "Permission to throw it all away" in prompt
assert "React to what Luke says" in prompt
assert "Stay in character" in prompt
assert "NEVER use asterisks" in prompt
assert "NEVER use parenthetical stage directions" in prompt
assert "Mix short punchy replies with longer ones" in prompt
assert "YOU CAN BE MOVED" in prompt
assert "NEVER restate the same dilemma" in prompt
assert len(prompt) < 3500
def test_prompt_includes_opening_line():
caller = {
"name": "Tina",
"identity": "A nurse who just got off a 16-hour shift",
"situation": "Found her ex's wedding invitation in her mailbox",
"reason_calling": "She's not sure if she should go",
"secret_want": "Wants someone to tell her she's over him",
"opening_line": "Luke, I literally just got home from work and there's this gold envelope sitting on my kitchen counter.",
"specific_details": ["invitation was hand-addressed", "wedding is in two weeks"],
}
prompt = get_caller_prompt(caller)
assert "gold envelope" in prompt
assert "FIRST message" in prompt
assert "listening for" in prompt.lower() or "been listening" in prompt.lower()
def test_prompt_without_opening_line():
caller = {
"name": "Ray",
"identity": "A retired mechanic",
"situation": "Neighbor's dog dug up something weird",
"reason_calling": "He thinks it might be human bones",
"secret_want": "Doesn't want to call the cops on his neighbor",
"specific_details": ["bones were wrapped in a tarp"],
}
prompt = get_caller_prompt(caller)
assert "FIRST message" not in prompt
assert "planned opening" not in prompt.lower()