{"version":3,"file":"llms.cjs","names":["LLM","AsyncCaller","GenerationChunk","MistralAIHTTPClient"],"sources":["../src/llms.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { BaseLLMParams, LLM } from \"@langchain/core/language_models/llms\";\nimport { type BaseLanguageModelCallOptions } from \"@langchain/core/language_models/base\";\nimport { GenerationChunk, LLMResult } from \"@langchain/core/outputs\";\nimport { FIMCompletionRequest as MistralAIFIMCompletionRequest } from \"@mistralai/mistralai/models/components/fimcompletionrequest.js\";\nimport { FIMCompletionStreamRequest as MistralAIFIMCompletionStreamRequest } from \"@mistralai/mistralai/models/components/fimcompletionstreamrequest.js\";\nimport { FIMCompletionResponse as MistralAIFIMCompletionResponse } from \"@mistralai/mistralai/models/components/fimcompletionresponse.js\";\nimport { ChatCompletionRequest as MistralAIChatCompletionRequest } from \"@mistralai/mistralai/models/components/chatcompletionrequest.js\";\nimport { ChatCompletionStreamRequest as MistralAIChatCompletionStreamRequest } from \"@mistralai/mistralai/models/components/chatcompletionstreamrequest.js\";\nimport { ChatCompletionResponse as MistralAIChatCompletionResponse } from \"@mistralai/mistralai/models/components/chatcompletionresponse.js\";\nimport { ChatCompletionChoice as MistralAIChatCompletionChoice } from \"@mistralai/mistralai/models/components/chatcompletionchoice.js\";\nimport { CompletionEvent as MistralAIChatCompletionEvent } from \"@mistralai/mistralai/models/components/completionevent.js\";\nimport { CompletionChunk as MistralAICompetionChunk } from \"@mistralai/mistralai/models/components/completionchunk.js\";\nimport {\n  BeforeRequestHook,\n  RequestErrorHook,\n  ResponseHook,\n  HTTPClient as MistralAIHTTPClient,\n} from \"@mistralai/mistralai/lib/http.js\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { chunkArray } from \"@langchain/core/utils/chunk_array\";\nimport { AsyncCaller } from \"@langchain/core/utils/async_caller\";\n\nexport interface MistralAICallOptions extends BaseLanguageModelCallOptions {\n  /**\n   * Optional text/code that adds more context for the model.\n   * When given a prompt and a suffix the model will fill what\n   * is between them. When suffix is not provided, the model\n   * will simply execute completion starting with prompt.\n   */\n  suffix?: string;\n}\n\nexport interface MistralAIInput extends BaseLLMParams {\n  /**\n   * The name of the model to use.\n   * @default \"codestral-latest\"\n   */\n  model?: string;\n  /**\n   * The API key to use.\n   * @default {process.env.MISTRAL_API_KEY}\n   */\n  apiKey?: 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   * What sampling temperature to use, between 0.0 and 2.0.\n   * Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.\n   * @default {0.7}\n   */\n  temperature?: number;\n  /**\n   * Nucleus sampling, where the model considers the results of the tokens with `topP` probability mass.\n   * So 0.1 means only the tokens comprising the top 10% probability mass are considered.\n   * Should be between 0 and 1.\n   * @default {1}\n   */\n  topP?: number;\n  /**\n   * The maximum number of tokens to generate in the completion.\n   * The token count of your prompt plus maxTokens cannot exceed the model's context length.\n   */\n  maxTokens?: number;\n  /**\n   * Whether or not to stream the response.\n   * @default {false}\n   */\n  streaming?: boolean;\n  /**\n   * The seed to use for random sampling. If set, different calls will generate deterministic results.\n   * Alias for `seed`\n   */\n  randomSeed?: number;\n  /**\n   * Batch size to use when passing multiple documents to generate\n   */\n  batchSize?: number;\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   * Whether to use the Fill-In-Middle (FIM) API for code completion.\n   * When true, uses `client.fim.complete()` / `client.fim.stream()`.\n   * When false, uses `client.chat.complete()` / `client.chat.stream()` with the prompt wrapped as a user message.\n   *\n   * FIM is only supported for code models like `codestral-latest`.\n   * For general-purpose models like `mistral-large-latest`, set this to `false`.\n   *\n   * @default true for codestral models, false for other models\n   */\n  useFim?: boolean;\n}\n\n/**\n * Helper function to determine if a model is a codestral (FIM-compatible) model.\n * @param model The model name to check.\n * @returns True if the model is a codestral model, false otherwise.\n */\nfunction isCodestralModel(model: string): boolean {\n  const lowerModel = model.toLowerCase();\n  return lowerModel.includes(\"codestral\");\n}\n\n/**\n * MistralAI completions LLM.\n */\nexport class MistralAI\n  extends LLM<MistralAICallOptions>\n  implements MistralAIInput\n{\n  static lc_name() {\n    return \"MistralAI\";\n  }\n\n  lc_namespace = [\"langchain\", \"llms\", \"mistralai\"];\n\n  lc_serializable = true;\n\n  model = \"codestral-latest\";\n\n  temperature = 0;\n\n  topP?: number;\n\n  maxTokens?: number | undefined;\n\n  randomSeed?: number | undefined;\n\n  streaming = false;\n\n  batchSize = 20;\n\n  apiKey: string;\n\n  /**\n   * @deprecated use serverURL instead\n   */\n  endpoint: string;\n\n  serverURL?: string;\n\n  maxRetries?: number;\n\n  maxConcurrency?: number;\n\n  beforeRequestHooks?: Array<BeforeRequestHook>;\n\n  requestErrorHooks?: Array<RequestErrorHook>;\n\n  responseHooks?: Array<ResponseHook>;\n\n  httpClient?: MistralAIHTTPClient;\n\n  useFim: boolean;\n\n  constructor(fields?: MistralAIInput) {\n    super(fields ?? {});\n    this._addVersion(\"@langchain/mistralai\", __PKG_VERSION__);\n\n    this.model = fields?.model ?? this.model;\n    this.temperature = fields?.temperature ?? this.temperature;\n    this.topP = fields?.topP ?? this.topP;\n    this.maxTokens = fields?.maxTokens ?? this.maxTokens;\n    this.randomSeed = fields?.randomSeed ?? this.randomSeed;\n    this.batchSize = fields?.batchSize ?? this.batchSize;\n    this.streaming = fields?.streaming ?? this.streaming;\n    this.serverURL = fields?.serverURL ?? this.serverURL;\n    this.maxRetries = fields?.maxRetries;\n    this.maxConcurrency = fields?.maxConcurrency;\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    // Default useFim based on model - true for codestral models, false for others\n    this.useFim = fields?.useFim ?? isCodestralModel(this.model);\n\n    const apiKey = fields?.apiKey ?? getEnvironmentVariable(\"MISTRAL_API_KEY\");\n    if (!apiKey) {\n      throw new Error(\n        `MistralAI requires an API key to be set.\nEither provide one via the \"apiKey\" field in the constructor, or set the \"MISTRAL_API_KEY\" environment variable.`\n      );\n    }\n    this.apiKey = apiKey;\n\n    this.addAllHooksToHttpClient();\n  }\n\n  get lc_secrets(): { [key: string]: string } | undefined {\n    return {\n      apiKey: \"MISTRAL_API_KEY\",\n    };\n  }\n\n  get lc_aliases(): { [key: string]: string } | undefined {\n    return {\n      apiKey: \"mistral_api_key\",\n    };\n  }\n\n  _llmType() {\n    return \"mistralai\";\n  }\n\n  invocationParams(\n    options: this[\"ParsedCallOptions\"]\n  ): Omit<\n    MistralAIFIMCompletionRequest | MistralAIFIMCompletionStreamRequest,\n    \"prompt\"\n  > {\n    return {\n      model: this.model,\n      suffix: options.suffix,\n      temperature: this.temperature,\n      maxTokens: this.maxTokens,\n      topP: this.topP,\n      randomSeed: this.randomSeed,\n      stop: options.stop,\n    };\n  }\n\n  /**\n   * For some given input string and options, return a string output.\n   *\n   * Despite the fact that `invoke` is overridden below, we still need this\n   * in order to handle public APi calls to `generate()`.\n   */\n  async _call(\n    prompt: string,\n    options: this[\"ParsedCallOptions\"]\n  ): Promise<string> {\n    const params = {\n      ...this.invocationParams(options),\n      prompt,\n    };\n    const result = await this.completionWithRetry(params, options, false);\n    let content = result?.choices?.[0].message.content ?? \"\";\n    if (Array.isArray(content)) {\n      content = content[0].type === \"text\" ? content[0].text : \"\";\n    }\n    return content;\n  }\n\n  async _generate(\n    prompts: string[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): Promise<LLMResult> {\n    const subPrompts = chunkArray(prompts, this.batchSize);\n    const choices: MistralAIChatCompletionChoice[][] = [];\n\n    const params = this.invocationParams(options);\n\n    for (let i = 0; i < subPrompts.length; i += 1) {\n      const data = await (async () => {\n        if (this.streaming) {\n          const responseData: Array<\n            { choices: MistralAIChatCompletionChoice[] } & Partial<\n              Omit<MistralAICompetionChunk, \"choices\">\n            >\n          > = [];\n          for (let x = 0; x < subPrompts[i].length; x += 1) {\n            const choices: MistralAIChatCompletionChoice[] = [];\n            let response:\n              | Omit<MistralAICompetionChunk, \"choices\" | \"usage\">\n              | undefined;\n            const stream = await this.completionWithRetry(\n              {\n                ...params,\n                prompt: subPrompts[i][x],\n              },\n              options,\n              true\n            );\n            for await (const { data } of stream) {\n              // on the first message set the response properties\n              if (!response) {\n                response = {\n                  id: data.id,\n                  object: \"chat.completion\",\n                  created: data.created,\n                  model: data.model,\n                };\n              }\n\n              // on all messages, update choice\n              for (const part of data.choices) {\n                let content = part.delta.content ?? \"\";\n                // Convert MistralContentChunk data into a string\n                if (Array.isArray(content)) {\n                  let strContent = \"\";\n                  for (const contentChunk of content) {\n                    if (contentChunk.type === \"text\") {\n                      strContent += contentChunk.text;\n                    } else if (contentChunk.type === \"image_url\") {\n                      const imageURL =\n                        typeof contentChunk.imageUrl === \"string\"\n                          ? contentChunk.imageUrl\n                          : contentChunk.imageUrl.url;\n                      strContent += imageURL;\n                    }\n                  }\n                  content = strContent;\n                }\n                if (!choices[part.index]) {\n                  choices[part.index] = {\n                    index: part.index,\n                    message: {\n                      role: \"assistant\",\n                      content,\n                      toolCalls: null,\n                    },\n                    finishReason: part.finishReason ?? \"length\",\n                  };\n                } else {\n                  const choice = choices[part.index];\n                  choice.message.content += content;\n                  choice.finishReason = part.finishReason ?? \"length\";\n                }\n                // oxlint-disable-next-line no-void\n                void runManager?.handleLLMNewToken(content, {\n                  prompt: part.index,\n                  completion: part.index,\n                });\n              }\n            }\n            if (options.signal?.aborted) {\n              throw new Error(\"AbortError\");\n            }\n            responseData.push({\n              ...response,\n              choices,\n            });\n          }\n          return responseData;\n        } else {\n          const responseData: Array<MistralAIFIMCompletionResponse> = [];\n          for (let x = 0; x < subPrompts[i].length; x += 1) {\n            const res = await this.completionWithRetry(\n              {\n                ...params,\n                prompt: subPrompts[i][x],\n              },\n              options,\n              false\n            );\n            responseData.push(res);\n          }\n          return responseData;\n        }\n      })();\n\n      choices.push(...data.map((d) => d.choices ?? []));\n    }\n\n    const generations = choices.map((promptChoices) =>\n      promptChoices.map((choice) => {\n        let text = choice.message?.content ?? \"\";\n        if (Array.isArray(text)) {\n          text = text[0].type === \"text\" ? text[0].text : \"\";\n        }\n        return {\n          text,\n          generationInfo: {\n            finishReason: choice.finishReason,\n          },\n        };\n      })\n    );\n    return {\n      generations,\n    };\n  }\n\n  async completionWithRetry(\n    request: MistralAIFIMCompletionRequest,\n    options: this[\"ParsedCallOptions\"],\n    stream: false\n  ): Promise<MistralAIFIMCompletionResponse | MistralAIChatCompletionResponse>;\n\n  async completionWithRetry(\n    request: MistralAIFIMCompletionStreamRequest,\n    options: this[\"ParsedCallOptions\"],\n    stream: true\n  ): Promise<AsyncIterable<MistralAIChatCompletionEvent>>;\n\n  async completionWithRetry(\n    request:\n      | MistralAIFIMCompletionRequest\n      | MistralAIFIMCompletionStreamRequest,\n    options: this[\"ParsedCallOptions\"],\n    stream: boolean\n  ): Promise<\n    | MistralAIFIMCompletionResponse\n    | MistralAIChatCompletionResponse\n    | AsyncIterable<MistralAIChatCompletionEvent>\n  > {\n    const { Mistral } = await this.imports();\n    const caller = new AsyncCaller({\n      maxConcurrency: options.maxConcurrency || this.maxConcurrency,\n      maxRetries: this.maxRetries,\n    });\n    const client = new Mistral({\n      apiKey: this.apiKey,\n      serverURL: this.serverURL,\n      timeoutMs: options.timeout,\n      // If httpClient exists, pass it into constructor\n      ...(this.httpClient ? { httpClient: this.httpClient } : {}),\n    });\n    return caller.callWithOptions(\n      {\n        signal: options.signal,\n      },\n      async () => {\n        try {\n          let res:\n            | MistralAIFIMCompletionResponse\n            | MistralAIChatCompletionResponse\n            | AsyncIterable<MistralAIChatCompletionEvent>;\n\n          if (this.useFim) {\n            // Use FIM API for code completion models like codestral\n            if (stream) {\n              // The Mistral SDK requires `stream: true` to be explicitly set\n              // in the request body for streaming to work properly\n              res = await client.fim.stream({ ...request, stream: true });\n            } else {\n              res = await client.fim.complete(request);\n            }\n          } else {\n            // Use Chat API for general-purpose models\n            // Convert the prompt to a chat message format\n            const chatRequest:\n              | MistralAIChatCompletionRequest\n              | MistralAIChatCompletionStreamRequest = {\n              model: request.model,\n              messages: [{ role: \"user\", content: request.prompt }],\n              temperature: request.temperature,\n              maxTokens: request.maxTokens,\n              topP: request.topP,\n              randomSeed: request.randomSeed,\n              stop: request.stop,\n            };\n            if (stream) {\n              // The Mistral SDK requires `stream: true` to be explicitly set\n              // in the request body for streaming to work properly\n              res = await client.chat.stream({ ...chatRequest, stream: true });\n            } else {\n              res = await client.chat.complete(chatRequest);\n            }\n          }\n          return res;\n          // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n        } catch (e: any) {\n          if (\n            e.message?.includes(\"status: 400\") ||\n            e.message?.toLowerCase().includes(\"status 400\") ||\n            e.message?.includes(\"validation failed\")\n          ) {\n            e.status = 400;\n          }\n          throw e;\n        }\n      }\n    );\n  }\n\n  async *_streamResponseChunks(\n    prompt: string,\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<GenerationChunk> {\n    const params = {\n      ...this.invocationParams(options),\n      prompt,\n    };\n    const stream = await this.completionWithRetry(params, options, true);\n    for await (const message of stream) {\n      const { data } = message;\n      const choice = data?.choices[0];\n      if (!choice) {\n        continue;\n      }\n      let text = choice.delta.content ?? \"\";\n      if (Array.isArray(text)) {\n        text = text[0].type === \"text\" ? text[0].text : \"\";\n      }\n      const chunk = new GenerationChunk({\n        text,\n        generationInfo: {\n          finishReason: choice.finishReason,\n          tokenUsage: data.usage,\n        },\n      });\n      yield chunk;\n      // oxlint-disable-next-line no-void\n      void runManager?.handleLLMNewToken(chunk.text ?? \"\");\n    }\n    if (options.signal?.aborted) {\n      throw new Error(\"AbortError\");\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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"}