import _ from "lodash";
import { lazyLoadTransformers } from "../internal/deps/transformers.js";
import { MultiModalEmbedding } from "./MultiModalEmbedding.js";
async function readImage(input) {
    const { RawImage } = await lazyLoadTransformers();
    if (input instanceof Blob) {
        return await RawImage.fromBlob(input);
    } else if (_.isString(input) || input instanceof URL) {
        return await RawImage.fromURL(input);
    } else {
        throw new Error(`Unsupported input type: ${typeof input}`);
    }
}
export var ClipEmbeddingModelType;
(function(ClipEmbeddingModelType) {
    ClipEmbeddingModelType["XENOVA_CLIP_VIT_BASE_PATCH32"] = "Xenova/clip-vit-base-patch32";
    ClipEmbeddingModelType["XENOVA_CLIP_VIT_BASE_PATCH16"] = "Xenova/clip-vit-base-patch16";
})(ClipEmbeddingModelType || (ClipEmbeddingModelType = {}));
export class ClipEmbedding extends MultiModalEmbedding {
    modelType = "Xenova/clip-vit-base-patch16";
    tokenizer = null;
    processor = null;
    visionModel = null;
    textModel = null;
    async getTokenizer() {
        const { AutoTokenizer } = await lazyLoadTransformers();
        if (!this.tokenizer) {
            this.tokenizer = await AutoTokenizer.from_pretrained(this.modelType);
        }
        return this.tokenizer;
    }
    async getProcessor() {
        const { AutoProcessor } = await lazyLoadTransformers();
        if (!this.processor) {
            this.processor = await AutoProcessor.from_pretrained(this.modelType);
        }
        return this.processor;
    }
    async getVisionModel() {
        const { CLIPVisionModelWithProjection } = await lazyLoadTransformers();
        if (!this.visionModel) {
            this.visionModel = await CLIPVisionModelWithProjection.from_pretrained(this.modelType);
        }
        return this.visionModel;
    }
    async getTextModel() {
        const { CLIPTextModelWithProjection } = await lazyLoadTransformers();
        if (!this.textModel) {
            this.textModel = await CLIPTextModelWithProjection.from_pretrained(this.modelType);
        }
        return this.textModel;
    }
    async getImageEmbedding(image) {
        const loadedImage = await readImage(image);
        const imageInputs = await (await this.getProcessor())(loadedImage);
        const { image_embeds } = await (await this.getVisionModel())(imageInputs);
        return Array.from(image_embeds.data);
    }
    async getTextEmbedding(text) {
        const textInputs = await (await this.getTokenizer())([
            text
        ], {
            padding: true,
            truncation: true
        });
        const { text_embeds } = await (await this.getTextModel())(textInputs);
        return text_embeds.data;
    }
}
