fix: /reasoning command output ordering, display, and inline think extraction#1031
Merged
fix: /reasoning command output ordering, display, and inline think extraction#1031
Conversation
…traction Three issues with the /reasoning command: 1. Output interleaving: The command echo used print() while feedback used _cprint(), causing them to render out-of-order under prompt_toolkit's patch_stdout. Changed echo to use _cprint() so all output renders through the same path in correct order. 2. Reasoning display not working: /reasoning show toggled a flag but reasoning never appeared for models that embed thinking in inline <think> blocks rather than structured API fields. Added fallback extraction in _build_assistant_message to capture <think> block content as reasoning when no structured reasoning fields (reasoning, reasoning_content, reasoning_details) are present. This feeds into both the reasoning callback (during tool loops) and the post-response reasoning box display. 3. Feedback clarity: Added checkmarks to confirm actions, persisted show/hide to config (was session-only before), and aligned the status display for readability. Tests: 7 new tests for inline think block extraction (41 total).
The /reasoning command only existed in the CLI — messaging platforms
had no way to view or change reasoning settings. This adds:
1. /reasoning command handler in the gateway:
- No args: shows current effort level and display state
- /reasoning <level>: sets reasoning effort (none/low/medium/high/xhigh)
- /reasoning show|hide: toggles reasoning display in responses
- All changes saved to config.yaml immediately
2. Reasoning display in gateway responses:
- When show_reasoning is enabled, prepends a 'Reasoning' block
with the model's last_reasoning content before the response
- Collapses long reasoning (>15 lines) to keep messages readable
- Uses last_reasoning from run_conversation result dict
3. Plumbing:
- Added _show_reasoning attribute loaded from config at startup
- Propagated last_reasoning through _run_agent return dict
- Added /reasoning to help text and known_commands set
- Uses getattr for _show_reasoning to handle test stubs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the
/reasoningcommand across both CLI and gateway (Telegram/Discord/etc).Problem
print()while feedback used_cprint(), causing output to render out-of-order under prompt_toolkit/reasoning showtoggled a flag but reasoning was never captured from models using inline<think>blocks/reasoning showwas session-only, lost on restartChanges
Gateway (
gateway/run.py)/reasoningcommand with full feature parity:/reasoning <level>: sets effort (none/low/medium/high/xhigh), saved to config/reasoning show|hide: toggles reasoning display, saved to config💭 Reasoningblock with the model's thinking before the response (collapses >15 lines)last_reasoningpropagated through_run_agentreturn dict,_show_reasoningloaded from config at startup, added to help textCLI (
cli.py)print()to_cprint()so echo and feedback render through the same path/reasoning show|hidenow saves todisplay.show_reasoningin configAgent Core (
run_agent.py)<think>block extraction: when_extract_reasoning()finds no structured API-level reasoning fields, falls back to extracting<think>...</think>blocks from the response contentTests
test_reasoning_command.py)