From 8352ffc06c9c8a42fb01d8b35938328a77a64e53 Mon Sep 17 00:00:00 2001 From: Tudor Golubenco Date: Thu, 3 Aug 2023 06:11:05 +0300 Subject: [PATCH] Add support for Xata as a vector store (#2125) * Added Xata as vector store + integration tests * Added examples and docs * Declare xata in peerDependencies as per the contributing guide * Removed any for the client type * review comments --- .../vectorstores/integrations/xata.mdx | 52 ++++++ examples/package.json | 1 + examples/src/indexes/vector_stores/xata.ts | 65 +++++++ .../indexes/vector_stores/xata_metadata.ts | 61 +++++++ langchain/.gitignore | 3 + langchain/package.json | 13 ++ langchain/scripts/create-entrypoints.js | 4 +- langchain/src/load/import_map.ts | 1 + .../src/vectorstores/tests/xata.int.test.ts | 161 ++++++++++++++++++ langchain/src/vectorstores/xata.ts | 104 +++++++++++ langchain/tsconfig.json | 1 + test-exports-cf/src/entrypoints.js | 1 + test-exports-cjs/src/entrypoints.js | 1 + test-exports-esbuild/src/entrypoints.js | 1 + test-exports-esm/src/entrypoints.js | 1 + test-exports-vercel/src/entrypoints.js | 1 + test-exports-vite/src/entrypoints.js | 1 + yarn.lock | 14 ++ 18 files changed, 485 insertions(+), 1 deletion(-) create mode 100644 docs/extras/modules/data_connection/vectorstores/integrations/xata.mdx create mode 100644 examples/src/indexes/vector_stores/xata.ts create mode 100644 examples/src/indexes/vector_stores/xata_metadata.ts create mode 100644 langchain/src/vectorstores/tests/xata.int.test.ts create mode 100644 langchain/src/vectorstores/xata.ts diff --git a/docs/extras/modules/data_connection/vectorstores/integrations/xata.mdx b/docs/extras/modules/data_connection/vectorstores/integrations/xata.mdx new file mode 100644 index 000000000000..a5888669533b --- /dev/null +++ b/docs/extras/modules/data_connection/vectorstores/integrations/xata.mdx @@ -0,0 +1,52 @@ +# Xata + +[Xata](https://xata.io) is a serverless data platform, based on PostgreSQL. It provides a type-safe TypeScript/JavaScript SDK for interacting with your database, and a UI for managing your data. + +Xata has a native vector type, which can be added to any table, and supports similarity search. LangChain inserts vectors directly to Xata, and queries it for the nearest neighbors of a given vector, so that you can use all the LangChain Embeddings integrations with Xata. + +## Setup + +### Install the Xata CLI + +```bash +npm install @xata.io/cli -g +``` + +### Create a database to be used as a vector store + +In the [Xata UI](https://app.xata.io) create a new database. You can name it whatever you want, but for this example we'll use `langchain`. +Create a table, again you can name it anything, but we will use `vectors`. Add the following columns via the UI: + +* `content` of type "Long text". This is used to store the `Document.pageContent` values. +* `embedding` of type "Vector". Use the dimension used by the model you plan to use (1536 for OpenAI). +* any other columns you want to use as metadata. They are populated from the `Document.metadata` object. For example, if in the `Document.metadata` object you have a `title` property, you can create a `title` column in the table and it will be populated. + +### Initialize the project + +In your project, run: + +```bash +xata init +``` + +and then choose the database you created above. This will also generate a `xata.ts` or `xata.js` file that defines the client you can use to interact with the database. See the [Xata getting started docs](https://xata.io/docs/getting-started/installation) for more details on using the Xata JavaScript/TypeScript SDK. + +## Usage + +import CodeBlock from "@theme/CodeBlock"; + +### Example: Q&A chatbot using OpenAI and Xata as vector store + +This example uses the `VectorDBQAChain` to search the documents stored in Xata and then pass them as context to the OpenAI model, in order to answer the question asked by the user. + +import FromDocs from "@examples/indexes/vector_stores/xata.ts"; + +{FromDocs} + +### Example: Similarity search with a metadata filter + +This example shows how to implement semantic search using LangChain.js and Xata. Before running it, make sure to add an `author` column of type String to the `vectors` table in Xata. + +import SimSearch from "@examples/indexes/vector_stores/xata_metadata.ts"; + +{SimSearch} diff --git a/examples/package.json b/examples/package.json index d8981b88cd2d..a5bf5536f046 100644 --- a/examples/package.json +++ b/examples/package.json @@ -35,6 +35,7 @@ "@tensorflow/tfjs-backend-cpu": "^4.4.0", "@tigrisdata/vector": "^1.1.0", "@upstash/redis": "^1.20.6", + "@xata.io/client": "^0.25.1", "@zilliz/milvus2-sdk-node": "^2.2.7", "axios": "^0.26.0", "chromadb": "^1.4.0", diff --git a/examples/src/indexes/vector_stores/xata.ts b/examples/src/indexes/vector_stores/xata.ts new file mode 100644 index 000000000000..7319e863c9c5 --- /dev/null +++ b/examples/src/indexes/vector_stores/xata.ts @@ -0,0 +1,65 @@ +import { XataVectorSearch } from "langchain/vectorstores/xata"; +import { OpenAIEmbeddings } from "langchain/embeddings/openai"; +import { BaseClient } from "@xata.io/client"; +import { Document } from "langchain/document"; +import { VectorDBQAChain } from "langchain/chains"; +import { OpenAI } from "langchain/llms/openai"; + +// First, follow set-up instructions at +// https://js.langchain.com/docs/modules/data_connection/vectorstores/integrations/xata + +// if you use the generated client, you don't need this function. +// Just import getXataClient from the generated xata.ts instead. +const getXataClient = () => { + if (!process.env.XATA_API_KEY) { + throw new Error("XATA_API_KEY not set"); + } + + if (!process.env.XATA_DB_URL) { + throw new Error("XATA_DB_URL not set"); + } + const xata = new BaseClient({ + databaseURL: process.env.XATA_DB_URL, + apiKey: process.env.XATA_API_KEY, + branch: process.env.XATA_BRANCH || "main", + }); + return xata; +}; + +export async function run() { + const client = getXataClient(); + + const table = "vectors"; + const embeddings = new OpenAIEmbeddings(); + const store = new XataVectorSearch(embeddings, { client, table }); + + // Add documents + const docs = [ + new Document({ + pageContent: "Xata is a Serverless Data platform based on PostgreSQL", + }), + new Document({ + pageContent: + "Xata offers a built-in vector type that can be used to store and query vectors", + }), + new Document({ + pageContent: "Xata includes similarity search", + }), + ]; + + const ids = await store.addDocuments(docs); + + // eslint-disable-next-line no-promise-executor-return + await new Promise((r) => setTimeout(r, 2000)); + + const model = new OpenAI(); + const chain = VectorDBQAChain.fromLLM(model, store, { + k: 1, + returnSourceDocuments: true, + }); + const response = await chain.call({ query: "What is Xata?" }); + + console.log(JSON.stringify(response, null, 2)); + + await store.delete({ ids }); +} diff --git a/examples/src/indexes/vector_stores/xata_metadata.ts b/examples/src/indexes/vector_stores/xata_metadata.ts new file mode 100644 index 000000000000..306534a894f0 --- /dev/null +++ b/examples/src/indexes/vector_stores/xata_metadata.ts @@ -0,0 +1,61 @@ +import { XataVectorSearch } from "langchain/vectorstores/xata"; +import { OpenAIEmbeddings } from "langchain/embeddings/openai"; +import { BaseClient } from "@xata.io/client"; +import { Document } from "langchain/document"; + +// First, follow set-up instructions at +// https://js.langchain.com/docs/modules/data_connection/vectorstores/integrations/xata +// Also, add a column named "author" to the "vectors" table. + +// if you use the generated client, you don't need this function. +// Just import getXataClient from the generated xata.ts instead. +const getXataClient = () => { + if (!process.env.XATA_API_KEY) { + throw new Error("XATA_API_KEY not set"); + } + + if (!process.env.XATA_DB_URL) { + throw new Error("XATA_DB_URL not set"); + } + const xata = new BaseClient({ + databaseURL: process.env.XATA_DB_URL, + apiKey: process.env.XATA_API_KEY, + branch: process.env.XATA_BRANCH || "main", + }); + return xata; +}; + +export async function run() { + const client = getXataClient(); + const table = "vectors"; + const embeddings = new OpenAIEmbeddings(); + const store = new XataVectorSearch(embeddings, { client, table }); + // Add documents + const docs = [ + new Document({ + pageContent: "Xata works great with Langchain.js", + metadata: { author: "Xata" }, + }), + new Document({ + pageContent: "Xata works great with Langchain", + metadata: { author: "Langchain" }, + }), + new Document({ + pageContent: "Xata includes similarity search", + metadata: { author: "Xata" }, + }), + ]; + const ids = await store.addDocuments(docs); + + // eslint-disable-next-line no-promise-executor-return + await new Promise((r) => setTimeout(r, 2000)); + + // author is applied as pre-filter to the similarity search + const results = await store.similaritySearchWithScore("xata works great", 6, { + author: "Langchain", + }); + + console.log(JSON.stringify(results, null, 2)); + + await store.delete({ ids }); +} diff --git a/langchain/.gitignore b/langchain/.gitignore index 1a9c0d974deb..be60fae4e5f4 100644 --- a/langchain/.gitignore +++ b/langchain/.gitignore @@ -202,6 +202,9 @@ vectorstores/tigris.d.ts vectorstores/vectara.cjs vectorstores/vectara.js vectorstores/vectara.d.ts +vectorstores/xata.cjs +vectorstores/xata.js +vectorstores/xata.d.ts text_splitter.cjs text_splitter.js text_splitter.d.ts diff --git a/langchain/package.json b/langchain/package.json index 20e681f93045..0d6741c65e34 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -214,6 +214,9 @@ "vectorstores/vectara.cjs", "vectorstores/vectara.js", "vectorstores/vectara.d.ts", + "vectorstores/xata.cjs", + "vectorstores/xata.js", + "vectorstores/xata.d.ts", "text_splitter.cjs", "text_splitter.js", "text_splitter.d.ts", @@ -574,6 +577,7 @@ "@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/parser": "^5.58.0", "@upstash/redis": "^1.20.6", + "@xata.io/client": "^0.25.1", "@zilliz/milvus2-sdk-node": ">=2.2.7", "apify-client": "^2.7.1", "axios": "^0.26.0", @@ -655,6 +659,7 @@ "@tensorflow/tfjs-core": "*", "@tigrisdata/vector": "^1.1.0", "@upstash/redis": "^1.20.6", + "@xata.io/client": "^0.25.1", "@zilliz/milvus2-sdk-node": ">=2.2.7", "apify-client": "^2.7.1", "axios": "*", @@ -772,6 +777,9 @@ "@upstash/redis": { "optional": true }, + "@xata.io/client": { + "optional": true + }, "@zilliz/milvus2-sdk-node": { "optional": true }, @@ -1267,6 +1275,11 @@ "import": "./vectorstores/vectara.js", "require": "./vectorstores/vectara.cjs" }, + "./vectorstores/xata": { + "types": "./vectorstores/xata.d.ts", + "import": "./vectorstores/xata.js", + "require": "./vectorstores/xata.cjs" + }, "./text_splitter": { "types": "./text_splitter.d.ts", "import": "./text_splitter.js", diff --git a/langchain/scripts/create-entrypoints.js b/langchain/scripts/create-entrypoints.js index bc880032a385..c0eed9b4a0e0 100644 --- a/langchain/scripts/create-entrypoints.js +++ b/langchain/scripts/create-entrypoints.js @@ -84,6 +84,7 @@ const entrypoints = { "vectorstores/singlestore": "vectorstores/singlestore", "vectorstores/tigris": "vectorstores/tigris", "vectorstores/vectara": "vectorstores/vectara", + "vectorstores/xata": "vectorstores/xata", // text_splitter text_splitter: "text_splitter", // memory @@ -197,7 +198,8 @@ const entrypoints = { "experimental/babyagi": "experimental/babyagi/index", "experimental/generative_agents": "experimental/generative_agents/index", "experimental/plan_and_execute": "experimental/plan_and_execute/index", - "experimental/multimodal_embeddings/googlevertexai": "experimental/multimodal_embeddings/googlevertexai", + "experimental/multimodal_embeddings/googlevertexai": + "experimental/multimodal_embeddings/googlevertexai", // evaluation evaluation: "evaluation/index", }; diff --git a/langchain/src/load/import_map.ts b/langchain/src/load/import_map.ts index 885ff58991b0..83e166efdb4f 100644 --- a/langchain/src/load/import_map.ts +++ b/langchain/src/load/import_map.ts @@ -19,6 +19,7 @@ export * as vectorstores__base from "../vectorstores/base.js"; export * as vectorstores__memory from "../vectorstores/memory.js"; export * as vectorstores__prisma from "../vectorstores/prisma.js"; export * as vectorstores__vectara from "../vectorstores/vectara.js"; +export * as vectorstores__xata from "../vectorstores/xata.js"; export * as text_splitter from "../text_splitter.js"; export * as memory from "../memory/index.js"; export * as document from "../document.js"; diff --git a/langchain/src/vectorstores/tests/xata.int.test.ts b/langchain/src/vectorstores/tests/xata.int.test.ts new file mode 100644 index 000000000000..cab301657669 --- /dev/null +++ b/langchain/src/vectorstores/tests/xata.int.test.ts @@ -0,0 +1,161 @@ +/* eslint-disable no-process-env */ +// eslint-disable-next-line import/no-extraneous-dependencies +import { BaseClient } from "@xata.io/client"; + +import { XataVectorSearch } from "../xata.js"; +import { OpenAIEmbeddings } from "../../embeddings/openai.js"; +import { Document } from "../../document.js"; + +test.skip("XataVectorSearch integration", async () => { + if (!process.env.XATA_API_KEY) { + throw new Error("XATA_API_KEY not set"); + } + + if (!process.env.XATA_DB_URL) { + throw new Error("XATA_DB_URL not set"); + } + const xata = new BaseClient({ + databaseURL: process.env.XATA_DB_URL, + apiKey: process.env.XATA_API_KEY, + branch: process.env.XATA_BRANCH || "main", + }); + + const table = "docs"; + const embeddings = new OpenAIEmbeddings(); + + const store = new XataVectorSearch(embeddings, { client: xata, table }); + expect(store).toBeDefined(); + + const createdAt = new Date().getTime(); + + const ids1 = await store.addDocuments([ + { pageContent: "hello", metadata: { a: createdAt + 1 } }, + { pageContent: "car", metadata: { a: createdAt } }, + { pageContent: "adjective", metadata: { a: createdAt } }, + { pageContent: "hi", metadata: { a: createdAt } }, + ]); + + let results1 = await store.similaritySearch("hello!", 1); + + // search store is eventually consistent so we need to retry if nothing is + // returned + for (let i = 0; i < 5 && results1.length === 0; i += 1) { + results1 = await store.similaritySearch("hello!", 1); + // eslint-disable-next-line no-promise-executor-return + await new Promise((r) => setTimeout(r, 1000)); + } + + expect(results1).toHaveLength(1); + expect(results1).toEqual([ + new Document({ metadata: { a: createdAt + 1 }, pageContent: "hello" }), + ]); + + const results2 = await store.similaritySearchWithScore("testing!", 6, { + a: createdAt, + }); + expect(results2).toHaveLength(3); + + const ids2 = await store.addDocuments( + [ + { pageContent: "hello upserted", metadata: { a: createdAt + 1 } }, + { pageContent: "car upserted", metadata: { a: createdAt } }, + { pageContent: "adjective upserted", metadata: { a: createdAt } }, + { pageContent: "hi upserted", metadata: { a: createdAt } }, + ], + { ids: ids1 } + ); + + expect(ids1).toEqual(ids2); + + const results3 = await store.similaritySearchWithScore("testing!", 6, { + a: createdAt, + }); + + expect(results3).toHaveLength(3); + + await store.delete({ ids: ids1.slice(2) }); + + let results4 = await store.similaritySearchWithScore("testing!", 3, { + a: createdAt, + }); + for (let i = 0; i < 5 && results4.length > 1; i += 1) { + results4 = await store.similaritySearchWithScore("testing!", 3, { + a: createdAt, + }); + // eslint-disable-next-line no-promise-executor-return + await new Promise((r) => setTimeout(r, 1000)); + } + + expect(results4).toHaveLength(1); + + await store.delete({ ids: ids1 }); + let results5 = await store.similaritySearch("hello!", 1); + for (let i = 0; i < 5 && results1.length > 0; i += 1) { + results5 = await store.similaritySearch("hello!", 1); + // eslint-disable-next-line no-promise-executor-return + await new Promise((r) => setTimeout(r, 1000)); + } + expect(results5).toHaveLength(0); +}); + +test.skip("Search a XataVectorSearch using a metadata filter", async () => { + if (!process.env.XATA_API_KEY) { + throw new Error("XATA_API_KEY not set"); + } + + if (!process.env.XATA_DB_URL) { + throw new Error("XATA_DB_URL not set"); + } + const xata = new BaseClient({ + databaseURL: process.env.XATA_DB_URL, + apiKey: process.env.XATA_API_KEY, + branch: process.env.XATA_BRANCH || "main", + }); + + const table = "docs"; + const embeddings = new OpenAIEmbeddings(); + + const store = new XataVectorSearch(embeddings, { client: xata, table }); + expect(store).toBeDefined(); + + const createdAt = new Date().getTime(); + + const ids = await store.addDocuments([ + { pageContent: "hello 0", metadata: { a: createdAt } }, + { pageContent: "hello 1", metadata: { a: createdAt + 1 } }, + { pageContent: "hello 2", metadata: { a: createdAt + 2 } }, + { pageContent: "hello 3", metadata: { a: createdAt + 3 } }, + ]); + + // search store is eventually consistent so we need to retry if nothing is + // returned + let results1 = await store.similaritySearch("hello!", 1); + for (let i = 0; i < 5 && results1.length < 4; i += 1) { + results1 = await store.similaritySearch("hello", 6); + // eslint-disable-next-line no-promise-executor-return + await new Promise((r) => setTimeout(r, 1000)); + } + + expect(results1).toHaveLength(4); + + const results = await store.similaritySearch("hello", 1, { + a: createdAt + 2, + }); + expect(results).toHaveLength(1); + + expect(results).toEqual([ + new Document({ + metadata: { a: createdAt + 2 }, + pageContent: "hello 2", + }), + ]); + + await store.delete({ ids }); + let results5 = await store.similaritySearch("hello!", 1); + for (let i = 0; i < 5 && results1.length > 0; i += 1) { + results5 = await store.similaritySearch("hello", 1); + // eslint-disable-next-line no-promise-executor-return + await new Promise((r) => setTimeout(r, 1000)); + } + expect(results5).toHaveLength(0); +}); diff --git a/langchain/src/vectorstores/xata.ts b/langchain/src/vectorstores/xata.ts new file mode 100644 index 000000000000..c0719f25fbb0 --- /dev/null +++ b/langchain/src/vectorstores/xata.ts @@ -0,0 +1,104 @@ +import { BaseClient } from "@xata.io/client"; +import { VectorStore } from "./base.js"; +import { Embeddings } from "../embeddings/base.js"; +import { Document } from "../document.js"; + +export interface XataClientArgs { + readonly client: XataClient; + readonly table: string; +} + +type XataFilter = object; + +export class XataVectorSearch< + XataClient extends BaseClient +> extends VectorStore { + declare FilterType: XataFilter; + + private readonly client: XataClient; + + private readonly table: string; + + _vectorstoreType(): string { + return "xata"; + } + + constructor(embeddings: Embeddings, args: XataClientArgs) { + super(embeddings, args); + + this.client = args.client; + this.table = args.table; + } + + async addDocuments(documents: Document[], options?: { ids?: string[] }) { + const texts = documents.map(({ pageContent }) => pageContent); + return this.addVectors( + await this.embeddings.embedDocuments(texts), + documents, + options + ); + } + + async addVectors( + vectors: number[][], + documents: Document[], + options?: { ids?: string[] } + ) { + const rows = vectors + .map((embedding, idx) => ({ + content: documents[idx].pageContent, + embedding, + ...documents[idx].metadata, + })) + .map((row, idx) => { + if (options?.ids) { + return { id: options.ids[idx], ...row }; + } + return row; + }); + + const res = await this.client.db[this.table].createOrReplace(rows); + // Since we have an untyped BaseClient, it doesn't know the + // actual return type of the overload. + const results = res as unknown as { id: string }[]; + const returnedIds = results.map((row) => row.id); + return returnedIds; + } + + async delete(params: { ids: string[] }): Promise { + const { ids } = params; + await this.client.db[this.table].delete(ids); + } + + async similaritySearchVectorWithScore( + query: number[], + k: number, + filter?: XataFilter | undefined + ): Promise<[Document, number][]> { + const records = await this.client.db[this.table].vectorSearch( + "embedding", + query, + { + size: k, + filter, + } + ); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return records.map((record: any) => [ + new Document({ + pageContent: record.content, + metadata: Object.fromEntries( + Object.entries(record).filter( + ([key]) => + key !== "content" && + key !== "embedding" && + key !== "xata" && + key !== "id" + ) + ), + }), + record.xata.score, + ]); + } +} diff --git a/langchain/tsconfig.json b/langchain/tsconfig.json index 11f09c28eac5..63eddb521200 100644 --- a/langchain/tsconfig.json +++ b/langchain/tsconfig.json @@ -97,6 +97,7 @@ "src/vectorstores/singlestore.ts", "src/vectorstores/tigris.ts", "src/vectorstores/vectara.ts", + "src/vectorstores/xata.ts", "src/text_splitter.ts", "src/memory/index.ts", "src/memory/zep.ts", diff --git a/test-exports-cf/src/entrypoints.js b/test-exports-cf/src/entrypoints.js index 7a28aa29f78d..a583ff422a4e 100644 --- a/test-exports-cf/src/entrypoints.js +++ b/test-exports-cf/src/entrypoints.js @@ -18,6 +18,7 @@ export * from "langchain/vectorstores/base"; export * from "langchain/vectorstores/memory"; export * from "langchain/vectorstores/prisma"; export * from "langchain/vectorstores/vectara"; +export * from "langchain/vectorstores/xata"; export * from "langchain/text_splitter"; export * from "langchain/memory"; export * from "langchain/document"; diff --git a/test-exports-cjs/src/entrypoints.js b/test-exports-cjs/src/entrypoints.js index ded8b3398217..d4b316f47d94 100644 --- a/test-exports-cjs/src/entrypoints.js +++ b/test-exports-cjs/src/entrypoints.js @@ -18,6 +18,7 @@ const vectorstores_base = require("langchain/vectorstores/base"); const vectorstores_memory = require("langchain/vectorstores/memory"); const vectorstores_prisma = require("langchain/vectorstores/prisma"); const vectorstores_vectara = require("langchain/vectorstores/vectara"); +const vectorstores_xata = require("langchain/vectorstores/xata"); const text_splitter = require("langchain/text_splitter"); const memory = require("langchain/memory"); const document = require("langchain/document"); diff --git a/test-exports-esbuild/src/entrypoints.js b/test-exports-esbuild/src/entrypoints.js index 92dc77f660e7..afb2fb7b79c6 100644 --- a/test-exports-esbuild/src/entrypoints.js +++ b/test-exports-esbuild/src/entrypoints.js @@ -18,6 +18,7 @@ import * as vectorstores_base from "langchain/vectorstores/base"; import * as vectorstores_memory from "langchain/vectorstores/memory"; import * as vectorstores_prisma from "langchain/vectorstores/prisma"; import * as vectorstores_vectara from "langchain/vectorstores/vectara"; +import * as vectorstores_xata from "langchain/vectorstores/xata"; import * as text_splitter from "langchain/text_splitter"; import * as memory from "langchain/memory"; import * as document from "langchain/document"; diff --git a/test-exports-esm/src/entrypoints.js b/test-exports-esm/src/entrypoints.js index 92dc77f660e7..afb2fb7b79c6 100644 --- a/test-exports-esm/src/entrypoints.js +++ b/test-exports-esm/src/entrypoints.js @@ -18,6 +18,7 @@ import * as vectorstores_base from "langchain/vectorstores/base"; import * as vectorstores_memory from "langchain/vectorstores/memory"; import * as vectorstores_prisma from "langchain/vectorstores/prisma"; import * as vectorstores_vectara from "langchain/vectorstores/vectara"; +import * as vectorstores_xata from "langchain/vectorstores/xata"; import * as text_splitter from "langchain/text_splitter"; import * as memory from "langchain/memory"; import * as document from "langchain/document"; diff --git a/test-exports-vercel/src/entrypoints.js b/test-exports-vercel/src/entrypoints.js index 7a28aa29f78d..a583ff422a4e 100644 --- a/test-exports-vercel/src/entrypoints.js +++ b/test-exports-vercel/src/entrypoints.js @@ -18,6 +18,7 @@ export * from "langchain/vectorstores/base"; export * from "langchain/vectorstores/memory"; export * from "langchain/vectorstores/prisma"; export * from "langchain/vectorstores/vectara"; +export * from "langchain/vectorstores/xata"; export * from "langchain/text_splitter"; export * from "langchain/memory"; export * from "langchain/document"; diff --git a/test-exports-vite/src/entrypoints.js b/test-exports-vite/src/entrypoints.js index 7a28aa29f78d..a583ff422a4e 100644 --- a/test-exports-vite/src/entrypoints.js +++ b/test-exports-vite/src/entrypoints.js @@ -18,6 +18,7 @@ export * from "langchain/vectorstores/base"; export * from "langchain/vectorstores/memory"; export * from "langchain/vectorstores/prisma"; export * from "langchain/vectorstores/vectara"; +export * from "langchain/vectorstores/xata"; export * from "langchain/text_splitter"; export * from "langchain/memory"; export * from "langchain/document"; diff --git a/yarn.lock b/yarn.lock index a72091b35c10..804243f7636c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6786,6 +6786,15 @@ __metadata: languageName: node linkType: hard +"@xata.io/client@npm:^0.25.1": + version: 0.25.1 + resolution: "@xata.io/client@npm:0.25.1" + peerDependencies: + typescript: ">=4.5" + checksum: 041988667b19e84a4af27b8abb6c3ca79904df595a687e4a8cd19ce0c1e3d180781fb2e54ba55de2217893f76b05048cffa99d171034f9a4229d694904d43bcd + languageName: node + linkType: hard + "@zilliz/milvus2-sdk-node@npm:>=2.2.7, @zilliz/milvus2-sdk-node@npm:^2.2.7": version: 2.2.10 resolution: "@zilliz/milvus2-sdk-node@npm:2.2.10" @@ -10060,6 +10069,7 @@ __metadata: "@typescript-eslint/eslint-plugin": ^5.51.0 "@typescript-eslint/parser": ^5.51.0 "@upstash/redis": ^1.20.6 + "@xata.io/client": ^0.25.1 "@zilliz/milvus2-sdk-node": ^2.2.7 axios: ^0.26.0 chromadb: ^1.4.0 @@ -13137,6 +13147,7 @@ __metadata: "@typescript-eslint/eslint-plugin": ^5.58.0 "@typescript-eslint/parser": ^5.58.0 "@upstash/redis": ^1.20.6 + "@xata.io/client": ^0.25.1 "@zilliz/milvus2-sdk-node": ">=2.2.7" ansi-styles: ^5.0.0 apify-client: ^2.7.1 @@ -13237,6 +13248,7 @@ __metadata: "@tensorflow/tfjs-core": "*" "@tigrisdata/vector": ^1.1.0 "@upstash/redis": ^1.20.6 + "@xata.io/client": ^0.25.1 "@zilliz/milvus2-sdk-node": ">=2.2.7" apify-client: ^2.7.1 axios: "*" @@ -13326,6 +13338,8 @@ __metadata: optional: true "@upstash/redis": optional: true + "@xata.io/client": + optional: true "@zilliz/milvus2-sdk-node": optional: true apify-client: