From 58d0b8b5dd1d571673054eff35d08c036988c696 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 1 Feb 2026 02:24:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=99=BA=E8=83=BD=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E5=88=86=E9=98=B6=E6=AE=B5=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=8D=A0=E4=BD=8D=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 流程: 1. 用户发送请求 → 显示'AI正在思考'(Qwen3在分析) 2. 对话消息出现(带GENERATING_IMAGE标记)→ 切换到生图占位图 3. 图片生成完成 → 隐藏占位图 修改: - 检测 GENERATING_IMAGE 标记来区分阶段 - 分析阶段显示 ThinkingMessage - 生图阶段显示 ImageGenerationLoading Co-authored-by: Cursor --- components/messages.tsx | 105 +++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 39 deletions(-) diff --git a/components/messages.tsx b/components/messages.tsx index 7da88f4..d18df2f 100644 --- a/components/messages.tsx +++ b/components/messages.tsx @@ -158,9 +158,11 @@ function PureMessages({ const isAutoModeWithImage = selectedModelId === "auto" && lastUserMessage?.parts?.some((p: any) => p.type === "file" || p.type === "image"); - // 🆕 检查是否有"图片正在生成"的标记 - const isGeneratingImage = lastMessage?.parts?.some( - (part: any) => part.type === "text" && part.text?.includes("") + // 🆕 检查是否有"图片正在生成"的标记(表示对话消息已发送,正在等待图片生成) + const isGeneratingImage = messages.some(msg => + msg.role === "assistant" && msg.parts?.some( + (part: any) => part.type === "text" && part.text?.includes("") + ) ); // 对于图片模型,检查是否有图片内容(包含 ![thumb| 或 ![thumb||| 标记) @@ -178,11 +180,6 @@ function PureMessages({ part.text.includes("![Generated Image") )) ); - - // 🆕 如果有"正在生成"标记,强制认为没有图片内容(继续显示占位图) - if (isGeneratingImage) { - hasImageContent = false; - } } else { // 普通模式:只检查最后一条消息 hasImageContent = lastMessage?.parts && lastMessage.parts.some( @@ -202,39 +199,59 @@ function PureMessages({ // 判断是否是图片生成模型(包括 Gemini、火山、阿里) const isImageGenModel = isGeminiModel || isVolcanoVisionModel || isAlibabaImageModel; - // 根据模型类型判断是否有有效内容 + // 🆕 智能自动模式的特殊处理 + // - 收到 GENERATING_IMAGE 标记前:显示普通思考动画 + // - 收到 GENERATING_IMAGE 标记后:显示生图占位图 + // - 收到图片后:隐藏占位图 let hasContent = false; if (isQianwenVideoModel || isVideoModel) { - hasContent = hasVideoContent ?? false; // 视频模型:只有真正的视频才算有内容 - } else if (isImageGenModel || isAutoModeWithImage) { - hasContent = hasImageContent ?? false; // 图片模型或智能自动+图片:只有图片才算有内容(文字不算) + hasContent = hasVideoContent ?? false; + } else if (isImageGenModel) { + hasContent = hasImageContent ?? false; + } else if (isAutoModeWithImage) { + // 智能自动模式:只有图片出现才算有内容 + hasContent = hasImageContent ?? false; } else { - hasContent = hasTextContent ?? false; // 其他模型:任何文本都算有内容 + hasContent = hasTextContent ?? false; } - // 根据模型类型设置延迟时间(视频模型 60 秒,图片模型 4 秒,其他 6 秒) - // 🆕 智能自动模式如果有图片,也按图片模型处理 + // 根据模型类型设置延迟时间 const delayTime = (isQianwenVideoModel || isVideoModel) ? 60000 : (isImageGenModel || isAutoModeWithImage) ? 4000 : 6000; - // 如果是 submitted 状态,立即显示 - if (status === "submitted") { - setShowThinkingWithDelay(true); - } - // 如果是 streaming 状态且没有内容,显示 - else if (status === "streaming" && lastMessage?.role === "assistant" && !hasContent) { - setShowThinkingWithDelay(true); - } - // 如果 AI 开始有内容了,延迟后隐藏 - else if (status === "streaming" && lastMessage?.role === "assistant" && hasContent) { - const timer = setTimeout(() => { + // 🆕 智能自动模式的占位图逻辑 + if (isAutoModeWithImage) { + if (hasImageContent) { + // 图片已生成,延迟后隐藏占位图 + const timer = setTimeout(() => { + setShowThinkingWithDelay(false); + }, delayTime); + return () => clearTimeout(timer); + } else if (isGeneratingImage) { + // 收到 GENERATING_IMAGE 标记,显示生图占位图 + setShowThinkingWithDelay(true); + } else if (status === "submitted" || (status === "streaming" && !hasTextContent)) { + // 正在分析意图,显示普通思考动画 + setShowThinkingWithDelay(true); + } else if (status === "streaming" && hasTextContent && !isGeneratingImage) { + // 对话消息出现了但还没有 GENERATING_IMAGE 标记,继续显示思考动画 + setShowThinkingWithDelay(true); + } else { setShowThinkingWithDelay(false); - }, delayTime); - - return () => clearTimeout(timer); - } - // 其他情况立即隐藏 - else { - setShowThinkingWithDelay(false); + } + } else { + // 非智能自动模式的原有逻辑 + if (status === "submitted") { + setShowThinkingWithDelay(true); + } else if (status === "streaming" && lastMessage?.role === "assistant" && !hasContent) { + setShowThinkingWithDelay(true); + } else if (status === "streaming" && lastMessage?.role === "assistant" && hasContent) { + const timer = setTimeout(() => { + setShowThinkingWithDelay(false); + }, delayTime); + return () => clearTimeout(timer); + } else { + setShowThinkingWithDelay(false); + } } }, [status, messages, isGeminiModel, isQianwenVideoModel, isVolcanoVisionModel, isVideoModel, isAlibabaImageModel, selectedModelId]); @@ -363,20 +380,30 @@ function PureMessages({ const showAlibabaImage = modelType === "alibaba-image" || (!modelType && isAlibabaImageModel); const showVideo = modelType === "volcano-video" || modelType === "qianwen-video" || (!modelType && (isQianwenVideoModel || isVideoModel)); - // 🆕 检查智能自动模式是否有图片(需要显示生图占位图) + // 🆕 检查智能自动模式 const isAutoMode = selectedModelId === "auto"; - // 🆕 找用户的最后一条消息(而不是整个对话的最后一条) const lastUserMsg = [...messages].reverse().find(m => m.role === "user"); const userMessageHasImage = lastUserMsg?.parts?.some((p: any) => p.type === "file" || p.type === "image"); - const showAutoModeImage = isAutoMode && userMessageHasImage; + + // 🆕 检查是否收到了 GENERATING_IMAGE 标记(表示对话已发送,开始生图) + const hasGeneratingMarker = messages.some(msg => + msg.role === "assistant" && msg.parts?.some( + (part: any) => part.type === "text" && part.text?.includes("") + ) + ); + + // 🆕 智能自动模式:根据阶段显示不同占位图 + const showAutoModeImagePlaceholder = isAutoMode && userMessageHasImage && hasGeneratingMarker; + const showAutoModeThinking = isAutoMode && userMessageHasImage && !hasGeneratingMarker; if (showVideo) return ; if (showGemini) return ; if (showVolcano) return ; - // 🆕 阿里生图模型使用通用组件,橙色主题,最多 6 张,传递自定义模型名称 if (showAlibabaImage) return ; - // 🆕 智能自动模式:如果用户发送了图片,显示智能处理占位图 - if (showAutoModeImage) return ; + // 🆕 智能自动模式:收到 GENERATING_IMAGE 后显示生图占位图 + if (showAutoModeImagePlaceholder) return ; + // 🆕 智能自动模式:分析阶段显示思考动画 + if (showAutoModeThinking) return ; // 其他情况显示通用思考动画 return ; })()}