test(narrative): add e2e tests for event injection and kill

This commit is contained in:
anadoris007 2026-04-22 14:55:03 +05:30
parent d3bec344c7
commit c223d77267
1 changed files with 89 additions and 0 deletions

View File

@ -70,3 +70,92 @@ def test_full_pipeline_from_fake_simulation(tmp_path):
# Translator state advanced — next call for round 3 would resume, not re-read
assert store.get_file_offset("twitter") > 0
# ---------------------------------------------------------------------------
# God Mode integration tests
# ---------------------------------------------------------------------------
from app.services.narrative.god_mode import inject_event, kill_character
def test_injected_event_appears_in_next_round_prompt(tmp_path):
sim_dir = str(tmp_path / "sim_evt")
os.makedirs(os.path.join(sim_dir, "twitter"))
actions_path = os.path.join(sim_dir, "twitter", "actions.jsonl")
lines = [
{"round": 1, "agent_id": 1, "agent_name": "Elena", "action_type": "CREATE_POST",
"action_args": {"content": "x"}, "success": True, "timestamp": "t"},
{"event_type": "round_end", "round": 1, "timestamp": "t"},
{"round": 2, "agent_id": 1, "agent_name": "Elena", "action_type": "REPOST",
"action_args": {}, "success": True, "timestamp": "t"},
{"event_type": "round_end", "round": 2, "timestamp": "t"},
]
with open(actions_path, "w") as f:
for a in lines:
f.write(json.dumps(a) + "\n")
store = StoryStore(sim_dir)
neutral = {k: 0.0 for k in ["anger", "fear", "joy", "sadness", "surprise"]}
store.save_characters([{
"id": "1", "name": "Elena", "status": "alive",
"emotional_state": {"current": {**neutral, "trust": 0.5}, "history": []},
}])
with patch("app.services.narrative.narrative_translator.call_llm") as mock_llm:
mock_llm.return_value = "beat"
translate_round(sim_dir, "twitter", 1, "noir")
# Inject between rounds
inject_event(sim_dir, description="A mysterious letter arrives.")
translate_round(sim_dir, "twitter", 2, "noir")
# Round-2 prompt should contain the injected event
round2_prompt = mock_llm.call_args_list[1][0][0]
assert "mysterious letter" in round2_prompt
def test_killed_character_filtered_from_next_round(tmp_path):
sim_dir = str(tmp_path / "sim_kill")
os.makedirs(os.path.join(sim_dir, "twitter"))
actions_path = os.path.join(sim_dir, "twitter", "actions.jsonl")
lines = [
{"round": 1, "agent_id": 1, "agent_name": "Elena", "action_type": "CREATE_POST",
"action_args": {"content": "x"}, "success": True, "timestamp": "t"},
{"round": 1, "agent_id": 2, "agent_name": "Marcus", "action_type": "DISLIKE_POST",
"action_args": {}, "success": True, "timestamp": "t"},
{"event_type": "round_end", "round": 1, "timestamp": "t"},
{"round": 2, "agent_id": 2, "agent_name": "Marcus", "action_type": "REPOST",
"action_args": {}, "success": True, "timestamp": "t"},
{"event_type": "round_end", "round": 2, "timestamp": "t"},
]
with open(actions_path, "w") as f:
for a in lines:
f.write(json.dumps(a) + "\n")
store = StoryStore(sim_dir)
neutral = {k: 0.0 for k in ["anger", "fear", "joy", "sadness", "surprise"]}
store.save_characters([
{"id": "1", "name": "Elena", "status": "alive",
"emotional_state": {"current": {**neutral, "trust": 0.5}, "history": []}},
{"id": "2", "name": "Marcus", "status": "alive",
"emotional_state": {"current": {**neutral, "trust": 0.5}, "history": []}},
])
with patch("app.services.narrative.narrative_translator.call_llm") as mock_llm:
mock_llm.return_value = "beat"
translate_round(sim_dir, "twitter", 1, "noir")
# Kill Marcus between rounds
kill_character(sim_dir, "2")
beat2 = translate_round(sim_dir, "twitter", 2, "noir")
# Marcus acted in round 2 but is dead — his name should not be in
# the beat's 'characters' list (which reflects who participated)
assert "Marcus" not in beat2["characters"]
# Round-2 prompt's characters-in-scene section must not include Marcus.
# Marcus may appear in the event log as a death event; we exclude him
# from the "feeling:" lines which describe living characters.
round2_prompt = mock_llm.call_args_list[1][0][0]
char_lines = [l for l in round2_prompt.split("\n") if "feeling:" in l]
assert not any("Marcus" in l for l in char_lines)