Two related root causes for the '?[33mTool progress: NEW?[0m' garbling reported on kitty, alacritty, ghostty and gnome-console: 1. /verbose label printing used self.console.print() with Rich markup ([yellow]...[/]). self.console is a plain Rich Console() whose output goes directly to sys.stdout, which patch_stdout's StdoutProxy intercepts and mangles raw ANSI sequences. 2. Context pressure status lines (e.g. 'approaching compaction') from AIAgent._safe_print() had the same problem -- _safe_print() was a @staticmethod that always called builtin print(), bypassing the prompt_toolkit renderer entirely. Fix: - Convert AIAgent._safe_print() from @staticmethod to an instance method that delegates to self._print_fn (defaults to builtin print, preserving all non-CLI behaviour). - After the CLI creates its AIAgent instance, wire self.agent._print_fn to the existing _cprint() helper which routes through prompt_toolkit.print_formatted_text(ANSI(text)). - Rewrite the /verbose feedback labels to use hermes_cli.colors.Colors ANSI constants in f-strings and emit them via _cprint() directly, removing the Rich-markup-inside-patch_stdout anti-pattern. Fixes #2262 Co-authored-by: Animesh Mishra <animesh.m.7523@gmail.com>
This commit is contained in:
18
cli.py
Executable file → Normal file
18
cli.py
Executable file → Normal file
@@ -1915,6 +1915,9 @@ class HermesCLI:
|
||||
tool_progress_callback=self._on_tool_progress,
|
||||
stream_delta_callback=self._stream_delta if self.streaming_enabled else None,
|
||||
)
|
||||
# Route agent status output through prompt_toolkit so ANSI escape
|
||||
# sequences aren't garbled by patch_stdout's StdoutProxy (#2262).
|
||||
self.agent._print_fn = _cprint
|
||||
self._active_agent_route_signature = (
|
||||
effective_model,
|
||||
runtime.get("provider"),
|
||||
@@ -4238,13 +4241,18 @@ class HermesCLI:
|
||||
elif not self.show_reasoning:
|
||||
self.agent.reasoning_callback = None
|
||||
|
||||
# Use raw ANSI codes via _cprint so the output is routed through
|
||||
# prompt_toolkit's renderer. self.console.print() with Rich markup
|
||||
# writes directly to stdout which patch_stdout's StdoutProxy mangles
|
||||
# into garbled sequences like '?[33mTool progress: NEW?[0m' (#2262).
|
||||
from hermes_cli.colors import Colors as _Colors
|
||||
labels = {
|
||||
"off": "[dim]Tool progress: OFF[/] — silent mode, just the final response.",
|
||||
"new": "[yellow]Tool progress: NEW[/] — show each new tool (skip repeats).",
|
||||
"all": "[green]Tool progress: ALL[/] — show every tool call.",
|
||||
"verbose": "[bold green]Tool progress: VERBOSE[/] — full args, results, think blocks, and debug logs.",
|
||||
"off": f"{_Colors.DIM}Tool progress: OFF{_Colors.RESET} — silent mode, just the final response.",
|
||||
"new": f"{_Colors.YELLOW}Tool progress: NEW{_Colors.RESET} — show each new tool (skip repeats).",
|
||||
"all": f"{_Colors.GREEN}Tool progress: ALL{_Colors.RESET} — show every tool call.",
|
||||
"verbose": f"{_Colors.BOLD}{_Colors.GREEN}Tool progress: VERBOSE{_Colors.RESET} — full args, results, think blocks, and debug logs.",
|
||||
}
|
||||
self.console.print(labels.get(self.tool_progress_mode, ""))
|
||||
_cprint(labels.get(self.tool_progress_mode, ""))
|
||||
|
||||
def _handle_reasoning_command(self, cmd: str):
|
||||
"""Handle /reasoning — manage effort level and display toggle.
|
||||
|
||||
Reference in New Issue
Block a user