Skip to content

fix(tui): prefer raw text over rendered ANSI in render-markdown mode#16464

Closed
0xsir0000 wants to merge 1 commit into
NousResearch:mainfrom
0xsir0000:fix/tui-render-mode-garbled-output
Closed

fix(tui): prefer raw text over rendered ANSI in render-markdown mode#16464
0xsir0000 wants to merge 1 commit into
NousResearch:mainfrom
0xsir0000:fix/tui-render-mode-garbled-output

Conversation

@0xsir0000

Copy link
Copy Markdown
Contributor

What does this PR do?

When display.final_response_markdown: render is set, the TUI gateway populates payload.rendered with Rich-generated ANSI (cursor moves like \x1b[A, line clears \x1b[K, color codes). Ink's <Md> renderer cannot interpret those sequences and displays them as garbled, overlapping output — color layering, misaligned columns, escape artifacts.

The TUI's turnController was prioritizing rendered over the raw markdown text in two places:

  1. recordMessageComplete (ui-tui/src/app/turnController.ts:426) — used payload.rendered ?? payload.text for the final assistant message, so Ink got ANSI instead of raw markdown.
  2. recordMessageDelta (ui-tui/src/app/turnController.ts:519) — this.bufRef = rendered ?? this.bufRef + text. Worse: rendered arrives as an incomplete Rich fragment on every streaming tick, so this replaced the full accumulated buffer with that fragment, dropping prior content.

The CLI and other gateway platforms (Telegram, Discord, …) feed rendered to real terminal emulators that interpret Rich ANSI correctly. Ink does not — it has its own markdown renderer in ui-tui/src/components/markdown.tsx and just needs the raw markdown.

Related Issue

Fixes #16391

Type of Change

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

Changes Made

  • ui-tui/src/app/turnController.tsrecordMessageComplete now prefers payload.text; recordMessageDelta ignores rendered and accumulates text only.
  • ui-tui/src/__tests__/createGatewayEventHandler.test.ts — two new tests covering the complete and delta paths.

How to Test

  1. Set in ~/.hermes/config.yaml:
    display:
      final_response_markdown: render
  2. Run hermes --tui and ask for a multi-paragraph reply (or one with tables/code blocks).
  3. Before this PR: output is garbled with ANSI escape artifacts.
  4. After this PR: markdown renders cleanly via Ink's <Md> component.

Automated:

cd ui-tui
npm test       # 368 passed (incl. 2 new)
npm run type-check
npx eslint src/app/turnController.ts src/__tests__/createGatewayEventHandler.test.ts

Notes

This is the minimal targeted fix (Option A from the issue). Two follow-ups remain possible but are out of scope here:

  • Option B — make rendered/text priority configurable via display.tui_prefer_raw_text.
  • Option C — gateway-side: skip rendered population for TUI sessions entirely (tui_gateway/server.py:2319 and :2264). That would also save the wasted Rich render work for TUI clients.

…ousResearch#16391)

When `final_response_markdown: render` is set, the gateway populates
`payload.rendered` with Rich-generated ANSI (cursor moves, line clears,
color codes). Ink's <Md> renderer cannot interpret those sequences and
displays them as garbled, overlapping text.

`recordMessageComplete` now prefers `payload.text` over `payload.rendered`
so Ink renders raw markdown via its own component. `recordMessageDelta`
ignores the `rendered` fragment entirely during streaming — it was
otherwise replacing the whole accumulated buffer with an incomplete Rich
fragment on every delta, dropping prior content.

Fixes NousResearch#16391
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/tui Terminal UI (ui-tui/ + tui_gateway/) labels Apr 27, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #16392 — same fix (prefer raw text over rendered ANSI in TUI turnController.ts) for #16391. Please coordinate with the existing PR author or close one.

@teknium1

teknium1 commented May 4, 2026

Copy link
Copy Markdown
Contributor

The 'prefer raw text over rendered ANSI' fix was independently applied on current main via #16391. Your analysis was correct; the same root cause was addressed with similar logic. Closing as already-fixed. Thanks @0xsir0000!

@teknium1 teknium1 closed this May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] TUI garbles output when final_response_markdown: render — rendered/text priority inverted

3 participants