@langchain/openai 1.5.13 → 1.6.0

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 (60) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/chat_models/base.cjs +7 -1
  3. package/dist/chat_models/base.cjs.map +1 -1
  4. package/dist/chat_models/base.d.cts +9 -1
  5. package/dist/chat_models/base.d.cts.map +1 -1
  6. package/dist/chat_models/base.d.ts +9 -1
  7. package/dist/chat_models/base.d.ts.map +1 -1
  8. package/dist/chat_models/base.js +7 -1
  9. package/dist/chat_models/base.js.map +1 -1
  10. package/dist/chat_models/completions.cjs +10 -3
  11. package/dist/chat_models/completions.cjs.map +1 -1
  12. package/dist/chat_models/completions.d.cts.map +1 -1
  13. package/dist/chat_models/completions.d.ts.map +1 -1
  14. package/dist/chat_models/completions.js +11 -4
  15. package/dist/chat_models/completions.js.map +1 -1
  16. package/dist/chat_models/index.cjs +64 -0
  17. package/dist/chat_models/index.cjs.map +1 -1
  18. package/dist/chat_models/index.d.cts +64 -0
  19. package/dist/chat_models/index.d.cts.map +1 -1
  20. package/dist/chat_models/index.d.ts +64 -0
  21. package/dist/chat_models/index.d.ts.map +1 -1
  22. package/dist/chat_models/index.js +64 -0
  23. package/dist/chat_models/index.js.map +1 -1
  24. package/dist/chat_models/responses.cjs +5 -3
  25. package/dist/chat_models/responses.cjs.map +1 -1
  26. package/dist/chat_models/responses.d.cts.map +1 -1
  27. package/dist/chat_models/responses.d.ts.map +1 -1
  28. package/dist/chat_models/responses.js +5 -3
  29. package/dist/chat_models/responses.js.map +1 -1
  30. package/dist/converters/completions.cjs +9 -8
  31. package/dist/converters/completions.cjs.map +1 -1
  32. package/dist/converters/completions.d.cts.map +1 -1
  33. package/dist/converters/completions.d.ts.map +1 -1
  34. package/dist/converters/completions.js +10 -9
  35. package/dist/converters/completions.js.map +1 -1
  36. package/dist/converters/responses.cjs +79 -50
  37. package/dist/converters/responses.cjs.map +1 -1
  38. package/dist/converters/responses.d.cts.map +1 -1
  39. package/dist/converters/responses.d.ts.map +1 -1
  40. package/dist/converters/responses.js +80 -51
  41. package/dist/converters/responses.js.map +1 -1
  42. package/dist/index.d.cts +2 -2
  43. package/dist/index.d.ts +2 -2
  44. package/dist/llms.cjs +1 -1
  45. package/dist/llms.cjs.map +1 -1
  46. package/dist/llms.js +1 -1
  47. package/dist/llms.js.map +1 -1
  48. package/dist/types.d.cts +7 -2
  49. package/dist/types.d.cts.map +1 -1
  50. package/dist/types.d.ts +7 -2
  51. package/dist/types.d.ts.map +1 -1
  52. package/dist/utils/misc.cjs +30 -1
  53. package/dist/utils/misc.cjs.map +1 -1
  54. package/dist/utils/misc.d.cts +1 -0
  55. package/dist/utils/misc.d.cts.map +1 -1
  56. package/dist/utils/misc.d.ts +1 -0
  57. package/dist/utils/misc.d.ts.map +1 -1
  58. package/dist/utils/misc.js +27 -2
  59. package/dist/utils/misc.js.map +1 -1
  60. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
1
  import { isComputerToolCall, isCustomToolCall, parseComputerCall, parseCustomToolCall } from "../utils/tools.js";
2
- import { getFilenameFromMetadata, getRequiredFilenameFromMetadata, iife as iife$1, isReasoningModel, messageToOpenAIRole } from "../utils/misc.js";
2
+ import { applyPromptCacheBreakpoint, getFilenameFromMetadata, getRequiredFilenameFromMetadata, iife as iife$1, isReasoningModel, messageToOpenAIRole } from "../utils/misc.js";
3
3
  import { completionsApiContentBlockConverter } from "./completions.js";
4
4
  import { AIMessage, AIMessageChunk, convertToProviderContentBlock, isDataContentBlock } from "@langchain/core/messages";
5
5
  import { ChatGenerationChunk } from "@langchain/core/outputs";
@@ -613,6 +613,51 @@ const convertResponsesDeltaToChatGenerationChunk = (event) => {
613
613
  generationInfo
614
614
  });
615
615
  };
616
+ function resolveImageItem(block) {
617
+ const detail = iife$1(() => {
618
+ const raw = block.metadata?.detail;
619
+ if (raw === "low" || raw === "high" || raw === "auto") return raw;
620
+ return "auto";
621
+ });
622
+ if (block.fileId) return {
623
+ type: "input_image",
624
+ detail,
625
+ file_id: block.fileId
626
+ };
627
+ if (block.url) return {
628
+ type: "input_image",
629
+ detail,
630
+ image_url: block.url
631
+ };
632
+ if (block.data) {
633
+ const base64Data = typeof block.data === "string" ? block.data : Buffer.from(block.data).toString("base64");
634
+ return {
635
+ type: "input_image",
636
+ detail,
637
+ image_url: `data:${block.mimeType ?? "image/png"};base64,${base64Data}`
638
+ };
639
+ }
640
+ }
641
+ /** Converts tool content with images into a native `function_call_output` list. */
642
+ function convertToolContentToResponsesOutput(message) {
643
+ if (!Array.isArray(message.content)) return;
644
+ const blocks = message.contentBlocks;
645
+ if (!blocks.some((block) => block.type === "image")) return;
646
+ return blocks.map((block) => {
647
+ if (block.type === "text") return {
648
+ type: "input_text",
649
+ text: block.text
650
+ };
651
+ if (block.type === "image") {
652
+ const image = resolveImageItem(block);
653
+ if (image) return image;
654
+ }
655
+ return {
656
+ type: "input_text",
657
+ text: JSON.stringify(block)
658
+ };
659
+ });
660
+ }
616
661
  /**
617
662
  * Converts a single LangChain BaseMessage to OpenAI Responses API input format.
618
663
  *
@@ -664,6 +709,7 @@ const convertStandardContentMessageToResponsesInput = (message) => {
664
709
  return "assistant";
665
710
  }
666
711
  });
712
+ const withBreakpoint = (block, part) => messageRole === "assistant" ? part : applyPromptCacheBreakpoint(block, part);
667
713
  const makeTextPart = (text) => messageRole === "assistant" ? {
668
714
  type: "output_text",
669
715
  text,
@@ -701,31 +747,6 @@ const convertStandardContentMessageToResponsesInput = (message) => {
701
747
  return "{}";
702
748
  }
703
749
  };
704
- const resolveImageItem = (block) => {
705
- const detail = iife$1(() => {
706
- const raw = block.metadata?.detail;
707
- if (raw === "low" || raw === "high" || raw === "auto") return raw;
708
- return "auto";
709
- });
710
- if (block.fileId) return {
711
- type: "input_image",
712
- detail,
713
- file_id: block.fileId
714
- };
715
- if (block.url) return {
716
- type: "input_image",
717
- detail,
718
- image_url: block.url
719
- };
720
- if (block.data) {
721
- const base64Data = typeof block.data === "string" ? block.data : Buffer.from(block.data).toString("base64");
722
- return {
723
- type: "input_image",
724
- detail,
725
- image_url: `data:${block.mimeType ?? "image/png"};base64,${base64Data}`
726
- };
727
- }
728
- };
729
750
  const resolveFileItem = (block) => {
730
751
  if (block.fileId) {
731
752
  const filename = getFilenameFromMetadata(block);
@@ -797,7 +818,7 @@ const convertStandardContentMessageToResponsesInput = (message) => {
797
818
  if (!("extras" in block && typeof block.extras === "object" && block.extras !== null && "phase" in block.extras)) return void 0;
798
819
  return block.extras.phase;
799
820
  });
800
- pushMessageContent([makeTextPart(block.text)], phase);
821
+ pushMessageContent([withBreakpoint(block, makeTextPart(block.text))], phase);
801
822
  } else if (block.type === "invalid_tool_call") {} else if (block.type === "reasoning") {
802
823
  yield* flushMessage();
803
824
  yield convertReasoningBlock(block);
@@ -842,15 +863,15 @@ const convertStandardContentMessageToResponsesInput = (message) => {
842
863
  yield convertFunctionCallOutput(block);
843
864
  } else if (block.type === "audio") {} else if (block.type === "file") {
844
865
  const fileItem = resolveFileItem(block);
845
- if (fileItem) pushMessageContent([fileItem]);
866
+ if (fileItem) pushMessageContent([withBreakpoint(block, fileItem)]);
846
867
  } else if (block.type === "image") {
847
868
  const imageItem = resolveImageItem(block);
848
- if (imageItem) pushMessageContent([imageItem]);
869
+ if (imageItem) pushMessageContent([withBreakpoint(block, imageItem)]);
849
870
  } else if (block.type === "video") {
850
871
  const videoItem = resolveFileItem(block);
851
- if (videoItem) pushMessageContent([videoItem]);
872
+ if (videoItem) pushMessageContent([withBreakpoint(block, videoItem)]);
852
873
  } else if (block.type === "text-plain") {
853
- if (block.text) pushMessageContent([makeTextPart(block.text)]);
874
+ if (block.text) pushMessageContent([withBreakpoint(block, makeTextPart(block.text))]);
854
875
  } else if (block.type === "non_standard" && isResponsesMessage) {
855
876
  yield* flushMessage();
856
877
  yield block.value;
@@ -963,11 +984,12 @@ const convertMessagesToResponsesInput = ({ messages, zdrEnabled, model }) => {
963
984
  output: toolMessage.content
964
985
  };
965
986
  const isProviderNativeContent = Array.isArray(toolMessage.content) && toolMessage.content.every((item) => typeof item === "object" && item !== null && "type" in item && (item.type === "input_file" || item.type === "input_image" || item.type === "input_text"));
987
+ const attachmentOutput = isProviderNativeContent ? void 0 : convertToolContentToResponsesOutput(toolMessage);
966
988
  return {
967
989
  type: "function_call_output",
968
990
  call_id: toolMessage.tool_call_id,
969
991
  id: toolMessage.id?.startsWith("fc_") ? toolMessage.id : void 0,
970
- output: isProviderNativeContent ? toolMessage.content : typeof toolMessage.content !== "string" ? JSON.stringify(toolMessage.content) : toolMessage.content
992
+ output: isProviderNativeContent ? toolMessage.content : attachmentOutput ?? (typeof toolMessage.content !== "string" ? JSON.stringify(toolMessage.content) : toolMessage.content)
971
993
  };
972
994
  }
973
995
  if (role === "assistant") {
@@ -1093,39 +1115,46 @@ const convertMessagesToResponsesInput = ({ messages, zdrEnabled, model }) => {
1093
1115
  if (isDataContentBlock(item)) {
1094
1116
  if (item.type === "file") {
1095
1117
  const filename = getFilenameFromMetadata(item);
1096
- if (item.source_type === "url") return {
1118
+ if (item.source_type === "url") return applyPromptCacheBreakpoint(item, {
1097
1119
  type: "input_file",
1098
1120
  file_url: item.url,
1099
1121
  ...filename ? { filename } : {}
1100
- };
1101
- if (item.source_type === "id") return {
1122
+ });
1123
+ if (item.source_type === "id") return applyPromptCacheBreakpoint(item, {
1102
1124
  type: "input_file",
1103
1125
  file_id: item.id,
1104
1126
  ...filename ? { filename } : {}
1105
- };
1106
- if (item.source_type === "base64") return {
1107
- type: "input_file",
1108
- file_data: `data:${item.mime_type ?? ""};base64,${item.data}`,
1109
- filename: getRequiredFilenameFromMetadata(item)
1110
- };
1127
+ });
1128
+ if (item.source_type === "base64") {
1129
+ const mimeType = item.mime_type ?? "";
1130
+ return applyPromptCacheBreakpoint(item, {
1131
+ type: "input_file",
1132
+ file_data: `data:${mimeType};base64,${item.data}`,
1133
+ filename: getRequiredFilenameFromMetadata(item)
1134
+ });
1135
+ }
1111
1136
  }
1112
- return convertToProviderContentBlock(item, completionsApiContentBlockConverter);
1137
+ return applyPromptCacheBreakpoint(item, convertToProviderContentBlock(item, completionsApiContentBlockConverter));
1113
1138
  }
1114
- if (item.type === "text") return {
1139
+ if (item.type === "text") return applyPromptCacheBreakpoint(item, {
1115
1140
  type: "input_text",
1116
1141
  text: item.text
1117
- };
1118
- if (item.type === "image_url") return {
1119
- type: "input_image",
1120
- image_url: iife$1(() => {
1142
+ });
1143
+ if (item.type === "image_url") {
1144
+ const imageUrl = iife$1(() => {
1121
1145
  if (typeof item.image_url === "string") return item.image_url;
1122
1146
  else if (typeof item.image_url === "object" && item.image_url !== null && "url" in item.image_url) return item.image_url.url;
1123
- }),
1124
- detail: iife$1(() => {
1147
+ });
1148
+ const detail = iife$1(() => {
1125
1149
  if (typeof item.image_url === "string") return "auto";
1126
1150
  else if (typeof item.image_url === "object" && item.image_url !== null && "detail" in item.image_url) return item.image_url.detail;
1127
- })
1128
- };
1151
+ });
1152
+ return applyPromptCacheBreakpoint(item, {
1153
+ type: "input_image",
1154
+ image_url: imageUrl,
1155
+ detail
1156
+ });
1157
+ }
1129
1158
  if (item.type === "input_text" || item.type === "input_image" || item.type === "input_file") return item;
1130
1159
  return [];
1131
1160
  });