fix(cli): stop spinner before resumed answer deltas

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Xubin Ren 2026-05-13 09:18:59 +00:00
parent 53831e1611
commit 567e95dee6
2 changed files with 23 additions and 2 deletions

View File

@ -143,10 +143,13 @@ class StreamRenderer:
return self._header_printed
def ensure_header(self) -> None:
"""Print the assistant header once, before trace or answer content."""
"""Stop transient status and print the assistant header once."""
# A turn can print trace rows before the final answer, then restart the
# spinner while tools run. The next answer delta still needs to stop
# that spinner even though the header was already printed.
self._stop_spinner()
if self._header_printed:
return
self._stop_spinner()
self._console.print()
header = f"{self._bot_icon} {self._bot_name}" if self._bot_icon else self._bot_name
self._console.print(f"[cyan]{header}[/cyan]")

View File

@ -115,6 +115,24 @@ def test_thinking_spinner_clears_status_line_when_paused():
assert "\r\x1b[2K" in stream.getvalue()
def test_stream_renderer_stops_spinner_even_after_header_printed():
"""A later answer delta must stop the spinner even when header already exists."""
stream = StringIO()
stream.isatty = lambda: True # type: ignore[method-assign]
mock_console = MagicMock()
mock_console.file = stream
spinner = MagicMock()
mock_console.status.return_value = spinner
with patch.object(stream_mod, "_make_console", return_value=mock_console):
renderer = stream_mod.StreamRenderer(show_spinner=True)
renderer._header_printed = True
renderer.ensure_header()
spinner.stop.assert_called_once()
assert "\r\x1b[2K" in stream.getvalue()
def test_print_cli_progress_line_opens_renderer_header_before_trace():
"""Trace lines should appear under the assistant header, not under You."""
order: list[str] = []