{"version":3,"file":"vectorstores.cjs","names":["VectorStore","PineconeIndex","AsyncCaller","Document"],"sources":["../src/vectorstores.ts"],"sourcesContent":["import { v4 as uuid } from \"@langchain/core/utils/uuid\";\nimport flatten from \"flat\";\n\nimport {\n  RecordMetadata,\n  PineconeRecord,\n  Index as PineconeIndex,\n  ScoredPineconeRecord,\n} from \"@pinecone-database/pinecone\";\n\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport {\n  VectorStore,\n  type MaxMarginalRelevanceSearchOptions,\n} from \"@langchain/core/vectorstores\";\nimport { Document, type DocumentInterface } from \"@langchain/core/documents\";\nimport {\n  AsyncCaller,\n  AsyncCallerParams,\n} from \"@langchain/core/utils/async_caller\";\nimport { chunkArray } from \"@langchain/core/utils/chunk_array\";\nimport { maximalMarginalRelevance } from \"@langchain/core/utils/math\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype PineconeMetadata = Record<string, any>;\n\ntype HTTPHeaders = {\n  [key: string]: string;\n};\n\n/**\n * Database config for your vectorstore.\n */\nexport interface PineconeStoreParams extends AsyncCallerParams {\n  /**\n   * The Pinecone index to use.\n   * Either this or pineconeConfig must be provided.\n   */\n  pineconeIndex?: PineconeIndex;\n  textKey?: string;\n  namespace?: string;\n  filter?: PineconeMetadata;\n  /**\n   * Configuration for the Pinecone index.\n   * Either this or pineconeIndex must be provided.\n   */\n  pineconeConfig?: {\n    indexName: ConstructorParameters<typeof PineconeIndex>[0];\n    config: ConstructorParameters<typeof PineconeIndex>[1];\n    namespace?: string;\n    indexHostUrl?: string;\n    additionalHeaders?: HTTPHeaders;\n  };\n}\n\n/**\n * Type that defines the parameters for the delete operation in the\n * PineconeStore class. It includes ids, filter, deleteAll flag, and namespace.\n */\nexport type PineconeDeleteParams = {\n  ids?: string[];\n  deleteAll?: boolean;\n  filter?: object;\n  namespace?: string;\n};\n\n/**\n * Pinecone vector store integration.\n *\n * Setup:\n * Install `@langchain/pinecone` and `@pinecone-database/pinecone` to pass a client in.\n *\n * ```bash\n * npm install @langchain/pinecone @pinecone-database/pinecone\n * ```\n *\n * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_pinecone.PineconeStore.html#constructor)\n *\n * <details open>\n * <summary><strong>Instantiate</strong></summary>\n *\n * ```typescript\n * import { PineconeStore } from '@langchain/pinecone';\n * // Or other embeddings\n * import { OpenAIEmbeddings } from '@langchain/openai';\n *\n * import { Pinecone as PineconeClient } from \"@pinecone-database/pinecone\";\n *\n * const pinecone = new PineconeClient();\n *\n * // Will automatically read the PINECONE_API_KEY env var\n * const pineconeIndex = pinecone.Index(process.env.PINECONE_INDEX!);\n *\n * const embeddings = new OpenAIEmbeddings({\n *   model: \"text-embedding-3-small\",\n * });\n *\n * const vectorStore = await PineconeStore.fromExistingIndex(embeddings, {\n *   pineconeIndex,\n *   // Maximum number of batch requests to allow at once. Each batch is 1000 vectors.\n *   maxConcurrency: 5,\n *   // You can pass a namespace here too\n *   // namespace: \"foo\",\n * });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Add documents</strong></summary>\n *\n * ```typescript\n * import type { Document } from '@langchain/core/documents';\n *\n * const document1 = { pageContent: \"foo\", metadata: { baz: \"bar\" } };\n * const document2 = { pageContent: \"thud\", metadata: { bar: \"baz\" } };\n * const document3 = { pageContent: \"i will be deleted :(\", metadata: {} };\n *\n * const documents: Document[] = [document1, document2, document3];\n * const ids = [\"1\", \"2\", \"3\"];\n * await vectorStore.addDocuments(documents, { ids });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Delete documents</strong></summary>\n *\n * ```typescript\n * await vectorStore.delete({ ids: [\"3\"] });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Similarity search</strong></summary>\n *\n * ```typescript\n * const results = await vectorStore.similaritySearch(\"thud\", 1);\n * for (const doc of results) {\n *   console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`);\n * }\n * // Output: * thud [{\"baz\":\"bar\"}]\n * ```\n * </details>\n *\n * <br />\n *\n *\n * <details>\n * <summary><strong>Similarity search with filter</strong></summary>\n *\n * ```typescript\n * const resultsWithFilter = await vectorStore.similaritySearch(\"thud\", 1, { baz: \"bar\" });\n *\n * for (const doc of resultsWithFilter) {\n *   console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`);\n * }\n * // Output: * foo [{\"baz\":\"bar\"}]\n * ```\n * </details>\n *\n * <br />\n *\n *\n * <details>\n * <summary><strong>Similarity search with score</strong></summary>\n *\n * ```typescript\n * const resultsWithScore = await vectorStore.similaritySearchWithScore(\"qux\", 1);\n * for (const [doc, score] of resultsWithScore) {\n *   console.log(`* [SIM=${score.toFixed(6)}] ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`);\n * }\n * // Output: * [SIM=0.000000] qux [{\"bar\":\"baz\",\"baz\":\"bar\"}]\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>As a retriever</strong></summary>\n *\n * ```typescript\n * const retriever = vectorStore.asRetriever({\n *   searchType: \"mmr\", // Leave blank for standard similarity search\n *   k: 1,\n * });\n * const resultAsRetriever = await retriever.invoke(\"thud\");\n * console.log(resultAsRetriever);\n *\n * // Output: [Document({ metadata: { \"baz\":\"bar\" }, pageContent: \"thud\" })]\n * ```\n * </details>\n *\n * <br />\n */\nexport class PineconeStore extends VectorStore {\n  declare FilterType: PineconeMetadata;\n\n  textKey: string;\n\n  namespace?: string;\n\n  pineconeIndex: PineconeIndex;\n\n  filter?: PineconeMetadata;\n\n  caller: AsyncCaller;\n\n  _vectorstoreType(): string {\n    return \"pinecone\";\n  }\n\n  constructor(embeddings: EmbeddingsInterface, params: PineconeStoreParams) {\n    super(embeddings, params);\n    this.embeddings = embeddings;\n\n    const {\n      namespace,\n      pineconeIndex,\n      textKey,\n      filter,\n      pineconeConfig,\n      ...asyncCallerArgs\n    } = params;\n    this.namespace = namespace;\n    if (!pineconeIndex && !pineconeConfig) {\n      throw new Error(\"pineconeConfig or pineconeIndex must be provided.\");\n    }\n    if (pineconeIndex && pineconeConfig) {\n      throw new Error(\n        \"Only one of pineconeConfig or pineconeIndex can be provided.\"\n      );\n    }\n\n    if (pineconeIndex) {\n      this.pineconeIndex = pineconeIndex;\n    } else if (pineconeConfig) {\n      this.pineconeIndex = new PineconeIndex(\n        pineconeConfig.indexName,\n        {\n          ...pineconeConfig.config,\n          sourceTag: \"langchainjs\",\n        },\n        pineconeConfig.namespace,\n        pineconeConfig.indexHostUrl,\n        pineconeConfig.additionalHeaders\n      );\n    }\n\n    this.textKey = textKey ?? \"text\";\n    this.filter = filter;\n    this.caller = new AsyncCaller(asyncCallerArgs);\n  }\n\n  /**\n   * Method that adds documents to the Pinecone database.\n   *\n   * @param documents Array of documents to add to the Pinecone database.\n   * @param options Optional ids for the documents.\n   * @returns Promise that resolves with the ids of the added documents.\n   */\n  async addDocuments(\n    documents: Document[],\n    options?: { ids?: string[]; namespace?: string } | string[]\n  ): Promise<string[]> {\n    const texts = documents.map(({ pageContent }) => pageContent);\n    return this.addVectors(\n      await this.embeddings.embedDocuments(texts),\n      documents,\n      options\n    );\n  }\n\n  /**\n   * Method that adds vectors to the Pinecone database.\n   *\n   * @param vectors Array of vectors to add to the Pinecone database.\n   * @param documents Array of documents associated with the vectors.\n   * @param options Optional ids for the vectors.\n   * @returns Promise that resolves with the ids of the added vectors.\n   */\n  async addVectors(\n    vectors: number[][],\n    documents: Document[],\n    options?: { ids?: string[]; namespace?: string } | string[]\n  ) {\n    const ids = Array.isArray(options) ? options : options?.ids;\n    const documentIds = ids == null ? documents.map(() => uuid()) : ids;\n    const pineconeVectors = vectors.map((values, idx) => {\n      // Pinecone doesn't support nested objects, so we flatten them\n      const documentMetadata = { ...documents[idx].metadata };\n      // preserve string arrays which are allowed\n      const stringArrays: Record<string, string[]> = {};\n      for (const key of Object.keys(documentMetadata)) {\n        if (\n          Array.isArray(documentMetadata[key]) &&\n          documentMetadata[key].every((el: unknown) => typeof el === \"string\")\n        ) {\n          stringArrays[key] = documentMetadata[key];\n          delete documentMetadata[key];\n        }\n      }\n      const metadata: {\n        [key: string]: string | number | boolean | string[] | null;\n      } = {\n        ...flatten(documentMetadata),\n        ...stringArrays,\n        [this.textKey]: documents[idx].pageContent,\n      };\n      // Pinecone doesn't support null values, so we remove them\n      for (const key of Object.keys(metadata)) {\n        if (metadata[key] == null) {\n          delete metadata[key];\n        } else if (\n          typeof metadata[key] === \"object\" &&\n          Object.keys(metadata[key] as unknown as object).length === 0\n        ) {\n          delete metadata[key];\n        }\n      }\n\n      return {\n        id: documentIds[idx],\n        metadata,\n        values,\n      } as PineconeRecord<RecordMetadata>;\n    });\n\n    const optionsNamespace =\n      !Array.isArray(options) && options?.namespace\n        ? options.namespace\n        : this.namespace;\n    const namespace = this.pineconeIndex.namespace(optionsNamespace ?? \"\");\n    // Pinecone recommends a limit of 100 vectors per upsert request\n    const chunkSize = 100;\n    const chunkedVectors = chunkArray(pineconeVectors, chunkSize);\n    const batchRequests = chunkedVectors.map((chunk) =>\n      this.caller.call(async () => {\n        try {\n          await namespace.upsert(chunk);\n          // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        } catch (e: any) {\n          if (e.message.includes(\"404\")) {\n            e.statusCode = 404;\n          }\n          throw e;\n        }\n      })\n    );\n\n    await Promise.all(batchRequests);\n\n    return documentIds;\n  }\n\n  /**\n   * Method that deletes vectors from the Pinecone database.\n   * @param params Parameters for the delete operation.\n   * @returns Promise that resolves when the delete operation is complete.\n   */\n  async delete(params: PineconeDeleteParams): Promise<void> {\n    const { deleteAll, ids, filter } = params;\n    const optionsNamespace = params.namespace ?? this.namespace;\n    const namespace = this.pineconeIndex.namespace(optionsNamespace ?? \"\");\n\n    if (deleteAll) {\n      await namespace.deleteAll();\n    } else if (ids) {\n      const batchSize = 1000;\n      for (let i = 0; i < ids.length; i += batchSize) {\n        const batchIds = ids.slice(i, i + batchSize);\n        await namespace.deleteMany(batchIds);\n      }\n    } else if (filter) {\n      await namespace.deleteMany(filter);\n    } else {\n      throw new Error(\"Either ids or delete_all must be provided.\");\n    }\n  }\n\n  protected async _runPineconeQuery(\n    query: number[],\n    k: number,\n    filter?: PineconeMetadata,\n    options?: { includeValues: boolean }\n  ) {\n    if (filter && this.filter) {\n      throw new Error(\"cannot provide both `filter` and `this.filter`\");\n    }\n    let _filter = filter ?? this.filter;\n\n    let optionsNamespace = this.namespace ?? \"\";\n    if (_filter && \"namespace\" in _filter) {\n      optionsNamespace = _filter.namespace;\n      delete _filter.namespace;\n    }\n\n    if (Object.keys(_filter ?? {}).length === 0) {\n      _filter = undefined;\n    }\n\n    const namespace = this.pineconeIndex.namespace(optionsNamespace ?? \"\");\n\n    const results = await namespace.query({\n      includeMetadata: true,\n      topK: k,\n      vector: query,\n      filter: _filter,\n      ...options,\n    });\n    return results;\n  }\n\n  /**\n   * Format the matching results from the Pinecone query.\n   * @param matches Matching results from the Pinecone query.\n   * @returns An array of arrays, where each inner array contains a document and its score.\n   */\n  private _formatMatches(\n    matches: ScoredPineconeRecord<RecordMetadata>[] = []\n  ): [Document, number][] {\n    const documentsWithScores: [Document, number][] = [];\n\n    for (const record of matches) {\n      const {\n        id,\n        score,\n        metadata: { [this.textKey]: pageContent, ...metadata } = {\n          [this.textKey]: \"\",\n        },\n      } = record;\n\n      if (score) {\n        documentsWithScores.push([\n          new Document({\n            id,\n            pageContent: pageContent?.toString() ?? \"\",\n            metadata,\n          }),\n          score,\n        ]);\n      }\n    }\n\n    return documentsWithScores;\n  }\n\n  /**\n   * Method that performs a similarity search in the Pinecone database and\n   * returns the results along with their scores.\n   * @param query Query vector for the similarity search.\n   * @param k Number of top results to return.\n   * @param filter Optional filter to apply to the search.\n   * @returns Promise that resolves with an array of documents and their scores.\n   */\n  async similaritySearchVectorWithScore(\n    query: number[],\n    k: number,\n    filter?: PineconeMetadata\n  ): Promise<[Document, number][]> {\n    const { matches = [] } = await this._runPineconeQuery(query, k, filter);\n    const records = this._formatMatches(matches);\n\n    return records;\n  }\n\n  /**\n   * Return documents selected using the maximal marginal relevance.\n   * Maximal marginal relevance optimizes for similarity to the query AND diversity\n   * among selected documents.\n   *\n   * @param {string} query - Text to look up documents similar to.\n   * @param {number} options.k - Number of documents to return.\n   * @param {number} options.fetchK=20 - Number of documents to fetch before passing to the MMR algorithm.\n   * @param {number} options.lambda=0.5 - Number between 0 and 1 that determines the degree of diversity among the results,\n   *                 where 0 corresponds to maximum diversity and 1 to minimum diversity.\n   * @param {PineconeMetadata} options.filter - Optional filter to apply to the search.\n   *\n   * @returns {Promise<DocumentInterface[]>} - List of documents selected by maximal marginal relevance.\n   */\n  async maxMarginalRelevanceSearch(\n    query: string,\n    options: MaxMarginalRelevanceSearchOptions<this[\"FilterType\"]>\n  ): Promise<DocumentInterface[]> {\n    const queryEmbedding = await this.embeddings.embedQuery(query);\n\n    const results = await this._runPineconeQuery(\n      queryEmbedding,\n      options.fetchK ?? 20,\n      options.filter,\n      { includeValues: true }\n    );\n\n    const { matches = [] } = results;\n    const embeddingList = matches.map((match) => match.values!);\n\n    const mmrIndexes = maximalMarginalRelevance(\n      queryEmbedding,\n      embeddingList,\n      options.lambda,\n      options.k\n    );\n\n    const topMmrMatches = mmrIndexes.map((idx) => matches[idx]);\n    const records = this._formatMatches(topMmrMatches);\n    return records.map(([doc, _score]) => doc);\n  }\n\n  /**\n   * Static method that creates a new instance of the PineconeStore class\n   * from texts.\n   * @param texts Array of texts to add to the Pinecone database.\n   * @param metadatas Metadata associated with the texts.\n   * @param embeddings Embeddings to use for the texts.\n   * @param dbConfig Configuration for the Pinecone database.\n   * @returns Promise that resolves with a new instance of the PineconeStore class.\n   */\n  static async fromTexts(\n    texts: string[],\n    metadatas: object[] | object,\n    embeddings: EmbeddingsInterface,\n    dbConfig:\n      | {\n          pineconeIndex: PineconeIndex;\n          textKey?: string;\n          namespace?: string | undefined;\n        }\n      | PineconeStoreParams\n  ): Promise<PineconeStore> {\n    const docs: Document[] = [];\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    const args: PineconeStoreParams = {\n      pineconeIndex: dbConfig.pineconeIndex,\n      textKey: dbConfig.textKey,\n      namespace: dbConfig.namespace,\n    };\n    return PineconeStore.fromDocuments(docs, embeddings, args);\n  }\n\n  /**\n   * Static method that creates a new instance of the PineconeStore class\n   * from documents.\n   * @param docs Array of documents to add to the Pinecone database.\n   * @param embeddings Embeddings to use for the documents.\n   * @param dbConfig Configuration for the Pinecone database.\n   * @returns Promise that resolves with a new instance of the PineconeStore class.\n   */\n  static async fromDocuments(\n    docs: Document[],\n    embeddings: EmbeddingsInterface,\n    dbConfig: PineconeStoreParams\n  ): Promise<PineconeStore> {\n    const args = dbConfig;\n    args.textKey = dbConfig.textKey ?? \"text\";\n\n    const instance = new this(embeddings, args);\n    await instance.addDocuments(docs);\n    return instance;\n  }\n\n  /**\n   * Static method that creates a new instance of the PineconeStore class\n   * from an existing index.\n   * @param embeddings Embeddings to use for the documents.\n   * @param dbConfig Configuration for the Pinecone database.\n   * @returns Promise that resolves with a new instance of the PineconeStore class.\n   */\n  static async fromExistingIndex(\n    embeddings: EmbeddingsInterface,\n    dbConfig: PineconeStoreParams\n  ): Promise<PineconeStore> {\n    const instance = new this(embeddings, dbConfig);\n    return instance;\n  }\n}\n"],"mappings":"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"}