From 40210917c29f30bf4de1c4d06e051a5efe5ddbd4 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Thu, 21 May 2026 13:00:37 +0300 Subject: [PATCH] fix(ui): keep completed reasoning collapsed --- .../src/components/chat/message/parts/ReasoningPart.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/components/chat/message/parts/ReasoningPart.tsx b/packages/ui/src/components/chat/message/parts/ReasoningPart.tsx index e36505cd..59797252 100644 --- a/packages/ui/src/components/chat/message/parts/ReasoningPart.tsx +++ b/packages/ui/src/components/chat/message/parts/ReasoningPart.tsx @@ -89,12 +89,14 @@ export const ReasoningTimelineBlock: React.FC = ({ variant, onContentChange, blockId, + time, isStreaming = false, actions, defaultExpanded, }) => { const { t } = useI18n(); - const [isExpanded, setIsExpanded] = React.useState(defaultExpanded ?? isStreaming); + const hasEnded = typeof time?.end === 'number'; + const [isExpanded, setIsExpanded] = React.useState(hasEnded ? false : (defaultExpanded ?? isStreaming)); const contentId = React.useId(); const scrollRef = React.useRef(null); const contentRef = React.useRef(null); @@ -126,10 +128,10 @@ export const ReasoningTimelineBlock: React.FC = ({ prevIsStreamingRef.current = isStreaming; // Auto-collapse only when streaming ends (true → false). // Do not fire on mount so that defaultExpanded is respected. - if (wasStreaming && !isStreaming) { + if (hasEnded || (wasStreaming && !isStreaming)) { setIsExpanded(false); } - }, [isStreaming]); + }, [hasEnded, isStreaming]); React.useEffect(() => { if (text.trim().length === 0) {