@langchain/openai 1.5.7 → 1.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/chat_models/base.cjs +1 -1
  3. package/dist/chat_models/base.js +1 -1
  4. package/dist/chat_models/completions.cjs +9 -5
  5. package/dist/chat_models/completions.cjs.map +1 -1
  6. package/dist/chat_models/completions.d.cts.map +1 -1
  7. package/dist/chat_models/completions.d.ts.map +1 -1
  8. package/dist/chat_models/completions.js +9 -5
  9. package/dist/chat_models/completions.js.map +1 -1
  10. package/dist/chat_models/index.d.cts +5 -3
  11. package/dist/chat_models/index.d.cts.map +1 -1
  12. package/dist/chat_models/index.d.ts +5 -3
  13. package/dist/chat_models/index.d.ts.map +1 -1
  14. package/dist/chat_models/responses.cjs +4 -2
  15. package/dist/chat_models/responses.cjs.map +1 -1
  16. package/dist/chat_models/responses.d.cts.map +1 -1
  17. package/dist/chat_models/responses.d.ts.map +1 -1
  18. package/dist/chat_models/responses.js +4 -2
  19. package/dist/chat_models/responses.js.map +1 -1
  20. package/dist/converters/completions.cjs +1 -1
  21. package/dist/converters/completions.cjs.map +1 -1
  22. package/dist/converters/completions.js +1 -1
  23. package/dist/converters/completions.js.map +1 -1
  24. package/dist/converters/responses.cjs +9 -5
  25. package/dist/converters/responses.cjs.map +1 -1
  26. package/dist/converters/responses.d.cts +5 -4
  27. package/dist/converters/responses.d.cts.map +1 -1
  28. package/dist/converters/responses.d.ts +5 -4
  29. package/dist/converters/responses.d.ts.map +1 -1
  30. package/dist/converters/responses.js +9 -5
  31. package/dist/converters/responses.js.map +1 -1
  32. package/dist/llms.cjs +5 -3
  33. package/dist/llms.cjs.map +1 -1
  34. package/dist/llms.d.cts.map +1 -1
  35. package/dist/llms.d.ts.map +1 -1
  36. package/dist/llms.js +5 -3
  37. package/dist/llms.js.map +1 -1
  38. package/dist/utils/client.cjs +6 -4
  39. package/dist/utils/client.cjs.map +1 -1
  40. package/dist/utils/client.js +7 -5
  41. package/dist/utils/client.js.map +1 -1
  42. package/dist/utils/output.cjs.map +1 -1
  43. package/dist/utils/output.js.map +1 -1
  44. package/package.json +5 -5
package/dist/llms.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"llms.js","names":["OpenAI","OpenAIClient"],"sources":["../src/llms.ts"],"sourcesContent":["import type { TiktokenModel } from \"js-tiktoken/lite\";\nimport { type ClientOptions, OpenAI as OpenAIClient } from \"openai\";\nimport { calculateMaxTokens } from \"@langchain/core/language_models/base\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { GenerationChunk, type LLMResult } from \"@langchain/core/outputs\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport {\n BaseLLM,\n type BaseLLMParams,\n} from \"@langchain/core/language_models/llms\";\nimport { chunkArray } from \"@langchain/core/utils/chunk_array\";\nimport type {\n OpenAIApiKey,\n OpenAICallOptions,\n OpenAICoreRequestOptions,\n OpenAIInput,\n} from \"./types.js\";\nimport {\n OpenAIEndpointConfig,\n getEndpoint,\n getHeadersWithUserAgent,\n} from \"./utils/azure.js\";\nimport { wrapOpenAIClientError } from \"./utils/client.js\";\n\nexport type { OpenAICallOptions, OpenAIInput };\n\n/**\n * Interface for tracking token usage in OpenAI calls.\n */\ninterface TokenUsage {\n completionTokens?: number;\n promptTokens?: number;\n totalTokens?: number;\n}\n\n/**\n * Wrapper around OpenAI large language models.\n *\n * To use you should have the `openai` package installed, with the\n * `OPENAI_API_KEY` environment variable set.\n *\n * To use with Azure, import the `AzureOpenAI` class.\n *\n * @remarks\n * Any parameters that are valid to be passed to {@link\n * https://platform.openai.com/docs/api-reference/completions/create |\n * `openai.createCompletion`} can be passed through {@link modelKwargs}, even\n * if not explicitly available on this class.\n * @example\n * ```typescript\n * const model = new OpenAI({\n * modelName: \"gpt-4\",\n * temperature: 0.7,\n * maxTokens: 1000,\n * maxRetries: 5,\n * });\n *\n * const res = await model.invoke(\n * \"Question: What would be a good company name for a company that makes colorful socks?\\nAnswer:\"\n * );\n * console.log({ res });\n * ```\n */\nexport class OpenAI<CallOptions extends OpenAICallOptions = OpenAICallOptions>\n extends BaseLLM<CallOptions>\n implements Partial<OpenAIInput>\n{\n static lc_name() {\n return \"OpenAI\";\n }\n\n get callKeys() {\n return [...super.callKeys, \"options\"];\n }\n\n lc_serializable = true;\n\n get lc_secrets(): { [key: string]: string } | undefined {\n return {\n openAIApiKey: \"OPENAI_API_KEY\",\n apiKey: \"OPENAI_API_KEY\",\n organization: \"OPENAI_ORGANIZATION\",\n };\n }\n\n get lc_aliases(): Record<string, string> {\n return {\n modelName: \"model\",\n openAIApiKey: \"openai_api_key\",\n apiKey: \"openai_api_key\",\n };\n }\n\n temperature?: number;\n\n maxTokens?: number;\n\n topP?: number;\n\n frequencyPenalty?: number;\n\n presencePenalty?: number;\n\n n = 1;\n\n bestOf?: number;\n\n logitBias?: Record<string, number>;\n\n model = \"gpt-3.5-turbo-instruct\";\n\n /** @deprecated Use \"model\" instead */\n modelName: string;\n\n modelKwargs?: OpenAIInput[\"modelKwargs\"];\n\n batchSize = 20;\n\n timeout?: number;\n\n stop?: string[];\n\n stopSequences?: string[];\n\n user?: string;\n\n streaming = false;\n\n openAIApiKey?: OpenAIApiKey;\n\n apiKey?: OpenAIApiKey;\n\n organization?: string;\n\n protected client: OpenAIClient;\n\n protected clientConfig: ClientOptions;\n\n constructor(\n fields?: Partial<OpenAIInput> &\n BaseLLMParams & {\n configuration?: ClientOptions;\n }\n ) {\n super(fields ?? {});\n this._addVersion(\"@langchain/openai\", __PKG_VERSION__);\n\n this.openAIApiKey =\n fields?.apiKey ??\n fields?.openAIApiKey ??\n getEnvironmentVariable(\"OPENAI_API_KEY\");\n this.apiKey = this.openAIApiKey;\n\n this.organization =\n fields?.configuration?.organization ??\n getEnvironmentVariable(\"OPENAI_ORGANIZATION\");\n\n this.model = fields?.model ?? fields?.modelName ?? this.model;\n if (\n (this.model?.startsWith(\"gpt-3.5-turbo\") ||\n this.model?.startsWith(\"gpt-4\") ||\n this.model?.startsWith(\"o1\")) &&\n !this.model?.includes(\"-instruct\")\n ) {\n throw new Error(\n [\n `Your chosen OpenAI model, \"${this.model}\", is a chat model and not a text-in/text-out LLM.`,\n `Passing it into the \"OpenAI\" class is no longer supported.`,\n `Please use the \"ChatOpenAI\" class instead.`,\n \"\",\n `See this page for more information:`,\n \"|\",\n `└> https://js.langchain.com/docs/integrations/chat/openai`,\n ].join(\"\\n\")\n );\n }\n this.modelName = this.model;\n this.modelKwargs = fields?.modelKwargs ?? {};\n this.batchSize = fields?.batchSize ?? this.batchSize;\n this.timeout = fields?.timeout;\n\n this.temperature = fields?.temperature ?? this.temperature;\n this.maxTokens = fields?.maxTokens ?? this.maxTokens;\n this.topP = fields?.topP ?? this.topP;\n this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty;\n this.presencePenalty = fields?.presencePenalty ?? this.presencePenalty;\n this.n = fields?.n ?? this.n;\n this.bestOf = fields?.bestOf ?? this.bestOf;\n this.logitBias = fields?.logitBias;\n this.stop = fields?.stopSequences ?? fields?.stop;\n this.stopSequences = this.stop;\n this.user = fields?.user;\n\n this.streaming = fields?.streaming ?? false;\n\n if (this.streaming && this.bestOf && this.bestOf > 1) {\n throw new Error(\"Cannot stream results when bestOf > 1\");\n }\n\n this.clientConfig = {\n apiKey: this.apiKey,\n organization: this.organization,\n dangerouslyAllowBrowser: true,\n ...fields?.configuration,\n };\n }\n\n /**\n * Get the parameters used to invoke the model\n */\n invocationParams(\n options?: this[\"ParsedCallOptions\"]\n ): Omit<OpenAIClient.CompletionCreateParams, \"prompt\"> {\n return {\n model: this.model,\n temperature: this.temperature,\n max_tokens: this.maxTokens,\n top_p: this.topP,\n frequency_penalty: this.frequencyPenalty,\n presence_penalty: this.presencePenalty,\n n: this.n,\n best_of: this.bestOf,\n logit_bias: this.logitBias,\n stop: options?.stop ?? this.stopSequences,\n user: this.user,\n stream: this.streaming,\n ...this.modelKwargs,\n };\n }\n\n /** @ignore */\n _identifyingParams(): Omit<OpenAIClient.CompletionCreateParams, \"prompt\"> & {\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(): Omit<OpenAIClient.CompletionCreateParams, \"prompt\"> & {\n model_name: string;\n } & ClientOptions {\n return this._identifyingParams();\n }\n\n /**\n * Call out to OpenAI's endpoint with k unique prompts\n *\n * @param [prompts] - The prompts to pass into the model.\n * @param [options] - Optional list of stop words to use when generating.\n * @param [runManager] - Optional callback manager to use when generating.\n *\n * @returns The full LLM output.\n *\n * @example\n * ```ts\n * import { OpenAI } from \"langchain/llms/openai\";\n * const openai = new OpenAI();\n * const response = await openai.generate([\"Tell me a joke.\"]);\n * ```\n */\n async _generate(\n prompts: string[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<LLMResult> {\n const subPrompts = chunkArray(prompts, this.batchSize);\n const choices: OpenAIClient.CompletionChoice[] = [];\n const tokenUsage: TokenUsage = {};\n\n const params = this.invocationParams(options);\n\n if (params.max_tokens === -1) {\n if (prompts.length !== 1) {\n throw new Error(\n \"max_tokens set to -1 not supported for multiple inputs\"\n );\n }\n params.max_tokens = await calculateMaxTokens({\n prompt: prompts[0],\n // Cast here to allow for other models that may not fit the union\n modelName: this.model as TiktokenModel,\n });\n }\n\n for (let i = 0; i < subPrompts.length; i += 1) {\n const data = params.stream\n ? await (async () => {\n const choices: OpenAIClient.CompletionChoice[] = [];\n let response: Omit<OpenAIClient.Completion, \"choices\"> | undefined;\n const stream = await this.completionWithRetry(\n {\n ...params,\n stream: true,\n prompt: subPrompts[i],\n },\n options\n );\n for await (const message of stream) {\n // on the first message set the response properties\n if (!response) {\n response = {\n id: message.id,\n object: message.object,\n created: message.created,\n model: message.model,\n };\n }\n\n // on all messages, update choice\n for (const part of message.choices) {\n if (!choices[part.index]) {\n choices[part.index] = part;\n } else {\n const choice = choices[part.index];\n choice.text += part.text;\n choice.finish_reason = part.finish_reason;\n choice.logprobs = part.logprobs;\n }\n // oxlint-disable-next-line no-void\n void runManager?.handleLLMNewToken(part.text, {\n prompt: Math.floor(part.index / this.n),\n completion: part.index % this.n,\n });\n }\n }\n if (options.signal?.aborted) {\n throw new Error(\"AbortError\");\n }\n return { ...response, choices };\n })()\n : await this.completionWithRetry(\n {\n ...params,\n stream: false,\n prompt: subPrompts[i],\n },\n {\n signal: options.signal,\n ...options.options,\n }\n );\n\n choices.push(...data.choices);\n const {\n completion_tokens: completionTokens,\n prompt_tokens: promptTokens,\n total_tokens: totalTokens,\n } = data.usage\n ? data.usage\n : {\n completion_tokens: undefined,\n prompt_tokens: undefined,\n total_tokens: undefined,\n };\n\n if (completionTokens) {\n tokenUsage.completionTokens =\n (tokenUsage.completionTokens ?? 0) + completionTokens;\n }\n\n if (promptTokens) {\n tokenUsage.promptTokens = (tokenUsage.promptTokens ?? 0) + promptTokens;\n }\n\n if (totalTokens) {\n tokenUsage.totalTokens = (tokenUsage.totalTokens ?? 0) + totalTokens;\n }\n }\n\n const generations = chunkArray(choices, this.n).map((promptChoices) =>\n promptChoices.map((choice) => ({\n text: choice.text ?? \"\",\n generationInfo: {\n finishReason: choice.finish_reason,\n logprobs: choice.logprobs,\n },\n }))\n );\n return {\n generations,\n llmOutput: { tokenUsage },\n };\n }\n\n // TODO(jacoblee): Refactor with _generate(..., {stream: true}) implementation?\n async *_streamResponseChunks(\n input: string,\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<GenerationChunk> {\n const params = {\n ...this.invocationParams(options),\n prompt: input,\n stream: true as const,\n };\n const stream = await this.completionWithRetry(params, options);\n for await (const data of stream) {\n const choice = data?.choices[0];\n if (!choice) {\n continue;\n }\n const chunk = new GenerationChunk({\n text: choice.text,\n generationInfo: {\n finishReason: choice.finish_reason,\n },\n });\n yield chunk;\n // oxlint-disable-next-line no-void\n void runManager?.handleLLMNewToken(chunk.text ?? \"\");\n }\n if (options.signal?.aborted) {\n throw new Error(\"AbortError\");\n }\n }\n\n /**\n * Calls the OpenAI API with retry logic in case of failures.\n * @param request The request to send to the OpenAI API.\n * @param options Optional configuration for the API call.\n * @returns The response from the OpenAI API.\n */\n async completionWithRetry(\n request: OpenAIClient.CompletionCreateParamsStreaming,\n options?: OpenAICoreRequestOptions\n ): Promise<AsyncIterable<OpenAIClient.Completion>>;\n\n async completionWithRetry(\n request: OpenAIClient.CompletionCreateParamsNonStreaming,\n options?: OpenAICoreRequestOptions\n ): Promise<OpenAIClient.Completions.Completion>;\n\n async completionWithRetry(\n request:\n | OpenAIClient.CompletionCreateParamsStreaming\n | OpenAIClient.CompletionCreateParamsNonStreaming,\n options?: OpenAICoreRequestOptions\n ): Promise<\n AsyncIterable<OpenAIClient.Completion> | OpenAIClient.Completions.Completion\n > {\n const requestOptions = this._getClientOptions(options);\n return this.caller.call(async () => {\n try {\n const res = await this.client.completions.create(\n request,\n requestOptions\n );\n return res;\n } catch (e) {\n const error = wrapOpenAIClientError(e);\n throw error;\n }\n });\n }\n\n /**\n * Calls the OpenAI API with retry logic in case of failures.\n * @param request The request to send to the OpenAI API.\n * @param options Optional configuration for the API call.\n * @returns The response from the OpenAI API.\n */\n protected _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\n const params = {\n ...this.clientConfig,\n baseURL: endpoint,\n timeout: this.timeout,\n maxRetries: 0,\n };\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 _llmType() {\n return \"openai\";\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"llms.js","names":["OpenAI","OpenAIClient"],"sources":["../src/llms.ts"],"sourcesContent":["import type { TiktokenModel } from \"js-tiktoken/lite\";\nimport { type ClientOptions, OpenAI as OpenAIClient } from \"openai\";\nimport { calculateMaxTokens } from \"@langchain/core/language_models/base\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { GenerationChunk, type LLMResult } from \"@langchain/core/outputs\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport {\n BaseLLM,\n type BaseLLMParams,\n} from \"@langchain/core/language_models/llms\";\nimport { chunkArray } from \"@langchain/core/utils/chunk_array\";\nimport type {\n OpenAIApiKey,\n OpenAICallOptions,\n OpenAICoreRequestOptions,\n OpenAIInput,\n} from \"./types.js\";\nimport {\n OpenAIEndpointConfig,\n getEndpoint,\n getHeadersWithUserAgent,\n} from \"./utils/azure.js\";\nimport { wrapOpenAIClientError } from \"./utils/client.js\";\n\nexport type { OpenAICallOptions, OpenAIInput };\n\n/**\n * Interface for tracking token usage in OpenAI calls.\n */\ninterface TokenUsage {\n completionTokens?: number;\n promptTokens?: number;\n totalTokens?: number;\n}\n\n/**\n * Wrapper around OpenAI large language models.\n *\n * To use you should have the `openai` package installed, with the\n * `OPENAI_API_KEY` environment variable set.\n *\n * To use with Azure, import the `AzureOpenAI` class.\n *\n * @remarks\n * Any parameters that are valid to be passed to {@link\n * https://platform.openai.com/docs/api-reference/completions/create |\n * `openai.createCompletion`} can be passed through {@link modelKwargs}, even\n * if not explicitly available on this class.\n * @example\n * ```typescript\n * const model = new OpenAI({\n * modelName: \"gpt-4\",\n * temperature: 0.7,\n * maxTokens: 1000,\n * maxRetries: 5,\n * });\n *\n * const res = await model.invoke(\n * \"Question: What would be a good company name for a company that makes colorful socks?\\nAnswer:\"\n * );\n * console.log({ res });\n * ```\n */\nexport class OpenAI<CallOptions extends OpenAICallOptions = OpenAICallOptions>\n extends BaseLLM<CallOptions>\n implements Partial<OpenAIInput>\n{\n static lc_name() {\n return \"OpenAI\";\n }\n\n get callKeys() {\n return [...super.callKeys, \"options\"];\n }\n\n lc_serializable = true;\n\n get lc_secrets(): { [key: string]: string } | undefined {\n return {\n openAIApiKey: \"OPENAI_API_KEY\",\n apiKey: \"OPENAI_API_KEY\",\n organization: \"OPENAI_ORGANIZATION\",\n };\n }\n\n get lc_aliases(): Record<string, string> {\n return {\n modelName: \"model\",\n openAIApiKey: \"openai_api_key\",\n apiKey: \"openai_api_key\",\n };\n }\n\n temperature?: number;\n\n maxTokens?: number;\n\n topP?: number;\n\n frequencyPenalty?: number;\n\n presencePenalty?: number;\n\n n = 1;\n\n bestOf?: number;\n\n logitBias?: Record<string, number>;\n\n model = \"gpt-3.5-turbo-instruct\";\n\n /** @deprecated Use \"model\" instead */\n modelName: string;\n\n modelKwargs?: OpenAIInput[\"modelKwargs\"];\n\n batchSize = 20;\n\n timeout?: number;\n\n stop?: string[];\n\n stopSequences?: string[];\n\n user?: string;\n\n streaming = false;\n\n openAIApiKey?: OpenAIApiKey;\n\n apiKey?: OpenAIApiKey;\n\n organization?: string;\n\n protected client: OpenAIClient;\n\n protected clientConfig: ClientOptions;\n\n constructor(\n fields?: Partial<OpenAIInput> &\n BaseLLMParams & {\n configuration?: ClientOptions;\n }\n ) {\n super(fields ?? {});\n this._addVersion(\"@langchain/openai\", __PKG_VERSION__);\n\n this.openAIApiKey =\n fields?.apiKey ??\n fields?.openAIApiKey ??\n getEnvironmentVariable(\"OPENAI_API_KEY\");\n this.apiKey = this.openAIApiKey;\n\n this.organization =\n fields?.configuration?.organization ??\n getEnvironmentVariable(\"OPENAI_ORGANIZATION\");\n\n this.model = fields?.model ?? fields?.modelName ?? this.model;\n if (\n (this.model?.startsWith(\"gpt-3.5-turbo\") ||\n this.model?.startsWith(\"gpt-4\") ||\n this.model?.startsWith(\"o1\")) &&\n !this.model?.includes(\"-instruct\")\n ) {\n throw new Error(\n [\n `Your chosen OpenAI model, \"${this.model}\", is a chat model and not a text-in/text-out LLM.`,\n `Passing it into the \"OpenAI\" class is no longer supported.`,\n `Please use the \"ChatOpenAI\" class instead.`,\n \"\",\n `See this page for more information:`,\n \"|\",\n `└> https://js.langchain.com/docs/integrations/chat/openai`,\n ].join(\"\\n\")\n );\n }\n this.modelName = this.model;\n this.modelKwargs = fields?.modelKwargs ?? {};\n this.batchSize = fields?.batchSize ?? this.batchSize;\n this.timeout = fields?.timeout;\n\n this.temperature = fields?.temperature ?? this.temperature;\n this.maxTokens = fields?.maxTokens ?? this.maxTokens;\n this.topP = fields?.topP ?? this.topP;\n this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty;\n this.presencePenalty = fields?.presencePenalty ?? this.presencePenalty;\n this.n = fields?.n ?? this.n;\n this.bestOf = fields?.bestOf ?? this.bestOf;\n this.logitBias = fields?.logitBias;\n this.stop = fields?.stopSequences ?? fields?.stop;\n this.stopSequences = this.stop;\n this.user = fields?.user;\n\n this.streaming = fields?.streaming ?? false;\n\n if (this.streaming && this.bestOf && this.bestOf > 1) {\n throw new Error(\"Cannot stream results when bestOf > 1\");\n }\n\n this.clientConfig = {\n apiKey: this.apiKey,\n organization: this.organization,\n dangerouslyAllowBrowser: true,\n ...fields?.configuration,\n };\n }\n\n /**\n * Get the parameters used to invoke the model\n */\n invocationParams(\n options?: this[\"ParsedCallOptions\"]\n ): Omit<OpenAIClient.CompletionCreateParams, \"prompt\"> {\n return {\n model: this.model,\n temperature: this.temperature,\n max_tokens: this.maxTokens,\n top_p: this.topP,\n frequency_penalty: this.frequencyPenalty,\n presence_penalty: this.presencePenalty,\n n: this.n,\n best_of: this.bestOf,\n logit_bias: this.logitBias,\n stop: options?.stop ?? this.stopSequences,\n user: this.user,\n stream: this.streaming,\n ...this.modelKwargs,\n };\n }\n\n /** @ignore */\n _identifyingParams(): Omit<OpenAIClient.CompletionCreateParams, \"prompt\"> & {\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(): Omit<OpenAIClient.CompletionCreateParams, \"prompt\"> & {\n model_name: string;\n } & ClientOptions {\n return this._identifyingParams();\n }\n\n /**\n * Call out to OpenAI's endpoint with k unique prompts\n *\n * @param [prompts] - The prompts to pass into the model.\n * @param [options] - Optional list of stop words to use when generating.\n * @param [runManager] - Optional callback manager to use when generating.\n *\n * @returns The full LLM output.\n *\n * @example\n * ```ts\n * import { OpenAI } from \"langchain/llms/openai\";\n * const openai = new OpenAI();\n * const response = await openai.generate([\"Tell me a joke.\"]);\n * ```\n */\n async _generate(\n prompts: string[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<LLMResult> {\n const subPrompts = chunkArray(prompts, this.batchSize);\n const choices: OpenAIClient.CompletionChoice[] = [];\n const tokenUsage: TokenUsage = {};\n\n const params = this.invocationParams(options);\n\n if (params.max_tokens === -1) {\n if (prompts.length !== 1) {\n throw new Error(\n \"max_tokens set to -1 not supported for multiple inputs\"\n );\n }\n params.max_tokens = await calculateMaxTokens({\n prompt: prompts[0],\n // Cast here to allow for other models that may not fit the union\n modelName: this.model as TiktokenModel,\n });\n }\n\n for (let i = 0; i < subPrompts.length; i += 1) {\n const data = params.stream\n ? await (async () => {\n const choices: OpenAIClient.CompletionChoice[] = [];\n let response: Omit<OpenAIClient.Completion, \"choices\"> | undefined;\n const stream = await this.completionWithRetry(\n {\n ...params,\n stream: true,\n prompt: subPrompts[i],\n },\n options\n );\n for await (const message of stream) {\n // on the first message set the response properties\n if (!response) {\n response = {\n id: message.id,\n object: message.object,\n created: message.created,\n model: message.model,\n };\n }\n\n // on all messages, update choice\n for (const part of message.choices) {\n if (!choices[part.index]) {\n choices[part.index] = part;\n } else {\n const choice = choices[part.index];\n choice.text += part.text;\n choice.finish_reason = part.finish_reason;\n choice.logprobs = part.logprobs;\n }\n // oxlint-disable-next-line no-void\n void runManager?.handleLLMNewToken(part.text, {\n prompt: Math.floor(part.index / this.n),\n completion: part.index % this.n,\n });\n }\n }\n if (options.signal?.aborted) {\n throw new Error(\"AbortError\");\n }\n return { ...response, choices };\n })()\n : await this.completionWithRetry(\n {\n ...params,\n stream: false,\n prompt: subPrompts[i],\n },\n {\n signal: options.signal,\n maxRetries: options.maxRetries,\n ...options.options,\n }\n );\n\n choices.push(...data.choices);\n const {\n completion_tokens: completionTokens,\n prompt_tokens: promptTokens,\n total_tokens: totalTokens,\n } = data.usage\n ? data.usage\n : {\n completion_tokens: undefined,\n prompt_tokens: undefined,\n total_tokens: undefined,\n };\n\n if (completionTokens) {\n tokenUsage.completionTokens =\n (tokenUsage.completionTokens ?? 0) + completionTokens;\n }\n\n if (promptTokens) {\n tokenUsage.promptTokens = (tokenUsage.promptTokens ?? 0) + promptTokens;\n }\n\n if (totalTokens) {\n tokenUsage.totalTokens = (tokenUsage.totalTokens ?? 0) + totalTokens;\n }\n }\n\n const generations = chunkArray(choices, this.n).map((promptChoices) =>\n promptChoices.map((choice) => ({\n text: choice.text ?? \"\",\n generationInfo: {\n finishReason: choice.finish_reason,\n logprobs: choice.logprobs,\n },\n }))\n );\n return {\n generations,\n llmOutput: { tokenUsage },\n };\n }\n\n // TODO(jacoblee): Refactor with _generate(..., {stream: true}) implementation?\n async *_streamResponseChunks(\n input: string,\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<GenerationChunk> {\n const params = {\n ...this.invocationParams(options),\n prompt: input,\n stream: true as const,\n };\n const stream = await this.completionWithRetry(params, options);\n for await (const data of stream) {\n const choice = data?.choices[0];\n if (!choice) {\n continue;\n }\n const chunk = new GenerationChunk({\n text: choice.text,\n generationInfo: {\n finishReason: choice.finish_reason,\n },\n });\n yield chunk;\n // oxlint-disable-next-line no-void\n void runManager?.handleLLMNewToken(chunk.text ?? \"\");\n }\n if (options.signal?.aborted) {\n throw new Error(\"AbortError\");\n }\n }\n\n /**\n * Calls the OpenAI API with retry logic in case of failures.\n * @param request The request to send to the OpenAI API.\n * @param options Optional configuration for the API call.\n * @returns The response from the OpenAI API.\n */\n async completionWithRetry(\n request: OpenAIClient.CompletionCreateParamsStreaming,\n options?: OpenAICoreRequestOptions\n ): Promise<AsyncIterable<OpenAIClient.Completion>>;\n\n async completionWithRetry(\n request: OpenAIClient.CompletionCreateParamsNonStreaming,\n options?: OpenAICoreRequestOptions\n ): Promise<OpenAIClient.Completions.Completion>;\n\n async completionWithRetry(\n request:\n | OpenAIClient.CompletionCreateParamsStreaming\n | OpenAIClient.CompletionCreateParamsNonStreaming,\n options?: OpenAICoreRequestOptions\n ): Promise<\n AsyncIterable<OpenAIClient.Completion> | OpenAIClient.Completions.Completion\n > {\n // The SDK has its own `maxRetries`; take it for our caller instead so\n // the two retry loops don't multiply.\n const { maxRetries, ...sdkOptions } = options ?? {};\n const requestOptions = this._getClientOptions(sdkOptions);\n return this.caller.callWithOptions({ maxRetries }, async () => {\n try {\n const res = await this.client.completions.create(\n request,\n requestOptions\n );\n return res;\n } catch (e) {\n const error = wrapOpenAIClientError(e);\n throw error;\n }\n });\n }\n\n /**\n * Calls the OpenAI API with retry logic in case of failures.\n * @param request The request to send to the OpenAI API.\n * @param options Optional configuration for the API call.\n * @returns The response from the OpenAI API.\n */\n protected _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\n const params = {\n ...this.clientConfig,\n baseURL: endpoint,\n timeout: this.timeout,\n maxRetries: 0,\n };\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 _llmType() {\n return \"openai\";\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,IAAaA,WAAb,cACU,QAEV;CACE,OAAO,UAAU;EACf,OAAO;CACT;CAEA,IAAI,WAAW;EACb,OAAO,CAAC,GAAG,MAAM,UAAU,SAAS;CACtC;CAEA,kBAAkB;CAElB,IAAI,aAAoD;EACtD,OAAO;GACL,cAAc;GACd,QAAQ;GACR,cAAc;EAChB;CACF;CAEA,IAAI,aAAqC;EACvC,OAAO;GACL,WAAW;GACX,cAAc;GACd,QAAQ;EACV;CACF;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,IAAI;CAEJ;CAEA;CAEA,QAAQ;;CAGR;CAEA;CAEA,YAAY;CAEZ;CAEA;CAEA;CAEA;CAEA,YAAY;CAEZ;CAEA;CAEA;CAEA;CAEA;CAEA,YACE,QAIA;EACA,MAAM,UAAU,CAAC,CAAC;EAClB,KAAK,YAAY,qBAAA,OAAoC;EAErD,KAAK,eACH,QAAQ,UACR,QAAQ,gBACR,uBAAuB,gBAAgB;EACzC,KAAK,SAAS,KAAK;EAEnB,KAAK,eACH,QAAQ,eAAe,gBACvB,uBAAuB,qBAAqB;EAE9C,KAAK,QAAQ,QAAQ,SAAS,QAAQ,aAAa,KAAK;EACxD,KACG,KAAK,OAAO,WAAW,eAAe,KACrC,KAAK,OAAO,WAAW,OAAO,KAC9B,KAAK,OAAO,WAAW,IAAI,MAC7B,CAAC,KAAK,OAAO,SAAS,WAAW,GAEjC,MAAM,IAAI,MACR;GACE,8BAA8B,KAAK,MAAM;GACzC;GACA;GACA;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,IAAI,CACb;EAEF,KAAK,YAAY,KAAK;EACtB,KAAK,cAAc,QAAQ,eAAe,CAAC;EAC3C,KAAK,YAAY,QAAQ,aAAa,KAAK;EAC3C,KAAK,UAAU,QAAQ;EAEvB,KAAK,cAAc,QAAQ,eAAe,KAAK;EAC/C,KAAK,YAAY,QAAQ,aAAa,KAAK;EAC3C,KAAK,OAAO,QAAQ,QAAQ,KAAK;EACjC,KAAK,mBAAmB,QAAQ,oBAAoB,KAAK;EACzD,KAAK,kBAAkB,QAAQ,mBAAmB,KAAK;EACvD,KAAK,IAAI,QAAQ,KAAK,KAAK;EAC3B,KAAK,SAAS,QAAQ,UAAU,KAAK;EACrC,KAAK,YAAY,QAAQ;EACzB,KAAK,OAAO,QAAQ,iBAAiB,QAAQ;EAC7C,KAAK,gBAAgB,KAAK;EAC1B,KAAK,OAAO,QAAQ;EAEpB,KAAK,YAAY,QAAQ,aAAa;EAEtC,IAAI,KAAK,aAAa,KAAK,UAAU,KAAK,SAAS,GACjD,MAAM,IAAI,MAAM,uCAAuC;EAGzD,KAAK,eAAe;GAClB,QAAQ,KAAK;GACb,cAAc,KAAK;GACnB,yBAAyB;GACzB,GAAG,QAAQ;EACb;CACF;;;;CAKA,iBACE,SACqD;EACrD,OAAO;GACL,OAAO,KAAK;GACZ,aAAa,KAAK;GAClB,YAAY,KAAK;GACjB,OAAO,KAAK;GACZ,mBAAmB,KAAK;GACxB,kBAAkB,KAAK;GACvB,GAAG,KAAK;GACR,SAAS,KAAK;GACd,YAAY,KAAK;GACjB,MAAM,SAAS,QAAQ,KAAK;GAC5B,MAAM,KAAK;GACX,QAAQ,KAAK;GACb,GAAG,KAAK;EACV;CACF;;CAGA,qBAEkB;EAChB,OAAO;GACL,YAAY,KAAK;GACjB,GAAG,KAAK,iBAAiB;GACzB,GAAG,KAAK;EACV;CACF;;;;CAKA,oBAEkB;EAChB,OAAO,KAAK,mBAAmB;CACjC;;;;;;;;;;;;;;;;;CAkBA,MAAM,UACJ,SACA,SACA,YACoB;EACpB,MAAM,aAAa,WAAW,SAAS,KAAK,SAAS;EACrD,MAAM,UAA2C,CAAC;EAClD,MAAM,aAAyB,CAAC;EAEhC,MAAM,SAAS,KAAK,iBAAiB,OAAO;EAE5C,IAAI,OAAO,eAAe,IAAI;GAC5B,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,MACR,wDACF;GAEF,OAAO,aAAa,MAAM,mBAAmB;IAC3C,QAAQ,QAAQ;IAEhB,WAAW,KAAK;GAClB,CAAC;EACH;EAEA,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK,GAAG;GAC7C,MAAM,OAAO,OAAO,SAChB,OAAO,YAAY;IACjB,MAAM,UAA2C,CAAC;IAClD,IAAI;IACJ,MAAM,SAAS,MAAM,KAAK,oBACxB;KACE,GAAG;KACH,QAAQ;KACR,QAAQ,WAAW;IACrB,GACA,OACF;IACA,WAAW,MAAM,WAAW,QAAQ;KAElC,IAAI,CAAC,UACH,WAAW;MACT,IAAI,QAAQ;MACZ,QAAQ,QAAQ;MAChB,SAAS,QAAQ;MACjB,OAAO,QAAQ;KACjB;KAIF,KAAK,MAAM,QAAQ,QAAQ,SAAS;MAClC,IAAI,CAAC,QAAQ,KAAK,QAChB,QAAQ,KAAK,SAAS;WACjB;OACL,MAAM,SAAS,QAAQ,KAAK;OAC5B,OAAO,QAAQ,KAAK;OACpB,OAAO,gBAAgB,KAAK;OAC5B,OAAO,WAAW,KAAK;MACzB;MAEA,YAAiB,kBAAkB,KAAK,MAAM;OAC5C,QAAQ,KAAK,MAAM,KAAK,QAAQ,KAAK,CAAC;OACtC,YAAY,KAAK,QAAQ,KAAK;MAChC,CAAC;KACH;IACF;IACA,IAAI,QAAQ,QAAQ,SAClB,MAAM,IAAI,MAAM,YAAY;IAE9B,OAAO;KAAE,GAAG;KAAU;IAAQ;GAChC,EAAA,CAAG,IACH,MAAM,KAAK,oBACT;IACE,GAAG;IACH,QAAQ;IACR,QAAQ,WAAW;GACrB,GACA;IACE,QAAQ,QAAQ;IAChB,YAAY,QAAQ;IACpB,GAAG,QAAQ;GACb,CACF;GAEJ,QAAQ,KAAK,GAAG,KAAK,OAAO;GAC5B,MAAM,EACJ,mBAAmB,kBACnB,eAAe,cACf,cAAc,gBACZ,KAAK,QACL,KAAK,QACL;IACE,mBAAmB,KAAA;IACnB,eAAe,KAAA;IACf,cAAc,KAAA;GAChB;GAEJ,IAAI,kBACF,WAAW,oBACR,WAAW,oBAAoB,KAAK;GAGzC,IAAI,cACF,WAAW,gBAAgB,WAAW,gBAAgB,KAAK;GAG7D,IAAI,aACF,WAAW,eAAe,WAAW,eAAe,KAAK;EAE7D;EAWA,OAAO;GACL,aAVkB,WAAW,SAAS,KAAK,CAAC,CAAC,CAAC,KAAK,kBACnD,cAAc,KAAK,YAAY;IAC7B,MAAM,OAAO,QAAQ;IACrB,gBAAgB;KACd,cAAc,OAAO;KACrB,UAAU,OAAO;IACnB;GACF,EAAE,CAGQ;GACV,WAAW,EAAE,WAAW;EAC1B;CACF;CAGA,OAAO,sBACL,OACA,SACA,YACiC;EACjC,MAAM,SAAS;GACb,GAAG,KAAK,iBAAiB,OAAO;GAChC,QAAQ;GACR,QAAQ;EACV;EACA,MAAM,SAAS,MAAM,KAAK,oBAAoB,QAAQ,OAAO;EAC7D,WAAW,MAAM,QAAQ,QAAQ;GAC/B,MAAM,SAAS,MAAM,QAAQ;GAC7B,IAAI,CAAC,QACH;GAEF,MAAM,QAAQ,IAAI,gBAAgB;IAChC,MAAM,OAAO;IACb,gBAAgB,EACd,cAAc,OAAO,cACvB;GACF,CAAC;GACD,MAAM;GAEN,YAAiB,kBAAkB,MAAM,QAAQ,EAAE;EACrD;EACA,IAAI,QAAQ,QAAQ,SAClB,MAAM,IAAI,MAAM,YAAY;CAEhC;CAkBA,MAAM,oBACJ,SAGA,SAGA;EAGA,MAAM,EAAE,YAAY,GAAG,eAAe,WAAW,CAAC;EAClD,MAAM,iBAAiB,KAAK,kBAAkB,UAAU;EACxD,OAAO,KAAK,OAAO,gBAAgB,EAAE,WAAW,GAAG,YAAY;GAC7D,IAAI;IAKF,OAAO,MAJW,KAAK,OAAO,YAAY,OACxC,SACA,cACF;GAEF,SAAS,GAAG;IAEV,MADc,sBAAsB,CAC1B;GACZ;EACF,CAAC;CACH;;;;;;;CAQA,kBACE,SAC0B;EAC1B,IAAI,CAAC,KAAK,QAAQ;GAKhB,MAAM,WAAW,YAAY,EAH3B,SAAS,KAAK,aAAa,QAGmB,CAAC;GAEjD,MAAM,SAAS;IACb,GAAG,KAAK;IACR,SAAS;IACT,SAAS,KAAK;IACd,YAAY;GACd;GAEA,IAAI,CAAC,OAAO,SACV,OAAO,OAAO;GAGhB,OAAO,iBAAiB,wBAAwB,OAAO,cAAc;GAErE,KAAK,SAAS,IAAIC,OAAa,MAAM;EACvC;EAKA,OAAO;GAHL,GAAG,KAAK;GACR,GAAG;EAEe;CACtB;CAEA,WAAW;EACT,OAAO;CACT;AACF"}
@@ -13,14 +13,16 @@ function wrapOpenAIClientError(e) {
13
13
  if (e.constructor.name === openai.APIConnectionTimeoutError.name && "message" in e && typeof e.message === "string") {
14
14
  error = new Error(e.message);
15
15
  error.name = "TimeoutError";
16
+ (0, _langchain_core_errors.stampRetryable)(error, true);
16
17
  } else if (e.constructor.name === openai.APIUserAbortError.name && "message" in e && typeof e.message === "string") {
17
18
  error = new Error(e.message);
18
19
  error.name = "AbortError";
20
+ (0, _langchain_core_errors.stampRetryable)(error, false);
19
21
  } else if (_isOpenAIContextOverflowError(e)) error = _langchain_core_errors.ContextOverflowError.fromError(e);
20
- else if ("status" in e && e.status === 400 && "message" in e && typeof e.message === "string" && e.message.includes("tool_calls")) error = require_errors.addLangChainErrorFields(e, "INVALID_TOOL_RESULTS");
21
- else if ("status" in e && e.status === 401) error = require_errors.addLangChainErrorFields(e, "MODEL_AUTHENTICATION");
22
- else if ("status" in e && e.status === 429) error = require_errors.addLangChainErrorFields(e, "MODEL_RATE_LIMIT");
23
- else if ("status" in e && e.status === 404) error = require_errors.addLangChainErrorFields(e, "MODEL_NOT_FOUND");
22
+ else if ("status" in e && e.status === 400 && "message" in e && typeof e.message === "string" && e.message.includes("tool_calls")) error = (0, _langchain_core_errors.stampRetryable)(require_errors.addLangChainErrorFields(e, "INVALID_TOOL_RESULTS"), false);
23
+ else if ("status" in e && e.status === 401) error = (0, _langchain_core_errors.stampRetryable)(require_errors.addLangChainErrorFields(e, "MODEL_AUTHENTICATION"), false);
24
+ else if ("status" in e && e.status === 429) error = (0, _langchain_core_errors.stampRetryable)(require_errors.addLangChainErrorFields(e, "MODEL_RATE_LIMIT"), true);
25
+ else if ("status" in e && e.status === 404) error = (0, _langchain_core_errors.stampRetryable)(require_errors.addLangChainErrorFields(e, "MODEL_NOT_FOUND"), false);
24
26
  else error = e;
25
27
  return error;
26
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.cjs","names":["APIConnectionTimeoutError","APIUserAbortError","ContextOverflowError","addLangChainErrorFields"],"sources":["../../src/utils/client.ts"],"sourcesContent":["import { APIConnectionTimeoutError, APIUserAbortError } from \"openai\";\nimport { ContextOverflowError } from \"@langchain/core/errors\";\nimport { addLangChainErrorFields } from \"./errors.js\";\n\nfunction _isOpenAIContextOverflowError(e: object): boolean {\n const errorStr = String(e);\n if (errorStr.includes(\"context_length_exceeded\")) {\n return true;\n }\n if (\n \"message\" in e &&\n typeof e.message === \"string\" &&\n (e.message.includes(\"Input tokens exceed the configured limit\") ||\n e.message.includes(\"exceeds the context window\") ||\n e.message.includes(\"maximum context length\"))\n ) {\n return true;\n }\n return false;\n}\n\nexport function wrapOpenAIClientError(e: unknown) {\n if (!e || typeof e !== \"object\") {\n return e;\n }\n\n let error;\n if (\n e.constructor.name === APIConnectionTimeoutError.name &&\n \"message\" in e &&\n typeof e.message === \"string\"\n ) {\n error = new Error(e.message);\n error.name = \"TimeoutError\";\n } else if (\n e.constructor.name === APIUserAbortError.name &&\n \"message\" in e &&\n typeof e.message === \"string\"\n ) {\n error = new Error(e.message);\n error.name = \"AbortError\";\n } else if (_isOpenAIContextOverflowError(e)) {\n error = ContextOverflowError.fromError(e as Error);\n } else if (\n \"status\" in e &&\n e.status === 400 &&\n \"message\" in e &&\n typeof e.message === \"string\" &&\n e.message.includes(\"tool_calls\")\n ) {\n error = addLangChainErrorFields(e, \"INVALID_TOOL_RESULTS\");\n } else if (\"status\" in e && e.status === 401) {\n error = addLangChainErrorFields(e, \"MODEL_AUTHENTICATION\");\n } else if (\"status\" in e && e.status === 429) {\n error = addLangChainErrorFields(e, \"MODEL_RATE_LIMIT\");\n } else if (\"status\" in e && e.status === 404) {\n error = addLangChainErrorFields(e, \"MODEL_NOT_FOUND\");\n } else {\n error = e;\n }\n return error;\n}\n"],"mappings":";;;;AAIA,SAAS,8BAA8B,GAAoB;CAEzD,IADiB,OAAO,CACb,CAAC,CAAC,SAAS,yBAAyB,GAC7C,OAAO;CAET,IACE,aAAa,KACb,OAAO,EAAE,YAAY,aACpB,EAAE,QAAQ,SAAS,0CAA0C,KAC5D,EAAE,QAAQ,SAAS,4BAA4B,KAC/C,EAAE,QAAQ,SAAS,wBAAwB,IAE7C,OAAO;CAET,OAAO;AACT;AAEA,SAAgB,sBAAsB,GAAY;CAChD,IAAI,CAAC,KAAK,OAAO,MAAM,UACrB,OAAO;CAGT,IAAI;CACJ,IACE,EAAE,YAAY,SAASA,OAAAA,0BAA0B,QACjD,aAAa,KACb,OAAO,EAAE,YAAY,UACrB;EACA,QAAQ,IAAI,MAAM,EAAE,OAAO;EAC3B,MAAM,OAAO;CACf,OAAO,IACL,EAAE,YAAY,SAASC,OAAAA,kBAAkB,QACzC,aAAa,KACb,OAAO,EAAE,YAAY,UACrB;EACA,QAAQ,IAAI,MAAM,EAAE,OAAO;EAC3B,MAAM,OAAO;CACf,OAAO,IAAI,8BAA8B,CAAC,GACxC,QAAQC,uBAAAA,qBAAqB,UAAU,CAAU;MAC5C,IACL,YAAY,KACZ,EAAE,WAAW,OACb,aAAa,KACb,OAAO,EAAE,YAAY,YACrB,EAAE,QAAQ,SAAS,YAAY,GAE/B,QAAQC,eAAAA,wBAAwB,GAAG,sBAAsB;MACpD,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,QAAQA,eAAAA,wBAAwB,GAAG,sBAAsB;MACpD,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,QAAQA,eAAAA,wBAAwB,GAAG,kBAAkB;MAChD,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,QAAQA,eAAAA,wBAAwB,GAAG,iBAAiB;MAEpD,QAAQ;CAEV,OAAO;AACT"}
1
+ {"version":3,"file":"client.cjs","names":["APIConnectionTimeoutError","APIUserAbortError","ContextOverflowError","addLangChainErrorFields"],"sources":["../../src/utils/client.ts"],"sourcesContent":["import { APIConnectionTimeoutError, APIUserAbortError } from \"openai\";\nimport { ContextOverflowError, stampRetryable } from \"@langchain/core/errors\";\nimport { addLangChainErrorFields } from \"./errors.js\";\n\nfunction _isOpenAIContextOverflowError(e: object): boolean {\n const errorStr = String(e);\n if (errorStr.includes(\"context_length_exceeded\")) {\n return true;\n }\n if (\n \"message\" in e &&\n typeof e.message === \"string\" &&\n (e.message.includes(\"Input tokens exceed the configured limit\") ||\n e.message.includes(\"exceeds the context window\") ||\n e.message.includes(\"maximum context length\"))\n ) {\n return true;\n }\n return false;\n}\n\nexport function wrapOpenAIClientError(e: unknown) {\n if (!e || typeof e !== \"object\") {\n return e;\n }\n\n let error;\n if (\n e.constructor.name === APIConnectionTimeoutError.name &&\n \"message\" in e &&\n typeof e.message === \"string\"\n ) {\n error = new Error(e.message);\n error.name = \"TimeoutError\";\n // This branch discards the original status, so AsyncCaller can't classify it.\n stampRetryable(error, true);\n } else if (\n e.constructor.name === APIUserAbortError.name &&\n \"message\" in e &&\n typeof e.message === \"string\"\n ) {\n error = new Error(e.message);\n error.name = \"AbortError\";\n stampRetryable(error, false);\n } else if (_isOpenAIContextOverflowError(e)) {\n // ContextOverflowError marks itself non-retryable at construction.\n error = ContextOverflowError.fromError(e as Error);\n } else if (\n \"status\" in e &&\n e.status === 400 &&\n \"message\" in e &&\n typeof e.message === \"string\" &&\n e.message.includes(\"tool_calls\")\n ) {\n error = stampRetryable(\n addLangChainErrorFields(e, \"INVALID_TOOL_RESULTS\"),\n false\n );\n } else if (\"status\" in e && e.status === 401) {\n error = stampRetryable(\n addLangChainErrorFields(e, \"MODEL_AUTHENTICATION\"),\n false\n );\n } else if (\"status\" in e && e.status === 429) {\n // AsyncCaller runs after this and re-marks false if it's quota exhaustion.\n error = stampRetryable(\n addLangChainErrorFields(e, \"MODEL_RATE_LIMIT\"),\n true\n );\n } else if (\"status\" in e && e.status === 404) {\n error = stampRetryable(\n addLangChainErrorFields(e, \"MODEL_NOT_FOUND\"),\n false\n );\n } else {\n error = e;\n }\n return error;\n}\n"],"mappings":";;;;AAIA,SAAS,8BAA8B,GAAoB;CAEzD,IADiB,OAAO,CACb,CAAC,CAAC,SAAS,yBAAyB,GAC7C,OAAO;CAET,IACE,aAAa,KACb,OAAO,EAAE,YAAY,aACpB,EAAE,QAAQ,SAAS,0CAA0C,KAC5D,EAAE,QAAQ,SAAS,4BAA4B,KAC/C,EAAE,QAAQ,SAAS,wBAAwB,IAE7C,OAAO;CAET,OAAO;AACT;AAEA,SAAgB,sBAAsB,GAAY;CAChD,IAAI,CAAC,KAAK,OAAO,MAAM,UACrB,OAAO;CAGT,IAAI;CACJ,IACE,EAAE,YAAY,SAASA,OAAAA,0BAA0B,QACjD,aAAa,KACb,OAAO,EAAE,YAAY,UACrB;EACA,QAAQ,IAAI,MAAM,EAAE,OAAO;EAC3B,MAAM,OAAO;EAEb,CAAA,GAAA,uBAAA,eAAA,CAAe,OAAO,IAAI;CAC5B,OAAO,IACL,EAAE,YAAY,SAASC,OAAAA,kBAAkB,QACzC,aAAa,KACb,OAAO,EAAE,YAAY,UACrB;EACA,QAAQ,IAAI,MAAM,EAAE,OAAO;EAC3B,MAAM,OAAO;EACb,CAAA,GAAA,uBAAA,eAAA,CAAe,OAAO,KAAK;CAC7B,OAAO,IAAI,8BAA8B,CAAC,GAExC,QAAQC,uBAAAA,qBAAqB,UAAU,CAAU;MAC5C,IACL,YAAY,KACZ,EAAE,WAAW,OACb,aAAa,KACb,OAAO,EAAE,YAAY,YACrB,EAAE,QAAQ,SAAS,YAAY,GAE/B,SAAA,GAAA,uBAAA,eAAA,CACEC,eAAAA,wBAAwB,GAAG,sBAAsB,GACjD,KACF;MACK,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,SAAA,GAAA,uBAAA,eAAA,CACEA,eAAAA,wBAAwB,GAAG,sBAAsB,GACjD,KACF;MACK,IAAI,YAAY,KAAK,EAAE,WAAW,KAEvC,SAAA,GAAA,uBAAA,eAAA,CACEA,eAAAA,wBAAwB,GAAG,kBAAkB,GAC7C,IACF;MACK,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,SAAA,GAAA,uBAAA,eAAA,CACEA,eAAAA,wBAAwB,GAAG,iBAAiB,GAC5C,KACF;MAEA,QAAQ;CAEV,OAAO;AACT"}
@@ -1,6 +1,6 @@
1
1
  import { addLangChainErrorFields } from "./errors.js";
2
2
  import { APIConnectionTimeoutError, APIUserAbortError } from "openai";
3
- import { ContextOverflowError } from "@langchain/core/errors";
3
+ import { ContextOverflowError, stampRetryable } from "@langchain/core/errors";
4
4
  //#region src/utils/client.ts
5
5
  function _isOpenAIContextOverflowError(e) {
6
6
  if (String(e).includes("context_length_exceeded")) return true;
@@ -13,14 +13,16 @@ function wrapOpenAIClientError(e) {
13
13
  if (e.constructor.name === APIConnectionTimeoutError.name && "message" in e && typeof e.message === "string") {
14
14
  error = new Error(e.message);
15
15
  error.name = "TimeoutError";
16
+ stampRetryable(error, true);
16
17
  } else if (e.constructor.name === APIUserAbortError.name && "message" in e && typeof e.message === "string") {
17
18
  error = new Error(e.message);
18
19
  error.name = "AbortError";
20
+ stampRetryable(error, false);
19
21
  } else if (_isOpenAIContextOverflowError(e)) error = ContextOverflowError.fromError(e);
20
- else if ("status" in e && e.status === 400 && "message" in e && typeof e.message === "string" && e.message.includes("tool_calls")) error = addLangChainErrorFields(e, "INVALID_TOOL_RESULTS");
21
- else if ("status" in e && e.status === 401) error = addLangChainErrorFields(e, "MODEL_AUTHENTICATION");
22
- else if ("status" in e && e.status === 429) error = addLangChainErrorFields(e, "MODEL_RATE_LIMIT");
23
- else if ("status" in e && e.status === 404) error = addLangChainErrorFields(e, "MODEL_NOT_FOUND");
22
+ else if ("status" in e && e.status === 400 && "message" in e && typeof e.message === "string" && e.message.includes("tool_calls")) error = stampRetryable(addLangChainErrorFields(e, "INVALID_TOOL_RESULTS"), false);
23
+ else if ("status" in e && e.status === 401) error = stampRetryable(addLangChainErrorFields(e, "MODEL_AUTHENTICATION"), false);
24
+ else if ("status" in e && e.status === 429) error = stampRetryable(addLangChainErrorFields(e, "MODEL_RATE_LIMIT"), true);
25
+ else if ("status" in e && e.status === 404) error = stampRetryable(addLangChainErrorFields(e, "MODEL_NOT_FOUND"), false);
24
26
  else error = e;
25
27
  return error;
26
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":[],"sources":["../../src/utils/client.ts"],"sourcesContent":["import { APIConnectionTimeoutError, APIUserAbortError } from \"openai\";\nimport { ContextOverflowError } from \"@langchain/core/errors\";\nimport { addLangChainErrorFields } from \"./errors.js\";\n\nfunction _isOpenAIContextOverflowError(e: object): boolean {\n const errorStr = String(e);\n if (errorStr.includes(\"context_length_exceeded\")) {\n return true;\n }\n if (\n \"message\" in e &&\n typeof e.message === \"string\" &&\n (e.message.includes(\"Input tokens exceed the configured limit\") ||\n e.message.includes(\"exceeds the context window\") ||\n e.message.includes(\"maximum context length\"))\n ) {\n return true;\n }\n return false;\n}\n\nexport function wrapOpenAIClientError(e: unknown) {\n if (!e || typeof e !== \"object\") {\n return e;\n }\n\n let error;\n if (\n e.constructor.name === APIConnectionTimeoutError.name &&\n \"message\" in e &&\n typeof e.message === \"string\"\n ) {\n error = new Error(e.message);\n error.name = \"TimeoutError\";\n } else if (\n e.constructor.name === APIUserAbortError.name &&\n \"message\" in e &&\n typeof e.message === \"string\"\n ) {\n error = new Error(e.message);\n error.name = \"AbortError\";\n } else if (_isOpenAIContextOverflowError(e)) {\n error = ContextOverflowError.fromError(e as Error);\n } else if (\n \"status\" in e &&\n e.status === 400 &&\n \"message\" in e &&\n typeof e.message === \"string\" &&\n e.message.includes(\"tool_calls\")\n ) {\n error = addLangChainErrorFields(e, \"INVALID_TOOL_RESULTS\");\n } else if (\"status\" in e && e.status === 401) {\n error = addLangChainErrorFields(e, \"MODEL_AUTHENTICATION\");\n } else if (\"status\" in e && e.status === 429) {\n error = addLangChainErrorFields(e, \"MODEL_RATE_LIMIT\");\n } else if (\"status\" in e && e.status === 404) {\n error = addLangChainErrorFields(e, \"MODEL_NOT_FOUND\");\n } else {\n error = e;\n }\n return error;\n}\n"],"mappings":";;;;AAIA,SAAS,8BAA8B,GAAoB;CAEzD,IADiB,OAAO,CACb,CAAC,CAAC,SAAS,yBAAyB,GAC7C,OAAO;CAET,IACE,aAAa,KACb,OAAO,EAAE,YAAY,aACpB,EAAE,QAAQ,SAAS,0CAA0C,KAC5D,EAAE,QAAQ,SAAS,4BAA4B,KAC/C,EAAE,QAAQ,SAAS,wBAAwB,IAE7C,OAAO;CAET,OAAO;AACT;AAEA,SAAgB,sBAAsB,GAAY;CAChD,IAAI,CAAC,KAAK,OAAO,MAAM,UACrB,OAAO;CAGT,IAAI;CACJ,IACE,EAAE,YAAY,SAAS,0BAA0B,QACjD,aAAa,KACb,OAAO,EAAE,YAAY,UACrB;EACA,QAAQ,IAAI,MAAM,EAAE,OAAO;EAC3B,MAAM,OAAO;CACf,OAAO,IACL,EAAE,YAAY,SAAS,kBAAkB,QACzC,aAAa,KACb,OAAO,EAAE,YAAY,UACrB;EACA,QAAQ,IAAI,MAAM,EAAE,OAAO;EAC3B,MAAM,OAAO;CACf,OAAO,IAAI,8BAA8B,CAAC,GACxC,QAAQ,qBAAqB,UAAU,CAAU;MAC5C,IACL,YAAY,KACZ,EAAE,WAAW,OACb,aAAa,KACb,OAAO,EAAE,YAAY,YACrB,EAAE,QAAQ,SAAS,YAAY,GAE/B,QAAQ,wBAAwB,GAAG,sBAAsB;MACpD,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,QAAQ,wBAAwB,GAAG,sBAAsB;MACpD,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,QAAQ,wBAAwB,GAAG,kBAAkB;MAChD,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,QAAQ,wBAAwB,GAAG,iBAAiB;MAEpD,QAAQ;CAEV,OAAO;AACT"}
1
+ {"version":3,"file":"client.js","names":[],"sources":["../../src/utils/client.ts"],"sourcesContent":["import { APIConnectionTimeoutError, APIUserAbortError } from \"openai\";\nimport { ContextOverflowError, stampRetryable } from \"@langchain/core/errors\";\nimport { addLangChainErrorFields } from \"./errors.js\";\n\nfunction _isOpenAIContextOverflowError(e: object): boolean {\n const errorStr = String(e);\n if (errorStr.includes(\"context_length_exceeded\")) {\n return true;\n }\n if (\n \"message\" in e &&\n typeof e.message === \"string\" &&\n (e.message.includes(\"Input tokens exceed the configured limit\") ||\n e.message.includes(\"exceeds the context window\") ||\n e.message.includes(\"maximum context length\"))\n ) {\n return true;\n }\n return false;\n}\n\nexport function wrapOpenAIClientError(e: unknown) {\n if (!e || typeof e !== \"object\") {\n return e;\n }\n\n let error;\n if (\n e.constructor.name === APIConnectionTimeoutError.name &&\n \"message\" in e &&\n typeof e.message === \"string\"\n ) {\n error = new Error(e.message);\n error.name = \"TimeoutError\";\n // This branch discards the original status, so AsyncCaller can't classify it.\n stampRetryable(error, true);\n } else if (\n e.constructor.name === APIUserAbortError.name &&\n \"message\" in e &&\n typeof e.message === \"string\"\n ) {\n error = new Error(e.message);\n error.name = \"AbortError\";\n stampRetryable(error, false);\n } else if (_isOpenAIContextOverflowError(e)) {\n // ContextOverflowError marks itself non-retryable at construction.\n error = ContextOverflowError.fromError(e as Error);\n } else if (\n \"status\" in e &&\n e.status === 400 &&\n \"message\" in e &&\n typeof e.message === \"string\" &&\n e.message.includes(\"tool_calls\")\n ) {\n error = stampRetryable(\n addLangChainErrorFields(e, \"INVALID_TOOL_RESULTS\"),\n false\n );\n } else if (\"status\" in e && e.status === 401) {\n error = stampRetryable(\n addLangChainErrorFields(e, \"MODEL_AUTHENTICATION\"),\n false\n );\n } else if (\"status\" in e && e.status === 429) {\n // AsyncCaller runs after this and re-marks false if it's quota exhaustion.\n error = stampRetryable(\n addLangChainErrorFields(e, \"MODEL_RATE_LIMIT\"),\n true\n );\n } else if (\"status\" in e && e.status === 404) {\n error = stampRetryable(\n addLangChainErrorFields(e, \"MODEL_NOT_FOUND\"),\n false\n );\n } else {\n error = e;\n }\n return error;\n}\n"],"mappings":";;;;AAIA,SAAS,8BAA8B,GAAoB;CAEzD,IADiB,OAAO,CACb,CAAC,CAAC,SAAS,yBAAyB,GAC7C,OAAO;CAET,IACE,aAAa,KACb,OAAO,EAAE,YAAY,aACpB,EAAE,QAAQ,SAAS,0CAA0C,KAC5D,EAAE,QAAQ,SAAS,4BAA4B,KAC/C,EAAE,QAAQ,SAAS,wBAAwB,IAE7C,OAAO;CAET,OAAO;AACT;AAEA,SAAgB,sBAAsB,GAAY;CAChD,IAAI,CAAC,KAAK,OAAO,MAAM,UACrB,OAAO;CAGT,IAAI;CACJ,IACE,EAAE,YAAY,SAAS,0BAA0B,QACjD,aAAa,KACb,OAAO,EAAE,YAAY,UACrB;EACA,QAAQ,IAAI,MAAM,EAAE,OAAO;EAC3B,MAAM,OAAO;EAEb,eAAe,OAAO,IAAI;CAC5B,OAAO,IACL,EAAE,YAAY,SAAS,kBAAkB,QACzC,aAAa,KACb,OAAO,EAAE,YAAY,UACrB;EACA,QAAQ,IAAI,MAAM,EAAE,OAAO;EAC3B,MAAM,OAAO;EACb,eAAe,OAAO,KAAK;CAC7B,OAAO,IAAI,8BAA8B,CAAC,GAExC,QAAQ,qBAAqB,UAAU,CAAU;MAC5C,IACL,YAAY,KACZ,EAAE,WAAW,OACb,aAAa,KACb,OAAO,EAAE,YAAY,YACrB,EAAE,QAAQ,SAAS,YAAY,GAE/B,QAAQ,eACN,wBAAwB,GAAG,sBAAsB,GACjD,KACF;MACK,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,QAAQ,eACN,wBAAwB,GAAG,sBAAsB,GACjD,KACF;MACK,IAAI,YAAY,KAAK,EAAE,WAAW,KAEvC,QAAQ,eACN,wBAAwB,GAAG,kBAAkB,GAC7C,IACF;MACK,IAAI,YAAY,KAAK,EAAE,WAAW,KACvC,QAAQ,eACN,wBAAwB,GAAG,iBAAiB,GAC5C,KACF;MAEA,QAAQ;CAEV,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"output.cjs","names":[],"sources":["../../src/utils/output.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport {\n InteropZodType,\n isZodSchemaV3,\n isZodSchemaV4,\n} from \"@langchain/core/utils/types\";\nimport { parse as parseV4, type $ZodType } from \"zod/v4/core\";\nimport { ResponseFormatJSONSchema } from \"openai/resources\";\nimport { zodResponseFormat } from \"openai/helpers/zod\";\nimport { ContentBlock, UsageMetadata } from \"@langchain/core/messages\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\n\nconst SUPPORTED_METHODS = [\n \"jsonSchema\",\n \"functionCalling\",\n \"jsonMode\",\n] as const;\ntype SupportedMethod = (typeof SUPPORTED_METHODS)[number];\n\n/**\n * Get the structured output method for a given model. By default, it uses\n * `jsonSchema` if the model supports it, otherwise it uses `functionCalling`.\n *\n * @throws if the method is invalid, e.g. is not a string or invalid method is provided.\n * @param model - The model name.\n * @param config - The structured output method options.\n * @returns The structured output method.\n */\nexport function getStructuredOutputMethod(\n model: string,\n method: unknown\n): SupportedMethod {\n /**\n * If a method is provided, validate it.\n */\n if (\n typeof method !== \"undefined\" &&\n !SUPPORTED_METHODS.includes(method as SupportedMethod)\n ) {\n throw new Error(\n `Invalid method: ${method}. Supported methods are: ${SUPPORTED_METHODS.join(\n \", \"\n )}`\n );\n }\n\n const hasSupportForJsonSchema =\n !model.startsWith(\"gpt-3\") &&\n !model.startsWith(\"gpt-4-\") &&\n model !== \"gpt-4\";\n\n /**\n * If the model supports JSON Schema, use it by default.\n */\n if (hasSupportForJsonSchema && !method) {\n return \"jsonSchema\";\n }\n\n if (!hasSupportForJsonSchema && method === \"jsonSchema\") {\n throw new Error(\n `JSON Schema is not supported for model \"${model}\". Please use a different method, e.g. \"functionCalling\" or \"jsonMode\".`\n );\n }\n\n /**\n * If the model does not support JSON Schema, use function calling by default.\n */\n return (method as SupportedMethod) ?? \"functionCalling\";\n}\n\n// inlined from openai/lib/parser.ts\nfunction makeParseableResponseFormat<ParsedT>(\n response_format: ResponseFormatJSONSchema,\n parser: (content: string) => ParsedT\n) {\n const obj = { ...response_format };\n\n Object.defineProperties(obj, {\n $brand: {\n value: \"auto-parseable-response-format\",\n enumerable: false,\n },\n $parseRaw: {\n value: parser,\n enumerable: false,\n },\n });\n\n return obj;\n}\n\nexport function interopZodResponseFormat(\n zodSchema: InteropZodType,\n name: string,\n props: Omit<ResponseFormatJSONSchema.JSONSchema, \"schema\" | \"strict\" | \"name\">\n) {\n if (isZodSchemaV3(zodSchema)) {\n return zodResponseFormat(zodSchema as never, name, props);\n }\n if (isZodSchemaV4(zodSchema)) {\n return makeParseableResponseFormat(\n {\n type: \"json_schema\",\n json_schema: {\n ...props,\n name,\n strict: true,\n schema: toJsonSchema(zodSchema, {\n cycles: \"ref\", // equivalent to nameStrategy: 'duplicate-ref'\n reused: \"ref\", // equivalent to $refStrategy: 'extract-to-root'\n override(ctx) {\n ctx.jsonSchema.title = name; // equivalent to `name` property\n // TODO: implement `nullableStrategy` patch-fix (zod doesn't support openApi3 json schema target)\n // TODO: implement `openaiStrictMode` patch-fix (where optional properties without `nullable` are not supported)\n },\n /// property equivalents from native `zodResponseFormat` fn\n // openaiStrictMode: true,\n // name,\n // nameStrategy: 'duplicate-ref',\n // $refStrategy: 'extract-to-root',\n // nullableStrategy: 'property',\n }),\n },\n },\n (content) =>\n parseV4(zodSchema as unknown as $ZodType, JSON.parse(content))\n );\n }\n throw new Error(\"Unsupported schema response format\");\n}\n\n/**\n * Handle multi modal response content.\n *\n * @param content The content of the message.\n * @param messages The messages of the response.\n * @returns The new content of the message.\n */\nexport function handleMultiModalOutput(\n content: string,\n messages: unknown\n): ContentBlock[] | string {\n /**\n * Handle OpenRouter image responses\n * @see https://openrouter.ai/docs/features/multimodal/image-generation#api-usage\n */\n if (\n messages &&\n typeof messages === \"object\" &&\n \"images\" in messages &&\n Array.isArray(messages.images)\n ) {\n const images = messages.images\n .filter((image) => typeof image?.image_url?.url === \"string\")\n .map(\n (image) =>\n ({\n type: \"image\",\n url: image.image_url.url as string,\n }) as const\n );\n return [{ type: \"text\", text: content }, ...images];\n }\n\n return content;\n}\n\n// TODO: make this a converter\nexport function _convertOpenAIResponsesUsageToLangChainUsage(\n usage?: OpenAIClient.Responses.ResponseUsage\n): UsageMetadata {\n const inputTokenDetails = {\n ...(usage?.input_tokens_details?.cached_tokens != null && {\n cache_read: usage?.input_tokens_details?.cached_tokens,\n }),\n };\n const outputTokenDetails = {\n ...(usage?.output_tokens_details?.reasoning_tokens != null && {\n reasoning: usage?.output_tokens_details?.reasoning_tokens,\n }),\n };\n return {\n input_tokens: usage?.input_tokens ?? 0,\n output_tokens: usage?.output_tokens ?? 0,\n total_tokens: usage?.total_tokens ?? 0,\n input_token_details: inputTokenDetails,\n output_token_details: outputTokenDetails,\n };\n}\n"],"mappings":";;;;;AAYA,MAAM,oBAAoB;CACxB;CACA;CACA;AACF;;;;;;;;;;AAYA,SAAgB,0BACd,OACA,QACiB;;;;CAIjB,IACE,OAAO,WAAW,eAClB,CAAC,kBAAkB,SAAS,MAAyB,GAErD,MAAM,IAAI,MACR,mBAAmB,OAAO,2BAA2B,kBAAkB,KACrE,IACF,GACF;CAGF,MAAM,0BACJ,CAAC,MAAM,WAAW,OAAO,KACzB,CAAC,MAAM,WAAW,QAAQ,KAC1B,UAAU;;;;CAKZ,IAAI,2BAA2B,CAAC,QAC9B,OAAO;CAGT,IAAI,CAAC,2BAA2B,WAAW,cACzC,MAAM,IAAI,MACR,2CAA2C,MAAM,wEACnD;;;;CAMF,OAAQ,UAA8B;AACxC;AAGA,SAAS,4BACP,iBACA,QACA;CACA,MAAM,MAAM,EAAE,GAAG,gBAAgB;CAEjC,OAAO,iBAAiB,KAAK;EAC3B,QAAQ;GACN,OAAO;GACP,YAAY;EACd;EACA,WAAW;GACT,OAAO;GACP,YAAY;EACd;CACF,CAAC;CAED,OAAO;AACT;AAEA,SAAgB,yBACd,WACA,MACA,OACA;CACA,KAAA,GAAA,4BAAA,cAAA,CAAkB,SAAS,GACzB,QAAA,GAAA,mBAAA,kBAAA,CAAyB,WAAoB,MAAM,KAAK;CAE1D,KAAA,GAAA,4BAAA,cAAA,CAAkB,SAAS,GACzB,OAAO,4BACL;EACE,MAAM;EACN,aAAa;GACX,GAAG;GACH;GACA,QAAQ;GACR,SAAA,GAAA,kCAAA,aAAA,CAAqB,WAAW;IAC9B,QAAQ;IACR,QAAQ;IACR,SAAS,KAAK;KACZ,IAAI,WAAW,QAAQ;IAGzB;GAOF,CAAC;EACH;CACF,IACC,aAAA,GAAA,YAAA,MAAA,CACS,WAAkC,KAAK,MAAM,OAAO,CAAC,CACjE;CAEF,MAAM,IAAI,MAAM,oCAAoC;AACtD;;;;;;;;AASA,SAAgB,uBACd,SACA,UACyB;;;;;CAKzB,IACE,YACA,OAAO,aAAa,YACpB,YAAY,YACZ,MAAM,QAAQ,SAAS,MAAM,GAC7B;EACA,MAAM,SAAS,SAAS,OACrB,QAAQ,UAAU,OAAO,OAAO,WAAW,QAAQ,QAAQ,CAAC,CAC5D,KACE,WACE;GACC,MAAM;GACN,KAAK,MAAM,UAAU;EACvB,EACJ;EACF,OAAO,CAAC;GAAE,MAAM;GAAQ,MAAM;EAAQ,GAAG,GAAG,MAAM;CACpD;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"output.cjs","names":[],"sources":["../../src/utils/output.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport {\n InteropZodType,\n isZodSchemaV3,\n isZodSchemaV4,\n} from \"@langchain/core/utils/types\";\nimport { parse as parseV4, type $ZodType } from \"zod/v4/core\";\nimport { ResponseFormatJSONSchema } from \"openai/resources\";\nimport { zodResponseFormat } from \"openai/helpers/zod\";\nimport { ContentBlock, UsageMetadata } from \"@langchain/core/messages\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\n\nconst SUPPORTED_METHODS = [\n \"jsonSchema\",\n \"functionCalling\",\n \"jsonMode\",\n] as const;\ntype SupportedMethod = (typeof SUPPORTED_METHODS)[number];\n\n/**\n * Get the structured output method for a given model. By default, it uses\n * `jsonSchema` if the model supports it, otherwise it uses `functionCalling`.\n *\n * @throws if the method is invalid, e.g. is not a string or invalid method is provided.\n * @param model - The model name.\n * @param config - The structured output method options.\n * @returns The structured output method.\n */\nexport function getStructuredOutputMethod(\n model: string,\n method: unknown\n): SupportedMethod {\n /**\n * If a method is provided, validate it.\n */\n if (\n typeof method !== \"undefined\" &&\n !SUPPORTED_METHODS.includes(method as SupportedMethod)\n ) {\n throw new Error(\n `Invalid method: ${method}. Supported methods are: ${SUPPORTED_METHODS.join(\n \", \"\n )}`\n );\n }\n\n const hasSupportForJsonSchema =\n !model.startsWith(\"gpt-3\") &&\n !model.startsWith(\"gpt-4-\") &&\n model !== \"gpt-4\";\n\n /**\n * If the model supports JSON Schema, use it by default.\n */\n if (hasSupportForJsonSchema && !method) {\n return \"jsonSchema\";\n }\n\n if (!hasSupportForJsonSchema && method === \"jsonSchema\") {\n throw new Error(\n `JSON Schema is not supported for model \"${model}\". Please use a different method, e.g. \"functionCalling\" or \"jsonMode\".`\n );\n }\n\n /**\n * If the model does not support JSON Schema, use function calling by default.\n */\n return (method as SupportedMethod) ?? \"functionCalling\";\n}\n\n// inlined from openai/lib/parser.ts\nfunction makeParseableResponseFormat<ParsedT>(\n response_format: ResponseFormatJSONSchema,\n parser: (content: string) => ParsedT\n) {\n const obj = { ...response_format };\n\n Object.defineProperties(obj, {\n $brand: {\n value: \"auto-parseable-response-format\",\n enumerable: false,\n },\n $parseRaw: {\n value: parser,\n enumerable: false,\n },\n });\n\n return obj;\n}\n\nexport function interopZodResponseFormat(\n zodSchema: InteropZodType,\n name: string,\n props: Omit<ResponseFormatJSONSchema.JSONSchema, \"schema\" | \"strict\" | \"name\">\n) {\n if (isZodSchemaV3(zodSchema)) {\n return zodResponseFormat(zodSchema as never, name, props);\n }\n if (isZodSchemaV4(zodSchema)) {\n return makeParseableResponseFormat(\n {\n type: \"json_schema\",\n json_schema: {\n ...props,\n name,\n strict: true,\n schema: toJsonSchema(zodSchema, {\n cycles: \"ref\", // equivalent to nameStrategy: 'duplicate-ref'\n reused: \"ref\", // equivalent to $refStrategy: 'extract-to-root'\n override(ctx) {\n ctx.jsonSchema.title = name; // equivalent to `name` property\n // TODO: implement `nullableStrategy` patch-fix (zod doesn't support openApi3 json schema target)\n // TODO: implement `openaiStrictMode` patch-fix (where optional properties without `nullable` are not supported)\n },\n /// property equivalents from native `zodResponseFormat` fn\n // openaiStrictMode: true,\n // name,\n // nameStrategy: 'duplicate-ref',\n // $refStrategy: 'extract-to-root',\n // nullableStrategy: 'property',\n }),\n },\n },\n (content) =>\n parseV4(zodSchema as unknown as $ZodType, JSON.parse(content))\n );\n }\n throw new Error(\"Unsupported schema response format\");\n}\n\n/**\n * Handle multi modal response content.\n *\n * @param content The content of the message.\n * @param messages The messages of the response.\n * @returns The new content of the message.\n */\nexport function handleMultiModalOutput(\n content: string,\n messages: unknown\n): ContentBlock[] | string {\n /**\n * Handle OpenRouter image responses\n * @see https://openrouter.ai/docs/features/multimodal/image-generation#api-usage\n */\n if (\n messages &&\n typeof messages === \"object\" &&\n \"images\" in messages &&\n Array.isArray(messages.images)\n ) {\n const images = messages.images\n .filter((image) => typeof image?.image_url?.url === \"string\")\n .map(\n (image) =>\n ({\n type: \"image\",\n url: image.image_url.url as string,\n }) as const\n );\n return [{ type: \"text\", text: content }, ...images];\n }\n\n return content;\n}\n\n// TODO: make this a converter\nexport function _convertOpenAIResponsesUsageToLangChainUsage(\n usage?: OpenAIClient.Responses.ResponseUsage\n): UsageMetadata {\n const inputTokenDetails = {\n ...(usage?.input_tokens_details?.cached_tokens != null && {\n cache_read: usage?.input_tokens_details?.cached_tokens,\n }),\n ...(usage?.input_tokens_details?.cache_write_tokens != null && {\n cache_creation: usage?.input_tokens_details?.cache_write_tokens,\n }),\n };\n const outputTokenDetails = {\n ...(usage?.output_tokens_details?.reasoning_tokens != null && {\n reasoning: usage?.output_tokens_details?.reasoning_tokens,\n }),\n };\n return {\n input_tokens: usage?.input_tokens ?? 0,\n output_tokens: usage?.output_tokens ?? 0,\n total_tokens: usage?.total_tokens ?? 0,\n input_token_details: inputTokenDetails,\n output_token_details: outputTokenDetails,\n };\n}\n"],"mappings":";;;;;AAYA,MAAM,oBAAoB;CACxB;CACA;CACA;AACF;;;;;;;;;;AAYA,SAAgB,0BACd,OACA,QACiB;;;;CAIjB,IACE,OAAO,WAAW,eAClB,CAAC,kBAAkB,SAAS,MAAyB,GAErD,MAAM,IAAI,MACR,mBAAmB,OAAO,2BAA2B,kBAAkB,KACrE,IACF,GACF;CAGF,MAAM,0BACJ,CAAC,MAAM,WAAW,OAAO,KACzB,CAAC,MAAM,WAAW,QAAQ,KAC1B,UAAU;;;;CAKZ,IAAI,2BAA2B,CAAC,QAC9B,OAAO;CAGT,IAAI,CAAC,2BAA2B,WAAW,cACzC,MAAM,IAAI,MACR,2CAA2C,MAAM,wEACnD;;;;CAMF,OAAQ,UAA8B;AACxC;AAGA,SAAS,4BACP,iBACA,QACA;CACA,MAAM,MAAM,EAAE,GAAG,gBAAgB;CAEjC,OAAO,iBAAiB,KAAK;EAC3B,QAAQ;GACN,OAAO;GACP,YAAY;EACd;EACA,WAAW;GACT,OAAO;GACP,YAAY;EACd;CACF,CAAC;CAED,OAAO;AACT;AAEA,SAAgB,yBACd,WACA,MACA,OACA;CACA,KAAA,GAAA,4BAAA,cAAA,CAAkB,SAAS,GACzB,QAAA,GAAA,mBAAA,kBAAA,CAAyB,WAAoB,MAAM,KAAK;CAE1D,KAAA,GAAA,4BAAA,cAAA,CAAkB,SAAS,GACzB,OAAO,4BACL;EACE,MAAM;EACN,aAAa;GACX,GAAG;GACH;GACA,QAAQ;GACR,SAAA,GAAA,kCAAA,aAAA,CAAqB,WAAW;IAC9B,QAAQ;IACR,QAAQ;IACR,SAAS,KAAK;KACZ,IAAI,WAAW,QAAQ;IAGzB;GAOF,CAAC;EACH;CACF,IACC,aAAA,GAAA,YAAA,MAAA,CACS,WAAkC,KAAK,MAAM,OAAO,CAAC,CACjE;CAEF,MAAM,IAAI,MAAM,oCAAoC;AACtD;;;;;;;;AASA,SAAgB,uBACd,SACA,UACyB;;;;;CAKzB,IACE,YACA,OAAO,aAAa,YACpB,YAAY,YACZ,MAAM,QAAQ,SAAS,MAAM,GAC7B;EACA,MAAM,SAAS,SAAS,OACrB,QAAQ,UAAU,OAAO,OAAO,WAAW,QAAQ,QAAQ,CAAC,CAC5D,KACE,WACE;GACC,MAAM;GACN,KAAK,MAAM,UAAU;EACvB,EACJ;EACF,OAAO,CAAC;GAAE,MAAM;GAAQ,MAAM;EAAQ,GAAG,GAAG,MAAM;CACpD;CAEA,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","names":["parseV4"],"sources":["../../src/utils/output.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport {\n InteropZodType,\n isZodSchemaV3,\n isZodSchemaV4,\n} from \"@langchain/core/utils/types\";\nimport { parse as parseV4, type $ZodType } from \"zod/v4/core\";\nimport { ResponseFormatJSONSchema } from \"openai/resources\";\nimport { zodResponseFormat } from \"openai/helpers/zod\";\nimport { ContentBlock, UsageMetadata } from \"@langchain/core/messages\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\n\nconst SUPPORTED_METHODS = [\n \"jsonSchema\",\n \"functionCalling\",\n \"jsonMode\",\n] as const;\ntype SupportedMethod = (typeof SUPPORTED_METHODS)[number];\n\n/**\n * Get the structured output method for a given model. By default, it uses\n * `jsonSchema` if the model supports it, otherwise it uses `functionCalling`.\n *\n * @throws if the method is invalid, e.g. is not a string or invalid method is provided.\n * @param model - The model name.\n * @param config - The structured output method options.\n * @returns The structured output method.\n */\nexport function getStructuredOutputMethod(\n model: string,\n method: unknown\n): SupportedMethod {\n /**\n * If a method is provided, validate it.\n */\n if (\n typeof method !== \"undefined\" &&\n !SUPPORTED_METHODS.includes(method as SupportedMethod)\n ) {\n throw new Error(\n `Invalid method: ${method}. Supported methods are: ${SUPPORTED_METHODS.join(\n \", \"\n )}`\n );\n }\n\n const hasSupportForJsonSchema =\n !model.startsWith(\"gpt-3\") &&\n !model.startsWith(\"gpt-4-\") &&\n model !== \"gpt-4\";\n\n /**\n * If the model supports JSON Schema, use it by default.\n */\n if (hasSupportForJsonSchema && !method) {\n return \"jsonSchema\";\n }\n\n if (!hasSupportForJsonSchema && method === \"jsonSchema\") {\n throw new Error(\n `JSON Schema is not supported for model \"${model}\". Please use a different method, e.g. \"functionCalling\" or \"jsonMode\".`\n );\n }\n\n /**\n * If the model does not support JSON Schema, use function calling by default.\n */\n return (method as SupportedMethod) ?? \"functionCalling\";\n}\n\n// inlined from openai/lib/parser.ts\nfunction makeParseableResponseFormat<ParsedT>(\n response_format: ResponseFormatJSONSchema,\n parser: (content: string) => ParsedT\n) {\n const obj = { ...response_format };\n\n Object.defineProperties(obj, {\n $brand: {\n value: \"auto-parseable-response-format\",\n enumerable: false,\n },\n $parseRaw: {\n value: parser,\n enumerable: false,\n },\n });\n\n return obj;\n}\n\nexport function interopZodResponseFormat(\n zodSchema: InteropZodType,\n name: string,\n props: Omit<ResponseFormatJSONSchema.JSONSchema, \"schema\" | \"strict\" | \"name\">\n) {\n if (isZodSchemaV3(zodSchema)) {\n return zodResponseFormat(zodSchema as never, name, props);\n }\n if (isZodSchemaV4(zodSchema)) {\n return makeParseableResponseFormat(\n {\n type: \"json_schema\",\n json_schema: {\n ...props,\n name,\n strict: true,\n schema: toJsonSchema(zodSchema, {\n cycles: \"ref\", // equivalent to nameStrategy: 'duplicate-ref'\n reused: \"ref\", // equivalent to $refStrategy: 'extract-to-root'\n override(ctx) {\n ctx.jsonSchema.title = name; // equivalent to `name` property\n // TODO: implement `nullableStrategy` patch-fix (zod doesn't support openApi3 json schema target)\n // TODO: implement `openaiStrictMode` patch-fix (where optional properties without `nullable` are not supported)\n },\n /// property equivalents from native `zodResponseFormat` fn\n // openaiStrictMode: true,\n // name,\n // nameStrategy: 'duplicate-ref',\n // $refStrategy: 'extract-to-root',\n // nullableStrategy: 'property',\n }),\n },\n },\n (content) =>\n parseV4(zodSchema as unknown as $ZodType, JSON.parse(content))\n );\n }\n throw new Error(\"Unsupported schema response format\");\n}\n\n/**\n * Handle multi modal response content.\n *\n * @param content The content of the message.\n * @param messages The messages of the response.\n * @returns The new content of the message.\n */\nexport function handleMultiModalOutput(\n content: string,\n messages: unknown\n): ContentBlock[] | string {\n /**\n * Handle OpenRouter image responses\n * @see https://openrouter.ai/docs/features/multimodal/image-generation#api-usage\n */\n if (\n messages &&\n typeof messages === \"object\" &&\n \"images\" in messages &&\n Array.isArray(messages.images)\n ) {\n const images = messages.images\n .filter((image) => typeof image?.image_url?.url === \"string\")\n .map(\n (image) =>\n ({\n type: \"image\",\n url: image.image_url.url as string,\n }) as const\n );\n return [{ type: \"text\", text: content }, ...images];\n }\n\n return content;\n}\n\n// TODO: make this a converter\nexport function _convertOpenAIResponsesUsageToLangChainUsage(\n usage?: OpenAIClient.Responses.ResponseUsage\n): UsageMetadata {\n const inputTokenDetails = {\n ...(usage?.input_tokens_details?.cached_tokens != null && {\n cache_read: usage?.input_tokens_details?.cached_tokens,\n }),\n };\n const outputTokenDetails = {\n ...(usage?.output_tokens_details?.reasoning_tokens != null && {\n reasoning: usage?.output_tokens_details?.reasoning_tokens,\n }),\n };\n return {\n input_tokens: usage?.input_tokens ?? 0,\n output_tokens: usage?.output_tokens ?? 0,\n total_tokens: usage?.total_tokens ?? 0,\n input_token_details: inputTokenDetails,\n output_token_details: outputTokenDetails,\n };\n}\n"],"mappings":";;;;;AAYA,MAAM,oBAAoB;CACxB;CACA;CACA;AACF;;;;;;;;;;AAYA,SAAgB,0BACd,OACA,QACiB;;;;CAIjB,IACE,OAAO,WAAW,eAClB,CAAC,kBAAkB,SAAS,MAAyB,GAErD,MAAM,IAAI,MACR,mBAAmB,OAAO,2BAA2B,kBAAkB,KACrE,IACF,GACF;CAGF,MAAM,0BACJ,CAAC,MAAM,WAAW,OAAO,KACzB,CAAC,MAAM,WAAW,QAAQ,KAC1B,UAAU;;;;CAKZ,IAAI,2BAA2B,CAAC,QAC9B,OAAO;CAGT,IAAI,CAAC,2BAA2B,WAAW,cACzC,MAAM,IAAI,MACR,2CAA2C,MAAM,wEACnD;;;;CAMF,OAAQ,UAA8B;AACxC;AAGA,SAAS,4BACP,iBACA,QACA;CACA,MAAM,MAAM,EAAE,GAAG,gBAAgB;CAEjC,OAAO,iBAAiB,KAAK;EAC3B,QAAQ;GACN,OAAO;GACP,YAAY;EACd;EACA,WAAW;GACT,OAAO;GACP,YAAY;EACd;CACF,CAAC;CAED,OAAO;AACT;AAEA,SAAgB,yBACd,WACA,MACA,OACA;CACA,IAAI,cAAc,SAAS,GACzB,OAAO,kBAAkB,WAAoB,MAAM,KAAK;CAE1D,IAAI,cAAc,SAAS,GACzB,OAAO,4BACL;EACE,MAAM;EACN,aAAa;GACX,GAAG;GACH;GACA,QAAQ;GACR,QAAQ,aAAa,WAAW;IAC9B,QAAQ;IACR,QAAQ;IACR,SAAS,KAAK;KACZ,IAAI,WAAW,QAAQ;IAGzB;GAOF,CAAC;EACH;CACF,IACC,YACCA,MAAQ,WAAkC,KAAK,MAAM,OAAO,CAAC,CACjE;CAEF,MAAM,IAAI,MAAM,oCAAoC;AACtD;;;;;;;;AASA,SAAgB,uBACd,SACA,UACyB;;;;;CAKzB,IACE,YACA,OAAO,aAAa,YACpB,YAAY,YACZ,MAAM,QAAQ,SAAS,MAAM,GAC7B;EACA,MAAM,SAAS,SAAS,OACrB,QAAQ,UAAU,OAAO,OAAO,WAAW,QAAQ,QAAQ,CAAC,CAC5D,KACE,WACE;GACC,MAAM;GACN,KAAK,MAAM,UAAU;EACvB,EACJ;EACF,OAAO,CAAC;GAAE,MAAM;GAAQ,MAAM;EAAQ,GAAG,GAAG,MAAM;CACpD;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"output.js","names":["parseV4"],"sources":["../../src/utils/output.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport {\n InteropZodType,\n isZodSchemaV3,\n isZodSchemaV4,\n} from \"@langchain/core/utils/types\";\nimport { parse as parseV4, type $ZodType } from \"zod/v4/core\";\nimport { ResponseFormatJSONSchema } from \"openai/resources\";\nimport { zodResponseFormat } from \"openai/helpers/zod\";\nimport { ContentBlock, UsageMetadata } from \"@langchain/core/messages\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\n\nconst SUPPORTED_METHODS = [\n \"jsonSchema\",\n \"functionCalling\",\n \"jsonMode\",\n] as const;\ntype SupportedMethod = (typeof SUPPORTED_METHODS)[number];\n\n/**\n * Get the structured output method for a given model. By default, it uses\n * `jsonSchema` if the model supports it, otherwise it uses `functionCalling`.\n *\n * @throws if the method is invalid, e.g. is not a string or invalid method is provided.\n * @param model - The model name.\n * @param config - The structured output method options.\n * @returns The structured output method.\n */\nexport function getStructuredOutputMethod(\n model: string,\n method: unknown\n): SupportedMethod {\n /**\n * If a method is provided, validate it.\n */\n if (\n typeof method !== \"undefined\" &&\n !SUPPORTED_METHODS.includes(method as SupportedMethod)\n ) {\n throw new Error(\n `Invalid method: ${method}. Supported methods are: ${SUPPORTED_METHODS.join(\n \", \"\n )}`\n );\n }\n\n const hasSupportForJsonSchema =\n !model.startsWith(\"gpt-3\") &&\n !model.startsWith(\"gpt-4-\") &&\n model !== \"gpt-4\";\n\n /**\n * If the model supports JSON Schema, use it by default.\n */\n if (hasSupportForJsonSchema && !method) {\n return \"jsonSchema\";\n }\n\n if (!hasSupportForJsonSchema && method === \"jsonSchema\") {\n throw new Error(\n `JSON Schema is not supported for model \"${model}\". Please use a different method, e.g. \"functionCalling\" or \"jsonMode\".`\n );\n }\n\n /**\n * If the model does not support JSON Schema, use function calling by default.\n */\n return (method as SupportedMethod) ?? \"functionCalling\";\n}\n\n// inlined from openai/lib/parser.ts\nfunction makeParseableResponseFormat<ParsedT>(\n response_format: ResponseFormatJSONSchema,\n parser: (content: string) => ParsedT\n) {\n const obj = { ...response_format };\n\n Object.defineProperties(obj, {\n $brand: {\n value: \"auto-parseable-response-format\",\n enumerable: false,\n },\n $parseRaw: {\n value: parser,\n enumerable: false,\n },\n });\n\n return obj;\n}\n\nexport function interopZodResponseFormat(\n zodSchema: InteropZodType,\n name: string,\n props: Omit<ResponseFormatJSONSchema.JSONSchema, \"schema\" | \"strict\" | \"name\">\n) {\n if (isZodSchemaV3(zodSchema)) {\n return zodResponseFormat(zodSchema as never, name, props);\n }\n if (isZodSchemaV4(zodSchema)) {\n return makeParseableResponseFormat(\n {\n type: \"json_schema\",\n json_schema: {\n ...props,\n name,\n strict: true,\n schema: toJsonSchema(zodSchema, {\n cycles: \"ref\", // equivalent to nameStrategy: 'duplicate-ref'\n reused: \"ref\", // equivalent to $refStrategy: 'extract-to-root'\n override(ctx) {\n ctx.jsonSchema.title = name; // equivalent to `name` property\n // TODO: implement `nullableStrategy` patch-fix (zod doesn't support openApi3 json schema target)\n // TODO: implement `openaiStrictMode` patch-fix (where optional properties without `nullable` are not supported)\n },\n /// property equivalents from native `zodResponseFormat` fn\n // openaiStrictMode: true,\n // name,\n // nameStrategy: 'duplicate-ref',\n // $refStrategy: 'extract-to-root',\n // nullableStrategy: 'property',\n }),\n },\n },\n (content) =>\n parseV4(zodSchema as unknown as $ZodType, JSON.parse(content))\n );\n }\n throw new Error(\"Unsupported schema response format\");\n}\n\n/**\n * Handle multi modal response content.\n *\n * @param content The content of the message.\n * @param messages The messages of the response.\n * @returns The new content of the message.\n */\nexport function handleMultiModalOutput(\n content: string,\n messages: unknown\n): ContentBlock[] | string {\n /**\n * Handle OpenRouter image responses\n * @see https://openrouter.ai/docs/features/multimodal/image-generation#api-usage\n */\n if (\n messages &&\n typeof messages === \"object\" &&\n \"images\" in messages &&\n Array.isArray(messages.images)\n ) {\n const images = messages.images\n .filter((image) => typeof image?.image_url?.url === \"string\")\n .map(\n (image) =>\n ({\n type: \"image\",\n url: image.image_url.url as string,\n }) as const\n );\n return [{ type: \"text\", text: content }, ...images];\n }\n\n return content;\n}\n\n// TODO: make this a converter\nexport function _convertOpenAIResponsesUsageToLangChainUsage(\n usage?: OpenAIClient.Responses.ResponseUsage\n): UsageMetadata {\n const inputTokenDetails = {\n ...(usage?.input_tokens_details?.cached_tokens != null && {\n cache_read: usage?.input_tokens_details?.cached_tokens,\n }),\n ...(usage?.input_tokens_details?.cache_write_tokens != null && {\n cache_creation: usage?.input_tokens_details?.cache_write_tokens,\n }),\n };\n const outputTokenDetails = {\n ...(usage?.output_tokens_details?.reasoning_tokens != null && {\n reasoning: usage?.output_tokens_details?.reasoning_tokens,\n }),\n };\n return {\n input_tokens: usage?.input_tokens ?? 0,\n output_tokens: usage?.output_tokens ?? 0,\n total_tokens: usage?.total_tokens ?? 0,\n input_token_details: inputTokenDetails,\n output_token_details: outputTokenDetails,\n };\n}\n"],"mappings":";;;;;AAYA,MAAM,oBAAoB;CACxB;CACA;CACA;AACF;;;;;;;;;;AAYA,SAAgB,0BACd,OACA,QACiB;;;;CAIjB,IACE,OAAO,WAAW,eAClB,CAAC,kBAAkB,SAAS,MAAyB,GAErD,MAAM,IAAI,MACR,mBAAmB,OAAO,2BAA2B,kBAAkB,KACrE,IACF,GACF;CAGF,MAAM,0BACJ,CAAC,MAAM,WAAW,OAAO,KACzB,CAAC,MAAM,WAAW,QAAQ,KAC1B,UAAU;;;;CAKZ,IAAI,2BAA2B,CAAC,QAC9B,OAAO;CAGT,IAAI,CAAC,2BAA2B,WAAW,cACzC,MAAM,IAAI,MACR,2CAA2C,MAAM,wEACnD;;;;CAMF,OAAQ,UAA8B;AACxC;AAGA,SAAS,4BACP,iBACA,QACA;CACA,MAAM,MAAM,EAAE,GAAG,gBAAgB;CAEjC,OAAO,iBAAiB,KAAK;EAC3B,QAAQ;GACN,OAAO;GACP,YAAY;EACd;EACA,WAAW;GACT,OAAO;GACP,YAAY;EACd;CACF,CAAC;CAED,OAAO;AACT;AAEA,SAAgB,yBACd,WACA,MACA,OACA;CACA,IAAI,cAAc,SAAS,GACzB,OAAO,kBAAkB,WAAoB,MAAM,KAAK;CAE1D,IAAI,cAAc,SAAS,GACzB,OAAO,4BACL;EACE,MAAM;EACN,aAAa;GACX,GAAG;GACH;GACA,QAAQ;GACR,QAAQ,aAAa,WAAW;IAC9B,QAAQ;IACR,QAAQ;IACR,SAAS,KAAK;KACZ,IAAI,WAAW,QAAQ;IAGzB;GAOF,CAAC;EACH;CACF,IACC,YACCA,MAAQ,WAAkC,KAAK,MAAM,OAAO,CAAC,CACjE;CAEF,MAAM,IAAI,MAAM,oCAAoC;AACtD;;;;;;;;AASA,SAAgB,uBACd,SACA,UACyB;;;;;CAKzB,IACE,YACA,OAAO,aAAa,YACpB,YAAY,YACZ,MAAM,QAAQ,SAAS,MAAM,GAC7B;EACA,MAAM,SAAS,SAAS,OACrB,QAAQ,UAAU,OAAO,OAAO,WAAW,QAAQ,QAAQ,CAAC,CAC5D,KACE,WACE;GACC,MAAM;GACN,KAAK,MAAM,UAAU;EACvB,EACJ;EACF,OAAO,CAAC;GAAE,MAAM;GAAQ,MAAM;EAAQ,GAAG,GAAG,MAAM;CACpD;CAEA,OAAO;AACT"}
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@langchain/openai",
3
- "version": "1.5.7",
3
+ "version": "1.5.9",
4
4
  "description": "OpenAI integrations for LangChain.js",
5
5
  "author": "LangChain",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "engines": {
9
- "node": ">=20"
9
+ "node": ">=22"
10
10
  },
11
11
  "repository": {
12
12
  "type": "git",
@@ -15,11 +15,11 @@
15
15
  "homepage": "https://github.com/langchain-ai/langchainjs/tree/main/libs/providers/langchain-openai/",
16
16
  "dependencies": {
17
17
  "js-tiktoken": "^1.0.12",
18
- "openai": "^6.41.0",
18
+ "openai": "^7.5.0",
19
19
  "zod": "^3.25.76 || ^4"
20
20
  },
21
21
  "peerDependencies": {
22
- "@langchain/core": "^1.2.6"
22
+ "@langchain/core": "^1.2.9"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@azure/identity": "^4.2.1",
@@ -33,7 +33,7 @@
33
33
  "typescript": "~7.0.2",
34
34
  "vitest": "^4.1.8",
35
35
  "zod-to-json-schema": "^3.25.2",
36
- "@langchain/core": "^1.2.6",
36
+ "@langchain/core": "^1.2.9",
37
37
  "@langchain/standard-tests": "0.0.23",
38
38
  "@langchain/tsconfig": "0.0.1"
39
39
  },