diff --git a/cli.py b/cli.py index 379ca15df1a..560b5d9a2e3 100644 --- a/cli.py +++ b/cli.py @@ -4862,6 +4862,12 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin): self._pet_event = state self._pet_event_until = time.monotonic() + secs + def _on_reaction(self, kind: str) -> None: + """User affection (ily / <3 / good bot), core-detected — the pet's share + of the vibe signal that plays hearts on the TUI/desktop. Flash a celebrate.""" + if kind == "vibe": + self._pet_flash("jump") + def _pet_react_turn_end(self) -> None: """Flash the end-of-turn beat: failed on error, jump on a finished plan, else wave.""" if not self._pet_enabled: diff --git a/hermes_cli/cli_agent_setup_mixin.py b/hermes_cli/cli_agent_setup_mixin.py index a71d8835698..d3c967405ad 100644 --- a/hermes_cli/cli_agent_setup_mixin.py +++ b/hermes_cli/cli_agent_setup_mixin.py @@ -390,6 +390,7 @@ class CLIAgentSetupMixin: tool_gen_callback=self._on_tool_gen_start if self.streaming_enabled else None, notice_callback=self._on_notice, notice_clear_callback=self._on_notice_clear, + reaction_callback=self._on_reaction, ) # Store reference for atexit memory provider shutdown. # NOTE: this MUST write to the ``cli`` module's global, not a diff --git a/tui_gateway/server.py b/tui_gateway/server.py index 8e825a22669..b9cc8e478ec 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -3860,6 +3860,9 @@ def _agent_cbs(sid: str) -> dict: "tool_gen_callback": lambda name: _tool_progress_enabled(sid) and _emit("tool.generating", sid, {"name": name}), "thinking_callback": lambda text: _emit("thinking.delta", sid, {"text": text}), + # Affection reaction (ily / <3 / good bot) → hearts. Core-detected, so + # the TUI heart and desktop floating hearts share one signal. + "reaction_callback": lambda kind: _emit("reaction", sid, {"kind": kind}), "reasoning_callback": lambda text: _emit( "reasoning.delta", sid,