From a779555f3f73c9f3a09424959614ee2812b5c763 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 1 Feb 2026 11:24:05 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=20chat=20=E5=92=8C=20?= =?UTF-8?q?dynamic-provider=20=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- components/chat.tsx | 47 +++++++++++++++++++++++++++----------- lib/ai/dynamic-provider.ts | 20 ++++------------ 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/components/chat.tsx b/components/chat.tsx index 0231ece37..454f995e6 100644 --- a/components/chat.tsx +++ b/components/chat.tsx @@ -356,11 +356,33 @@ export function Chat({ } } }, - onFinish: () => { + onFinish: async () => { mutate(unstable_serialize(getChatHistoryPaginationKey)); + // 🆕 生成完成,清除持久化状态 + completeGeneration(); console.log("[Chat] onFinish called"); - // 注意:不在这里清除 completeGeneration(),因为图片生成可能还在进行中 - // completeGeneration() 会在收到图片消息时调用 + + // 🆕 从数据库重新加载消息,确保 data-appendMessage 的消息正确显示 + // 这是根治方案 B:后端已保存消息到数据库,前端从数据库重新加载 + try { + // 延迟一小段时间确保数据库写入完成 + await new Promise(resolve => setTimeout(resolve, 500)); + + // 获取最新消息 + const response = await fetch(`/api/messages?chatId=${id}`); + if (response.ok) { + const data = await response.json(); + if (data.messages && Array.isArray(data.messages)) { + console.log("[Chat] Reloading messages from database:", data.messages.length); + // 更新消息状态 + setMessages(data.messages); + // 清空 appendedMessages,因为已经从数据库加载了完整消息 + setAppendedMessages([]); + } + } + } catch (error) { + console.error("[Chat] Failed to reload messages:", error); + } }, onError: (error) => { if (error instanceof ChatSDKError) { @@ -378,8 +400,13 @@ export function Chat({ // 🆕 保存 initialMessages 的引用,防止历史消息丢失 // 当 useChat 内部状态重置时,我们仍然有初始消息 - // 注意:这个 ref 永远保持初始加载的消息,不会更新 const initialMessagesRef = useRef(initialMessages); + useEffect(() => { + // 只在初始化时设置,不在后续更新 + if (initialMessagesRef.current.length === 0 && initialMessages.length > 0) { + initialMessagesRef.current = initialMessages; + } + }, [initialMessages]); // 调试:监控聊天状态变化 & 持久化生成状态 // 使用 ref 来访问最新的 modelsData,避免依赖数组问题 @@ -1075,14 +1102,8 @@ export function Chat({ // 使用 Map 进行去重,以 ID 为键 const messageMap = new Map(); - // 🆕 确保 initialMessagesRef 有值 - // 如果 ref 是空的但 initialMessages prop 有值,使用 prop - const baseMessages = initialMessagesRef.current.length > 0 - ? initialMessagesRef.current - : initialMessages; - // 1. 首先添加初始消息(历史记录) - baseMessages.forEach(m => { + initialMessagesRef.current.forEach(m => { messageMap.set(m.id, m); }); @@ -1105,9 +1126,9 @@ export function Chat({ return timeA - timeB; }); - console.log("[Chat] Merged messages:", result.length, "(base:", baseMessages.length, ", current:", messages.length, ", appended:", appendedMessages.length, ")"); + console.log("[Chat] Merged messages:", result.length, "(initial:", initialMessagesRef.current.length, ", current:", messages.length, ", appended:", appendedMessages.length, ")"); return result; - }, [messages, appendedMessages, initialMessages]); + }, [messages, appendedMessages]); return ( <> diff --git a/lib/ai/dynamic-provider.ts b/lib/ai/dynamic-provider.ts index 74e04ab05..b39a0cad0 100644 --- a/lib/ai/dynamic-provider.ts +++ b/lib/ai/dynamic-provider.ts @@ -6,12 +6,11 @@ import { wrapLanguageModel, type LanguageModel, } from "ai"; -// 使用动态导入避免循环依赖问题 -// import { -// getEnabledAiModelsWithProvider, -// getAiProviderById, -// getAiModelById, -// } from "@/lib/db/queries"; +import { + getEnabledAiModelsWithProvider, + getAiProviderById, + getAiModelById, +} from "@/lib/db/queries"; import type { AiProvider } from "@/lib/db/schema"; import { createLocalQwen } from "./providers/local-qwen"; import { createGeminiImage } from "./providers/gemini-image"; @@ -144,9 +143,6 @@ export async function getDynamicModel( modelId: string ): Promise { try { - // 使用动态导入避免循环依赖 - const { getAiModelById, getAiProviderById } = await import("@/lib/db/queries"); - const model = await getAiModelById({ id: modelId }); if (!model || !model.isEnabled) { console.warn(`[getDynamicModel] Model ${modelId} not found or disabled`); @@ -242,9 +238,6 @@ export async function getLanguageModelById( // 获取所有可用的模型列表(用于前端展示) export async function getAvailableModels() { try { - // 使用动态导入避免循环依赖 - const { getEnabledAiModelsWithProvider } = await import("@/lib/db/queries"); - const modelsWithProvider = await getEnabledAiModelsWithProvider(); return modelsWithProvider.map(({ model, provider }) => ({ id: model.id, @@ -269,9 +262,6 @@ export async function getSystemModel( purpose: "title" | "artifact" ): Promise { try { - // 使用动态导入避免循环依赖 - const { getEnabledAiModelsWithProvider } = await import("@/lib/db/queries"); - // 首先尝试从数据库获取默认模型 const modelsWithProvider = await getEnabledAiModelsWithProvider();