@ai-sdk/langchain 2.0.240 → 2.0.242

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @ai-sdk/langchain
2
2
 
3
+ ## 2.0.242
4
+
5
+ ### Patch Changes
6
+
7
+ - 533f6c4: Emit canonical LangChain image content blocks when converting user messages.
8
+ - Updated dependencies [1efdef8]
9
+ - Updated dependencies [49414cf]
10
+ - ai@6.0.234
11
+
12
+ ## 2.0.241
13
+
14
+ ### Patch Changes
15
+
16
+ - Updated dependencies [fe410e7]
17
+ - Updated dependencies [af7188c]
18
+ - ai@6.0.233
19
+
3
20
  ## 2.0.240
4
21
 
5
22
  ### Patch Changes
package/dist/index.js CHANGED
@@ -85,6 +85,37 @@ function getDefaultFilename(mediaType, prefix = "file") {
85
85
  const ext = mediaType.split("/")[1] || "bin";
86
86
  return `${prefix}.${ext}`;
87
87
  }
88
+ function convertImageToContentBlock(data, mediaType = "image/png") {
89
+ if (data instanceof URL) {
90
+ if (data.protocol !== "data:") {
91
+ return { type: "image", url: data.toString() };
92
+ }
93
+ data = data.toString();
94
+ }
95
+ if (typeof data === "string") {
96
+ if (data.startsWith("http://") || data.startsWith("https://")) {
97
+ return { type: "image", url: data };
98
+ }
99
+ if (data.startsWith("data:")) {
100
+ const matches = data.match(/^data:([^;]+);base64,(.+)$/);
101
+ if (matches) {
102
+ return {
103
+ type: "image",
104
+ data: matches[2],
105
+ mimeType: matches[1]
106
+ };
107
+ }
108
+ return { type: "image", url: data };
109
+ }
110
+ return { type: "image", data, mimeType: mediaType };
111
+ }
112
+ const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
113
+ return {
114
+ type: "image",
115
+ data: btoa(String.fromCharCode(...bytes)),
116
+ mimeType: mediaType
117
+ };
118
+ }
88
119
  function convertUserContent(content) {
89
120
  var _a;
90
121
  if (typeof content === "string") {
@@ -96,69 +127,18 @@ function convertUserContent(content) {
96
127
  contentBlocks.push({ type: "text", text: part.text });
97
128
  } else if (part.type === "image") {
98
129
  const imagePart = part;
99
- if (imagePart.image instanceof URL) {
100
- contentBlocks.push({
101
- type: "image_url",
102
- image_url: { url: imagePart.image.toString() }
103
- });
104
- } else if (typeof imagePart.image === "string") {
105
- if (imagePart.image.startsWith("http://") || imagePart.image.startsWith("https://") || imagePart.image.startsWith("data:")) {
106
- contentBlocks.push({
107
- type: "image_url",
108
- image_url: { url: imagePart.image }
109
- });
110
- } else {
111
- const mimeType = imagePart.mediaType || "image/png";
112
- contentBlocks.push({
113
- type: "image_url",
114
- image_url: { url: `data:${mimeType};base64,${imagePart.image}` }
115
- });
116
- }
117
- } else if (
118
- /**
119
- * Handle Uint8Array or ArrayBuffer (binary data)
120
- */
121
- imagePart.image instanceof Uint8Array || imagePart.image instanceof ArrayBuffer
122
- ) {
123
- const bytes = imagePart.image instanceof ArrayBuffer ? new Uint8Array(imagePart.image) : imagePart.image;
124
- const base64 = btoa(String.fromCharCode(...bytes));
125
- const mimeType = imagePart.mediaType || "image/png";
126
- contentBlocks.push({
127
- type: "image_url",
128
- image_url: { url: `data:${mimeType};base64,${base64}` }
129
- });
130
+ if (imagePart.image instanceof URL || typeof imagePart.image === "string" || imagePart.image instanceof Uint8Array || imagePart.image instanceof ArrayBuffer) {
131
+ contentBlocks.push(
132
+ convertImageToContentBlock(imagePart.image, imagePart.mediaType)
133
+ );
130
134
  }
131
135
  } else if (part.type === "file") {
132
136
  const filePart = part;
133
137
  const isImage = (_a = filePart.mediaType) == null ? void 0 : _a.startsWith("image/");
134
138
  if (isImage) {
135
- if (filePart.data instanceof URL) {
136
- contentBlocks.push({
137
- type: "image_url",
138
- image_url: { url: filePart.data.toString() }
139
- });
140
- } else if (typeof filePart.data === "string") {
141
- if (filePart.data.startsWith("http://") || filePart.data.startsWith("https://") || filePart.data.startsWith("data:")) {
142
- contentBlocks.push({
143
- type: "image_url",
144
- image_url: { url: filePart.data }
145
- });
146
- } else {
147
- contentBlocks.push({
148
- type: "image_url",
149
- image_url: {
150
- url: `data:${filePart.mediaType};base64,${filePart.data}`
151
- }
152
- });
153
- }
154
- } else if (filePart.data instanceof Uint8Array || filePart.data instanceof ArrayBuffer) {
155
- const bytes = filePart.data instanceof ArrayBuffer ? new Uint8Array(filePart.data) : filePart.data;
156
- const base64 = btoa(String.fromCharCode(...bytes));
157
- contentBlocks.push({
158
- type: "image_url",
159
- image_url: { url: `data:${filePart.mediaType};base64,${base64}` }
160
- });
161
- }
139
+ contentBlocks.push(
140
+ convertImageToContentBlock(filePart.data, filePart.mediaType)
141
+ );
162
142
  } else {
163
143
  const filename = filePart.filename || getDefaultFilename(filePart.mediaType, "file");
164
144
  if (filePart.data instanceof URL) {
@@ -219,7 +199,7 @@ function convertUserContent(content) {
219
199
  content: contentBlocks.map((block) => block.text).join("")
220
200
  });
221
201
  }
222
- return new import_messages.HumanMessage({ content: contentBlocks });
202
+ return new import_messages.HumanMessage({ contentBlocks });
223
203
  }
224
204
  function isToolResultPart(item) {
225
205
  return item != null && typeof item === "object" && "type" in item && item.type === "tool-result";