From a610472fd477c78e27e33a0ac0b6d49a99986b0d Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Thu, 23 Mar 2023 02:27:42 +0100 Subject: [PATCH 01/11] Add implementation of Prisma vectorstore --- langchain/package.json | 2 + langchain/src/vectorstores/prisma.ts | 133 +++++++++++++++++++++++++++ yarn.lock | 22 +++++ 3 files changed, 157 insertions(+) create mode 100644 langchain/src/vectorstores/prisma.ts diff --git a/langchain/package.json b/langchain/package.json index ecdc89791e1f..3d36021f8088 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -108,6 +108,7 @@ "@jest/globals": "^29.5.0", "@pinecone-database/pinecone": "^0.0.10", "@supabase/supabase-js": "^2.10.0", + "@prisma/client": "^4.11.0", "@tsconfig/recommended": "^1.0.2", "@types/d3-dsv": "^2", "@types/flat": "^5.0.2", @@ -156,6 +157,7 @@ "@huggingface/inference": "^1.5.1", "@pinecone-database/pinecone": "^0.0.10", "@supabase/supabase-js": "^2.10.0", + "@prisma/client": "^4.11.0", "cheerio": "^1.0.0-rc.12", "chromadb": "^1.3.0", "cohere-ai": "^5.0.2", diff --git a/langchain/src/vectorstores/prisma.ts b/langchain/src/vectorstores/prisma.ts new file mode 100644 index 000000000000..7825aece40cd --- /dev/null +++ b/langchain/src/vectorstores/prisma.ts @@ -0,0 +1,133 @@ +import { VectorStore } from "../vectorstores"; +import { Document } from "../document"; +import { type Embeddings } from "../embeddings"; + +export const TypeId = Symbol("id"); +export const TypeColumn = Symbol("content"); + +type BasicColumnType = typeof TypeId | typeof TypeColumn; + +namespace Prisma { + declare type Value = unknown; + declare type RawValue = Value | Sql; + + export declare class Sql { + strings: string[]; + constructor( + rawStrings: ReadonlyArray, + rawValues: ReadonlyArray + ); + } +} + +type PrismaNamespace = { + ModelName: Record; + Sql: typeof Prisma.Sql; + raw: (sql: string) => Prisma.Sql; +}; + +type PrismaClient = { + $queryRaw( + query: TemplateStringsArray | Prisma.Sql, + ...values: any[] + ): Promise; + $executeRaw( + query: TemplateStringsArray | Prisma.Sql, + ...values: any[] + ): Promise; + $transaction

[]>(arg: [...P]): Promise; +}; + +export class PrismaVectorStore< + TModel extends Record = Record, + TModelName extends string = string +> extends VectorStore { + tableSql: Prisma.Sql; + vectorColumnSql: Prisma.Sql; + selectSql: Prisma.Sql; + + idColumn: keyof TModel; + contentColumn: keyof TModel; + + constructor( + protected db: PrismaClient, + protected Prisma: PrismaNamespace, + config: { + tableName: TModelName; + vectorColumnName: string; + columns: { + [K in keyof TModel]?: boolean | BasicColumnType; + }; + }, + embeddings: Embeddings + ) { + super(embeddings, {}); + + const entries = Object.entries(config.columns); + this.idColumn = entries.find((i) => i[1] === TypeId)?.[0]!; + this.contentColumn = entries.find((i) => i[1] === TypeColumn)?.[0]!; + + this.tableSql = Prisma.raw(`"${config.tableName}"`); + this.vectorColumnSql = Prisma.raw(`"${config.vectorColumnName}"`); + + this.selectSql = Prisma.raw( + entries + .map(([key, alias]) => (alias && key) || null) + .filter((x): x is string => !!x) + .map((key) => `"${key}"`) + .join(", ") + ); + } + + async addDocuments(documents: Document[]) { + const texts = documents.map(({ pageContent }) => pageContent); + return this.addVectors( + await this.embeddings.embedDocuments(texts), + documents + ); + } + + async addVectors(vectors: number[][], documents: Document[]) { + const idSql = this.Prisma.raw(`"${this.idColumn as string}"`); + + this.db.$transaction( + vectors.map( + (vector) => this.db.$executeRaw` + UPDATE ${this.tableSql} + SET ${this.vectorColumnSql} = ${`[${vector.join(",")}]`}::vector + WHERE ${idSql} = ${documents[0].metadata.id} + ` + ) + ); + } + + async similaritySearchVectorWithScore( + query: number[], + k: number + ): Promise<[Document, number][]> { + const vectorQuery = `[${query.join(",")}]`; + const articles = await this.db.$queryRaw< + Array + >` + SELECT ${this.selectSql}, ${this.vectorColumnSql} <=> ${vectorQuery}::vector as "_distance" + FROM ${this.tableSql} + ORDER BY "_distance" ASC + LIMIT ${k}; + `; + + const results: [Document, number][] = []; + for (const article of articles) { + if (article._distance != null) { + results.push([ + new Document({ + pageContent: article[this.contentColumn] as string | undefined, + metadata: article, + }), + article._distance, + ]); + } + } + + return results; + } +} diff --git a/yarn.lock b/yarn.lock index 7c22527aa942..492b9119842f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3223,6 +3223,27 @@ __metadata: languageName: node linkType: hard +"@prisma/client@npm:^4.11.0": + version: 4.11.0 + resolution: "@prisma/client@npm:4.11.0" + dependencies: + "@prisma/engines-version": 4.11.0-57.8fde8fef4033376662cad983758335009d522acb + peerDependencies: + prisma: "*" + peerDependenciesMeta: + prisma: + optional: true + checksum: ca8d8f820caaf4a76b94674f88207d5bb14f57a9682d37d2f79c56378f259cd3b14b30a110ab59a97647fcf3c46f896e7a2d20ded2777e09b835d7accd70cf1d + languageName: node + linkType: hard + +"@prisma/engines-version@npm:4.11.0-57.8fde8fef4033376662cad983758335009d522acb": + version: 4.11.0-57.8fde8fef4033376662cad983758335009d522acb + resolution: "@prisma/engines-version@npm:4.11.0-57.8fde8fef4033376662cad983758335009d522acb" + checksum: f040b93d09b21feaef193080eed22142fa26b3cf86d089ebb4286f5f45ed17a98e030a8bb55c0bec2892e15880a697f6754c6966b7795cf7ba4553f59fb387e7 + languageName: node + linkType: hard + "@redis/bloom@npm:1.2.0": version: 1.2.0 resolution: "@redis/bloom@npm:1.2.0" @@ -11453,6 +11474,7 @@ __metadata: "@huggingface/inference": ^1.5.1 "@jest/globals": ^29.5.0 "@pinecone-database/pinecone": ^0.0.10 + "@prisma/client": ^4.11.0 "@supabase/supabase-js": ^2.10.0 "@tsconfig/recommended": ^1.0.2 "@types/d3-dsv": ^2 From 2563b78b907a914d021a661afc8d7b77147c636a Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Thu, 23 Mar 2023 02:29:00 +0100 Subject: [PATCH 02/11] Fix CI --- langchain/package.json | 4 ++-- yarn.lock | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/langchain/package.json b/langchain/package.json index 3d36021f8088..5db9be1b0206 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -107,8 +107,8 @@ "@huggingface/inference": "^1.5.1", "@jest/globals": "^29.5.0", "@pinecone-database/pinecone": "^0.0.10", - "@supabase/supabase-js": "^2.10.0", "@prisma/client": "^4.11.0", + "@supabase/supabase-js": "^2.10.0", "@tsconfig/recommended": "^1.0.2", "@types/d3-dsv": "^2", "@types/flat": "^5.0.2", @@ -156,8 +156,8 @@ "@getmetal/metal-sdk": "*", "@huggingface/inference": "^1.5.1", "@pinecone-database/pinecone": "^0.0.10", - "@supabase/supabase-js": "^2.10.0", "@prisma/client": "^4.11.0", + "@supabase/supabase-js": "^2.10.0", "cheerio": "^1.0.0-rc.12", "chromadb": "^1.3.0", "cohere-ai": "^5.0.2", diff --git a/yarn.lock b/yarn.lock index 492b9119842f..32a4bc46b79b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11534,6 +11534,7 @@ __metadata: "@getmetal/metal-sdk": "*" "@huggingface/inference": ^1.5.1 "@pinecone-database/pinecone": ^0.0.10 + "@prisma/client": ^4.11.0 "@supabase/supabase-js": ^2.10.0 cheerio: ^1.0.0-rc.12 chromadb: ^1.3.0 From 7aa9c129c8d88f9a6746b83c49f987f7a261d476 Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Thu, 23 Mar 2023 02:39:22 +0100 Subject: [PATCH 03/11] FIx lint issues --- langchain/package.json | 2 +- langchain/src/vectorstores/prisma.ts | 62 +++++++++++++++++----------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/langchain/package.json b/langchain/package.json index 5db9be1b0206..c50af097ef5b 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -379,4 +379,4 @@ }, "./package.json": "./package.json" } -} +} \ No newline at end of file diff --git a/langchain/src/vectorstores/prisma.ts b/langchain/src/vectorstores/prisma.ts index 7825aece40cd..324f42d3a2fb 100644 --- a/langchain/src/vectorstores/prisma.ts +++ b/langchain/src/vectorstores/prisma.ts @@ -1,40 +1,43 @@ -import { VectorStore } from "../vectorstores"; -import { Document } from "../document"; -import { type Embeddings } from "../embeddings"; +import { VectorStore } from "./base.js"; +import { Document } from "../document.js"; +import { type Embeddings } from "../embeddings/base.js"; export const TypeId = Symbol("id"); export const TypeColumn = Symbol("content"); type BasicColumnType = typeof TypeId | typeof TypeColumn; -namespace Prisma { - declare type Value = unknown; - declare type RawValue = Value | Sql; +declare type Value = unknown; +declare type RawValue = Value | Sql; - export declare class Sql { - strings: string[]; - constructor( - rawStrings: ReadonlyArray, - rawValues: ReadonlyArray - ); - } +declare class Sql { + strings: string[]; + + constructor( + rawStrings: ReadonlyArray, + rawValues: ReadonlyArray + ); } type PrismaNamespace = { ModelName: Record; - Sql: typeof Prisma.Sql; - raw: (sql: string) => Prisma.Sql; + Sql: typeof Sql; + raw: (sql: string) => Sql; }; type PrismaClient = { $queryRaw( - query: TemplateStringsArray | Prisma.Sql, + query: TemplateStringsArray | Sql, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ...values: any[] ): Promise; $executeRaw( - query: TemplateStringsArray | Prisma.Sql, + query: TemplateStringsArray | Sql, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ...values: any[] - ): Promise; + ): // eslint-disable-next-line @typescript-eslint/no-explicit-any + Promise; + // eslint-disable-next-line @typescript-eslint/no-explicit-any $transaction

[]>(arg: [...P]): Promise; }; @@ -42,11 +45,14 @@ export class PrismaVectorStore< TModel extends Record = Record, TModelName extends string = string > extends VectorStore { - tableSql: Prisma.Sql; - vectorColumnSql: Prisma.Sql; - selectSql: Prisma.Sql; + tableSql: Sql; + + vectorColumnSql: Sql; + + selectSql: Sql; idColumn: keyof TModel; + contentColumn: keyof TModel; constructor( @@ -64,8 +70,14 @@ export class PrismaVectorStore< super(embeddings, {}); const entries = Object.entries(config.columns); - this.idColumn = entries.find((i) => i[1] === TypeId)?.[0]!; - this.contentColumn = entries.find((i) => i[1] === TypeColumn)?.[0]!; + const idColumn = entries.find((i) => i[1] === TypeId)?.[0]; + const contentColumn = entries.find((i) => i[1] === TypeColumn)?.[0]; + + if (idColumn == null) throw new Error("Missing ID column"); + if (contentColumn == null) throw new Error("Missing content column"); + + this.idColumn = idColumn; + this.contentColumn = contentColumn; this.tableSql = Prisma.raw(`"${config.tableName}"`); this.vectorColumnSql = Prisma.raw(`"${config.vectorColumnName}"`); @@ -81,6 +93,8 @@ export class PrismaVectorStore< async addDocuments(documents: Document[]) { const texts = documents.map(({ pageContent }) => pageContent); + + // TODO: add documents to database return this.addVectors( await this.embeddings.embedDocuments(texts), documents @@ -90,7 +104,7 @@ export class PrismaVectorStore< async addVectors(vectors: number[][], documents: Document[]) { const idSql = this.Prisma.raw(`"${this.idColumn as string}"`); - this.db.$transaction( + await this.db.$transaction( vectors.map( (vector) => this.db.$executeRaw` UPDATE ${this.tableSql} From 80124870c22cf547c79ca5c716a3c66e0f73bfa4 Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Thu, 23 Mar 2023 02:42:00 +0100 Subject: [PATCH 04/11] FIx incorrect index for addVectors --- langchain/src/vectorstores/prisma.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/langchain/src/vectorstores/prisma.ts b/langchain/src/vectorstores/prisma.ts index 324f42d3a2fb..572dcb1cc781 100644 --- a/langchain/src/vectorstores/prisma.ts +++ b/langchain/src/vectorstores/prisma.ts @@ -106,10 +106,10 @@ export class PrismaVectorStore< await this.db.$transaction( vectors.map( - (vector) => this.db.$executeRaw` + (vector, idx) => this.db.$executeRaw` UPDATE ${this.tableSql} SET ${this.vectorColumnSql} = ${`[${vector.join(",")}]`}::vector - WHERE ${idSql} = ${documents[0].metadata.id} + WHERE ${idSql} = ${documents[idx].metadata.id} ` ) ); From 449b50f4d793e3898e473275af14a4ea4ca839d6 Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Sat, 25 Mar 2023 15:33:50 +0100 Subject: [PATCH 05/11] Add example to Prisma --- examples/package.json | 2 + .../prisma_vectorstore/.env.example | 2 + .../prisma_vectorstore/.gitignore | 2 + .../docker-compose.example.yml | 11 +++++ .../prisma_vectorstore/prisma.ts | 43 +++++++++++++++++++ .../prisma/migrations/00_init/migration.sql | 9 ++++ .../prisma/migrations/migration_lock.toml | 3 ++ .../prisma_vectorstore/prisma/schema.prisma | 17 ++++++++ langchain/package.json | 2 +- langchain/src/document.ts | 21 +++++---- langchain/src/vectorstores/index.ts | 5 +++ langchain/src/vectorstores/prisma.ts | 31 ++++++++----- yarn.lock | 21 +++++++++ 13 files changed, 149 insertions(+), 20 deletions(-) create mode 100644 examples/src/indexes/vector_stores/prisma_vectorstore/.env.example create mode 100644 examples/src/indexes/vector_stores/prisma_vectorstore/.gitignore create mode 100644 examples/src/indexes/vector_stores/prisma_vectorstore/docker-compose.example.yml create mode 100644 examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts create mode 100644 examples/src/indexes/vector_stores/prisma_vectorstore/prisma/migrations/00_init/migration.sql create mode 100644 examples/src/indexes/vector_stores/prisma_vectorstore/prisma/migrations/migration_lock.toml create mode 100644 examples/src/indexes/vector_stores/prisma_vectorstore/prisma/schema.prisma diff --git a/examples/package.json b/examples/package.json index 72df0ad3cc42..b98b207cfc12 100644 --- a/examples/package.json +++ b/examples/package.json @@ -23,10 +23,12 @@ "@dqbd/tiktoken": "^1.0.2", "@getmetal/metal-sdk": "^1.0.12", "@pinecone-database/pinecone": "^0.0.10", + "@prisma/client": "^4.11.0", "@supabase/supabase-js": "^2.10.0", "chromadb": "^1.3.0", "js-yaml": "^4.1.0", "langchain": "workspace:*", + "prisma": "^4.11.0", "sqlite3": "^5.1.4", "typeorm": "^0.3.12", "zod": "^3.21.4" diff --git a/examples/src/indexes/vector_stores/prisma_vectorstore/.env.example b/examples/src/indexes/vector_stores/prisma_vectorstore/.env.example new file mode 100644 index 000000000000..56822a6c7017 --- /dev/null +++ b/examples/src/indexes/vector_stores/prisma_vectorstore/.env.example @@ -0,0 +1,2 @@ +# Add DATABASE_URL to .env file in this directory +DATABASE_URL=postgresql://[USERNAME]:[PASSWORD]@[ADDR]/[DBNAME] \ No newline at end of file diff --git a/examples/src/indexes/vector_stores/prisma_vectorstore/.gitignore b/examples/src/indexes/vector_stores/prisma_vectorstore/.gitignore new file mode 100644 index 000000000000..fc1505015fe4 --- /dev/null +++ b/examples/src/indexes/vector_stores/prisma_vectorstore/.gitignore @@ -0,0 +1,2 @@ +data +docker-compose.yml \ No newline at end of file diff --git a/examples/src/indexes/vector_stores/prisma_vectorstore/docker-compose.example.yml b/examples/src/indexes/vector_stores/prisma_vectorstore/docker-compose.example.yml new file mode 100644 index 000000000000..cdebd387e666 --- /dev/null +++ b/examples/src/indexes/vector_stores/prisma_vectorstore/docker-compose.example.yml @@ -0,0 +1,11 @@ +services: + db: + image: ankane/pgvector + ports: + - 5432:5432 + volumes: + - ./data:/var/lib/postgresql/data + environment: + - POSTGRES_PASSWORD= + - POSTGRES_USER= + - POSTGRES_DB= \ No newline at end of file diff --git a/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts new file mode 100644 index 000000000000..cc32dc060327 --- /dev/null +++ b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts @@ -0,0 +1,43 @@ +import { + PrismaTypeContent, + PrismaTypeId, + PrismaVectorStore, +} from "langchain/vectorstores"; +import { OpenAIEmbeddings } from "langchain/embeddings"; +import { + PrismaClient, + Prisma, + Document as PrismaDocument, +} from "@prisma/client"; +import { Document } from "langchain/document"; + +export const run = async () => { + const client = new PrismaClient(); + + const vectorStore = new PrismaVectorStore( + { + tableName: "Document", + columns: { id: PrismaTypeId, content: PrismaTypeContent }, + vectorColumnName: "vector", + }, + client, + Prisma, + new OpenAIEmbeddings() + ); + + const texts = ["Hello world", "Bye bye", "What's this?"]; + + const data = await client.$transaction(async (tx) => + Promise.all( + texts.map(async (content) => { + const metadata = await tx.document.create({ data: { content } }); + return new Document({ pageContent: metadata.content, metadata }); + }) + ) + ); + + await vectorStore.addDocuments(data); + const resultOne = await vectorStore.similaritySearch("Hello world", 1); + + console.log(resultOne); +}; diff --git a/examples/src/indexes/vector_stores/prisma_vectorstore/prisma/migrations/00_init/migration.sql b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma/migrations/00_init/migration.sql new file mode 100644 index 000000000000..a78a52760042 --- /dev/null +++ b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma/migrations/00_init/migration.sql @@ -0,0 +1,9 @@ +-- CreateTable +CREATE EXTENSION IF NOT EXISTS vector; +CREATE TABLE "Document" ( + "id" TEXT NOT NULL, + "content" TEXT NOT NULL, + "vector" vector, + + CONSTRAINT "Document_pkey" PRIMARY KEY ("id") +); diff --git a/examples/src/indexes/vector_stores/prisma_vectorstore/prisma/migrations/migration_lock.toml b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma/migrations/migration_lock.toml new file mode 100644 index 000000000000..fbffa92c2bb7 --- /dev/null +++ b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/examples/src/indexes/vector_stores/prisma_vectorstore/prisma/schema.prisma b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma/schema.prisma new file mode 100644 index 000000000000..4171076f2d1b --- /dev/null +++ b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma/schema.prisma @@ -0,0 +1,17 @@ +// This is your Prisma schema file, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model Document { + id String @id @default(cuid()) + content String + vector Unsupported("vector")? +} diff --git a/langchain/package.json b/langchain/package.json index c50af097ef5b..5db9be1b0206 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -379,4 +379,4 @@ }, "./package.json": "./package.json" } -} \ No newline at end of file +} diff --git a/langchain/src/document.ts b/langchain/src/document.ts index 278bce28d1be..bfc05bf047e4 100644 --- a/langchain/src/document.ts +++ b/langchain/src/document.ts @@ -1,21 +1,26 @@ -export interface DocumentParams { +export interface DocumentParams< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Metadata extends Record = Record +> { pageContent: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - metadata: Record; + metadata: Metadata; } /** * Interface for interacting with a document. */ -export class Document implements DocumentParams { +export class Document< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Metadata extends Record = Record +> implements DocumentParams +{ pageContent: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - metadata: Record; + metadata: Metadata; - constructor(fields?: Partial) { + constructor(fields?: Partial>) { this.pageContent = fields?.pageContent ?? this.pageContent; - this.metadata = fields?.metadata ?? {}; + this.metadata = fields?.metadata ?? ({} as Metadata); } } diff --git a/langchain/src/vectorstores/index.ts b/langchain/src/vectorstores/index.ts index 98f3f51e24ff..fe95e02493c4 100644 --- a/langchain/src/vectorstores/index.ts +++ b/langchain/src/vectorstores/index.ts @@ -3,3 +3,8 @@ export { Chroma } from "./chroma.js"; export { PineconeStore } from "./pinecone.js"; export { VectorStore, SaveableVectorStore } from "./base.js"; export { SupabaseVectorStore } from "./supabase.js"; +export { + PrismaVectorStore, + PrismaTypeId, + PrismaTypeContent, +} from "./prisma.js"; diff --git a/langchain/src/vectorstores/prisma.ts b/langchain/src/vectorstores/prisma.ts index 572dcb1cc781..881dfb7ab025 100644 --- a/langchain/src/vectorstores/prisma.ts +++ b/langchain/src/vectorstores/prisma.ts @@ -2,10 +2,10 @@ import { VectorStore } from "./base.js"; import { Document } from "../document.js"; import { type Embeddings } from "../embeddings/base.js"; -export const TypeId = Symbol("id"); -export const TypeColumn = Symbol("content"); +export const PrismaTypeId = Symbol("id"); +export const PrismaTypeContent = Symbol("content"); -type BasicColumnType = typeof TypeId | typeof TypeColumn; +type BasicColumnType = typeof PrismaTypeId | typeof PrismaTypeContent; declare type Value = unknown; declare type RawValue = Value | Sql; @@ -56,8 +56,6 @@ export class PrismaVectorStore< contentColumn: keyof TModel; constructor( - protected db: PrismaClient, - protected Prisma: PrismaNamespace, config: { tableName: TModelName; vectorColumnName: string; @@ -65,13 +63,15 @@ export class PrismaVectorStore< [K in keyof TModel]?: boolean | BasicColumnType; }; }, + protected db: PrismaClient, + protected Prisma: PrismaNamespace, embeddings: Embeddings ) { super(embeddings, {}); const entries = Object.entries(config.columns); - const idColumn = entries.find((i) => i[1] === TypeId)?.[0]; - const contentColumn = entries.find((i) => i[1] === TypeColumn)?.[0]; + const idColumn = entries.find((i) => i[1] === PrismaTypeId)?.[0]; + const contentColumn = entries.find((i) => i[1] === PrismaTypeContent)?.[0]; if (idColumn == null) throw new Error("Missing ID column"); if (contentColumn == null) throw new Error("Missing content column"); @@ -91,7 +91,7 @@ export class PrismaVectorStore< ); } - async addDocuments(documents: Document[]) { + async addDocuments(documents: Document[]) { const texts = documents.map(({ pageContent }) => pageContent); // TODO: add documents to database @@ -101,7 +101,7 @@ export class PrismaVectorStore< ); } - async addVectors(vectors: number[][], documents: Document[]) { + async addVectors(vectors: number[][], documents: Document[]) { const idSql = this.Prisma.raw(`"${this.idColumn as string}"`); await this.db.$transaction( @@ -115,10 +115,19 @@ export class PrismaVectorStore< ); } + async similaritySearch(query: string, k = 4): Promise[]> { + const results = await this.similaritySearchVectorWithScore( + await this.embeddings.embedQuery(query), + k + ); + + return results.map((result) => result[0]); + } + async similaritySearchVectorWithScore( query: number[], k: number - ): Promise<[Document, number][]> { + ): Promise<[Document, number][]> { const vectorQuery = `[${query.join(",")}]`; const articles = await this.db.$queryRaw< Array @@ -129,7 +138,7 @@ export class PrismaVectorStore< LIMIT ${k}; `; - const results: [Document, number][] = []; + const results: [Document, number][] = []; for (const article of articles) { if (article._distance != null) { results.push([ diff --git a/yarn.lock b/yarn.lock index 32a4bc46b79b..aed52620bad0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3244,6 +3244,13 @@ __metadata: languageName: node linkType: hard +"@prisma/engines@npm:4.11.0": + version: 4.11.0 + resolution: "@prisma/engines@npm:4.11.0" + checksum: 98030cead39e5009b7a91fd2463433ccdb16cbeb6c7345ed7950c25dbe0731a425fc888458a1423b594d659972e081ca3d63d301ef647f05a634209c75769db2 + languageName: node + linkType: hard + "@redis/bloom@npm:1.2.0": version: 1.2.0 resolution: "@redis/bloom@npm:1.2.0" @@ -11437,6 +11444,7 @@ __metadata: "@dqbd/tiktoken": ^1.0.2 "@getmetal/metal-sdk": ^1.0.12 "@pinecone-database/pinecone": ^0.0.10 + "@prisma/client": ^4.11.0 "@supabase/supabase-js": ^2.10.0 "@tsconfig/recommended": ^1.0.2 "@types/js-yaml": ^4 @@ -11452,6 +11460,7 @@ __metadata: js-yaml: ^4.1.0 langchain: "workspace:*" prettier: ^2.8.3 + prisma: ^4.11.0 sqlite3: ^5.1.4 tsx: ^3.12.3 typeorm: ^0.3.12 @@ -14155,6 +14164,18 @@ __metadata: languageName: node linkType: hard +"prisma@npm:^4.11.0": + version: 4.11.0 + resolution: "prisma@npm:4.11.0" + dependencies: + "@prisma/engines": 4.11.0 + bin: + prisma: build/index.js + prisma2: build/index.js + checksum: 760d80766ae16ad2d25cfc20d75433b020dff0937eab864b94b95beadd89e481508e4d3c6370a5df90749d5ac5c7af77c9c2f293b74bfdee0e548b04a905c2e7 + languageName: node + linkType: hard + "prismjs@npm:^1.28.0": version: 1.29.0 resolution: "prismjs@npm:1.29.0" From 3da79eec6ff9f018920d12bf2e6b6bc73292c383 Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Sat, 25 Mar 2023 17:55:09 +0100 Subject: [PATCH 06/11] Fix returned types --- examples/package.json | 1 + .../prisma_vectorstore/prisma.ts | 39 ++--- langchain/src/vectorstores/index.ts | 6 +- langchain/src/vectorstores/prisma.ts | 143 +++++++++++++++--- 4 files changed, 133 insertions(+), 56 deletions(-) diff --git a/examples/package.json b/examples/package.json index b98b207cfc12..d6c907dd73ab 100644 --- a/examples/package.json +++ b/examples/package.json @@ -11,6 +11,7 @@ "scripts": { "build": "tsc --declaration --outDir dist/", "start": "tsx -r dotenv/config src/index.ts", + "postinstall": "prisma generate --schema ./src/indexes/vector_stores/prisma_vectorstore/prisma/schema.prisma", "start:dist": "yarn build && node -r dotenv/config dist/index.js", "lint": "eslint src", "lint:fix": "yarn lint --fix", diff --git a/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts index cc32dc060327..53e26649abec 100644 --- a/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts +++ b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts @@ -1,43 +1,30 @@ -import { - PrismaTypeContent, - PrismaTypeId, - PrismaVectorStore, -} from "langchain/vectorstores"; +import { PrismaVectorStore } from "langchain/vectorstores"; import { OpenAIEmbeddings } from "langchain/embeddings"; -import { - PrismaClient, - Prisma, - Document as PrismaDocument, -} from "@prisma/client"; -import { Document } from "langchain/document"; +import { PrismaClient, Prisma, Document } from "@prisma/client"; export const run = async () => { - const client = new PrismaClient(); + const db = new PrismaClient(); - const vectorStore = new PrismaVectorStore( + const vectorStore = PrismaVectorStore.withModel(db).create( { + prisma: Prisma, tableName: "Document", - columns: { id: PrismaTypeId, content: PrismaTypeContent }, vectorColumnName: "vector", + columns: { + id: PrismaVectorStore.IdColumn, + content: PrismaVectorStore.ContentColumn, + }, }, - client, - Prisma, new OpenAIEmbeddings() ); const texts = ["Hello world", "Bye bye", "What's this?"]; - - const data = await client.$transaction(async (tx) => - Promise.all( - texts.map(async (content) => { - const metadata = await tx.document.create({ data: { content } }); - return new Document({ pageContent: metadata.content, metadata }); - }) + await vectorStore.addModels( + await db.$transaction( + texts.map((content) => db.document.create({ data: { content } })) ) ); - await vectorStore.addDocuments(data); const resultOne = await vectorStore.similaritySearch("Hello world", 1); - - console.log(resultOne); + console.log(resultOne.at(0)?.metadata.content); }; diff --git a/langchain/src/vectorstores/index.ts b/langchain/src/vectorstores/index.ts index fe95e02493c4..5834faed9194 100644 --- a/langchain/src/vectorstores/index.ts +++ b/langchain/src/vectorstores/index.ts @@ -3,8 +3,4 @@ export { Chroma } from "./chroma.js"; export { PineconeStore } from "./pinecone.js"; export { VectorStore, SaveableVectorStore } from "./base.js"; export { SupabaseVectorStore } from "./supabase.js"; -export { - PrismaVectorStore, - PrismaTypeId, - PrismaTypeContent, -} from "./prisma.js"; +export { PrismaVectorStore } from "./prisma.js"; diff --git a/langchain/src/vectorstores/prisma.ts b/langchain/src/vectorstores/prisma.ts index 881dfb7ab025..82e8675e2e07 100644 --- a/langchain/src/vectorstores/prisma.ts +++ b/langchain/src/vectorstores/prisma.ts @@ -2,10 +2,10 @@ import { VectorStore } from "./base.js"; import { Document } from "../document.js"; import { type Embeddings } from "../embeddings/base.js"; -export const PrismaTypeId = Symbol("id"); -export const PrismaTypeContent = Symbol("content"); +const IdColumnSymbol = Symbol("id"); +const ContentColumnSymbol = Symbol("content"); -type BasicColumnType = typeof PrismaTypeId | typeof PrismaTypeContent; +type ColumnSymbol = typeof IdColumnSymbol | typeof ContentColumnSymbol; declare type Value = unknown; declare type RawValue = Value | Sql; @@ -37,13 +37,30 @@ type PrismaClient = { ...values: any[] ): // eslint-disable-next-line @typescript-eslint/no-explicit-any Promise; + // eslint-disable-next-line @typescript-eslint/no-explicit-any $transaction

[]>(arg: [...P]): Promise; }; -export class PrismaVectorStore< +type ObjectIntersect = { + [P in keyof A & keyof B]: A[P] | B[P]; +}; + +type ModelColumns> = { + [K in keyof TModel]?: true | ColumnSymbol; +}; + +type SimilarityModel< TModel extends Record = Record, - TModelName extends string = string + TColumns extends ModelColumns = ModelColumns +> = Pick> & { + _distance: number | null; +}; + +export class PrismaVectorStore< + TModel extends Record, + TModelName extends string, + TSelectModel extends ModelColumns > extends VectorStore { tableSql: Sql; @@ -51,27 +68,38 @@ export class PrismaVectorStore< selectSql: Sql; - idColumn: keyof TModel; + idColumn: keyof TModel & string; + + contentColumn: keyof TModel & string; + + static IdColumn: typeof IdColumnSymbol = IdColumnSymbol; + + static ContentColumn: typeof ContentColumnSymbol = ContentColumnSymbol; - contentColumn: keyof TModel; + protected db: PrismaClient; + + protected Prisma: PrismaNamespace; constructor( config: { + db: PrismaClient; + prisma: PrismaNamespace; tableName: TModelName; vectorColumnName: string; - columns: { - [K in keyof TModel]?: boolean | BasicColumnType; - }; + columns: TSelectModel; }, - protected db: PrismaClient, - protected Prisma: PrismaNamespace, embeddings: Embeddings ) { super(embeddings, {}); + this.Prisma = config.prisma; + this.db = config.db; + const entries = Object.entries(config.columns); - const idColumn = entries.find((i) => i[1] === PrismaTypeId)?.[0]; - const contentColumn = entries.find((i) => i[1] === PrismaTypeContent)?.[0]; + const idColumn = entries.find((i) => i[1] === IdColumnSymbol)?.[0]; + const contentColumn = entries.find( + (i) => i[1] === ContentColumnSymbol + )?.[0]; if (idColumn == null) throw new Error("Missing ID column"); if (contentColumn == null) throw new Error("Missing content column"); @@ -79,10 +107,10 @@ export class PrismaVectorStore< this.idColumn = idColumn; this.contentColumn = contentColumn; - this.tableSql = Prisma.raw(`"${config.tableName}"`); - this.vectorColumnSql = Prisma.raw(`"${config.vectorColumnName}"`); + this.tableSql = this.Prisma.raw(`"${config.tableName}"`); + this.vectorColumnSql = this.Prisma.raw(`"${config.vectorColumnName}"`); - this.selectSql = Prisma.raw( + this.selectSql = this.Prisma.raw( entries .map(([key, alias]) => (alias && key) || null) .filter((x): x is string => !!x) @@ -91,10 +119,42 @@ export class PrismaVectorStore< ); } + static withModel>(db: PrismaClient) { + function create< + TPrisma extends PrismaNamespace, + TColumns extends ModelColumns + >( + config: { + prisma: TPrisma; + tableName: keyof TPrisma["ModelName"] & string; + vectorColumnName: string; + columns: TColumns; + }, + embeddings: Embeddings + ) { + type ModelName = keyof TPrisma["ModelName"] & string; + return new PrismaVectorStore( + { db, ...config }, + embeddings + ); + } + + return { create }; + } + + async addModels(models: TModel[]) { + return this.addDocuments( + models.map((metadata) => { + const pageContent = typeof metadata[this.contentColumn]; + if (pageContent !== "string") + throw new Error("Content column must be a string"); + return new Document({ pageContent, metadata }); + }) + ); + } + async addDocuments(documents: Document[]) { const texts = documents.map(({ pageContent }) => pageContent); - - // TODO: add documents to database return this.addVectors( await this.embeddings.embedDocuments(texts), documents @@ -102,20 +162,23 @@ export class PrismaVectorStore< } async addVectors(vectors: number[][], documents: Document[]) { - const idSql = this.Prisma.raw(`"${this.idColumn as string}"`); + const idSql = this.Prisma.raw(`"${this.idColumn}"`); await this.db.$transaction( vectors.map( (vector, idx) => this.db.$executeRaw` UPDATE ${this.tableSql} SET ${this.vectorColumnSql} = ${`[${vector.join(",")}]`}::vector - WHERE ${idSql} = ${documents[idx].metadata.id} + WHERE ${idSql} = ${documents[idx].metadata[this.idColumn]} ` ) ); } - async similaritySearch(query: string, k = 4): Promise[]> { + async similaritySearch( + query: string, + k = 4 + ): Promise>[]> { const results = await this.similaritySearchVectorWithScore( await this.embeddings.embedQuery(query), k @@ -127,10 +190,10 @@ export class PrismaVectorStore< async similaritySearchVectorWithScore( query: number[], k: number - ): Promise<[Document, number][]> { + ): Promise<[Document>, number][]> { const vectorQuery = `[${query.join(",")}]`; const articles = await this.db.$queryRaw< - Array + Array> >` SELECT ${this.selectSql}, ${this.vectorColumnSql} <=> ${vectorQuery}::vector as "_distance" FROM ${this.tableSql} @@ -138,7 +201,8 @@ export class PrismaVectorStore< LIMIT ${k}; `; - const results: [Document, number][] = []; + const results: [Document>, number][] = + []; for (const article of articles) { if (article._distance != null) { results.push([ @@ -153,4 +217,33 @@ export class PrismaVectorStore< return results; } + + /** + * @deprecated Not implemented in Prisma vectorstore, please use PrismaVectorStore.withModel instead + */ + static fromTexts( + _texts: string[], + _metadatas: object[], + _embeddings: Embeddings, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + _dbConfig: Record + ): Promise { + throw new Error( + "Not implemented in Prisma vectorstore, please use PrismaVectorStore.withModel instead" + ); + } + + /** + * @deprecated Not implemented in Prisma vectorstore, please use PrismaVectorStore.withModel instead + */ + static fromDocuments( + _docs: Document[], + _embeddings: Embeddings, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + _dbConfig: Record + ): Promise { + throw new Error( + "Not implemented in Prisma vectorstore, please use PrismaVectorStore.withModel instead" + ); + } } From ce4ff0697a9b116a834f0bd94434a5bfb79fc89d Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Sat, 25 Mar 2023 18:17:36 +0100 Subject: [PATCH 07/11] Add docs --- .../modules/indexes/vector_stores/prisma.mdx | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 docs/docs/modules/indexes/vector_stores/prisma.mdx diff --git a/docs/docs/modules/indexes/vector_stores/prisma.mdx b/docs/docs/modules/indexes/vector_stores/prisma.mdx new file mode 100644 index 000000000000..8cfe5674a84d --- /dev/null +++ b/docs/docs/modules/indexes/vector_stores/prisma.mdx @@ -0,0 +1,74 @@ +# Prisma + +For augmenting existing models in PostgreSQL database with vector search, Langchain supports using [Prisma](https://www.prisma.io/) together with PostgreSQL and [`pgvector`](https://github.com/pgvector/pgvector) Postgres extension. + +## Setup + +### Setup database instance with Supabase + +Refer to the [Prisma and Supabase integration guide](https://supabase.com/docs/guides/integrations/prisma) to setup a new database instance with Supabase and Prisma. + +### Setup `pgvector` self hosted instance with `docker-compose` + +`pgvector` provides a prebuilt Docker image that can be used to quickly setup a self-hosted Postgres instance. + +```yaml +services: + db: + image: ankane/pgvector + ports: + - 5432:5432 + volumes: + - db:/var/lib/postgresql/data + environment: + - POSTGRES_PASSWORD= + - POSTGRES_USER= + - POSTGRES_DB= + +volumes: + db: +``` + +### Create a new schema + +Assuming you haven't created a schema yet, create a new model with a `vector` field of type `Unsupported("vector")`: + +```prisma +model Document { + id String @id @default(cuid()) + content String + vector Unsupported("vector")? +} +``` + +Afterwards, create a new migration with `--create-only` to avoid running the migration directly. + +```bash npm2yarn +npm run prisma migrate dev --create-only +``` + +Add the following line to the newly created migration to enable `pgvector` extension if it hasn't been enabled yet: + +```sql +CREATE EXTENSION IF NOT EXISTS vector; +``` + +Run the migration afterwards: + +```bash npm2yarn +npm run prisma migrate dev +``` + +## Usage + +import CodeBlock from "@theme/CodeBlock"; +import Example from "@examples/indexes/vector_stores/prisma_vectorstore/prisma.ts"; +import Schema from "@examples/indexes/vector_stores/prisma_vectorstore/prisma/schema.prisma"; + +Use the `withModel` method to get proper type hints for `metadata` field: + +{Example} + +The sample above uses the following schema: + +{Schema} From 783d4b3305028f6c62aa87125e3fb544aae97f27 Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Sat, 8 Apr 2023 13:32:43 +0200 Subject: [PATCH 08/11] Remove @prisma/client from peer-dependencies and dependencies --- langchain/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/langchain/package.json b/langchain/package.json index 5db9be1b0206..ecdc89791e1f 100644 --- a/langchain/package.json +++ b/langchain/package.json @@ -107,7 +107,6 @@ "@huggingface/inference": "^1.5.1", "@jest/globals": "^29.5.0", "@pinecone-database/pinecone": "^0.0.10", - "@prisma/client": "^4.11.0", "@supabase/supabase-js": "^2.10.0", "@tsconfig/recommended": "^1.0.2", "@types/d3-dsv": "^2", @@ -156,7 +155,6 @@ "@getmetal/metal-sdk": "*", "@huggingface/inference": "^1.5.1", "@pinecone-database/pinecone": "^0.0.10", - "@prisma/client": "^4.11.0", "@supabase/supabase-js": "^2.10.0", "cheerio": "^1.0.0-rc.12", "chromadb": "^1.3.0", From a9335c993b464b51d10ebf4ed3ab2d802799e093 Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Sat, 8 Apr 2023 14:06:53 +0200 Subject: [PATCH 09/11] Add implementation of fromTexts and fromDocuments --- langchain/src/vectorstores/prisma.ts | 136 ++++++++++++++++++++------- 1 file changed, 103 insertions(+), 33 deletions(-) diff --git a/langchain/src/vectorstores/prisma.ts b/langchain/src/vectorstores/prisma.ts index 82e8675e2e07..4c8fd6853c64 100644 --- a/langchain/src/vectorstores/prisma.ts +++ b/langchain/src/vectorstores/prisma.ts @@ -57,6 +57,12 @@ type SimilarityModel< _distance: number | null; }; +type DefaultPrismaVectorStore = PrismaVectorStore< + Record, + string, + ModelColumns> +>; + export class PrismaVectorStore< TModel extends Record, TModelName extends string, @@ -81,14 +87,14 @@ export class PrismaVectorStore< protected Prisma: PrismaNamespace; constructor( + embeddings: Embeddings, config: { db: PrismaClient; prisma: PrismaNamespace; tableName: TModelName; vectorColumnName: string; columns: TSelectModel; - }, - embeddings: Embeddings + } ) { super(embeddings, {}); @@ -124,22 +130,74 @@ export class PrismaVectorStore< TPrisma extends PrismaNamespace, TColumns extends ModelColumns >( + embeddings: Embeddings, config: { prisma: TPrisma; tableName: keyof TPrisma["ModelName"] & string; vectorColumnName: string; columns: TColumns; - }, - embeddings: Embeddings + } + ) { + type ModelName = keyof TPrisma["ModelName"] & string; + return new PrismaVectorStore(embeddings, { + ...config, + db, + }); + } + + async function fromTexts< + TPrisma extends PrismaNamespace, + TColumns extends ModelColumns + >( + texts: string[], + metadatas: TModel[], + embeddings: Embeddings, + dbConfig: { + prisma: TPrisma; + tableName: keyof TPrisma["ModelName"] & string; + vectorColumnName: string; + columns: TColumns; + } + ) { + const docs: Document[] = []; + for (let i = 0; i < texts.length; i += 1) { + const metadata = Array.isArray(metadatas) ? metadatas[i] : metadatas; + const newDoc = new Document({ + pageContent: texts[i], + metadata, + }); + docs.push(newDoc); + } + + return PrismaVectorStore.fromDocuments(docs, embeddings, { + ...dbConfig, + db, + }); + } + + async function fromDocuments< + TPrisma extends PrismaNamespace, + TColumns extends ModelColumns + >( + docs: Document[], + embeddings: Embeddings, + dbConfig: { + prisma: TPrisma; + tableName: keyof TPrisma["ModelName"] & string; + vectorColumnName: string; + columns: TColumns; + } ) { type ModelName = keyof TPrisma["ModelName"] & string; - return new PrismaVectorStore( - { db, ...config }, - embeddings + const instance = new PrismaVectorStore( + embeddings, + { ...dbConfig, db } ); + await instance.addDocuments(docs); + return instance; } - return { create }; + return { create, fromTexts, fromDocuments }; } async addModels(models: TModel[]) { @@ -218,32 +276,44 @@ export class PrismaVectorStore< return results; } - /** - * @deprecated Not implemented in Prisma vectorstore, please use PrismaVectorStore.withModel instead - */ - static fromTexts( - _texts: string[], - _metadatas: object[], - _embeddings: Embeddings, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - _dbConfig: Record - ): Promise { - throw new Error( - "Not implemented in Prisma vectorstore, please use PrismaVectorStore.withModel instead" - ); + static async fromTexts( + texts: string[], + metadatas: object[], + embeddings: Embeddings, + dbConfig: { + db: PrismaClient; + prisma: PrismaNamespace; + tableName: string; + vectorColumnName: string; + columns: ModelColumns>; + } + ): Promise { + const docs: Document[] = []; + for (let i = 0; i < texts.length; i += 1) { + const metadata = Array.isArray(metadatas) ? metadatas[i] : metadatas; + const newDoc = new Document({ + pageContent: texts[i], + metadata, + }); + docs.push(newDoc); + } + + return PrismaVectorStore.fromDocuments(docs, embeddings, dbConfig); } - /** - * @deprecated Not implemented in Prisma vectorstore, please use PrismaVectorStore.withModel instead - */ - static fromDocuments( - _docs: Document[], - _embeddings: Embeddings, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - _dbConfig: Record - ): Promise { - throw new Error( - "Not implemented in Prisma vectorstore, please use PrismaVectorStore.withModel instead" - ); + static async fromDocuments( + docs: Document[], + embeddings: Embeddings, + dbConfig: { + db: PrismaClient; + prisma: PrismaNamespace; + tableName: string; + vectorColumnName: string; + columns: ModelColumns>; + } + ): Promise { + const instance = new PrismaVectorStore(embeddings, dbConfig); + await instance.addDocuments(docs); + return instance; } } From 57e69a099caf43221dbf03a286fdab970896a50f Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Sat, 8 Apr 2023 14:23:49 +0200 Subject: [PATCH 10/11] Update yarn.lock --- yarn.lock | 2 -- 1 file changed, 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index aed52620bad0..f9d83e2d2833 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11483,7 +11483,6 @@ __metadata: "@huggingface/inference": ^1.5.1 "@jest/globals": ^29.5.0 "@pinecone-database/pinecone": ^0.0.10 - "@prisma/client": ^4.11.0 "@supabase/supabase-js": ^2.10.0 "@tsconfig/recommended": ^1.0.2 "@types/d3-dsv": ^2 @@ -11543,7 +11542,6 @@ __metadata: "@getmetal/metal-sdk": "*" "@huggingface/inference": ^1.5.1 "@pinecone-database/pinecone": ^0.0.10 - "@prisma/client": ^4.11.0 "@supabase/supabase-js": ^2.10.0 cheerio: ^1.0.0-rc.12 chromadb: ^1.3.0 From 5f3e56ada8445a5cddec443dd02e7d00b92e9b63 Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Sat, 8 Apr 2023 14:30:20 +0200 Subject: [PATCH 11/11] Fix broken example --- .../src/indexes/vector_stores/prisma_vectorstore/prisma.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts index 53e26649abec..b6f889e8ae5f 100644 --- a/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts +++ b/examples/src/indexes/vector_stores/prisma_vectorstore/prisma.ts @@ -6,6 +6,7 @@ export const run = async () => { const db = new PrismaClient(); const vectorStore = PrismaVectorStore.withModel(db).create( + new OpenAIEmbeddings(), { prisma: Prisma, tableName: "Document", @@ -14,8 +15,7 @@ export const run = async () => { id: PrismaVectorStore.IdColumn, content: PrismaVectorStore.ContentColumn, }, - }, - new OpenAIEmbeddings() + } ); const texts = ["Hello world", "Bye bye", "What's this?"];