From 0e2adf9dadab1cc9eaf5ae2028765d7c7037092e Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Fri, 10 Jul 2026 05:42:04 -0500 Subject: [PATCH] feat(gateway,cli): emit + consume the reaction signal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tui_gateway forwards reaction_callback as a `reaction` event (shared by the TUI and the desktop app). The interactive CLI wires reaction_callback to flash the pet's celebrate ("jump") pose — the CLI's analogue of hearts. --- cli.py | 6 ++++++ hermes_cli/cli_agent_setup_mixin.py | 1 + tui_gateway/server.py | 3 +++ 3 files changed, 10 insertions(+) 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,