ai-chatbot/lib/chat/message-image-attachments.ts

82 lines
2.5 KiB
TypeScript

import type { Attachment } from "@/lib/types";
type MessageImageSource = {
parts?: unknown[] | null;
attachments?: unknown[] | null;
};
function normalizeImageContentType(value: unknown) {
const contentType = String(value || "").trim().toLowerCase();
return contentType.startsWith("image/") ? contentType : "image/jpeg";
}
export function getMessageImagePartUrl(part: unknown) {
const value = part as Record<string, any> | null;
if (!value) return "";
const imageUrl = value.image_url;
const candidate =
value.type === "image_url"
? typeof imageUrl === "string"
? imageUrl
: imageUrl?.url || value.url
: value.type === "image" || value.type === "input_image"
? value.image || value.url || value.data
: value.type === "file"
? value.url || value.data
: "";
return typeof candidate === "string" ? candidate.trim() : "";
}
export function collectMessageImageAttachments(
message: MessageImageSource | null | undefined
): Attachment[] {
if (!message) return [];
const result: Attachment[] = [];
const seen = new Set<string>();
const append = (value: unknown, fallbackIndex: number, fromPart: boolean) => {
const item = value as Record<string, any> | null;
if (!item) return;
const url = fromPart
? getMessageImagePartUrl(item)
: typeof item.url === "string"
? item.url.trim()
: "";
if (!url || seen.has(url)) return;
const explicitContentType = String(
item.contentType || item.mediaType || item.mimeType || ""
).trim();
if (explicitContentType && !explicitContentType.startsWith("image/")) {
return;
}
seen.add(url);
result.push({
name: String(item.name || item.filename || item.alt || `图片${fallbackIndex + 1}`),
url,
contentType: normalizeImageContentType(explicitContentType),
assetId:
typeof item.assetId === "string" && item.assetId.trim()
? item.assetId.trim()
: undefined,
width: Number.isFinite(Number(item.width)) ? Number(item.width) : undefined,
height: Number.isFinite(Number(item.height)) ? Number(item.height) : undefined,
});
};
(Array.isArray(message.parts) ? message.parts : []).forEach((part, index) => {
append(part, index, true);
});
(Array.isArray(message.attachments) ? message.attachments : []).forEach(
(attachment, index) => {
append(attachment, result.length + index, false);
}
);
return result;
}