mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-03 05:43:27 +00:00
90 lines
2.5 KiB
TypeScript
90 lines
2.5 KiB
TypeScript
|
|
import type { Base64ContentBlock } from "@langchain/core/messages";
|
||
|
|
import { toast } from "sonner";
|
||
|
|
|
||
|
|
// Returns a Promise of a typed multimodal block for images or PDFs
|
||
|
|
export async function fileToContentBlock(
|
||
|
|
file: File,
|
||
|
|
): Promise<Base64ContentBlock> {
|
||
|
|
const supportedImageTypes = [
|
||
|
|
"image/jpeg",
|
||
|
|
"image/png",
|
||
|
|
"image/gif",
|
||
|
|
"image/webp",
|
||
|
|
];
|
||
|
|
const supportedFileTypes = [...supportedImageTypes, "application/pdf"];
|
||
|
|
|
||
|
|
if (!supportedFileTypes.includes(file.type)) {
|
||
|
|
toast.error(
|
||
|
|
`Unsupported file type: ${file.type}. Supported types are: ${supportedFileTypes.join(", ")}`,
|
||
|
|
);
|
||
|
|
return Promise.reject(new Error(`Unsupported file type: ${file.type}`));
|
||
|
|
}
|
||
|
|
|
||
|
|
const data = await fileToBase64(file);
|
||
|
|
|
||
|
|
if (supportedImageTypes.includes(file.type)) {
|
||
|
|
return {
|
||
|
|
type: "image",
|
||
|
|
source_type: "base64",
|
||
|
|
mime_type: file.type,
|
||
|
|
data,
|
||
|
|
metadata: { name: file.name },
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// PDF
|
||
|
|
return {
|
||
|
|
type: "file",
|
||
|
|
source_type: "base64",
|
||
|
|
mime_type: "application/pdf",
|
||
|
|
data,
|
||
|
|
metadata: { filename: file.name },
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// Helper to convert File to base64 string
|
||
|
|
export async function fileToBase64(file: File): Promise<string> {
|
||
|
|
return new Promise<string>((resolve, reject) => {
|
||
|
|
const reader = new FileReader();
|
||
|
|
reader.onloadend = () => {
|
||
|
|
const result = reader.result as string;
|
||
|
|
// Remove the data:...;base64, prefix
|
||
|
|
resolve(result.split(",")[1]);
|
||
|
|
};
|
||
|
|
reader.onerror = reject;
|
||
|
|
reader.readAsDataURL(file);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Type guard for Base64ContentBlock
|
||
|
|
export function isBase64ContentBlock(
|
||
|
|
block: unknown,
|
||
|
|
): block is Base64ContentBlock {
|
||
|
|
if (typeof block !== "object" || block === null || !("type" in block))
|
||
|
|
return false;
|
||
|
|
// file type (legacy)
|
||
|
|
if (
|
||
|
|
(block as { type: unknown }).type === "file" &&
|
||
|
|
"source_type" in block &&
|
||
|
|
(block as { source_type: unknown }).source_type === "base64" &&
|
||
|
|
"mime_type" in block &&
|
||
|
|
typeof (block as { mime_type?: unknown }).mime_type === "string" &&
|
||
|
|
((block as { mime_type: string }).mime_type.startsWith("image/") ||
|
||
|
|
(block as { mime_type: string }).mime_type === "application/pdf")
|
||
|
|
) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
// image type (new)
|
||
|
|
if (
|
||
|
|
(block as { type: unknown }).type === "image" &&
|
||
|
|
"source_type" in block &&
|
||
|
|
(block as { source_type: unknown }).source_type === "base64" &&
|
||
|
|
"mime_type" in block &&
|
||
|
|
typeof (block as { mime_type?: unknown }).mime_type === "string" &&
|
||
|
|
(block as { mime_type: string }).mime_type.startsWith("image/")
|
||
|
|
) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|