{"version":3,"file":"chroma.cjs","names":["VectorStore","embeddings: EmbeddingsInterface","args: ChromaLibArgs","documents: Document[]","options?: { ids?: string[] }","vectors: number[][]","newMetadata: Document[\"metadata\"]","params: ChromaDeleteParams<this[\"FilterType\"]>","query: number[]","k: number","filter?: this[\"FilterType\"]","results: [Document, number][]","metadata: Document[\"metadata\"]","Document","texts: string[]","metadatas: object[] | object","dbConfig: ChromaLibArgs","docs: Document[]","collectionName?: string"],"sources":["../../src/vectorstores/chroma.ts"],"sourcesContent":["import * as uuid from \"uuid\";\nimport type {\n  ChromaClient as ChromaClientT,\n  ChromaClientArgs,\n  Collection,\n  CollectionConfiguration,\n  CollectionMetadata,\n  Where,\n} from \"chromadb\";\n\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { VectorStore } from \"@langchain/core/vectorstores\";\nimport { Document } from \"@langchain/core/documents\";\n\ntype SharedChromaLibArgs = {\n  numDimensions?: number;\n  collectionName?: string;\n  filter?: object;\n  collectionMetadata?: CollectionMetadata;\n  collectionConfiguration?: CollectionConfiguration;\n  chromaCloudAPIKey?: string;\n  clientParams?: Omit<ChromaClientArgs, \"path\">;\n};\n\n/**\n * Defines the arguments that can be passed to the `Chroma` class\n * constructor. It can either contain a `url` for the Chroma database, the\n * number of dimensions for the vectors (`numDimensions`), a\n * `collectionName` for the collection to be used in the database, and a\n * `filter` object; or it can contain an `index` which is an instance of\n * `ChromaClientT`, along with the `numDimensions`, `collectionName`, and\n * `filter`.\n */\nexport type ChromaLibArgs =\n  | ({\n      url?: string;\n    } & SharedChromaLibArgs)\n  | ({\n      index?: ChromaClientT;\n    } & SharedChromaLibArgs);\n\n/**\n * Defines the parameters for the `delete` method in the `Chroma` class.\n * It can either contain an array of `ids` of the documents to be deleted\n * or a `filter` object to specify the documents to be deleted.\n */\nexport interface ChromaDeleteParams<T> {\n  ids?: string[];\n  filter?: T;\n}\n\n/**\n * Chroma vector store integration.\n *\n * Setup:\n * Install `@langchain/community` and `chromadb`.\n *\n * ```bash\n * npm install @langchain/community chromadb\n * ```\n *\n * ## [Constructor args](https://api.js.langchain.com/classes/langchain_community_vectorstores_chroma.Chroma.html#constructor)\n *\n * <details open>\n * <summary><strong>Instantiate</strong></summary>\n *\n * ```typescript\n * import { Chroma } from '@langchain/community/vectorstores/chroma';\n * // Or other embeddings\n * import { OpenAIEmbeddings } from '@langchain/openai';\n *\n * const embeddings = new OpenAIEmbeddings({\n *   model: \"text-embedding-3-small\",\n * })\n *\n * const vectorStore = new Chroma(\n *   embeddings,\n *   {\n *     collectionName: \"foo\",\n *     host: \"localhost\",\n *   }\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 Chroma extends VectorStore {\n  declare FilterType: Where;\n\n  index?: ChromaClientT;\n\n  collection?: Collection;\n\n  collectionName: string;\n\n  collectionMetadata?: CollectionMetadata;\n\n  numDimensions?: number;\n\n  clientParams?: Omit<ChromaClientArgs, \"path\">;\n\n  url: string;\n\n  filter?: object;\n\n  _vectorstoreType(): string {\n    return \"chroma\";\n  }\n\n  constructor(embeddings: EmbeddingsInterface, args: ChromaLibArgs) {\n    super(embeddings, args);\n    this.numDimensions = args.numDimensions;\n    this.embeddings = embeddings;\n    this.collectionName = ensureCollectionName(args.collectionName);\n    this.collectionMetadata = args.collectionMetadata;\n    this.clientParams = args.clientParams || {};\n    if (\"index\" in args) {\n      this.index = args.index;\n    } else if (\"url\" in args) {\n      this.url = args.url || \"http://localhost:8000\";\n    }\n\n    if (args.chromaCloudAPIKey) {\n      this.clientParams.headers = {\n        ...(this.clientParams?.headers || {}),\n        \"x-chroma-token\": args.chromaCloudAPIKey,\n      };\n    }\n\n    this.filter = args.filter;\n  }\n\n  /**\n   * Adds documents to the Chroma database. The documents are first\n   * converted to vectors using the `embeddings` instance, and then added to\n   * the database.\n   * @param documents An array of `Document` instances to be added to the database.\n   * @param options Optional. An object containing an array of `ids` for the documents.\n   * @returns A promise that resolves when the documents have been added to the database.\n   */\n  async addDocuments(documents: Document[], options?: { ids?: 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   * Ensures that a collection exists in the Chroma database. If the\n   * collection does not exist, it is created.\n   * @returns A promise that resolves with the `Collection` instance.\n   */\n  async ensureCollection(): Promise<Collection> {\n    if (!this.collection) {\n      if (!this.index) {\n        this.index = new (await Chroma.imports()).ChromaClient({\n          path: this.url,\n          ...(this.clientParams ?? {}),\n        });\n      }\n      try {\n        this.collection = await this.index.getOrCreateCollection({\n          name: this.collectionName,\n          embeddingFunction: null,\n          ...(this.collectionMetadata && { metadata: this.collectionMetadata }),\n        });\n      } catch (err) {\n        throw new Error(`Chroma getOrCreateCollection error: ${err}`);\n      }\n    }\n\n    return this.collection;\n  }\n\n  /**\n   * Adds vectors to the Chroma database. The vectors are associated with\n   * the provided documents.\n   * @param vectors An array of vectors to be added to the database.\n   * @param documents An array of `Document` instances associated with the vectors.\n   * @param options Optional. An object containing an array of `ids` for the vectors.\n   * @returns A promise that resolves with an array of document IDs when the vectors have been added to the database.\n   */\n  async addVectors(\n    vectors: number[][],\n    documents: Document[],\n    options?: { ids?: string[] }\n  ) {\n    if (vectors.length === 0) {\n      return [];\n    }\n    if (this.numDimensions === undefined) {\n      this.numDimensions = vectors[0].length;\n    }\n    if (vectors.length !== documents.length) {\n      throw new Error(`Vectors and metadatas must have the same length`);\n    }\n    if (vectors[0].length !== this.numDimensions) {\n      throw new Error(\n        `Vectors must have the same length as the number of dimensions (${this.numDimensions})`\n      );\n    }\n\n    const documentIds =\n      options?.ids ?? Array.from({ length: vectors.length }, () => uuid.v1());\n    const collection = await this.ensureCollection();\n\n    const mappedMetadatas = documents.map(({ metadata }) => {\n      let locFrom;\n      let locTo;\n\n      if (metadata?.loc) {\n        if (metadata.loc.lines?.from !== undefined)\n          locFrom = metadata.loc.lines.from;\n        if (metadata.loc.lines?.to !== undefined) locTo = metadata.loc.lines.to;\n      }\n\n      const newMetadata: Document[\"metadata\"] = {\n        ...metadata,\n        ...(locFrom !== undefined && { locFrom }),\n        ...(locTo !== undefined && { locTo }),\n      };\n\n      if (newMetadata.loc) delete newMetadata.loc;\n\n      return newMetadata;\n    });\n\n    await collection.upsert({\n      ids: documentIds,\n      embeddings: vectors,\n      metadatas: mappedMetadatas,\n      documents: documents.map(({ pageContent }) => pageContent),\n    });\n    return documentIds;\n  }\n\n  /**\n   * Deletes documents from the Chroma database. The documents to be deleted\n   * can be specified by providing an array of `ids` or a `filter` object.\n   * @param params An object containing either an array of `ids` of the documents to be deleted or a `filter` object to specify the documents to be deleted.\n   * @returns A promise that resolves when the specified documents have been deleted from the database.\n   */\n  async delete(params: ChromaDeleteParams<this[\"FilterType\"]>): Promise<void> {\n    const collection = await this.ensureCollection();\n    if (Array.isArray(params.ids)) {\n      await collection.delete({ ids: params.ids });\n    } else if (params.filter) {\n      await collection.delete({\n        where: { ...params.filter },\n      });\n    } else {\n      throw new Error(`You must provide one of \"ids or \"filter\".`);\n    }\n  }\n\n  /**\n   * Searches for vectors in the Chroma database that are similar to the\n   * provided query vector. The search can be filtered using the provided\n   * `filter` object or the `filter` property of the `Chroma` instance.\n   * @param query The query vector.\n   * @param k The number of similar vectors to return.\n   * @param filter Optional. A `filter` object to filter the search results.\n   * @returns A promise that resolves with an array of tuples, each containing a `Document` instance and a similarity score.\n   */\n  async similaritySearchVectorWithScore(\n    query: number[],\n    k: number,\n    filter?: this[\"FilterType\"]\n  ) {\n    if (filter && this.filter) {\n      throw new Error(\"cannot provide both `filter` and `this.filter`\");\n    }\n    const _filter = filter ?? this.filter;\n    const where = _filter === undefined ? undefined : { ..._filter };\n\n    const collection = await this.ensureCollection();\n\n    // similaritySearchVectorWithScore supports one query vector at a time\n    // chroma supports multiple query vectors at a time\n    const result = await collection.query({\n      queryEmbeddings: [query],\n      nResults: k,\n      where,\n    });\n\n    const { ids, distances, documents, metadatas } = result;\n    if (!ids || !distances || !documents || !metadatas) {\n      return [];\n    }\n    // get the result data from the first and only query vector\n    const [firstIds] = ids;\n    const [firstDistances] = distances;\n    const [firstDocuments] = documents;\n    const [firstMetadatas] = metadatas;\n\n    if (firstDistances.some((item) => item === null)) {\n      return [];\n    }\n\n    const cleanDistances = firstDistances.filter((item) => item !== null);\n\n    const results: [Document, number][] = [];\n    for (let i = 0; i < firstIds.length; i += 1) {\n      let metadata: Document[\"metadata\"] = firstMetadatas?.[i] ?? {};\n\n      if (metadata.locFrom && metadata.locTo) {\n        metadata = {\n          ...metadata,\n          loc: {\n            lines: {\n              from: metadata.locFrom,\n              to: metadata.locTo,\n            },\n          },\n        };\n\n        delete metadata.locFrom;\n        delete metadata.locTo;\n      }\n\n      results.push([\n        new Document({\n          pageContent: firstDocuments?.[i] ?? \"\",\n          metadata,\n          id: firstIds[i],\n        }),\n        cleanDistances[i],\n      ]);\n    }\n    return results;\n  }\n\n  /**\n   * Creates a new `Chroma` instance from an array of text strings. The text\n   * strings are converted to `Document` instances and added to the Chroma\n   * database.\n   * @param texts An array of text strings.\n   * @param metadatas An array of metadata objects or a single metadata object. If an array is provided, it must have the same length as the `texts` array.\n   * @param embeddings An `Embeddings` instance used to generate embeddings for the documents.\n   * @param dbConfig A `ChromaLibArgs` object containing the configuration for the Chroma database.\n   * @returns A promise that resolves with a new `Chroma` instance.\n   */\n  static async fromTexts(\n    texts: string[],\n    metadatas: object[] | object,\n    embeddings: EmbeddingsInterface,\n    dbConfig: ChromaLibArgs\n  ): Promise<Chroma> {\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    return this.fromDocuments(docs, embeddings, dbConfig);\n  }\n\n  /**\n   * Creates a new `Chroma` instance from an array of `Document` instances.\n   * The documents are added to the Chroma database.\n   * @param docs An array of `Document` instances.\n   * @param embeddings An `Embeddings` instance used to generate embeddings for the documents.\n   * @param dbConfig A `ChromaLibArgs` object containing the configuration for the Chroma database.\n   * @returns A promise that resolves with a new `Chroma` instance.\n   */\n  static async fromDocuments(\n    docs: Document[],\n    embeddings: EmbeddingsInterface,\n    dbConfig: ChromaLibArgs\n  ): Promise<Chroma> {\n    const instance = new this(embeddings, dbConfig);\n    await instance.addDocuments(docs);\n    return instance;\n  }\n\n  /**\n   * Creates a new `Chroma` instance from an existing collection in the\n   * Chroma database.\n   * @param embeddings An `Embeddings` instance used to generate embeddings for the documents.\n   * @param dbConfig A `ChromaLibArgs` object containing the configuration for the Chroma database.\n   * @returns A promise that resolves with a new `Chroma` instance.\n   */\n  static async fromExistingCollection(\n    embeddings: EmbeddingsInterface,\n    dbConfig: ChromaLibArgs\n  ): Promise<Chroma> {\n    const instance = new this(embeddings, dbConfig);\n    await instance.ensureCollection();\n    return instance;\n  }\n\n  /** @ignore */\n  static async imports(): Promise<{\n    ChromaClient: typeof ChromaClientT;\n  }> {\n    try {\n      const { ChromaClient } = await import(\"chromadb\");\n      return { ChromaClient };\n    } catch {\n      throw new Error(\n        \"Please install chromadb as a dependency with, e.g. `npm install -S chromadb`\"\n      );\n    }\n  }\n}\n\n/**\n * Generates a unique collection name if none is provided.\n */\nfunction ensureCollectionName(collectionName?: string) {\n  if (!collectionName) {\n    return `langchain-${uuid.v4()}`;\n  }\n  return collectionName;\n}\n"],"mappings":"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"}