@ai-sdk/deepseek 3.0.48 → 3.0.50

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,21 @@
1
1
  # @ai-sdk/deepseek
2
2
 
3
+ ## 3.0.50
4
+
5
+ ### Patch Changes
6
+
7
+ - 7bed0ef: fix(deepseek): send tool-result images as image content parts
8
+
9
+ ## 3.0.49
10
+
11
+ ### Patch Changes
12
+
13
+ - a36eaaf: fix(deepseek): return a typed error for non-streaming responses without choices
14
+ - Updated dependencies [2973485]
15
+ - Updated dependencies [a4db5ea]
16
+ - Updated dependencies [2937ea2]
17
+ - @ai-sdk/provider-utils@5.0.45
18
+
3
19
  ## 3.0.48
4
20
 
5
21
  ### Patch Changes
package/dist/index.js CHANGED
@@ -9,6 +9,9 @@ import {
9
9
  } from "@ai-sdk/provider-utils";
10
10
 
11
11
  // src/chat/deepseek-chat-language-model.ts
12
+ import {
13
+ InvalidResponseDataError
14
+ } from "@ai-sdk/provider";
12
15
  import {
13
16
  combineHeaders,
14
17
  createEventSourceResponseHandler,
@@ -133,6 +136,27 @@ var supportedImageMediaTypes = /* @__PURE__ */ new Set([
133
136
  "image/png",
134
137
  "image/webp"
135
138
  ]);
139
+ function resolveDeepSeekImageMediaType(part) {
140
+ const resolvedMediaType = resolveFullMediaType({ part });
141
+ if (!supportedImageMediaTypes.has(resolvedMediaType)) {
142
+ throw new UnsupportedFunctionalityError({
143
+ functionality: `DeepSeek image media type ${resolvedMediaType}`,
144
+ message: "DeepSeek supports JPEG, PNG, GIF, and WebP image inputs."
145
+ });
146
+ }
147
+ return resolvedMediaType;
148
+ }
149
+ function validateDeepSeekImageUrl({
150
+ url,
151
+ prompt
152
+ }) {
153
+ if (url.length > 8192) {
154
+ throw new InvalidPromptError({
155
+ prompt,
156
+ message: "DeepSeek image URLs must not exceed 8192 characters."
157
+ });
158
+ }
159
+ }
136
160
  async function convertToDeepSeekChatMessages({
137
161
  prompt,
138
162
  responseFormat,
@@ -239,21 +263,10 @@ async function convertToDeepSeekChatMessages({
239
263
  })
240
264
  });
241
265
  } else if (part.data.type === "url" || part.data.type === "data") {
242
- const resolvedMediaType = resolveFullMediaType({ part });
243
- if (!supportedImageMediaTypes.has(resolvedMediaType)) {
244
- throw new UnsupportedFunctionalityError({
245
- functionality: `DeepSeek image media type ${resolvedMediaType}`,
246
- message: "DeepSeek supports JPEG, PNG, GIF, and WebP image inputs."
247
- });
248
- }
266
+ const resolvedMediaType = resolveDeepSeekImageMediaType(part);
249
267
  if (part.data.type === "url") {
250
268
  const url = part.data.url.toString();
251
- if (url.length > 8192) {
252
- throw new InvalidPromptError({
253
- prompt,
254
- message: "DeepSeek image URLs must not exceed 8192 characters."
255
- });
256
- }
269
+ validateDeepSeekImageUrl({ url, prompt });
257
270
  if ((filePartOptions == null ? void 0 : filePartOptions.fileData) === true) {
258
271
  throw new InvalidPromptError({
259
272
  prompt,
@@ -400,11 +413,64 @@ async function convertToDeepSeekChatMessages({
400
413
  case "execution-denied":
401
414
  contentValue = (_a = output.reason) != null ? _a : "Tool call execution denied.";
402
415
  break;
403
- case "content":
404
416
  case "json":
405
417
  case "error-json":
406
418
  contentValue = JSON.stringify(output.value);
407
419
  break;
420
+ case "content": {
421
+ const hasImagePart = output.value.some(
422
+ (part) => part.type === "file" && (part.data.type === "reference" || part.data.type === "url" || part.data.type === "data") && getTopLevelMediaType(part.mediaType) === "image"
423
+ );
424
+ if (!hasImagePart) {
425
+ contentValue = JSON.stringify(output.value);
426
+ break;
427
+ }
428
+ contentValue = [];
429
+ for (const part of output.value) {
430
+ if (part.type === "text") {
431
+ contentValue.push({ type: "text", text: part.text });
432
+ } else if (part.type === "file" && (part.data.type === "reference" || part.data.type === "url" || part.data.type === "data") && getTopLevelMediaType(part.mediaType) === "image") {
433
+ if (part.data.type === "reference") {
434
+ contentValue.push({
435
+ type: "file",
436
+ file_id: resolveProviderReference({
437
+ reference: part.data.reference,
438
+ provider: "deepseek"
439
+ })
440
+ });
441
+ continue;
442
+ }
443
+ const filePartOptions = await parseProviderOptions({
444
+ provider: providerOptionsName,
445
+ providerOptions: part.providerOptions,
446
+ schema: deepseekFilePartProviderOptions
447
+ });
448
+ const resolvedMediaType = resolveDeepSeekImageMediaType(part);
449
+ let url;
450
+ if (part.data.type === "url") {
451
+ url = part.data.url.toString();
452
+ validateDeepSeekImageUrl({ url, prompt });
453
+ } else {
454
+ url = `data:${resolvedMediaType === "image/jpg" ? "image/jpeg" : resolvedMediaType};base64,${convertToBase64(part.data.data)}`;
455
+ }
456
+ contentValue.push({
457
+ type: "image_url",
458
+ image_url: {
459
+ url,
460
+ ...(filePartOptions == null ? void 0 : filePartOptions.imageDetail) != null && {
461
+ detail: filePartOptions.imageDetail
462
+ }
463
+ }
464
+ });
465
+ } else {
466
+ warnings.push({
467
+ type: "unsupported",
468
+ feature: `tool result content part type: ${part.type}`
469
+ });
470
+ }
471
+ }
472
+ break;
473
+ }
408
474
  }
409
475
  messages.push({
410
476
  role: "tool",
@@ -925,6 +991,12 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
925
991
  fetch: this.config.fetch
926
992
  });
927
993
  const choice = responseBody.choices[0];
994
+ if (choice == null) {
995
+ throw new InvalidResponseDataError({
996
+ data: rawResponse,
997
+ message: "Response did not contain any choices."
998
+ });
999
+ }
928
1000
  const content = [];
929
1001
  const reasoning = choice.message.reasoning_content;
930
1002
  if (reasoning != null && reasoning.length > 0) {
@@ -1393,7 +1465,7 @@ function hasSupportedFilenameExtension(filename) {
1393
1465
  }
1394
1466
 
1395
1467
  // src/version.ts
1396
- var VERSION = true ? "3.0.48" : "0.0.0-test";
1468
+ var VERSION = true ? "3.0.50" : "0.0.0-test";
1397
1469
 
1398
1470
  // src/deepseek-provider.ts
1399
1471
  function createDeepSeek(options = {}) {