feat(autofix): Stream agent output via Markdown streaming variant#115982
feat(autofix): Stream agent output via Markdown streaming variant#115982priscilawebdev wants to merge 2 commits into
Conversation
Replace the local StyledMarkedText wrapper (built on the legacy sentry/utils/marked MarkedText component) with the new <Markdown /> primitive from @sentry/scraps/markdown introduced in #115025. Covers the Solution and Root Cause cards rendered in the issue details sidebar and Seer drawer, plus the streaming loading details. The shared v3/styled.tsx wrapper is no longer needed and is removed.
Use the `variant="streaming"` mode of the `<Markdown />` primitive for the live agent content rendered in v3 cards. This applies to both `block.message.content` and `block.message.thinking_content`, which arrive incrementally as the autofix run progresses. The streaming variant re-keys tokens per chunk and applies an animation tailored to incremental output. Other cards (root cause, solution, previews) continue to render finalized artifacts with the default static variant.
📊 Type Coverage Diff✅ No new type safety issues introduced. Coverage: 93.56% |
| if (block.message.thinking_content) { | ||
| return <Markdown key={index} raw={block.message.thinking_content} />; | ||
| return ( | ||
| <Markdown | ||
| key={index} | ||
| raw={block.message.thinking_content} | ||
| variant="streaming" | ||
| /> | ||
| ); | ||
| } | ||
|
|
||
| return null; |
There was a problem hiding this comment.
Bug: The prevTextLensRef in the <Markdown> component is not reset when content changes, causing the streaming animation to be skipped for new text.
Severity: LOW
Suggested Fix
Reset prevTextLensRef.current to 0 when the content prop of the <Markdown> component changes. This can be achieved by adding an effect that triggers on content change or by adjusting the existing useLayoutEffect's dependency array to correctly handle the content update and reset the stored length.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: static/app/components/events/autofix/v3/artifactLoadingDetails.tsx#L40-L58
Potential issue: When a content block transitions from displaying `thinking_content` to
the final `content`, the `prevTextLensRef` within the `<Markdown>` component retains the
length of the previous text. This stale length is then used in a `useLayoutEffect` to
set an incorrect `data-skip` attribute for the new content. As a result, the animation
logic skips rendering the new characters, causing the text to appear instantly instead
of streaming in as intended.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit db548af. Configure here.
| if (block.message.content && block.message.content !== 'Thinking...') { | ||
| return <Markdown key={index} raw={block.message.content} />; | ||
| return ( | ||
| <Markdown key={index} raw={block.message.content} variant="streaming" /> |
There was a problem hiding this comment.
Stale animation state when switching thinking to content
Low Severity
When a block transitions from rendering thinking_content to content (e.g., content goes from "Thinking..." to a real value), both branches use the same key={index}. React reuses the Markdown instance, so the internal prevTextLensRef retains stale token text lengths from thinking_content. The streaming variant's useLayoutEffect then writes incorrect data-skip values onto the new content's DOM children, causing the decode animation to wrongly skip characters at the start of the actual content. Using a key that distinguishes the two branches (e.g., incorporating "content" vs "thinking") would give each a fresh Markdown instance with clean animation state.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit db548af. Configure here.


Summary
artifactLoadingDetails.tsxto<Markdown variant="streaming" />. Bothblock.message.contentandblock.message.thinking_contentare produced incrementally during an autofix run, so the streaming variant — which re-keys tokens per chunk and applies an animation tailored to incremental output — is the right fit here.Stacked on
Builds on top of #115879 (the
<Markdown />primitive adoption). Base the merge on that PR landing first.Test plan