Repository navigation
feat(local): render the thinking trace as markdown - #2049
Conversation
A thinking model writes its trace in markdown, and the box showed it as literal ##, ** and fences under an answer that renders properly. The trace now goes through Streamdown with the shared code and math plugins, the same link safety as the answer, and the answer's harden limits: http, https and mailto links only, no images, no data images. Streamdown's own prop is a rehype plugin list, so the limits are its default raw and sanitize passes plus its harden pass re-run with those options, the way the assistant-ui primitive builds them for the answer. Default mode, since the trace streams. The box keeps its fold, fade, follow-the-newest-line scrolling, region role, name and tabIndex; whitespace-pre-wrap goes, markdown handles it. The scroll tests find the viewport by its role now that the text sits inside elements. The chat doc's gap line is cut down to the thinking switch (MODSetter#1950). Fixes MODSetter#1949
|
@ybai08 is attempting to deploy a commit to the Rohan Verma's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What
The thinking trace in
reply-thinking.tsxrenders as markdown: headings, lists, emphasis and fenced code inside the existing box. It usesStreamdownwith the sharedstreamdownPlugins(code and math),linkSafetyon, and the answer's restrictions frommessage.tsx:http,httpsandmailtolinks only, no images, no data images. Default mode, since a trace streams in.whitespace-pre-wrapis dropped from the viewport class; markdown handles line breaks.One thing worth knowing: the plain
Streamdowncomponent has nosecurityprop; that belongs to the assistant-ui primitive, which turns it into a rehype plugin list. So the trace passesrehypePluginsbuilt from Streamdown's exporteddefaultRehypePlugins: itsrawandsanitizepasses as they are, and itshardenpass re-run with the answer's options. Same passes, same order, stricter limits.The box keeps everything it had: the fold, the fade, following the newest line,
role="region", its accessible name andtabIndex={0}. The trace still rides inmetadata.custom, so Copy still takes the answer alone.docs/architecture/chat.md: the Known gaps line is cut down to the thinking switch, since #1950 has not landed, and the trace paragraph says it renders as markdown with the answer's restrictions.Why
The answer directly below the trace is rendered, so a trace full of literal
##and**read as broken rather than plain. Now the same model's output gets the same treatment on both sides of the fold.Fixes #1949
How to test
Two new tests in
reply-thinking.test.tsx, written first: a trace with a heading, a list, emphasis and a code fence renders as elements with no literal syntax left, and ajavascript:link, a data-URI image and anhttpslink come out as blocked text, blocked image and the one link. The two scroll-following tests now find the viewport by its region role, since the text no longer sits directly in it. Locally: chat feature 27/27, whole frontend suite green,eslint,prettier --check,pnpm typecheckandcheck_docs.pyclean.High-level PR Summary
This PR enhances the thinking trace display in the chat interface by rendering it as markdown instead of plain text. The trace now supports headings, lists, emphasis, and code blocks using the
Streamdowncomponent with the same security restrictions as the answer (allowing onlyhttp,https, andmailtolinks, no images). The implementation reuses the sharedstreamdownPluginsand carefully reconstructs the rehype plugin chain to apply the answer's stricter link and image policies while maintaining all existing functionality like scroll-following, folding, and accessibility features.⏱️ Estimated Review Time: 5-15 minutes
💡 Review Order Suggestion
surfsense_local/frontend/src/features/chat/reply-thinking.test.tsxsurfsense_local/frontend/src/features/chat/reply-thinking.tsxdocs/architecture/chat.md