"""Token-free detection of user *reactions* to the agent. Currently the only reaction is ``vibe`` — an expression of affection or gratitude toward the agent (``ily``, ``<3``, ``love you``, ``good bot``, a heart emoji, …). Detection is a curated regex/lexicon: **no model call, no tokens**. This is the single source of truth shared by every surface — the CLI pet, the TUI heart, and the desktop floating hearts all react off the same signal, delivered via ``AIAgent.reaction_callback`` (wired per interactive host). Generalized on purpose: :func:`detect_reaction` returns a reaction *kind* string, so new kinds (other emoji reactions, etc.) can be added here without touching any caller. We match affection specifically — not general positive sentiment — so "this is great" does NOT fire, but "good bot" / "❤️" do. """ from __future__ import annotations import re #: The affection/gratitude reaction — the only kind today. VIBE = "vibe" # Curated affection lexicon. Kept deliberately narrow: gratitude + love aimed at # the agent, heart emoji, and ``<3`` (but not the broken heart `` str | None: """Return the reaction kind for *text* (currently :data:`VIBE`), or ``None``. Pure, token-free, and safe to call on every user turn. """ if not text: return None return VIBE if _VIBE_RE.search(text) else None