{"version":3,"file":"completions.cjs","names":["BaseChatOpenAI","getChatOpenAIModelParams","formatToOpenAIToolChoice","isReasoningModel","convertMessagesToCompletionsMessageParams","AIMessage","ChatGenerationChunk","AIMessageChunk","wrapOpenAIClientError","convertCompletionsDeltaToBaseMessageChunk","convertCompletionsMessageToBaseMessage"],"sources":["../../src/chat_models/completions.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n  AIMessage,\n  AIMessageChunk,\n  type BaseMessage,\n  isAIMessage,\n  type UsageMetadata,\n  type AIMessageFields,\n  BaseMessageChunk,\n} from \"@langchain/core/messages\";\nimport {\n  ChatGenerationChunk,\n  type ChatGeneration,\n  type ChatResult,\n} from \"@langchain/core/outputs\";\nimport { NewTokenIndices } from \"@langchain/core/callbacks/base\";\nimport { wrapOpenAIClientError } from \"../utils/client.js\";\nimport {\n  OpenAIToolChoice,\n  formatToOpenAIToolChoice,\n  _convertToOpenAITool,\n} from \"../utils/tools.js\";\nimport { isReasoningModel } from \"../utils/misc.js\";\nimport {\n  BaseChatOpenAI,\n  BaseChatOpenAICallOptions,\n  BaseChatOpenAIFields,\n  getChatOpenAIModelParams,\n} from \"./base.js\";\nimport {\n  convertCompletionsDeltaToBaseMessageChunk,\n  convertCompletionsMessageToBaseMessage,\n  convertMessagesToCompletionsMessageParams,\n} from \"../converters/completions.js\";\n\nexport interface ChatOpenAICompletionsCallOptions extends BaseChatOpenAICallOptions {}\n\ntype ChatCompletionsInvocationParams = Omit<\n  OpenAIClient.Chat.Completions.ChatCompletionCreateParams,\n  \"messages\"\n>;\n\n/**\n * OpenAI Completions API implementation.\n * @internal\n */\nexport class ChatOpenAICompletions<\n  CallOptions extends ChatOpenAICompletionsCallOptions =\n    ChatOpenAICompletionsCallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n  constructor(model: string, fields?: Omit<BaseChatOpenAIFields, \"model\">);\n  constructor(fields?: BaseChatOpenAIFields);\n  constructor(\n    modelOrFields?: string | BaseChatOpenAIFields,\n    fieldsArg?: Omit<BaseChatOpenAIFields, \"model\">\n  ) {\n    super(getChatOpenAIModelParams(modelOrFields, fieldsArg));\n  }\n\n  /** @internal */\n  override invocationParams(\n    options?: this[\"ParsedCallOptions\"],\n    extra?: { streaming?: boolean }\n  ): ChatCompletionsInvocationParams {\n    let strict: boolean | undefined;\n    if (options?.strict !== undefined) {\n      strict = options.strict;\n    } else if (this.supportsStrictToolCalling !== undefined) {\n      strict = this.supportsStrictToolCalling;\n    }\n\n    let streamOptionsConfig = {};\n    if (options?.stream_options !== undefined) {\n      streamOptionsConfig = { stream_options: options.stream_options };\n    } else if (this.streamUsage && (this.streaming || extra?.streaming)) {\n      streamOptionsConfig = { stream_options: { include_usage: true } };\n    }\n\n    const params: Partial<ChatCompletionsInvocationParams> = {\n      model: this.model,\n      temperature: this.temperature,\n      top_p: this.topP,\n      frequency_penalty: this.frequencyPenalty,\n      presence_penalty: this.presencePenalty,\n      logprobs: this.logprobs,\n      top_logprobs: this.topLogprobs,\n      n: this.n,\n      logit_bias: this.logitBias,\n      stop: options?.stop ?? this.stopSequences,\n      user: this.user,\n      // if include_usage is set or streamUsage then stream must be set to true.\n      stream: this.streaming,\n      functions: options?.functions,\n      function_call: options?.function_call,\n      tools: options?.tools?.length\n        ? options.tools.map((tool) =>\n            this._convertChatOpenAIToolToCompletionsTool(tool, { strict })\n          )\n        : undefined,\n      tool_choice: formatToOpenAIToolChoice(\n        options?.tool_choice as OpenAIToolChoice\n      ),\n      response_format: this._getResponseFormat(options?.response_format),\n      seed: options?.seed,\n      ...streamOptionsConfig,\n      parallel_tool_calls: options?.parallel_tool_calls,\n      ...(this.audio || options?.audio\n        ? { audio: this.audio || options?.audio }\n        : {}),\n      ...(this.modalities || options?.modalities\n        ? { modalities: this.modalities || options?.modalities }\n        : {}),\n      ...this.modelKwargs,\n      prompt_cache_key: options?.promptCacheKey ?? this.promptCacheKey,\n      prompt_cache_retention:\n        options?.promptCacheRetention ?? this.promptCacheRetention,\n      verbosity: options?.verbosity ?? this.verbosity,\n    };\n    if (options?.prediction !== undefined) {\n      params.prediction = options.prediction;\n    }\n    if (this.service_tier !== undefined) {\n      params.service_tier = this.service_tier;\n    }\n    if (options?.service_tier !== undefined) {\n      params.service_tier = options.service_tier;\n    }\n    const reasoning = this._getReasoningParams(options);\n    if (reasoning !== undefined && reasoning.effort !== undefined) {\n      params.reasoning_effort = reasoning.effort;\n    }\n    if (isReasoningModel(params.model)) {\n      params.max_completion_tokens =\n        this.maxTokens === -1 ? undefined : this.maxTokens;\n    } else {\n      params.max_tokens = this.maxTokens === -1 ? undefined : this.maxTokens;\n    }\n\n    return params as ChatCompletionsInvocationParams;\n  }\n\n  async _generate(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): Promise<ChatResult> {\n    options.signal?.throwIfAborted();\n    const usageMetadata = {} as UsageMetadata;\n    const params = this.invocationParams(options);\n    const messagesMapped: OpenAIClient.Chat.Completions.ChatCompletionMessageParam[] =\n      convertMessagesToCompletionsMessageParams({\n        messages,\n        model: this.model,\n      });\n\n    if (params.stream) {\n      const stream = this._streamResponseChunks(messages, options, runManager);\n      const finalChunks: Record<number, ChatGenerationChunk> = {};\n      for await (const chunk of stream) {\n        chunk.message.response_metadata = {\n          ...chunk.generationInfo,\n          ...chunk.message.response_metadata,\n        };\n        const index =\n          (chunk.generationInfo as NewTokenIndices)?.completion ?? 0;\n        if (finalChunks[index] === undefined) {\n          finalChunks[index] = chunk;\n        } else {\n          finalChunks[index] = finalChunks[index].concat(chunk);\n        }\n      }\n      const generations = Object.entries(finalChunks)\n        .sort(([aKey], [bKey]) => parseInt(aKey, 10) - parseInt(bKey, 10))\n        .map(([_, value]) => value);\n\n      const { functions, function_call } = this.invocationParams(options);\n\n      // OpenAI does not support token usage report under stream mode,\n      // fallback to estimation.\n\n      const promptTokenUsage = await this._getEstimatedTokenCountFromPrompt(\n        messages,\n        functions,\n        function_call\n      );\n      const completionTokenUsage =\n        await this._getNumTokensFromGenerations(generations);\n\n      usageMetadata.input_tokens = promptTokenUsage;\n      usageMetadata.output_tokens = completionTokenUsage;\n      usageMetadata.total_tokens = promptTokenUsage + completionTokenUsage;\n      return {\n        generations,\n        llmOutput: {\n          estimatedTokenUsage: {\n            promptTokens: usageMetadata.input_tokens,\n            completionTokens: usageMetadata.output_tokens,\n            totalTokens: usageMetadata.total_tokens,\n          },\n        },\n      };\n    } else {\n      const data = await this.completionWithRetry(\n        {\n          ...params,\n          stream: false,\n          messages: messagesMapped,\n        },\n        {\n          signal: options?.signal,\n          ...options?.options,\n        }\n      );\n\n      const {\n        completion_tokens: completionTokens,\n        prompt_tokens: promptTokens,\n        total_tokens: totalTokens,\n        prompt_tokens_details: promptTokensDetails,\n        completion_tokens_details: completionTokensDetails,\n      } = data?.usage ?? {};\n\n      if (completionTokens) {\n        usageMetadata.output_tokens =\n          (usageMetadata.output_tokens ?? 0) + completionTokens;\n      }\n\n      if (promptTokens) {\n        usageMetadata.input_tokens =\n          (usageMetadata.input_tokens ?? 0) + promptTokens;\n      }\n\n      if (totalTokens) {\n        usageMetadata.total_tokens =\n          (usageMetadata.total_tokens ?? 0) + totalTokens;\n      }\n\n      if (\n        promptTokensDetails?.audio_tokens !== null ||\n        promptTokensDetails?.cached_tokens !== null\n      ) {\n        usageMetadata.input_token_details = {\n          ...(promptTokensDetails?.audio_tokens !== null && {\n            audio: promptTokensDetails?.audio_tokens,\n          }),\n          ...(promptTokensDetails?.cached_tokens !== null && {\n            cache_read: promptTokensDetails?.cached_tokens,\n          }),\n        };\n      }\n\n      if (\n        completionTokensDetails?.audio_tokens !== null ||\n        completionTokensDetails?.reasoning_tokens !== null\n      ) {\n        usageMetadata.output_token_details = {\n          ...(completionTokensDetails?.audio_tokens !== null && {\n            audio: completionTokensDetails?.audio_tokens,\n          }),\n          ...(completionTokensDetails?.reasoning_tokens !== null && {\n            reasoning: completionTokensDetails?.reasoning_tokens,\n          }),\n        };\n      }\n\n      const generations: ChatGeneration[] = [];\n      for (const part of data?.choices ?? []) {\n        const text = part.message?.content ?? \"\";\n        const generation: ChatGeneration = {\n          text,\n          message: this._convertCompletionsMessageToBaseMessage(\n            part.message ?? { role: \"assistant\" },\n            data\n          ),\n        };\n        generation.generationInfo = {\n          ...(part.finish_reason ? { finish_reason: part.finish_reason } : {}),\n          ...(part.logprobs ? { logprobs: part.logprobs } : {}),\n        };\n        if (isAIMessage(generation.message)) {\n          generation.message.usage_metadata = usageMetadata;\n        }\n        // Fields are not serialized unless passed to the constructor\n        // Doing this ensures all fields on the message are serialized\n        generation.message = new AIMessage(\n          Object.fromEntries(\n            Object.entries(generation.message).filter(\n              ([key]) => !key.startsWith(\"lc_\")\n            )\n          ) as AIMessageFields\n        );\n        generations.push(generation);\n      }\n      return {\n        generations,\n        llmOutput: {\n          tokenUsage: {\n            promptTokens: usageMetadata.input_tokens,\n            completionTokens: usageMetadata.output_tokens,\n            totalTokens: usageMetadata.total_tokens,\n          },\n        },\n      };\n    }\n  }\n\n  async *_streamResponseChunks(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<ChatGenerationChunk> {\n    const messagesMapped: OpenAIClient.Chat.Completions.ChatCompletionMessageParam[] =\n      convertMessagesToCompletionsMessageParams({\n        messages,\n        model: this.model,\n      });\n\n    const params = {\n      ...this.invocationParams(options, {\n        streaming: true,\n      }),\n      messages: messagesMapped,\n      stream: true as const,\n    };\n    let defaultRole: OpenAIClient.Chat.ChatCompletionRole | undefined;\n\n    const streamIterable = await this.completionWithRetry(params, options);\n    let usage: OpenAIClient.Completions.CompletionUsage | undefined;\n    for await (const data of streamIterable) {\n      if (options.signal?.aborted) {\n        return;\n      }\n      const choice = data?.choices?.[0];\n      if (data.usage) {\n        usage = data.usage;\n      }\n      if (!choice) {\n        continue;\n      }\n\n      const { delta } = choice;\n      if (!delta) {\n        continue;\n      }\n      const chunk = this._convertCompletionsDeltaToBaseMessageChunk(\n        delta,\n        data,\n        defaultRole\n      );\n      defaultRole = delta.role ?? defaultRole;\n      const newTokenIndices = {\n        prompt: options.promptIndex ?? 0,\n        completion: choice.index ?? 0,\n      };\n      if (typeof chunk.content !== \"string\") {\n        console.log(\n          \"[WARNING]: Received non-string content from OpenAI. This is currently not supported.\"\n        );\n        continue;\n      }\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      const generationInfo: Record<string, any> = { ...newTokenIndices };\n      if (choice.finish_reason != null) {\n        generationInfo.finish_reason = choice.finish_reason;\n        // Only include system fingerprint in the last chunk for now\n        // to avoid concatenation issues\n        generationInfo.system_fingerprint = data.system_fingerprint;\n        generationInfo.model_name = data.model;\n        generationInfo.service_tier = data.service_tier;\n      }\n      if (this.logprobs) {\n        generationInfo.logprobs = choice.logprobs;\n      }\n      const generationChunk = new ChatGenerationChunk({\n        message: chunk,\n        text: chunk.content,\n        generationInfo,\n      });\n      yield generationChunk;\n      await runManager?.handleLLMNewToken(\n        generationChunk.text ?? \"\",\n        newTokenIndices,\n        undefined,\n        undefined,\n        undefined,\n        { chunk: generationChunk }\n      );\n    }\n    if (usage) {\n      const inputTokenDetails = {\n        ...(usage.prompt_tokens_details?.audio_tokens !== null && {\n          audio: usage.prompt_tokens_details?.audio_tokens,\n        }),\n        ...(usage.prompt_tokens_details?.cached_tokens !== null && {\n          cache_read: usage.prompt_tokens_details?.cached_tokens,\n        }),\n      };\n      const outputTokenDetails = {\n        ...(usage.completion_tokens_details?.audio_tokens !== null && {\n          audio: usage.completion_tokens_details?.audio_tokens,\n        }),\n        ...(usage.completion_tokens_details?.reasoning_tokens !== null && {\n          reasoning: usage.completion_tokens_details?.reasoning_tokens,\n        }),\n      };\n      const generationChunk = new ChatGenerationChunk({\n        message: new AIMessageChunk({\n          content: \"\",\n          response_metadata: {\n            usage: { ...usage },\n          },\n          usage_metadata: {\n            input_tokens: usage.prompt_tokens,\n            output_tokens: usage.completion_tokens,\n            total_tokens: usage.total_tokens,\n            ...(Object.keys(inputTokenDetails).length > 0 && {\n              input_token_details: inputTokenDetails,\n            }),\n            ...(Object.keys(outputTokenDetails).length > 0 && {\n              output_token_details: outputTokenDetails,\n            }),\n          },\n        }),\n        text: \"\",\n      });\n      yield generationChunk;\n      await runManager?.handleLLMNewToken(\n        generationChunk.text ?? \"\",\n        { prompt: 0, completion: 0 },\n        undefined,\n        undefined,\n        undefined,\n        { chunk: generationChunk }\n      );\n    }\n    if (options.signal?.aborted) {\n      throw new Error(\"AbortError\");\n    }\n  }\n\n  async completionWithRetry(\n    request: OpenAIClient.Chat.ChatCompletionCreateParamsStreaming,\n    requestOptions?: OpenAIClient.RequestOptions\n  ): Promise<AsyncIterable<OpenAIClient.Chat.Completions.ChatCompletionChunk>>;\n\n  async completionWithRetry(\n    request: OpenAIClient.Chat.ChatCompletionCreateParamsNonStreaming,\n    requestOptions?: OpenAIClient.RequestOptions\n  ): Promise<OpenAIClient.Chat.Completions.ChatCompletion>;\n\n  async completionWithRetry(\n    request: OpenAIClient.Chat.ChatCompletionCreateParams,\n    requestOptions?: OpenAIClient.RequestOptions\n  ): Promise<\n    | AsyncIterable<OpenAIClient.Chat.Completions.ChatCompletionChunk>\n    | OpenAIClient.Chat.Completions.ChatCompletion\n  > {\n    const clientOptions = this._getClientOptions(requestOptions);\n    const isParseableFormat =\n      request.response_format && request.response_format.type === \"json_schema\";\n    return this.caller.call(async () => {\n      try {\n        if (isParseableFormat && !request.stream) {\n          return await this.client.chat.completions.parse(\n            request,\n            clientOptions\n          );\n        } else {\n          return await this.client.chat.completions.create(\n            request,\n            clientOptions\n          );\n        }\n      } catch (e) {\n        const error = wrapOpenAIClientError(e);\n        throw error;\n      }\n    });\n  }\n\n  /**\n   * @deprecated\n   * This function was hoisted into a publicly accessible function from a\n   * different export, but to maintain backwards compatibility with chat models\n   * that depend on ChatOpenAICompletions, we'll keep it here as an overridable\n   * method. This will be removed in a future release\n   */\n  protected _convertCompletionsDeltaToBaseMessageChunk(\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    delta: Record<string, any>,\n    rawResponse: OpenAIClient.Chat.Completions.ChatCompletionChunk,\n    defaultRole?: OpenAIClient.Chat.ChatCompletionRole\n  ): BaseMessageChunk {\n    return convertCompletionsDeltaToBaseMessageChunk({\n      delta,\n      rawResponse,\n      includeRawResponse: this.__includeRawResponse,\n      defaultRole,\n    });\n  }\n\n  /**\n   * @deprecated\n   * This function was hoisted into a publicly accessible function from a\n   * different export, but to maintain backwards compatibility with chat models\n   * that depend on ChatOpenAICompletions, we'll keep it here as an overridable\n   * method. This will be removed in a future release\n   */\n  protected _convertCompletionsMessageToBaseMessage(\n    message: OpenAIClient.ChatCompletionMessage,\n    rawResponse: OpenAIClient.ChatCompletion\n  ): BaseMessage {\n    return convertCompletionsMessageToBaseMessage({\n      message,\n      rawResponse,\n      includeRawResponse: this.__includeRawResponse,\n    });\n  }\n}\n"],"mappings":"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"}