mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-27 01:11:40 +00:00
fix(cli): use display width for wrapped spinner height
This commit is contained in:
parent
ca32a2a60b
commit
4e8f60fd11
2 changed files with 31 additions and 20 deletions
44
cli.py
44
cli.py
|
|
@ -2068,20 +2068,35 @@ class HermesCLI:
|
||||||
|
|
||||||
def _spinner_widget_height(self, width: Optional[int] = None) -> int:
|
def _spinner_widget_height(self, width: Optional[int] = None) -> int:
|
||||||
"""Return the visible height for the spinner/status text line above the status bar."""
|
"""Return the visible height for the spinner/status text line above the status bar."""
|
||||||
if not getattr(self, "_spinner_text", ""):
|
spinner_line = self._render_spinner_text()
|
||||||
|
if not spinner_line:
|
||||||
return 0
|
return 0
|
||||||
if self._use_minimal_tui_chrome(width=width):
|
if self._use_minimal_tui_chrome(width=width):
|
||||||
return 0
|
return 0
|
||||||
# Compute how many lines the spinner text needs when wrapped.
|
|
||||||
# The rendered text is " {emoji} {label} ({elapsed})" — about
|
|
||||||
# len(_spinner_text) + 16 chars for indent + timer suffix.
|
|
||||||
width = width or self._get_tui_terminal_width()
|
width = width or self._get_tui_terminal_width()
|
||||||
if width and width > 10:
|
if width and width > 10:
|
||||||
import math
|
import math
|
||||||
text_len = len(self._spinner_text) + 16 # indent + timer
|
text_width = self._status_bar_display_width(spinner_line)
|
||||||
return max(1, math.ceil(text_len / width))
|
return max(1, math.ceil(text_width / width))
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def _render_spinner_text(self) -> str:
|
||||||
|
"""Return the live spinner/status text exactly as rendered in the TUI."""
|
||||||
|
txt = getattr(self, "_spinner_text", "")
|
||||||
|
if not txt:
|
||||||
|
return ""
|
||||||
|
t0 = getattr(self, "_tool_start_time", 0) or 0
|
||||||
|
if t0 > 0:
|
||||||
|
import time as _time
|
||||||
|
elapsed = _time.monotonic() - t0
|
||||||
|
if elapsed >= 60:
|
||||||
|
_m, _s = int(elapsed // 60), int(elapsed % 60)
|
||||||
|
elapsed_str = f"{_m}m {_s}s"
|
||||||
|
else:
|
||||||
|
elapsed_str = f"{elapsed:.1f}s"
|
||||||
|
return f" {txt} ({elapsed_str})"
|
||||||
|
return f" {txt}"
|
||||||
|
|
||||||
def _get_voice_status_fragments(self, width: Optional[int] = None):
|
def _get_voice_status_fragments(self, width: Optional[int] = None):
|
||||||
"""Return the voice status bar fragments for the interactive TUI."""
|
"""Return the voice status bar fragments for the interactive TUI."""
|
||||||
width = width or self._get_tui_terminal_width()
|
width = width or self._get_tui_terminal_width()
|
||||||
|
|
@ -9375,21 +9390,10 @@ class HermesCLI:
|
||||||
return cli_ref._agent_spacer_height()
|
return cli_ref._agent_spacer_height()
|
||||||
|
|
||||||
def get_spinner_text():
|
def get_spinner_text():
|
||||||
txt = cli_ref._spinner_text
|
spinner_line = cli_ref._render_spinner_text()
|
||||||
if not txt:
|
if not spinner_line:
|
||||||
return []
|
return []
|
||||||
# Append live elapsed timer when a tool is running
|
return [('class:hint', spinner_line)]
|
||||||
t0 = cli_ref._tool_start_time
|
|
||||||
if t0 > 0:
|
|
||||||
import time as _time
|
|
||||||
elapsed = _time.monotonic() - t0
|
|
||||||
if elapsed >= 60:
|
|
||||||
_m, _s = int(elapsed // 60), int(elapsed % 60)
|
|
||||||
elapsed_str = f"{_m}m {_s}s"
|
|
||||||
else:
|
|
||||||
elapsed_str = f"{elapsed:.1f}s"
|
|
||||||
return [('class:hint', f' {txt} ({elapsed_str})')]
|
|
||||||
return [('class:hint', f' {txt}')]
|
|
||||||
|
|
||||||
def get_spinner_height():
|
def get_spinner_height():
|
||||||
return cli_ref._spinner_widget_height()
|
return cli_ref._spinner_widget_height()
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,13 @@ class TestCLIStatusBar:
|
||||||
cli_obj._spinner_text = ""
|
cli_obj._spinner_text = ""
|
||||||
assert cli_obj._spinner_widget_height(width=90) == 0
|
assert cli_obj._spinner_widget_height(width=90) == 0
|
||||||
|
|
||||||
|
def test_spinner_height_uses_display_width_for_wide_characters(self):
|
||||||
|
cli_obj = _make_cli()
|
||||||
|
cli_obj._spinner_text = "你" * 40
|
||||||
|
cli_obj._tool_start_time = 0
|
||||||
|
|
||||||
|
assert cli_obj._spinner_widget_height(width=64) == 2
|
||||||
|
|
||||||
def test_voice_status_bar_compacts_on_narrow_terminals(self):
|
def test_voice_status_bar_compacts_on_narrow_terminals(self):
|
||||||
cli_obj = _make_cli()
|
cli_obj = _make_cli()
|
||||||
cli_obj._voice_mode = True
|
cli_obj._voice_mode = True
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue