diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index 4157b4028..b3b264db0 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -3071,10 +3071,64 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF continue; } - const content = message.parts?.map((p: any) => p.text || "").join("") || ""; const nearestUserImageKeys = getNearestUserImageUrlKeys(messages, messageIndex); - const imageUrls = extractAssistantImageUrls(content, nearestUserImageKeys); - const videoUrls = extractVideoUrls(content); + const imageUrlSet = new Set(); + const videoUrlSet = new Set(); + const parts = (message.parts || []) as any[]; + + parts.forEach((part) => { + if (!part) return; + + if (part.type === "text" && typeof part.text === "string") { + extractAssistantImageUrls(part.text, nearestUserImageKeys).forEach((url) => + imageUrlSet.add(url) + ); + extractVideoUrls(part.text).forEach((url) => videoUrlSet.add(url)); + return; + } + + const rawUrl = + typeof part.url === "string" && part.url.trim() + ? part.url.trim() + : typeof part.data === "string" && part.data.trim() + ? part.data.trim() + : ""; + if (!rawUrl || !/^https?:\/\//i.test(rawUrl)) return; + + const mediaType = String( + part.mediaType || part.mimeType || part.contentType || "" + ).toLowerCase(); + if ( + mediaType.startsWith("video/") || + /\.(mp4|mov|webm|m4v)(?:[?#].*)?$/i.test(rawUrl) + ) { + videoUrlSet.add(rawUrl); + return; + } + + imageUrlSet.add(rawUrl); + }); + + const messageAttachments = ((message as any).attachments || []) as Array<{ + url?: string; + contentType?: string; + }>; + messageAttachments.forEach((attachment) => { + const rawUrl = String(attachment?.url || "").trim(); + if (!rawUrl || !/^https?:\/\//i.test(rawUrl)) return; + const contentType = String(attachment?.contentType || "").toLowerCase(); + if ( + contentType.startsWith("video/") || + /\.(mp4|mov|webm|m4v)(?:[?#].*)?$/i.test(rawUrl) + ) { + videoUrlSet.add(rawUrl); + return; + } + imageUrlSet.add(rawUrl); + }); + + const imageUrls = Array.from(imageUrlSet); + const videoUrls = Array.from(videoUrlSet); if (imageUrls.length === 0 && videoUrls.length === 0) continue; processedMessageIds.current.add(message.id);