feat: syntax highlighting for tool outputs and LLM responses - #2
Closed
KUSH42 wants to merge 2 commits into
Closed
Conversation
Wires the SyntaxHighlighter/LanguageDetector from rich_output.py into tool result display and LLM response rendering. execute_code preview: - Highlighted Python block printed after successful execution - Gated on _result_succeeded — nothing shown after a failed run - Cute-msg drops the inline snippet when highlight is active (no duplication) read_file preview: - ┊ 📄 filename.py header + syntax-highlighted content - Language from extension only; unknown types skipped silently terminal preview: - Verb-based language detection from the command - _FILE_EXEC_COMMANDS blocklist (node, python3, bash, …) prevents runtime stdout from being mistaken for source code LLM response rendering: - format_response() highlights fenced code blocks in complete responses - StreamingCodeBlockHighlighter state machine for streaming: buffers fenced blocks, flushes highlighted on closing fence, plain text passes through immediately with response text colour preserved Plumbing: - Verbosity gate: all previews suppressed when tool_progress_mode == "off" - display.code_highlight config key + /code-highlight toggle - set_code_highlight_active() keeps display.py decoupled from CLI state - Module-level _rich_detector singleton (no per-call instantiation) Tests: 135 passing (tests/test_display.py + tests/test_rich_output.py)
format_response wrapped highlighted code in ``` delimiters under the theory that "the Panel still looks like a code block". In practice the ANSI-highlighted block reads cleanly without them, and keeping the fences caused raw backtick lines to appear in the rendered response.
KUSH42
force-pushed
the
feat/tool-output-highlighting
branch
2 times, most recently
from
April 1, 2026 21:49
d3045a2 to
47ce516
Compare
Owner
Author
|
Superseded by NousResearch#4471 |
KUSH42
added a commit
that referenced
this pull request
Apr 11, 2026
…flash - GAP-17: restore input focus after every agent turn (call_after_refresh) - GAP-7: flash hint bar with "Unknown command: /X" when slash lookup is empty - GAP-4: ctrl+p inserts @ and opens path/file completion overlay - GAP-5: ctrl+r aliased to ctrl+f for history search (muscle-memory parity) - #1: dim input chevron (--busy class) while agent_running instead of hiding - #2: brief $success background flash on ToolHeader when streaming completes 460 TUI tests passing.
KUSH42
pushed a commit
that referenced
this pull request
May 1, 2026
* ci(nix): auto-fix stale npm hashes on push to main When a PR merges to main with updated package-lock.json or package.json in ui-tui/ or web/, the new auto-fix-main job detects stale npmDepsHash values and pushes a fix commit directly to main. This eliminates the recurring manual hash-bump PRs (NousResearch#15420, NousResearch#15314, NousResearch#15272, NousResearch#15244) by reusing the existing fix-lockfiles --apply pipeline. The fix commit only touches nix/*.nix files, which are outside the push path filter (package-lock.json / package.json), so it cannot re-trigger itself. Closes NousResearch#15314 * fix(ci): use GitHub App token for auto-fix-main push GITHUB_TOKEN commits are invisible to workflow triggers (GitHub's infinite-loop prevention). The auto-fix-main job pushes directly to main, so the fix commit never triggered downstream nix.yml verification. Mint a short-lived token via the repo's GitHub App (daimon-nous, APP_ID + APP_PRIVATE_KEY secrets) so the push is treated as a real event and nix.yml fires to verify the corrected hashes. Tested via workflow_dispatch dry-run: app token minted successfully, checkout with app token succeeded, fix job correctly gated. Resolves review feedback from Bugbot (r3144569551). * ci(nix): rename lockfile check job for required status check Rename 'check' → 'nix-lockfile-check' so the status check name is unambiguous when added as a required check on main. * fix(ci): harden auto-fix-main against races, loops, and silent failures Address adversarial review findings: 1. Race condition (#1): Job-level concurrency with cancel-in-progress collapses back-to-back pushes; ref: main checkout always gets latest branch state; explicit push target (origin HEAD:main). 2. Loop prevention (#2): File-whitelist check before commit aborts if any file outside nix/{tui,web}.nix was modified, preventing accidental self-triggering. 3. Silent infra failures (#8): nix-lockfile-check now fails explicitly when fix-lockfiles exits without reporting stale status (catches nix setup failures, network errors, script bugs that bypass continue-on-error). 4. Commit traceability (NousResearch#11): Auto-fix commits include source SHA and workflow run URL in the commit body. 5. Explicit push target (NousResearch#12): git push origin HEAD:main instead of bare git push. --------- Co-authored-by: alt-glitch <alt-glitch@users.noreply.github.com>
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.
feat: syntax highlighting for tool outputs and LLM responses
Wires the
SyntaxHighlighter/LanguageDetectorfrom the diff-renderer PR into tool result display and LLM response rendering.Changes
execute_codepreview_result_succeeded— no highlight shown after a failed runread_filepreview┊ 📄 filename.pyheader + syntax-highlighted contentterminalpreview_FILE_EXEC_COMMANDSblocklist (node,python3,bash,ruby, …) — runtime stdout is never mistaken for source codeLLM response rendering
format_response()for complete responses: replaces fenced code blocks with ANSI-highlighted versionsStreamingCodeBlockHighlighterstate machine for streaming: buffers lines inside fences, flushes the highlighted block on the closing fence, passes plain text through immediately. Language hint used when present, content-detection fallback otherwise.Plumbing
tool_progress_mode == "off"code_highlight(display.code_highlightin config.yaml) +/code-highlighttoggleset_code_highlight_active()indisplay.pykeeps it decoupled from CLI stateBug fixes
Fence delimiters in Panel output —
format_responsepreserved```fence markers around highlighted code blocks ("so the Panel still looks like a code block"). In practice the ANSI-highlighted block reads cleanly without them, and keeping the fences caused raw backtick lines to appear in the rendered response view. Removed; the regex replacement now returns the highlighted code directly.LLM response markdown gated on
/code-highlighttoggle —apply_block_line/apply_inline_markdownin_emit_stream_textand_flush_streamwere guarded by_display._code_highlight_active, the same flag that controls tool-output syntax highlighting. Toggling/code-highlightoff silently suppressed bold, italic, headings, blockquotes and all inline markdown in LLM responses. Fixed by removing the inner guard —_RICH_RESPONSE(import guard) is the correct gate for response rendering.CommonMark backslash escapes visible in output — LLM responses containing escaped punctuation (e.g.
\]in task-list syntax[ \]) showed the raw backslash. Added a step-7 pass inapply_inline_markdownthat strips all CommonMark backslash escapes (\]→],\*→*, etc.) after code spans are restored, so protected spans are never affected.Tests
135 passing (
tests/test_display.py+tests/test_rich_output.py).