From cba0e6974193ef2dbf6449ae70a92dff95eeb743 Mon Sep 17 00:00:00 2001 From: waleed Date: Sat, 13 Jun 2026 11:16:57 -0700 Subject: [PATCH 1/2] fix(mothership): keep isAnimating latched so completed messages don't flash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../components/chat-content/chat-content.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/chat-content.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/chat-content.tsx index 75a323d04b1..39acbce7b6c 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/chat-content.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/chat-content/chat-content.tsx @@ -294,6 +294,17 @@ function ChatContentInner({ const streamedContent = useSmoothText(displayContent, isStreaming) const isRevealing = isStreaming || streamedContent.length < displayContent.length + /** + * One-way latch: once a message has streamed in this mount, keep rendering it + * through Streamdown's streaming/animation pipeline for the rest of its life. + * Drives `mode`, `animated`, AND `isAnimating` together — all three must stay + * constant across the completion boundary. Streamdown removes the per-word + * `` wrappers (and re-parses the whole message) the instant `isAnimating` + * goes false, so wiring `isAnimating` to `isRevealing` (which flips at + * completion) reintroduces the streaming→static flash this latch exists to + * prevent. Content is stable once revealed, so a permanently-true + * `isAnimating` never re-fades anything. + */ const streamedThisSession = useRef(false) if (isStreaming) streamedThisSession.current = true const keepStreamingTree = isRevealing || streamedThisSession.current @@ -372,7 +383,7 @@ function ChatContentInner({ {group.markdown} @@ -398,7 +409,7 @@ function ChatContentInner({ {streamedContent} From b62f4931e00e761b418421e0b3d6e33249be0a4c Mon Sep 17 00:00:00 2001 From: waleed Date: Sat, 13 Jun 2026 11:23:52 -0700 Subject: [PATCH 2/2] feat(tavily): official brand icon and white block background 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. --- apps/docs/components/icons.tsx | 31 +++++++++---------- .../content/docs/en/integrations/tavily.mdx | 2 +- apps/sim/blocks/blocks/tavily.ts | 2 +- apps/sim/components/icons.tsx | 31 +++++++++---------- apps/sim/lib/integrations/integrations.json | 4 +-- 5 files changed, 32 insertions(+), 38 deletions(-) diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index 162de3ad5f9..36c53d53417 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -874,34 +874,31 @@ export function TailscaleIcon(props: SVGProps) { export function TavilyIcon(props: SVGProps) { return ( - - + + Tavily ) diff --git a/apps/docs/content/docs/en/integrations/tavily.mdx b/apps/docs/content/docs/en/integrations/tavily.mdx index 8665df2415f..906a755d542 100644 --- a/apps/docs/content/docs/en/integrations/tavily.mdx +++ b/apps/docs/content/docs/en/integrations/tavily.mdx @@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" {/* MANUAL-CONTENT-START:intro */} diff --git a/apps/sim/blocks/blocks/tavily.ts b/apps/sim/blocks/blocks/tavily.ts index 40ef332a619..be7a873ac72 100644 --- a/apps/sim/blocks/blocks/tavily.ts +++ b/apps/sim/blocks/blocks/tavily.ts @@ -13,7 +13,7 @@ export const TavilyBlock: BlockConfig = { category: 'tools', integrationType: IntegrationType.Search, docsLink: 'https://docs.sim.ai/integrations/tavily', - bgColor: '#0066FF', + bgColor: '#FFFFFF', icon: TavilyIcon, subBlocks: [ { diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index 162de3ad5f9..36c53d53417 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -874,34 +874,31 @@ export function TailscaleIcon(props: SVGProps) { export function TavilyIcon(props: SVGProps) { return ( - - + + Tavily ) diff --git a/apps/sim/lib/integrations/integrations.json b/apps/sim/lib/integrations/integrations.json index 853a8728a02..c9e426a8aaf 100644 --- a/apps/sim/lib/integrations/integrations.json +++ b/apps/sim/lib/integrations/integrations.json @@ -1,5 +1,5 @@ { - "updatedAt": "2026-06-12", + "updatedAt": "2026-06-13", "integrations": [ { "type": "onepassword", @@ -15051,7 +15051,7 @@ "name": "Tavily", "description": "Search and extract information", "longDescription": "Integrate Tavily into the workflow. Can search the web and extract content from specific URLs. Requires API Key.", - "bgColor": "#0066FF", + "bgColor": "#FFFFFF", "iconName": "TavilyIcon", "docsUrl": "https://docs.sim.ai/integrations/tavily", "operations": [