Skip to content

feat: syntax highlighting for tool outputs and LLM responses - #2

Closed
KUSH42 wants to merge 2 commits into
feat/rich-diff-rendererfrom
feat/tool-output-highlighting
Closed

feat: syntax highlighting for tool outputs and LLM responses#2
KUSH42 wants to merge 2 commits into
feat/rich-diff-rendererfrom
feat/tool-output-highlighting

Conversation

@KUSH42

@KUSH42 KUSH42 commented Apr 1, 2026

Copy link
Copy Markdown
Owner

feat: syntax highlighting for tool outputs and LLM responses

⚠️ Stacked on feat/rich-diff-renderer — merge that first. All commits above the tip of that branch are new here.

Wires the SyntaxHighlighter / LanguageDetector from the diff-renderer PR into tool result display and LLM response rendering.

Changes

execute_code preview

  • Highlighted Python block printed after successful execution
  • Success-gated via _result_succeeded — no highlight shown after a failed run
  • Cute-msg drops the inline code snippet when highlight is active to avoid duplication

read_file preview

  • ┊ 📄 filename.py header + syntax-highlighted content
  • Language detected from file extension only (no content guessing)

terminal preview

  • Verb-based language detection from the command
  • _FILE_EXEC_COMMANDS blocklist (node, python3, bash, ruby, …) — runtime stdout is never mistaken for source code

LLM response rendering

  • format_response() for complete responses: replaces fenced code blocks with ANSI-highlighted versions
  • StreamingCodeBlockHighlighter state 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

  • Verbosity gate: all previews early-return when tool_progress_mode == "off"
  • Config key code_highlight (display.code_highlight in config.yaml) + /code-highlight toggle
  • set_code_highlight_active() in display.py keeps it decoupled from CLI state

Bug fixes

  • Fence delimiters in Panel outputformat_response preserved ``` 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-highlight toggleapply_block_line / apply_inline_markdown in _emit_stream_text and _flush_stream were guarded by _display._code_highlight_active, the same flag that controls tool-output syntax highlighting. Toggling /code-highlight off 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 in apply_inline_markdown that 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).

KUSH42 added 2 commits April 1, 2026 23:38
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
KUSH42 force-pushed the feat/tool-output-highlighting branch 2 times, most recently from d3045a2 to 47ce516 Compare April 1, 2026 21:49
@KUSH42

KUSH42 commented Apr 1, 2026

Copy link
Copy Markdown
Owner Author

Superseded by NousResearch#4471

@KUSH42 KUSH42 closed this Apr 1, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant