@ai-sdk/deepseek 2.0.56 → 2.0.57

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.
@@ -3,7 +3,11 @@ import type {
3
3
  LanguageModelV3Prompt,
4
4
  SharedV3Warning,
5
5
  } from '@ai-sdk/provider';
6
- import type { DeepSeekChatPrompt } from './deepseek-chat-api-types';
6
+ import { convertToBase64 } from '@ai-sdk/provider-utils';
7
+ import type {
8
+ DeepSeekChatPrompt,
9
+ DeepSeekContentPart,
10
+ } from './deepseek-chat-api-types';
7
11
 
8
12
  export function convertToDeepSeekChatMessages({
9
13
  prompt,
@@ -65,10 +69,51 @@ export function convertToDeepSeekChatMessages({
65
69
  }
66
70
 
67
71
  case 'user': {
68
- let userContent = '';
72
+ const hasImagePart = content.some(
73
+ part =>
74
+ part.type === 'file' &&
75
+ (part.mediaType === 'image' || part.mediaType.startsWith('image/')),
76
+ );
77
+
78
+ if (!hasImagePart) {
79
+ let userContent = '';
80
+ for (const part of content) {
81
+ if (part.type === 'text') {
82
+ userContent += part.text;
83
+ } else {
84
+ warnings.push({
85
+ type: 'unsupported',
86
+ feature: `user message part type: ${part.type}`,
87
+ });
88
+ }
89
+ }
90
+
91
+ messages.push({ role: 'user', content: userContent });
92
+ break;
93
+ }
94
+
95
+ const userContent: Array<DeepSeekContentPart> = [];
69
96
  for (const part of content) {
70
97
  if (part.type === 'text') {
71
- userContent += part.text;
98
+ userContent.push({ type: 'text', text: part.text });
99
+ } else if (
100
+ part.type === 'file' &&
101
+ (part.mediaType === 'image' || part.mediaType.startsWith('image/'))
102
+ ) {
103
+ const mediaType =
104
+ part.mediaType === 'image' || part.mediaType === 'image/*'
105
+ ? 'image/jpeg'
106
+ : part.mediaType;
107
+
108
+ userContent.push({
109
+ type: 'image_url',
110
+ image_url: {
111
+ url:
112
+ part.data instanceof URL
113
+ ? part.data.toString()
114
+ : `data:${mediaType};base64,${convertToBase64(part.data)}`,
115
+ },
116
+ });
72
117
  } else {
73
118
  warnings.push({
74
119
  type: 'unsupported',
@@ -77,10 +122,7 @@ export function convertToDeepSeekChatMessages({
77
122
  }
78
123
  }
79
124
 
80
- messages.push({
81
- role: 'user',
82
- content: userContent,
83
- });
125
+ messages.push({ role: 'user', content: userContent });
84
126
 
85
127
  break;
86
128
  }
@@ -16,7 +16,21 @@ export interface DeepSeekSystemMessage {
16
16
 
17
17
  export interface DeepSeekUserMessage {
18
18
  role: 'user';
19
- content: string;
19
+ content: string | Array<DeepSeekContentPart>;
20
+ }
21
+
22
+ export type DeepSeekContentPart =
23
+ | DeepSeekContentPartText
24
+ | DeepSeekContentPartImage;
25
+
26
+ export interface DeepSeekContentPartText {
27
+ type: 'text';
28
+ text: string;
29
+ }
30
+
31
+ export interface DeepSeekContentPartImage {
32
+ type: 'image_url';
33
+ image_url: { url: string };
20
34
  }
21
35
 
22
36
  export interface DeepSeekAssistantMessage {
@@ -51,7 +51,10 @@ export class DeepSeekChatLanguageModel implements LanguageModelV3 {
51
51
  readonly specificationVersion = 'v3';
52
52
 
53
53
  readonly modelId: DeepSeekChatModelId;
54
- readonly supportedUrls = {};
54
+
55
+ readonly supportedUrls = {
56
+ 'image/*': [/^https?:\/\/.*$/],
57
+ };
55
58
 
56
59
  private readonly config: DeepSeekChatConfig;
57
60
  private readonly failedResponseHandler: ResponseHandler<APICallError>;
@@ -4,6 +4,7 @@ import { z } from 'zod/v4';
4
4
  export type DeepSeekChatModelId =
5
5
  | 'deepseek-chat'
6
6
  | 'deepseek-reasoner'
7
+ | 'deepseek-v4-flash-vision-exp'
7
8
  | (string & {});
8
9
 
9
10
  export const deepseekLanguageModelOptions = z.object({