From ef89ab1aeb6de0c2f0e3274dec56f5f4f56256dc Mon Sep 17 00:00:00 2001 From: 134 Date: Mon, 22 Jun 2026 10:36:08 +0800 Subject: [PATCH] fix: restore canvas generation placeholders --- components/canvas/CanvasChatPanel.tsx | 21 +++++++++++++++++++++ components/image-params-bar.tsx | 10 +++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index 23a79819b..b21e63adc 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -7631,6 +7631,10 @@ export function CanvasChatPanel({ textContent = `请按「${selectedSkillTag.name}」标签的要求处理。`; } textContent = clampChatRequestText(textContent, MAX_CHAT_TEXT_PART_LENGTH); + const requestModel = allModels.find((model) => model.id === effectiveModelId); + const shouldShowOptimisticImageGeneration = + effectiveComposerMode === "image" && + Boolean(requestModel && isCanvasImageModel(requestModel)); // 🆕 隐藏提示词(不在 UI 中展示) const hiddenSegments: string[] = []; @@ -7728,6 +7732,16 @@ export function CanvasChatPanel({ inFlightRawChatIdRef.current = rawChatId; clearStreamImageGenerationStateForChat(activeChatId); clearAgentProgressStateForChat(activeChatId); + if (shouldShowOptimisticImageGeneration) { + const imageParamSnapshot = imageParamsRef.current || imageParams; + setStreamImageGenerationStateForChat(activeChatId, { + phase: "processing", + providerType: requestModel?.providerType, + modelName: getAgentSafeModelName(requestModel?.displayName), + imageCount: + Math.max(1, Math.round(Number(imageParamSnapshot?.imageCount || 1))) || 1, + }); + } // 使用与 multimodal-input 相同的格式发送消息 try { @@ -7737,6 +7751,9 @@ export function CanvasChatPanel({ }); } catch (error) { releaseSendGuard(activeChatId); + if (shouldShowOptimisticImageGeneration) { + clearStreamImageGenerationStateForChat(activeChatId); + } if (inFlightChatIdRef.current === activeChatId) { inFlightChatIdRef.current = null; inFlightRawChatIdRef.current = null; @@ -7778,10 +7795,13 @@ export function CanvasChatPanel({ clearSelection, buildAutoContext, buildContextPayload, + allModels, isVideoModel, + isCanvasImageModel, videoParams, videoFrameSlots.length, currentModel?.providerType, + imageParams, selectedImageNodes, isDetailGenerationMode, canUseDetailGeneration, @@ -7790,6 +7810,7 @@ export function CanvasChatPanel({ getSendGuard, clearStreamImageGenerationStateForChat, clearAgentProgressStateForChat, + setStreamImageGenerationStateForChat, computedComposerMode, releaseSendGuard, setSendGuard, diff --git a/components/image-params-bar.tsx b/components/image-params-bar.tsx index 5b3b80702..04f063c46 100644 --- a/components/image-params-bar.tsx +++ b/components/image-params-bar.tsx @@ -191,18 +191,22 @@ export function ImageParamsBar({ a.watermark === b.watermark && a.seed === b.seed; - const buildBaseParams = (source?: Partial) => - clampParamsByProvider({ + const buildBaseParams = (source?: Partial) => { + const hasSourceAspectRatio = + typeof source?.aspectRatio === "string" && source.aspectRatio.trim().length > 0; + + return clampParamsByProvider({ aspectRatio: inlineTheme === "minimal" ? "1:1" : "auto", imageSize: "2K", imageCount: 1, promptExtend: true, watermark: false, ...source, - ...(inlineTheme === "minimal" && (!source?.aspectRatio || source.aspectRatio === "auto") + ...(inlineTheme === "minimal" && !hasSourceAspectRatio ? { aspectRatio: "1:1" } : {}), }); + }; const [params, setParams] = useState({ ...buildBaseParams(initialParams),