fix(mothership): streaming completion-flash fix + Tavily brand icon#5030
Conversation
… flash The streamed-text reveal latches `mode` and `animated` via `keepStreamingTree` to avoid the streaming→static handoff flash, but `isAnimating` was still wired to `isRevealing`, which flips false the instant the reveal catches up. Streamdown treats `isAnimating: false` as "streaming over" and rebuilds the whole message without the per-word animation spans — that DOM rebuild is a visible flash when a message finishes. Wire `isAnimating` to the same `keepStreamingTree` latch so all three Streamdown props stay constant across completion. Content is stable once revealed, so a permanently-true `isAnimating` has no new tokens to fade and never re-animates.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryLow Risk Overview Tavily is updated to current brand assets: Reviewed by Cursor Bugbot for commit b62f493. Configure here. |
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit cba0e69. Configure here.
Greptile SummaryThis PR bundles two independent changes: a streaming completion-flash fix for the chat surface and an official Tavily brand icon swap. The flash fix correctly extends the
Confidence Score: 5/5Safe to merge — both changes are narrowly scoped, the streaming fix is a one-line prop correction backed by clear documentation of Streamdown's behavior, and the icon swap is mechanical with no logic impact. The streaming fix touches exactly the two Streamdown call sites and does nothing else; the latch logic is already proven by No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Message renders] --> B{isStreaming?}
B -- yes --> C[streamedThisSession.current = true]
C --> D[isRevealing = true
keepStreamingTree = true]
B -- no --> E{streamedContent
== displayContent?}
E -- no --> D
E -- yes --> F{streamedThisSession
.current?}
F -- yes --> G[keepStreamingTree = true
PERMANENT LATCH]
F -- no --> H[keepStreamingTree = false
history message, never streamed]
D --> I[Streamdown
mode=undefined
animated=STREAM_ANIMATION
isAnimating=true]
G --> I
H --> J[Streamdown
mode=static
animated=false
isAnimating=false]
I --> M{After fix: isAnimating
wired to keepStreamingTree}
M -- completion --> N[keepStreamingTree stays true
isAnimating stays true
No DOM rebuild
No flash ✓]
Reviews (3): Last reviewed commit: "feat(tavily): official brand icon and wh..." | Re-trigger Greptile |
Greptile SummaryThis PR fixes a flash that occurred when a streamed assistant message finished by ensuring all three Streamdown props (
Confidence Score: 5/5Safe to merge — a minimal, well-scoped change that aligns a single prop assignment with the two companion props it must stay in sync with. The diff is two one-line substitutions at exactly the two Streamdown call sites in the component. The keepStreamingTree latch was already controlling mode and animated; extending it to isAnimating closes the inconsistency that caused the flash. History messages are unaffected, active streaming is unaffected, and the only changed behavior is at the completion boundary. No other files are touched. No files require special attention. Important Files Changed
Reviews (1): Last reviewed commit: "fix(mothership): keep isAnimating latche..." | Re-trigger Greptile |
Replace the Tavily block icon with the official brand mark and set the block bgColor to white. Ran generate-docs so the docs app icon, the Tavily docs page, and the integrations catalog pick up the new icon/color.
|
Added a second, unrelated change to this branch: Tavily block icon updated to the official brand mark with a white @greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit b62f493. Configure here.
Problem
When a streamed assistant message finishes, the whole message briefly flashes.
Root cause
The streamed-text reveal uses a one-way
keepStreamingTreelatch to avoid the streaming→static handoff flash — it freezes Streamdown'smodeandanimatedprops so they don't change at completion. ButisAnimatingwas left wired toisRevealing, which flipstrue → falsethe instant the paced reveal catches up.Per Streamdown's docs,
isAnimating: falseremoves the animation plugin from the rehype pipeline and re-parses the entire message without the per-word<span>wrappers. That full-message DOM rebuild at completion is the flash.Fix
Wire
isAnimatingto the samekeepStreamingTreelatch (both Streamdown call sites), so all three props stay constant across the completion boundary — the spans are never torn out, so there's no rebuild and no flash.Content is stable once revealed, so a permanently-true
isAnimatinghas no new tokens to fade and never re-animates (Streamdown already keepsisAnimatingtrue across the whole stream without re-fading prior words — otherwise streaming itself would flicker every chunk).Edge cases verified
Only the completion state changes; everything else is byte-identical.
parseSpecialTags/PendingTagIndicatorstill correctly key onisRevealing.Scope
Chat surface only. The file-viewer preview (
preview-panel.tsx) usesisAnimating={isStreaming}and likely wants to settle to static at completion — left as a separate follow-up.Tests
message-contenttests pass (10/10); typecheck + Biome clean.🤖 Generated with Claude Code