fix: duplicate goodbye msg

This commit is contained in:
Brooklyn Nicholson 2026-03-09 17:38:30 -05:00
parent af6a92a4c2
commit 57faddd808
2 changed files with 11 additions and 14 deletions

14
cli.py
View file

@ -658,7 +658,6 @@ _DIM = "\033[2m"
_RST = "\033[0m" _RST = "\033[0m"
def _cprint(text: str): def _cprint(text: str):
"""Print ANSI-colored text to stdout."""
print(text) print(text)
# ASCII Art - HERMES-AGENT logo (full width, single line - requires ~95 char terminal) # ASCII Art - HERMES-AGENT logo (full width, single line - requires ~95 char terminal)
@ -1119,7 +1118,7 @@ class HermesCLI:
# Agent will be initialized on first use # Agent will be initialized on first use
self.agent: Optional[AIAgent] = None self.agent: Optional[AIAgent] = None
self._app = None # retained for backward compat (no longer used by TUI) self._app = None
# Conversation state # Conversation state
self.conversation_history: List[Dict[str, Any]] = [] self.conversation_history: List[Dict[str, Any]] = []
@ -1147,10 +1146,7 @@ class HermesCLI:
# History file for persistent input recall across sessions # History file for persistent input recall across sessions
self._history_file = Path.home() / ".hermes_history" self._history_file = Path.home() / ".hermes_history"
self._last_invalidate: float = 0.0
def _invalidate(self, min_interval: float = 0.25) -> None: def _invalidate(self, min_interval: float = 0.25) -> None:
"""No-op — retained for callback compatibility."""
pass pass
def _normalize_model_for_provider(self, resolved_provider: str) -> bool: def _normalize_model_for_provider(self, resolved_provider: str) -> bool:
@ -2826,8 +2822,7 @@ class HermesCLI:
except Exception as e: except Exception as e:
print(f" ❌ MCP reload failed: {e}") print(f" ❌ MCP reload failed: {e}")
def _stream_delta(self, text: str) -> None: def _stream_delta(self, text: str):
"""Write streaming token directly to stdout."""
sys.stdout.write(text) sys.stdout.write(text)
sys.stdout.flush() sys.stdout.flush()
@ -2967,9 +2962,9 @@ class HermesCLI:
self._approval_state = None self._approval_state = None
self._approval_deadline = 0 self._approval_deadline = 0
self._invalidate() self._invalidate()
def chat(self, message, images: list = None) -> Optional[str]: def chat(self, message, images: list = None) -> Optional[str]:
"""Send a message and get a response. Runs synchronously — streaming """Send a message and stream the response to stdout."""
tokens go directly to stdout via stream_delta_callback."""
if not self._ensure_runtime_credentials(): if not self._ensure_runtime_credentials():
return None return None
if not self._init_agent(): if not self._init_agent():
@ -3090,7 +3085,6 @@ class HermesCLI:
self.agent.interrupt() self.agent.interrupt()
print("\n⚡ Interrupted") print("\n⚡ Interrupted")
else: else:
print("\nGoodbye! ⚕")
break break
continue continue
except EOFError: except EOFError:

View file

@ -3492,12 +3492,15 @@ class AIAgent:
if thinking_spinner: if thinking_spinner:
thinking_spinner.stop("") thinking_spinner.stop("")
thinking_spinner = None thinking_spinner = None
response = self._interruptible_streaming_api_call( response = self._interruptible_streaming_api_call(
api_kwargs, on_first_delta=_stop_spinner) api_kwargs, on_first_delta=_stop_spinner)
# Newline after streamed content so tool lines don't overwrite it
if response and hasattr(response, 'choices') and response.choices: # Separate streamed content from tool status lines
msg = response.choices[0].message msg = getattr(response, "choices", [None])[0]
if msg and msg.content and msg.tool_calls: if msg and getattr(msg, "message", None):
m = msg.message
if m.content and m.tool_calls:
print(flush=True) print(flush=True)
else: else:
response = self._interruptible_api_call(api_kwargs) response = self._interruptible_api_call(api_kwargs)