From 4ac4ac26cfa5f146e6d914a69e37d4382145101a Mon Sep 17 00:00:00 2001 From: 134 Date: Tue, 7 Jul 2026 21:07:18 +0800 Subject: [PATCH] fix canvas agent image generation status --- app/(chat)/api/chat/route.ts | 31 +++++++++++++++++++++++++++ components/canvas/CanvasChatPanel.tsx | 22 ++++++++++++------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index 67e892f9b..fcbfd0b3d 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -7896,6 +7896,32 @@ export async function POST(request: Request) { operationLabel: "agent-generate-image", resultType: "image", }); + const directImageStatusPayload = { + providerType: requestedModelProviderType, + modelName: finalModelId, + imageCount: + effectiveImageParams?.imageCount || + defaultImageQualityParams.imageCount || + 1, + }; + const stopDirectImageKeepalive = startStreamKeepalive( + writer, + "agent:generate_image", + DEFAULT_STREAM_KEEPALIVE_INTERVAL_MS, + ); + const stopDirectImageStatus = + contextPayload?.source === "canvas" + ? setInterval(() => { + writeImageGenerationStatusChunk( + writer, + { + phase: "processing", + ...directImageStatusPayload, + }, + "agent:generate_image:status-processing-keepalive", + ); + }, DEFAULT_STREAM_KEEPALIVE_INTERVAL_MS) + : null; try { const directImageResult = await executeDirectAgentImageGeneration({ requestTextContent, @@ -8037,6 +8063,11 @@ export async function POST(request: Request) { "", "agent:generate_image:end-error", ); + } finally { + stopDirectImageKeepalive(); + if (stopDirectImageStatus) { + clearInterval(stopDirectImageStatus); + } } }, }); diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index 8b7e3f299..c16e2d7a5 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -11006,16 +11006,20 @@ export function CanvasChatPanel({ metadata: optimisticUserMetadata, } as ChatMessage; + setMessages((previousMessages) => + sortCanvasMessagesByCreatedAt([ + ...previousMessages.filter((message) => message.id !== userMessageId), + optimisticUserMessage, + ]) + ); + // 使用与 multimodal-input 相同的格式发送消息 try { sendMessage(optimisticUserMessage as any); - setMessages((previousMessages) => - sortCanvasMessagesByCreatedAt([ - ...previousMessages.filter((message) => message.id !== userMessageId), - optimisticUserMessage, - ]) - ); } catch (error) { + setMessages((previousMessages) => + previousMessages.filter((message) => message.id !== userMessageId) + ); releaseSendGuard(activeChatId); if (shouldShowOptimisticImageGeneration) { clearStreamImageGenerationStateForChat(activeChatId); @@ -12010,8 +12014,10 @@ export function CanvasChatPanel({ ) ); const shouldShowImageLoading = - ((hasGenerationStart && !hasGenerationEnd) || Boolean(streamImageGenerationState)) && - !!currentModel; + Boolean(streamImageGenerationState) || + (hasGenerationStart && + !hasGenerationEnd && + Boolean(currentModel || activeComposerMode === "agent")); const hasActiveTypewriter = Object.keys(activeTypingSections).length > 0; const shouldRenderImageLoading = shouldShowImageLoading && !hasActiveTypewriter; const loadingImageCount = streamImageGenerationState?.imageCount || imageParams.imageCount || 1;