fix(cli): commit tool scrollback lines in verbose mode (non-streaming/MoA) (#53785)

In the interactive CLI, the aggregator's tool calls under a MoA preset (or
any non-streaming model call, e.g. copilot-acp) appeared to overwrite each
other instead of building scrollable history. Each tool only updated the
transient spinner line; no committed scrollback line was printed.

Root cause: persistent tool lines in _on_tool_progress's tool.completed
branch were gated on tool_progress_mode in {all, new}, omitting 'verbose'.
Streaming models hid the bug because _on_tool_gen_start commits a 'preparing'
line per tool during streaming; non-streaming calls (MoA forces
_use_streaming=False) never emit that, so under 'verbose' there was no
committed line at all — only the self-overwriting spinner.

'verbose' is strictly more than 'all', so it now commits the same scrollback
line. Verified live via interactive PTY on the MoA opus-gpt preset: three
terminal calls in turn 1 and two in turn 2 each render as separate persistent
lines.
This commit is contained in:
Teknium 2026-06-27 12:29:55 -07:00 committed by GitHub
parent 227e6c0143
commit d470ed0c4c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 5 deletions

12
cli.py
View file

@ -10485,8 +10485,16 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin):
if event_type == "tool.completed":
self._tool_start_time = 0.0
# Print stacked scrollback line for "all" / "new" modes
if function_name and self.tool_progress_mode in {"all", "new"}:
# Print stacked scrollback line for "new" / "all" / "verbose" modes.
# "verbose" was previously omitted here, so non-streaming model
# calls (MoA aggregator, copilot-acp) rendered each tool only into
# the transient spinner line — which overwrites itself, so no
# scrollable tool history accumulated. Streaming models hid the bug
# because _on_tool_gen_start commits a "preparing" line per tool;
# non-streaming calls never emit that, leaving verbose mode with no
# committed line at all. "verbose" is strictly more than "all", so
# it must commit at least the same line.
if function_name and self.tool_progress_mode in {"new", "all", "verbose"}:
duration = kwargs.get("duration", 0.0)
is_error = kwargs.get("is_error", False)
# Pop stored args from tool.started for this function