Files
local 7a5c22593a feat: enable rich text display for assistant messages
Add markdown-to-HTML rendering for assistant messages using Markdig with
HTML sanitization. Includes cached rendering to avoid lag during streaming,
styled markdown elements (code blocks, tables, lists, blockquotes) within
chat bubbles, and 18 unit tests covering rendering and XSS prevention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 01:29:58 +01:00

3.7 KiB

ADDED Requirements

Requirement: Markdown rendering for assistant messages

The system SHALL convert assistant message content from markdown to formatted HTML using Markdig, displaying headings, bold, italic, code blocks, lists, tables, links, and blockquotes with proper visual formatting.

Scenario: Markdown bold and italic rendered

  • WHEN an assistant message contains **bold** or *italic* text
  • THEN the text is displayed with bold or italic formatting respectively

Scenario: Code block rendered

  • WHEN an assistant message contains a fenced code block (triple backticks)
  • THEN the code is displayed in a monospace font within a visually distinct block

Scenario: Inline code rendered

  • WHEN an assistant message contains inline code (single backticks)
  • THEN the code is displayed in a monospace font with a subtle background

Scenario: List rendered

  • WHEN an assistant message contains a markdown list (ordered or unordered)
  • THEN the list is displayed with proper indentation and bullet/number markers

Scenario: Heading rendered

  • WHEN an assistant message contains markdown headings (# through ######)
  • THEN the headings are displayed with appropriate size and weight
  • WHEN an assistant message contains a markdown link [text](url)
  • THEN the link is displayed as a clickable hyperlink opening in a new tab

Scenario: Table rendered

  • WHEN an assistant message contains a markdown table
  • THEN the table is displayed with borders, header row styling, and proper alignment

Requirement: HTML sanitization

The system SHALL sanitize all HTML output from the markdown renderer to prevent cross-site scripting (XSS) attacks from LLM-generated content.

Scenario: Script tags stripped

  • WHEN assistant message content contains <script> tags
  • THEN the script tags and their content are removed from the rendered output

Scenario: Event handlers stripped

  • WHEN assistant message content contains HTML attributes like onclick or onerror
  • THEN the attributes are removed from the rendered output

Scenario: Safe tags preserved

  • WHEN assistant message content contains allowed structural HTML (p, strong, em, code, pre, ul, ol, li, a, table elements, blockquote, br, h1-h6)
  • THEN the tags are preserved in the rendered output

Requirement: Markdown styling within chat bubbles

The system SHALL style rendered markdown elements to be visually consistent with the MudBlazor chat bubble theme.

Scenario: Code block styled in bubble

  • WHEN a code block is rendered inside an assistant chat bubble
  • THEN it has a distinct background color, padding, border-radius, and does not overflow the bubble width (horizontal scroll if needed)

Scenario: Paragraph spacing in bubble

  • WHEN multiple paragraphs are rendered inside an assistant chat bubble
  • THEN paragraphs have appropriate spacing without excessive gaps

Requirement: Streaming compatibility

The system SHALL re-render markdown as new tokens arrive during streaming without visual glitches.

Scenario: Partial markdown rendered during streaming

  • WHEN tokens are arriving and the current content contains incomplete markdown (e.g., a code block not yet closed)
  • THEN the content is rendered with best-effort formatting and updates smoothly as more tokens complete the markdown structure

Requirement: User messages remain plain text

The system SHALL continue to render user messages as plain text without markdown processing.

Scenario: User message not processed as markdown

  • WHEN a user message contains markdown syntax like **bold**
  • THEN the raw text **bold** is displayed, not formatted bold text