"""Token-free detection of user *reactions* to the agent. The only reaction today is ``vibe`` — affection/gratitude aimed at the agent (``ily``, ``<3``, ``good bot``, a heart emoji). Detection is a curated regex: no model call. Single source of truth for the CLI pet, TUI heart and desktop hearts via ``AIAgent.reaction_callback``. :func:`detect_reaction` returns a *kind* string so new kinds can be added without touching callers. Matches affection specifically, not general positive sentiment ("this is great" does NOT fire). """ from __future__ import annotations import re #: The affection/gratitude reaction — the only kind today. VIBE = "vibe" # Narrow lexicon: gratitude + love aimed at the agent, hearts, ``<3`` (not `` str | None: """Return the reaction kind for *text* (currently :data:`VIBE`), or ``None``.""" if not text: return None return VIBE if _VIBE_RE.search(text) else None