Skip to content

bug(tui): 流式输出期间显示原始 Markdown 源码,turn 结束后才一次性渲染 #220

Description

@minorcell

现象

流式输出时,TUI 先展示原始 Markdown 源码(如 **加粗**# 标题、未闭合的 ``` 代码块),等整个 turn 的文本全部输出结束后,才一次性切换成渲染好的 Markdown。流式过程中用户看到的不是最终排版,体验割裂。

Pre-check

  • 我搜索了 open/closed issues,没有找到已有的报告。
  • 我可以在本仓库最新代码上复现。

Version

0.8.62(分支 refactor/ai-sdk)

Environment

macOS 26.5.2 · Node 22.14.0 · pnpm 10.6.5

Reproduction Steps

  1. 运行 memo,让模型输出包含 Markdown 格式(标题、列表、代码块等)的回答;
  2. 观察流式输出过程:文本以原始 Markdown 源码形式逐字出现;
  3. 等 turn 结束后观察:整段文本突然切换为 Markdown 渲染后的样式。

Expected Behavior

流式输出过程中就按 Markdown 渲染(增量样式更新),与最终展示一致。

Actual Behavior

流式阶段展示原始 Markdown 源码,turn 结束后才一次性渲染 Markdown。

根因定位

TUI 存在两条不一致的渲染路径:

  • 流式阶段assistant_chunk 累积到 step.assistantTextpackages/tui/src/features/timeline/Cells.tsx:180-184<Text>{step.assistantText}</Text> 直接输出原始文本,未经过 Markdown 解析;
  • 完成阶段turn_final 设置 turn.finalText 后,Cells.tsx:246-250 才使用 <MarkdownRenderer content={turn.finalText} /> 渲染。

流式文本由 chatTimeline.tsassistant_chunk reducer 追加到 step.assistantTextTurnCell 通过 inProgress!turn.finalText)判断走哪条路径(Cells.tsx:222)。

建议修复方向

  • 流式阶段复用 MarkdownRenderer 渲染 step.assistantTextparseMarkdownContent 基于 marked.lexer,对未闭合代码块/未闭合强调符有兜底,可接受临时不完整状态);
  • 注意避免对已完成 turn 做重复渲染/闪烁:只对流式中的 step 使用增量渲染路径;
  • 补充流式阶段(未闭合代码块、未闭合 ** 等)的渲染测试。

Logs / Screenshots

(如有截图可补充)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:tuiTerminal UI and interaction layerbugSomething isn't workingneeds-triageIssue needs initial triage

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions