function applyDecs2203RFactory() {
    function createAddInitializerMethod(initializers, decoratorFinishedRef) {
        return function addInitializer(initializer) {
            assertNotFinished(decoratorFinishedRef, "addInitializer");
            assertCallable(initializer, "An initializer");
            initializers.push(initializer);
        };
    }
    function memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value) {
        var kindStr;
        switch(kind){
            case 1:
                kindStr = "accessor";
                break;
            case 2:
                kindStr = "method";
                break;
            case 3:
                kindStr = "getter";
                break;
            case 4:
                kindStr = "setter";
                break;
            default:
                kindStr = "field";
        }
        var ctx = {
            kind: kindStr,
            name: isPrivate ? "#" + name : name,
            static: isStatic,
            private: isPrivate,
            metadata: metadata
        };
        var decoratorFinishedRef = {
            v: false
        };
        ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
        var get, set;
        if (kind === 0) {
            if (isPrivate) {
                get = desc.get;
                set = desc.set;
            } else {
                get = function() {
                    return this[name];
                };
                set = function(v) {
                    this[name] = v;
                };
            }
        } else if (kind === 2) {
            get = function() {
                return desc.value;
            };
        } else {
            if (kind === 1 || kind === 3) {
                get = function() {
                    return desc.get.call(this);
                };
            }
            if (kind === 1 || kind === 4) {
                set = function(v) {
                    desc.set.call(this, v);
                };
            }
        }
        ctx.access = get && set ? {
            get: get,
            set: set
        } : get ? {
            get: get
        } : {
            set: set
        };
        try {
            return dec(value, ctx);
        } finally{
            decoratorFinishedRef.v = true;
        }
    }
    function assertNotFinished(decoratorFinishedRef, fnName) {
        if (decoratorFinishedRef.v) {
            throw new Error("attempted to call " + fnName + " after decoration was finished");
        }
    }
    function assertCallable(fn, hint) {
        if (typeof fn !== "function") {
            throw new TypeError(hint + " must be a function");
        }
    }
    function assertValidReturnValue(kind, value) {
        var type = typeof value;
        if (kind === 1) {
            if (type !== "object" || value === null) {
                throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
            }
            if (value.get !== undefined) {
                assertCallable(value.get, "accessor.get");
            }
            if (value.set !== undefined) {
                assertCallable(value.set, "accessor.set");
            }
            if (value.init !== undefined) {
                assertCallable(value.init, "accessor.init");
            }
        } else if (type !== "function") {
            var hint;
            if (kind === 0) {
                hint = "field";
            } else if (kind === 10) {
                hint = "class";
            } else {
                hint = "method";
            }
            throw new TypeError(hint + " decorators must return a function or void 0");
        }
    }
    function applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata) {
        var decs = decInfo[0];
        var desc, init, value;
        if (isPrivate) {
            if (kind === 0 || kind === 1) {
                desc = {
                    get: decInfo[3],
                    set: decInfo[4]
                };
            } else if (kind === 3) {
                desc = {
                    get: decInfo[3]
                };
            } else if (kind === 4) {
                desc = {
                    set: decInfo[3]
                };
            } else {
                desc = {
                    value: decInfo[3]
                };
            }
        } else if (kind !== 0) {
            desc = Object.getOwnPropertyDescriptor(base, name);
        }
        if (kind === 1) {
            value = {
                get: desc.get,
                set: desc.set
            };
        } else if (kind === 2) {
            value = desc.value;
        } else if (kind === 3) {
            value = desc.get;
        } else if (kind === 4) {
            value = desc.set;
        }
        var newValue, get, set;
        if (typeof decs === "function") {
            newValue = memberDec(decs, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
            if (newValue !== void 0) {
                assertValidReturnValue(kind, newValue);
                if (kind === 0) {
                    init = newValue;
                } else if (kind === 1) {
                    init = newValue.init;
                    get = newValue.get || value.get;
                    set = newValue.set || value.set;
                    value = {
                        get: get,
                        set: set
                    };
                } else {
                    value = newValue;
                }
            }
        } else {
            for(var i = decs.length - 1; i >= 0; i--){
                var dec = decs[i];
                newValue = memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
                if (newValue !== void 0) {
                    assertValidReturnValue(kind, newValue);
                    var newInit;
                    if (kind === 0) {
                        newInit = newValue;
                    } else if (kind === 1) {
                        newInit = newValue.init;
                        get = newValue.get || value.get;
                        set = newValue.set || value.set;
                        value = {
                            get: get,
                            set: set
                        };
                    } else {
                        value = newValue;
                    }
                    if (newInit !== void 0) {
                        if (init === void 0) {
                            init = newInit;
                        } else if (typeof init === "function") {
                            init = [
                                init,
                                newInit
                            ];
                        } else {
                            init.push(newInit);
                        }
                    }
                }
            }
        }
        if (kind === 0 || kind === 1) {
            if (init === void 0) {
                init = function(instance, init) {
                    return init;
                };
            } else if (typeof init !== "function") {
                var ownInitializers = init;
                init = function(instance, init) {
                    var value = init;
                    for(var i = 0; i < ownInitializers.length; i++){
                        value = ownInitializers[i].call(instance, value);
                    }
                    return value;
                };
            } else {
                var originalInitializer = init;
                init = function(instance, init) {
                    return originalInitializer.call(instance, init);
                };
            }
            ret.push(init);
        }
        if (kind !== 0) {
            if (kind === 1) {
                desc.get = value.get;
                desc.set = value.set;
            } else if (kind === 2) {
                desc.value = value;
            } else if (kind === 3) {
                desc.get = value;
            } else if (kind === 4) {
                desc.set = value;
            }
            if (isPrivate) {
                if (kind === 1) {
                    ret.push(function(instance, args) {
                        return value.get.call(instance, args);
                    });
                    ret.push(function(instance, args) {
                        return value.set.call(instance, args);
                    });
                } else if (kind === 2) {
                    ret.push(value);
                } else {
                    ret.push(function(instance, args) {
                        return value.call(instance, args);
                    });
                }
            } else {
                Object.defineProperty(base, name, desc);
            }
        }
    }
    function applyMemberDecs(Class, decInfos, metadata) {
        var ret = [];
        var protoInitializers;
        var staticInitializers;
        var existingProtoNonFields = new Map();
        var existingStaticNonFields = new Map();
        for(var i = 0; i < decInfos.length; i++){
            var decInfo = decInfos[i];
            if (!Array.isArray(decInfo)) continue;
            var kind = decInfo[1];
            var name = decInfo[2];
            var isPrivate = decInfo.length > 3;
            var isStatic = kind >= 5;
            var base;
            var initializers;
            if (isStatic) {
                base = Class;
                kind = kind - 5;
                staticInitializers = staticInitializers || [];
                initializers = staticInitializers;
            } else {
                base = Class.prototype;
                protoInitializers = protoInitializers || [];
                initializers = protoInitializers;
            }
            if (kind !== 0 && !isPrivate) {
                var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
                var existingKind = existingNonFields.get(name) || 0;
                if (existingKind === true || existingKind === 3 && kind !== 4 || existingKind === 4 && kind !== 3) {
                    throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
                } else if (!existingKind && kind > 2) {
                    existingNonFields.set(name, kind);
                } else {
                    existingNonFields.set(name, true);
                }
            }
            applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
        }
        pushInitializers(ret, protoInitializers);
        pushInitializers(ret, staticInitializers);
        return ret;
    }
    function pushInitializers(ret, initializers) {
        if (initializers) {
            ret.push(function(instance) {
                for(var i = 0; i < initializers.length; i++){
                    initializers[i].call(instance);
                }
                return instance;
            });
        }
    }
    function applyClassDecs(targetClass, classDecs, metadata) {
        if (classDecs.length > 0) {
            var initializers = [];
            var newClass = targetClass;
            var name = targetClass.name;
            for(var i = classDecs.length - 1; i >= 0; i--){
                var decoratorFinishedRef = {
                    v: false
                };
                try {
                    var nextNewClass = classDecs[i](newClass, {
                        kind: "class",
                        name: name,
                        addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
                        metadata
                    });
                } finally{
                    decoratorFinishedRef.v = true;
                }
                if (nextNewClass !== undefined) {
                    assertValidReturnValue(10, nextNewClass);
                    newClass = nextNewClass;
                }
            }
            return [
                defineMetadata(newClass, metadata),
                function() {
                    for(var i = 0; i < initializers.length; i++){
                        initializers[i].call(newClass);
                    }
                }
            ];
        }
    }
    function defineMetadata(Class, metadata) {
        return Object.defineProperty(Class, Symbol.metadata || Symbol.for("Symbol.metadata"), {
            configurable: true,
            enumerable: true,
            value: metadata
        });
    }
    return function applyDecs2203R(targetClass, memberDecs, classDecs, parentClass) {
        if (parentClass !== void 0) {
            var parentMetadata = parentClass[Symbol.metadata || Symbol.for("Symbol.metadata")];
        }
        var metadata = Object.create(parentMetadata === void 0 ? null : parentMetadata);
        var e = applyMemberDecs(targetClass, memberDecs, metadata);
        if (!classDecs.length) defineMetadata(targetClass, metadata);
        return {
            e: e,
            get c () {
                return applyClassDecs(targetClass, classDecs, metadata);
            }
        };
    };
}
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
    return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
}
var _initProto;
import { ImageNode, ModalityType, ObjectType, splitNodesByType } from "../../Node.js";
import { nodeParserFromSettingsOrContext } from "../../Settings.js";
import { DEFAULT_SIMILARITY_TOP_K } from "../../constants.js";
import { RetrieverQueryEngine } from "../../engines/query/RetrieverQueryEngine.js";
import { addNodesToVectorStores, runTransformations } from "../../ingestion/IngestionPipeline.js";
import { DocStoreStrategy, createDocStoreStrategy } from "../../ingestion/strategies/index.js";
import { wrapEventCaller } from "../../internal/context/EventCaller.js";
import { getCallbackManager } from "../../internal/settings/CallbackManager.js";
import { storageContextFromDefaults } from "../../storage/StorageContext.js";
import { VectorStoreQueryMode } from "../../storage/vectorStore/types.js";
import { BaseIndex } from "../BaseIndex.js";
import { IndexDict, IndexStructType } from "../json-to-index-struct.js";
/**
 * The VectorStoreIndex, an index that stores the nodes only according to their vector embeddings.
 */ export class VectorStoreIndex extends BaseIndex {
    indexStore;
    embedModel;
    vectorStores;
    constructor(init){
        super(init);
        this.indexStore = init.indexStore;
        this.vectorStores = init.vectorStores ?? init.storageContext.vectorStores;
        this.embedModel = init.serviceContext?.embedModel;
    }
    /**
   * The async init function creates a new VectorStoreIndex.
   * @param options
   * @returns
   */ static async init(options) {
        const storageContext = options.storageContext ?? await storageContextFromDefaults({});
        const serviceContext = options.serviceContext;
        const indexStore = storageContext.indexStore;
        const docStore = storageContext.docStore;
        let indexStruct = await VectorStoreIndex.setupIndexStructFromStorage(indexStore, options);
        if (!options.nodes && !indexStruct) {
            throw new Error("Cannot initialize VectorStoreIndex without nodes or indexStruct");
        }
        indexStruct = indexStruct ?? new IndexDict();
        const index = new this({
            storageContext,
            serviceContext,
            docStore,
            indexStruct,
            indexStore,
            vectorStores: options.vectorStores
        });
        if (options.nodes) {
            // If nodes are passed in, then we need to update the index
            await index.buildIndexFromNodes(options.nodes, {
                logProgress: options.logProgress
            });
        }
        return index;
    }
    static async setupIndexStructFromStorage(indexStore, options) {
        const indexStructs = await indexStore.getIndexStructs();
        let indexStruct;
        if (options.indexStruct && indexStructs.length > 0) {
            throw new Error("Cannot initialize index with both indexStruct and indexStore");
        }
        if (options.indexStruct) {
            indexStruct = options.indexStruct;
        } else if (indexStructs.length == 1) {
            indexStruct = indexStructs[0].type === IndexStructType.SIMPLE_DICT ? indexStructs[0] : undefined;
            indexStruct = indexStructs[0];
        } else if (indexStructs.length > 1 && options.indexId) {
            indexStruct = await indexStore.getIndexStruct(options.indexId);
        }
        // Check indexStruct type
        if (indexStruct && indexStruct.type !== IndexStructType.SIMPLE_DICT) {
            throw new Error("Attempting to initialize VectorStoreIndex with non-vector indexStruct");
        }
        return indexStruct;
    }
    /**
   * Calculates the embeddings for the given nodes.
   *
   * @param nodes - An array of BaseNode objects representing the nodes for which embeddings are to be calculated.
   * @param {Object} [options] - An optional object containing additional parameters.
   *   @param {boolean} [options.logProgress] - A boolean indicating whether to log progress to the console (useful for debugging).
   */ async getNodeEmbeddingResults(nodes, options) {
        const nodeMap = splitNodesByType(nodes);
        for(const type in nodeMap){
            const nodes = nodeMap[type];
            const embedModel = this.embedModel ?? this.vectorStores[type]?.embedModel;
            if (embedModel && nodes) {
                await embedModel.transform(nodes, {
                    logProgress: options?.logProgress
                });
            }
        }
        return nodes;
    }
    /**
   * Get embeddings for nodes and place them into the index.
   * @param nodes
   * @returns
   */ async buildIndexFromNodes(nodes, options) {
        await this.insertNodes(nodes, options);
    }
    /**
   * High level API: split documents, get embeddings, and build index.
   * @param documents
   * @param args
   * @returns
   */ static async fromDocuments(documents, args = {}) {
        args.storageContext = args.storageContext ?? await storageContextFromDefaults({});
        args.vectorStores = args.vectorStores ?? args.storageContext.vectorStores;
        args.docStoreStrategy = args.docStoreStrategy ?? // set doc store strategy defaults to the same as for the IngestionPipeline
        (args.vectorStores ? DocStoreStrategy.UPSERTS : DocStoreStrategy.DUPLICATES_ONLY);
        args.serviceContext = args.serviceContext;
        const docStore = args.storageContext.docStore;
        if (args.logProgress) {
            console.log("Using node parser on documents...");
        }
        // use doc store strategy to avoid duplicates
        const vectorStores = Object.values(args.vectorStores ?? {});
        const docStoreStrategy = createDocStoreStrategy(args.docStoreStrategy, docStore, vectorStores);
        args.nodes = await runTransformations(documents, [
            nodeParserFromSettingsOrContext(args.serviceContext)
        ], {}, {
            docStoreStrategy
        });
        if (args.logProgress) {
            console.log("Finished parsing documents.");
        }
        return await this.init(args);
    }
    static async fromVectorStores(vectorStores, serviceContext) {
        if (!vectorStores[ModalityType.TEXT]?.storesText) {
            throw new Error("Cannot initialize from a vector store that does not store text");
        }
        const storageContext = await storageContextFromDefaults({
            vectorStores
        });
        const index = await this.init({
            nodes: [],
            storageContext,
            serviceContext
        });
        return index;
    }
    static async fromVectorStore(vectorStore, serviceContext) {
        return this.fromVectorStores({
            [ModalityType.TEXT]: vectorStore
        }, serviceContext);
    }
    asRetriever(options) {
        return new VectorIndexRetriever({
            index: this,
            ...options
        });
    }
    /**
   * Create a RetrieverQueryEngine.
   * similarityTopK is only used if no existing retriever is provided.
   */ asQueryEngine(options) {
        const { retriever, responseSynthesizer, preFilters, nodePostprocessors, similarityTopK } = options ?? {};
        return new RetrieverQueryEngine(retriever ?? this.asRetriever({
            similarityTopK
        }), responseSynthesizer, preFilters, nodePostprocessors);
    }
    async insertNodesToStore(newIds, nodes, vectorStore) {
        // NOTE: if the vector store doesn't store text,
        // we need to add the nodes to the index struct and document store
        // NOTE: if the vector store keeps text,
        // we only need to add image and index nodes
        for(let i = 0; i < nodes.length; ++i){
            const { type } = nodes[i];
            if (!vectorStore.storesText || type === ObjectType.INDEX || type === ObjectType.IMAGE) {
                const nodeWithoutEmbedding = nodes[i].clone();
                nodeWithoutEmbedding.embedding = undefined;
                this.indexStruct.addNode(nodeWithoutEmbedding, newIds[i]);
                await this.docStore.addDocuments([
                    nodeWithoutEmbedding
                ], true);
            }
        }
    }
    async insertNodes(nodes, options) {
        if (!nodes || nodes.length === 0) {
            return;
        }
        nodes = await this.getNodeEmbeddingResults(nodes, options);
        await addNodesToVectorStores(nodes, this.vectorStores, this.insertNodesToStore.bind(this));
        await this.indexStore.addIndexStruct(this.indexStruct);
    }
    async deleteRefDoc(refDocId, deleteFromDocStore = true) {
        for (const vectorStore of Object.values(this.vectorStores)){
            await this.deleteRefDocFromStore(vectorStore, refDocId);
        }
        if (deleteFromDocStore) {
            await this.docStore.deleteDocument(refDocId, false);
        }
    }
    async deleteRefDocFromStore(vectorStore, refDocId) {
        await vectorStore.delete(refDocId);
        if (!vectorStore.storesText) {
            const refDocInfo = await this.docStore.getRefDocInfo(refDocId);
            if (refDocInfo) {
                for (const nodeId of refDocInfo.nodeIds){
                    this.indexStruct.delete(nodeId);
                    await vectorStore.delete(nodeId);
                }
            }
            await this.indexStore.addIndexStruct(this.indexStruct);
        }
    }
}
export class VectorIndexRetriever {
    static{
        ({ e: [_initProto] } = _apply_decs_2203_r(this, [
            [
                wrapEventCaller,
                2,
                "retrieve"
            ]
        ], []));
    }
    index;
    topK;
    serviceContext;
    constructor({ index, similarityTopK, topK }){
        _initProto(this);
        this.index = index;
        this.serviceContext = this.index.serviceContext;
        this.topK = topK ?? {
            [ModalityType.TEXT]: similarityTopK ?? DEFAULT_SIMILARITY_TOP_K,
            [ModalityType.IMAGE]: DEFAULT_SIMILARITY_TOP_K
        };
    }
    /**
   * @deprecated, pass topK in constructor instead
   */ set similarityTopK(similarityTopK) {
        this.topK[ModalityType.TEXT] = similarityTopK;
    }
    async retrieve({ query, preFilters }) {
        getCallbackManager().dispatchEvent("retrieve-start", {
            payload: {
                query
            }
        });
        const vectorStores = this.index.vectorStores;
        let nodesWithScores = [];
        for(const type in vectorStores){
            const vectorStore = vectorStores[type];
            nodesWithScores = nodesWithScores.concat(await this.retrieveQuery(query, type, vectorStore, preFilters));
        }
        getCallbackManager().dispatchEvent("retrieve-end", {
            payload: {
                query,
                nodes: nodesWithScores
            }
        });
        // send deprecated event
        getCallbackManager().dispatchEvent("retrieve", {
            query,
            nodes: nodesWithScores
        });
        return nodesWithScores;
    }
    async retrieveQuery(query, type, vectorStore, preFilters) {
        // convert string message to multi-modal format
        if (typeof query === "string") {
            query = [
                {
                    type: "text",
                    text: query
                }
            ];
        }
        // overwrite embed model if specified, otherwise use the one from the vector store
        const embedModel = this.index.embedModel ?? vectorStore.embedModel;
        let nodes = [];
        // query each content item (e.g. text or image) separately
        for (const item of query){
            const queryEmbedding = await embedModel.getQueryEmbedding(item);
            if (queryEmbedding) {
                const result = await vectorStore.query({
                    queryEmbedding,
                    mode: VectorStoreQueryMode.DEFAULT,
                    similarityTopK: this.topK[type],
                    filters: preFilters ?? undefined
                });
                nodes = nodes.concat(this.buildNodeListFromQueryResult(result));
            }
        }
        return nodes;
    }
    buildNodeListFromQueryResult(result) {
        const nodesWithScores = [];
        for(let i = 0; i < result.ids.length; i++){
            const nodeFromResult = result.nodes?.[i];
            if (!this.index.indexStruct.nodesDict[result.ids[i]] && nodeFromResult) {
                this.index.indexStruct.nodesDict[result.ids[i]] = nodeFromResult;
            }
            const node = this.index.indexStruct.nodesDict[result.ids[i]];
            // XXX: Hack, if it's an image node, we reconstruct the image from the URL
            // Alternative: Store image in doc store and retrieve it here
            if (node instanceof ImageNode) {
                node.image = node.getUrl();
            }
            nodesWithScores.push({
                node: node,
                score: result.similarities[i]
            });
        }
        return nodesWithScores;
    }
}
