From 23527b3bdcbbeeba54ccf387c6adc3156abfca61 Mon Sep 17 00:00:00 2001 From: gongzhiyong Date: Wed, 15 Apr 2026 01:52:45 +0800 Subject: [PATCH] fix(P1): restore historical thread message loading after thread switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The threadJustSwitched suppression was too aggressive — it cleared lastMessagesRef on every thread switch, then relied on historicalMessages which loads async and may still be empty. Historical thread messages would never appear. Simplified fix: thread.switchThread() already clears thread.messages when switching, so thread.messages is always safe to trust directly. Use thread.messages when non-empty, else fall back to historicalMessages. Removes threadJustSwitched / lastMessagesRef / lastThreadIdRef entirely. Co-Authored-By: Claude Sonnet 4.6 --- langgraph/src/main.tsx | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/langgraph/src/main.tsx b/langgraph/src/main.tsx index 7a0d5d7..ff05bb9 100644 --- a/langgraph/src/main.tsx +++ b/langgraph/src/main.tsx @@ -153,26 +153,12 @@ function App() { useEffect(() => { autoResizeTextarea(textareaRef); }, [input]); // ── Active messages ────────────────────────────────────────────────────── - const lastMessagesRef = useRef([]); - const lastThreadIdRef = useRef(null); - // Detect thread switch — when threadId changes, thread.messages still holds stale data - // for the current render cycle (useStream is async). Track this to suppress stale data. - const threadJustSwitched = currentThreadId !== lastThreadIdRef.current; - if (threadJustSwitched) { - lastMessagesRef.current = []; - lastThreadIdRef.current = currentThreadId; - } - // Only trust thread.messages when useStream has caught up to the current threadId - const threadMessagesValid = !threadJustSwitched && thread.messages.length > 0; - if (threadMessagesValid) { - lastMessagesRef.current = thread.messages; - } + // thread.switchThread() is called in useEffect whenever currentThreadId changes, + // which clears thread.messages. So thread.messages is always safe to trust: + // - empty = thread just switched or genuinely empty → fall back to historicalMessages + // - non-empty = useStream has loaded messages for the current thread const activeMessages: Message[] = deduplicateMessages( - threadMessagesValid - ? thread.messages - : lastMessagesRef.current.length > 0 - ? lastMessagesRef.current - : historicalMessages + thread.messages.length > 0 ? thread.messages : historicalMessages ); // Completed / failed tool IDs