"""Perceive: cheap heuristic read of the moment, and route turning it into a nudge.""" from __future__ import annotations import importlib import pytest from lyra import perceive def test_reads_tilt(): m = perceive.read("I'm so fucking tilted, card dead all night, this is brutal!!") assert m["tilt"] >= 0.5 and m["sentiment"] < 0 and m["kind"] == "emotional" def test_reads_strategy_calm(): m = perceive.read("Should I fold the river here given his range and the board?") assert m["kind"] == "strategic" and m["tilt"] < 0.4 def test_reads_up_energy(): m = perceive.read("Let's go!! crushing it tonight, feeling so good!") assert m["sentiment"] > 0 and m["kind"] == "emotional" def test_reads_build_and_casual(): assert perceive.read("let's refactor the cognition pipeline module").get("kind") == "build" assert perceive.read("ok sounds good to me").get("kind") == "casual" assert perceive.read("ok sounds good to me")["tilt"] == 0.0 @pytest.fixture def mind(tmp_path, monkeypatch): monkeypatch.setenv("LYRA_DB_PATH", str(tmp_path / "test.db")) monkeypatch.setenv("CHAT_DELIBERATE", "false") 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.mind as mind importlib.reload(mind) memory.ensure_session("s1") return mind def test_route_injects_tilt_nudge(mind): turn = mind.assemble("s1", "ugh I'm steaming, fucking coolered again!!", "cloud", None) assert turn.register == "steady" sys_blob = " ".join(m["content"] for m in turn.messages if m["role"] == "system") assert "on tilt" in sys_blob.lower() or "frustrated" in sys_blob.lower() def test_route_quiet_on_neutral_turn(mind): turn = mind.assemble("s1", "what did we decide about the schema yesterday?", "cloud", None) assert turn.register is None # neutral -> no nudge assert not (turn.moment or {}).get("note")