Skip to content

fix(cli): drop the blank line above the streamed reasoning box footer - #139000

Open
iyoda wants to merge 1 commit into
NousResearch:mainfrom
iyoda:fix/cli-reasoning-trailing-blank-line
Open

iyoda wants to merge 1 commit into
NousResearch:mainfrom
iyoda:fix/cli-reasoning-trailing-blank-line

Conversation

@iyoda

@iyoda iyoda commented Oct 15, 2026

Copy link
Copy Markdown

What does this PR do?

With show_reasoning + streaming on, the CLI reasoning box always ends with an empty dim line just above the └───┘ footer when the model is Anthropic Opus.

Cause: Anthropic thinking text ends with \n\n (every Opus reasoning in my local state.db does), and _stream_reasoning_delta (hermes_cli/cli_stream_mixin.py) prints every newline as a line, so the second \n becomes a blank row before _close_reasoning_box draws the footer.

Fix: trailing newlines stay in _reasoning_buf until more text arrives, and _close_reasoning_box strips them. Paragraph breaks inside the reasoning are released as soon as the next text arrives, so they still render; leading blank lines are unchanged.

Same loop, same symptom: the newline that ends a force-flushed (>80 char, no newline yet) partial line was also printed as an empty row, so a paragraph break after a long line rendered as two blank lines. That newline is now consumed as the end of the already-printed line.

Scope: only the blank-line handling. #53535 (streaming reasoning clamp, open) rewrites the same loop with a similar blank-line hold as part of a larger feature; this PR is the minimal bug fix, and the two will conflict textually; the tests here describe the display contract a clamp change can keep.

Related Issue

No existing issue. Related: #53535 (overlapping lines, larger scope).

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • hermes_cli/cli_stream_mixin.py: _stream_reasoning_delta holds trailing newlines and skips the newline that ends a force-flushed line; _close_reasoning_box strips the held newlines and clears the flush flag; _reset_stream_state clears the flag too.
  • tests/hermes_cli/test_reasoning_box_blank_lines.py: two behaviour contracts (no trailing blank line, single and split chunks; no extra blank after a force-flushed line, including a whitespace continuation).

How to Test

  1. scripts/run_tests.sh tests/hermes_cli/test_reasoning_box_blank_lines.py — 4 cases fail on main, pass with this change.
  2. scripts/run_tests.sh tests/hermes_cli/test_reasoning_box_blank_lines.py tests/hermes_cli/test_reasoning_command.py tests/hermes_cli/test_stream_delta_think_tag.py tests/hermes_cli/test_status_lines_held_during_stream_box.py — 42 passed.
  3. Replayed 200 real Opus reasoning texts from a local state.db through _stream_reasoning_delta in random 1–12 char chunks (5 chunkings each): no box ends on a blank line and no text is lost.
  4. Manual: /reasoning show with an Anthropic Opus model; the reasoning box closes directly on its last text line.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass — ran the affected tests/hermes_cli/ files via scripts/run_tests.sh, not the full suite
  • python scripts/check passes (the blocking lint and code-health checks CI runs)
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 26.7

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — N/A (string handling only)
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

Anthropic thinking text ends with "\n\n", and _stream_reasoning_delta printed
every newline as a line, so the reasoning box always closed on an empty dim
row. Trailing newlines are now held in the buffer and stripped at close;
paragraph breaks inside the reasoning still render.

The newline that ends a force-flushed (>80 char) partial line was also
printed as an empty row, doubling paragraph gaps after long lines.
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard area/streaming Streaming responses: gateway delivery, provider wire labels Oct 15, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/streaming Streaming responses: gateway delivery, provider wire comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants