Skip to content

fix(cli): preserve trailing block separators in streamed markdown#3272

Open
nankingjing wants to merge 1 commit into
ultraworkers:mainfrom
nankingjing:fix/stream-markdown-block-sep
Open

fix(cli): preserve trailing block separators in streamed markdown#3272
nankingjing wants to merge 1 commit into
ultraworkers:mainfrom
nankingjing:fix/stream-markdown-block-sep

Conversation

@nankingjing

Copy link
Copy Markdown

Summary

Fixes #3257. During streaming, block-separating newlines were being dropped, causing paragraphs, lists and code blocks to run into the previous line in the terminal (e.g. ...Hello World!1. 打开记事本 and ...:╭─ python).

Root cause

MarkdownStreamState::push renders each ready chunk with TerminalRenderer::markdown_to_ansi, which calls render_markdownoutput.trim_end(). That trim strips the structural trailing \n\n that the parser emits at the end of a paragraph/heading/list/code block. In run_turn the streamed chunk is written straight to the terminal with write!(out, "{rendered}") and no separator of its own (see main.rs), so once the trailing newlines are trimmed the next block is printed flush against the previous one.

The final flush path legitimately wants the tail trimmed, so only the per-chunk push path is wrong.

Fix

  • Extract the untrimmed render into a private render_markdown_raw; render_markdown now trims its result (behavior unchanged for one-shot rendering).
  • Add markdown_to_ansi_stream, a stream-friendly variant that returns the untrimmed output.
  • MarkdownStreamState::push now uses markdown_to_ansi_stream, preserving the block separators between chunks. flush is unchanged and still trims the final tail.

Because pulldown-cmark collapses runs of blank lines and chunk boundaries fall on blank lines, each block still ends with at most one blank line — no extra blank-line accumulation is introduced.

Test

Adds stream_rendering_preserves_block_separators, which asserts the stream variant keeps trailing newlines (while markdown_to_ansi still trims) and that two consecutive streamed chunks do not stick together.

Verification

Verified by reading the source and tracing the parser/stream logic; not compiled or executed in this environment. The change is additive plus a one-line call swap, matches the existing render_markdown/markdown_to_ansi convention, and preserves all existing tests.

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.

bug: Missing newlines before paragraphs and code blocks in streamed Markdown rendering

1 participant