@langchain/openai 1.5.12 → 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 +28 -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 +87 -52
  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 +88 -53
  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 +4 -4
@@ -4,6 +4,7 @@ const require_completions = require("./completions.cjs");
4
4
  let _langchain_core_messages = require("@langchain/core/messages");
5
5
  let _langchain_core_outputs = require("@langchain/core/outputs");
6
6
  let _langchain_core_output_parsers_openai_tools = require("@langchain/core/output_parsers/openai_tools");
7
+ let openai_lib_responses_ResponseInputItems_js = require("openai/lib/responses/ResponseInputItems.js");
7
8
  //#region src/converters/responses.ts
8
9
  const _FUNCTION_CALL_IDS_MAP_KEY = "__openai_function_call_ids__";
9
10
  const _CUSTOM_TOOL_CALL_IDS_MAP_KEY = "__openai_custom_tool_call_ids__";
@@ -612,6 +613,51 @@ const convertResponsesDeltaToChatGenerationChunk = (event) => {
612
613
  generationInfo
613
614
  });
614
615
  };
616
+ function resolveImageItem(block) {
617
+ const detail = require_misc.iife(() => {
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
+ }
615
661
  /**
616
662
  * Converts a single LangChain BaseMessage to OpenAI Responses API input format.
617
663
  *
@@ -663,6 +709,7 @@ const convertStandardContentMessageToResponsesInput = (message) => {
663
709
  return "assistant";
664
710
  }
665
711
  });
712
+ const withBreakpoint = (block, part) => messageRole === "assistant" ? part : require_misc.applyPromptCacheBreakpoint(block, part);
666
713
  const makeTextPart = (text) => messageRole === "assistant" ? {
667
714
  type: "output_text",
668
715
  text,
@@ -700,31 +747,6 @@ const convertStandardContentMessageToResponsesInput = (message) => {
700
747
  return "{}";
701
748
  }
702
749
  };
703
- const resolveImageItem = (block) => {
704
- const detail = require_misc.iife(() => {
705
- const raw = block.metadata?.detail;
706
- if (raw === "low" || raw === "high" || raw === "auto") return raw;
707
- return "auto";
708
- });
709
- if (block.fileId) return {
710
- type: "input_image",
711
- detail,
712
- file_id: block.fileId
713
- };
714
- if (block.url) return {
715
- type: "input_image",
716
- detail,
717
- image_url: block.url
718
- };
719
- if (block.data) {
720
- const base64Data = typeof block.data === "string" ? block.data : Buffer.from(block.data).toString("base64");
721
- return {
722
- type: "input_image",
723
- detail,
724
- image_url: `data:${block.mimeType ?? "image/png"};base64,${base64Data}`
725
- };
726
- }
727
- };
728
750
  const resolveFileItem = (block) => {
729
751
  if (block.fileId) {
730
752
  const filename = require_misc.getFilenameFromMetadata(block);
@@ -767,10 +789,12 @@ const convertStandardContentMessageToResponsesInput = (message) => {
767
789
  type: "summary_text",
768
790
  text: ""
769
791
  }];
792
+ const encryptedContent = block.encrypted_content;
770
793
  return {
771
794
  type: "reasoning",
772
795
  ...block.id ? { id: block.id } : {},
773
- summary
796
+ summary,
797
+ ...typeof encryptedContent === "string" ? { encrypted_content: encryptedContent } : {}
774
798
  };
775
799
  };
776
800
  const convertFunctionCall = (block) => ({
@@ -794,7 +818,7 @@ const convertStandardContentMessageToResponsesInput = (message) => {
794
818
  if (!("extras" in block && typeof block.extras === "object" && block.extras !== null && "phase" in block.extras)) return void 0;
795
819
  return block.extras.phase;
796
820
  });
797
- pushMessageContent([makeTextPart(block.text)], phase);
821
+ pushMessageContent([withBreakpoint(block, makeTextPart(block.text))], phase);
798
822
  } else if (block.type === "invalid_tool_call") {} else if (block.type === "reasoning") {
799
823
  yield* flushMessage();
800
824
  yield convertReasoningBlock(block);
@@ -839,15 +863,15 @@ const convertStandardContentMessageToResponsesInput = (message) => {
839
863
  yield convertFunctionCallOutput(block);
840
864
  } else if (block.type === "audio") {} else if (block.type === "file") {
841
865
  const fileItem = resolveFileItem(block);
842
- if (fileItem) pushMessageContent([fileItem]);
866
+ if (fileItem) pushMessageContent([withBreakpoint(block, fileItem)]);
843
867
  } else if (block.type === "image") {
844
868
  const imageItem = resolveImageItem(block);
845
- if (imageItem) pushMessageContent([imageItem]);
869
+ if (imageItem) pushMessageContent([withBreakpoint(block, imageItem)]);
846
870
  } else if (block.type === "video") {
847
871
  const videoItem = resolveFileItem(block);
848
- if (videoItem) pushMessageContent([videoItem]);
872
+ if (videoItem) pushMessageContent([withBreakpoint(block, videoItem)]);
849
873
  } else if (block.type === "text-plain") {
850
- if (block.text) pushMessageContent([makeTextPart(block.text)]);
874
+ if (block.text) pushMessageContent([withBreakpoint(block, makeTextPart(block.text))]);
851
875
  } else if (block.type === "non_standard" && isResponsesMessage) {
852
876
  yield* flushMessage();
853
877
  yield block.value;
@@ -960,15 +984,19 @@ const convertMessagesToResponsesInput = ({ messages, zdrEnabled, model }) => {
960
984
  output: toolMessage.content
961
985
  };
962
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);
963
988
  return {
964
989
  type: "function_call_output",
965
990
  call_id: toolMessage.tool_call_id,
966
991
  id: toolMessage.id?.startsWith("fc_") ? toolMessage.id : void 0,
967
- 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)
968
993
  };
969
994
  }
970
995
  if (role === "assistant") {
971
- if (!zdrEnabled && responseMetadata?.output != null && Array.isArray(responseMetadata?.output) && responseMetadata?.output.length > 0 && responseMetadata?.output.every((item) => "type" in item)) return responseMetadata?.output;
996
+ if (responseMetadata?.output != null && Array.isArray(responseMetadata.output) && responseMetadata.output.length > 0 && responseMetadata.output.every((item) => typeof item === "object" && item != null && "type" in item && typeof item.type === "string")) {
997
+ const output = responseMetadata.output;
998
+ return zdrEnabled ? (0, openai_lib_responses_ResponseInputItems_js.toResponseInputItems)(output) : output;
999
+ }
972
1000
  const input = [];
973
1001
  const reasoning = additional_kwargs?.reasoning;
974
1002
  const hasEncryptedContent = !!reasoning?.encrypted_content;
@@ -1087,39 +1115,46 @@ const convertMessagesToResponsesInput = ({ messages, zdrEnabled, model }) => {
1087
1115
  if ((0, _langchain_core_messages.isDataContentBlock)(item)) {
1088
1116
  if (item.type === "file") {
1089
1117
  const filename = require_misc.getFilenameFromMetadata(item);
1090
- if (item.source_type === "url") return {
1118
+ if (item.source_type === "url") return require_misc.applyPromptCacheBreakpoint(item, {
1091
1119
  type: "input_file",
1092
1120
  file_url: item.url,
1093
1121
  ...filename ? { filename } : {}
1094
- };
1095
- if (item.source_type === "id") return {
1122
+ });
1123
+ if (item.source_type === "id") return require_misc.applyPromptCacheBreakpoint(item, {
1096
1124
  type: "input_file",
1097
1125
  file_id: item.id,
1098
1126
  ...filename ? { filename } : {}
1099
- };
1100
- if (item.source_type === "base64") return {
1101
- type: "input_file",
1102
- file_data: `data:${item.mime_type ?? ""};base64,${item.data}`,
1103
- filename: require_misc.getRequiredFilenameFromMetadata(item)
1104
- };
1127
+ });
1128
+ if (item.source_type === "base64") {
1129
+ const mimeType = item.mime_type ?? "";
1130
+ return require_misc.applyPromptCacheBreakpoint(item, {
1131
+ type: "input_file",
1132
+ file_data: `data:${mimeType};base64,${item.data}`,
1133
+ filename: require_misc.getRequiredFilenameFromMetadata(item)
1134
+ });
1135
+ }
1105
1136
  }
1106
- return (0, _langchain_core_messages.convertToProviderContentBlock)(item, require_completions.completionsApiContentBlockConverter);
1137
+ return require_misc.applyPromptCacheBreakpoint(item, (0, _langchain_core_messages.convertToProviderContentBlock)(item, require_completions.completionsApiContentBlockConverter));
1107
1138
  }
1108
- if (item.type === "text") return {
1139
+ if (item.type === "text") return require_misc.applyPromptCacheBreakpoint(item, {
1109
1140
  type: "input_text",
1110
1141
  text: item.text
1111
- };
1112
- if (item.type === "image_url") return {
1113
- type: "input_image",
1114
- image_url: require_misc.iife(() => {
1142
+ });
1143
+ if (item.type === "image_url") {
1144
+ const imageUrl = require_misc.iife(() => {
1115
1145
  if (typeof item.image_url === "string") return item.image_url;
1116
1146
  else if (typeof item.image_url === "object" && item.image_url !== null && "url" in item.image_url) return item.image_url.url;
1117
- }),
1118
- detail: require_misc.iife(() => {
1147
+ });
1148
+ const detail = require_misc.iife(() => {
1119
1149
  if (typeof item.image_url === "string") return "auto";
1120
1150
  else if (typeof item.image_url === "object" && item.image_url !== null && "detail" in item.image_url) return item.image_url.detail;
1121
- })
1122
- };
1151
+ });
1152
+ return require_misc.applyPromptCacheBreakpoint(item, {
1153
+ type: "input_image",
1154
+ image_url: imageUrl,
1155
+ detail
1156
+ });
1157
+ }
1123
1158
  if (item.type === "input_text" || item.type === "input_image" || item.type === "input_file") return item;
1124
1159
  return [];
1125
1160
  });