import pytest import app.npc as npc from app.ollama_client import ModelError LOG = { "player": {"name": "Aldric", "race_id": "human", "calling_id": "sellsword", "luck_descriptor": "kind"}, "location": {"id": "greywater_docks", "name": "Greywater Docks"}, "party": [], "recent_events": [], "established_facts": [], "active_quests": [], "humiliations": [], } FENN = {"id": "fenn", "name": "Fenn", "persona": "A clerk.", "knowledge": ["The ledger is gone."], "capabilities": {}} def test_run_returns_prose_and_logs(monkeypatch): seen = {} def fake_chat(model, messages, options, *, think=None): seen.update(messages=messages, think=think) return 'Aye. [MOVE: reveal(varrell_twins)] [FACT: the ledger is gone]' logs = [] monkeypatch.setattr(npc, "load_npc", lambda i: FENN) monkeypatch.setattr(npc.ollama_client, "chat", fake_chat) monkeypatch.setattr(npc.call_log, "record", lambda **kw: logs.append(kw)) out = npc.run(LOG, "fenn", -10, ["reveal(varrell_twins)", "refuse"], "What happened?") assert out.startswith("Aye.") # persona + knowledge reached the model; utterance is present user_msg = seen["messages"][1]["content"] assert "A clerk." in user_msg and "The ledger is gone." in user_msg assert "What happened?" in user_msg assert seen["think"] is False assert logs and logs[0]["ok"] is True and logs[0]["role"] == "npc" def test_run_unknown_npc_raises(monkeypatch): monkeypatch.setattr(npc, "load_npc", lambda i: None) with pytest.raises(npc.UnknownNpc): npc.run(LOG, "nobody", 0, [], "hi") def test_run_logs_failure_and_reraises(monkeypatch): monkeypatch.setattr(npc, "load_npc", lambda i: FENN) def boom(*a, **k): raise ModelError("down") logs = [] monkeypatch.setattr(npc.ollama_client, "chat", boom) monkeypatch.setattr(npc.call_log, "record", lambda **kw: logs.append(kw)) with pytest.raises(ModelError): npc.run(LOG, "fenn", 0, [], "hi") assert logs and logs[0]["ok"] is False