Skip to content

fix(display): suppress KawaiiSpinner animation under patch_stdout#2994

Merged
teknium1 merged 1 commit intomainfrom
hermes/hermes-7d7ac769
Mar 25, 2026
Merged

fix(display): suppress KawaiiSpinner animation under patch_stdout#2994
teknium1 merged 1 commit intomainfrom
hermes/hermes-7d7ac769

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

Summary

When the CLI is active, sys.stdout is prompt_toolkit's StdoutProxy which queues writes and injects newlines around each flush(). This causes every \r spinner frame to land on its own line instead of overwriting the previous one, producing visible flickering where the spinner and status bar repeatedly swap positions during long agent runs.

The CLI already renders spinner state via a dedicated TUI widget (_spinner_text / get_spinner_text), so KawaiiSpinner's \r-based loop is redundant under StdoutProxy. Detect the proxy and suppress the animation entirely — the thread still runs to preserve start()/stop() semantics.

Also removes the 0.4s flush rate-limit workaround that was papering over the same issue, and cleans up the unused _last_flush_time attribute.

Salvaged from PR #2908 by @Mibayy. Fixes applied:

  • Fixed detection: PR checked _raw (doesn't exist), actual attribute is raw — used hasattr + class name check instead
  • Dropped unrelated bundled changes (OpenClaw migration, delegation budgets, docs)

Test plan

  • 98 display/spinner tests pass
  • Display changes — needs live PTY verification on next interactive session
When the CLI is active, sys.stdout is prompt_toolkit's StdoutProxy which
queues writes and injects newlines around each flush(). This causes every
\r spinner frame to land on its own line instead of overwriting the
previous one, producing visible flickering where the spinner and status
bar repeatedly swap positions.

The CLI already renders spinner state via a dedicated TUI widget
(_spinner_text / get_spinner_text), so KawaiiSpinner's \r-based loop is
redundant under StdoutProxy. Detect the proxy and suppress the animation
entirely — the thread still runs to preserve start()/stop() semantics.

Also removes the 0.4s flush rate-limit workaround that was papering over
the same issue, and cleans up the unused _last_flush_time attribute.

Salvaged from PR #2908 by Mibayy (fixed _raw -> raw detection, dropped
unrelated bundled changes).
@teknium1 teknium1 merged commit 114e636 into main Mar 25, 2026
1 of 2 checks passed
InB4DevOps pushed a commit to InB4DevOps/hermes-agent that referenced this pull request Mar 25, 2026
…usResearch#2994)

When the CLI is active, sys.stdout is prompt_toolkit's StdoutProxy which
queues writes and injects newlines around each flush(). This causes every
\r spinner frame to land on its own line instead of overwriting the
previous one, producing visible flickering where the spinner and status
bar repeatedly swap positions.

The CLI already renders spinner state via a dedicated TUI widget
(_spinner_text / get_spinner_text), so KawaiiSpinner's \r-based loop is
redundant under StdoutProxy. Detect the proxy and suppress the animation
entirely — the thread still runs to preserve start()/stop() semantics.

Also removes the 0.4s flush rate-limit workaround that was papering over
the same issue, and cleans up the unused _last_flush_time attribute.

Salvaged from PR NousResearch#2908 by Mibayy (fixed _raw -> raw detection, dropped
unrelated bundled changes).
outsourc-e pushed a commit to outsourc-e/hermes-agent that referenced this pull request Mar 26, 2026
…usResearch#2994)

When the CLI is active, sys.stdout is prompt_toolkit's StdoutProxy which
queues writes and injects newlines around each flush(). This causes every
\r spinner frame to land on its own line instead of overwriting the
previous one, producing visible flickering where the spinner and status
bar repeatedly swap positions.

The CLI already renders spinner state via a dedicated TUI widget
(_spinner_text / get_spinner_text), so KawaiiSpinner's \r-based loop is
redundant under StdoutProxy. Detect the proxy and suppress the animation
entirely — the thread still runs to preserve start()/stop() semantics.

Also removes the 0.4s flush rate-limit workaround that was papering over
the same issue, and cleans up the unused _last_flush_time attribute.

Salvaged from PR NousResearch#2908 by Mibayy (fixed _raw -> raw detection, dropped
unrelated bundled changes).
StreamOfRon pushed a commit to StreamOfRon/hermes-agent that referenced this pull request Mar 29, 2026
…usResearch#2994)

When the CLI is active, sys.stdout is prompt_toolkit's StdoutProxy which
queues writes and injects newlines around each flush(). This causes every
\r spinner frame to land on its own line instead of overwriting the
previous one, producing visible flickering where the spinner and status
bar repeatedly swap positions.

The CLI already renders spinner state via a dedicated TUI widget
(_spinner_text / get_spinner_text), so KawaiiSpinner's \r-based loop is
redundant under StdoutProxy. Detect the proxy and suppress the animation
entirely — the thread still runs to preserve start()/stop() semantics.

Also removes the 0.4s flush rate-limit workaround that was papering over
the same issue, and cleans up the unused _last_flush_time attribute.

Salvaged from PR NousResearch#2908 by Mibayy (fixed _raw -> raw detection, dropped
unrelated bundled changes).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant