From 12ae592746f2a1b0fea40c97ffe47b550f2ce838 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 1 Feb 2026 11:04:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=B6=88=E5=A4=B1=E5=92=8C=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E9=87=8D=E5=A4=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 移除 wrappedSendMessage,避免用户消息 ID 冲突导致重复 2. 添加 initialMessagesRef 保存初始消息,防止历史消息丢失 3. 改进 mergedMessages 逻辑:合并 初始消息 + useChat消息 + appendedMessages 4. 使用 Map 进行去重,按创建时间排序 Co-authored-by: Cursor --- components/chat.tsx | 82 ++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/components/chat.tsx b/components/chat.tsx index 0db0648f5..454f995e6 100644 --- a/components/chat.tsx +++ b/components/chat.tsx @@ -398,26 +398,15 @@ export function Chat({ }, }); - // 🆕 包装 sendMessage,在发送时保存用户消息到 appendedMessages - // 这样即使 useChat 重置消息状态,用户消息也会保留在 mergedMessages 中 - const wrappedSendMessage = useCallback((message: Parameters[0]) => { - // 保存用户消息到 appendedMessages - const textPart = message?.parts?.find((p: any) => p.type === "text") as any; - const userMessage: ChatMessage = { - id: generateUUID(), - role: "user", - content: textPart?.text || "", - createdAt: new Date(), - parts: message?.parts || [], - attachments: (message as any)?.attachments || [], - } as ChatMessage; - - console.log("[Chat] Saving user message to appendedMessages:", userMessage.id); - setAppendedMessages((prev) => [...prev, userMessage]); - - // 调用原始的 sendMessage - return sendMessage(message); - }, [sendMessage]); + // 🆕 保存 initialMessages 的引用,防止历史消息丢失 + // 当 useChat 内部状态重置时,我们仍然有初始消息 + const initialMessagesRef = useRef(initialMessages); + useEffect(() => { + // 只在初始化时设置,不在后续更新 + if (initialMessagesRef.current.length === 0 && initialMessages.length > 0) { + initialMessagesRef.current = initialMessages; + } + }, [initialMessages]); // 调试:监控聊天状态变化 & 持久化生成状态 // 使用 ref 来访问最新的 modelsData,避免依赖数组问题 @@ -456,7 +445,7 @@ export function Chat({ useEffect(() => { if (query && !hasAppendedQuery) { - wrappedSendMessage({ + sendMessage({ role: "user" as const, parts: [{ type: "text", text: query }], }); @@ -1107,21 +1096,38 @@ export function Chat({ setMessages, }); - // 🆕 合并 useChat 的 messages 和 appendedMessages - // appendedMessages 包含通过 data-appendMessage 添加的消息 + // 🆕 合并消息:初始消息 + useChat 消息 + appendedMessages + // 确保历史消息不会因为 useChat 内部状态重置而丢失 const mergedMessages = useMemo(() => { - if (appendedMessages.length === 0) { - return messages; - } - // 过滤掉已存在的消息,然后合并 - const newMessages = appendedMessages.filter( - (appended) => !messages.some((m) => m.id === appended.id) - ); - if (newMessages.length > 0) { - console.log("[Chat] Rendering with merged messages:", messages.length, "+", newMessages.length); - return [...messages, ...newMessages]; - } - return messages; + // 使用 Map 进行去重,以 ID 为键 + const messageMap = new Map(); + + // 1. 首先添加初始消息(历史记录) + initialMessagesRef.current.forEach(m => { + messageMap.set(m.id, m); + }); + + // 2. 然后添加 useChat 的当前消息(会覆盖相同 ID 的旧消息) + messages.forEach(m => { + messageMap.set(m.id, m); + }); + + // 3. 最后添加 appendedMessages(data-appendMessage 的消息) + appendedMessages.forEach(m => { + if (!messageMap.has(m.id)) { + messageMap.set(m.id, m); + } + }); + + // 按创建时间排序 + const result = Array.from(messageMap.values()).sort((a, b) => { + const timeA = (a as any).createdAt ? new Date((a as any).createdAt).getTime() : 0; + const timeB = (b as any).createdAt ? new Date((b as any).createdAt).getTime() : 0; + return timeA - timeB; + }); + + console.log("[Chat] Merged messages:", result.length, "(initial:", initialMessagesRef.current.length, ", current:", messages.length, ", appended:", appendedMessages.length, ")"); + return result; }, [messages, appendedMessages]); return ( @@ -1139,7 +1145,7 @@ export function Chat({ isReadonly={isReadonly} messages={mergedMessages} regenerate={regenerate} - sendMessage={wrappedSendMessage} + sendMessage={sendMessage} selectedModelId={currentModelId} setMessages={setMessages} status={status} @@ -1169,7 +1175,7 @@ export function Chat({ onModelChange={setCurrentModelId} selectedModelId={currentModelId} selectedVisibilityType={visibilityType} - sendMessage={wrappedSendMessage} + sendMessage={sendMessage} setAttachments={setAttachments} setInput={setInput} setMessages={setMessages} @@ -1202,7 +1208,7 @@ export function Chat({ regenerate={regenerate} selectedModelId={currentModelId} selectedVisibilityType={visibilityType} - sendMessage={wrappedSendMessage} + sendMessage={sendMessage} setAttachments={setAttachments} setInput={setInput} setMessages={setMessages}