@langchain/openai 1.2.3-dev-1768440391024 → 1.2.4

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 (38) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/chat_models/base.cjs +6 -2
  3. package/dist/chat_models/base.cjs.map +1 -1
  4. package/dist/chat_models/base.d.cts +10 -0
  5. package/dist/chat_models/base.d.cts.map +1 -1
  6. package/dist/chat_models/base.d.ts +10 -0
  7. package/dist/chat_models/base.d.ts.map +1 -1
  8. package/dist/chat_models/base.js +6 -2
  9. package/dist/chat_models/base.js.map +1 -1
  10. package/dist/chat_models/completions.cjs +2 -0
  11. package/dist/chat_models/completions.cjs.map +1 -1
  12. package/dist/chat_models/completions.js +2 -0
  13. package/dist/chat_models/completions.js.map +1 -1
  14. package/dist/chat_models/index.cjs +1 -1
  15. package/dist/chat_models/index.cjs.map +1 -1
  16. package/dist/chat_models/index.js +1 -1
  17. package/dist/chat_models/index.js.map +1 -1
  18. package/dist/chat_models/responses.cjs +2 -0
  19. package/dist/chat_models/responses.cjs.map +1 -1
  20. package/dist/chat_models/responses.js +2 -0
  21. package/dist/chat_models/responses.js.map +1 -1
  22. package/dist/converters/responses.cjs +86 -15
  23. package/dist/converters/responses.cjs.map +1 -1
  24. package/dist/converters/responses.js +87 -16
  25. package/dist/converters/responses.js.map +1 -1
  26. package/dist/tools/imageGeneration.cjs.map +1 -1
  27. package/dist/tools/imageGeneration.d.cts +1 -1
  28. package/dist/tools/imageGeneration.d.cts.map +1 -1
  29. package/dist/tools/imageGeneration.d.ts +1 -1
  30. package/dist/tools/imageGeneration.d.ts.map +1 -1
  31. package/dist/tools/imageGeneration.js.map +1 -1
  32. package/dist/utils/misc.cjs +4 -0
  33. package/dist/utils/misc.cjs.map +1 -1
  34. package/dist/utils/misc.d.cts.map +1 -1
  35. package/dist/utils/misc.d.ts.map +1 -1
  36. package/dist/utils/misc.js +4 -1
  37. package/dist/utils/misc.js.map +1 -1
  38. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["BaseChatOpenAI","fields?: ChatOpenAIFields","ChatOpenAIResponses","ChatOpenAICompletions","options: this[\"ParsedCallOptions\"] | undefined","isBuiltInTool","isOpenAICustomTool","isCustomTool","_modelPrefersResponsesAPI","options: this[\"ParsedCallOptions\"]","options?: this[\"ParsedCallOptions\"]","messages: BaseMessage[]","runManager?: CallbackManagerForLLMRun","config: Partial<CallOptions>"],"sources":["../../src/chat_models/index.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessageChunk, type BaseMessage } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { type BaseLanguageModelInput } from \"@langchain/core/language_models/base\";\nimport { Runnable } from \"@langchain/core/runnables\";\nimport { type OpenAICallOptions, type OpenAIChatInput } from \"../types.js\";\nimport {\n _convertToOpenAITool,\n isBuiltInTool,\n isCustomTool,\n isOpenAICustomTool,\n} from \"../utils/tools.js\";\nimport { _modelPrefersResponsesAPI } from \"../utils/misc.js\";\nimport { _convertOpenAIResponsesUsageToLangChainUsage } from \"../utils/output.js\";\nimport {\n ChatOpenAICompletions,\n ChatOpenAICompletionsCallOptions,\n} from \"./completions.js\";\nimport {\n ChatOpenAIResponses,\n ChatOpenAIResponsesCallOptions,\n} from \"./responses.js\";\nimport { BaseChatOpenAI, BaseChatOpenAIFields } from \"./base.js\";\n\nexport type { OpenAICallOptions, OpenAIChatInput };\n\nexport type ChatOpenAICallOptions = ChatOpenAICompletionsCallOptions &\n ChatOpenAIResponsesCallOptions;\n\nexport interface ChatOpenAIFields extends BaseChatOpenAIFields {\n /**\n * Whether to use the responses API for all requests. If `false` the responses API will be used\n * only when required in order to fulfill the request.\n */\n useResponsesApi?: boolean;\n /**\n * The completions chat instance\n * @internal\n */\n completions?: ChatOpenAICompletions;\n /**\n * The responses chat instance\n * @internal\n */\n responses?: ChatOpenAIResponses;\n}\n\n/**\n * OpenAI chat model integration.\n *\n * To use with Azure, import the `AzureChatOpenAI` class.\n *\n * Setup:\n * Install `@langchain/openai` and set an environment variable named `OPENAI_API_KEY`.\n *\n * ```bash\n * npm install @langchain/openai\n * export OPENAI_API_KEY=\"your-api-key\"\n * ```\n *\n * ## [Constructor args](https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html#constructor)\n *\n * ## [Runtime args](https://api.js.langchain.com/interfaces/langchain_openai.ChatOpenAICallOptions.html)\n *\n * Runtime args can be passed as the second argument to any of the base runnable methods `.invoke`. `.stream`, `.batch`, etc.\n * They can also be passed via `.withConfig`, or the second arg in `.bindTools`, like shown in the examples below:\n *\n * ```typescript\n * // When calling `.withConfig`, call options should be passed via the first argument\n * const llmWithArgsBound = llm.withConfig({\n * stop: [\"\\n\"],\n * tools: [...],\n * });\n *\n * // When calling `.bindTools`, call options should be passed via the second argument\n * const llmWithTools = llm.bindTools(\n * [...],\n * {\n * tool_choice: \"auto\",\n * }\n * );\n * ```\n *\n * ## Examples\n *\n * <details open>\n * <summary><strong>Instantiate</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from '@langchain/openai';\n *\n * const llm = new ChatOpenAI({\n * model: \"gpt-4o-mini\",\n * temperature: 0,\n * maxTokens: undefined,\n * timeout: undefined,\n * maxRetries: 2,\n * // apiKey: \"...\",\n * // configuration: {\n * // baseURL: \"...\",\n * // }\n * // organization: \"...\",\n * // other params...\n * });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Invoking</strong></summary>\n *\n * ```typescript\n * const input = `Translate \"I love programming\" into French.`;\n *\n * // Models also accept a list of chat messages or a formatted prompt\n * const result = await llm.invoke(input);\n * console.log(result);\n * ```\n *\n * ```txt\n * AIMessage {\n * \"id\": \"chatcmpl-9u4Mpu44CbPjwYFkTbeoZgvzB00Tz\",\n * \"content\": \"J'adore la programmation.\",\n * \"response_metadata\": {\n * \"tokenUsage\": {\n * \"completionTokens\": 5,\n * \"promptTokens\": 28,\n * \"totalTokens\": 33\n * },\n * \"finish_reason\": \"stop\",\n * \"system_fingerprint\": \"fp_3aa7262c27\"\n * },\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Streaming Chunks</strong></summary>\n *\n * ```typescript\n * for await (const chunk of await llm.stream(input)) {\n * console.log(chunk);\n * }\n * ```\n *\n * ```txt\n * AIMessageChunk {\n * \"id\": \"chatcmpl-9u4NWB7yUeHCKdLr6jP3HpaOYHTqs\",\n * \"content\": \"\"\n * }\n * AIMessageChunk {\n * \"content\": \"J\"\n * }\n * AIMessageChunk {\n * \"content\": \"'adore\"\n * }\n * AIMessageChunk {\n * \"content\": \" la\"\n * }\n * AIMessageChunk {\n * \"content\": \" programmation\",,\n * }\n * AIMessageChunk {\n * \"content\": \".\",,\n * }\n * AIMessageChunk {\n * \"content\": \"\",\n * \"response_metadata\": {\n * \"finish_reason\": \"stop\",\n * \"system_fingerprint\": \"fp_c9aa9c0491\"\n * },\n * }\n * AIMessageChunk {\n * \"content\": \"\",\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Aggregate Streamed Chunks</strong></summary>\n *\n * ```typescript\n * import { AIMessageChunk } from '@langchain/core/messages';\n * import { concat } from '@langchain/core/utils/stream';\n *\n * const stream = await llm.stream(input);\n * let full: AIMessageChunk | undefined;\n * for await (const chunk of stream) {\n * full = !full ? chunk : concat(full, chunk);\n * }\n * console.log(full);\n * ```\n *\n * ```txt\n * AIMessageChunk {\n * \"id\": \"chatcmpl-9u4PnX6Fy7OmK46DASy0bH6cxn5Xu\",\n * \"content\": \"J'adore la programmation.\",\n * \"response_metadata\": {\n * \"prompt\": 0,\n * \"completion\": 0,\n * \"finish_reason\": \"stop\",\n * },\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Bind tools</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const GetWeather = {\n * name: \"GetWeather\",\n * description: \"Get the current weather in a given location\",\n * schema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n * }),\n * }\n *\n * const GetPopulation = {\n * name: \"GetPopulation\",\n * description: \"Get the current population in a given location\",\n * schema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n * }),\n * }\n *\n * const llmWithTools = llm.bindTools(\n * [GetWeather, GetPopulation],\n * {\n * // strict: true // enforce tool args schema is respected\n * }\n * );\n * const aiMsg = await llmWithTools.invoke(\n * \"Which city is hotter today and which is bigger: LA or NY?\"\n * );\n * console.log(aiMsg.tool_calls);\n * ```\n *\n * ```txt\n * [\n * {\n * name: 'GetWeather',\n * args: { location: 'Los Angeles, CA' },\n * type: 'tool_call',\n * id: 'call_uPU4FiFzoKAtMxfmPnfQL6UK'\n * },\n * {\n * name: 'GetWeather',\n * args: { location: 'New York, NY' },\n * type: 'tool_call',\n * id: 'call_UNkEwuQsHrGYqgDQuH9nPAtX'\n * },\n * {\n * name: 'GetPopulation',\n * args: { location: 'Los Angeles, CA' },\n * type: 'tool_call',\n * id: 'call_kL3OXxaq9OjIKqRTpvjaCH14'\n * },\n * {\n * name: 'GetPopulation',\n * args: { location: 'New York, NY' },\n * type: 'tool_call',\n * id: 'call_s9KQB1UWj45LLGaEnjz0179q'\n * }\n * ]\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Structured Output</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const Joke = z.object({\n * setup: z.string().describe(\"The setup of the joke\"),\n * punchline: z.string().describe(\"The punchline to the joke\"),\n * rating: z.number().nullable().describe(\"How funny the joke is, from 1 to 10\")\n * }).describe('Joke to tell user.');\n *\n * const structuredLlm = llm.withStructuredOutput(Joke, {\n * name: \"Joke\",\n * strict: true, // Optionally enable OpenAI structured outputs\n * });\n * const jokeResult = await structuredLlm.invoke(\"Tell me a joke about cats\");\n * console.log(jokeResult);\n * ```\n *\n * ```txt\n * {\n * setup: 'Why was the cat sitting on the computer?',\n * punchline: 'Because it wanted to keep an eye on the mouse!',\n * rating: 7\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>JSON Object Response Format</strong></summary>\n *\n * ```typescript\n * const jsonLlm = llm.withConfig({ response_format: { type: \"json_object\" } });\n * const jsonLlmAiMsg = await jsonLlm.invoke(\n * \"Return a JSON object with key 'randomInts' and a value of 10 random ints in [0-99]\"\n * );\n * console.log(jsonLlmAiMsg.content);\n * ```\n *\n * ```txt\n * {\n * \"randomInts\": [23, 87, 45, 12, 78, 34, 56, 90, 11, 67]\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Multimodal</strong></summary>\n *\n * ```typescript\n * import { HumanMessage } from '@langchain/core/messages';\n *\n * const imageUrl = \"https://example.com/image.jpg\";\n * const imageData = await fetch(imageUrl).then(res => res.arrayBuffer());\n * const base64Image = Buffer.from(imageData).toString('base64');\n *\n * const message = new HumanMessage({\n * content: [\n * { type: \"text\", text: \"describe the weather in this image\" },\n * {\n * type: \"image_url\",\n * image_url: { url: `data:image/jpeg;base64,${base64Image}` },\n * },\n * ]\n * });\n *\n * const imageDescriptionAiMsg = await llm.invoke([message]);\n * console.log(imageDescriptionAiMsg.content);\n * ```\n *\n * ```txt\n * The weather in the image appears to be clear and sunny. The sky is mostly blue with a few scattered white clouds, indicating fair weather. The bright sunlight is casting shadows on the green, grassy hill, suggesting it is a pleasant day with good visibility. There are no signs of rain or stormy conditions.\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Usage Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForMetadata = await llm.invoke(input);\n * console.log(aiMsgForMetadata.usage_metadata);\n * ```\n *\n * ```txt\n * { input_tokens: 28, output_tokens: 5, total_tokens: 33 }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Logprobs</strong></summary>\n *\n * ```typescript\n * const logprobsLlm = new ChatOpenAI({ model: \"gpt-4o-mini\", logprobs: true });\n * const aiMsgForLogprobs = await logprobsLlm.invoke(input);\n * console.log(aiMsgForLogprobs.response_metadata.logprobs);\n * ```\n *\n * ```txt\n * {\n * content: [\n * {\n * token: 'J',\n * logprob: -0.000050616763,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: \"'\",\n * logprob: -0.01868736,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: 'ad',\n * logprob: -0.0000030545007,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * { token: 'ore', logprob: 0, bytes: [Array], top_logprobs: [] },\n * {\n * token: ' la',\n * logprob: -0.515404,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: ' programm',\n * logprob: -0.0000118755715,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * { token: 'ation', logprob: 0, bytes: [Array], top_logprobs: [] },\n * {\n * token: '.',\n * logprob: -0.0000037697225,\n * bytes: [Array],\n * top_logprobs: []\n * }\n * ],\n * refusal: null\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Response Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForResponseMetadata = await llm.invoke(input);\n * console.log(aiMsgForResponseMetadata.response_metadata);\n * ```\n *\n * ```txt\n * {\n * tokenUsage: { completionTokens: 5, promptTokens: 28, totalTokens: 33 },\n * finish_reason: 'stop',\n * system_fingerprint: 'fp_3aa7262c27'\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>JSON Schema Structured Output</strong></summary>\n *\n * ```typescript\n * const llmForJsonSchema = new ChatOpenAI({\n * model: \"gpt-4o-2024-08-06\",\n * }).withStructuredOutput(\n * z.object({\n * command: z.string().describe(\"The command to execute\"),\n * expectedOutput: z.string().describe(\"The expected output of the command\"),\n * options: z\n * .array(z.string())\n * .describe(\"The options you can pass to the command\"),\n * }),\n * {\n * method: \"jsonSchema\",\n * strict: true, // Optional when using the `jsonSchema` method\n * }\n * );\n *\n * const jsonSchemaRes = await llmForJsonSchema.invoke(\n * \"What is the command to list files in a directory?\"\n * );\n * console.log(jsonSchemaRes);\n * ```\n *\n * ```txt\n * {\n * command: 'ls',\n * expectedOutput: 'A list of files and subdirectories within the specified directory.',\n * options: [\n * '-a: include directory entries whose names begin with a dot (.).',\n * '-l: use a long listing format.',\n * '-h: with -l, print sizes in human readable format (e.g., 1K, 234M, 2G).',\n * '-t: sort by time, newest first.',\n * '-r: reverse order while sorting.',\n * '-S: sort by file size, largest first.',\n * '-R: list subdirectories recursively.'\n * ]\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Audio Outputs</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from \"@langchain/openai\";\n *\n * const modelWithAudioOutput = new ChatOpenAI({\n * model: \"gpt-4o-audio-preview\",\n * // You may also pass these fields to `.withConfig` as a call argument.\n * modalities: [\"text\", \"audio\"], // Specifies that the model should output audio.\n * audio: {\n * voice: \"alloy\",\n * format: \"wav\",\n * },\n * });\n *\n * const audioOutputResult = await modelWithAudioOutput.invoke(\"Tell me a joke about cats.\");\n * const castMessageContent = audioOutputResult.content[0] as Record<string, any>;\n *\n * console.log({\n * ...castMessageContent,\n * data: castMessageContent.data.slice(0, 100) // Sliced for brevity\n * })\n * ```\n *\n * ```txt\n * {\n * id: 'audio_67117718c6008190a3afad3e3054b9b6',\n * data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',\n * expires_at: 1729201448,\n * transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Audio Outputs</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from \"@langchain/openai\";\n *\n * const modelWithAudioOutput = new ChatOpenAI({\n * model: \"gpt-4o-audio-preview\",\n * // You may also pass these fields to `.withConfig` as a call argument.\n * modalities: [\"text\", \"audio\"], // Specifies that the model should output audio.\n * audio: {\n * voice: \"alloy\",\n * format: \"wav\",\n * },\n * });\n *\n * const audioOutputResult = await modelWithAudioOutput.invoke(\"Tell me a joke about cats.\");\n * const castAudioContent = audioOutputResult.additional_kwargs.audio as Record<string, any>;\n *\n * console.log({\n * ...castAudioContent,\n * data: castAudioContent.data.slice(0, 100) // Sliced for brevity\n * })\n * ```\n *\n * ```txt\n * {\n * id: 'audio_67117718c6008190a3afad3e3054b9b6',\n * data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',\n * expires_at: 1729201448,\n * transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'\n * }\n * ```\n * </details>\n *\n * <br />\n */\nexport class ChatOpenAI<\n CallOptions extends ChatOpenAICallOptions = ChatOpenAICallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n /**\n * Whether to use the responses API for all requests. If `false` the responses API will be used\n * only when required in order to fulfill the request.\n */\n useResponsesApi = false;\n\n protected responses: ChatOpenAIResponses;\n\n protected completions: ChatOpenAICompletions;\n\n get lc_serializable_keys(): string[] {\n return [...super.lc_serializable_keys, \"useResponsesApi\"];\n }\n\n get callKeys(): string[] {\n return [...super.callKeys, \"useResponsesApi\"];\n }\n\n constructor(protected fields?: ChatOpenAIFields) {\n super(fields);\n this.useResponsesApi = fields?.useResponsesApi ?? false;\n this.responses = fields?.responses ?? new ChatOpenAIResponses(fields);\n this.completions = fields?.completions ?? new ChatOpenAICompletions(fields);\n }\n\n protected _useResponsesApi(options: this[\"ParsedCallOptions\"] | undefined) {\n const usesBuiltInTools = options?.tools?.some(isBuiltInTool);\n const hasResponsesOnlyKwargs =\n options?.previous_response_id != null ||\n options?.text != null ||\n options?.truncation != null ||\n options?.include != null ||\n options?.reasoning?.summary != null ||\n this.reasoning?.summary != null;\n const hasCustomTools =\n options?.tools?.some(isOpenAICustomTool) ||\n options?.tools?.some(isCustomTool);\n\n return (\n this.useResponsesApi ||\n usesBuiltInTools ||\n hasResponsesOnlyKwargs ||\n hasCustomTools ||\n _modelPrefersResponsesAPI(this.model)\n );\n }\n\n override getLsParams(options: this[\"ParsedCallOptions\"]) {\n const optionsWithDefaults = this._combineCallOptions(options);\n if (this._useResponsesApi(options)) {\n return this.responses.getLsParams(optionsWithDefaults);\n }\n return this.completions.getLsParams(optionsWithDefaults);\n }\n\n override invocationParams(options?: this[\"ParsedCallOptions\"]) {\n const optionsWithDefaults = this._combineCallOptions(options);\n if (this._useResponsesApi(options)) {\n return this.responses.invocationParams(optionsWithDefaults);\n }\n return this.completions.invocationParams(optionsWithDefaults);\n }\n\n /** @ignore */\n override async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this._useResponsesApi(options)) {\n return this.responses._generate(messages, options);\n }\n return this.completions._generate(messages, options, runManager);\n }\n\n override async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n if (this._useResponsesApi(options)) {\n yield* this.responses._streamResponseChunks(\n messages,\n this._combineCallOptions(options),\n runManager\n );\n return;\n }\n yield* this.completions._streamResponseChunks(\n messages,\n this._combineCallOptions(options),\n runManager\n );\n }\n\n override withConfig(\n config: Partial<CallOptions>\n ): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions> {\n const newModel = new ChatOpenAI<CallOptions>(this.fields);\n newModel.defaultOptions = { ...this.defaultOptions, ...config };\n return newModel;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2kBA,IAAa,aAAb,MAAa,mBAEHA,4BAA4B;;;;;CAKpC,kBAAkB;CAElB,AAAU;CAEV,AAAU;CAEV,IAAI,uBAAiC;AACnC,SAAO,CAAC,GAAG,MAAM,sBAAsB,iBAAkB;CAC1D;CAED,IAAI,WAAqB;AACvB,SAAO,CAAC,GAAG,MAAM,UAAU,iBAAkB;CAC9C;CAED,YAAsBC,QAA2B;EAC/C,MAAM,OAAO;EADO;EAEpB,KAAK,kBAAkB,QAAQ,mBAAmB;EAClD,KAAK,YAAY,QAAQ,aAAa,IAAIC,sCAAoB;EAC9D,KAAK,cAAc,QAAQ,eAAe,IAAIC,0CAAsB;CACrE;CAED,AAAU,iBAAiBC,SAAgD;EACzE,MAAM,mBAAmB,SAAS,OAAO,KAAKC,4BAAc;EAC5D,MAAM,yBACJ,SAAS,wBAAwB,QACjC,SAAS,QAAQ,QACjB,SAAS,cAAc,QACvB,SAAS,WAAW,QACpB,SAAS,WAAW,WAAW,QAC/B,KAAK,WAAW,WAAW;EAC7B,MAAM,iBACJ,SAAS,OAAO,KAAKC,iCAAmB,IACxC,SAAS,OAAO,KAAKC,2BAAa;AAEpC,SACE,KAAK,mBACL,oBACA,0BACA,kBACAC,uCAA0B,KAAK,MAAM;CAExC;CAED,AAAS,YAAYC,SAAoC;EACvD,MAAM,sBAAsB,KAAK,oBAAoB,QAAQ;AAC7D,MAAI,KAAK,iBAAiB,QAAQ,CAChC,QAAO,KAAK,UAAU,YAAY,oBAAoB;AAExD,SAAO,KAAK,YAAY,YAAY,oBAAoB;CACzD;CAED,AAAS,iBAAiBC,SAAqC;EAC7D,MAAM,sBAAsB,KAAK,oBAAoB,QAAQ;AAC7D,MAAI,KAAK,iBAAiB,QAAQ,CAChC,QAAO,KAAK,UAAU,iBAAiB,oBAAoB;AAE7D,SAAO,KAAK,YAAY,iBAAiB,oBAAoB;CAC9D;;CAGD,MAAe,UACbC,UACAF,SACAG,YACqB;AACrB,MAAI,KAAK,iBAAiB,QAAQ,CAChC,QAAO,KAAK,UAAU,UAAU,UAAU,QAAQ;AAEpD,SAAO,KAAK,YAAY,UAAU,UAAU,SAAS,WAAW;CACjE;CAED,OAAgB,sBACdD,UACAF,SACAG,YACqC;AACrC,MAAI,KAAK,iBAAiB,QAAQ,EAAE;GAClC,OAAO,KAAK,UAAU,sBACpB,UACA,KAAK,oBAAoB,QAAQ,EACjC,WACD;AACD;EACD;EACD,OAAO,KAAK,YAAY,sBACtB,UACA,KAAK,oBAAoB,QAAQ,EACjC,WACD;CACF;CAED,AAAS,WACPC,QAC+D;EAC/D,MAAM,WAAW,IAAI,WAAwB,KAAK;EAClD,SAAS,iBAAiB;GAAE,GAAG,KAAK;GAAgB,GAAG;EAAQ;AAC/D,SAAO;CACR;AACF"}
1
+ {"version":3,"file":"index.cjs","names":["BaseChatOpenAI","fields?: ChatOpenAIFields","ChatOpenAIResponses","ChatOpenAICompletions","options: this[\"ParsedCallOptions\"] | undefined","isBuiltInTool","isOpenAICustomTool","isCustomTool","_modelPrefersResponsesAPI","options: this[\"ParsedCallOptions\"]","options?: this[\"ParsedCallOptions\"]","messages: BaseMessage[]","runManager?: CallbackManagerForLLMRun","config: Partial<CallOptions>"],"sources":["../../src/chat_models/index.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessageChunk, type BaseMessage } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { type BaseLanguageModelInput } from \"@langchain/core/language_models/base\";\nimport { Runnable } from \"@langchain/core/runnables\";\nimport { type OpenAICallOptions, type OpenAIChatInput } from \"../types.js\";\nimport {\n _convertToOpenAITool,\n isBuiltInTool,\n isCustomTool,\n isOpenAICustomTool,\n} from \"../utils/tools.js\";\nimport { _modelPrefersResponsesAPI } from \"../utils/misc.js\";\nimport { _convertOpenAIResponsesUsageToLangChainUsage } from \"../utils/output.js\";\nimport {\n ChatOpenAICompletions,\n ChatOpenAICompletionsCallOptions,\n} from \"./completions.js\";\nimport {\n ChatOpenAIResponses,\n ChatOpenAIResponsesCallOptions,\n} from \"./responses.js\";\nimport { BaseChatOpenAI, BaseChatOpenAIFields } from \"./base.js\";\n\nexport type { OpenAICallOptions, OpenAIChatInput };\n\nexport type ChatOpenAICallOptions = ChatOpenAICompletionsCallOptions &\n ChatOpenAIResponsesCallOptions;\n\nexport interface ChatOpenAIFields extends BaseChatOpenAIFields {\n /**\n * Whether to use the responses API for all requests. If `false` the responses API will be used\n * only when required in order to fulfill the request.\n */\n useResponsesApi?: boolean;\n /**\n * The completions chat instance\n * @internal\n */\n completions?: ChatOpenAICompletions;\n /**\n * The responses chat instance\n * @internal\n */\n responses?: ChatOpenAIResponses;\n}\n\n/**\n * OpenAI chat model integration.\n *\n * To use with Azure, import the `AzureChatOpenAI` class.\n *\n * Setup:\n * Install `@langchain/openai` and set an environment variable named `OPENAI_API_KEY`.\n *\n * ```bash\n * npm install @langchain/openai\n * export OPENAI_API_KEY=\"your-api-key\"\n * ```\n *\n * ## [Constructor args](https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html#constructor)\n *\n * ## [Runtime args](https://api.js.langchain.com/interfaces/langchain_openai.ChatOpenAICallOptions.html)\n *\n * Runtime args can be passed as the second argument to any of the base runnable methods `.invoke`. `.stream`, `.batch`, etc.\n * They can also be passed via `.withConfig`, or the second arg in `.bindTools`, like shown in the examples below:\n *\n * ```typescript\n * // When calling `.withConfig`, call options should be passed via the first argument\n * const llmWithArgsBound = llm.withConfig({\n * stop: [\"\\n\"],\n * tools: [...],\n * });\n *\n * // When calling `.bindTools`, call options should be passed via the second argument\n * const llmWithTools = llm.bindTools(\n * [...],\n * {\n * tool_choice: \"auto\",\n * }\n * );\n * ```\n *\n * ## Examples\n *\n * <details open>\n * <summary><strong>Instantiate</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from '@langchain/openai';\n *\n * const llm = new ChatOpenAI({\n * model: \"gpt-4o-mini\",\n * temperature: 0,\n * maxTokens: undefined,\n * timeout: undefined,\n * maxRetries: 2,\n * // apiKey: \"...\",\n * // configuration: {\n * // baseURL: \"...\",\n * // }\n * // organization: \"...\",\n * // other params...\n * });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Invoking</strong></summary>\n *\n * ```typescript\n * const input = `Translate \"I love programming\" into French.`;\n *\n * // Models also accept a list of chat messages or a formatted prompt\n * const result = await llm.invoke(input);\n * console.log(result);\n * ```\n *\n * ```txt\n * AIMessage {\n * \"id\": \"chatcmpl-9u4Mpu44CbPjwYFkTbeoZgvzB00Tz\",\n * \"content\": \"J'adore la programmation.\",\n * \"response_metadata\": {\n * \"tokenUsage\": {\n * \"completionTokens\": 5,\n * \"promptTokens\": 28,\n * \"totalTokens\": 33\n * },\n * \"finish_reason\": \"stop\",\n * \"system_fingerprint\": \"fp_3aa7262c27\"\n * },\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Streaming Chunks</strong></summary>\n *\n * ```typescript\n * for await (const chunk of await llm.stream(input)) {\n * console.log(chunk);\n * }\n * ```\n *\n * ```txt\n * AIMessageChunk {\n * \"id\": \"chatcmpl-9u4NWB7yUeHCKdLr6jP3HpaOYHTqs\",\n * \"content\": \"\"\n * }\n * AIMessageChunk {\n * \"content\": \"J\"\n * }\n * AIMessageChunk {\n * \"content\": \"'adore\"\n * }\n * AIMessageChunk {\n * \"content\": \" la\"\n * }\n * AIMessageChunk {\n * \"content\": \" programmation\",,\n * }\n * AIMessageChunk {\n * \"content\": \".\",,\n * }\n * AIMessageChunk {\n * \"content\": \"\",\n * \"response_metadata\": {\n * \"finish_reason\": \"stop\",\n * \"system_fingerprint\": \"fp_c9aa9c0491\"\n * },\n * }\n * AIMessageChunk {\n * \"content\": \"\",\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Aggregate Streamed Chunks</strong></summary>\n *\n * ```typescript\n * import { AIMessageChunk } from '@langchain/core/messages';\n * import { concat } from '@langchain/core/utils/stream';\n *\n * const stream = await llm.stream(input);\n * let full: AIMessageChunk | undefined;\n * for await (const chunk of stream) {\n * full = !full ? chunk : concat(full, chunk);\n * }\n * console.log(full);\n * ```\n *\n * ```txt\n * AIMessageChunk {\n * \"id\": \"chatcmpl-9u4PnX6Fy7OmK46DASy0bH6cxn5Xu\",\n * \"content\": \"J'adore la programmation.\",\n * \"response_metadata\": {\n * \"prompt\": 0,\n * \"completion\": 0,\n * \"finish_reason\": \"stop\",\n * },\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Bind tools</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const GetWeather = {\n * name: \"GetWeather\",\n * description: \"Get the current weather in a given location\",\n * schema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n * }),\n * }\n *\n * const GetPopulation = {\n * name: \"GetPopulation\",\n * description: \"Get the current population in a given location\",\n * schema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n * }),\n * }\n *\n * const llmWithTools = llm.bindTools(\n * [GetWeather, GetPopulation],\n * {\n * // strict: true // enforce tool args schema is respected\n * }\n * );\n * const aiMsg = await llmWithTools.invoke(\n * \"Which city is hotter today and which is bigger: LA or NY?\"\n * );\n * console.log(aiMsg.tool_calls);\n * ```\n *\n * ```txt\n * [\n * {\n * name: 'GetWeather',\n * args: { location: 'Los Angeles, CA' },\n * type: 'tool_call',\n * id: 'call_uPU4FiFzoKAtMxfmPnfQL6UK'\n * },\n * {\n * name: 'GetWeather',\n * args: { location: 'New York, NY' },\n * type: 'tool_call',\n * id: 'call_UNkEwuQsHrGYqgDQuH9nPAtX'\n * },\n * {\n * name: 'GetPopulation',\n * args: { location: 'Los Angeles, CA' },\n * type: 'tool_call',\n * id: 'call_kL3OXxaq9OjIKqRTpvjaCH14'\n * },\n * {\n * name: 'GetPopulation',\n * args: { location: 'New York, NY' },\n * type: 'tool_call',\n * id: 'call_s9KQB1UWj45LLGaEnjz0179q'\n * }\n * ]\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Structured Output</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const Joke = z.object({\n * setup: z.string().describe(\"The setup of the joke\"),\n * punchline: z.string().describe(\"The punchline to the joke\"),\n * rating: z.number().nullable().describe(\"How funny the joke is, from 1 to 10\")\n * }).describe('Joke to tell user.');\n *\n * const structuredLlm = llm.withStructuredOutput(Joke, {\n * name: \"Joke\",\n * strict: true, // Optionally enable OpenAI structured outputs\n * });\n * const jokeResult = await structuredLlm.invoke(\"Tell me a joke about cats\");\n * console.log(jokeResult);\n * ```\n *\n * ```txt\n * {\n * setup: 'Why was the cat sitting on the computer?',\n * punchline: 'Because it wanted to keep an eye on the mouse!',\n * rating: 7\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>JSON Object Response Format</strong></summary>\n *\n * ```typescript\n * const jsonLlm = llm.withConfig({ response_format: { type: \"json_object\" } });\n * const jsonLlmAiMsg = await jsonLlm.invoke(\n * \"Return a JSON object with key 'randomInts' and a value of 10 random ints in [0-99]\"\n * );\n * console.log(jsonLlmAiMsg.content);\n * ```\n *\n * ```txt\n * {\n * \"randomInts\": [23, 87, 45, 12, 78, 34, 56, 90, 11, 67]\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Multimodal</strong></summary>\n *\n * ```typescript\n * import { HumanMessage } from '@langchain/core/messages';\n *\n * const imageUrl = \"https://example.com/image.jpg\";\n * const imageData = await fetch(imageUrl).then(res => res.arrayBuffer());\n * const base64Image = Buffer.from(imageData).toString('base64');\n *\n * const message = new HumanMessage({\n * content: [\n * { type: \"text\", text: \"describe the weather in this image\" },\n * {\n * type: \"image_url\",\n * image_url: { url: `data:image/jpeg;base64,${base64Image}` },\n * },\n * ]\n * });\n *\n * const imageDescriptionAiMsg = await llm.invoke([message]);\n * console.log(imageDescriptionAiMsg.content);\n * ```\n *\n * ```txt\n * The weather in the image appears to be clear and sunny. The sky is mostly blue with a few scattered white clouds, indicating fair weather. The bright sunlight is casting shadows on the green, grassy hill, suggesting it is a pleasant day with good visibility. There are no signs of rain or stormy conditions.\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Usage Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForMetadata = await llm.invoke(input);\n * console.log(aiMsgForMetadata.usage_metadata);\n * ```\n *\n * ```txt\n * { input_tokens: 28, output_tokens: 5, total_tokens: 33 }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Logprobs</strong></summary>\n *\n * ```typescript\n * const logprobsLlm = new ChatOpenAI({ model: \"gpt-4o-mini\", logprobs: true });\n * const aiMsgForLogprobs = await logprobsLlm.invoke(input);\n * console.log(aiMsgForLogprobs.response_metadata.logprobs);\n * ```\n *\n * ```txt\n * {\n * content: [\n * {\n * token: 'J',\n * logprob: -0.000050616763,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: \"'\",\n * logprob: -0.01868736,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: 'ad',\n * logprob: -0.0000030545007,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * { token: 'ore', logprob: 0, bytes: [Array], top_logprobs: [] },\n * {\n * token: ' la',\n * logprob: -0.515404,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: ' programm',\n * logprob: -0.0000118755715,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * { token: 'ation', logprob: 0, bytes: [Array], top_logprobs: [] },\n * {\n * token: '.',\n * logprob: -0.0000037697225,\n * bytes: [Array],\n * top_logprobs: []\n * }\n * ],\n * refusal: null\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Response Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForResponseMetadata = await llm.invoke(input);\n * console.log(aiMsgForResponseMetadata.response_metadata);\n * ```\n *\n * ```txt\n * {\n * tokenUsage: { completionTokens: 5, promptTokens: 28, totalTokens: 33 },\n * finish_reason: 'stop',\n * system_fingerprint: 'fp_3aa7262c27'\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>JSON Schema Structured Output</strong></summary>\n *\n * ```typescript\n * const llmForJsonSchema = new ChatOpenAI({\n * model: \"gpt-4o-2024-08-06\",\n * }).withStructuredOutput(\n * z.object({\n * command: z.string().describe(\"The command to execute\"),\n * expectedOutput: z.string().describe(\"The expected output of the command\"),\n * options: z\n * .array(z.string())\n * .describe(\"The options you can pass to the command\"),\n * }),\n * {\n * method: \"jsonSchema\",\n * strict: true, // Optional when using the `jsonSchema` method\n * }\n * );\n *\n * const jsonSchemaRes = await llmForJsonSchema.invoke(\n * \"What is the command to list files in a directory?\"\n * );\n * console.log(jsonSchemaRes);\n * ```\n *\n * ```txt\n * {\n * command: 'ls',\n * expectedOutput: 'A list of files and subdirectories within the specified directory.',\n * options: [\n * '-a: include directory entries whose names begin with a dot (.).',\n * '-l: use a long listing format.',\n * '-h: with -l, print sizes in human readable format (e.g., 1K, 234M, 2G).',\n * '-t: sort by time, newest first.',\n * '-r: reverse order while sorting.',\n * '-S: sort by file size, largest first.',\n * '-R: list subdirectories recursively.'\n * ]\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Audio Outputs</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from \"@langchain/openai\";\n *\n * const modelWithAudioOutput = new ChatOpenAI({\n * model: \"gpt-4o-audio-preview\",\n * // You may also pass these fields to `.withConfig` as a call argument.\n * modalities: [\"text\", \"audio\"], // Specifies that the model should output audio.\n * audio: {\n * voice: \"alloy\",\n * format: \"wav\",\n * },\n * });\n *\n * const audioOutputResult = await modelWithAudioOutput.invoke(\"Tell me a joke about cats.\");\n * const castMessageContent = audioOutputResult.content[0] as Record<string, any>;\n *\n * console.log({\n * ...castMessageContent,\n * data: castMessageContent.data.slice(0, 100) // Sliced for brevity\n * })\n * ```\n *\n * ```txt\n * {\n * id: 'audio_67117718c6008190a3afad3e3054b9b6',\n * data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',\n * expires_at: 1729201448,\n * transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Audio Outputs</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from \"@langchain/openai\";\n *\n * const modelWithAudioOutput = new ChatOpenAI({\n * model: \"gpt-4o-audio-preview\",\n * // You may also pass these fields to `.withConfig` as a call argument.\n * modalities: [\"text\", \"audio\"], // Specifies that the model should output audio.\n * audio: {\n * voice: \"alloy\",\n * format: \"wav\",\n * },\n * });\n *\n * const audioOutputResult = await modelWithAudioOutput.invoke(\"Tell me a joke about cats.\");\n * const castAudioContent = audioOutputResult.additional_kwargs.audio as Record<string, any>;\n *\n * console.log({\n * ...castAudioContent,\n * data: castAudioContent.data.slice(0, 100) // Sliced for brevity\n * })\n * ```\n *\n * ```txt\n * {\n * id: 'audio_67117718c6008190a3afad3e3054b9b6',\n * data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',\n * expires_at: 1729201448,\n * transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'\n * }\n * ```\n * </details>\n *\n * <br />\n */\nexport class ChatOpenAI<\n CallOptions extends ChatOpenAICallOptions = ChatOpenAICallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n /**\n * Whether to use the responses API for all requests. If `false` the responses API will be used\n * only when required in order to fulfill the request.\n */\n useResponsesApi = false;\n\n protected responses: ChatOpenAIResponses;\n\n protected completions: ChatOpenAICompletions;\n\n get lc_serializable_keys(): string[] {\n return [...super.lc_serializable_keys, \"useResponsesApi\"];\n }\n\n get callKeys(): string[] {\n return [...super.callKeys, \"useResponsesApi\"];\n }\n\n constructor(protected fields?: ChatOpenAIFields) {\n super(fields);\n this.useResponsesApi = fields?.useResponsesApi ?? false;\n this.responses = fields?.responses ?? new ChatOpenAIResponses(fields);\n this.completions = fields?.completions ?? new ChatOpenAICompletions(fields);\n }\n\n protected _useResponsesApi(options: this[\"ParsedCallOptions\"] | undefined) {\n const usesBuiltInTools = options?.tools?.some(isBuiltInTool);\n const hasResponsesOnlyKwargs =\n options?.previous_response_id != null ||\n options?.text != null ||\n options?.truncation != null ||\n options?.include != null ||\n options?.reasoning?.summary != null ||\n this.reasoning?.summary != null;\n const hasCustomTools =\n options?.tools?.some(isOpenAICustomTool) ||\n options?.tools?.some(isCustomTool);\n\n return (\n this.useResponsesApi ||\n usesBuiltInTools ||\n hasResponsesOnlyKwargs ||\n hasCustomTools ||\n _modelPrefersResponsesAPI(this.model)\n );\n }\n\n override getLsParams(options: this[\"ParsedCallOptions\"]) {\n const optionsWithDefaults = this._combineCallOptions(options);\n if (this._useResponsesApi(options)) {\n return this.responses.getLsParams(optionsWithDefaults);\n }\n return this.completions.getLsParams(optionsWithDefaults);\n }\n\n override invocationParams(options?: this[\"ParsedCallOptions\"]) {\n const optionsWithDefaults = this._combineCallOptions(options);\n if (this._useResponsesApi(options)) {\n return this.responses.invocationParams(optionsWithDefaults);\n }\n return this.completions.invocationParams(optionsWithDefaults);\n }\n\n /** @ignore */\n override async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this._useResponsesApi(options)) {\n return this.responses._generate(messages, options, runManager);\n }\n return this.completions._generate(messages, options, runManager);\n }\n\n override async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n if (this._useResponsesApi(options)) {\n yield* this.responses._streamResponseChunks(\n messages,\n this._combineCallOptions(options),\n runManager\n );\n return;\n }\n yield* this.completions._streamResponseChunks(\n messages,\n this._combineCallOptions(options),\n runManager\n );\n }\n\n override withConfig(\n config: Partial<CallOptions>\n ): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions> {\n const newModel = new ChatOpenAI<CallOptions>(this.fields);\n newModel.defaultOptions = { ...this.defaultOptions, ...config };\n return newModel;\n }\n}\n"],"mappings":"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"}
@@ -584,7 +584,7 @@ var ChatOpenAI = class ChatOpenAI extends BaseChatOpenAI {
584
584
  }
585
585
  /** @ignore */
586
586
  async _generate(messages, options, runManager) {
587
- if (this._useResponsesApi(options)) return this.responses._generate(messages, options);
587
+ if (this._useResponsesApi(options)) return this.responses._generate(messages, options, runManager);
588
588
  return this.completions._generate(messages, options, runManager);
589
589
  }
590
590
  async *_streamResponseChunks(messages, options, runManager) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["fields?: ChatOpenAIFields","options: this[\"ParsedCallOptions\"] | undefined","options: this[\"ParsedCallOptions\"]","options?: this[\"ParsedCallOptions\"]","messages: BaseMessage[]","runManager?: CallbackManagerForLLMRun","config: Partial<CallOptions>"],"sources":["../../src/chat_models/index.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessageChunk, type BaseMessage } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { type BaseLanguageModelInput } from \"@langchain/core/language_models/base\";\nimport { Runnable } from \"@langchain/core/runnables\";\nimport { type OpenAICallOptions, type OpenAIChatInput } from \"../types.js\";\nimport {\n _convertToOpenAITool,\n isBuiltInTool,\n isCustomTool,\n isOpenAICustomTool,\n} from \"../utils/tools.js\";\nimport { _modelPrefersResponsesAPI } from \"../utils/misc.js\";\nimport { _convertOpenAIResponsesUsageToLangChainUsage } from \"../utils/output.js\";\nimport {\n ChatOpenAICompletions,\n ChatOpenAICompletionsCallOptions,\n} from \"./completions.js\";\nimport {\n ChatOpenAIResponses,\n ChatOpenAIResponsesCallOptions,\n} from \"./responses.js\";\nimport { BaseChatOpenAI, BaseChatOpenAIFields } from \"./base.js\";\n\nexport type { OpenAICallOptions, OpenAIChatInput };\n\nexport type ChatOpenAICallOptions = ChatOpenAICompletionsCallOptions &\n ChatOpenAIResponsesCallOptions;\n\nexport interface ChatOpenAIFields extends BaseChatOpenAIFields {\n /**\n * Whether to use the responses API for all requests. If `false` the responses API will be used\n * only when required in order to fulfill the request.\n */\n useResponsesApi?: boolean;\n /**\n * The completions chat instance\n * @internal\n */\n completions?: ChatOpenAICompletions;\n /**\n * The responses chat instance\n * @internal\n */\n responses?: ChatOpenAIResponses;\n}\n\n/**\n * OpenAI chat model integration.\n *\n * To use with Azure, import the `AzureChatOpenAI` class.\n *\n * Setup:\n * Install `@langchain/openai` and set an environment variable named `OPENAI_API_KEY`.\n *\n * ```bash\n * npm install @langchain/openai\n * export OPENAI_API_KEY=\"your-api-key\"\n * ```\n *\n * ## [Constructor args](https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html#constructor)\n *\n * ## [Runtime args](https://api.js.langchain.com/interfaces/langchain_openai.ChatOpenAICallOptions.html)\n *\n * Runtime args can be passed as the second argument to any of the base runnable methods `.invoke`. `.stream`, `.batch`, etc.\n * They can also be passed via `.withConfig`, or the second arg in `.bindTools`, like shown in the examples below:\n *\n * ```typescript\n * // When calling `.withConfig`, call options should be passed via the first argument\n * const llmWithArgsBound = llm.withConfig({\n * stop: [\"\\n\"],\n * tools: [...],\n * });\n *\n * // When calling `.bindTools`, call options should be passed via the second argument\n * const llmWithTools = llm.bindTools(\n * [...],\n * {\n * tool_choice: \"auto\",\n * }\n * );\n * ```\n *\n * ## Examples\n *\n * <details open>\n * <summary><strong>Instantiate</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from '@langchain/openai';\n *\n * const llm = new ChatOpenAI({\n * model: \"gpt-4o-mini\",\n * temperature: 0,\n * maxTokens: undefined,\n * timeout: undefined,\n * maxRetries: 2,\n * // apiKey: \"...\",\n * // configuration: {\n * // baseURL: \"...\",\n * // }\n * // organization: \"...\",\n * // other params...\n * });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Invoking</strong></summary>\n *\n * ```typescript\n * const input = `Translate \"I love programming\" into French.`;\n *\n * // Models also accept a list of chat messages or a formatted prompt\n * const result = await llm.invoke(input);\n * console.log(result);\n * ```\n *\n * ```txt\n * AIMessage {\n * \"id\": \"chatcmpl-9u4Mpu44CbPjwYFkTbeoZgvzB00Tz\",\n * \"content\": \"J'adore la programmation.\",\n * \"response_metadata\": {\n * \"tokenUsage\": {\n * \"completionTokens\": 5,\n * \"promptTokens\": 28,\n * \"totalTokens\": 33\n * },\n * \"finish_reason\": \"stop\",\n * \"system_fingerprint\": \"fp_3aa7262c27\"\n * },\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Streaming Chunks</strong></summary>\n *\n * ```typescript\n * for await (const chunk of await llm.stream(input)) {\n * console.log(chunk);\n * }\n * ```\n *\n * ```txt\n * AIMessageChunk {\n * \"id\": \"chatcmpl-9u4NWB7yUeHCKdLr6jP3HpaOYHTqs\",\n * \"content\": \"\"\n * }\n * AIMessageChunk {\n * \"content\": \"J\"\n * }\n * AIMessageChunk {\n * \"content\": \"'adore\"\n * }\n * AIMessageChunk {\n * \"content\": \" la\"\n * }\n * AIMessageChunk {\n * \"content\": \" programmation\",,\n * }\n * AIMessageChunk {\n * \"content\": \".\",,\n * }\n * AIMessageChunk {\n * \"content\": \"\",\n * \"response_metadata\": {\n * \"finish_reason\": \"stop\",\n * \"system_fingerprint\": \"fp_c9aa9c0491\"\n * },\n * }\n * AIMessageChunk {\n * \"content\": \"\",\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Aggregate Streamed Chunks</strong></summary>\n *\n * ```typescript\n * import { AIMessageChunk } from '@langchain/core/messages';\n * import { concat } from '@langchain/core/utils/stream';\n *\n * const stream = await llm.stream(input);\n * let full: AIMessageChunk | undefined;\n * for await (const chunk of stream) {\n * full = !full ? chunk : concat(full, chunk);\n * }\n * console.log(full);\n * ```\n *\n * ```txt\n * AIMessageChunk {\n * \"id\": \"chatcmpl-9u4PnX6Fy7OmK46DASy0bH6cxn5Xu\",\n * \"content\": \"J'adore la programmation.\",\n * \"response_metadata\": {\n * \"prompt\": 0,\n * \"completion\": 0,\n * \"finish_reason\": \"stop\",\n * },\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Bind tools</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const GetWeather = {\n * name: \"GetWeather\",\n * description: \"Get the current weather in a given location\",\n * schema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n * }),\n * }\n *\n * const GetPopulation = {\n * name: \"GetPopulation\",\n * description: \"Get the current population in a given location\",\n * schema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n * }),\n * }\n *\n * const llmWithTools = llm.bindTools(\n * [GetWeather, GetPopulation],\n * {\n * // strict: true // enforce tool args schema is respected\n * }\n * );\n * const aiMsg = await llmWithTools.invoke(\n * \"Which city is hotter today and which is bigger: LA or NY?\"\n * );\n * console.log(aiMsg.tool_calls);\n * ```\n *\n * ```txt\n * [\n * {\n * name: 'GetWeather',\n * args: { location: 'Los Angeles, CA' },\n * type: 'tool_call',\n * id: 'call_uPU4FiFzoKAtMxfmPnfQL6UK'\n * },\n * {\n * name: 'GetWeather',\n * args: { location: 'New York, NY' },\n * type: 'tool_call',\n * id: 'call_UNkEwuQsHrGYqgDQuH9nPAtX'\n * },\n * {\n * name: 'GetPopulation',\n * args: { location: 'Los Angeles, CA' },\n * type: 'tool_call',\n * id: 'call_kL3OXxaq9OjIKqRTpvjaCH14'\n * },\n * {\n * name: 'GetPopulation',\n * args: { location: 'New York, NY' },\n * type: 'tool_call',\n * id: 'call_s9KQB1UWj45LLGaEnjz0179q'\n * }\n * ]\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Structured Output</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const Joke = z.object({\n * setup: z.string().describe(\"The setup of the joke\"),\n * punchline: z.string().describe(\"The punchline to the joke\"),\n * rating: z.number().nullable().describe(\"How funny the joke is, from 1 to 10\")\n * }).describe('Joke to tell user.');\n *\n * const structuredLlm = llm.withStructuredOutput(Joke, {\n * name: \"Joke\",\n * strict: true, // Optionally enable OpenAI structured outputs\n * });\n * const jokeResult = await structuredLlm.invoke(\"Tell me a joke about cats\");\n * console.log(jokeResult);\n * ```\n *\n * ```txt\n * {\n * setup: 'Why was the cat sitting on the computer?',\n * punchline: 'Because it wanted to keep an eye on the mouse!',\n * rating: 7\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>JSON Object Response Format</strong></summary>\n *\n * ```typescript\n * const jsonLlm = llm.withConfig({ response_format: { type: \"json_object\" } });\n * const jsonLlmAiMsg = await jsonLlm.invoke(\n * \"Return a JSON object with key 'randomInts' and a value of 10 random ints in [0-99]\"\n * );\n * console.log(jsonLlmAiMsg.content);\n * ```\n *\n * ```txt\n * {\n * \"randomInts\": [23, 87, 45, 12, 78, 34, 56, 90, 11, 67]\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Multimodal</strong></summary>\n *\n * ```typescript\n * import { HumanMessage } from '@langchain/core/messages';\n *\n * const imageUrl = \"https://example.com/image.jpg\";\n * const imageData = await fetch(imageUrl).then(res => res.arrayBuffer());\n * const base64Image = Buffer.from(imageData).toString('base64');\n *\n * const message = new HumanMessage({\n * content: [\n * { type: \"text\", text: \"describe the weather in this image\" },\n * {\n * type: \"image_url\",\n * image_url: { url: `data:image/jpeg;base64,${base64Image}` },\n * },\n * ]\n * });\n *\n * const imageDescriptionAiMsg = await llm.invoke([message]);\n * console.log(imageDescriptionAiMsg.content);\n * ```\n *\n * ```txt\n * The weather in the image appears to be clear and sunny. The sky is mostly blue with a few scattered white clouds, indicating fair weather. The bright sunlight is casting shadows on the green, grassy hill, suggesting it is a pleasant day with good visibility. There are no signs of rain or stormy conditions.\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Usage Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForMetadata = await llm.invoke(input);\n * console.log(aiMsgForMetadata.usage_metadata);\n * ```\n *\n * ```txt\n * { input_tokens: 28, output_tokens: 5, total_tokens: 33 }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Logprobs</strong></summary>\n *\n * ```typescript\n * const logprobsLlm = new ChatOpenAI({ model: \"gpt-4o-mini\", logprobs: true });\n * const aiMsgForLogprobs = await logprobsLlm.invoke(input);\n * console.log(aiMsgForLogprobs.response_metadata.logprobs);\n * ```\n *\n * ```txt\n * {\n * content: [\n * {\n * token: 'J',\n * logprob: -0.000050616763,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: \"'\",\n * logprob: -0.01868736,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: 'ad',\n * logprob: -0.0000030545007,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * { token: 'ore', logprob: 0, bytes: [Array], top_logprobs: [] },\n * {\n * token: ' la',\n * logprob: -0.515404,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: ' programm',\n * logprob: -0.0000118755715,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * { token: 'ation', logprob: 0, bytes: [Array], top_logprobs: [] },\n * {\n * token: '.',\n * logprob: -0.0000037697225,\n * bytes: [Array],\n * top_logprobs: []\n * }\n * ],\n * refusal: null\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Response Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForResponseMetadata = await llm.invoke(input);\n * console.log(aiMsgForResponseMetadata.response_metadata);\n * ```\n *\n * ```txt\n * {\n * tokenUsage: { completionTokens: 5, promptTokens: 28, totalTokens: 33 },\n * finish_reason: 'stop',\n * system_fingerprint: 'fp_3aa7262c27'\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>JSON Schema Structured Output</strong></summary>\n *\n * ```typescript\n * const llmForJsonSchema = new ChatOpenAI({\n * model: \"gpt-4o-2024-08-06\",\n * }).withStructuredOutput(\n * z.object({\n * command: z.string().describe(\"The command to execute\"),\n * expectedOutput: z.string().describe(\"The expected output of the command\"),\n * options: z\n * .array(z.string())\n * .describe(\"The options you can pass to the command\"),\n * }),\n * {\n * method: \"jsonSchema\",\n * strict: true, // Optional when using the `jsonSchema` method\n * }\n * );\n *\n * const jsonSchemaRes = await llmForJsonSchema.invoke(\n * \"What is the command to list files in a directory?\"\n * );\n * console.log(jsonSchemaRes);\n * ```\n *\n * ```txt\n * {\n * command: 'ls',\n * expectedOutput: 'A list of files and subdirectories within the specified directory.',\n * options: [\n * '-a: include directory entries whose names begin with a dot (.).',\n * '-l: use a long listing format.',\n * '-h: with -l, print sizes in human readable format (e.g., 1K, 234M, 2G).',\n * '-t: sort by time, newest first.',\n * '-r: reverse order while sorting.',\n * '-S: sort by file size, largest first.',\n * '-R: list subdirectories recursively.'\n * ]\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Audio Outputs</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from \"@langchain/openai\";\n *\n * const modelWithAudioOutput = new ChatOpenAI({\n * model: \"gpt-4o-audio-preview\",\n * // You may also pass these fields to `.withConfig` as a call argument.\n * modalities: [\"text\", \"audio\"], // Specifies that the model should output audio.\n * audio: {\n * voice: \"alloy\",\n * format: \"wav\",\n * },\n * });\n *\n * const audioOutputResult = await modelWithAudioOutput.invoke(\"Tell me a joke about cats.\");\n * const castMessageContent = audioOutputResult.content[0] as Record<string, any>;\n *\n * console.log({\n * ...castMessageContent,\n * data: castMessageContent.data.slice(0, 100) // Sliced for brevity\n * })\n * ```\n *\n * ```txt\n * {\n * id: 'audio_67117718c6008190a3afad3e3054b9b6',\n * data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',\n * expires_at: 1729201448,\n * transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Audio Outputs</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from \"@langchain/openai\";\n *\n * const modelWithAudioOutput = new ChatOpenAI({\n * model: \"gpt-4o-audio-preview\",\n * // You may also pass these fields to `.withConfig` as a call argument.\n * modalities: [\"text\", \"audio\"], // Specifies that the model should output audio.\n * audio: {\n * voice: \"alloy\",\n * format: \"wav\",\n * },\n * });\n *\n * const audioOutputResult = await modelWithAudioOutput.invoke(\"Tell me a joke about cats.\");\n * const castAudioContent = audioOutputResult.additional_kwargs.audio as Record<string, any>;\n *\n * console.log({\n * ...castAudioContent,\n * data: castAudioContent.data.slice(0, 100) // Sliced for brevity\n * })\n * ```\n *\n * ```txt\n * {\n * id: 'audio_67117718c6008190a3afad3e3054b9b6',\n * data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',\n * expires_at: 1729201448,\n * transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'\n * }\n * ```\n * </details>\n *\n * <br />\n */\nexport class ChatOpenAI<\n CallOptions extends ChatOpenAICallOptions = ChatOpenAICallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n /**\n * Whether to use the responses API for all requests. If `false` the responses API will be used\n * only when required in order to fulfill the request.\n */\n useResponsesApi = false;\n\n protected responses: ChatOpenAIResponses;\n\n protected completions: ChatOpenAICompletions;\n\n get lc_serializable_keys(): string[] {\n return [...super.lc_serializable_keys, \"useResponsesApi\"];\n }\n\n get callKeys(): string[] {\n return [...super.callKeys, \"useResponsesApi\"];\n }\n\n constructor(protected fields?: ChatOpenAIFields) {\n super(fields);\n this.useResponsesApi = fields?.useResponsesApi ?? false;\n this.responses = fields?.responses ?? new ChatOpenAIResponses(fields);\n this.completions = fields?.completions ?? new ChatOpenAICompletions(fields);\n }\n\n protected _useResponsesApi(options: this[\"ParsedCallOptions\"] | undefined) {\n const usesBuiltInTools = options?.tools?.some(isBuiltInTool);\n const hasResponsesOnlyKwargs =\n options?.previous_response_id != null ||\n options?.text != null ||\n options?.truncation != null ||\n options?.include != null ||\n options?.reasoning?.summary != null ||\n this.reasoning?.summary != null;\n const hasCustomTools =\n options?.tools?.some(isOpenAICustomTool) ||\n options?.tools?.some(isCustomTool);\n\n return (\n this.useResponsesApi ||\n usesBuiltInTools ||\n hasResponsesOnlyKwargs ||\n hasCustomTools ||\n _modelPrefersResponsesAPI(this.model)\n );\n }\n\n override getLsParams(options: this[\"ParsedCallOptions\"]) {\n const optionsWithDefaults = this._combineCallOptions(options);\n if (this._useResponsesApi(options)) {\n return this.responses.getLsParams(optionsWithDefaults);\n }\n return this.completions.getLsParams(optionsWithDefaults);\n }\n\n override invocationParams(options?: this[\"ParsedCallOptions\"]) {\n const optionsWithDefaults = this._combineCallOptions(options);\n if (this._useResponsesApi(options)) {\n return this.responses.invocationParams(optionsWithDefaults);\n }\n return this.completions.invocationParams(optionsWithDefaults);\n }\n\n /** @ignore */\n override async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this._useResponsesApi(options)) {\n return this.responses._generate(messages, options);\n }\n return this.completions._generate(messages, options, runManager);\n }\n\n override async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n if (this._useResponsesApi(options)) {\n yield* this.responses._streamResponseChunks(\n messages,\n this._combineCallOptions(options),\n runManager\n );\n return;\n }\n yield* this.completions._streamResponseChunks(\n messages,\n this._combineCallOptions(options),\n runManager\n );\n }\n\n override withConfig(\n config: Partial<CallOptions>\n ): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions> {\n const newModel = new ChatOpenAI<CallOptions>(this.fields);\n newModel.defaultOptions = { ...this.defaultOptions, ...config };\n return newModel;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2kBA,IAAa,aAAb,MAAa,mBAEH,eAA4B;;;;;CAKpC,kBAAkB;CAElB,AAAU;CAEV,AAAU;CAEV,IAAI,uBAAiC;AACnC,SAAO,CAAC,GAAG,MAAM,sBAAsB,iBAAkB;CAC1D;CAED,IAAI,WAAqB;AACvB,SAAO,CAAC,GAAG,MAAM,UAAU,iBAAkB;CAC9C;CAED,YAAsBA,QAA2B;EAC/C,MAAM,OAAO;EADO;EAEpB,KAAK,kBAAkB,QAAQ,mBAAmB;EAClD,KAAK,YAAY,QAAQ,aAAa,IAAI,oBAAoB;EAC9D,KAAK,cAAc,QAAQ,eAAe,IAAI,sBAAsB;CACrE;CAED,AAAU,iBAAiBC,SAAgD;EACzE,MAAM,mBAAmB,SAAS,OAAO,KAAK,cAAc;EAC5D,MAAM,yBACJ,SAAS,wBAAwB,QACjC,SAAS,QAAQ,QACjB,SAAS,cAAc,QACvB,SAAS,WAAW,QACpB,SAAS,WAAW,WAAW,QAC/B,KAAK,WAAW,WAAW;EAC7B,MAAM,iBACJ,SAAS,OAAO,KAAK,mBAAmB,IACxC,SAAS,OAAO,KAAK,aAAa;AAEpC,SACE,KAAK,mBACL,oBACA,0BACA,kBACA,0BAA0B,KAAK,MAAM;CAExC;CAED,AAAS,YAAYC,SAAoC;EACvD,MAAM,sBAAsB,KAAK,oBAAoB,QAAQ;AAC7D,MAAI,KAAK,iBAAiB,QAAQ,CAChC,QAAO,KAAK,UAAU,YAAY,oBAAoB;AAExD,SAAO,KAAK,YAAY,YAAY,oBAAoB;CACzD;CAED,AAAS,iBAAiBC,SAAqC;EAC7D,MAAM,sBAAsB,KAAK,oBAAoB,QAAQ;AAC7D,MAAI,KAAK,iBAAiB,QAAQ,CAChC,QAAO,KAAK,UAAU,iBAAiB,oBAAoB;AAE7D,SAAO,KAAK,YAAY,iBAAiB,oBAAoB;CAC9D;;CAGD,MAAe,UACbC,UACAF,SACAG,YACqB;AACrB,MAAI,KAAK,iBAAiB,QAAQ,CAChC,QAAO,KAAK,UAAU,UAAU,UAAU,QAAQ;AAEpD,SAAO,KAAK,YAAY,UAAU,UAAU,SAAS,WAAW;CACjE;CAED,OAAgB,sBACdD,UACAF,SACAG,YACqC;AACrC,MAAI,KAAK,iBAAiB,QAAQ,EAAE;GAClC,OAAO,KAAK,UAAU,sBACpB,UACA,KAAK,oBAAoB,QAAQ,EACjC,WACD;AACD;EACD;EACD,OAAO,KAAK,YAAY,sBACtB,UACA,KAAK,oBAAoB,QAAQ,EACjC,WACD;CACF;CAED,AAAS,WACPC,QAC+D;EAC/D,MAAM,WAAW,IAAI,WAAwB,KAAK;EAClD,SAAS,iBAAiB;GAAE,GAAG,KAAK;GAAgB,GAAG;EAAQ;AAC/D,SAAO;CACR;AACF"}
1
+ {"version":3,"file":"index.js","names":["fields?: ChatOpenAIFields","options: this[\"ParsedCallOptions\"] | undefined","options: this[\"ParsedCallOptions\"]","options?: this[\"ParsedCallOptions\"]","messages: BaseMessage[]","runManager?: CallbackManagerForLLMRun","config: Partial<CallOptions>"],"sources":["../../src/chat_models/index.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessageChunk, type BaseMessage } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { type BaseLanguageModelInput } from \"@langchain/core/language_models/base\";\nimport { Runnable } from \"@langchain/core/runnables\";\nimport { type OpenAICallOptions, type OpenAIChatInput } from \"../types.js\";\nimport {\n _convertToOpenAITool,\n isBuiltInTool,\n isCustomTool,\n isOpenAICustomTool,\n} from \"../utils/tools.js\";\nimport { _modelPrefersResponsesAPI } from \"../utils/misc.js\";\nimport { _convertOpenAIResponsesUsageToLangChainUsage } from \"../utils/output.js\";\nimport {\n ChatOpenAICompletions,\n ChatOpenAICompletionsCallOptions,\n} from \"./completions.js\";\nimport {\n ChatOpenAIResponses,\n ChatOpenAIResponsesCallOptions,\n} from \"./responses.js\";\nimport { BaseChatOpenAI, BaseChatOpenAIFields } from \"./base.js\";\n\nexport type { OpenAICallOptions, OpenAIChatInput };\n\nexport type ChatOpenAICallOptions = ChatOpenAICompletionsCallOptions &\n ChatOpenAIResponsesCallOptions;\n\nexport interface ChatOpenAIFields extends BaseChatOpenAIFields {\n /**\n * Whether to use the responses API for all requests. If `false` the responses API will be used\n * only when required in order to fulfill the request.\n */\n useResponsesApi?: boolean;\n /**\n * The completions chat instance\n * @internal\n */\n completions?: ChatOpenAICompletions;\n /**\n * The responses chat instance\n * @internal\n */\n responses?: ChatOpenAIResponses;\n}\n\n/**\n * OpenAI chat model integration.\n *\n * To use with Azure, import the `AzureChatOpenAI` class.\n *\n * Setup:\n * Install `@langchain/openai` and set an environment variable named `OPENAI_API_KEY`.\n *\n * ```bash\n * npm install @langchain/openai\n * export OPENAI_API_KEY=\"your-api-key\"\n * ```\n *\n * ## [Constructor args](https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html#constructor)\n *\n * ## [Runtime args](https://api.js.langchain.com/interfaces/langchain_openai.ChatOpenAICallOptions.html)\n *\n * Runtime args can be passed as the second argument to any of the base runnable methods `.invoke`. `.stream`, `.batch`, etc.\n * They can also be passed via `.withConfig`, or the second arg in `.bindTools`, like shown in the examples below:\n *\n * ```typescript\n * // When calling `.withConfig`, call options should be passed via the first argument\n * const llmWithArgsBound = llm.withConfig({\n * stop: [\"\\n\"],\n * tools: [...],\n * });\n *\n * // When calling `.bindTools`, call options should be passed via the second argument\n * const llmWithTools = llm.bindTools(\n * [...],\n * {\n * tool_choice: \"auto\",\n * }\n * );\n * ```\n *\n * ## Examples\n *\n * <details open>\n * <summary><strong>Instantiate</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from '@langchain/openai';\n *\n * const llm = new ChatOpenAI({\n * model: \"gpt-4o-mini\",\n * temperature: 0,\n * maxTokens: undefined,\n * timeout: undefined,\n * maxRetries: 2,\n * // apiKey: \"...\",\n * // configuration: {\n * // baseURL: \"...\",\n * // }\n * // organization: \"...\",\n * // other params...\n * });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Invoking</strong></summary>\n *\n * ```typescript\n * const input = `Translate \"I love programming\" into French.`;\n *\n * // Models also accept a list of chat messages or a formatted prompt\n * const result = await llm.invoke(input);\n * console.log(result);\n * ```\n *\n * ```txt\n * AIMessage {\n * \"id\": \"chatcmpl-9u4Mpu44CbPjwYFkTbeoZgvzB00Tz\",\n * \"content\": \"J'adore la programmation.\",\n * \"response_metadata\": {\n * \"tokenUsage\": {\n * \"completionTokens\": 5,\n * \"promptTokens\": 28,\n * \"totalTokens\": 33\n * },\n * \"finish_reason\": \"stop\",\n * \"system_fingerprint\": \"fp_3aa7262c27\"\n * },\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Streaming Chunks</strong></summary>\n *\n * ```typescript\n * for await (const chunk of await llm.stream(input)) {\n * console.log(chunk);\n * }\n * ```\n *\n * ```txt\n * AIMessageChunk {\n * \"id\": \"chatcmpl-9u4NWB7yUeHCKdLr6jP3HpaOYHTqs\",\n * \"content\": \"\"\n * }\n * AIMessageChunk {\n * \"content\": \"J\"\n * }\n * AIMessageChunk {\n * \"content\": \"'adore\"\n * }\n * AIMessageChunk {\n * \"content\": \" la\"\n * }\n * AIMessageChunk {\n * \"content\": \" programmation\",,\n * }\n * AIMessageChunk {\n * \"content\": \".\",,\n * }\n * AIMessageChunk {\n * \"content\": \"\",\n * \"response_metadata\": {\n * \"finish_reason\": \"stop\",\n * \"system_fingerprint\": \"fp_c9aa9c0491\"\n * },\n * }\n * AIMessageChunk {\n * \"content\": \"\",\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Aggregate Streamed Chunks</strong></summary>\n *\n * ```typescript\n * import { AIMessageChunk } from '@langchain/core/messages';\n * import { concat } from '@langchain/core/utils/stream';\n *\n * const stream = await llm.stream(input);\n * let full: AIMessageChunk | undefined;\n * for await (const chunk of stream) {\n * full = !full ? chunk : concat(full, chunk);\n * }\n * console.log(full);\n * ```\n *\n * ```txt\n * AIMessageChunk {\n * \"id\": \"chatcmpl-9u4PnX6Fy7OmK46DASy0bH6cxn5Xu\",\n * \"content\": \"J'adore la programmation.\",\n * \"response_metadata\": {\n * \"prompt\": 0,\n * \"completion\": 0,\n * \"finish_reason\": \"stop\",\n * },\n * \"usage_metadata\": {\n * \"input_tokens\": 28,\n * \"output_tokens\": 5,\n * \"total_tokens\": 33\n * }\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Bind tools</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const GetWeather = {\n * name: \"GetWeather\",\n * description: \"Get the current weather in a given location\",\n * schema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n * }),\n * }\n *\n * const GetPopulation = {\n * name: \"GetPopulation\",\n * description: \"Get the current population in a given location\",\n * schema: z.object({\n * location: z.string().describe(\"The city and state, e.g. San Francisco, CA\")\n * }),\n * }\n *\n * const llmWithTools = llm.bindTools(\n * [GetWeather, GetPopulation],\n * {\n * // strict: true // enforce tool args schema is respected\n * }\n * );\n * const aiMsg = await llmWithTools.invoke(\n * \"Which city is hotter today and which is bigger: LA or NY?\"\n * );\n * console.log(aiMsg.tool_calls);\n * ```\n *\n * ```txt\n * [\n * {\n * name: 'GetWeather',\n * args: { location: 'Los Angeles, CA' },\n * type: 'tool_call',\n * id: 'call_uPU4FiFzoKAtMxfmPnfQL6UK'\n * },\n * {\n * name: 'GetWeather',\n * args: { location: 'New York, NY' },\n * type: 'tool_call',\n * id: 'call_UNkEwuQsHrGYqgDQuH9nPAtX'\n * },\n * {\n * name: 'GetPopulation',\n * args: { location: 'Los Angeles, CA' },\n * type: 'tool_call',\n * id: 'call_kL3OXxaq9OjIKqRTpvjaCH14'\n * },\n * {\n * name: 'GetPopulation',\n * args: { location: 'New York, NY' },\n * type: 'tool_call',\n * id: 'call_s9KQB1UWj45LLGaEnjz0179q'\n * }\n * ]\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Structured Output</strong></summary>\n *\n * ```typescript\n * import { z } from 'zod';\n *\n * const Joke = z.object({\n * setup: z.string().describe(\"The setup of the joke\"),\n * punchline: z.string().describe(\"The punchline to the joke\"),\n * rating: z.number().nullable().describe(\"How funny the joke is, from 1 to 10\")\n * }).describe('Joke to tell user.');\n *\n * const structuredLlm = llm.withStructuredOutput(Joke, {\n * name: \"Joke\",\n * strict: true, // Optionally enable OpenAI structured outputs\n * });\n * const jokeResult = await structuredLlm.invoke(\"Tell me a joke about cats\");\n * console.log(jokeResult);\n * ```\n *\n * ```txt\n * {\n * setup: 'Why was the cat sitting on the computer?',\n * punchline: 'Because it wanted to keep an eye on the mouse!',\n * rating: 7\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>JSON Object Response Format</strong></summary>\n *\n * ```typescript\n * const jsonLlm = llm.withConfig({ response_format: { type: \"json_object\" } });\n * const jsonLlmAiMsg = await jsonLlm.invoke(\n * \"Return a JSON object with key 'randomInts' and a value of 10 random ints in [0-99]\"\n * );\n * console.log(jsonLlmAiMsg.content);\n * ```\n *\n * ```txt\n * {\n * \"randomInts\": [23, 87, 45, 12, 78, 34, 56, 90, 11, 67]\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Multimodal</strong></summary>\n *\n * ```typescript\n * import { HumanMessage } from '@langchain/core/messages';\n *\n * const imageUrl = \"https://example.com/image.jpg\";\n * const imageData = await fetch(imageUrl).then(res => res.arrayBuffer());\n * const base64Image = Buffer.from(imageData).toString('base64');\n *\n * const message = new HumanMessage({\n * content: [\n * { type: \"text\", text: \"describe the weather in this image\" },\n * {\n * type: \"image_url\",\n * image_url: { url: `data:image/jpeg;base64,${base64Image}` },\n * },\n * ]\n * });\n *\n * const imageDescriptionAiMsg = await llm.invoke([message]);\n * console.log(imageDescriptionAiMsg.content);\n * ```\n *\n * ```txt\n * The weather in the image appears to be clear and sunny. The sky is mostly blue with a few scattered white clouds, indicating fair weather. The bright sunlight is casting shadows on the green, grassy hill, suggesting it is a pleasant day with good visibility. There are no signs of rain or stormy conditions.\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Usage Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForMetadata = await llm.invoke(input);\n * console.log(aiMsgForMetadata.usage_metadata);\n * ```\n *\n * ```txt\n * { input_tokens: 28, output_tokens: 5, total_tokens: 33 }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Logprobs</strong></summary>\n *\n * ```typescript\n * const logprobsLlm = new ChatOpenAI({ model: \"gpt-4o-mini\", logprobs: true });\n * const aiMsgForLogprobs = await logprobsLlm.invoke(input);\n * console.log(aiMsgForLogprobs.response_metadata.logprobs);\n * ```\n *\n * ```txt\n * {\n * content: [\n * {\n * token: 'J',\n * logprob: -0.000050616763,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: \"'\",\n * logprob: -0.01868736,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: 'ad',\n * logprob: -0.0000030545007,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * { token: 'ore', logprob: 0, bytes: [Array], top_logprobs: [] },\n * {\n * token: ' la',\n * logprob: -0.515404,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * {\n * token: ' programm',\n * logprob: -0.0000118755715,\n * bytes: [Array],\n * top_logprobs: []\n * },\n * { token: 'ation', logprob: 0, bytes: [Array], top_logprobs: [] },\n * {\n * token: '.',\n * logprob: -0.0000037697225,\n * bytes: [Array],\n * top_logprobs: []\n * }\n * ],\n * refusal: null\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Response Metadata</strong></summary>\n *\n * ```typescript\n * const aiMsgForResponseMetadata = await llm.invoke(input);\n * console.log(aiMsgForResponseMetadata.response_metadata);\n * ```\n *\n * ```txt\n * {\n * tokenUsage: { completionTokens: 5, promptTokens: 28, totalTokens: 33 },\n * finish_reason: 'stop',\n * system_fingerprint: 'fp_3aa7262c27'\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>JSON Schema Structured Output</strong></summary>\n *\n * ```typescript\n * const llmForJsonSchema = new ChatOpenAI({\n * model: \"gpt-4o-2024-08-06\",\n * }).withStructuredOutput(\n * z.object({\n * command: z.string().describe(\"The command to execute\"),\n * expectedOutput: z.string().describe(\"The expected output of the command\"),\n * options: z\n * .array(z.string())\n * .describe(\"The options you can pass to the command\"),\n * }),\n * {\n * method: \"jsonSchema\",\n * strict: true, // Optional when using the `jsonSchema` method\n * }\n * );\n *\n * const jsonSchemaRes = await llmForJsonSchema.invoke(\n * \"What is the command to list files in a directory?\"\n * );\n * console.log(jsonSchemaRes);\n * ```\n *\n * ```txt\n * {\n * command: 'ls',\n * expectedOutput: 'A list of files and subdirectories within the specified directory.',\n * options: [\n * '-a: include directory entries whose names begin with a dot (.).',\n * '-l: use a long listing format.',\n * '-h: with -l, print sizes in human readable format (e.g., 1K, 234M, 2G).',\n * '-t: sort by time, newest first.',\n * '-r: reverse order while sorting.',\n * '-S: sort by file size, largest first.',\n * '-R: list subdirectories recursively.'\n * ]\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Audio Outputs</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from \"@langchain/openai\";\n *\n * const modelWithAudioOutput = new ChatOpenAI({\n * model: \"gpt-4o-audio-preview\",\n * // You may also pass these fields to `.withConfig` as a call argument.\n * modalities: [\"text\", \"audio\"], // Specifies that the model should output audio.\n * audio: {\n * voice: \"alloy\",\n * format: \"wav\",\n * },\n * });\n *\n * const audioOutputResult = await modelWithAudioOutput.invoke(\"Tell me a joke about cats.\");\n * const castMessageContent = audioOutputResult.content[0] as Record<string, any>;\n *\n * console.log({\n * ...castMessageContent,\n * data: castMessageContent.data.slice(0, 100) // Sliced for brevity\n * })\n * ```\n *\n * ```txt\n * {\n * id: 'audio_67117718c6008190a3afad3e3054b9b6',\n * data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',\n * expires_at: 1729201448,\n * transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'\n * }\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Audio Outputs</strong></summary>\n *\n * ```typescript\n * import { ChatOpenAI } from \"@langchain/openai\";\n *\n * const modelWithAudioOutput = new ChatOpenAI({\n * model: \"gpt-4o-audio-preview\",\n * // You may also pass these fields to `.withConfig` as a call argument.\n * modalities: [\"text\", \"audio\"], // Specifies that the model should output audio.\n * audio: {\n * voice: \"alloy\",\n * format: \"wav\",\n * },\n * });\n *\n * const audioOutputResult = await modelWithAudioOutput.invoke(\"Tell me a joke about cats.\");\n * const castAudioContent = audioOutputResult.additional_kwargs.audio as Record<string, any>;\n *\n * console.log({\n * ...castAudioContent,\n * data: castAudioContent.data.slice(0, 100) // Sliced for brevity\n * })\n * ```\n *\n * ```txt\n * {\n * id: 'audio_67117718c6008190a3afad3e3054b9b6',\n * data: 'UklGRqYwBgBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAATElTVBoAAABJTkZPSVNGVA4AAABMYXZmNTguMjkuMTAwAGRhdGFg',\n * expires_at: 1729201448,\n * transcript: 'Sure! Why did the cat sit on the computer? Because it wanted to keep an eye on the mouse!'\n * }\n * ```\n * </details>\n *\n * <br />\n */\nexport class ChatOpenAI<\n CallOptions extends ChatOpenAICallOptions = ChatOpenAICallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n /**\n * Whether to use the responses API for all requests. If `false` the responses API will be used\n * only when required in order to fulfill the request.\n */\n useResponsesApi = false;\n\n protected responses: ChatOpenAIResponses;\n\n protected completions: ChatOpenAICompletions;\n\n get lc_serializable_keys(): string[] {\n return [...super.lc_serializable_keys, \"useResponsesApi\"];\n }\n\n get callKeys(): string[] {\n return [...super.callKeys, \"useResponsesApi\"];\n }\n\n constructor(protected fields?: ChatOpenAIFields) {\n super(fields);\n this.useResponsesApi = fields?.useResponsesApi ?? false;\n this.responses = fields?.responses ?? new ChatOpenAIResponses(fields);\n this.completions = fields?.completions ?? new ChatOpenAICompletions(fields);\n }\n\n protected _useResponsesApi(options: this[\"ParsedCallOptions\"] | undefined) {\n const usesBuiltInTools = options?.tools?.some(isBuiltInTool);\n const hasResponsesOnlyKwargs =\n options?.previous_response_id != null ||\n options?.text != null ||\n options?.truncation != null ||\n options?.include != null ||\n options?.reasoning?.summary != null ||\n this.reasoning?.summary != null;\n const hasCustomTools =\n options?.tools?.some(isOpenAICustomTool) ||\n options?.tools?.some(isCustomTool);\n\n return (\n this.useResponsesApi ||\n usesBuiltInTools ||\n hasResponsesOnlyKwargs ||\n hasCustomTools ||\n _modelPrefersResponsesAPI(this.model)\n );\n }\n\n override getLsParams(options: this[\"ParsedCallOptions\"]) {\n const optionsWithDefaults = this._combineCallOptions(options);\n if (this._useResponsesApi(options)) {\n return this.responses.getLsParams(optionsWithDefaults);\n }\n return this.completions.getLsParams(optionsWithDefaults);\n }\n\n override invocationParams(options?: this[\"ParsedCallOptions\"]) {\n const optionsWithDefaults = this._combineCallOptions(options);\n if (this._useResponsesApi(options)) {\n return this.responses.invocationParams(optionsWithDefaults);\n }\n return this.completions.invocationParams(optionsWithDefaults);\n }\n\n /** @ignore */\n override async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this._useResponsesApi(options)) {\n return this.responses._generate(messages, options, runManager);\n }\n return this.completions._generate(messages, options, runManager);\n }\n\n override async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n if (this._useResponsesApi(options)) {\n yield* this.responses._streamResponseChunks(\n messages,\n this._combineCallOptions(options),\n runManager\n );\n return;\n }\n yield* this.completions._streamResponseChunks(\n messages,\n this._combineCallOptions(options),\n runManager\n );\n }\n\n override withConfig(\n config: Partial<CallOptions>\n ): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions> {\n const newModel = new ChatOpenAI<CallOptions>(this.fields);\n newModel.defaultOptions = { ...this.defaultOptions, ...config };\n return newModel;\n }\n}\n"],"mappings":"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"}
@@ -83,6 +83,7 @@ var ChatOpenAIResponses = class extends require_base.BaseChatOpenAI {
83
83
  return params;
84
84
  }
85
85
  async _generate(messages, options, runManager) {
86
+ options.signal?.throwIfAborted();
86
87
  const invocationParams = this.invocationParams(options);
87
88
  if (invocationParams.stream) {
88
89
  const stream = this._streamResponseChunks(messages, options, runManager);
@@ -138,6 +139,7 @@ var ChatOpenAIResponses = class extends require_base.BaseChatOpenAI {
138
139
  stream: true
139
140
  }, options);
140
141
  for await (const data of streamIterable) {
142
+ if (options.signal?.aborted) return;
141
143
  const chunk = require_responses.convertResponsesDeltaToChatGenerationChunk(data);
142
144
  if (chunk == null) continue;
143
145
  yield chunk;
@@ -1 +1 @@
1
- {"version":3,"file":"responses.cjs","names":["BaseChatOpenAI","options?: this[\"ParsedCallOptions\"]","strict: boolean | undefined","params: ChatResponsesInvocationParams","isBuiltInToolChoice","formatToOpenAIToolChoice","messages: BaseMessage[]","options: this[\"ParsedCallOptions\"]","runManager?: CallbackManagerForLLMRun","finalChunk: ChatGenerationChunk | undefined","convertMessagesToResponsesInput","convertResponsesMessageToAIMessage","convertResponsesDeltaToChatGenerationChunk","request: OpenAIClient.Responses.ResponseCreateParams","requestOptions?: OpenAIClient.RequestOptions","wrapOpenAIClientError","tools: ChatOpenAIToolType[]","fields: { stream?: boolean; strict?: boolean }","reducedTools: ResponsesTool[]","isBuiltInTool","isCustomTool","isOpenAICustomTool","convertCompletionsCustomTool"],"sources":["../../src/chat_models/responses.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessage, type BaseMessage } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { isOpenAITool as isOpenAIFunctionTool } from \"@langchain/core/language_models/base\";\nimport { wrapOpenAIClientError } from \"../utils/client.js\";\nimport {\n ChatOpenAIToolType,\n convertCompletionsCustomTool,\n formatToOpenAIToolChoice,\n isBuiltInTool,\n isBuiltInToolChoice,\n isCustomTool,\n isOpenAICustomTool,\n ResponsesTool,\n} from \"../utils/tools.js\";\nimport { BaseChatOpenAI, BaseChatOpenAICallOptions } from \"./base.js\";\nimport {\n convertMessagesToResponsesInput,\n convertResponsesDeltaToChatGenerationChunk,\n convertResponsesMessageToAIMessage,\n} from \"../converters/responses.js\";\nimport { OpenAIVerbosityParam } from \"../types.js\";\n\nexport interface ChatOpenAIResponsesCallOptions\n extends BaseChatOpenAICallOptions {\n /**\n * Configuration options for a text response from the model. Can be plain text or\n * structured JSON data.\n */\n text?: OpenAIClient.Responses.ResponseCreateParams[\"text\"];\n\n /**\n * The truncation strategy to use for the model response.\n */\n truncation?: OpenAIClient.Responses.ResponseCreateParams[\"truncation\"];\n\n /**\n * Specify additional output data to include in the model response.\n */\n include?: OpenAIClient.Responses.ResponseCreateParams[\"include\"];\n\n /**\n * The unique ID of the previous response to the model. Use this to create multi-turn\n * conversations.\n */\n previous_response_id?: OpenAIClient.Responses.ResponseCreateParams[\"previous_response_id\"];\n\n /**\n * The verbosity of the model's response.\n */\n verbosity?: OpenAIVerbosityParam;\n}\n\nexport type ChatResponsesInvocationParams = Omit<\n OpenAIClient.Responses.ResponseCreateParams,\n \"input\"\n>;\n\n/**\n * OpenAI Responses API implementation.\n *\n * Will be exported in a later version of @langchain/openai.\n *\n * @internal\n */\nexport class ChatOpenAIResponses<\n CallOptions extends\n ChatOpenAIResponsesCallOptions = ChatOpenAIResponsesCallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n override invocationParams(\n options?: this[\"ParsedCallOptions\"]\n ): ChatResponsesInvocationParams {\n let strict: boolean | undefined;\n if (options?.strict !== undefined) {\n strict = options.strict;\n }\n if (strict === undefined && this.supportsStrictToolCalling !== undefined) {\n strict = this.supportsStrictToolCalling;\n }\n\n const params: ChatResponsesInvocationParams = {\n model: this.model,\n temperature: this.temperature,\n top_p: this.topP,\n user: this.user,\n\n // if include_usage is set or streamUsage then stream must be set to true.\n stream: this.streaming,\n previous_response_id: options?.previous_response_id,\n truncation: options?.truncation,\n include: options?.include,\n tools: options?.tools?.length\n ? this._reduceChatOpenAITools(options.tools, {\n stream: this.streaming,\n strict,\n })\n : undefined,\n tool_choice: isBuiltInToolChoice(options?.tool_choice)\n ? options?.tool_choice\n : (() => {\n const formatted = formatToOpenAIToolChoice(options?.tool_choice);\n if (typeof formatted === \"object\" && \"type\" in formatted) {\n if (formatted.type === \"function\") {\n return { type: \"function\", name: formatted.function.name };\n } else if (formatted.type === \"allowed_tools\") {\n return {\n type: \"allowed_tools\",\n mode: formatted.allowed_tools.mode,\n tools: formatted.allowed_tools.tools,\n };\n } else if (formatted.type === \"custom\") {\n return {\n type: \"custom\",\n name: formatted.custom.name,\n };\n }\n }\n return undefined;\n })(),\n text: (() => {\n if (options?.text) return options.text;\n const format = this._getResponseFormat(options?.response_format);\n if (format?.type === \"json_schema\") {\n if (format.json_schema.schema != null) {\n return {\n format: {\n type: \"json_schema\",\n schema: format.json_schema.schema,\n description: format.json_schema.description,\n name: format.json_schema.name,\n strict: format.json_schema.strict,\n },\n verbosity: options?.verbosity,\n };\n }\n return undefined;\n }\n return { format, verbosity: options?.verbosity };\n })(),\n parallel_tool_calls: options?.parallel_tool_calls,\n max_output_tokens: this.maxTokens === -1 ? undefined : this.maxTokens,\n prompt_cache_key: options?.promptCacheKey ?? this.promptCacheKey,\n prompt_cache_retention:\n options?.promptCacheRetention ?? this.promptCacheRetention,\n ...(this.zdrEnabled ? { store: false } : {}),\n ...this.modelKwargs,\n };\n\n const reasoning = this._getReasoningParams(options);\n\n if (reasoning !== undefined) {\n params.reasoning = reasoning;\n }\n\n return params;\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const invocationParams = this.invocationParams(options);\n if (invocationParams.stream) {\n const stream = this._streamResponseChunks(messages, options, runManager);\n let finalChunk: ChatGenerationChunk | undefined;\n for await (const chunk of stream) {\n chunk.message.response_metadata = {\n ...chunk.generationInfo,\n ...chunk.message.response_metadata,\n };\n finalChunk = finalChunk?.concat(chunk) ?? chunk;\n }\n\n return {\n generations: finalChunk ? [finalChunk] : [],\n llmOutput: {\n estimatedTokenUsage: (finalChunk?.message as AIMessage | undefined)\n ?.usage_metadata,\n },\n };\n } else {\n const data = await this.completionWithRetry(\n {\n input: convertMessagesToResponsesInput({\n messages,\n zdrEnabled: this.zdrEnabled ?? false,\n model: this.model,\n }),\n ...invocationParams,\n stream: false,\n },\n { signal: options?.signal, ...options?.options }\n );\n\n return {\n generations: [\n {\n text: data.output_text,\n message: convertResponsesMessageToAIMessage(data),\n },\n ],\n llmOutput: {\n id: data.id,\n estimatedTokenUsage: data.usage\n ? {\n promptTokens: data.usage.input_tokens,\n completionTokens: data.usage.output_tokens,\n totalTokens: data.usage.total_tokens,\n }\n : undefined,\n },\n };\n }\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamIterable = await this.completionWithRetry(\n {\n ...this.invocationParams(options),\n input: convertMessagesToResponsesInput({\n messages,\n zdrEnabled: this.zdrEnabled ?? false,\n model: this.model,\n }),\n stream: true,\n },\n options\n );\n\n for await (const data of streamIterable) {\n const chunk = convertResponsesDeltaToChatGenerationChunk(data);\n if (chunk == null) continue;\n yield chunk;\n await runManager?.handleLLMNewToken(\n chunk.text || \"\",\n {\n prompt: options.promptIndex ?? 0,\n completion: 0,\n },\n undefined,\n undefined,\n undefined,\n { chunk }\n );\n }\n }\n\n /**\n * Calls the Responses 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.Responses.ResponseCreateParamsStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>>;\n\n async completionWithRetry(\n request: OpenAIClient.Responses.ResponseCreateParamsNonStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<OpenAIClient.Responses.Response>;\n\n async completionWithRetry(\n request: OpenAIClient.Responses.ResponseCreateParams,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<\n | AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>\n | OpenAIClient.Responses.Response\n > {\n return this.caller.call(async () => {\n const clientOptions = this._getClientOptions(requestOptions);\n try {\n // use parse if dealing with json_schema\n if (request.text?.format?.type === \"json_schema\" && !request.stream) {\n return await this.client.responses.parse(request, clientOptions);\n }\n return await this.client.responses.create(request, clientOptions);\n } catch (e) {\n const error = wrapOpenAIClientError(e);\n throw error;\n }\n });\n }\n\n /** @internal */\n protected _reduceChatOpenAITools(\n tools: ChatOpenAIToolType[],\n fields: { stream?: boolean; strict?: boolean }\n ): ResponsesTool[] {\n const reducedTools: ResponsesTool[] = [];\n for (const tool of tools) {\n if (isBuiltInTool(tool)) {\n if (tool.type === \"image_generation\" && fields?.stream) {\n // OpenAI sends a 400 error if partial_images is not set and we want to stream.\n // We also set it to 1 since we don't support partial images yet.\n tool.partial_images = 1;\n }\n reducedTools.push(tool);\n } else if (isCustomTool(tool)) {\n const customToolData = tool.metadata.customTool;\n reducedTools.push({\n type: \"custom\",\n name: customToolData.name,\n description: customToolData.description,\n format: customToolData.format,\n } as ResponsesTool);\n } else if (isOpenAIFunctionTool(tool)) {\n reducedTools.push({\n type: \"function\",\n name: tool.function.name,\n parameters: tool.function.parameters,\n description: tool.function.description,\n strict: fields?.strict ?? null,\n });\n } else if (isOpenAICustomTool(tool)) {\n reducedTools.push(convertCompletionsCustomTool(tool));\n }\n }\n return reducedTools;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"responses.cjs","names":["BaseChatOpenAI","options?: this[\"ParsedCallOptions\"]","strict: boolean | undefined","params: ChatResponsesInvocationParams","isBuiltInToolChoice","formatToOpenAIToolChoice","messages: BaseMessage[]","options: this[\"ParsedCallOptions\"]","runManager?: CallbackManagerForLLMRun","finalChunk: ChatGenerationChunk | undefined","convertMessagesToResponsesInput","convertResponsesMessageToAIMessage","convertResponsesDeltaToChatGenerationChunk","request: OpenAIClient.Responses.ResponseCreateParams","requestOptions?: OpenAIClient.RequestOptions","wrapOpenAIClientError","tools: ChatOpenAIToolType[]","fields: { stream?: boolean; strict?: boolean }","reducedTools: ResponsesTool[]","isBuiltInTool","isCustomTool","isOpenAICustomTool","convertCompletionsCustomTool"],"sources":["../../src/chat_models/responses.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessage, type BaseMessage } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { isOpenAITool as isOpenAIFunctionTool } from \"@langchain/core/language_models/base\";\nimport { wrapOpenAIClientError } from \"../utils/client.js\";\nimport {\n ChatOpenAIToolType,\n convertCompletionsCustomTool,\n formatToOpenAIToolChoice,\n isBuiltInTool,\n isBuiltInToolChoice,\n isCustomTool,\n isOpenAICustomTool,\n ResponsesTool,\n} from \"../utils/tools.js\";\nimport { BaseChatOpenAI, BaseChatOpenAICallOptions } from \"./base.js\";\nimport {\n convertMessagesToResponsesInput,\n convertResponsesDeltaToChatGenerationChunk,\n convertResponsesMessageToAIMessage,\n} from \"../converters/responses.js\";\nimport { OpenAIVerbosityParam } from \"../types.js\";\n\nexport interface ChatOpenAIResponsesCallOptions\n extends BaseChatOpenAICallOptions {\n /**\n * Configuration options for a text response from the model. Can be plain text or\n * structured JSON data.\n */\n text?: OpenAIClient.Responses.ResponseCreateParams[\"text\"];\n\n /**\n * The truncation strategy to use for the model response.\n */\n truncation?: OpenAIClient.Responses.ResponseCreateParams[\"truncation\"];\n\n /**\n * Specify additional output data to include in the model response.\n */\n include?: OpenAIClient.Responses.ResponseCreateParams[\"include\"];\n\n /**\n * The unique ID of the previous response to the model. Use this to create multi-turn\n * conversations.\n */\n previous_response_id?: OpenAIClient.Responses.ResponseCreateParams[\"previous_response_id\"];\n\n /**\n * The verbosity of the model's response.\n */\n verbosity?: OpenAIVerbosityParam;\n}\n\nexport type ChatResponsesInvocationParams = Omit<\n OpenAIClient.Responses.ResponseCreateParams,\n \"input\"\n>;\n\n/**\n * OpenAI Responses API implementation.\n *\n * Will be exported in a later version of @langchain/openai.\n *\n * @internal\n */\nexport class ChatOpenAIResponses<\n CallOptions extends\n ChatOpenAIResponsesCallOptions = ChatOpenAIResponsesCallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n override invocationParams(\n options?: this[\"ParsedCallOptions\"]\n ): ChatResponsesInvocationParams {\n let strict: boolean | undefined;\n if (options?.strict !== undefined) {\n strict = options.strict;\n }\n if (strict === undefined && this.supportsStrictToolCalling !== undefined) {\n strict = this.supportsStrictToolCalling;\n }\n\n const params: ChatResponsesInvocationParams = {\n model: this.model,\n temperature: this.temperature,\n top_p: this.topP,\n user: this.user,\n\n // if include_usage is set or streamUsage then stream must be set to true.\n stream: this.streaming,\n previous_response_id: options?.previous_response_id,\n truncation: options?.truncation,\n include: options?.include,\n tools: options?.tools?.length\n ? this._reduceChatOpenAITools(options.tools, {\n stream: this.streaming,\n strict,\n })\n : undefined,\n tool_choice: isBuiltInToolChoice(options?.tool_choice)\n ? options?.tool_choice\n : (() => {\n const formatted = formatToOpenAIToolChoice(options?.tool_choice);\n if (typeof formatted === \"object\" && \"type\" in formatted) {\n if (formatted.type === \"function\") {\n return { type: \"function\", name: formatted.function.name };\n } else if (formatted.type === \"allowed_tools\") {\n return {\n type: \"allowed_tools\",\n mode: formatted.allowed_tools.mode,\n tools: formatted.allowed_tools.tools,\n };\n } else if (formatted.type === \"custom\") {\n return {\n type: \"custom\",\n name: formatted.custom.name,\n };\n }\n }\n return undefined;\n })(),\n text: (() => {\n if (options?.text) return options.text;\n const format = this._getResponseFormat(options?.response_format);\n if (format?.type === \"json_schema\") {\n if (format.json_schema.schema != null) {\n return {\n format: {\n type: \"json_schema\",\n schema: format.json_schema.schema,\n description: format.json_schema.description,\n name: format.json_schema.name,\n strict: format.json_schema.strict,\n },\n verbosity: options?.verbosity,\n };\n }\n return undefined;\n }\n return { format, verbosity: options?.verbosity };\n })(),\n parallel_tool_calls: options?.parallel_tool_calls,\n max_output_tokens: this.maxTokens === -1 ? undefined : this.maxTokens,\n prompt_cache_key: options?.promptCacheKey ?? this.promptCacheKey,\n prompt_cache_retention:\n options?.promptCacheRetention ?? this.promptCacheRetention,\n ...(this.zdrEnabled ? { store: false } : {}),\n ...this.modelKwargs,\n };\n\n const reasoning = this._getReasoningParams(options);\n\n if (reasoning !== undefined) {\n params.reasoning = reasoning;\n }\n\n return params;\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n options.signal?.throwIfAborted();\n const invocationParams = this.invocationParams(options);\n if (invocationParams.stream) {\n const stream = this._streamResponseChunks(messages, options, runManager);\n let finalChunk: ChatGenerationChunk | undefined;\n for await (const chunk of stream) {\n chunk.message.response_metadata = {\n ...chunk.generationInfo,\n ...chunk.message.response_metadata,\n };\n finalChunk = finalChunk?.concat(chunk) ?? chunk;\n }\n\n return {\n generations: finalChunk ? [finalChunk] : [],\n llmOutput: {\n estimatedTokenUsage: (finalChunk?.message as AIMessage | undefined)\n ?.usage_metadata,\n },\n };\n } else {\n const data = await this.completionWithRetry(\n {\n input: convertMessagesToResponsesInput({\n messages,\n zdrEnabled: this.zdrEnabled ?? false,\n model: this.model,\n }),\n ...invocationParams,\n stream: false,\n },\n { signal: options?.signal, ...options?.options }\n );\n\n return {\n generations: [\n {\n text: data.output_text,\n message: convertResponsesMessageToAIMessage(data),\n },\n ],\n llmOutput: {\n id: data.id,\n estimatedTokenUsage: data.usage\n ? {\n promptTokens: data.usage.input_tokens,\n completionTokens: data.usage.output_tokens,\n totalTokens: data.usage.total_tokens,\n }\n : undefined,\n },\n };\n }\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamIterable = await this.completionWithRetry(\n {\n ...this.invocationParams(options),\n input: convertMessagesToResponsesInput({\n messages,\n zdrEnabled: this.zdrEnabled ?? false,\n model: this.model,\n }),\n stream: true,\n },\n options\n );\n\n for await (const data of streamIterable) {\n if (options.signal?.aborted) {\n return;\n }\n const chunk = convertResponsesDeltaToChatGenerationChunk(data);\n if (chunk == null) continue;\n yield chunk;\n await runManager?.handleLLMNewToken(\n chunk.text || \"\",\n {\n prompt: options.promptIndex ?? 0,\n completion: 0,\n },\n undefined,\n undefined,\n undefined,\n { chunk }\n );\n }\n }\n\n /**\n * Calls the Responses 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.Responses.ResponseCreateParamsStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>>;\n\n async completionWithRetry(\n request: OpenAIClient.Responses.ResponseCreateParamsNonStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<OpenAIClient.Responses.Response>;\n\n async completionWithRetry(\n request: OpenAIClient.Responses.ResponseCreateParams,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<\n | AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>\n | OpenAIClient.Responses.Response\n > {\n return this.caller.call(async () => {\n const clientOptions = this._getClientOptions(requestOptions);\n try {\n // use parse if dealing with json_schema\n if (request.text?.format?.type === \"json_schema\" && !request.stream) {\n return await this.client.responses.parse(request, clientOptions);\n }\n return await this.client.responses.create(request, clientOptions);\n } catch (e) {\n const error = wrapOpenAIClientError(e);\n throw error;\n }\n });\n }\n\n /** @internal */\n protected _reduceChatOpenAITools(\n tools: ChatOpenAIToolType[],\n fields: { stream?: boolean; strict?: boolean }\n ): ResponsesTool[] {\n const reducedTools: ResponsesTool[] = [];\n for (const tool of tools) {\n if (isBuiltInTool(tool)) {\n if (tool.type === \"image_generation\" && fields?.stream) {\n // OpenAI sends a 400 error if partial_images is not set and we want to stream.\n // We also set it to 1 since we don't support partial images yet.\n tool.partial_images = 1;\n }\n reducedTools.push(tool);\n } else if (isCustomTool(tool)) {\n const customToolData = tool.metadata.customTool;\n reducedTools.push({\n type: \"custom\",\n name: customToolData.name,\n description: customToolData.description,\n format: customToolData.format,\n } as ResponsesTool);\n } else if (isOpenAIFunctionTool(tool)) {\n reducedTools.push({\n type: \"function\",\n name: tool.function.name,\n parameters: tool.function.parameters,\n description: tool.function.description,\n strict: fields?.strict ?? null,\n });\n } else if (isOpenAICustomTool(tool)) {\n reducedTools.push(convertCompletionsCustomTool(tool));\n }\n }\n return reducedTools;\n }\n}\n"],"mappings":"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"}
@@ -82,6 +82,7 @@ var ChatOpenAIResponses = class extends BaseChatOpenAI {
82
82
  return params;
83
83
  }
84
84
  async _generate(messages, options, runManager) {
85
+ options.signal?.throwIfAborted();
85
86
  const invocationParams = this.invocationParams(options);
86
87
  if (invocationParams.stream) {
87
88
  const stream = this._streamResponseChunks(messages, options, runManager);
@@ -137,6 +138,7 @@ var ChatOpenAIResponses = class extends BaseChatOpenAI {
137
138
  stream: true
138
139
  }, options);
139
140
  for await (const data of streamIterable) {
141
+ if (options.signal?.aborted) return;
140
142
  const chunk = convertResponsesDeltaToChatGenerationChunk(data);
141
143
  if (chunk == null) continue;
142
144
  yield chunk;
@@ -1 +1 @@
1
- {"version":3,"file":"responses.js","names":["options?: this[\"ParsedCallOptions\"]","strict: boolean | undefined","params: ChatResponsesInvocationParams","messages: BaseMessage[]","options: this[\"ParsedCallOptions\"]","runManager?: CallbackManagerForLLMRun","finalChunk: ChatGenerationChunk | undefined","request: OpenAIClient.Responses.ResponseCreateParams","requestOptions?: OpenAIClient.RequestOptions","tools: ChatOpenAIToolType[]","fields: { stream?: boolean; strict?: boolean }","reducedTools: ResponsesTool[]","isOpenAIFunctionTool"],"sources":["../../src/chat_models/responses.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessage, type BaseMessage } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { isOpenAITool as isOpenAIFunctionTool } from \"@langchain/core/language_models/base\";\nimport { wrapOpenAIClientError } from \"../utils/client.js\";\nimport {\n ChatOpenAIToolType,\n convertCompletionsCustomTool,\n formatToOpenAIToolChoice,\n isBuiltInTool,\n isBuiltInToolChoice,\n isCustomTool,\n isOpenAICustomTool,\n ResponsesTool,\n} from \"../utils/tools.js\";\nimport { BaseChatOpenAI, BaseChatOpenAICallOptions } from \"./base.js\";\nimport {\n convertMessagesToResponsesInput,\n convertResponsesDeltaToChatGenerationChunk,\n convertResponsesMessageToAIMessage,\n} from \"../converters/responses.js\";\nimport { OpenAIVerbosityParam } from \"../types.js\";\n\nexport interface ChatOpenAIResponsesCallOptions\n extends BaseChatOpenAICallOptions {\n /**\n * Configuration options for a text response from the model. Can be plain text or\n * structured JSON data.\n */\n text?: OpenAIClient.Responses.ResponseCreateParams[\"text\"];\n\n /**\n * The truncation strategy to use for the model response.\n */\n truncation?: OpenAIClient.Responses.ResponseCreateParams[\"truncation\"];\n\n /**\n * Specify additional output data to include in the model response.\n */\n include?: OpenAIClient.Responses.ResponseCreateParams[\"include\"];\n\n /**\n * The unique ID of the previous response to the model. Use this to create multi-turn\n * conversations.\n */\n previous_response_id?: OpenAIClient.Responses.ResponseCreateParams[\"previous_response_id\"];\n\n /**\n * The verbosity of the model's response.\n */\n verbosity?: OpenAIVerbosityParam;\n}\n\nexport type ChatResponsesInvocationParams = Omit<\n OpenAIClient.Responses.ResponseCreateParams,\n \"input\"\n>;\n\n/**\n * OpenAI Responses API implementation.\n *\n * Will be exported in a later version of @langchain/openai.\n *\n * @internal\n */\nexport class ChatOpenAIResponses<\n CallOptions extends\n ChatOpenAIResponsesCallOptions = ChatOpenAIResponsesCallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n override invocationParams(\n options?: this[\"ParsedCallOptions\"]\n ): ChatResponsesInvocationParams {\n let strict: boolean | undefined;\n if (options?.strict !== undefined) {\n strict = options.strict;\n }\n if (strict === undefined && this.supportsStrictToolCalling !== undefined) {\n strict = this.supportsStrictToolCalling;\n }\n\n const params: ChatResponsesInvocationParams = {\n model: this.model,\n temperature: this.temperature,\n top_p: this.topP,\n user: this.user,\n\n // if include_usage is set or streamUsage then stream must be set to true.\n stream: this.streaming,\n previous_response_id: options?.previous_response_id,\n truncation: options?.truncation,\n include: options?.include,\n tools: options?.tools?.length\n ? this._reduceChatOpenAITools(options.tools, {\n stream: this.streaming,\n strict,\n })\n : undefined,\n tool_choice: isBuiltInToolChoice(options?.tool_choice)\n ? options?.tool_choice\n : (() => {\n const formatted = formatToOpenAIToolChoice(options?.tool_choice);\n if (typeof formatted === \"object\" && \"type\" in formatted) {\n if (formatted.type === \"function\") {\n return { type: \"function\", name: formatted.function.name };\n } else if (formatted.type === \"allowed_tools\") {\n return {\n type: \"allowed_tools\",\n mode: formatted.allowed_tools.mode,\n tools: formatted.allowed_tools.tools,\n };\n } else if (formatted.type === \"custom\") {\n return {\n type: \"custom\",\n name: formatted.custom.name,\n };\n }\n }\n return undefined;\n })(),\n text: (() => {\n if (options?.text) return options.text;\n const format = this._getResponseFormat(options?.response_format);\n if (format?.type === \"json_schema\") {\n if (format.json_schema.schema != null) {\n return {\n format: {\n type: \"json_schema\",\n schema: format.json_schema.schema,\n description: format.json_schema.description,\n name: format.json_schema.name,\n strict: format.json_schema.strict,\n },\n verbosity: options?.verbosity,\n };\n }\n return undefined;\n }\n return { format, verbosity: options?.verbosity };\n })(),\n parallel_tool_calls: options?.parallel_tool_calls,\n max_output_tokens: this.maxTokens === -1 ? undefined : this.maxTokens,\n prompt_cache_key: options?.promptCacheKey ?? this.promptCacheKey,\n prompt_cache_retention:\n options?.promptCacheRetention ?? this.promptCacheRetention,\n ...(this.zdrEnabled ? { store: false } : {}),\n ...this.modelKwargs,\n };\n\n const reasoning = this._getReasoningParams(options);\n\n if (reasoning !== undefined) {\n params.reasoning = reasoning;\n }\n\n return params;\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const invocationParams = this.invocationParams(options);\n if (invocationParams.stream) {\n const stream = this._streamResponseChunks(messages, options, runManager);\n let finalChunk: ChatGenerationChunk | undefined;\n for await (const chunk of stream) {\n chunk.message.response_metadata = {\n ...chunk.generationInfo,\n ...chunk.message.response_metadata,\n };\n finalChunk = finalChunk?.concat(chunk) ?? chunk;\n }\n\n return {\n generations: finalChunk ? [finalChunk] : [],\n llmOutput: {\n estimatedTokenUsage: (finalChunk?.message as AIMessage | undefined)\n ?.usage_metadata,\n },\n };\n } else {\n const data = await this.completionWithRetry(\n {\n input: convertMessagesToResponsesInput({\n messages,\n zdrEnabled: this.zdrEnabled ?? false,\n model: this.model,\n }),\n ...invocationParams,\n stream: false,\n },\n { signal: options?.signal, ...options?.options }\n );\n\n return {\n generations: [\n {\n text: data.output_text,\n message: convertResponsesMessageToAIMessage(data),\n },\n ],\n llmOutput: {\n id: data.id,\n estimatedTokenUsage: data.usage\n ? {\n promptTokens: data.usage.input_tokens,\n completionTokens: data.usage.output_tokens,\n totalTokens: data.usage.total_tokens,\n }\n : undefined,\n },\n };\n }\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamIterable = await this.completionWithRetry(\n {\n ...this.invocationParams(options),\n input: convertMessagesToResponsesInput({\n messages,\n zdrEnabled: this.zdrEnabled ?? false,\n model: this.model,\n }),\n stream: true,\n },\n options\n );\n\n for await (const data of streamIterable) {\n const chunk = convertResponsesDeltaToChatGenerationChunk(data);\n if (chunk == null) continue;\n yield chunk;\n await runManager?.handleLLMNewToken(\n chunk.text || \"\",\n {\n prompt: options.promptIndex ?? 0,\n completion: 0,\n },\n undefined,\n undefined,\n undefined,\n { chunk }\n );\n }\n }\n\n /**\n * Calls the Responses 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.Responses.ResponseCreateParamsStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>>;\n\n async completionWithRetry(\n request: OpenAIClient.Responses.ResponseCreateParamsNonStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<OpenAIClient.Responses.Response>;\n\n async completionWithRetry(\n request: OpenAIClient.Responses.ResponseCreateParams,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<\n | AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>\n | OpenAIClient.Responses.Response\n > {\n return this.caller.call(async () => {\n const clientOptions = this._getClientOptions(requestOptions);\n try {\n // use parse if dealing with json_schema\n if (request.text?.format?.type === \"json_schema\" && !request.stream) {\n return await this.client.responses.parse(request, clientOptions);\n }\n return await this.client.responses.create(request, clientOptions);\n } catch (e) {\n const error = wrapOpenAIClientError(e);\n throw error;\n }\n });\n }\n\n /** @internal */\n protected _reduceChatOpenAITools(\n tools: ChatOpenAIToolType[],\n fields: { stream?: boolean; strict?: boolean }\n ): ResponsesTool[] {\n const reducedTools: ResponsesTool[] = [];\n for (const tool of tools) {\n if (isBuiltInTool(tool)) {\n if (tool.type === \"image_generation\" && fields?.stream) {\n // OpenAI sends a 400 error if partial_images is not set and we want to stream.\n // We also set it to 1 since we don't support partial images yet.\n tool.partial_images = 1;\n }\n reducedTools.push(tool);\n } else if (isCustomTool(tool)) {\n const customToolData = tool.metadata.customTool;\n reducedTools.push({\n type: \"custom\",\n name: customToolData.name,\n description: customToolData.description,\n format: customToolData.format,\n } as ResponsesTool);\n } else if (isOpenAIFunctionTool(tool)) {\n reducedTools.push({\n type: \"function\",\n name: tool.function.name,\n parameters: tool.function.parameters,\n description: tool.function.description,\n strict: fields?.strict ?? null,\n });\n } else if (isOpenAICustomTool(tool)) {\n reducedTools.push(convertCompletionsCustomTool(tool));\n }\n }\n return reducedTools;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"responses.js","names":["options?: this[\"ParsedCallOptions\"]","strict: boolean | undefined","params: ChatResponsesInvocationParams","messages: BaseMessage[]","options: this[\"ParsedCallOptions\"]","runManager?: CallbackManagerForLLMRun","finalChunk: ChatGenerationChunk | undefined","request: OpenAIClient.Responses.ResponseCreateParams","requestOptions?: OpenAIClient.RequestOptions","tools: ChatOpenAIToolType[]","fields: { stream?: boolean; strict?: boolean }","reducedTools: ResponsesTool[]","isOpenAIFunctionTool"],"sources":["../../src/chat_models/responses.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessage, type BaseMessage } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { isOpenAITool as isOpenAIFunctionTool } from \"@langchain/core/language_models/base\";\nimport { wrapOpenAIClientError } from \"../utils/client.js\";\nimport {\n ChatOpenAIToolType,\n convertCompletionsCustomTool,\n formatToOpenAIToolChoice,\n isBuiltInTool,\n isBuiltInToolChoice,\n isCustomTool,\n isOpenAICustomTool,\n ResponsesTool,\n} from \"../utils/tools.js\";\nimport { BaseChatOpenAI, BaseChatOpenAICallOptions } from \"./base.js\";\nimport {\n convertMessagesToResponsesInput,\n convertResponsesDeltaToChatGenerationChunk,\n convertResponsesMessageToAIMessage,\n} from \"../converters/responses.js\";\nimport { OpenAIVerbosityParam } from \"../types.js\";\n\nexport interface ChatOpenAIResponsesCallOptions\n extends BaseChatOpenAICallOptions {\n /**\n * Configuration options for a text response from the model. Can be plain text or\n * structured JSON data.\n */\n text?: OpenAIClient.Responses.ResponseCreateParams[\"text\"];\n\n /**\n * The truncation strategy to use for the model response.\n */\n truncation?: OpenAIClient.Responses.ResponseCreateParams[\"truncation\"];\n\n /**\n * Specify additional output data to include in the model response.\n */\n include?: OpenAIClient.Responses.ResponseCreateParams[\"include\"];\n\n /**\n * The unique ID of the previous response to the model. Use this to create multi-turn\n * conversations.\n */\n previous_response_id?: OpenAIClient.Responses.ResponseCreateParams[\"previous_response_id\"];\n\n /**\n * The verbosity of the model's response.\n */\n verbosity?: OpenAIVerbosityParam;\n}\n\nexport type ChatResponsesInvocationParams = Omit<\n OpenAIClient.Responses.ResponseCreateParams,\n \"input\"\n>;\n\n/**\n * OpenAI Responses API implementation.\n *\n * Will be exported in a later version of @langchain/openai.\n *\n * @internal\n */\nexport class ChatOpenAIResponses<\n CallOptions extends\n ChatOpenAIResponsesCallOptions = ChatOpenAIResponsesCallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n override invocationParams(\n options?: this[\"ParsedCallOptions\"]\n ): ChatResponsesInvocationParams {\n let strict: boolean | undefined;\n if (options?.strict !== undefined) {\n strict = options.strict;\n }\n if (strict === undefined && this.supportsStrictToolCalling !== undefined) {\n strict = this.supportsStrictToolCalling;\n }\n\n const params: ChatResponsesInvocationParams = {\n model: this.model,\n temperature: this.temperature,\n top_p: this.topP,\n user: this.user,\n\n // if include_usage is set or streamUsage then stream must be set to true.\n stream: this.streaming,\n previous_response_id: options?.previous_response_id,\n truncation: options?.truncation,\n include: options?.include,\n tools: options?.tools?.length\n ? this._reduceChatOpenAITools(options.tools, {\n stream: this.streaming,\n strict,\n })\n : undefined,\n tool_choice: isBuiltInToolChoice(options?.tool_choice)\n ? options?.tool_choice\n : (() => {\n const formatted = formatToOpenAIToolChoice(options?.tool_choice);\n if (typeof formatted === \"object\" && \"type\" in formatted) {\n if (formatted.type === \"function\") {\n return { type: \"function\", name: formatted.function.name };\n } else if (formatted.type === \"allowed_tools\") {\n return {\n type: \"allowed_tools\",\n mode: formatted.allowed_tools.mode,\n tools: formatted.allowed_tools.tools,\n };\n } else if (formatted.type === \"custom\") {\n return {\n type: \"custom\",\n name: formatted.custom.name,\n };\n }\n }\n return undefined;\n })(),\n text: (() => {\n if (options?.text) return options.text;\n const format = this._getResponseFormat(options?.response_format);\n if (format?.type === \"json_schema\") {\n if (format.json_schema.schema != null) {\n return {\n format: {\n type: \"json_schema\",\n schema: format.json_schema.schema,\n description: format.json_schema.description,\n name: format.json_schema.name,\n strict: format.json_schema.strict,\n },\n verbosity: options?.verbosity,\n };\n }\n return undefined;\n }\n return { format, verbosity: options?.verbosity };\n })(),\n parallel_tool_calls: options?.parallel_tool_calls,\n max_output_tokens: this.maxTokens === -1 ? undefined : this.maxTokens,\n prompt_cache_key: options?.promptCacheKey ?? this.promptCacheKey,\n prompt_cache_retention:\n options?.promptCacheRetention ?? this.promptCacheRetention,\n ...(this.zdrEnabled ? { store: false } : {}),\n ...this.modelKwargs,\n };\n\n const reasoning = this._getReasoningParams(options);\n\n if (reasoning !== undefined) {\n params.reasoning = reasoning;\n }\n\n return params;\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n options.signal?.throwIfAborted();\n const invocationParams = this.invocationParams(options);\n if (invocationParams.stream) {\n const stream = this._streamResponseChunks(messages, options, runManager);\n let finalChunk: ChatGenerationChunk | undefined;\n for await (const chunk of stream) {\n chunk.message.response_metadata = {\n ...chunk.generationInfo,\n ...chunk.message.response_metadata,\n };\n finalChunk = finalChunk?.concat(chunk) ?? chunk;\n }\n\n return {\n generations: finalChunk ? [finalChunk] : [],\n llmOutput: {\n estimatedTokenUsage: (finalChunk?.message as AIMessage | undefined)\n ?.usage_metadata,\n },\n };\n } else {\n const data = await this.completionWithRetry(\n {\n input: convertMessagesToResponsesInput({\n messages,\n zdrEnabled: this.zdrEnabled ?? false,\n model: this.model,\n }),\n ...invocationParams,\n stream: false,\n },\n { signal: options?.signal, ...options?.options }\n );\n\n return {\n generations: [\n {\n text: data.output_text,\n message: convertResponsesMessageToAIMessage(data),\n },\n ],\n llmOutput: {\n id: data.id,\n estimatedTokenUsage: data.usage\n ? {\n promptTokens: data.usage.input_tokens,\n completionTokens: data.usage.output_tokens,\n totalTokens: data.usage.total_tokens,\n }\n : undefined,\n },\n };\n }\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamIterable = await this.completionWithRetry(\n {\n ...this.invocationParams(options),\n input: convertMessagesToResponsesInput({\n messages,\n zdrEnabled: this.zdrEnabled ?? false,\n model: this.model,\n }),\n stream: true,\n },\n options\n );\n\n for await (const data of streamIterable) {\n if (options.signal?.aborted) {\n return;\n }\n const chunk = convertResponsesDeltaToChatGenerationChunk(data);\n if (chunk == null) continue;\n yield chunk;\n await runManager?.handleLLMNewToken(\n chunk.text || \"\",\n {\n prompt: options.promptIndex ?? 0,\n completion: 0,\n },\n undefined,\n undefined,\n undefined,\n { chunk }\n );\n }\n }\n\n /**\n * Calls the Responses 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.Responses.ResponseCreateParamsStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>>;\n\n async completionWithRetry(\n request: OpenAIClient.Responses.ResponseCreateParamsNonStreaming,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<OpenAIClient.Responses.Response>;\n\n async completionWithRetry(\n request: OpenAIClient.Responses.ResponseCreateParams,\n requestOptions?: OpenAIClient.RequestOptions\n ): Promise<\n | AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>\n | OpenAIClient.Responses.Response\n > {\n return this.caller.call(async () => {\n const clientOptions = this._getClientOptions(requestOptions);\n try {\n // use parse if dealing with json_schema\n if (request.text?.format?.type === \"json_schema\" && !request.stream) {\n return await this.client.responses.parse(request, clientOptions);\n }\n return await this.client.responses.create(request, clientOptions);\n } catch (e) {\n const error = wrapOpenAIClientError(e);\n throw error;\n }\n });\n }\n\n /** @internal */\n protected _reduceChatOpenAITools(\n tools: ChatOpenAIToolType[],\n fields: { stream?: boolean; strict?: boolean }\n ): ResponsesTool[] {\n const reducedTools: ResponsesTool[] = [];\n for (const tool of tools) {\n if (isBuiltInTool(tool)) {\n if (tool.type === \"image_generation\" && fields?.stream) {\n // OpenAI sends a 400 error if partial_images is not set and we want to stream.\n // We also set it to 1 since we don't support partial images yet.\n tool.partial_images = 1;\n }\n reducedTools.push(tool);\n } else if (isCustomTool(tool)) {\n const customToolData = tool.metadata.customTool;\n reducedTools.push({\n type: \"custom\",\n name: customToolData.name,\n description: customToolData.description,\n format: customToolData.format,\n } as ResponsesTool);\n } else if (isOpenAIFunctionTool(tool)) {\n reducedTools.push({\n type: \"function\",\n name: tool.function.name,\n parameters: tool.function.parameters,\n description: tool.function.description,\n strict: fields?.strict ?? null,\n });\n } else if (isOpenAICustomTool(tool)) {\n reducedTools.push(convertCompletionsCustomTool(tool));\n }\n }\n return reducedTools;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAkEA,IAAa,sBAAb,cAGU,eAA4B;CACpC,AAAS,iBACPA,SAC+B;EAC/B,IAAIC;AACJ,MAAI,SAAS,WAAW,QACtB,SAAS,QAAQ;AAEnB,MAAI,WAAW,UAAa,KAAK,8BAA8B,QAC7D,SAAS,KAAK;EAGhB,MAAMC,SAAwC;GAC5C,OAAO,KAAK;GACZ,aAAa,KAAK;GAClB,OAAO,KAAK;GACZ,MAAM,KAAK;GAGX,QAAQ,KAAK;GACb,sBAAsB,SAAS;GAC/B,YAAY,SAAS;GACrB,SAAS,SAAS;GAClB,OAAO,SAAS,OAAO,SACnB,KAAK,uBAAuB,QAAQ,OAAO;IACzC,QAAQ,KAAK;IACb;GACD,EAAC,GACF;GACJ,aAAa,oBAAoB,SAAS,YAAY,GAClD,SAAS,eACR,MAAM;IACL,MAAM,YAAY,yBAAyB,SAAS,YAAY;AAChE,QAAI,OAAO,cAAc,YAAY,UAAU,WAC7C;SAAI,UAAU,SAAS,WACrB,QAAO;MAAE,MAAM;MAAY,MAAM,UAAU,SAAS;KAAM;cACjD,UAAU,SAAS,gBAC5B,QAAO;MACL,MAAM;MACN,MAAM,UAAU,cAAc;MAC9B,OAAO,UAAU,cAAc;KAChC;cACQ,UAAU,SAAS,SAC5B,QAAO;MACL,MAAM;MACN,MAAM,UAAU,OAAO;KACxB;IACF;AAEH,WAAO;GACR,IAAG;GACR,OAAO,MAAM;AACX,QAAI,SAAS,KAAM,QAAO,QAAQ;IAClC,MAAM,SAAS,KAAK,mBAAmB,SAAS,gBAAgB;AAChE,QAAI,QAAQ,SAAS,eAAe;AAClC,SAAI,OAAO,YAAY,UAAU,KAC/B,QAAO;MACL,QAAQ;OACN,MAAM;OACN,QAAQ,OAAO,YAAY;OAC3B,aAAa,OAAO,YAAY;OAChC,MAAM,OAAO,YAAY;OACzB,QAAQ,OAAO,YAAY;MAC5B;MACD,WAAW,SAAS;KACrB;AAEH,YAAO;IACR;AACD,WAAO;KAAE;KAAQ,WAAW,SAAS;IAAW;GACjD,IAAG;GACJ,qBAAqB,SAAS;GAC9B,mBAAmB,KAAK,cAAc,KAAK,SAAY,KAAK;GAC5D,kBAAkB,SAAS,kBAAkB,KAAK;GAClD,wBACE,SAAS,wBAAwB,KAAK;GACxC,GAAI,KAAK,aAAa,EAAE,OAAO,MAAO,IAAG,CAAE;GAC3C,GAAG,KAAK;EACT;EAED,MAAM,YAAY,KAAK,oBAAoB,QAAQ;AAEnD,MAAI,cAAc,QAChB,OAAO,YAAY;AAGrB,SAAO;CACR;CAED,MAAM,UACJC,UACAC,SACAC,YACqB;EACrB,QAAQ,QAAQ,gBAAgB;EAChC,MAAM,mBAAmB,KAAK,iBAAiB,QAAQ;AACvD,MAAI,iBAAiB,QAAQ;GAC3B,MAAM,SAAS,KAAK,sBAAsB,UAAU,SAAS,WAAW;GACxE,IAAIC;AACJ,cAAW,MAAM,SAAS,QAAQ;IAChC,MAAM,QAAQ,oBAAoB;KAChC,GAAG,MAAM;KACT,GAAG,MAAM,QAAQ;IAClB;IACD,aAAa,YAAY,OAAO,MAAM,IAAI;GAC3C;AAED,UAAO;IACL,aAAa,aAAa,CAAC,UAAW,IAAG,CAAE;IAC3C,WAAW,EACT,sBAAsB,YAAY,UAC9B,eACL;GACF;EACF,OAAM;GACL,MAAM,OAAO,MAAM,KAAK,oBACtB;IACE,OAAO,gCAAgC;KACrC;KACA,YAAY,KAAK,cAAc;KAC/B,OAAO,KAAK;IACb,EAAC;IACF,GAAG;IACH,QAAQ;GACT,GACD;IAAE,QAAQ,SAAS;IAAQ,GAAG,SAAS;GAAS,EACjD;AAED,UAAO;IACL,aAAa,CACX;KACE,MAAM,KAAK;KACX,SAAS,mCAAmC,KAAK;IAClD,CACF;IACD,WAAW;KACT,IAAI,KAAK;KACT,qBAAqB,KAAK,QACtB;MACE,cAAc,KAAK,MAAM;MACzB,kBAAkB,KAAK,MAAM;MAC7B,aAAa,KAAK,MAAM;KACzB,IACD;IACL;GACF;EACF;CACF;CAED,OAAO,sBACLH,UACAC,SACAC,YACqC;EACrC,MAAM,iBAAiB,MAAM,KAAK,oBAChC;GACE,GAAG,KAAK,iBAAiB,QAAQ;GACjC,OAAO,gCAAgC;IACrC;IACA,YAAY,KAAK,cAAc;IAC/B,OAAO,KAAK;GACb,EAAC;GACF,QAAQ;EACT,GACD,QACD;AAED,aAAW,MAAM,QAAQ,gBAAgB;AACvC,OAAI,QAAQ,QAAQ,QAClB;GAEF,MAAM,QAAQ,2CAA2C,KAAK;AAC9D,OAAI,SAAS,KAAM;GACnB,MAAM;GACN,MAAM,YAAY,kBAChB,MAAM,QAAQ,IACd;IACE,QAAQ,QAAQ,eAAe;IAC/B,YAAY;GACb,GACD,QACA,QACA,QACA,EAAE,MAAO,EACV;EACF;CACF;CAkBD,MAAM,oBACJE,SACAC,gBAIA;AACA,SAAO,KAAK,OAAO,KAAK,YAAY;GAClC,MAAM,gBAAgB,KAAK,kBAAkB,eAAe;AAC5D,OAAI;AAEF,QAAI,QAAQ,MAAM,QAAQ,SAAS,iBAAiB,CAAC,QAAQ,OAC3D,QAAO,MAAM,KAAK,OAAO,UAAU,MAAM,SAAS,cAAc;AAElE,WAAO,MAAM,KAAK,OAAO,UAAU,OAAO,SAAS,cAAc;GAClE,SAAQ,GAAG;IACV,MAAM,QAAQ,sBAAsB,EAAE;AACtC,UAAM;GACP;EACF,EAAC;CACH;;CAGD,AAAU,uBACRC,OACAC,QACiB;EACjB,MAAMC,eAAgC,CAAE;AACxC,OAAK,MAAM,QAAQ,MACjB,KAAI,cAAc,KAAK,EAAE;AACvB,OAAI,KAAK,SAAS,sBAAsB,QAAQ,QAG9C,KAAK,iBAAiB;GAExB,aAAa,KAAK,KAAK;EACxB,WAAU,aAAa,KAAK,EAAE;GAC7B,MAAM,iBAAiB,KAAK,SAAS;GACrC,aAAa,KAAK;IAChB,MAAM;IACN,MAAM,eAAe;IACrB,aAAa,eAAe;IAC5B,QAAQ,eAAe;GACxB,EAAkB;EACpB,WAAUC,aAAqB,KAAK,EACnC,aAAa,KAAK;GAChB,MAAM;GACN,MAAM,KAAK,SAAS;GACpB,YAAY,KAAK,SAAS;GAC1B,aAAa,KAAK,SAAS;GAC3B,QAAQ,QAAQ,UAAU;EAC3B,EAAC;WACO,mBAAmB,KAAK,EACjC,aAAa,KAAK,6BAA6B,KAAK,CAAC;AAGzD,SAAO;CACR;AACF"}
@@ -9,6 +9,53 @@ const __langchain_core_output_parsers_openai_tools = require_rolldown_runtime.__
9
9
  //#region src/converters/responses.ts
10
10
  const _FUNCTION_CALL_IDS_MAP_KEY = "__openai_function_call_ids__";
11
11
  /**
12
+ * Converts an OpenAI annotation to a LangChain Citation or BaseContentBlock.
13
+ *
14
+ * OpenAI has several annotation types:
15
+ * - `url_citation`: Web citations with url, title, start_index, end_index
16
+ * - `file_citation`: File citations with file_id, filename, index
17
+ * - `container_file_citation`: Container file citations with container_id, file_id, filename, start_index, end_index
18
+ * - `file_path`: File paths with file_id, index
19
+ *
20
+ * This function maps them to LangChain's Citation format or preserves them as non-standard blocks.
21
+ */
22
+ function convertOpenAIAnnotationToLangChain(annotation) {
23
+ if (annotation.type === "url_citation") return {
24
+ type: "citation",
25
+ source: "url_citation",
26
+ url: annotation.url,
27
+ title: annotation.title,
28
+ startIndex: annotation.start_index,
29
+ endIndex: annotation.end_index
30
+ };
31
+ if (annotation.type === "file_citation") return {
32
+ type: "citation",
33
+ source: "file_citation",
34
+ title: annotation.filename,
35
+ startIndex: annotation.index,
36
+ file_id: annotation.file_id
37
+ };
38
+ if (annotation.type === "container_file_citation") return {
39
+ type: "citation",
40
+ source: "container_file_citation",
41
+ title: annotation.filename,
42
+ startIndex: annotation.start_index,
43
+ endIndex: annotation.end_index,
44
+ file_id: annotation.file_id,
45
+ container_id: annotation.container_id
46
+ };
47
+ if (annotation.type === "file_path") return {
48
+ type: "citation",
49
+ source: "file_path",
50
+ startIndex: annotation.index,
51
+ file_id: annotation.file_id
52
+ };
53
+ return {
54
+ type: "non_standard",
55
+ value: annotation
56
+ };
57
+ }
58
+ /**
12
59
  * Converts OpenAI Responses API usage statistics to LangChain's UsageMetadata format.
13
60
  *
14
61
  * This converter transforms token usage information from OpenAI's Responses API into
@@ -150,7 +197,7 @@ const convertResponsesMessageToAIMessage = (response) => {
150
197
  return {
151
198
  type: "text",
152
199
  text: part.text,
153
- annotations: part.annotations
200
+ annotations: part.annotations.map(convertOpenAIAnnotationToLangChain)
154
201
  };
155
202
  }
156
203
  if (part.type === "refusal") {
@@ -191,6 +238,16 @@ const convertResponsesMessageToAIMessage = (response) => {
191
238
  const parsed = require_tools.parseComputerCall(item);
192
239
  if (parsed) tool_calls.push(parsed);
193
240
  else invalid_tool_calls.push((0, __langchain_core_output_parsers_openai_tools.makeInvalidToolCall)(item, "Malformed computer call"));
241
+ } else if (item.type === "image_generation_call") {
242
+ if (item.result) content.push({
243
+ type: "image",
244
+ mimeType: "image/png",
245
+ data: item.result,
246
+ id: item.id,
247
+ metadata: { status: item.status }
248
+ });
249
+ additional_kwargs.tool_outputs ??= [];
250
+ additional_kwargs.tool_outputs.push(item);
194
251
  } else {
195
252
  additional_kwargs.tool_outputs ??= [];
196
253
  additional_kwargs.tool_outputs.push(item);
@@ -347,7 +404,7 @@ const convertResponsesDeltaToChatGenerationChunk = (event) => {
347
404
  else if (event.type === "response.output_text.annotation.added") content.push({
348
405
  type: "text",
349
406
  text: "",
350
- annotations: [event.annotation],
407
+ annotations: [convertOpenAIAnnotationToLangChain(event.annotation)],
351
408
  index: event.content_index
352
409
  });
353
410
  else if (event.type === "response.output_item.added" && event.item.type === "message") id = event.item.id;
@@ -369,6 +426,15 @@ const convertResponsesDeltaToChatGenerationChunk = (event) => {
369
426
  index: event.output_index
370
427
  });
371
428
  additional_kwargs.tool_outputs = [event.item];
429
+ } else if (event.type === "response.output_item.done" && event.item.type === "image_generation_call") {
430
+ if (event.item.result) content.push({
431
+ type: "image",
432
+ mimeType: "image/png",
433
+ data: event.item.result,
434
+ id: event.item.id,
435
+ metadata: { status: event.item.status }
436
+ });
437
+ additional_kwargs.tool_outputs = [event.item];
372
438
  } else if (event.type === "response.output_item.done" && [
373
439
  "web_search_call",
374
440
  "file_search_call",
@@ -376,7 +442,6 @@ const convertResponsesDeltaToChatGenerationChunk = (event) => {
376
442
  "mcp_call",
377
443
  "mcp_list_tools",
378
444
  "mcp_approval_request",
379
- "image_generation_call",
380
445
  "custom_tool_call"
381
446
  ].includes(event.item.type)) additional_kwargs.tool_outputs = [event.item];
382
447
  else if (event.type === "response.created") {
@@ -564,18 +629,24 @@ const convertStandardContentMessageToResponsesInput = (message) => {
564
629
  return void 0;
565
630
  };
566
631
  const resolveFileItem = (block) => {
567
- const filename = require_misc.getRequiredFilenameFromMetadata(block);
568
- if (block.fileId && typeof filename === "string") return {
569
- type: "input_file",
570
- file_id: block.fileId,
571
- ...filename ? { filename } : {}
572
- };
573
- if (block.url && typeof filename === "string") return {
574
- type: "input_file",
575
- file_url: block.url,
576
- ...filename ? { filename } : {}
577
- };
578
- if (block.data && typeof filename === "string") {
632
+ if (block.fileId) {
633
+ const filename = require_misc.getFilenameFromMetadata(block);
634
+ return {
635
+ type: "input_file",
636
+ file_id: block.fileId,
637
+ ...filename ? { filename } : {}
638
+ };
639
+ }
640
+ if (block.url) {
641
+ const filename = require_misc.getFilenameFromMetadata(block);
642
+ return {
643
+ ...filename ? { filename } : {},
644
+ type: "input_file",
645
+ file_url: block.url
646
+ };
647
+ }
648
+ if (block.data) {
649
+ const filename = require_misc.getRequiredFilenameFromMetadata(block);
579
650
  const encoded = typeof block.data === "string" ? block.data : Buffer.from(block.data).toString("base64");
580
651
  const mimeType = block.mimeType ?? "application/octet-stream";
581
652
  return {