fix(cli): keep trace output under assistant header
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
from contextlib import nullcontext
|
||||
from unittest.mock import AsyncMock, MagicMock, call, patch
|
||||
|
||||
import pytest
|
||||
@@ -96,6 +97,31 @@ def test_print_cli_progress_line_pauses_spinner_before_printing():
|
||||
assert order == ["start", "stop", "print", "start", "stop"]
|
||||
|
||||
|
||||
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] = []
|
||||
renderer = MagicMock()
|
||||
renderer.console.print.side_effect = lambda *_args, **_kwargs: order.append("print")
|
||||
renderer.ensure_header.side_effect = lambda: order.append("header")
|
||||
renderer.pause_spinner.return_value = nullcontext()
|
||||
|
||||
commands._print_cli_progress_line("tool running", None, renderer)
|
||||
|
||||
assert order == ["header", "print"]
|
||||
|
||||
|
||||
def test_print_cli_progress_line_stops_live_before_trace():
|
||||
"""A trace line should not leak the current transient Live frame."""
|
||||
mock_live = MagicMock()
|
||||
renderer = stream_mod.StreamRenderer(show_spinner=False)
|
||||
renderer._live = mock_live
|
||||
|
||||
commands._print_cli_progress_line("tool running", None, renderer)
|
||||
|
||||
mock_live.stop.assert_called_once()
|
||||
assert renderer._live is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_print_interactive_progress_line_pauses_spinner_before_printing():
|
||||
"""Interactive progress output should also pause spinner cleanly."""
|
||||
|
||||
@@ -50,6 +50,25 @@ async def test_reasoning_displayed_when_show_reasoning_enabled():
|
||||
assert calls == ["Let me think about this..."]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_reasoning_delta_displayed_when_show_reasoning_enabled():
|
||||
"""Streamed reasoning delta frames should use the reasoning renderer."""
|
||||
calls: list[str] = []
|
||||
channels_config = SimpleNamespace(
|
||||
send_progress=True, send_tool_hints=False, show_reasoning=True,
|
||||
)
|
||||
msg = SimpleNamespace(
|
||||
content="I should search first.",
|
||||
metadata={"_progress": True, "_reasoning_delta": True},
|
||||
)
|
||||
|
||||
with patch("nanobot.cli.commands._print_cli_reasoning", side_effect=lambda t, th, r=None: calls.append(t)):
|
||||
handled = await commands._maybe_print_interactive_progress(msg, None, channels_config)
|
||||
|
||||
assert handled is True
|
||||
assert calls == ["I should search first."]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_reasoning_hidden_when_show_reasoning_disabled():
|
||||
"""Reasoning content should be suppressed when show_reasoning is False."""
|
||||
|
||||
Reference in New Issue
Block a user