diff --git a/packages/app/src/attachments/utils.ts b/packages/app/src/attachments/utils.ts index 448b706d2..f6a78f6a0 100644 --- a/packages/app/src/attachments/utils.ts +++ b/packages/app/src/attachments/utils.ts @@ -55,9 +55,10 @@ export function parseImageDataUrl( if (!parsed.mimeType.toLowerCase().startsWith("image/")) { return null; } + const fingerprint = `${parsed.mimeType}\0${parsed.base64.length}\0${parsed.base64.slice(0, 64)}\0${parsed.base64.slice(-64)}`; return { ...parsed, - cacheKey: `data-image:${parsed.mimeType}:${parsed.base64.length}:${hashString(parsed.base64)}`, + cacheKey: `data-image:${parsed.mimeType}:${parsed.base64.length}:${hashString(fingerprint)}`, }; } catch { return null; @@ -80,13 +81,18 @@ export function getFileNameFromPath(path: string | null | undefined): string | n } export function createPreviewAttachmentId(input: { - base64: string; mimeType: string; path?: string | null; + size?: number | null; + modifiedAt?: string | null; + contentLength?: number | null; }): string { const path = input.path?.trim() ?? ""; - const hash = hashString(`${input.mimeType}\0${path}\0${input.base64}`); - return `preview_${input.base64.length}_${hash}`; + const size = Number.isFinite(input.size) ? String(input.size) : ""; + const modifiedAt = input.modifiedAt?.trim() ?? ""; + const contentLength = Number.isFinite(input.contentLength) ? String(input.contentLength) : ""; + const hash = hashString(`${input.mimeType}\0${path}\0${size}\0${modifiedAt}\0${contentLength}`); + return `preview_${size || contentLength || "unknown"}_${hash}`; } export async function blobToBase64(blob: Blob): Promise { diff --git a/packages/app/src/components/file-pane.tsx b/packages/app/src/components/file-pane.tsx index d0bff6a59..2a11d8cb0 100644 --- a/packages/app/src/components/file-pane.tsx +++ b/packages/app/src/components/file-pane.tsx @@ -76,9 +76,11 @@ async function createFilePanePreview(file: ExplorerFile | null): Promise<{ const { content: _content, ...imageFile } = file; const imageAttachment = await persistAttachmentFromBase64({ id: createPreviewAttachmentId({ - base64: file.content, mimeType: file.mimeType ?? "image/png", path: file.path, + size: file.size, + modifiedAt: file.modifiedAt, + contentLength: file.content.length, }), base64: file.content, mimeType: file.mimeType, diff --git a/packages/app/src/components/message.tsx b/packages/app/src/components/message.tsx index b137b8254..06da47460 100644 --- a/packages/app/src/components/message.tsx +++ b/packages/app/src/components/message.tsx @@ -635,9 +635,11 @@ function AssistantMarkdownImage({ return await persistAttachmentFromBase64({ id: createPreviewAttachmentId({ - base64: file.content, mimeType: file.mimeType ?? "image/png", path: file.path || resolution.path, + size: file.size, + modifiedAt: file.modifiedAt, + contentLength: file.content.length, }), base64: file.content, mimeType: file.mimeType, @@ -655,7 +657,10 @@ function AssistantMarkdownImage({ } return await persistAttachmentFromDataUrl({ - id: createPreviewAttachmentId(dataImage), + id: createPreviewAttachmentId({ + mimeType: dataImage.mimeType, + contentLength: dataImage.base64.length, + }), dataUrl: source, mimeType: dataImage.mimeType, });