From e7e31eeeac93af8163d41a930353c11043a55577 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 05:35:55 +0000 Subject: [PATCH] Fix thinking blocks rendering below streaming text due to SSE race condition Sort assistant group items so reasoning items always appear before message items, regardless of the order SSE events arrive. This prevents the race condition where the assistant message 'added' event arrives before the reasoning 'added' event, causing thinking blocks to render below the '...' loading dots or streamed text. Co-Authored-By: tony@opensecret.cloud --- frontend/src/components/UnifiedChat.tsx | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/UnifiedChat.tsx b/frontend/src/components/UnifiedChat.tsx index 830958ee..41ed4874 100644 --- a/frontend/src/components/UnifiedChat.tsx +++ b/frontend/src/components/UnifiedChat.tsx @@ -493,6 +493,22 @@ const MessageList = memo( return { callMap: calls, outputMap: outputs }; }, [messages]); + // Sort priority for assistant items: reasoning first, then tool-related, then messages last. + // This prevents a race condition where SSE events arrive out of order (e.g., assistant message + // "added" event before reasoning "added" event), which would cause thinking blocks to render + // below the "..." loading dots or streamed text. + const assistantItemSortOrder = (item: Message): number => { + if (item.type === "reasoning") return 0; + if ( + item.type === "web_search_call" || + item.type === "function_call" || + item.type === "function_call_output" + ) + return 1; + // "message" items (assistant content / streaming text) come last + return 2; + }; + // Group messages into user turns and assistant turns // Assistant turns include: reasoning, tool calls, tool outputs, web search, and assistant messages const groupedMessages = useMemo(() => { @@ -506,7 +522,9 @@ const MessageList = memo( if (currentAssistantItems.length > 0) { groups.push({ type: "assistant", - items: currentAssistantItems, + items: [...currentAssistantItems].sort( + (a, b) => assistantItemSortOrder(a) - assistantItemSortOrder(b) + ), id: `assistant-${currentAssistantItems[0].id}` }); currentAssistantItems = []; @@ -526,7 +544,9 @@ const MessageList = memo( if (currentAssistantItems.length > 0) { groups.push({ type: "assistant", - items: currentAssistantItems, + items: [...currentAssistantItems].sort( + (a, b) => assistantItemSortOrder(a) - assistantItemSortOrder(b) + ), id: `assistant-${currentAssistantItems[0].id}` }); }