{"version":3,"file":"vercel_postgres.cjs","names":["VectorStore","embeddings: EmbeddingsInterface","config: VercelPostgresFields","config?: Partial<VercelPostgresFields> & {\n      postgresConnectionOptions?: VercelPostgresPoolConfig;\n    }","documents: Document[]","options?: { ids?: string[] }","row: (string | Record<string, any>)[]","index: number","rows: (string | Record<string, any>)[][]","useIdColumn: boolean","vectors: number[][]","query: number[]","k: number","filter?: this[\"FilterType\"]","_filter: this[\"FilterType\"]","Document","params: { ids?: string[]; deleteAll?: boolean }","texts: string[]","metadatas: object[] | object","dbConfig?: Partial<VercelPostgresFields> & {\n      postgresConnectionOptions?: VercelPostgresPoolConfig;\n    }","docs: Document[]"],"sources":["../../src/vectorstores/vercel_postgres.ts"],"sourcesContent":["import {\n  type VercelPool,\n  type VercelPoolClient,\n  type VercelPostgresPoolConfig,\n  createPool,\n} from \"@vercel/postgres\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { VectorStore } from \"@langchain/core/vectorstores\";\nimport { Document } from \"@langchain/core/documents\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\n\ntype Metadata = Record<string, string | number | Record<\"in\", string[]>>;\n\n/**\n * Interface that defines the arguments required to create a\n * `VercelPostgres` instance. It includes Postgres connection options,\n * table name, filter, and verbosity level.\n */\nexport interface VercelPostgresFields {\n  pool: VercelPool;\n  client: VercelPoolClient;\n  tableName?: string;\n  columns?: {\n    idColumnName?: string;\n    vectorColumnName?: string;\n    contentColumnName?: string;\n    metadataColumnName?: string;\n  };\n  filter?: Metadata;\n  verbose?: boolean;\n}\n\n/**\n * Class that provides an interface to a Vercel Postgres vector database. It\n * extends the `VectorStore` base class and implements methods for adding\n * documents and vectors and performing similarity searches.\n */\nexport class VercelPostgres extends VectorStore {\n  declare FilterType: Metadata;\n\n  tableName: string;\n\n  idColumnName: string;\n\n  vectorColumnName: string;\n\n  contentColumnName: string;\n\n  metadataColumnName: string;\n\n  filter?: Metadata;\n\n  _verbose?: boolean;\n\n  pool: VercelPool;\n\n  client: VercelPoolClient;\n\n  _vectorstoreType(): string {\n    return \"vercel\";\n  }\n\n  constructor(embeddings: EmbeddingsInterface, config: VercelPostgresFields) {\n    super(embeddings, config);\n    this.tableName = config.tableName ?? \"langchain_vectors\";\n    this.filter = config.filter;\n\n    this.vectorColumnName = config.columns?.vectorColumnName ?? \"embedding\";\n    this.contentColumnName = config.columns?.contentColumnName ?? \"text\";\n    this.idColumnName = config.columns?.idColumnName ?? \"id\";\n    this.metadataColumnName = config.columns?.metadataColumnName ?? \"metadata\";\n\n    this.pool = config.pool;\n    this.client = config.client;\n\n    this._verbose =\n      config.verbose ?? getEnvironmentVariable(\"LANGCHAIN_VERBOSE\") === \"true\";\n  }\n\n  /**\n   * Static method to create a new `VercelPostgres` instance from a\n   * connection. It creates a table if one does not exist, and calls\n   * `connect` to return a new instance of `VercelPostgres`.\n   *\n   * @param embeddings - Embeddings instance.\n   * @param fields - `VercelPostgres` configuration options.\n   * @returns A new instance of `VercelPostgres`.\n   */\n  static async initialize(\n    embeddings: EmbeddingsInterface,\n    config?: Partial<VercelPostgresFields> & {\n      postgresConnectionOptions?: VercelPostgresPoolConfig;\n    }\n  ): Promise<VercelPostgres> {\n    // Default maxUses to 1 for edge environments:\n    // https://github.com/vercel/storage/tree/main/packages/postgres#a-note-on-edge-environments\n    const pool =\n      config?.pool ??\n      createPool({ maxUses: 1, ...config?.postgresConnectionOptions });\n    const client = config?.client ?? (await pool.connect());\n    const postgresqlVectorStore = new VercelPostgres(embeddings, {\n      ...config,\n      pool,\n      client,\n    });\n\n    await postgresqlVectorStore.ensureTableInDatabase();\n\n    return postgresqlVectorStore;\n  }\n\n  /**\n   * Method to add documents to the vector store. It converts the documents into\n   * vectors, and adds them to the store.\n   *\n   * @param documents - Array of `Document` instances.\n   * @returns Promise that resolves when the documents have been added.\n   */\n  async addDocuments(\n    documents: Document[],\n    options?: { ids?: string[] }\n  ): Promise<string[]> {\n    const texts = documents.map(({ pageContent }) => pageContent);\n\n    return this.addVectors(\n      await this.embeddings.embedDocuments(texts),\n      documents,\n      options\n    );\n  }\n\n  /**\n   * Generates the SQL placeholders for a specific row at the provided index.\n   *\n   * @param index - The index of the row for which placeholders need to be generated.\n   * @returns The SQL placeholders for the row values.\n   */\n  protected generatePlaceholderForRowAt(\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    row: (string | Record<string, any>)[],\n    index: number\n  ): string {\n    const base = index * row.length;\n    return `(${row.map((_, j) => `$${base + 1 + j}`)})`;\n  }\n\n  /**\n   * Constructs the SQL query for inserting rows into the specified table.\n   *\n   * @param rows - The rows of data to be inserted, consisting of values and records.\n   * @param chunkIndex - The starting index for generating query placeholders based on chunk positioning.\n   * @returns The complete SQL INSERT INTO query string.\n   */\n  protected async runInsertQuery(\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    rows: (string | Record<string, any>)[][],\n    useIdColumn: boolean\n  ) {\n    const values = rows.map((row, j) =>\n      this.generatePlaceholderForRowAt(row, j)\n    );\n    const flatValues = rows.flat();\n    return this.client.query(\n      `\n    INSERT INTO ${this.tableName} (\n      ${useIdColumn ? `${this.idColumnName},` : \"\"}\n      ${this.contentColumnName}, \n      ${this.vectorColumnName}, \n      ${this.metadataColumnName}\n    ) VALUES ${values.join(\", \")}\n    ON CONFLICT (${this.idColumnName}) \n    DO UPDATE \n    SET \n    ${this.contentColumnName} = EXCLUDED.${this.contentColumnName},\n    ${this.vectorColumnName} = EXCLUDED.${this.vectorColumnName},\n    ${this.metadataColumnName} = EXCLUDED.${this.metadataColumnName}\n    RETURNING ${this.idColumnName}`,\n      flatValues\n    );\n  }\n\n  /**\n   * Method to add vectors to the vector store. It converts the vectors into\n   * rows and inserts them into the database.\n   *\n   * @param vectors - Array of vectors.\n   * @param documents - Array of `Document` instances.\n   * @returns Promise that resolves when the vectors have been added.\n   */\n  async addVectors(\n    vectors: number[][],\n    documents: Document[],\n    options?: { ids?: string[] }\n  ): Promise<string[]> {\n    if (options?.ids !== undefined && options?.ids.length !== vectors.length) {\n      throw new Error(\n        `If provided, the length of \"ids\" must be the same as the number of vectors.`\n      );\n    }\n    const rows = vectors.map((embedding, idx) => {\n      const embeddingString = `[${embedding.join(\",\")}]`;\n      const row = [\n        documents[idx].pageContent,\n        embeddingString,\n        documents[idx].metadata,\n      ];\n      if (options?.ids) {\n        return [options.ids[idx], ...row];\n      }\n      return row;\n    });\n\n    const chunkSize = 500;\n\n    const ids = [];\n\n    for (let i = 0; i < rows.length; i += chunkSize) {\n      const chunk = rows.slice(i, i + chunkSize);\n      try {\n        const result = await this.runInsertQuery(\n          chunk,\n          options?.ids !== undefined\n        );\n        ids.push(...result.rows.map((row) => row[this.idColumnName]));\n      } catch (e) {\n        console.error(e);\n        throw new Error(`Error inserting: ${(e as Error).message}`);\n      }\n    }\n    return ids;\n  }\n\n  /**\n   * Method to perform a similarity search in the vector store. It returns\n   * the `k` most similar documents to the query vector, along with their\n   * similarity scores.\n   *\n   * @param query - Query vector.\n   * @param k - Number of most similar documents to return.\n   * @param filter - Optional filter to apply to the search.\n   * @returns Promise that resolves with an array of tuples, each containing a `Document` and its similarity score.\n   */\n  async similaritySearchVectorWithScore(\n    query: number[],\n    k: number,\n    filter?: this[\"FilterType\"]\n  ): Promise<[Document, number][]> {\n    const embeddingString = `[${query.join(\",\")}]`;\n    const _filter: this[\"FilterType\"] = filter ?? {};\n    const whereClauses = [];\n    const values = [embeddingString, k];\n    let paramCount = values.length;\n\n    for (const [key, value] of Object.entries(_filter)) {\n      if (typeof value === \"object\" && value !== null) {\n        const currentParamCount = paramCount;\n        const placeholders = value.in\n          .map((_, index) => `$${currentParamCount + index + 1}`)\n          .join(\",\");\n        whereClauses.push(\n          `${this.metadataColumnName}->>'${key}' IN (${placeholders})`\n        );\n        values.push(...value.in);\n        paramCount += value.in.length;\n      } else {\n        paramCount += 1;\n        whereClauses.push(\n          `${this.metadataColumnName}->>'${key}' = $${paramCount}`\n        );\n        values.push(value);\n      }\n    }\n\n    const whereClause = whereClauses.length\n      ? `WHERE ${whereClauses.join(\" AND \")}`\n      : \"\";\n\n    const queryString = `\n            SELECT *, ${this.vectorColumnName} <=> $1 as \"_distance\"\n            FROM ${this.tableName}\n            ${whereClause}\n            ORDER BY \"_distance\" ASC\n            LIMIT $2;`;\n\n    const documents = (await this.client.query(queryString, values)).rows;\n    const results = [] as [Document, number][];\n    for (const doc of documents) {\n      if (doc._distance != null && doc[this.contentColumnName] != null) {\n        const document = new Document({\n          pageContent: doc[this.contentColumnName],\n          metadata: doc[this.metadataColumnName],\n        });\n        results.push([document, doc._distance]);\n      }\n    }\n    return results;\n  }\n\n  async delete(params: { ids?: string[]; deleteAll?: boolean }): Promise<void> {\n    if (params.ids !== undefined) {\n      await this.client.query(\n        `DELETE FROM ${this.tableName} WHERE ${\n          this.idColumnName\n        } IN (${params.ids.map((_, idx) => `$${idx + 1}`)})`,\n        params.ids\n      );\n    } else if (params.deleteAll) {\n      await this.client.query(`TRUNCATE TABLE ${this.tableName}`);\n    }\n  }\n\n  /**\n   * Method to ensure the existence of the table in the database. It creates\n   * the table if it does not already exist.\n   *\n   * @returns Promise that resolves when the table has been ensured.\n   */\n  async ensureTableInDatabase(): Promise<void> {\n    await this.client.query(`CREATE EXTENSION IF NOT EXISTS vector;`);\n    await this.client.query(`CREATE TABLE IF NOT EXISTS \"${this.tableName}\" (\n      \"${this.idColumnName}\" uuid NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,\n      \"${this.contentColumnName}\" text,\n      \"${this.metadataColumnName}\" jsonb,\n      \"${this.vectorColumnName}\" vector\n    );`);\n  }\n\n  /**\n   * Static method to create a new `VercelPostgres` instance from an\n   * array of texts and their metadata. It converts the texts into\n   * `Document` instances and adds them to the store.\n   *\n   * @param texts - Array of texts.\n   * @param metadatas - Array of metadata objects or a single metadata object.\n   * @param embeddings - Embeddings instance.\n   * @param fields - `VercelPostgres` configuration options.\n   * @returns Promise that resolves with a new instance of `VercelPostgres`.\n   */\n  static async fromTexts(\n    texts: string[],\n    metadatas: object[] | object,\n    embeddings: EmbeddingsInterface,\n    dbConfig?: Partial<VercelPostgresFields> & {\n      postgresConnectionOptions?: VercelPostgresPoolConfig;\n    }\n  ): Promise<VercelPostgres> {\n    const docs = [];\n    for (let i = 0; i < texts.length; i += 1) {\n      const metadata = Array.isArray(metadatas) ? metadatas[i] : metadatas;\n      const newDoc = new Document({\n        pageContent: texts[i],\n        metadata,\n      });\n      docs.push(newDoc);\n    }\n\n    return this.fromDocuments(docs, embeddings, dbConfig);\n  }\n\n  /**\n   * Static method to create a new `VercelPostgres` instance from an\n   * array of `Document` instances. It adds the documents to the store.\n   *\n   * @param docs - Array of `Document` instances.\n   * @param embeddings - Embeddings instance.\n   * @param fields - `VercelPostgres` configuration options.\n   * @returns Promise that resolves with a new instance of `VercelPostgres`.\n   */\n  static async fromDocuments(\n    docs: Document[],\n    embeddings: EmbeddingsInterface,\n    dbConfig?: Partial<VercelPostgresFields> & {\n      postgresConnectionOptions?: VercelPostgresPoolConfig;\n    }\n  ): Promise<VercelPostgres> {\n    const instance = await this.initialize(embeddings, dbConfig);\n    await instance.addDocuments(docs);\n\n    return instance;\n  }\n\n  /**\n   * Closes all the clients in the pool and terminates the pool.\n   *\n   * @returns Promise that resolves when all clients are closed and the pool is terminated.\n   */\n  async end(): Promise<void> {\n    await this.client?.release();\n    return this.pool.end();\n  }\n}\n"],"mappings":"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"}