Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4020,9 +4020,13 @@ def _on_thinking(self, text: str) -> None:

def _current_reasoning_callback(self):
"""Return the active reasoning display callback for the current mode."""
if self.show_reasoning and self.streaming_enabled:
return self._stream_reasoning_delta
if self.verbose and not self.show_reasoning:
if self.show_reasoning:
return (
self._stream_reasoning_delta
if self.streaming_enabled
else self._on_reasoning
)
if self.verbose:
return self._on_reasoning
return None

Expand All @@ -4031,6 +4035,8 @@ def _emit_reasoning_preview(self, reasoning_text: str) -> None:
preview_text = reasoning_text.strip()
if not preview_text:
return
if getattr(self, "show_reasoning", False):
self._reasoning_shown_this_turn = True

try:
term_width = shutil.get_terminal_size().columns
Expand Down
19 changes: 16 additions & 3 deletions tests/cli/test_reasoning_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,15 @@ def test_callback_none_does_not_crash(self):


class TestReasoningPreviewBuffering(unittest.TestCase):
def _make_cli(self):
def _make_cli(self, *, show_reasoning=False):
from cli import HermesCLI

cli = HermesCLI.__new__(HermesCLI)
cli.verbose = True
cli.show_reasoning = show_reasoning
cli._spinner_text = ""
cli._reasoning_preview_buf = ""
cli._reasoning_shown_this_turn = False
cli._invalidate = lambda *args, **kwargs: None
return cli

Expand Down Expand Up @@ -373,6 +375,15 @@ def test_reasoning_flush_threshold_tracks_terminal_width(self, _mock_term):
cli._flush_reasoning_preview(force=False)
self.assertEqual(cli._reasoning_preview_buf, "a" * 30)

@patch("cli._cprint")
def test_show_reasoning_preview_marks_turn_as_displayed(self, mock_cprint):
cli = self._make_cli(show_reasoning=True)

cli._emit_reasoning_preview("working through the answer")

self.assertTrue(cli._reasoning_shown_this_turn)
self.assertEqual(mock_cprint.call_count, 1)


class TestReasoningDisplayModeSelection(unittest.TestCase):
def _make_cli(self, *, show_reasoning=False, streaming_enabled=False, verbose=False):
Expand All @@ -386,10 +397,12 @@ def _make_cli(self, *, show_reasoning=False, streaming_enabled=False, verbose=Fa
cli._on_reasoning = lambda text: ("preview", text)
return cli

def test_show_reasoning_non_streaming_uses_final_box_only(self):
def test_show_reasoning_non_streaming_uses_preview_callback(self):
cli = self._make_cli(show_reasoning=True, streaming_enabled=False, verbose=False)

self.assertIsNone(cli._current_reasoning_callback())
callback = cli._current_reasoning_callback()
self.assertIsNotNone(callback)
self.assertEqual(callback("x"), ("preview", "x"))

def test_show_reasoning_streaming_uses_live_reasoning_box(self):
cli = self._make_cli(show_reasoning=True, streaming_enabled=True, verbose=False)
Expand Down
Loading