{"version":3,"file":"embeddings.cjs","names":["Embeddings","MistralAIHTTPClient"],"sources":["../src/embeddings.ts"],"sourcesContent":["import { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { Embeddings, type EmbeddingsParams } from \"@langchain/core/embeddings\";\nimport { chunkArray } from \"@langchain/core/utils/chunk_array\";\nimport { EmbeddingRequest as MistralAIEmbeddingsRequest } from \"@mistralai/mistralai/src/models/components/embeddingrequest.js\";\nimport { EmbeddingResponse as MistralAIEmbeddingsResponse } from \"@mistralai/mistralai/src/models/components/embeddingresponse.js\";\nimport {\n  BeforeRequestHook,\n  RequestErrorHook,\n  ResponseHook,\n  HTTPClient as MistralAIHTTPClient,\n} from \"@mistralai/mistralai/lib/http.js\";\n\n/**\n * Interface for MistralAIEmbeddings parameters. Extends EmbeddingsParams and\n * defines additional parameters specific to the MistralAIEmbeddings class.\n */\nexport interface MistralAIEmbeddingsParams extends EmbeddingsParams {\n  /**\n   * The API key to use.\n   * @default {process.env.MISTRAL_API_KEY}\n   */\n  apiKey?: string;\n  /**\n   * The name of the model to use.\n   * Alias for `model`.\n   * @default {\"mistral-embed\"}\n   */\n  modelName?: string;\n  /**\n   * The name of the model to use.\n   * @default {\"mistral-embed\"}\n   */\n  model?: string;\n  /**\n   * The format of the output data.\n   * @default {\"float\"}\n   */\n  encodingFormat?: string;\n  /**\n   * Override the default server URL used by the Mistral SDK.\n   * @deprecated use serverURL instead\n   */\n  endpoint?: string;\n  /**\n   * Override the default server URL used by the Mistral SDK.\n   */\n  serverURL?: string;\n  /**\n   * The maximum number of documents to embed in a single request.\n   * @default {512}\n   */\n  batchSize?: number;\n  /**\n   * Whether to strip new lines from the input text. This is recommended,\n   * but may not be suitable for all use cases.\n   * @default {true}\n   */\n  stripNewLines?: boolean;\n  /**\n   * A list of custom hooks that must follow (req: Request) => Awaitable<Request | void>\n   * They are automatically added when a ChatMistralAI instance is created\n   */\n  beforeRequestHooks?: BeforeRequestHook[];\n  /**\n   * A list of custom hooks that must follow (err: unknown, req: Request) => Awaitable<void>\n   * They are automatically added when a ChatMistralAI instance is created\n   */\n  requestErrorHooks?: RequestErrorHook[];\n  /**\n   * A list of custom hooks that must follow (res: Response, req: Request) => Awaitable<void>\n   * They are automatically added when a ChatMistralAI instance is created\n   */\n  responseHooks?: ResponseHook[];\n  /**\n   * Optional custom HTTP client to manage API requests\n   * Allows users to add custom fetch implementations, hooks, as well as error and response processing.\n   */\n  httpClient?: MistralAIHTTPClient;\n}\n\n/**\n * Class for generating embeddings using the MistralAI API.\n */\nexport class MistralAIEmbeddings\n  extends Embeddings\n  implements MistralAIEmbeddingsParams\n{\n  modelName = \"mistral-embed\";\n\n  model = \"mistral-embed\";\n\n  encodingFormat = \"float\";\n\n  batchSize = 512;\n\n  stripNewLines = true;\n\n  apiKey: string;\n\n  /**\n   * @deprecated use serverURL instead\n   */\n  endpoint: string;\n\n  serverURL?: string;\n\n  beforeRequestHooks?: Array<BeforeRequestHook>;\n\n  requestErrorHooks?: Array<RequestErrorHook>;\n\n  responseHooks?: Array<ResponseHook>;\n\n  httpClient?: MistralAIHTTPClient;\n\n  constructor(fields?: Partial<MistralAIEmbeddingsParams>) {\n    super(fields ?? {});\n    const apiKey = fields?.apiKey ?? getEnvironmentVariable(\"MISTRAL_API_KEY\");\n    if (!apiKey) {\n      throw new Error(\"API key missing for MistralAI, but it is required.\");\n    }\n    this.apiKey = apiKey;\n    this.serverURL = fields?.serverURL ?? this.serverURL;\n    this.modelName = fields?.model ?? fields?.modelName ?? this.model;\n    this.model = this.modelName;\n    this.encodingFormat = fields?.encodingFormat ?? this.encodingFormat;\n    this.batchSize = fields?.batchSize ?? this.batchSize;\n    this.stripNewLines = fields?.stripNewLines ?? this.stripNewLines;\n    this.beforeRequestHooks =\n      fields?.beforeRequestHooks ?? this.beforeRequestHooks;\n    this.requestErrorHooks =\n      fields?.requestErrorHooks ?? this.requestErrorHooks;\n    this.responseHooks = fields?.responseHooks ?? this.responseHooks;\n    this.httpClient = fields?.httpClient ?? this.httpClient;\n    this.addAllHooksToHttpClient();\n  }\n\n  /**\n   * Method to generate embeddings for an array of documents. Splits the\n   * documents into batches and makes requests to the MistralAI API to generate\n   * embeddings.\n   * @param {Array<string>} texts Array of documents to generate embeddings for.\n   * @returns {Promise<number[][]>} Promise that resolves to a 2D array of embeddings for each document.\n   */\n  async embedDocuments(texts: string[]): Promise<number[][]> {\n    const batches = chunkArray(\n      this.stripNewLines ? texts.map((t) => t.replace(/\\n/g, \" \")) : texts,\n      this.batchSize\n    );\n\n    const batchRequests = batches.map((batch) =>\n      this.embeddingWithRetry(batch)\n    );\n    const batchResponses = await Promise.all(batchRequests);\n\n    const embeddings: number[][] = [];\n    for (let i = 0; i < batchResponses.length; i += 1) {\n      const batch = batches[i];\n      const { data: batchResponse } = batchResponses[i];\n      for (let j = 0; j < batch.length; j += 1) {\n        embeddings.push(batchResponse[j].embedding ?? []);\n      }\n    }\n    return embeddings;\n  }\n\n  /**\n   * Method to generate an embedding for a single document. Calls the\n   * embeddingWithRetry method with the document as the input.\n   * @param {string} text Document to generate an embedding for.\n   * @returns {Promise<number[]>} Promise that resolves to an embedding for the document.\n   */\n  async embedQuery(text: string): Promise<number[]> {\n    const { data } = await this.embeddingWithRetry(\n      this.stripNewLines ? text.replace(/\\n/g, \" \") : text\n    );\n    return data[0].embedding ?? [];\n  }\n\n  /**\n   * Private method to make a request to the MistralAI API to generate\n   * embeddings. Handles the retry logic and returns the response from the\n   * API.\n   * @param {string | Array<string>} inputs Text to send to the MistralAI API.\n   * @returns {Promise<MistralAIEmbeddingsResponse>} Promise that resolves to the response from the API.\n   */\n  private async embeddingWithRetry(\n    inputs: string | Array<string>\n  ): Promise<MistralAIEmbeddingsResponse> {\n    const { Mistral } = await this.imports();\n    const client = new Mistral({\n      apiKey: this.apiKey,\n      serverURL: this.serverURL,\n      // If httpClient exists, pass it into constructor\n      ...(this.httpClient ? { httpClient: this.httpClient } : {}),\n    });\n    const embeddingsRequest: MistralAIEmbeddingsRequest = {\n      model: this.model,\n      inputs,\n      encodingFormat: this.encodingFormat,\n    };\n    return this.caller.call(async () => {\n      const res = await client.embeddings.create(embeddingsRequest);\n      return res;\n    });\n  }\n\n  addAllHooksToHttpClient() {\n    try {\n      // To prevent duplicate hooks\n      this.removeAllHooksFromHttpClient();\n\n      // If the user wants to use hooks, but hasn't created an HTTPClient yet\n      const hasHooks = [\n        this.beforeRequestHooks,\n        this.requestErrorHooks,\n        this.responseHooks,\n      ].some((hook) => hook && hook.length > 0);\n      if (hasHooks && !this.httpClient) {\n        this.httpClient = new MistralAIHTTPClient();\n      }\n\n      if (this.beforeRequestHooks) {\n        for (const hook of this.beforeRequestHooks) {\n          this.httpClient?.addHook(\"beforeRequest\", hook);\n        }\n      }\n\n      if (this.requestErrorHooks) {\n        for (const hook of this.requestErrorHooks) {\n          this.httpClient?.addHook(\"requestError\", hook);\n        }\n      }\n\n      if (this.responseHooks) {\n        for (const hook of this.responseHooks) {\n          this.httpClient?.addHook(\"response\", hook);\n        }\n      }\n    } catch {\n      throw new Error(\"Error in adding all hooks\");\n    }\n  }\n\n  removeAllHooksFromHttpClient() {\n    try {\n      if (this.beforeRequestHooks) {\n        for (const hook of this.beforeRequestHooks) {\n          this.httpClient?.removeHook(\"beforeRequest\", hook);\n        }\n      }\n\n      if (this.requestErrorHooks) {\n        for (const hook of this.requestErrorHooks) {\n          this.httpClient?.removeHook(\"requestError\", hook);\n        }\n      }\n\n      if (this.responseHooks) {\n        for (const hook of this.responseHooks) {\n          this.httpClient?.removeHook(\"response\", hook);\n        }\n      }\n    } catch {\n      throw new Error(\"Error in removing hooks\");\n    }\n  }\n\n  removeHookFromHttpClient(\n    hook: BeforeRequestHook | RequestErrorHook | ResponseHook\n  ) {\n    try {\n      this.httpClient?.removeHook(\"beforeRequest\", hook as BeforeRequestHook);\n      this.httpClient?.removeHook(\"requestError\", hook as RequestErrorHook);\n      this.httpClient?.removeHook(\"response\", hook as ResponseHook);\n    } catch {\n      throw new Error(\"Error in removing hook\");\n    }\n  }\n\n  /** @ignore */\n  private async imports() {\n    const { Mistral } = await import(\"@mistralai/mistralai\");\n    return { Mistral };\n  }\n}\n"],"mappings":"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"}