Files
project-lyra/tests/test_perceive.py
T
serversdown ad1087e630 feat(prompting): Phase A — suppress the two mush sources in poker mode
Per docs/superpowers/specs/2026-07-01-poker-prompts-design.md, Phase A. Two
independent pipeline fixes that reduce mush at the table, ahead of the classifier:

1. _mode_menu_note is no longer injected in poker_cash — mid-session she should
   not be offering to switch modes.
2. _route skips the register/mood nudge in poker_cash — the lexicon heuristic
   misfired (neutral logistics like "table broke, 11:50pm" read as tilt/fatigue).
   Poker register will come from the Phase B MENTAL fragment instead. Non-poker
   modes keep the nudge unchanged.

2 tests. Full suite 180 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 23:25:16 +00:00

77 lines
3.1 KiB
Python

"""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")
# --- Phase A pipeline fixes: poker mode suppresses the two mush sources ---
def test_poker_mode_suppresses_tilt_nudge(mind):
from lyra import memory
memory.set_session_mode("s1", "poker_cash")
turn = mind.assemble("s1", "ugh I'm steaming, fucking coolered again!!", "cloud", None)
assert turn.register is None # at the table, register comes from fragments
sys_blob = " ".join(m["content"] for m in turn.messages if m["role"] == "system")
assert "on tilt" not in sys_blob.lower() # false-positive lexicon nudge suppressed
def test_mode_menu_note_suppressed_in_poker(mind):
from lyra import modes
poker = " ".join(m["content"] for m in mind.build_messages("s1", "stack 350", mode=modes.CASH)
if m["role"] == "system")
build = " ".join(m["content"] for m in mind.build_messages("s1", "let's refactor", mode=modes.get("build"))
if m["role"] == "system")
assert "Your modes:" not in poker # no "offer to switch" note at the table
assert "Your modes:" in build # still present in a non-poker mode