Spaces:
Sleeping
Sleeping
| {"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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"} |