fix(cli): make refresh_interval configurable, default to 0 (disabled)

Commit 6724daa2c added refresh_interval=1.0 to keep the idle clock
ticking, but unconditional 1 Hz redraws in non-fullscreen prompt_toolkit
mode cause terminal emulators (Xshell, iTerm2, Windows Terminal) to
auto-scroll to the bottom on every tick — breaking scroll-up to read
history.

Drive it from display.cli_refresh_interval (0 = disabled, the default)
so users who want the ticking clock can opt in without affecting everyone.

Fixes: #48309
Related: 6724daa2c, 8972a151a
This commit is contained in:
OYLFLMH 2026-06-18 07:59:37 +00:00 committed by Teknium
parent 01a6f11896
commit c1ffd4c3b4
2 changed files with 13 additions and 7 deletions

14
cli.py
View file

@ -13527,13 +13527,13 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin):
style=style,
full_screen=False,
mouse_support=False,
# The status bar contains wall-clock read-outs (live prompt elapsed
# and idle-since-last-turn). Once a turn finishes there may be no
# further events to invalidate the app, so prompt_toolkit would keep
# rendering the first post-turn value (usually ``✓ 0s``) forever.
# A low-rate refresh keeps the clock honest without reintroducing a
# custom repaint thread or touching conversation state.
refresh_interval=1.0,
# Read from display.cli_refresh_interval (default 0 = disabled).
# When non-zero, prompt_toolkit redraws the UI on this cadence
# during idle, keeping wall-clock status-bar read-outs ticking.
# Set to 0 to suppress background redraws entirely — avoids
# fighting terminal auto-scroll in non-fullscreen mode (Xshell,
# iTerm2, Windows Terminal). See #48309.
refresh_interval=float(CLI_CONFIG.get("display", {}).get("cli_refresh_interval", 0)),
# Erase the live bottom chrome (status bar, input box, separator
# rules) on exit instead of freezing a final copy into scrollback.
# Without this, prompt_toolkit's render_as_done teardown repaints

View file

@ -1581,6 +1581,12 @@ DEFAULT_CONFIG = {
# TUI busy indicator style: kaomoji (default), emoji, unicode (braille
# spinner), or ascii. Live-swappable via `/indicator <style>`.
"tui_status_indicator": "kaomoji",
# Seconds between prompt_toolkit redraws in the classic CLI when idle.
# 0 = disabled (no background refresh — the pre-0.15.2 behaviour).
# Positive values e.g. 1.0 keep wall-clock status-bar read-outs
# (idle-since-last-turn) ticking but may fight terminal auto-scroll in
# non-fullscreen mode on some emulators (Xshell, iTerm2, etc.).
"cli_refresh_interval": 0,
"user_message_preview": { # CLI: how many submitted user-message lines to echo back in scrollback
"first_lines": 2,
"last_lines": 2,