fix(bridge): block thinking spinner kaomoji from contaminating conversation history (#1051)
The hermes-agent CLI KawaiiSpinner sends decorative kaomoji text like "(◕‿◕✿) pondering..." through thinking_callback for its TUI widget. The bridge forwarded this as thinking.delta events, which the frontend stored in the message reasoning field. Over long conversations this contaminated the model's context: _copy_reasoning_content_for_api promoted the kaomoji text to reasoning_content, causing the LLM to reproduce kaomoji patterns in a self-reinforcing degradation loop. Fix: _make_thinking_callback unconditionally sends empty text. thinking_callback is purely CLI spinner status — it has no place in conversation history. Actual model reasoning (reasoning.delta) is unaffected.
This commit is contained in:
@@ -740,7 +740,7 @@ class AgentPool:
|
||||
session_db=self._db.get_for_profile(profile),
|
||||
ephemeral_system_prompt=prompt,
|
||||
status_callback=self._status_callback(session_id),
|
||||
thinking_callback=self._text_event_callback(session_id, "thinking.delta"),
|
||||
thinking_callback=self._make_thinking_callback(session_id),
|
||||
reasoning_callback=self._text_event_callback(session_id, "reasoning.delta"),
|
||||
tool_progress_callback=self._tool_progress_callback(session_id),
|
||||
tool_start_callback=self._tool_start_callback(session_id),
|
||||
@@ -992,6 +992,28 @@ class AgentPool:
|
||||
|
||||
return callback
|
||||
|
||||
def _make_thinking_callback(self, session_id: str):
|
||||
"""Create a thinking callback that never forwards spinner text as content.
|
||||
|
||||
The hermes-agent CLI uses thinking_callback for its KawaiiSpinner TUI
|
||||
widget — sending decorative text like "(◕‿◕✿) pondering..." during
|
||||
API calls. This is pure CLI UX decoration; it has no place in Web UI
|
||||
conversation history.
|
||||
|
||||
Prior behaviour forwarded this text as thinking.delta events, which the
|
||||
frontend stored in the message reasoning field. Over long conversations
|
||||
this contaminated the model's context: the LLM learned to reproduce
|
||||
kaomoji patterns, creating a self-reinforcing degradation loop.
|
||||
|
||||
This callback sends empty text unconditionally. The model's real
|
||||
reasoning content arrives through reasoning_callback → reasoning.delta,
|
||||
which is unaffected.
|
||||
"""
|
||||
def callback(text=None):
|
||||
self._append_event(session_id, {"event": "thinking.delta", "text": ""})
|
||||
|
||||
return callback
|
||||
|
||||
def _tool_start_callback(self, session_id: str):
|
||||
def callback(tool_call_id, function_name, function_args):
|
||||
self._append_event(session_id, {
|
||||
|
||||
Reference in New Issue
Block a user