"""The scouting desk: named + descriptor recall, ambiguous→queue, generic→silence.""" from __future__ import annotations import importlib import numpy as np import pytest def _fake_embed(texts): out = [] for t in texts: v = np.zeros(64, dtype=np.float32) for w in t.lower().split(): v[hash(w) % 64] += 1.0 out.append((v if v.any() else np.full(64, 1e-6, dtype=np.float32)).tolist()) return out @pytest.fixture def mods(tmp_path, monkeypatch): monkeypatch.setenv("LYRA_DB_PATH", str(tmp_path / "test.db")) from lyra import llm monkeypatch.setattr(llm, "embed", _fake_embed) import lyra.memory as memory importlib.reload(memory) import lyra.poker as poker importlib.reload(poker) import lyra.scouting as scouting importlib.reload(scouting) return poker, scouting def test_named_player_surfaces_a_brief(mods): poker, scouting = mods sid = poker.start_session(venue="Meadows", stakes="1/3", buy_in=300) pid = poker.upsert_player("Sleepy John", venue="Meadows", category="reg") poker._c().execute( "INSERT INTO player_observations (player_id, session_id, cards, created_at) VALUES (?,?,?,?)", (pid, sid, "As Ks", poker._now())) poker._c().commit() note = scouting.scout("sleepy john just sat down on my left", venue="Meadows") assert note and "Sleepy John" in note and "SCOUTING DESK" in note def test_descriptor_high_match_surfaces_with_confirm(mods): poker, scouting = mods poker.create_descriptor_villain("neck tattoo sleeve arm", venue="Meadows", category="reg") note = scouting.scout("the neck tattoo sleeve guy just 3bet me again", venue="Meadows") assert note and "confirm it's the same guy" in note def test_ambiguous_descriptor_queues_instead_of_interrupting(mods): poker, scouting = mods poker.create_descriptor_villain("neck tattoo sleeve arm", venue="Meadows") note = scouting.scout("the neck tattoo guy raised", venue="Meadows") assert note is None # didn't interrupt q = poker.list_identity_queue() assert q and q[0]["kind"] == "needs_clarification" def test_generic_descriptor_stays_silent(mods): poker, scouting = mods poker.create_descriptor_villain("neck tattoo sleeve arm", venue="Meadows") note = scouting.scout("the mid aged white guy with glasses raised", venue="Meadows") assert note is None assert poker.list_identity_queue() == [] # no queue spam for a non-identifier def test_no_player_reference_returns_nothing(mods): poker, scouting = mods poker.upsert_player("Sleepy John", venue="Meadows") assert scouting.scout("i folded pocket kings to a 4bet", venue="Meadows") is None