@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 14.5 kB
Source Map (JSON)
{"version":3,"file":"convex.cjs","names":["VectorStore","embeddings: EmbeddingsInterface","config: ConvexVectorStoreConfig<\n DataModel,\n TableName,\n IndexName,\n TextFieldName,\n EmbeddingFieldName,\n MetadataFieldName,\n InsertMutation,\n GetQuery\n >","vectors: number[][]","documents: Document[]","query: number[]","k: number","filter?: this[\"FilterType\"]","Document","texts: string[]","metadatas: object[] | object","dbConfig: ConvexVectorStoreConfig<\n DataModel,\n TableName,\n IndexName,\n TextFieldName,\n EmbeddingFieldName,\n MetadataFieldName,\n InsertMutation,\n GetQuery\n >","docs: Document[]"],"sources":["../../src/vectorstores/convex.ts"],"sourcesContent":["import {\n DocumentByInfo,\n FieldPaths,\n FilterExpression,\n FunctionReference,\n GenericActionCtx,\n GenericDataModel,\n GenericTableInfo,\n NamedTableInfo,\n NamedVectorIndex,\n TableNamesInDataModel,\n VectorFilterBuilder,\n VectorIndexNames,\n makeFunctionReference,\n} from \"convex/server\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { VectorStore } from \"@langchain/core/vectorstores\";\nimport { Document } from \"@langchain/core/documents\";\n\n/**\n * Type that defines the config required to initialize the\n * ConvexVectorStore class. It includes the table name,\n * index name, text field name, and embedding field name.\n */\nexport type ConvexVectorStoreConfig<\n DataModel extends GenericDataModel,\n TableName extends TableNamesInDataModel<DataModel>,\n IndexName extends VectorIndexNames<NamedTableInfo<DataModel, TableName>>,\n TextFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n EmbeddingFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n MetadataFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n InsertMutation extends FunctionReference<\n \"mutation\",\n \"internal\",\n { table: string; document: object }\n >,\n GetQuery extends FunctionReference<\n \"query\",\n \"internal\",\n { id: string },\n object | null\n >,\n> = {\n readonly ctx: GenericActionCtx<DataModel>;\n /**\n * Defaults to \"documents\"\n */\n readonly table?: TableName;\n /**\n * Defaults to \"byEmbedding\"\n */\n readonly index?: IndexName;\n /**\n * Defaults to \"text\"\n */\n readonly textField?: TextFieldName;\n /**\n * Defaults to \"embedding\"\n */\n readonly embeddingField?: EmbeddingFieldName;\n /**\n * Defaults to \"metadata\"\n */\n readonly metadataField?: MetadataFieldName;\n /**\n * Defaults to `internal.langchain.db.insert`\n */\n readonly insert?: InsertMutation;\n /**\n * Defaults to `internal.langchain.db.get`\n */\n readonly get?: GetQuery;\n};\n\n/**\n * Class that is a wrapper around Convex storage and vector search. It is used\n * to insert embeddings in Convex documents with a vector search index,\n * and perform a vector search on them.\n *\n * ConvexVectorStore does NOT implement maxMarginalRelevanceSearch.\n */\nexport class ConvexVectorStore<\n DataModel extends GenericDataModel,\n TableName extends TableNamesInDataModel<DataModel>,\n IndexName extends VectorIndexNames<NamedTableInfo<DataModel, TableName>>,\n TextFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n EmbeddingFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n MetadataFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n InsertMutation extends FunctionReference<\n \"mutation\",\n \"internal\",\n { table: string; document: object }\n >,\n GetQuery extends FunctionReference<\n \"query\",\n \"internal\",\n { id: string },\n object | null\n >,\n> extends VectorStore {\n /**\n * Type that defines the filter used in the\n * similaritySearchVectorWithScore and maxMarginalRelevanceSearch methods.\n * It includes limit, filter and a flag to include embeddings.\n */\n declare FilterType: {\n filter?: (\n q: VectorFilterBuilder<\n DocumentByInfo<GenericTableInfo>,\n NamedVectorIndex<NamedTableInfo<DataModel, TableName>, IndexName>\n >\n ) => FilterExpression<boolean>;\n includeEmbeddings?: boolean;\n };\n\n private readonly ctx: GenericActionCtx<DataModel>;\n\n private readonly table: TableName;\n\n private readonly index: IndexName;\n\n private readonly textField: TextFieldName;\n\n private readonly embeddingField: EmbeddingFieldName;\n\n private readonly metadataField: MetadataFieldName;\n\n private readonly insert: InsertMutation;\n\n private readonly get: GetQuery;\n\n _vectorstoreType(): string {\n return \"convex\";\n }\n\n constructor(\n embeddings: EmbeddingsInterface,\n config: ConvexVectorStoreConfig<\n DataModel,\n TableName,\n IndexName,\n TextFieldName,\n EmbeddingFieldName,\n MetadataFieldName,\n InsertMutation,\n GetQuery\n >\n ) {\n super(embeddings, config);\n this.ctx = config.ctx;\n this.table = config.table ?? (\"documents\" as TableName);\n this.index = config.index ?? (\"byEmbedding\" as IndexName);\n this.textField = config.textField ?? (\"text\" as TextFieldName);\n this.embeddingField =\n config.embeddingField ?? (\"embedding\" as EmbeddingFieldName);\n this.metadataField =\n config.metadataField ?? (\"metadata\" as MetadataFieldName);\n this.insert =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n config.insert ?? (makeFunctionReference(\"langchain/db:insert\") as any);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.get = config.get ?? (makeFunctionReference(\"langchain/db:get\") as any);\n }\n\n /**\n * Add vectors and their corresponding documents to the Convex table.\n * @param vectors Vectors to be added.\n * @param documents Corresponding documents to be added.\n * @returns Promise that resolves when the vectors and documents have been added.\n */\n async addVectors(vectors: number[][], documents: Document[]): Promise<void> {\n const convexDocuments = vectors.map((embedding, idx) => ({\n [this.textField]: documents[idx].pageContent,\n [this.embeddingField]: embedding,\n [this.metadataField]: documents[idx].metadata,\n }));\n // TODO: Remove chunking when Convex handles the concurrent requests correctly\n const PAGE_SIZE = 16;\n for (let i = 0; i < convexDocuments.length; i += PAGE_SIZE) {\n await Promise.all(\n convexDocuments.slice(i, i + PAGE_SIZE).map((document) =>\n this.ctx.runMutation(this.insert, {\n table: this.table,\n document,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any)\n )\n );\n }\n }\n\n /**\n * Add documents to the Convex table. It first converts\n * the documents to vectors using the embeddings and then calls the\n * addVectors method.\n * @param documents Documents to be added.\n * @returns Promise that resolves when the documents have been added.\n */\n async addDocuments(documents: Document[]): Promise<void> {\n const texts = documents.map(({ pageContent }) => pageContent);\n return this.addVectors(\n await this.embeddings.embedDocuments(texts),\n documents\n );\n }\n\n /**\n * Similarity search on the vectors stored in the\n * Convex table. It returns a list of documents and their\n * corresponding similarity scores.\n * @param query Query vector for the similarity search.\n * @param k Number of nearest neighbors to return.\n * @param filter Optional filter to be applied.\n * @returns Promise that resolves to a list of documents and their corresponding similarity scores.\n */\n async similaritySearchVectorWithScore(\n query: number[],\n k: number,\n filter?: this[\"FilterType\"]\n ): Promise<[Document, number][]> {\n const idsAndScores = await this.ctx.vectorSearch(this.table, this.index, {\n vector: query,\n limit: k,\n filter: filter?.filter,\n });\n\n const documents = await Promise.all(\n idsAndScores.map(({ _id }) =>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ctx.runQuery(this.get, { id: _id } as any)\n )\n );\n\n return documents.map(\n (\n {\n [this.textField]: text,\n [this.embeddingField]: embedding,\n [this.metadataField]: metadata,\n },\n idx\n ) => [\n new Document({\n pageContent: text as string,\n metadata: {\n ...metadata,\n ...(filter?.includeEmbeddings ? { embedding } : null),\n },\n }),\n idsAndScores[idx]._score,\n ]\n );\n }\n\n /**\n * Static method to create an instance of ConvexVectorStore from a\n * list of texts. It first converts the texts to vectors and then adds\n * them to the Convex table.\n * @param texts List of texts to be converted to vectors.\n * @param metadatas Metadata for the texts.\n * @param embeddings Embeddings to be used for conversion.\n * @param dbConfig Database configuration for Convex.\n * @returns Promise that resolves to a new instance of ConvexVectorStore.\n */\n static async fromTexts<\n DataModel extends GenericDataModel,\n TableName extends TableNamesInDataModel<DataModel>,\n IndexName extends VectorIndexNames<NamedTableInfo<DataModel, TableName>>,\n TextFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n EmbeddingFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n MetadataFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n InsertMutation extends FunctionReference<\n \"mutation\",\n \"internal\",\n { table: string; document: object }\n >,\n GetQuery extends FunctionReference<\n \"query\",\n \"internal\",\n { id: string },\n object | null\n >,\n >(\n texts: string[],\n metadatas: object[] | object,\n embeddings: EmbeddingsInterface,\n dbConfig: ConvexVectorStoreConfig<\n DataModel,\n TableName,\n IndexName,\n TextFieldName,\n EmbeddingFieldName,\n MetadataFieldName,\n InsertMutation,\n GetQuery\n >\n ): Promise<\n ConvexVectorStore<\n DataModel,\n TableName,\n IndexName,\n TextFieldName,\n EmbeddingFieldName,\n MetadataFieldName,\n InsertMutation,\n GetQuery\n >\n > {\n const docs = texts.map(\n (text, i) =>\n new Document({\n pageContent: text,\n metadata: Array.isArray(metadatas) ? metadatas[i] : metadatas,\n })\n );\n return ConvexVectorStore.fromDocuments(docs, embeddings, dbConfig);\n }\n\n /**\n * Static method to create an instance of ConvexVectorStore from a\n * list of documents. It first converts the documents to vectors and then\n * adds them to the Convex table.\n * @param docs List of documents to be converted to vectors.\n * @param embeddings Embeddings to be used for conversion.\n * @param dbConfig Database configuration for Convex.\n * @returns Promise that resolves to a new instance of ConvexVectorStore.\n */\n static async fromDocuments<\n DataModel extends GenericDataModel,\n TableName extends TableNamesInDataModel<DataModel>,\n IndexName extends VectorIndexNames<NamedTableInfo<DataModel, TableName>>,\n TextFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n EmbeddingFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n MetadataFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>>,\n InsertMutation extends FunctionReference<\n \"mutation\",\n \"internal\",\n { table: string; document: object }\n >,\n GetQuery extends FunctionReference<\n \"query\",\n \"internal\",\n { id: string },\n object | null\n >,\n >(\n docs: Document[],\n embeddings: EmbeddingsInterface,\n dbConfig: ConvexVectorStoreConfig<\n DataModel,\n TableName,\n IndexName,\n TextFieldName,\n EmbeddingFieldName,\n MetadataFieldName,\n InsertMutation,\n GetQuery\n >\n ): Promise<\n ConvexVectorStore<\n DataModel,\n TableName,\n IndexName,\n TextFieldName,\n EmbeddingFieldName,\n MetadataFieldName,\n InsertMutation,\n GetQuery\n >\n > {\n const instance = new this(embeddings, dbConfig);\n await instance.addDocuments(docs);\n return instance;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAiFA,IAAa,oBAAb,MAAa,0BAkBHA,0CAAY;CAgBpB,AAAiB;CAEjB,AAAiB;CAEjB,AAAiB;CAEjB,AAAiB;CAEjB,AAAiB;CAEjB,AAAiB;CAEjB,AAAiB;CAEjB,AAAiB;CAEjB,mBAA2B;AACzB,SAAO;CACR;CAED,YACEC,YACAC,QAUA;EACA,MAAM,YAAY,OAAO;EACzB,KAAK,MAAM,OAAO;EAClB,KAAK,QAAQ,OAAO,SAAU;EAC9B,KAAK,QAAQ,OAAO,SAAU;EAC9B,KAAK,YAAY,OAAO,aAAc;EACtC,KAAK,iBACH,OAAO,kBAAmB;EAC5B,KAAK,gBACH,OAAO,iBAAkB;EAC3B,KAAK,SAEH,OAAO,mDAAiC,sBAAsB;EAEhE,KAAK,MAAM,OAAO,gDAA8B,mBAAmB;CACpE;;;;;;;CAQD,MAAM,WAAWC,SAAqBC,WAAsC;EAC1E,MAAM,kBAAkB,QAAQ,IAAI,CAAC,WAAW,SAAS;IACtD,KAAK,YAAY,UAAU,KAAK;IAChC,KAAK,iBAAiB;IACtB,KAAK,gBAAgB,UAAU,KAAK;EACtC,GAAE;EAEH,MAAM,YAAY;AAClB,OAAK,IAAI,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK,WAC/C,MAAM,QAAQ,IACZ,gBAAgB,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,aAC3C,KAAK,IAAI,YAAY,KAAK,QAAQ;GAChC,OAAO,KAAK;GACZ;EAED,EAAQ,CACV,CACF;CAEJ;;;;;;;;CASD,MAAM,aAAaA,WAAsC;EACvD,MAAM,QAAQ,UAAU,IAAI,CAAC,EAAE,aAAa,KAAK,YAAY;AAC7D,SAAO,KAAK,WACV,MAAM,KAAK,WAAW,eAAe,MAAM,EAC3C,UACD;CACF;;;;;;;;;;CAWD,MAAM,gCACJC,OACAC,GACAC,QAC+B;EAC/B,MAAM,eAAe,MAAM,KAAK,IAAI,aAAa,KAAK,OAAO,KAAK,OAAO;GACvE,QAAQ;GACR,OAAO;GACP,QAAQ,QAAQ;EACjB,EAAC;EAEF,MAAM,YAAY,MAAM,QAAQ,IAC9B,aAAa,IAAI,CAAC,EAAE,KAAK,KAEvB,KAAK,IAAI,SAAS,KAAK,KAAK,EAAE,IAAI,IAAK,EAAQ,CAChD,CACF;AAED,SAAO,UAAU,IACf,CACE,EACE,CAAC,KAAK,YAAY,MAClB,CAAC,KAAK,iBAAiB,WACvB,CAAC,KAAK,gBAAgB,UACvB,EACD,QACG,CACH,IAAIC,oCAAS;GACX,aAAa;GACb,UAAU;IACR,GAAG;IACH,GAAI,QAAQ,oBAAoB,EAAE,UAAW,IAAG;GACjD;EACF,IACD,aAAa,KAAK,MACnB,EACF;CACF;;;;;;;;;;;CAYD,aAAa,UAmBXC,OACAC,WACAT,YACAU,UAqBA;EACA,MAAM,OAAO,MAAM,IACjB,CAAC,MAAM,MACL,IAAIH,oCAAS;GACX,aAAa;GACb,UAAU,MAAM,QAAQ,UAAU,GAAG,UAAU,KAAK;EACrD,GACJ;AACD,SAAO,kBAAkB,cAAc,MAAM,YAAY,SAAS;CACnE;;;;;;;;;;CAWD,aAAa,cAmBXI,MACAX,YACAU,UAqBA;EACA,MAAM,WAAW,IAAI,KAAK,YAAY;EACtC,MAAM,SAAS,aAAa,KAAK;AACjC,SAAO;CACR;AACF"}