@langchain/openai 0.5.12 → 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.
@@ -1,3 +1,4 @@
1
+ import * as z4 from "zod/v4/core";
1
2
  import { OpenAI as OpenAIClient } from "openai";
2
3
  import { AIMessage, AIMessageChunk, ChatMessage, ChatMessageChunk, FunctionMessageChunk, HumanMessageChunk, SystemMessageChunk, ToolMessageChunk, isAIMessage, parseBase64DataUrl, parseMimeType, convertToProviderContentBlock, isDataContentBlock, } from "@langchain/core/messages";
3
4
  import { ChatGenerationChunk, } from "@langchain/core/outputs";
@@ -7,8 +8,9 @@ import { isOpenAITool, } from "@langchain/core/language_models/base";
7
8
  import { RunnableLambda, RunnablePassthrough, RunnableSequence, } from "@langchain/core/runnables";
8
9
  import { JsonOutputParser, StructuredOutputParser, } from "@langchain/core/output_parsers";
9
10
  import { JsonOutputKeyToolsParser, convertLangChainToolCallToOpenAI, makeInvalidToolCall, parseToolCall, } from "@langchain/core/output_parsers/openai_tools";
10
- import { zodToJsonSchema } from "zod-to-json-schema";
11
11
  import { zodResponseFormat } from "openai/helpers/zod";
12
+ import { getSchemaDescription, isInteropZodSchema, isZodSchemaV3, isZodSchemaV4, } from "@langchain/core/utils/types";
13
+ import { toJsonSchema, } from "@langchain/core/utils/json_schema";
12
14
  import { getEndpoint } from "./utils/azure.js";
13
15
  import { formatToOpenAIToolChoice, wrapOpenAIClientError, } from "./utils/openai.js";
14
16
  import { formatFunctionDefinitions, } from "./utils/openai-format-fndef.js";
@@ -134,7 +136,7 @@ const completionsApiContentBlockConverter = {
134
136
  return {
135
137
  type: "file",
136
138
  file: {
137
- file_data: block.url,
139
+ file_data: block.url, // formatted as base64 data URL
138
140
  ...(block.metadata?.filename || block.metadata?.name
139
141
  ? {
140
142
  filename: (block.metadata?.filename ||
@@ -247,12 +249,8 @@ function _convertReasoningSummaryToOpenAIResponsesParams(reasoning) {
247
249
  };
248
250
  }
249
251
  function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
250
- const lastAIMessage = messages.filter((m) => isAIMessage(m)).pop();
251
- const lastAIMessageId = lastAIMessage?.response_metadata?.id;
252
- const newMessages = lastAIMessageId && lastAIMessageId.startsWith("resp_") && !zdrEnabled
253
- ? messages.slice(messages.indexOf(lastAIMessage) + 1)
254
- : messages;
255
- return newMessages.flatMap((lcMsg) => {
252
+ return messages.flatMap((lcMsg) => {
253
+ const additional_kwargs = lcMsg.additional_kwargs;
256
254
  let role = messageToOpenAIRole(lcMsg);
257
255
  if (role === "system" && isReasoningModel(model))
258
256
  role = "developer";
@@ -262,7 +260,7 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
262
260
  if (role === "tool") {
263
261
  const toolMessage = lcMsg;
264
262
  // Handle computer call output
265
- if (toolMessage.additional_kwargs?.type === "computer_call_output") {
263
+ if (additional_kwargs?.type === "computer_call_output") {
266
264
  const output = (() => {
267
265
  if (typeof toolMessage.content === "string") {
268
266
  return {
@@ -313,25 +311,19 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
313
311
  // otherwise, try to reconstruct the response from what we have
314
312
  const input = [];
315
313
  // reasoning items
316
- if (!zdrEnabled && lcMsg.additional_kwargs.reasoning != null) {
317
- const isReasoningItem = (item) => typeof item === "object" &&
318
- item != null &&
319
- "type" in item &&
320
- item.type === "reasoning";
321
- if (isReasoningItem(lcMsg.additional_kwargs.reasoning)) {
322
- const reasoningItem = _convertReasoningSummaryToOpenAIResponsesParams(lcMsg.additional_kwargs.reasoning);
323
- input.push(reasoningItem);
324
- }
314
+ if (additional_kwargs?.reasoning && !zdrEnabled) {
315
+ const reasoningItem = _convertReasoningSummaryToOpenAIResponsesParams(additional_kwargs.reasoning);
316
+ input.push(reasoningItem);
325
317
  }
326
318
  // ai content
327
319
  let { content } = lcMsg;
328
- if (lcMsg.additional_kwargs.refusal != null) {
320
+ if (additional_kwargs?.refusal) {
329
321
  if (typeof content === "string") {
330
322
  content = [{ type: "output_text", text: content, annotations: [] }];
331
323
  }
332
324
  content = [
333
325
  ...content,
334
- { type: "refusal", refusal: lcMsg.additional_kwargs.refusal },
326
+ { type: "refusal", refusal: additional_kwargs.refusal },
335
327
  ];
336
328
  }
337
329
  input.push({
@@ -355,10 +347,7 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
355
347
  return [];
356
348
  }),
357
349
  });
358
- // function tool calls and computer use tool calls
359
- const functionCallIds =
360
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
361
- lcMsg.additional_kwargs[_FUNCTION_CALL_IDS_MAP_KEY];
350
+ const functionCallIds = additional_kwargs?.[_FUNCTION_CALL_IDS_MAP_KEY];
362
351
  if (isAIMessage(lcMsg) && !!lcMsg.tool_calls?.length) {
363
352
  input.push(...lcMsg.tool_calls.map((toolCall) => ({
364
353
  type: "function_call",
@@ -368,44 +357,64 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
368
357
  ...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
369
358
  })));
370
359
  }
371
- else if (lcMsg.additional_kwargs.tool_calls != null) {
372
- input.push(...lcMsg.additional_kwargs.tool_calls.map((toolCall) => ({
360
+ else if (additional_kwargs?.tool_calls) {
361
+ input.push(...additional_kwargs.tool_calls.map((toolCall) => ({
373
362
  type: "function_call",
374
363
  name: toolCall.function.name,
375
364
  call_id: toolCall.id,
376
- ...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
377
365
  arguments: toolCall.function.arguments,
366
+ ...(zdrEnabled ? { id: functionCallIds?.[toolCall.id] } : {}),
378
367
  })));
379
368
  }
380
369
  const toolOutputs = lcMsg.response_metadata.output?.length
381
370
  ? lcMsg.response_metadata.output
382
- : lcMsg.additional_kwargs.tool_outputs;
383
- let computerCalls = [];
371
+ : additional_kwargs.tool_outputs;
372
+ const fallthroughCallTypes = [
373
+ "computer_call",
374
+ "mcp_call",
375
+ "code_interpreter_call",
376
+ "image_generation_call",
377
+ ];
384
378
  if (toolOutputs != null) {
385
379
  const castToolOutputs = toolOutputs;
386
- computerCalls = castToolOutputs?.filter((item) => item.type === "computer_call");
387
- if (computerCalls.length > 0)
388
- input.push(...computerCalls);
380
+ const fallthroughCalls = castToolOutputs?.filter((item) => fallthroughCallTypes.includes(item.type));
381
+ if (fallthroughCalls.length > 0)
382
+ input.push(...fallthroughCalls);
389
383
  }
390
384
  return input;
391
385
  }
392
- const content = typeof lcMsg.content === "string"
393
- ? lcMsg.content
394
- : lcMsg.content.flatMap((item) => {
386
+ if (role === "user" || role === "system" || role === "developer") {
387
+ if (typeof lcMsg.content === "string") {
388
+ return { type: "message", role, content: lcMsg.content };
389
+ }
390
+ const messages = [];
391
+ const content = lcMsg.content.flatMap((item) => {
392
+ if (item.type === "mcp_approval_response") {
393
+ messages.push({
394
+ type: "mcp_approval_response",
395
+ approval_request_id: item.approval_request_id,
396
+ approve: item.approve,
397
+ });
398
+ }
395
399
  if (isDataContentBlock(item)) {
396
400
  return convertToProviderContentBlock(item, completionsApiContentBlockConverter);
397
401
  }
398
402
  if (item.type === "text") {
399
- return { type: "input_text", text: item.text };
403
+ return {
404
+ type: "input_text",
405
+ text: item.text,
406
+ };
400
407
  }
401
408
  if (item.type === "image_url") {
402
- const image_url = typeof item.image_url === "string"
403
- ? item.image_url
404
- : item.image_url.url;
405
- const detail = typeof item.image_url === "string"
406
- ? "auto"
407
- : item.image_url.detail;
408
- return { type: "input_image", image_url, detail };
409
+ return {
410
+ type: "input_image",
411
+ image_url: typeof item.image_url === "string"
412
+ ? item.image_url
413
+ : item.image_url.url,
414
+ detail: typeof item.image_url === "string"
415
+ ? "auto"
416
+ : item.image_url.detail,
417
+ };
409
418
  }
410
419
  if (item.type === "input_text" ||
411
420
  item.type === "input_image" ||
@@ -414,8 +423,10 @@ function _convertMessagesToOpenAIResponsesParams(messages, model, zdrEnabled) {
414
423
  }
415
424
  return [];
416
425
  });
417
- if (role === "user" || role === "system" || role === "developer") {
418
- return { type: "message", role, content };
426
+ if (content.length > 0) {
427
+ messages.push({ type: "message", role, content });
428
+ }
429
+ return messages;
419
430
  }
420
431
  console.warn(`Unsupported role found when converting to OpenAI Responses API: ${role}`);
421
432
  return [];
@@ -522,7 +533,7 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
522
533
  index: chunk.content_index,
523
534
  });
524
535
  }
525
- else if (chunk.type === "response.output_text.annotation.added") {
536
+ else if (chunk.type === "response.output_text_annotation.added") {
526
537
  content.push({
527
538
  type: "text",
528
539
  text: "",
@@ -548,9 +559,16 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
548
559
  };
549
560
  }
550
561
  else if (chunk.type === "response.output_item.done" &&
551
- (chunk.item.type === "web_search_call" ||
552
- chunk.item.type === "file_search_call" ||
553
- chunk.item.type === "computer_call")) {
562
+ [
563
+ "web_search_call",
564
+ "file_search_call",
565
+ "computer_call",
566
+ "code_interpreter_call",
567
+ "mcp_call",
568
+ "mcp_list_tools",
569
+ "mcp_approval_request",
570
+ "image_generation_call",
571
+ ].includes(chunk.item.type)) {
554
572
  additional_kwargs.tool_outputs = [chunk.item];
555
573
  }
556
574
  else if (chunk.type === "response.created") {
@@ -622,6 +640,11 @@ function _convertOpenAIResponsesDeltaToBaseMessageChunk(chunk) {
622
640
  ],
623
641
  };
624
642
  }
643
+ else if (chunk.type === "response.image_generation_call.partial_image") {
644
+ // noop/fixme: retaining partial images in a message chunk means that _all_
645
+ // partial images get kept in history, so we don't do anything here.
646
+ return null;
647
+ }
625
648
  else {
626
649
  return null;
627
650
  }
@@ -648,6 +671,29 @@ function isBuiltInToolChoice(tool_choice) {
648
671
  "type" in tool_choice &&
649
672
  tool_choice.type !== "function");
650
673
  }
674
+ function _reduceChatOpenAIToolsForResponses(tools, fields) {
675
+ const reducedTools = [];
676
+ for (const tool of tools) {
677
+ if (isBuiltInTool(tool)) {
678
+ if (tool.type === "image_generation" && fields?.stream) {
679
+ // OpenAI sends a 400 error if partial_images is not set and we want to stream.
680
+ // We also set it to 1 since we don't support partial images yet.
681
+ tool.partial_images = 1;
682
+ }
683
+ reducedTools.push(tool);
684
+ }
685
+ else if (isOpenAITool(tool)) {
686
+ reducedTools.push({
687
+ type: "function",
688
+ name: tool.function.name,
689
+ parameters: tool.function.parameters,
690
+ description: tool.function.description,
691
+ strict: fields?.strict ?? null,
692
+ });
693
+ }
694
+ }
695
+ return reducedTools;
696
+ }
651
697
  function _convertChatOpenAIToolTypeToOpenAITool(tool, fields) {
652
698
  if (isOpenAITool(tool)) {
653
699
  if (fields?.strict !== undefined) {
@@ -1582,8 +1628,8 @@ export class ChatOpenAI extends BaseChatModel {
1582
1628
  if (resFormat &&
1583
1629
  resFormat.type === "json_schema" &&
1584
1630
  resFormat.json_schema.schema &&
1585
- isZodSchema(resFormat.json_schema.schema)) {
1586
- return zodResponseFormat(resFormat.json_schema.schema, resFormat.json_schema.name, {
1631
+ isInteropZodSchema(resFormat.json_schema.schema)) {
1632
+ return interopZodResponseFormat(resFormat.json_schema.schema, resFormat.json_schema.name, {
1587
1633
  description: resFormat.json_schema.description,
1588
1634
  });
1589
1635
  }
@@ -1641,25 +1687,10 @@ export class ChatOpenAI extends BaseChatModel {
1641
1687
  truncation: options?.truncation,
1642
1688
  include: options?.include,
1643
1689
  tools: options?.tools?.length
1644
- ? options.tools
1645
- .map((tool) => {
1646
- if (isBuiltInTool(tool)) {
1647
- return tool;
1648
- }
1649
- else if (isOpenAITool(tool)) {
1650
- return {
1651
- type: "function",
1652
- name: tool.function.name,
1653
- parameters: tool.function.parameters,
1654
- description: tool.function.description,
1655
- strict,
1656
- };
1657
- }
1658
- else {
1659
- return null;
1660
- }
1690
+ ? _reduceChatOpenAIToolsForResponses(options.tools, {
1691
+ stream: this.streaming,
1692
+ strict,
1661
1693
  })
1662
- .filter((tool) => tool !== null)
1663
1694
  : undefined,
1664
1695
  tool_choice: isBuiltInToolChoice(options?.tool_choice)
1665
1696
  ? options?.tool_choice
@@ -1902,17 +1933,10 @@ export class ChatOpenAI extends BaseChatModel {
1902
1933
  }
1903
1934
  async *_streamResponseChunks(messages, options, runManager) {
1904
1935
  if (this._useResponseApi(options)) {
1905
- const lastAIMessage = messages.filter((m) => isAIMessage(m)).pop();
1906
- const lastAIMessageId = lastAIMessage?.response_metadata?.id;
1907
1936
  const streamIterable = await this.responseApiWithRetry({
1908
1937
  ...this.invocationParams(options, { streaming: true }),
1909
1938
  input: _convertMessagesToOpenAIResponsesParams(messages, this.model, this.zdrEnabled),
1910
1939
  stream: true,
1911
- ...(lastAIMessageId &&
1912
- lastAIMessageId.startsWith("resp_") &&
1913
- !this.zdrEnabled
1914
- ? { previous_response_id: lastAIMessageId }
1915
- : {}),
1916
1940
  }, options);
1917
1941
  for await (const data of streamIterable) {
1918
1942
  const chunk = _convertOpenAIResponsesDeltaToBaseMessageChunk(data);
@@ -2046,17 +2070,10 @@ export class ChatOpenAI extends BaseChatModel {
2046
2070
  },
2047
2071
  };
2048
2072
  }
2049
- const lastAIMessage = messages.filter((m) => isAIMessage(m)).pop();
2050
- const lastAIMessageId = lastAIMessage?.response_metadata?.id;
2051
2073
  const input = _convertMessagesToOpenAIResponsesParams(messages, this.model, this.zdrEnabled);
2052
2074
  const data = await this.responseApiWithRetry({
2053
2075
  input,
2054
2076
  ...invocationParams,
2055
- ...(lastAIMessageId &&
2056
- lastAIMessageId.startsWith("resp_") &&
2057
- !this.zdrEnabled
2058
- ? { previous_response_id: lastAIMessageId }
2059
- : {}),
2060
2077
  }, { signal: options?.signal, ...options?.options });
2061
2078
  return {
2062
2079
  generations: [
@@ -2366,7 +2383,7 @@ export class ChatOpenAI extends BaseChatModel {
2366
2383
  const requestOptions = this._getClientOptions(options);
2367
2384
  return this.caller.call(async () => {
2368
2385
  try {
2369
- const res = await this.client.beta.chat.completions.parse(request, requestOptions);
2386
+ const res = await this.client.chat.completions.parse(request, requestOptions);
2370
2387
  return res;
2371
2388
  }
2372
2389
  catch (e) {
@@ -2453,15 +2470,21 @@ export class ChatOpenAI extends BaseChatModel {
2453
2470
  console.warn(`[WARNING]: JSON Schema is not supported for model "${this.model}". Falling back to tool calling.`);
2454
2471
  }
2455
2472
  if (method === "jsonMode") {
2456
- llm = this.withConfig({
2457
- response_format: { type: "json_object" },
2458
- });
2459
- if (isZodSchema(schema)) {
2473
+ let outputFormatSchema;
2474
+ if (isInteropZodSchema(schema)) {
2460
2475
  outputParser = StructuredOutputParser.fromZodSchema(schema);
2476
+ outputFormatSchema = toJsonSchema(schema);
2461
2477
  }
2462
2478
  else {
2463
2479
  outputParser = new JsonOutputParser();
2464
2480
  }
2481
+ llm = this.withConfig({
2482
+ response_format: { type: "json_object" },
2483
+ ls_structured_output_format: {
2484
+ kwargs: { method: "jsonMode" },
2485
+ schema: outputFormatSchema,
2486
+ },
2487
+ });
2465
2488
  }
2466
2489
  else if (method === "jsonSchema") {
2467
2490
  llm = this.withConfig({
@@ -2469,13 +2492,17 @@ export class ChatOpenAI extends BaseChatModel {
2469
2492
  type: "json_schema",
2470
2493
  json_schema: {
2471
2494
  name: name ?? "extract",
2472
- description: schema.description,
2495
+ description: getSchemaDescription(schema),
2473
2496
  schema,
2474
2497
  strict: config?.strict,
2475
2498
  },
2476
2499
  },
2500
+ ls_structured_output_format: {
2501
+ kwargs: { method: "jsonSchema" },
2502
+ schema: toJsonSchema(schema),
2503
+ },
2477
2504
  });
2478
- if (isZodSchema(schema)) {
2505
+ if (isInteropZodSchema(schema)) {
2479
2506
  const altParser = StructuredOutputParser.fromZodSchema(schema);
2480
2507
  outputParser = RunnableLambda.from((aiMessage) => {
2481
2508
  if ("parsed" in aiMessage.additional_kwargs) {
@@ -2491,8 +2518,8 @@ export class ChatOpenAI extends BaseChatModel {
2491
2518
  else {
2492
2519
  let functionName = name ?? "extract";
2493
2520
  // Is function calling
2494
- if (isZodSchema(schema)) {
2495
- const asJsonSchema = zodToJsonSchema(schema);
2521
+ if (isInteropZodSchema(schema)) {
2522
+ const asJsonSchema = toJsonSchema(schema);
2496
2523
  llm = this.withConfig({
2497
2524
  tools: [
2498
2525
  {
@@ -2510,6 +2537,10 @@ export class ChatOpenAI extends BaseChatModel {
2510
2537
  name: functionName,
2511
2538
  },
2512
2539
  },
2540
+ ls_structured_output_format: {
2541
+ kwargs: { method: "functionCalling" },
2542
+ schema: asJsonSchema,
2543
+ },
2513
2544
  // Do not pass `strict` argument to OpenAI if `config.strict` is undefined
2514
2545
  ...(config?.strict !== undefined ? { strict: config.strict } : {}),
2515
2546
  });
@@ -2548,6 +2579,10 @@ export class ChatOpenAI extends BaseChatModel {
2548
2579
  name: functionName,
2549
2580
  },
2550
2581
  },
2582
+ ls_structured_output_format: {
2583
+ kwargs: { method: "functionCalling" },
2584
+ schema: toJsonSchema(schema),
2585
+ },
2551
2586
  // Do not pass `strict` argument to OpenAI if `config.strict` is undefined
2552
2587
  ...(config?.strict !== undefined ? { strict: config.strict } : {}),
2553
2588
  });
@@ -2573,12 +2608,6 @@ export class ChatOpenAI extends BaseChatModel {
2573
2608
  return RunnableSequence.from([{ raw: llm }, parsedWithFallback]);
2574
2609
  }
2575
2610
  }
2576
- function isZodSchema(
2577
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
2578
- input) {
2579
- // Check for a characteristic method of Zod schemas
2580
- return typeof input?.parse === "function";
2581
- }
2582
2611
  function isStructuredOutputMethodParams(x
2583
2612
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2584
2613
  ) {
@@ -2587,3 +2616,49 @@ function isStructuredOutputMethodParams(x
2587
2616
  typeof x.schema ===
2588
2617
  "object");
2589
2618
  }
2619
+ // inlined from openai/lib/parser.ts
2620
+ function makeParseableResponseFormat(response_format, parser) {
2621
+ const obj = { ...response_format };
2622
+ Object.defineProperties(obj, {
2623
+ $brand: {
2624
+ value: "auto-parseable-response-format",
2625
+ enumerable: false,
2626
+ },
2627
+ $parseRaw: {
2628
+ value: parser,
2629
+ enumerable: false,
2630
+ },
2631
+ });
2632
+ return obj;
2633
+ }
2634
+ function interopZodResponseFormat(zodSchema, name, props) {
2635
+ if (isZodSchemaV3(zodSchema)) {
2636
+ return zodResponseFormat(zodSchema, name, props);
2637
+ }
2638
+ if (isZodSchemaV4(zodSchema)) {
2639
+ return makeParseableResponseFormat({
2640
+ type: "json_schema",
2641
+ json_schema: {
2642
+ ...props,
2643
+ name,
2644
+ strict: true,
2645
+ schema: z4.toJSONSchema(zodSchema, {
2646
+ cycles: "ref", // equivalent to nameStrategy: 'duplicate-ref'
2647
+ reused: "ref", // equivalent to $refStrategy: 'extract-to-root'
2648
+ override(ctx) {
2649
+ ctx.jsonSchema.title = name; // equivalent to `name` property
2650
+ // TODO: implement `nullableStrategy` patch-fix (zod doesn't support openApi3 json schema target)
2651
+ // TODO: implement `openaiStrictMode` patch-fix (where optional properties without `nullable` are not supported)
2652
+ },
2653
+ /// property equivalents from native `zodResponseFormat` fn
2654
+ // openaiStrictMode: true,
2655
+ // name,
2656
+ // nameStrategy: 'duplicate-ref',
2657
+ // $refStrategy: 'extract-to-root',
2658
+ // nullableStrategy: 'property',
2659
+ }),
2660
+ },
2661
+ }, (content) => z4.parse(zodSchema, JSON.parse(content)));
2662
+ }
2663
+ throw new Error("Unsupported schema response format");
2664
+ }
@@ -1,5 +1,9 @@
1
1
  import { type ClientOptions, OpenAI as OpenAIClient } from "openai";
2
2
  import { Embeddings, type EmbeddingsParams } from "@langchain/core/embeddings";
3
+ /**
4
+ * @see https://platform.openai.com/docs/guides/embeddings#embedding-models
5
+ */
6
+ export type OpenAIEmbeddingModelId = OpenAIClient.EmbeddingModel | (string & NonNullable<unknown>);
3
7
  /**
4
8
  * Interface for OpenAIEmbeddings parameters. Extends EmbeddingsParams and
5
9
  * defines additional parameters specific to the OpenAIEmbeddings class.
@@ -10,9 +14,9 @@ export interface OpenAIEmbeddingsParams extends EmbeddingsParams {
10
14
  * Alias for `model`
11
15
  * @deprecated Use "model" instead.
12
16
  */
13
- modelName: string;
17
+ modelName: OpenAIEmbeddingModelId;
14
18
  /** Model name to use */
15
- model: string;
19
+ model: OpenAIEmbeddingModelId;
16
20
  /**
17
21
  * The number of dimensions the resulting output embeddings should have.
18
22
  * Only supported in `text-embedding-3` and later models.
@@ -99,6 +103,6 @@ export declare class OpenAIEmbeddings extends Embeddings implements Partial<Open
99
103
  * @returns Promise that resolves to the response from the API.
100
104
  */
101
105
  protected embeddingWithRetry(request: OpenAIClient.EmbeddingCreateParams): Promise<OpenAIClient.Embeddings.CreateEmbeddingResponse & {
102
- _request_id?: string | null | undefined;
106
+ _request_id?: string | null;
103
107
  }>;
104
108
  }
@@ -1,6 +1,10 @@
1
1
  import { OpenAI as OpenAIClient } from "openai";
2
2
  import { Tool, ToolParams } from "@langchain/core/tools";
3
3
  import { MessageContentComplex } from "@langchain/core/messages";
4
+ /**
5
+ * @see https://platform.openai.com/docs/api-reference/images/create
6
+ */
7
+ export type OpenAIImageModelId = OpenAIClient.ImageModel | (string & NonNullable<unknown>);
4
8
  /**
5
9
  * An interface for the Dall-E API Wrapper.
6
10
  */
@@ -19,14 +23,15 @@ export interface DallEAPIWrapperParams extends ToolParams {
19
23
  * Alias for `model`
20
24
  * @params "dall-e-2" | "dall-e-3"
21
25
  * @default "dall-e-3"
26
+ * @deprecated Use `model` instead.
22
27
  */
23
- modelName?: string;
28
+ modelName?: OpenAIImageModelId;
24
29
  /**
25
30
  * The model to use.
26
31
  * @params "dall-e-2" | "dall-e-3"
27
32
  * @default "dall-e-3"
28
33
  */
29
- model?: string;
34
+ model?: OpenAIImageModelId;
30
35
  /**
31
36
  * The style of the generated images. Must be one of vivid or natural.
32
37
  * Vivid causes the model to lean towards generating hyper-real and dramatic images.
package/dist/types.d.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import type { OpenAI as OpenAIClient } from "openai";
2
- import type { RequestOptions as _OpenAICoreRequestOptions } from "openai/core";
3
2
  import type { ResponseFormatText, ResponseFormatJSONObject, ResponseFormatJSONSchema } from "openai/resources/shared";
4
3
  import { TiktokenModel } from "js-tiktoken/lite";
5
4
  import type { BaseLanguageModelCallOptions } from "@langchain/core/language_models/base";
6
- import type { z } from "zod";
5
+ import { InteropZodObject } from "@langchain/core/utils/types";
7
6
  export type { TiktokenModel };
7
+ /**
8
+ * @see https://platform.openai.com/docs/models
9
+ */
10
+ export type OpenAIChatModelId = OpenAIClient.ChatModel | (string & NonNullable<unknown>);
8
11
  export declare interface OpenAIBaseInput {
9
12
  /** Sampling temperature to use */
10
13
  temperature: number;
@@ -45,7 +48,7 @@ export declare interface OpenAIBaseInput {
45
48
  */
46
49
  modelName: string;
47
50
  /** Model name to use */
48
- model: string;
51
+ model: OpenAIChatModelId;
49
52
  /** Holds any additional parameters that are valid to pass to {@link
50
53
  * https://platform.openai.com/docs/api-reference/completions/create |
51
54
  * `openai.createCompletion`} that are not explicitly specified on this class.
@@ -74,7 +77,7 @@ export declare interface OpenAIBaseInput {
74
77
  */
75
78
  apiKey?: string;
76
79
  }
77
- export type OpenAICoreRequestOptions<Req = Record<string, unknown>> = _OpenAICoreRequestOptions<Req>;
80
+ export type OpenAICoreRequestOptions = OpenAIClient.RequestOptions;
78
81
  export interface OpenAICallOptions extends BaseLanguageModelCallOptions {
79
82
  /**
80
83
  * Additional options to pass to the underlying axios request.
@@ -218,7 +221,7 @@ type ChatOpenAIResponseFormatJSONSchema = Omit<ResponseFormatJSONSchema, "json_s
218
221
  * The schema for the response format, described as a JSON Schema object
219
222
  * or a Zod object.
220
223
  */
221
- schema: Record<string, any> | z.ZodObject<any, any, any, any>;
224
+ schema: Record<string, any> | InteropZodObject;
222
225
  };
223
226
  };
224
227
  /**
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getEndpoint = void 0;
3
+ exports.getEndpoint = getEndpoint;
4
4
  /**
5
5
  * This function generates an endpoint URL for (Azure) OpenAI
6
6
  * based on the configuration parameters provided.
@@ -48,4 +48,3 @@ function getEndpoint(config) {
48
48
  }
49
49
  return baseURL;
50
50
  }
51
- exports.getEndpoint = getEndpoint;
@@ -2,10 +2,9 @@
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
  /* eslint-disable no-param-reassign */
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.addLangChainErrorFields = void 0;
5
+ exports.addLangChainErrorFields = addLangChainErrorFields;
6
6
  function addLangChainErrorFields(error, lc_error_code) {
7
7
  error.lc_error_code = lc_error_code;
8
8
  error.message = `${error.message}\n\nTroubleshooting URL: https://js.langchain.com/docs/troubleshooting/errors/${lc_error_code}/\n`;
9
9
  return error;
10
10
  }
11
- exports.addLangChainErrorFields = addLangChainErrorFields;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isHeaders = isHeaders;
4
+ exports.normalizeHeaders = normalizeHeaders;
5
+ const iife = (fn) => fn();
6
+ function isHeaders(headers) {
7
+ return (typeof Headers !== "undefined" &&
8
+ headers !== null &&
9
+ typeof headers === "object" &&
10
+ Object.prototype.toString.call(headers) === "[object Headers]");
11
+ }
12
+ function normalizeHeaders(headers) {
13
+ const output = iife(() => {
14
+ // If headers is a Headers instance
15
+ if (isHeaders(headers)) {
16
+ return headers;
17
+ }
18
+ // If headers is an array of [key, value] pairs
19
+ else if (Array.isArray(headers)) {
20
+ return new Headers(headers);
21
+ }
22
+ // If headers is a NullableHeaders-like object (has 'values' property that is a Headers)
23
+ else if (typeof headers === "object" &&
24
+ headers !== null &&
25
+ "values" in headers &&
26
+ isHeaders(headers.values)) {
27
+ return headers.values;
28
+ }
29
+ // If headers is a plain object
30
+ else if (typeof headers === "object" && headers !== null) {
31
+ const entries = Object.entries(headers)
32
+ .filter(([, v]) => typeof v === "string")
33
+ .map(([k, v]) => [k, v]);
34
+ return new Headers(entries);
35
+ }
36
+ return new Headers();
37
+ });
38
+ return Object.fromEntries(output.entries());
39
+ }
@@ -0,0 +1,8 @@
1
+ type HeaderValue = string | undefined | null;
2
+ export type HeadersLike = Headers | readonly HeaderValue[][] | Record<string, HeaderValue | readonly HeaderValue[]> | undefined | null | {
3
+ values: Headers;
4
+ [key: string]: unknown;
5
+ };
6
+ export declare function isHeaders(headers: unknown): headers is Headers;
7
+ export declare function normalizeHeaders(headers: HeadersLike): Record<string, HeaderValue | readonly HeaderValue[]>;
8
+ export {};