{"version":3,"file":"base.cjs","names":["BaseChatModel","isReasoningModel","interopZodResponseFormat","getEndpoint","getHeadersWithUserAgent","OpenAIClient","isCustomTool","convertResponsesCustomTool","_convertToOpenAITool","isBuiltInTool","hasProviderToolDefinition","messageToOpenAIRole","formatFunctionDefinitions","wrapOpenAIClientError","PROFILES","getStructuredOutputMethod","RunnableLambda","JsonOutputParser"],"sources":["../../src/chat_models/base.ts"],"sourcesContent":["import OpenAI, { type ClientOptions, OpenAI as OpenAIClient } from \"openai\";\nimport { AIMessageChunk, type BaseMessage } from \"@langchain/core/messages\";\nimport { type ChatGeneration } from \"@langchain/core/outputs\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport {\n  BaseChatModel,\n  type LangSmithParams,\n  type BaseChatModelParams,\n  BaseChatModelCallOptions,\n} from \"@langchain/core/language_models/chat_models\";\nimport {\n  isOpenAITool as isOpenAIFunctionTool,\n  type BaseFunctionCallOptions,\n  type BaseLanguageModelInput,\n  type FunctionDefinition,\n  type StructuredOutputMethodOptions,\n} from \"@langchain/core/language_models/base\";\nimport { isLangChainTool } from \"@langchain/core/utils/function_calling\";\nimport { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport { Runnable, RunnableLambda } from \"@langchain/core/runnables\";\nimport { JsonOutputParser } from \"@langchain/core/output_parsers\";\nimport {\n  getSchemaDescription,\n  InteropZodType,\n  isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n  type OpenAICallOptions,\n  type OpenAIChatInput,\n  type OpenAICoreRequestOptions,\n  type ChatOpenAIResponseFormat,\n  ResponseFormatConfiguration,\n  OpenAIVerbosityParam,\n  type OpenAIApiKey,\n  OpenAICacheRetentionParam,\n} from \"../types.js\";\nimport {\n  type OpenAIEndpointConfig,\n  getEndpoint,\n  getHeadersWithUserAgent,\n} from \"../utils/azure.js\";\nimport {\n  type FunctionDef,\n  formatFunctionDefinitions,\n  OpenAIToolChoice,\n  _convertToOpenAITool,\n  ChatOpenAIToolType,\n  convertResponsesCustomTool,\n  isBuiltInTool,\n  isCustomTool,\n  hasProviderToolDefinition,\n  ResponsesToolChoice,\n} from \"../utils/tools.js\";\nimport {\n  getStructuredOutputMethod,\n  interopZodResponseFormat,\n  _convertOpenAIResponsesUsageToLangChainUsage,\n} from \"../utils/output.js\";\nimport { isReasoningModel, messageToOpenAIRole } from \"../utils/misc.js\";\nimport { wrapOpenAIClientError } from \"../utils/client.js\";\nimport PROFILES from \"./profiles.js\";\nimport {\n  isSerializableSchema,\n  SerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n  assembleStructuredOutputPipeline,\n  createContentParser,\n  createFunctionCallingParser,\n} from \"@langchain/core/language_models/structured_output\";\n\ninterface OpenAILLMOutput {\n  tokenUsage: {\n    completionTokens?: number;\n    promptTokens?: number;\n    totalTokens?: number;\n  };\n}\n\nexport type { OpenAICallOptions, OpenAIChatInput };\n\nexport interface BaseChatOpenAICallOptions\n  extends BaseChatModelCallOptions, BaseFunctionCallOptions {\n  /**\n   * Additional options to pass to the underlying axios request.\n   */\n  options?: OpenAICoreRequestOptions;\n\n  /**\n   * A list of tools that the model may use to generate responses.\n   * Each tool can be a function, a built-in tool, or a custom tool definition.\n   * If not provided, the model will not use any tools.\n   */\n  tools?: ChatOpenAIToolType[];\n\n  /**\n   * Specifies which tool the model should use to respond.\n   * Can be an {@link OpenAIToolChoice} or a {@link ResponsesToolChoice}.\n   * If not set, the model will decide which tool to use automatically.\n   */\n  // TODO: break OpenAIToolChoice and ResponsesToolChoice into options sub classes\n  tool_choice?: OpenAIToolChoice | ResponsesToolChoice;\n\n  /**\n   * Adds a prompt index to prompts passed to the model to track\n   * what prompt is being used for a given generation.\n   */\n  promptIndex?: number;\n\n  /**\n   * An object specifying the format that the model must output.\n   */\n  response_format?: ChatOpenAIResponseFormat;\n\n  /**\n   * When provided, the completions API will make a best effort to sample\n   * deterministically, such that repeated requests with the same `seed`\n   * and parameters should return the same result.\n   */\n  seed?: number;\n\n  /**\n   * Additional options to pass to streamed completions.\n   * If provided, this takes precedence over \"streamUsage\" set at\n   * initialization time.\n   */\n  stream_options?: OpenAIClient.Chat.ChatCompletionStreamOptions;\n\n  /**\n   * The model may choose to call multiple functions in a single turn. You can\n   * set parallel_tool_calls to false which ensures only one tool is called at most.\n   * [Learn more](https://platform.openai.com/docs/guides/function-calling#parallel-function-calling)\n   */\n  parallel_tool_calls?: boolean;\n\n  /**\n   * If `true`, model output is guaranteed to exactly match the JSON Schema\n   * provided in the tool definition. If `true`, the input schema will also be\n   * validated according to\n   * https://platform.openai.com/docs/guides/structured-outputs/supported-schemas.\n   *\n   * If `false`, input schema will not be validated and model output will not\n   * be validated.\n   *\n   * If `undefined`, `strict` argument will not be passed to the model.\n   */\n  strict?: boolean;\n\n  /**\n   * Output types that you would like the model to generate for this request. Most\n   * models are capable of generating text, which is the default:\n   *\n   * `[\"text\"]`\n   *\n   * The `gpt-4o-audio-preview` model can also be used to\n   * [generate audio](https://platform.openai.com/docs/guides/audio). To request that\n   * this model generate both text and audio responses, you can use:\n   *\n   * `[\"text\", \"audio\"]`\n   */\n  modalities?: Array<OpenAIClient.Chat.ChatCompletionModality>;\n\n  /**\n   * Parameters for audio output. Required when audio output is requested with\n   * `modalities: [\"audio\"]`.\n   * [Learn more](https://platform.openai.com/docs/guides/audio).\n   */\n  audio?: OpenAIClient.Chat.ChatCompletionAudioParam;\n\n  /**\n   * Static predicted output content, such as the content of a text file that is being regenerated.\n   * [Learn more](https://platform.openai.com/docs/guides/latency-optimization#use-predicted-outputs).\n   */\n  prediction?: OpenAIClient.ChatCompletionPredictionContent;\n\n  /**\n   * Options for reasoning models.\n   *\n   * Note that some options, like reasoning summaries, are only available when using the responses\n   * API. If these options are set, the responses API will be used to fulfill the request.\n   *\n   * These options will be ignored when not using a reasoning model.\n   */\n  reasoning?: OpenAIClient.Reasoning;\n\n  /**\n   * Constrains effort on reasoning for reasoning models. Reduces reasoning in responses,\n   * which can reduce latency and cost at the expense of quality.\n   *\n   * Accepts values: \"low\", \"medium\", or \"high\".\n   *\n   * @deprecated This is a convenience option that will be merged into the `reasoning` object.\n   * Use `reasoning.effort` instead.\n   */\n  reasoningEffort?: OpenAIClient.Reasoning[\"effort\"];\n\n  /**\n   * Service tier to use for this request. Can be \"auto\", \"default\", or \"flex\"\n   * Specifies the service tier for prioritization and latency optimization.\n   */\n  service_tier?: OpenAIClient.Chat.ChatCompletionCreateParams[\"service_tier\"];\n\n  /**\n   * Used by OpenAI to cache responses for similar requests to optimize your cache\n   * hit rates. Replaces the `user` field.\n   * [Learn more](https://platform.openai.com/docs/guides/prompt-caching).\n   */\n  promptCacheKey?: string;\n\n  /**\n   * Used by OpenAI to set cache retention time\n   */\n  promptCacheRetention?: OpenAICacheRetentionParam;\n\n  /**\n   * The verbosity of the model's response.\n   */\n  verbosity?: OpenAIVerbosityParam;\n}\n\nexport interface BaseChatOpenAIFields\n  extends Partial<OpenAIChatInput>, BaseChatModelParams {\n  /**\n   * Optional configuration options for the OpenAI client.\n   */\n  configuration?: ClientOptions;\n}\n\nexport function getChatOpenAIModelParams<TParams extends BaseChatOpenAIFields>(\n  modelOrParams?: string | TParams,\n  paramsArg?: Omit<TParams, \"model\">\n): TParams | undefined {\n  if (typeof modelOrParams === \"string\") {\n    return { model: modelOrParams, ...(paramsArg ?? {}) } as TParams;\n  }\n  if (modelOrParams == null) {\n    return paramsArg as TParams | undefined;\n  }\n  return modelOrParams;\n}\n\n/** @internal */\nexport abstract class BaseChatOpenAI<\n  CallOptions extends BaseChatOpenAICallOptions,\n>\n  extends BaseChatModel<CallOptions, AIMessageChunk>\n  implements Partial<OpenAIChatInput>\n{\n  temperature?: number;\n\n  topP?: number;\n\n  frequencyPenalty?: number;\n\n  presencePenalty?: number;\n\n  n?: number;\n\n  logitBias?: Record<string, number>;\n\n  model = \"gpt-3.5-turbo\";\n\n  modelKwargs?: OpenAIChatInput[\"modelKwargs\"];\n\n  stop?: string[];\n\n  stopSequences?: string[];\n\n  user?: string;\n\n  timeout?: number;\n\n  streaming = false;\n\n  streamUsage = true;\n\n  maxTokens?: number;\n\n  logprobs?: boolean;\n\n  topLogprobs?: number;\n\n  apiKey?: OpenAIApiKey;\n\n  organization?: string;\n\n  __includeRawResponse?: boolean;\n\n  /** @internal */\n  client: OpenAIClient;\n\n  /** @internal */\n  clientConfig: ClientOptions;\n\n  /**\n   * Whether the model supports the `strict` argument when passing in tools.\n   * If `undefined` the `strict` argument will not be passed to OpenAI.\n   */\n  supportsStrictToolCalling?: boolean;\n\n  audio?: OpenAIClient.Chat.ChatCompletionAudioParam;\n\n  modalities?: Array<OpenAIClient.Chat.ChatCompletionModality>;\n\n  reasoning?: OpenAIClient.Reasoning;\n\n  /**\n   * Must be set to `true` in tenancies with Zero Data Retention. Setting to `true` will disable\n   * output storage in the Responses API, but this DOES NOT enable Zero Data Retention in your\n   * OpenAI organization or project. This must be configured directly with OpenAI.\n   *\n   * See:\n   * https://platform.openai.com/docs/guides/your-data\n   * https://platform.openai.com/docs/api-reference/responses/create#responses-create-store\n   *\n   * @default false\n   */\n  zdrEnabled?: boolean | undefined;\n\n  /**\n   * Service tier to use for this request. Can be \"auto\", \"default\", or \"flex\" or \"priority\".\n   * Specifies the service tier for prioritization and latency optimization.\n   */\n  service_tier?: OpenAIClient.Chat.ChatCompletionCreateParams[\"service_tier\"];\n\n  /**\n   * Used by OpenAI to cache responses for similar requests to optimize your cache\n   * hit rates.\n   * [Learn more](https://platform.openai.com/docs/guides/prompt-caching).\n   */\n  promptCacheKey: string;\n\n  /**\n   * Used by OpenAI to set cache retention time\n   */\n  promptCacheRetention?: OpenAICacheRetentionParam;\n\n  /**\n   * The verbosity of the model's response.\n   */\n  verbosity?: OpenAIVerbosityParam;\n\n  protected defaultOptions: CallOptions;\n\n  _llmType() {\n    return \"openai\";\n  }\n\n  static lc_name() {\n    return \"ChatOpenAI\";\n  }\n\n  get callKeys() {\n    return [\n      ...super.callKeys,\n      \"options\",\n      \"function_call\",\n      \"functions\",\n      \"tools\",\n      \"tool_choice\",\n      \"promptIndex\",\n      \"response_format\",\n      \"seed\",\n      \"reasoning\",\n      \"reasoning_effort\",\n      \"service_tier\",\n    ];\n  }\n\n  lc_serializable = true;\n\n  get lc_secrets(): { [key: string]: string } | undefined {\n    return {\n      apiKey: \"OPENAI_API_KEY\",\n      organization: \"OPENAI_ORGANIZATION\",\n    };\n  }\n\n  get lc_aliases(): Record<string, string> {\n    return {\n      apiKey: \"openai_api_key\",\n      modelName: \"model\",\n    };\n  }\n\n  get lc_serializable_keys(): string[] {\n    return [\n      \"configuration\",\n      \"logprobs\",\n      \"topLogprobs\",\n      \"prefixMessages\",\n      \"supportsStrictToolCalling\",\n      \"modalities\",\n      \"audio\",\n      \"temperature\",\n      \"maxTokens\",\n      \"topP\",\n      \"frequencyPenalty\",\n      \"presencePenalty\",\n      \"n\",\n      \"logitBias\",\n      \"user\",\n      \"streaming\",\n      \"streamUsage\",\n      \"model\",\n      \"modelName\",\n      \"modelKwargs\",\n      \"stop\",\n      \"stopSequences\",\n      \"timeout\",\n      \"apiKey\",\n      \"cache\",\n      \"maxConcurrency\",\n      \"maxRetries\",\n      \"verbose\",\n      \"callbacks\",\n      \"tags\",\n      \"metadata\",\n      \"disableStreaming\",\n      \"zdrEnabled\",\n      \"reasoning\",\n      \"promptCacheKey\",\n      \"promptCacheRetention\",\n      \"verbosity\",\n    ];\n  }\n\n  getLsParams(options: this[\"ParsedCallOptions\"]): LangSmithParams {\n    const params = this.invocationParams(options);\n    return {\n      ls_provider: \"openai\",\n      ls_model_name: this.model,\n      ls_model_type: \"chat\",\n      ls_temperature: params.temperature ?? undefined,\n      ls_max_tokens: params.max_tokens ?? undefined,\n      ls_stop: options.stop,\n    };\n  }\n\n  /** @ignore */\n  _identifyingParams(): Omit<\n    OpenAIClient.Chat.ChatCompletionCreateParams,\n    \"messages\"\n  > & {\n    model_name: string;\n  } & ClientOptions {\n    return {\n      model_name: this.model,\n      ...this.invocationParams(),\n      ...this.clientConfig,\n    };\n  }\n\n  /**\n   * Get the identifying parameters for the model\n   */\n  identifyingParams() {\n    return this._identifyingParams();\n  }\n\n  constructor(fields?: BaseChatOpenAIFields) {\n    super(fields ?? {});\n\n    const configApiKey =\n      typeof fields?.configuration?.apiKey === \"string\" ||\n      typeof fields?.configuration?.apiKey === \"function\"\n        ? fields?.configuration?.apiKey\n        : undefined;\n    this.apiKey =\n      fields?.apiKey ??\n      configApiKey ??\n      getEnvironmentVariable(\"OPENAI_API_KEY\");\n    this.organization =\n      fields?.configuration?.organization ??\n      getEnvironmentVariable(\"OPENAI_ORGANIZATION\");\n\n    this.model = fields?.model ?? fields?.modelName ?? this.model;\n    this.modelKwargs = fields?.modelKwargs ?? {};\n    this.timeout = fields?.timeout;\n\n    this.temperature = fields?.temperature ?? this.temperature;\n    this.topP = fields?.topP ?? this.topP;\n    this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty;\n    this.presencePenalty = fields?.presencePenalty ?? this.presencePenalty;\n    this.logprobs = fields?.logprobs;\n    this.topLogprobs = fields?.topLogprobs;\n    this.n = fields?.n ?? this.n;\n    this.logitBias = fields?.logitBias;\n    this.stop = fields?.stopSequences ?? fields?.stop;\n    this.stopSequences = this.stop;\n    this.user = fields?.user;\n    this.__includeRawResponse = fields?.__includeRawResponse;\n    this.audio = fields?.audio;\n    this.modalities = fields?.modalities;\n    this.reasoning = fields?.reasoning;\n    this.maxTokens = fields?.maxCompletionTokens ?? fields?.maxTokens;\n    this.promptCacheKey = fields?.promptCacheKey ?? this.promptCacheKey;\n    this.promptCacheRetention =\n      fields?.promptCacheRetention ?? this.promptCacheRetention;\n    this.verbosity = fields?.verbosity ?? this.verbosity;\n\n    this.disableStreaming = fields?.disableStreaming === true;\n    this.streaming = fields?.streaming === true;\n    if (this.disableStreaming) this.streaming = false;\n    // disable streaming in BaseChatModel if explicitly disabled\n    if (fields?.streaming === false) this.disableStreaming = true;\n\n    this.streamUsage = fields?.streamUsage ?? this.streamUsage;\n    if (this.disableStreaming) this.streamUsage = false;\n\n    this.clientConfig = {\n      apiKey: this.apiKey,\n      organization: this.organization,\n      dangerouslyAllowBrowser: true,\n      ...fields?.configuration,\n    };\n\n    // If `supportsStrictToolCalling` is explicitly set, use that value.\n    // Else leave undefined so it's not passed to OpenAI.\n    if (fields?.supportsStrictToolCalling !== undefined) {\n      this.supportsStrictToolCalling = fields.supportsStrictToolCalling;\n    }\n\n    if (fields?.service_tier !== undefined) {\n      this.service_tier = fields.service_tier;\n    }\n\n    this.zdrEnabled = fields?.zdrEnabled ?? false;\n\n    this._addVersion(\"@langchain/openai\", __PKG_VERSION__);\n  }\n\n  /**\n   * Returns backwards compatible reasoning parameters from constructor params and call options\n   * @internal\n   */\n  protected _getReasoningParams(\n    options?: this[\"ParsedCallOptions\"]\n  ): OpenAIClient.Reasoning | undefined {\n    if (!isReasoningModel(this.model)) {\n      return;\n    }\n\n    // apply options in reverse order of importance -- newer options supersede older options\n    let reasoning: OpenAIClient.Reasoning | undefined;\n    if (this.reasoning !== undefined) {\n      reasoning = {\n        ...reasoning,\n        ...this.reasoning,\n      };\n    }\n    if (options?.reasoning !== undefined) {\n      reasoning = {\n        ...reasoning,\n        ...options.reasoning,\n      };\n    }\n\n    // Coalesce reasoningEffort into reasoning.effort if reasoning.effort is not already set\n    if (\n      options?.reasoningEffort !== undefined &&\n      reasoning?.effort === undefined\n    ) {\n      reasoning = {\n        ...reasoning,\n        effort: options.reasoningEffort,\n      };\n    }\n\n    return reasoning;\n  }\n\n  /**\n   * Returns an openai compatible response format from a set of options\n   * @internal\n   */\n  protected _getResponseFormat(\n    resFormat?: CallOptions[\"response_format\"]\n  ): ResponseFormatConfiguration | undefined {\n    if (\n      resFormat &&\n      resFormat.type === \"json_schema\" &&\n      resFormat.json_schema.schema &&\n      isInteropZodSchema(resFormat.json_schema.schema)\n    ) {\n      return interopZodResponseFormat(\n        resFormat.json_schema.schema,\n        resFormat.json_schema.name,\n        {\n          description: resFormat.json_schema.description,\n        }\n      );\n    }\n    return resFormat as ResponseFormatConfiguration | undefined;\n  }\n\n  protected _combineCallOptions(\n    additionalOptions?: this[\"ParsedCallOptions\"]\n  ): this[\"ParsedCallOptions\"] {\n    return {\n      ...this.defaultOptions,\n      ...(additionalOptions ?? {}),\n    };\n  }\n\n  /** @internal */\n  _getClientOptions(\n    options: OpenAICoreRequestOptions | undefined\n  ): OpenAICoreRequestOptions {\n    if (!this.client) {\n      const openAIEndpointConfig: OpenAIEndpointConfig = {\n        baseURL: this.clientConfig.baseURL,\n      };\n\n      const endpoint = getEndpoint(openAIEndpointConfig);\n      const params = {\n        ...this.clientConfig,\n        baseURL: endpoint,\n        timeout: this.timeout,\n        maxRetries: 0,\n      };\n      if (!params.baseURL) {\n        delete params.baseURL;\n      }\n\n      params.defaultHeaders = getHeadersWithUserAgent(params.defaultHeaders);\n\n      this.client = new OpenAIClient(params);\n    }\n    const requestOptions = {\n      ...this.clientConfig,\n      ...options,\n    } as OpenAICoreRequestOptions;\n    return requestOptions;\n  }\n\n  // TODO: move to completions class\n  protected _convertChatOpenAIToolToCompletionsTool(\n    tool: ChatOpenAIToolType,\n    fields?: { strict?: boolean }\n  ): OpenAIClient.ChatCompletionTool {\n    if (isCustomTool(tool)) {\n      return convertResponsesCustomTool(tool.metadata.customTool);\n    }\n    if (isOpenAIFunctionTool(tool)) {\n      if (fields?.strict !== undefined) {\n        return {\n          ...tool,\n          function: {\n            ...tool.function,\n            strict: fields.strict,\n          },\n        };\n      }\n\n      return tool;\n    }\n    return _convertToOpenAITool(tool, fields);\n  }\n\n  override bindTools(\n    tools: ChatOpenAIToolType[],\n    kwargs?: Partial<CallOptions>\n  ): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions> {\n    let strict: boolean | undefined;\n    if (kwargs?.strict !== undefined) {\n      strict = kwargs.strict;\n    } else if (this.supportsStrictToolCalling !== undefined) {\n      strict = this.supportsStrictToolCalling;\n    }\n    return this.withConfig({\n      tools: tools.map((tool) => {\n        // Built-in tools and custom tools pass through as-is\n        if (isBuiltInTool(tool) || isCustomTool(tool)) {\n          return tool;\n        }\n        // Tools with providerToolDefinition (e.g., localShell, shell, computerUse, applyPatch)\n        // should use their provider-specific definition\n        if (hasProviderToolDefinition(tool)) {\n          return tool.extras.providerToolDefinition;\n        }\n        // Regular tools get converted to OpenAI function format\n        const converted = this._convertChatOpenAIToolToCompletionsTool(tool, {\n          strict,\n        });\n        if (isLangChainTool(tool) && tool.extras?.defer_loading === true) {\n          return { ...converted, defer_loading: true };\n        }\n        return converted;\n      }),\n      ...kwargs,\n    } as Partial<CallOptions>);\n  }\n\n  override async stream(input: BaseLanguageModelInput, options?: CallOptions) {\n    return super.stream(\n      input,\n      this._combineCallOptions(options) as CallOptions\n    );\n  }\n\n  override async invoke(input: BaseLanguageModelInput, options?: CallOptions) {\n    return super.invoke(\n      input,\n      this._combineCallOptions(options) as CallOptions\n    );\n  }\n\n  /** @ignore */\n  _combineLLMOutput(...llmOutputs: OpenAILLMOutput[]): OpenAILLMOutput {\n    return llmOutputs.reduce<{\n      [key in keyof OpenAILLMOutput]: Required<OpenAILLMOutput[key]>;\n    }>(\n      (acc, llmOutput) => {\n        if (llmOutput && llmOutput.tokenUsage) {\n          acc.tokenUsage.completionTokens +=\n            llmOutput.tokenUsage.completionTokens ?? 0;\n          acc.tokenUsage.promptTokens += llmOutput.tokenUsage.promptTokens ?? 0;\n          acc.tokenUsage.totalTokens += llmOutput.tokenUsage.totalTokens ?? 0;\n        }\n        return acc;\n      },\n      {\n        tokenUsage: {\n          completionTokens: 0,\n          promptTokens: 0,\n          totalTokens: 0,\n        },\n      }\n    );\n  }\n\n  async getNumTokensFromMessages(messages: BaseMessage[]) {\n    let totalCount = 0;\n    let tokensPerMessage = 0;\n    let tokensPerName = 0;\n\n    // From: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_format_inputs_to_ChatGPT_models.ipynb\n    if (this.model === \"gpt-3.5-turbo-0301\") {\n      tokensPerMessage = 4;\n      tokensPerName = -1;\n    } else {\n      tokensPerMessage = 3;\n      tokensPerName = 1;\n    }\n\n    const countPerMessage = await Promise.all(\n      messages.map(async (message) => {\n        const [textCount, roleCount] = await Promise.all([\n          this.getNumTokens(message.content),\n          this.getNumTokens(messageToOpenAIRole(message)),\n        ]);\n        const nameCount =\n          message.name !== undefined\n            ? tokensPerName + (await this.getNumTokens(message.name))\n            : 0;\n        let count = textCount + tokensPerMessage + roleCount + nameCount;\n\n        // From: https://github.com/hmarr/openai-chat-tokens/blob/main/src/index.ts messageTokenEstimate\n        const openAIMessage = message;\n        if (openAIMessage._getType() === \"function\") {\n          count -= 2;\n        }\n        if (openAIMessage.additional_kwargs?.function_call) {\n          count += 3;\n        }\n        if (openAIMessage?.additional_kwargs.function_call?.name) {\n          count += await this.getNumTokens(\n            openAIMessage.additional_kwargs.function_call?.name\n          );\n        }\n        if (openAIMessage.additional_kwargs.function_call?.arguments) {\n          try {\n            count += await this.getNumTokens(\n              // Remove newlines and spaces\n              JSON.stringify(\n                JSON.parse(\n                  openAIMessage.additional_kwargs.function_call?.arguments\n                )\n              )\n            );\n          } catch (error) {\n            console.error(\n              \"Error parsing function arguments\",\n              error,\n              JSON.stringify(openAIMessage.additional_kwargs.function_call)\n            );\n            count += await this.getNumTokens(\n              openAIMessage.additional_kwargs.function_call?.arguments\n            );\n          }\n        }\n\n        totalCount += count;\n        return count;\n      })\n    );\n\n    totalCount += 3; // every reply is primed with <|start|>assistant<|message|>\n\n    return { totalCount, countPerMessage };\n  }\n\n  /** @internal */\n  protected async _getNumTokensFromGenerations(generations: ChatGeneration[]) {\n    const generationUsages = await Promise.all(\n      generations.map(async (generation) => {\n        if (generation.message.additional_kwargs?.function_call) {\n          return (await this.getNumTokensFromMessages([generation.message]))\n            .countPerMessage[0];\n        } else {\n          return await this.getNumTokens(generation.message.content);\n        }\n      })\n    );\n\n    return generationUsages.reduce((a, b) => a + b, 0);\n  }\n\n  /** @internal */\n  protected async _getEstimatedTokenCountFromPrompt(\n    messages: BaseMessage[],\n    functions?: OpenAIClient.Chat.ChatCompletionCreateParams.Function[],\n    function_call?:\n      | \"none\"\n      | \"auto\"\n      | OpenAIClient.Chat.ChatCompletionFunctionCallOption\n  ): Promise<number> {\n    // It appears that if functions are present, the first system message is padded with a trailing newline. This\n    // was inferred by trying lots of combinations of messages and functions and seeing what the token counts were.\n\n    let tokens = (await this.getNumTokensFromMessages(messages)).totalCount;\n\n    // If there are functions, add the function definitions as they count towards token usage\n    if (functions && function_call !== \"auto\") {\n      const promptDefinitions = formatFunctionDefinitions(\n        functions as unknown as FunctionDef[]\n      );\n      tokens += await this.getNumTokens(promptDefinitions);\n      tokens += 9; // Add nine per completion\n    }\n\n    // If there's a system message _and_ functions are present, subtract four tokens. I assume this is because\n    // functions typically add a system message, but reuse the first one if it's already there. This offsets\n    // the extra 9 tokens added by the function definitions.\n    if (functions && messages.find((m) => m._getType() === \"system\")) {\n      tokens -= 4;\n    }\n\n    // If function_call is 'none', add one token.\n    // If it's a FunctionCall object, add 4 + the number of tokens in the function name.\n    // If it's undefined or 'auto', don't add anything.\n    if (function_call === \"none\") {\n      tokens += 1;\n    } else if (typeof function_call === \"object\") {\n      tokens += (await this.getNumTokens(function_call.name)) + 4;\n    }\n\n    return tokens;\n  }\n\n  /**\n   * Moderate content using OpenAI's Moderation API.\n   *\n   * This method checks whether content violates OpenAI's content policy by\n   * analyzing text for categories such as hate, harassment, self-harm,\n   * sexual content, violence, and more.\n   *\n   * @param input - The text or array of texts to moderate\n   * @param params - Optional parameters for the moderation request\n   * @param params.model - The moderation model to use. Defaults to \"omni-moderation-latest\".\n   * @param params.options - Additional options to pass to the underlying request\n   * @returns A promise that resolves to the moderation response containing results for each input\n   *\n   * @example\n   * ```typescript\n   * const model = new ChatOpenAI({ model: \"gpt-4o-mini\" });\n   *\n   * // Moderate a single text\n   * const result = await model.moderateContent(\"This is a test message\");\n   * console.log(result.results[0].flagged); // false\n   * console.log(result.results[0].categories); // { hate: false, harassment: false, ... }\n   *\n   * // Moderate multiple texts\n   * const results = await model.moderateContent([\n   *   \"Hello, how are you?\",\n   *   \"This is inappropriate content\"\n   * ]);\n   * results.results.forEach((result, index) => {\n   *   console.log(`Text ${index + 1} flagged:`, result.flagged);\n   * });\n   *\n   * // Use a specific moderation model\n   * const stableResult = await model.moderateContent(\n   *   \"Test content\",\n   *   { model: \"omni-moderation-latest\" }\n   * );\n   * ```\n   */\n  async moderateContent(\n    input: string | string[],\n    params?: {\n      model?: OpenAI.ModerationModel;\n      options?: OpenAICoreRequestOptions;\n    }\n  ): Promise<OpenAIClient.ModerationCreateResponse> {\n    const clientOptions = this._getClientOptions(params?.options);\n    const moderationModel = params?.model ?? \"omni-moderation-latest\";\n    const moderationRequest: OpenAIClient.ModerationCreateParams = {\n      input,\n      model: moderationModel,\n    };\n\n    return this.caller.call(async () => {\n      try {\n        const response = await this.client.moderations.create(\n          moderationRequest,\n          clientOptions\n        );\n        return response;\n      } catch (e) {\n        const error = wrapOpenAIClientError(e);\n        throw error;\n      }\n    });\n  }\n\n  /**\n   * Return profiling information for the model.\n   *\n   * Provides information about the model's capabilities and constraints,\n   * including token limits, multimodal support, and advanced features like\n   * tool calling and structured output.\n   *\n   * @returns {ModelProfile} An object describing the model's capabilities and constraints\n   *\n   * @example\n   * ```typescript\n   * const model = new ChatOpenAI({ model: \"gpt-4o\" });\n   * const profile = model.profile;\n   * console.log(profile.maxInputTokens); // 128000\n   * console.log(profile.imageInputs); // true\n   * ```\n   */\n  get profile(): ModelProfile {\n    return PROFILES[this.model] ?? {};\n  }\n\n  /** @internal */\n  protected _getStructuredOutputMethod(\n    config: StructuredOutputMethodOptions<boolean>\n  ) {\n    const ensuredConfig = { ...config };\n    if (\n      !this.model.startsWith(\"gpt-3\") &&\n      !this.model.startsWith(\"gpt-4-\") &&\n      this.model !== \"gpt-4\"\n    ) {\n      if (ensuredConfig?.method === undefined) {\n        return \"jsonSchema\";\n      }\n    } else if (ensuredConfig.method === \"jsonSchema\") {\n      console.warn(\n        `[WARNING]: JSON Schema is not supported for model \"${this.model}\". Falling back to tool calling.`\n      );\n    }\n    return ensuredConfig.method;\n  }\n\n  withStructuredOutput<\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    outputSchema:\n      | InteropZodType<RunOutput>\n      | SerializableSchema<RunOutput>\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<false>\n  ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n  withStructuredOutput<\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    outputSchema:\n      | InteropZodType<RunOutput>\n      | SerializableSchema<RunOutput>\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<true>\n  ): Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n  withStructuredOutput<\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    outputSchema:\n      | InteropZodType<RunOutput>\n      | SerializableSchema<RunOutput>\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<boolean>\n  ):\n    | Runnable<BaseLanguageModelInput, RunOutput>\n    | Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n  /**\n   * Add structured output to the model.\n   *\n   * The OpenAI model family supports the following structured output methods:\n   * - `jsonSchema`: Use the `response_format` field in the response to return a JSON schema. Only supported with the `gpt-4o-mini`,\n   *   `gpt-4o-mini-2024-07-18`, and `gpt-4o-2024-08-06` model snapshots and later.\n   * - `functionCalling`: Function calling is useful when you are building an application that bridges the models and functionality\n   *   of your application.\n   * - `jsonMode`: JSON mode is a more basic version of the Structured Outputs feature. While JSON mode ensures that model\n   *   output is valid JSON, Structured Outputs reliably matches the model's output to the schema you specify.\n   *   We recommend you use `functionCalling` or `jsonSchema` if it is supported for your use case.\n   *\n   * The default method is `functionCalling`.\n   *\n   * @see https://platform.openai.com/docs/guides/structured-outputs\n   * @param outputSchema - The schema to use for structured output.\n   * @param config - The structured output method options.\n   * @returns The model with structured output.\n   */\n  withStructuredOutput<\n    RunOutput extends Record<string, unknown> = Record<string, unknown>,\n  >(\n    outputSchema:\n      | SerializableSchema<RunOutput>\n      | InteropZodType<RunOutput>\n      | Record<string, unknown>,\n    config?: StructuredOutputMethodOptions<boolean>\n  ) {\n    let llm: Runnable<BaseLanguageModelInput>;\n    let outputParser: Runnable<AIMessageChunk, RunOutput>;\n\n    const { schema, name, includeRaw } = {\n      ...config,\n      schema: outputSchema,\n    };\n\n    if (config?.strict !== undefined && config.method === \"jsonMode\") {\n      throw new Error(\n        \"Argument `strict` is only supported for `method` = 'function_calling'\"\n      );\n    }\n\n    const method = getStructuredOutputMethod(this.model, config?.method);\n\n    if (method === \"jsonMode\") {\n      outputParser = createContentParser(schema);\n      const asJsonSchema = toJsonSchema(schema);\n      llm = this.withConfig({\n        outputVersion: \"v0\",\n        response_format: { type: \"json_object\" },\n        ls_structured_output_format: {\n          kwargs: { method: \"json_mode\" },\n          schema: { title: name ?? \"extract\", ...asJsonSchema },\n        },\n      } as Partial<CallOptions>);\n    } else if (method === \"jsonSchema\") {\n      const asJsonSchema = toJsonSchema(schema);\n      const openaiJsonSchemaParams = {\n        name: name ?? \"extract\",\n        description: getSchemaDescription(asJsonSchema),\n        schema: isInteropZodSchema(schema) ? schema : asJsonSchema,\n        strict: config?.strict,\n      };\n      llm = this.withConfig({\n        outputVersion: \"v0\",\n        response_format: {\n          type: \"json_schema\",\n          json_schema: openaiJsonSchemaParams,\n        },\n        ls_structured_output_format: {\n          kwargs: { method: \"json_schema\" },\n          schema: {\n            title: openaiJsonSchemaParams.name,\n            description: openaiJsonSchemaParams.description,\n            ...asJsonSchema,\n          },\n        },\n      } as Partial<CallOptions>);\n      if (isInteropZodSchema(schema) || isSerializableSchema(schema)) {\n        const altParser = createContentParser(schema);\n        outputParser = RunnableLambda.from<AIMessageChunk, RunOutput>(\n          async (aiMessage: AIMessageChunk) => {\n            if (\"parsed\" in aiMessage.additional_kwargs) {\n              return aiMessage.additional_kwargs.parsed as RunOutput;\n            }\n            return altParser.invoke(aiMessage.content as string);\n          }\n        );\n      } else {\n        outputParser = new JsonOutputParser<RunOutput>();\n      }\n    } else {\n      let functionName = name ?? \"extract\";\n      const asJsonSchema = toJsonSchema(schema);\n\n      // Is function calling\n      let toolFunction: FunctionDefinition;\n      if (isInteropZodSchema(schema) || isSerializableSchema(schema)) {\n        toolFunction = {\n          name: functionName,\n          description: asJsonSchema.description,\n          parameters: asJsonSchema,\n        };\n      } else if (\n        typeof schema.name === \"string\" &&\n        typeof schema.parameters === \"object\" &&\n        schema.parameters != null\n      ) {\n        toolFunction = schema as unknown as FunctionDefinition;\n        functionName = schema.name;\n      } else {\n        functionName = (schema.title as string) ?? functionName;\n        toolFunction = {\n          name: functionName,\n          description: (schema.description as string) ?? \"\",\n          parameters: schema,\n        };\n      }\n\n      llm = this.withConfig({\n        outputVersion: \"v0\",\n        tools: [{ type: \"function\" as const, function: toolFunction }],\n        tool_choice: {\n          type: \"function\" as const,\n          function: { name: functionName },\n        },\n        ls_structured_output_format: {\n          kwargs: { method: \"function_calling\" },\n          schema: { title: functionName, ...asJsonSchema },\n        },\n        // Do not pass `strict` argument to OpenAI if `config.strict` is undefined\n        ...(config?.strict !== undefined ? { strict: config.strict } : {}),\n      } as Partial<CallOptions>);\n\n      outputParser = createFunctionCallingParser(schema, functionName);\n    }\n\n    return assembleStructuredOutputPipeline(llm, outputParser, includeRaw);\n  }\n}\n"],"mappings":"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"}