UNPKG

@langchain/openai

Version:
1 lines 48.4 kB
{"version":3,"file":"base.cjs","names":["BaseChatModel","options: this[\"ParsedCallOptions\"]","fields?: BaseChatOpenAIFields","options?: this[\"ParsedCallOptions\"]","isReasoningModel","reasoning: OpenAIClient.Reasoning | undefined","resFormat?: CallOptions[\"response_format\"]","interopZodResponseFormat","additionalOptions?: this[\"ParsedCallOptions\"]","options: OpenAICoreRequestOptions | undefined","openAIEndpointConfig: OpenAIEndpointConfig","getEndpoint","getHeadersWithUserAgent","OpenAIClient","tool: ChatOpenAIToolType","fields?: { strict?: boolean }","isCustomTool","convertResponsesCustomTool","_convertToOpenAITool","tools: ChatOpenAIToolType[]","kwargs?: Partial<CallOptions>","strict: boolean | undefined","isBuiltInTool","hasProviderToolDefinition","input: BaseLanguageModelInput","options?: CallOptions","messages: BaseMessage[]","messageToOpenAIRole","generations: ChatGeneration[]","functions?: OpenAIClient.Chat.ChatCompletionCreateParams.Function[]","function_call?:\n | \"none\"\n | \"auto\"\n | OpenAIClient.Chat.ChatCompletionFunctionCallOption","formatFunctionDefinitions","input: string | string[]","params?: {\n model?: OpenAI.ModerationModel;\n options?: OpenAICoreRequestOptions;\n }","moderationRequest: OpenAIClient.ModerationCreateParams","wrapOpenAIClientError","PROFILES","config: StructuredOutputMethodOptions<boolean>","outputSchema: InteropZodType<RunOutput> | Record<string, unknown>","config?: StructuredOutputMethodOptions<boolean>","llm: Runnable<BaseLanguageModelInput>","outputParser: Runnable<AIMessageChunk, RunOutput>","getStructuredOutputMethod","StructuredOutputParser","JsonOutputParser","RunnableLambda","aiMessage: AIMessageChunk","JsonOutputKeyToolsParser","openAIFunctionDefinition: FunctionDefinition","RunnablePassthrough","input: any","config","RunnableSequence"],"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 { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport {\n Runnable,\n RunnableLambda,\n RunnablePassthrough,\n RunnableSequence,\n} from \"@langchain/core/runnables\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport { JsonOutputKeyToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\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\";\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,\n 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 * 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>,\n BaseChatModelParams {\n /**\n * Optional configuration options for the OpenAI client.\n */\n configuration?: ClientOptions;\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 \"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\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 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 return this._convertChatOpenAIToolToCompletionsTool(tool, { strict });\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 = await this.getNumTokens(message.content);\n const roleCount = await this.getNumTokens(messageToOpenAIRole(message));\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<false>\n ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-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: InteropZodType<RunOutput> | 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 if (isInteropZodSchema(schema)) {\n outputParser = StructuredOutputParser.fromZodSchema(schema);\n } else {\n outputParser = new JsonOutputParser<RunOutput>();\n }\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 openaiJsonSchemaParams = {\n name: name ?? \"extract\",\n description: getSchemaDescription(schema),\n schema,\n strict: config?.strict,\n };\n const asJsonSchema = toJsonSchema(openaiJsonSchemaParams.schema);\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)) {\n const altParser = StructuredOutputParser.fromZodSchema(schema);\n outputParser = RunnableLambda.from<AIMessageChunk, RunOutput>(\n (aiMessage: AIMessageChunk) => {\n if (\"parsed\" in aiMessage.additional_kwargs) {\n return aiMessage.additional_kwargs.parsed as RunOutput;\n }\n return altParser;\n }\n );\n } else {\n outputParser = new JsonOutputParser<RunOutput>();\n }\n } else {\n let functionName = name ?? \"extract\";\n // Is function calling\n if (isInteropZodSchema(schema)) {\n const asJsonSchema = toJsonSchema(schema);\n llm = this.withConfig({\n outputVersion: \"v0\",\n tools: [\n {\n type: \"function\" as const,\n function: {\n name: functionName,\n description: asJsonSchema.description,\n parameters: asJsonSchema,\n },\n },\n ],\n tool_choice: {\n type: \"function\" as const,\n function: {\n name: functionName,\n },\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 outputParser = new JsonOutputKeyToolsParser({\n returnSingle: true,\n keyName: functionName,\n zodSchema: schema,\n });\n } else {\n let openAIFunctionDefinition: FunctionDefinition;\n if (\n typeof schema.name === \"string\" &&\n typeof schema.parameters === \"object\" &&\n schema.parameters != null\n ) {\n openAIFunctionDefinition = schema as unknown as FunctionDefinition;\n functionName = schema.name;\n } else {\n functionName = (schema.title as string) ?? functionName;\n openAIFunctionDefinition = {\n name: functionName,\n description: (schema.description as string) ?? \"\",\n parameters: schema,\n };\n }\n const asJsonSchema = toJsonSchema(schema);\n llm = this.withConfig({\n outputVersion: \"v0\",\n tools: [\n {\n type: \"function\" as const,\n function: openAIFunctionDefinition,\n },\n ],\n tool_choice: {\n type: \"function\" as const,\n function: {\n name: functionName,\n },\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 outputParser = new JsonOutputKeyToolsParser<RunOutput>({\n returnSingle: true,\n keyName: functionName,\n });\n }\n }\n\n if (!includeRaw) {\n return llm.pipe(outputParser) as Runnable<\n BaseLanguageModelInput,\n RunOutput\n >;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([{ raw: llm }, parsedWithFallback]);\n }\n}\n"],"mappings":"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"}