Skip to content

fix: resolve garbled ANSI escape codes in status printouts#2448

Merged
teknium1 merged 1 commit intomainfrom
hermes/hermes-baa39faf
Mar 22, 2026
Merged

fix: resolve garbled ANSI escape codes in status printouts#2448
teknium1 merged 1 commit intomainfrom
hermes/hermes-baa39faf

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

Summary

Fixes garbled terminal output like ?[33mTool progress: NEW?[0m on kitty, alacritty, ghostty, and gnome-console.

Two callsites bypassed _cprint() and wrote ANSI/Rich markup directly to stdout, where patch_stdout's StdoutProxy mangles escape sequences.

Fix

  • _safe_print → instance method with pluggable _print_fn. CLI sets agent._print_fn = _cprint to route through prompt_toolkit. Default (None) uses late-bound print so test patching still works.
  • /verbose labels → replaced Rich markup with raw ANSI constants via _cprint().

Cherry-picked from PR #2265 by @amethystani, with a follow-up fix: changed _print_fn default from print (captured reference) to None (late binding) to preserve test patchability.

Live tested

  • Interactive CLI via tmux: /verbose cycling through all 4 modes — clean output, no garbled codes
  • Two consecutive tool calls with reasoning blocks — clean rendering
  • TestVprintForceOnErrors passes (3/3)

Fixes #2262

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
@teknium1 teknium1 merged commit 8cb7864 into main Mar 22, 2026
1 check failed
outsourc-e pushed a commit to outsourc-e/hermes-agent that referenced this pull request Mar 26, 2026
…rch#2262) (NousResearch#2448)

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 NousResearch#2262

Co-authored-by: Animesh Mishra <animesh.m.7523@gmail.com>
aashizpoudel pushed a commit to aashizpoudel/hermes-agent that referenced this pull request Mar 30, 2026
…rch#2262) (NousResearch#2448)

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 NousResearch#2262

Co-authored-by: Animesh Mishra <animesh.m.7523@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant