fix: 修复历史消息消失和用户消息重复问题
1. 移除 wrappedSendMessage,避免用户消息 ID 冲突导致重复 2. 添加 initialMessagesRef 保存初始消息,防止历史消息丢失 3. 改进 mergedMessages 逻辑:合并 初始消息 + useChat消息 + appendedMessages 4. 使用 Map 进行去重,按创建时间排序 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
05236a7b86
commit
12ae592746
@ -398,26 +398,15 @@ export function Chat({
|
||||
},
|
||||
});
|
||||
|
||||
// 🆕 包装 sendMessage,在发送时保存用户消息到 appendedMessages
|
||||
// 这样即使 useChat 重置消息状态,用户消息也会保留在 mergedMessages 中
|
||||
const wrappedSendMessage = useCallback((message: Parameters<typeof sendMessage>[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<ChatMessage[]>(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<string, ChatMessage>();
|
||||
|
||||
// 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}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user