"""Poker domain: structured session/hand/villain storage + stats, and the tools.""" from __future__ import annotations import importlib import pytest @pytest.fixture def lyra(tmp_path, monkeypatch): monkeypatch.setenv("LYRA_DB_PATH", str(tmp_path / "test.db")) from lyra import llm monkeypatch.setattr(llm, "embed", lambda texts: [[0.1, 0.2, 0.3] for _ in texts]) import lyra.memory as memory importlib.reload(memory) import lyra.poker as poker importlib.reload(poker) # rebind to the reloaded memory + reset its schema flag return poker def test_session_lifecycle_and_net(lyra): poker = lyra sid = poker.start_session(venue="Meadows", stakes="1/3", buy_in=400) assert poker.live_session()["id"] == sid poker.add_buyin(500) # rebuy -> total 900 s = poker.end_session(cash_out=627) assert s["buy_in_total"] == 900 assert s["net"] == pytest.approx(-273) assert s["status"] == "closed" assert poker.live_session() is None # closed -> no live session def test_log_hand_partial_fields(lyra): poker = lyra poker.start_session(stakes="1/3", buy_in=300) hid = poker.log_hand(position="BTN", hole_cards="AKs", result=120, tag="confidence") hands = poker.list_hands() assert len(hands) == 1 and hands[0]["id"] == hid assert hands[0]["hole_cards"] == "AKs" and hands[0]["result"] == 120 assert hands[0]["board"] is None # unspecified fields stay null def test_villain_file_upsert_and_read(lyra): poker = lyra poker.start_session(venue="Meadows", stakes="1/3", buy_in=300) poker.add_read("limp-called K4s UTG", name="Sleepy John", seat="3", tendencies="loose-passive, jackpot dreamer", category="feeder", venue="Meadows") # update the same player poker.add_read("cold-called a 3-bet with A2o", name="sleepy john") file = poker.get_villain_file(name="Sleepy") assert len(file) == 1 # matched by name, not duplicated assert file[0]["category"] == "feeder" def test_running_stats(lyra): poker = lyra s1 = poker.start_session(stakes="1/3", buy_in=300) poker.end_session(540, session_id=s1) s2 = poker.start_session(stakes="1/3", buy_in=400) poker.end_session(300, session_id=s2) rs = poker.running_stats(stakes="1/3") assert rs["sessions"] == 2 assert rs["net"] == pytest.approx(140) # +240 then -100 assert "1/3" in rs["by_stake"] def test_poker_tools_dispatch(lyra): from lyra import tools assert "started" in tools.dispatch("start_session", {"stakes": "1/3", "buy_in": 300}) assert "logged" in tools.dispatch("log_hand", {"position": "CO", "hole_cards": "QQ"}) assert "closed" in tools.dispatch("end_session", {"cash_out": 500}) # the poker tools are offered to the model names = {s["function"]["name"] for s in tools.specs()} assert {"start_session", "log_hand", "end_session", "running_stats", "get_villain_file"} <= names