From 321c565ec490573550cfbc4bef2a66a20df28778 Mon Sep 17 00:00:00 2001 From: Xubin Ren Date: Wed, 13 May 2026 08:12:44 +0000 Subject: [PATCH] fix(webui): normalize thinking trace row box model Thinking and Used tools are both auxiliary rows, but Thinking still carried an internal mb-2 even when it was standalone. That made collapsed Thinking rows visually taller than tool trace rows despite the shared thread spacing. Only add the extra bottom margin when a Thinking bubble has answer content below it in the same assistant message. Standalone Thinking rows now share the same outer box model as Used tools. Tests lock both standalone and answer-backed cases. Co-authored-by: Cursor --- webui/src/components/MessageBubble.tsx | 12 +++++++++--- webui/src/tests/message-bubble.test.tsx | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/webui/src/components/MessageBubble.tsx b/webui/src/components/MessageBubble.tsx index abf85f663..bd1d8c93b 100644 --- a/webui/src/components/MessageBubble.tsx +++ b/webui/src/components/MessageBubble.tsx @@ -92,7 +92,7 @@ export function MessageBubble({ message }: MessageBubbleProps) { return (
{hasReasoning ? ( - + ) : null} {empty && message.isStreaming && !hasReasoning ? ( @@ -443,6 +443,7 @@ function TraceGroup({ message, animClass }: TraceGroupProps) { interface ReasoningBubbleProps { text: string; streaming: boolean; + hasBodyBelow: boolean; } /** @@ -456,7 +457,7 @@ interface ReasoningBubbleProps { * the user can re-expand to inspect the chain of thought. The local * toggle persists once the user interacts. */ -function ReasoningBubble({ text, streaming }: ReasoningBubbleProps) { +function ReasoningBubble({ text, streaming, hasBodyBelow }: ReasoningBubbleProps) { const { t } = useTranslation(); const [userToggled, setUserToggled] = useState(false); const [openLocal, setOpenLocal] = useState(true); @@ -466,7 +467,12 @@ function ReasoningBubble({ text, streaming }: ReasoningBubbleProps) { setOpenLocal((v) => (userToggled ? !v : !open)); }; return ( -
+