@langchain/openai 0.5.13 → 0.5.14

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.
@@ -5,6 +5,7 @@ const openai_1 = require("openai");
5
5
  const env_1 = require("@langchain/core/utils/env");
6
6
  const chat_models_js_1 = require("../chat_models.cjs");
7
7
  const azure_js_1 = require("../utils/azure.cjs");
8
+ const headers_js_1 = require("../utils/headers.cjs");
8
9
  /**
9
10
  * Azure OpenAI chat model integration.
10
11
  *
@@ -558,10 +559,12 @@ class AzureChatOpenAI extends chat_models_js_1.ChatOpenAI {
558
559
  if (env === "node" || env === "deno") {
559
560
  env = `(${env}/${process.version}; ${process.platform}; ${process.arch})`;
560
561
  }
561
- const specifiedUserAgent = params.defaultHeaders?.["User-Agent"];
562
+ const defaultHeaders = (0, headers_js_1.normalizeHeaders)(params.defaultHeaders);
562
563
  params.defaultHeaders = {
563
564
  ...params.defaultHeaders,
564
- "User-Agent": `langchainjs-azure-openai/2.0.0 (${env})${specifiedUserAgent ? ` ${specifiedUserAgent}` : ""}`,
565
+ "User-Agent": defaultHeaders["User-Agent"]
566
+ ? `langchainjs-azure-openai/2.0.0 (${env})${defaultHeaders["User-Agent"]}`
567
+ : `langchainjs-azure-openai/2.0.0 (${env})`,
565
568
  };
566
569
  this.client = new openai_1.AzureOpenAI({
567
570
  apiVersion: this.azureOpenAIApiVersion,
@@ -2,6 +2,7 @@ import { AzureOpenAI as AzureOpenAIClient } from "openai";
2
2
  import { getEnv, getEnvironmentVariable } from "@langchain/core/utils/env";
3
3
  import { ChatOpenAI, } from "../chat_models.js";
4
4
  import { getEndpoint } from "../utils/azure.js";
5
+ import { normalizeHeaders } from "../utils/headers.js";
5
6
  /**
6
7
  * Azure OpenAI chat model integration.
7
8
  *
@@ -555,10 +556,12 @@ export class AzureChatOpenAI extends ChatOpenAI {
555
556
  if (env === "node" || env === "deno") {
556
557
  env = `(${env}/${process.version}; ${process.platform}; ${process.arch})`;
557
558
  }
558
- const specifiedUserAgent = params.defaultHeaders?.["User-Agent"];
559
+ const defaultHeaders = normalizeHeaders(params.defaultHeaders);
559
560
  params.defaultHeaders = {
560
561
  ...params.defaultHeaders,
561
- "User-Agent": `langchainjs-azure-openai/2.0.0 (${env})${specifiedUserAgent ? ` ${specifiedUserAgent}` : ""}`,
562
+ "User-Agent": defaultHeaders["User-Agent"]
563
+ ? `langchainjs-azure-openai/2.0.0 (${env})${defaultHeaders["User-Agent"]}`
564
+ : `langchainjs-azure-openai/2.0.0 (${env})`,
562
565
  };
563
566
  this.client = new AzureOpenAIClient({
564
567
  apiVersion: this.azureOpenAIApiVersion,
@@ -6,6 +6,7 @@ const env_1 = require("@langchain/core/utils/env");
6
6
  const embeddings_js_1 = require("../embeddings.cjs");
7
7
  const azure_js_1 = require("../utils/azure.cjs");
8
8
  const openai_js_1 = require("../utils/openai.cjs");
9
+ const headers_js_1 = require("../utils/headers.cjs");
9
10
  class AzureOpenAIEmbeddings extends embeddings_js_1.OpenAIEmbeddings {
10
11
  constructor(fields) {
11
12
  super(fields);
@@ -90,10 +91,11 @@ class AzureOpenAIEmbeddings extends embeddings_js_1.OpenAIEmbeddings {
90
91
  if (!params.baseURL) {
91
92
  delete params.baseURL;
92
93
  }
94
+ const defaultHeaders = (0, headers_js_1.normalizeHeaders)(params.defaultHeaders);
93
95
  params.defaultHeaders = {
94
96
  ...params.defaultHeaders,
95
- "User-Agent": params.defaultHeaders?.["User-Agent"]
96
- ? `${params.defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
97
+ "User-Agent": defaultHeaders["User-Agent"]
98
+ ? `${defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
97
99
  : `langchainjs-azure-openai-v2`,
98
100
  };
99
101
  this.client = new openai_1.AzureOpenAI({
@@ -116,12 +118,7 @@ class AzureOpenAIEmbeddings extends embeddings_js_1.OpenAIEmbeddings {
116
118
  }
117
119
  return this.caller.call(async () => {
118
120
  try {
119
- const res = await this.client.embeddings.create(request,
120
- // This unknown cast is required because OpenAI types seem to be incorrect here
121
- // without it, we can't pass arbitrary keys via the `query` field in the options,
122
- // which means we can't specify the `api-version` as required by Azure OpenAI.
123
- // See https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#rest-api-versioning
124
- requestOptions);
121
+ const res = await this.client.embeddings.create(request, requestOptions);
125
122
  return res;
126
123
  }
127
124
  catch (e) {
@@ -17,6 +17,6 @@ export declare class AzureOpenAIEmbeddings extends OpenAIEmbeddings {
17
17
  openAIApiVersion?: string;
18
18
  });
19
19
  protected embeddingWithRetry(request: OpenAIClient.EmbeddingCreateParams): Promise<OpenAIClient.Embeddings.CreateEmbeddingResponse & {
20
- _request_id?: string | null | undefined;
20
+ _request_id?: string | null;
21
21
  }>;
22
22
  }
@@ -3,6 +3,7 @@ import { getEnvironmentVariable } from "@langchain/core/utils/env";
3
3
  import { OpenAIEmbeddings } from "../embeddings.js";
4
4
  import { getEndpoint } from "../utils/azure.js";
5
5
  import { wrapOpenAIClientError } from "../utils/openai.js";
6
+ import { normalizeHeaders } from "../utils/headers.js";
6
7
  export class AzureOpenAIEmbeddings extends OpenAIEmbeddings {
7
8
  constructor(fields) {
8
9
  super(fields);
@@ -87,10 +88,11 @@ export class AzureOpenAIEmbeddings extends OpenAIEmbeddings {
87
88
  if (!params.baseURL) {
88
89
  delete params.baseURL;
89
90
  }
91
+ const defaultHeaders = normalizeHeaders(params.defaultHeaders);
90
92
  params.defaultHeaders = {
91
93
  ...params.defaultHeaders,
92
- "User-Agent": params.defaultHeaders?.["User-Agent"]
93
- ? `${params.defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
94
+ "User-Agent": defaultHeaders["User-Agent"]
95
+ ? `${defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
94
96
  : `langchainjs-azure-openai-v2`,
95
97
  };
96
98
  this.client = new AzureOpenAIClient({
@@ -113,12 +115,7 @@ export class AzureOpenAIEmbeddings extends OpenAIEmbeddings {
113
115
  }
114
116
  return this.caller.call(async () => {
115
117
  try {
116
- const res = await this.client.embeddings.create(request,
117
- // This unknown cast is required because OpenAI types seem to be incorrect here
118
- // without it, we can't pass arbitrary keys via the `query` field in the options,
119
- // which means we can't specify the `api-version` as required by Azure OpenAI.
120
- // See https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#rest-api-versioning
121
- requestOptions);
118
+ const res = await this.client.embeddings.create(request, requestOptions);
122
119
  return res;
123
120
  }
124
121
  catch (e) {
@@ -5,6 +5,7 @@ const openai_1 = require("openai");
5
5
  const env_1 = require("@langchain/core/utils/env");
6
6
  const llms_js_1 = require("../llms.cjs");
7
7
  const azure_js_1 = require("../utils/azure.cjs");
8
+ const headers_js_1 = require("../utils/headers.cjs");
8
9
  class AzureOpenAI extends llms_js_1.OpenAI {
9
10
  get lc_aliases() {
10
11
  return {
@@ -120,10 +121,11 @@ class AzureOpenAI extends llms_js_1.OpenAI {
120
121
  if (!params.baseURL) {
121
122
  delete params.baseURL;
122
123
  }
124
+ const defaultHeaders = (0, headers_js_1.normalizeHeaders)(params.defaultHeaders);
123
125
  params.defaultHeaders = {
124
126
  ...params.defaultHeaders,
125
- "User-Agent": params.defaultHeaders?.["User-Agent"]
126
- ? `${params.defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
127
+ "User-Agent": defaultHeaders["User-Agent"]
128
+ ? `${defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
127
129
  : `langchainjs-azure-openai-v2`,
128
130
  };
129
131
  this.client = new openai_1.AzureOpenAI({
@@ -2,6 +2,7 @@ import { AzureOpenAI as AzureOpenAIClient } from "openai";
2
2
  import { getEnvironmentVariable } from "@langchain/core/utils/env";
3
3
  import { OpenAI } from "../llms.js";
4
4
  import { getEndpoint } from "../utils/azure.js";
5
+ import { normalizeHeaders } from "../utils/headers.js";
5
6
  export class AzureOpenAI extends OpenAI {
6
7
  get lc_aliases() {
7
8
  return {
@@ -117,10 +118,11 @@ export class AzureOpenAI extends OpenAI {
117
118
  if (!params.baseURL) {
118
119
  delete params.baseURL;
119
120
  }
121
+ const defaultHeaders = normalizeHeaders(params.defaultHeaders);
120
122
  params.defaultHeaders = {
121
123
  ...params.defaultHeaders,
122
- "User-Agent": params.defaultHeaders?.["User-Agent"]
123
- ? `${params.defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
124
+ "User-Agent": defaultHeaders["User-Agent"]
125
+ ? `${defaultHeaders["User-Agent"]}: langchainjs-azure-openai-v2`
124
126
  : `langchainjs-azure-openai-v2`,
125
127
  };
126
128
  this.client = new AzureOpenAIClient({
@@ -15,15 +15,27 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.ChatOpenAI = exports._convertMessagesToOpenAIParams = exports.messageToOpenAIRole = void 0;
36
+ exports.ChatOpenAI = void 0;
37
+ exports.messageToOpenAIRole = messageToOpenAIRole;
38
+ exports._convertMessagesToOpenAIParams = _convertMessagesToOpenAIParams;
27
39
  const z4 = __importStar(require("zod/v4/core"));
28
40
  const openai_1 = require("openai");
29
41
  const messages_1 = require("@langchain/core/messages");
@@ -74,7 +86,6 @@ function messageToOpenAIRole(message) {
74
86
  throw new Error(`Unknown message type: ${type}`);
75
87
  }
76
88
  }
77
- exports.messageToOpenAIRole = messageToOpenAIRole;
78
89
  const completionsApiContentBlockConverter = {
79
90
  providerName: "ChatOpenAI",
80
91
  fromStandardTextBlock(block) {
@@ -163,7 +174,7 @@ const completionsApiContentBlockConverter = {
163
174
  return {
164
175
  type: "file",
165
176
  file: {
166
- file_data: block.url,
177
+ file_data: block.url, // formatted as base64 data URL
167
178
  ...(block.metadata?.filename || block.metadata?.name
168
179
  ? {
169
180
  filename: (block.metadata?.filename ||
@@ -255,7 +266,6 @@ function _convertMessagesToOpenAIParams(messages, model) {
255
266
  return completionParam;
256
267
  });
257
268
  }
258
- exports._convertMessagesToOpenAIParams = _convertMessagesToOpenAIParams;
259
269
  const _FUNCTION_CALL_IDS_MAP_KEY = "__openai_function_call_ids__";
260
270
  function _convertReasoningSummaryToOpenAIResponsesParams(reasoning) {
261
271
  // combine summary parts that have the the same index and then remove the indexes
@@ -277,12 +287,8 @@ function _convertReasoningSummaryToOpenAIResponsesParams(reasoning) {
277
287
  };
278
288
  }
279
289
  function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
280
- const lastAIMessage = messages.filter((m) => (0, messages_1.isAIMessage)(m)).pop();
281
- const lastAIMessageId = lastAIMessage?.response_metadata?.id;
282
- const newMessages = lastAIMessageId && lastAIMessageId.startsWith("resp_") && !zdrEnabled
283
- ? messages.slice(messages.indexOf(lastAIMessage) + 1)
284
- : messages;
285
- return newMessages.flatMap((lcMsg) => {
290
+ return messages.flatMap((lcMsg) => {
291
+ const additional_kwargs = lcMsg.additional_kwargs;
286
292
  let role = messageToOpenAIRole(lcMsg);
287
293
  if (role === "system" && isReasoningModel(model))
288
294
  role = "developer";
@@ -292,7 +298,7 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
292
298
  if (role === "tool") {
293
299
  const toolMessage = lcMsg;
294
300
  // Handle computer call output
295
- if (toolMessage.additional_kwargs?.type === "computer_call_output") {
301
+ if (additional_kwargs?.type === "computer_call_output") {
296
302
  const output = (() => {
297
303
  if (typeof toolMessage.content === "string") {
298
304
  return {
@@ -343,25 +349,19 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
343
349
  // otherwise, try to reconstruct the response from what we have
344
350
  const input = [];
345
351
  // reasoning items
346
- if (!zdrEnabled && lcMsg.additional_kwargs.reasoning != null) {
347
- const isReasoningItem = (item) => typeof item === "object" &&
348
- item != null &&
349
- "type" in item &&
350
- item.type === "reasoning";
351
- if (isReasoningItem(lcMsg.additional_kwargs.reasoning)) {
352
- const reasoningItem = _convertReasoningSummaryToOpenAIResponsesParams(lcMsg.additional_kwargs.reasoning);
353
- input.push(reasoningItem);
354
- }
352
+ if (additional_kwargs?.reasoning && !zdrEnabled) {
353
+ const reasoningItem = _convertReasoningSummaryToOpenAIResponsesParams(additional_kwargs.reasoning);
354
+ input.push(reasoningItem);
355
355
  }
356
356
  // ai content
357
357
  let { content } = lcMsg;
358
- if (lcMsg.additional_kwargs.refusal != null) {
358
+ if (additional_kwargs?.refusal) {
359
359
  if (typeof content === "string") {
360
360
  content = [{ type: "output_text", text: content, annotations: [] }];
361
361
  }
362
362
  content = [
363
363
  ...content,
364
- { type: "refusal", refusal: lcMsg.additional_kwargs.refusal },
364
+ { type: "refusal", refusal: additional_kwargs.refusal },
365
365
  ];
366
366
  }
367
367
  input.push({
@@ -385,10 +385,7 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
385
385
  return [];
386
386
  }),
387
387
  });
388
- // function tool calls and computer use tool calls
389
- const functionCallIds =
390
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
391
- lcMsg.additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY];
388
+ const functionCallIds = additional_kwargs?.[_FUNCTION_CALL_IDS_MAP_KEY];
392
389
  if ((0, messages_1.isAIMessage)(lcMsg) && !!lcMsg.tool_calls?.length) {
393
390
  input.push(...lcMsg.tool_calls.map((toolCall) => ({
394
391
  type: "function_call",
@@ -398,44 +395,64 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
398
395
  ...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
399
396
  })));
400
397
  }
401
- else if (lcMsg.additional_kwargs.tool_calls != null) {
402
- input.push(...lcMsg.additional_kwargs.tool_calls.map((toolCall) => ({
398
+ else if (additional_kwargs?.tool_calls) {
399
+ input.push(...additional_kwargs.tool_calls.map((toolCall) => ({
403
400
  type: "function_call",
404
401
  name: toolCall.function.name,
405
402
  call_id: toolCall.id,
406
- ...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
407
403
  arguments: toolCall.function.arguments,
404
+ ...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
408
405
  })));
409
406
  }
410
407
  const toolOutputs = lcMsg.response_metadata.output?.length
411
408
  ? lcMsg.response_metadata.output
412
- : lcMsg.additional_kwargs.tool_outputs;
413
- let computerCalls = [];
409
+ : additional_kwargs.tool_outputs;
410
+ const fallthroughCallTypes = [
411
+ "computer_call",
412
+ "mcp_call",
413
+ "code_interpreter_call",
414
+ "image_generation_call",
415
+ ];
414
416
  if (toolOutputs != null) {
415
417
  const castToolOutputs = toolOutputs;
416
- computerCalls = castToolOutputs?.filter((item) => item.type === "computer_call");
417
- if (computerCalls.length > 0)
418
- input.push(...computerCalls);
418
+ const fallthroughCalls = castToolOutputs?.filter((item) => fallthroughCallTypes.includes(item.type));
419
+ if (fallthroughCalls.length > 0)
420
+ input.push(...fallthroughCalls);
419
421
  }
420
422
  return input;
421
423
  }
422
- const content = typeof lcMsg.content === "string"
423
- ? lcMsg.content
424
- : lcMsg.content.flatMap((item) => {
424
+ if (role === "user" || role === "system" || role === "developer") {
425
+ if (typeof lcMsg.content === "string") {
426
+ return { type: "message", role, content: lcMsg.content };
427
+ }
428
+ const messages = [];
429
+ const content = lcMsg.content.flatMap((item) => {
430
+ if (item.type === "mcp_approval_response") {
431
+ messages.push({
432
+ type: "mcp_approval_response",
433
+ approval_request_id: item.approval_request_id,
434
+ approve: item.approve,
435
+ });
436
+ }
425
437
  if ((0, messages_1.isDataContentBlock)(item)) {
426
438
  return (0, messages_1.convertToProviderContentBlock)(item, completionsApiContentBlockConverter);
427
439
  }
428
440
  if (item.type === "text") {
429
- return { type: "input_text", text: item.text };
441
+ return {
442
+ type: "input_text",
443
+ text: item.text,
444
+ };
430
445
  }
431
446
  if (item.type === "image_url") {
432
- const image_url = typeof item.image_url === "string"
433
- ? item.image_url
434
- : item.image_url.url;
435
- const detail = typeof item.image_url === "string"
436
- ? "auto"
437
- : item.image_url.detail;
438
- return { type: "input_image", image_url, detail };
447
+ return {
448
+ type: "input_image",
449
+ image_url: typeof item.image_url === "string"
450
+ ? item.image_url
451
+ : item.image_url.url,
452
+ detail: typeof item.image_url === "string"
453
+ ? "auto"
454
+ : item.image_url.detail,
455
+ };
439
456
  }
440
457
  if (item.type === "input_text" ||
441
458
  item.type === "input_image" ||
@@ -444,8 +461,10 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
444
461
  }
445
462
  return [];
446
463
  });
447
- if (role === "user" || role === "system" || role === "developer") {
448
- return { type: "message", role, content };
464
+ if (content.length > 0) {
465
+ messages.push({ type: "message", role, content });
466
+ }
467
+ return messages;
449
468
  }
450
469
  console.warn(`Unsupported role found when converting to OpenAI Responses API: ${role}`);
451
470
  return [];
@@ -552,7 +571,7 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
552
571
  index: chunk.content_index,
553
572
  });
554
573
  }
555
- else if (chunk.type === "response.output_text.annotation.added") {
574
+ else if (chunk.type === "response.output_text_annotation.added") {
556
575
  content.push({
557
576
  type: "text",
558
577
  text: "",
@@ -578,9 +597,16 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
578
597
  };
579
598
  }
580
599
  else if (chunk.type === "response.output_item.done" &&
581
- (chunk.item.type === "web_search_call" ||
582
- chunk.item.type === "file_search_call" ||
583
- chunk.item.type === "computer_call")) {
600
+ [
601
+ "web_search_call",
602
+ "file_search_call",
603
+ "computer_call",
604
+ "code_interpreter_call",
605
+ "mcp_call",
606
+ "mcp_list_tools",
607
+ "mcp_approval_request",
608
+ "image_generation_call",
609
+ ].includes(chunk.item.type)) {
584
610
  additional_kwargs.tool_outputs = [chunk.item];
585
611
  }
586
612
  else if (chunk.type === "response.created") {
@@ -652,6 +678,11 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
652
678
  ],
653
679
  };
654
680
  }
681
+ else if (chunk.type === "response.image_generation_call.partial_image") {
682
+ // noop/fixme: retaining partial images in a message chunk means that _all_
683
+ // partial images get kept in history, so we don't do anything here.
684
+ return null;
685
+ }
655
686
  else {
656
687
  return null;
657
688
  }
@@ -678,6 +709,29 @@ function isBuiltInToolChoice(tool_choice) {
678
709
  "type" in tool_choice &&
679
710
  tool_choice.type !== "function");
680
711
  }
712
+ function _reduceChatOpenAIToolsForResponses(tools, fields) {
713
+ const reducedTools = [];
714
+ for (const tool of tools) {
715
+ if (isBuiltInTool(tool)) {
716
+ if (tool.type === "image_generation" && fields?.stream) {
717
+ // OpenAI sends a 400 error if partial_images is not set and we want to stream.
718
+ // We also set it to 1 since we don't support partial images yet.
719
+ tool.partial_images = 1;
720
+ }
721
+ reducedTools.push(tool);
722
+ }
723
+ else if ((0, base_1.isOpenAITool)(tool)) {
724
+ reducedTools.push({
725
+ type: "function",
726
+ name: tool.function.name,
727
+ parameters: tool.function.parameters,
728
+ description: tool.function.description,
729
+ strict: fields?.strict ?? null,
730
+ });
731
+ }
732
+ }
733
+ return reducedTools;
734
+ }
681
735
  function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
682
736
  if ((0, base_1.isOpenAITool)(tool)) {
683
737
  if (fields?.strict !== undefined) {
@@ -1671,25 +1725,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
1671
1725
  truncation: options?.truncation,
1672
1726
  include: options?.include,
1673
1727
  tools: options?.tools?.length
1674
- ? options.tools
1675
- .map((tool) => {
1676
- if (isBuiltInTool(tool)) {
1677
- return tool;
1678
- }
1679
- else if ((0, base_1.isOpenAITool)(tool)) {
1680
- return {
1681
- type: "function",
1682
- name: tool.function.name,
1683
- parameters: tool.function.parameters,
1684
- description: tool.function.description,
1685
- strict,
1686
- };
1687
- }
1688
- else {
1689
- return null;
1690
- }
1728
+ ? _reduceChatOpenAIToolsForResponses(options.tools, {
1729
+ stream: this.streaming,
1730
+ strict,
1691
1731
  })
1692
- .filter((tool) => tool !== null)
1693
1732
  : undefined,
1694
1733
  tool_choice: isBuiltInToolChoice(options?.tool_choice)
1695
1734
  ? options?.tool_choice
@@ -1932,17 +1971,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
1932
1971
  }
1933
1972
  async *_streamResponseChunks(messages, options, runManager) {
1934
1973
  if (this._useResponseApi(options)) {
1935
- const lastAIMessage = messages.filter((m) => (0, messages_1.isAIMessage)(m)).pop();
1936
- const lastAIMessageId = lastAIMessage?.response_metadata?.id;
1937
1974
  const streamIterable = await this.responseApiWithRetry({
1938
1975
  ...this.invocationParams(options, { streaming: true }),
1939
1976
  input: _convertMessagesToOpenAIResponsesParams(messages, this.model, this.zdrEnabled),
1940
1977
  stream: true,
1941
- ...(lastAIMessageId &&
1942
- lastAIMessageId.startsWith("resp_") &&
1943
- !this.zdrEnabled
1944
- ? { previous_response_id: lastAIMessageId }
1945
- : {}),
1946
1978
  }, options);
1947
1979
  for await (const data of streamIterable) {
1948
1980
  const chunk = _convertOpenAIResponsesDeltaToBaseMessageChunk(data);
@@ -2076,17 +2108,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
2076
2108
  },
2077
2109
  };
2078
2110
  }
2079
- const lastAIMessage = messages.filter((m) => (0, messages_1.isAIMessage)(m)).pop();
2080
- const lastAIMessageId = lastAIMessage?.response_metadata?.id;
2081
2111
  const input = _convertMessagesToOpenAIResponsesParams(messages, this.model, this.zdrEnabled);
2082
2112
  const data = await this.responseApiWithRetry({
2083
2113
  input,
2084
2114
  ...invocationParams,
2085
- ...(lastAIMessageId &&
2086
- lastAIMessageId.startsWith("resp_") &&
2087
- !this.zdrEnabled
2088
- ? { previous_response_id: lastAIMessageId }
2089
- : {}),
2090
2115
  }, { signal: options?.signal, ...options?.options });
2091
2116
  return {
2092
2117
  generations: [
@@ -2396,7 +2421,7 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
2396
2421
  const requestOptions = this._getClientOptions(options);
2397
2422
  return this.caller.call(async () => {
2398
2423
  try {
2399
- const res = await this.client.beta.chat.completions.parse(request, requestOptions);
2424
+ const res = await this.client.chat.completions.parse(request, requestOptions);
2400
2425
  return res;
2401
2426
  }
2402
2427
  catch (e) {
@@ -2483,15 +2508,21 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
2483
2508
  console.warn(`[WARNING]: JSON Schema is not supported for model "${this.model}". Falling back to tool calling.`);
2484
2509
  }
2485
2510
  if (method === "jsonMode") {
2486
- llm = this.withConfig({
2487
- response_format: { type: "json_object" },
2488
- });
2511
+ let outputFormatSchema;
2489
2512
  if ((0, types_1.isInteropZodSchema)(schema)) {
2490
2513
  outputParser = output_parsers_1.StructuredOutputParser.fromZodSchema(schema);
2514
+ outputFormatSchema = (0, json_schema_1.toJsonSchema)(schema);
2491
2515
  }
2492
2516
  else {
2493
2517
  outputParser = new output_parsers_1.JsonOutputParser();
2494
2518
  }
2519
+ llm = this.withConfig({
2520
+ response_format: { type: "json_object" },
2521
+ ls_structured_output_format: {
2522
+ kwargs: { method: "jsonMode" },
2523
+ schema: outputFormatSchema,
2524
+ },
2525
+ });
2495
2526
  }
2496
2527
  else if (method === "jsonSchema") {
2497
2528
  llm = this.withConfig({
@@ -2504,6 +2535,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
2504
2535
  strict: config?.strict,
2505
2536
  },
2506
2537
  },
2538
+ ls_structured_output_format: {
2539
+ kwargs: { method: "jsonSchema" },
2540
+ schema: (0, json_schema_1.toJsonSchema)(schema),
2541
+ },
2507
2542
  });
2508
2543
  if ((0, types_1.isInteropZodSchema)(schema)) {
2509
2544
  const altParser = output_parsers_1.StructuredOutputParser.fromZodSchema(schema);
@@ -2540,6 +2575,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
2540
2575
  name: functionName,
2541
2576
  },
2542
2577
  },
2578
+ ls_structured_output_format: {
2579
+ kwargs: { method: "functionCalling" },
2580
+ schema: asJsonSchema,
2581
+ },
2543
2582
  // Do not pass `strict` argument to OpenAI if `config.strict` is undefined
2544
2583
  ...(config?.strict !== undefined ? { strict: config.strict } : {}),
2545
2584
  });
@@ -2578,6 +2617,10 @@ class ChatOpenAI extends chat_models_1.BaseChatModel {
2578
2617
  name: functionName,
2579
2618
  },
2580
2619
  },
2620
+ ls_structured_output_format: {
2621
+ kwargs: { method: "functionCalling" },
2622
+ schema: (0, json_schema_1.toJsonSchema)(schema),
2623
+ },
2581
2624
  // Do not pass `strict` argument to OpenAI if `config.strict` is undefined
2582
2625
  ...(config?.strict !== undefined ? { strict: config.strict } : {}),
2583
2626
  });
@@ -2639,8 +2682,8 @@ function interopZodResponseFormat(zodSchema, name, props) {
2639
2682
  name,
2640
2683
  strict: true,
2641
2684
  schema: z4.toJSONSchema(zodSchema, {
2642
- cycles: "ref",
2643
- reused: "ref",
2685
+ cycles: "ref", // equivalent to nameStrategy: 'duplicate-ref'
2686
+ reused: "ref", // equivalent to $refStrategy: 'extract-to-root'
2644
2687
  override(ctx) {
2645
2688
  ctx.jsonSchema.title = name; // equivalent to `name` property
2646
2689
  // TODO: implement `nullableStrategy` patch-fix (zod doesn't support openApi3 json schema target)
@@ -841,7 +841,7 @@ export declare class ChatOpenAI<CallOptions extends ChatOpenAICallOptions = Chat
841
841
  * @param {OpenAIClient.Chat.ChatCompletionCreateParamsNonStreaming} request
842
842
  * @param {OpenAICoreRequestOptions | undefined} options
843
843
  */
844
- betaParsedCompletionWithRetry(request: OpenAIClient.Chat.ChatCompletionCreateParamsNonStreaming, options?: OpenAICoreRequestOptions): Promise<ReturnType<OpenAIClient["beta"]["chat"]["completions"]["parse"]>>;
844
+ betaParsedCompletionWithRetry(request: OpenAIClient.Chat.ChatCompletionCreateParamsNonStreaming, options?: OpenAICoreRequestOptions): Promise<ReturnType<OpenAIClient["chat"]["completions"]["parse"]>>;
845
845
  protected _getClientOptions(options: OpenAICoreRequestOptions | undefined): OpenAICoreRequestOptions;
846
846
  _llmType(): string;
847
847
  /** @ignore */