feat(phase2): llm report writer (P5.3)
- New module src/pf1e_simulator/report.py with ReportContext, build_report_context, LLMReportPolicy, ReportBudget, format_llm_report, build_report_prompt - Prompt pack fixture: tests/fixtures/prompt_pack_fs/report.md (FR narrator) - CLI integration: --llm-report + --output flags, mutually exclusive with --transcript - Budget enforcement: ReportBudget integrates with CostBudget, allows max_retries+1 calls - Tests: test_report_context, test_report_prompt_pack, test_llm_report_policy, test_format_llm_report, test_cli_llm_report, test_report_budget (27 new tests)
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
"""Tests for report prompt pack (P5.3 T2)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from pf1e_simulator.prompt import PromptPack
|
||||
from pf1e_simulator.report import build_report_context, build_report_prompt
|
||||
from pf1e_simulator.runner import CombatantAttrition, EncounterReport
|
||||
|
||||
|
||||
def test_report_prompt_pack_version_stable() -> None:
|
||||
"""Prompt pack version hash is stable for the fixture."""
|
||||
pack_dir = Path(__file__).resolve().parent / "fixtures" / "prompt_pack_fs"
|
||||
pack = PromptPack.load(pack_dir)
|
||||
|
||||
report_version = pack.prompt_version("report")
|
||||
assert report_version.startswith("0.1.0-test:report:")
|
||||
assert len(report_version.split(":")[2]) == 12 # hash12
|
||||
|
||||
|
||||
def test_report_prompt_renders() -> None:
|
||||
"""build_report_prompt renders the context correctly."""
|
||||
pack_dir = Path(__file__).resolve().parent / "fixtures" / "prompt_pack_fs"
|
||||
pack = PromptPack.load(pack_dir)
|
||||
template = pack.get("report")
|
||||
|
||||
encounter = EncounterReport(
|
||||
runs=100,
|
||||
seed=1,
|
||||
wins={"players": 65, "monsters": 33},
|
||||
draws=2,
|
||||
avg_rounds=7.2,
|
||||
attrition={
|
||||
"goblin": CombatantAttrition(2.45, 0.12, 18.30, 4.20, 0.00),
|
||||
"orc": CombatantAttrition(3.20, 0.25, 28.40, 15.60, 0.00),
|
||||
},
|
||||
)
|
||||
|
||||
ctx = build_report_context(
|
||||
encounter=encounter,
|
||||
spec_name="test",
|
||||
)
|
||||
|
||||
prompt = build_report_prompt(ctx, template)
|
||||
|
||||
# Should contain the system prompt text
|
||||
assert "Vous êtes le narrateur" in prompt
|
||||
assert "Bilan d'équilibrage" in prompt
|
||||
assert "Danger et attrition" in prompt
|
||||
# Should contain the rendered encounter data
|
||||
assert "Victoires players : 65.0%" in prompt or "Victoires players : 65" in prompt
|
||||
assert "goblin" in prompt
|
||||
assert "orc" in prompt
|
||||
# Should contain attrition
|
||||
assert "Attrition moyenne par combatant" in prompt
|
||||
assert "touches" in prompt
|
||||
|
||||
|
||||
def test_report_prompt_version_different_from_nl_default() -> None:
|
||||
"""report prompt_version differs from nl_default."""
|
||||
pack_dir = Path(__file__).resolve().parent / "fixtures" / "prompt_pack_fs"
|
||||
pack = PromptPack.load(pack_dir)
|
||||
|
||||
report_version = pack.prompt_version("report")
|
||||
nl_version = pack.prompt_version("nl_default")
|
||||
assert report_version != nl_version
|
||||
Reference in New Issue
Block a user