Skip to content

feat(autofix): Stream agent output via Markdown streaming variant#115982

Open
priscilawebdev wants to merge 2 commits into
masterfrom
priscila/feat/autofix-streaming-markdown
Open

feat(autofix): Stream agent output via Markdown streaming variant#115982
priscilawebdev wants to merge 2 commits into
masterfrom
priscila/feat/autofix-streaming-markdown

Conversation

@priscilawebdev
Copy link
Copy Markdown
Member

Summary

  • Switch the live agent content in artifactLoadingDetails.tsx to <Markdown variant="streaming" />. Both block.message.content and block.message.thinking_content are 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.
  • Other v3 cards (root cause, solution, previews) continue to render finalized artifacts with the default static variant; they're intentionally not touched.

Stacked on

Builds on top of #115879 (the <Markdown /> primitive adoption). Base the merge on that PR landing first.

Test plan

  • Trigger an autofix run on an issue and watch the loading details panel — confirm streaming content renders progressively and the new animation feels right against Seer's actual token cadence.
  • Compare with the previous (static) behavior to verify no regressions in layout, scrolling, or auto-scroll behavior inside the 200px-max-height container.
  • Sanity check thinking_content rendering (use a run that surfaces thinking blocks).

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.
@priscilawebdev priscilawebdev requested a review from a team as a code owner May 21, 2026 09:31
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label May 21, 2026
@github-actions
Copy link
Copy Markdown
Contributor

📊 Type Coverage Diff

✅ No new type safety issues introduced. Coverage: 93.56%

Comment on lines 48 to 58
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;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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" />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit db548af. Configure here.

@natemoo-re natemoo-re requested a review from a team May 21, 2026 14:40
Base automatically changed from priscila/ref/autofix-use-new-markdown-for-suggested-fix to master May 22, 2026 04:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant