@ai-sdk/deepseek 3.0.31 → 3.0.32
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 +24 -0
- package/README.md +1 -1
- package/dist/index.d.ts +57 -19
- package/dist/index.js +561 -123
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +54 -4
- package/dist/internal/index.js +455 -108
- package/dist/internal/index.js.map +1 -1
- package/docs/30-deepseek.mdx +306 -23
- package/package.json +6 -6
- package/src/chat/convert-to-deepseek-chat-messages.ts +166 -19
- package/src/chat/convert-to-deepseek-usage.ts +1 -1
- package/src/chat/deepseek-chat-api-types.ts +50 -5
- package/src/chat/deepseek-chat-language-model-options.ts +102 -11
- package/src/chat/deepseek-chat-language-model.ts +193 -19
- package/src/chat/deepseek-file-part-options.ts +24 -0
- package/src/chat/deepseek-prepare-tools.ts +29 -3
- package/src/deepseek-provider.ts +2 -0
- package/src/files/deepseek-files-api.ts +9 -5
- package/src/files/deepseek-files.ts +129 -4
- package/src/index.ts +3 -0
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
generateId,
|
|
18
18
|
isCustomReasoning,
|
|
19
19
|
mapReasoningToProviderEffort,
|
|
20
|
-
parseProviderOptions,
|
|
20
|
+
parseProviderOptions as parseProviderOptions2,
|
|
21
21
|
postJsonToApi,
|
|
22
22
|
serializeModelOptions,
|
|
23
23
|
StreamingToolCallTracker,
|
|
@@ -26,16 +26,113 @@ import {
|
|
|
26
26
|
} from "@ai-sdk/provider-utils";
|
|
27
27
|
|
|
28
28
|
// src/chat/convert-to-deepseek-chat-messages.ts
|
|
29
|
+
import {
|
|
30
|
+
InvalidPromptError,
|
|
31
|
+
UnsupportedFunctionalityError
|
|
32
|
+
} from "@ai-sdk/provider";
|
|
29
33
|
import {
|
|
30
34
|
convertToBase64,
|
|
31
35
|
getTopLevelMediaType,
|
|
36
|
+
parseProviderOptions,
|
|
32
37
|
resolveFullMediaType,
|
|
33
38
|
resolveProviderReference
|
|
34
39
|
} from "@ai-sdk/provider-utils";
|
|
35
|
-
|
|
40
|
+
|
|
41
|
+
// src/chat/deepseek-file-part-options.ts
|
|
42
|
+
import { z } from "zod/v4";
|
|
43
|
+
var deepseekFilePartProviderOptions = z.object({
|
|
44
|
+
/**
|
|
45
|
+
* Controls how DeepSeek processes an image sent as an `image_url` part.
|
|
46
|
+
*
|
|
47
|
+
* @see https://api-docs.deepseek.com/api/create-chat-completion/
|
|
48
|
+
*/
|
|
49
|
+
imageDetail: z.enum(["low", "high", "original", "auto"]).optional(),
|
|
50
|
+
/**
|
|
51
|
+
* Sends inline image data as a DeepSeek `file` part using `file_data`
|
|
52
|
+
* instead of an `image_url` data URL. When set, the file part's filename
|
|
53
|
+
* is preserved.
|
|
54
|
+
*
|
|
55
|
+
* This option only applies to inline image data. It cannot be combined
|
|
56
|
+
* with `imageDetail`.
|
|
57
|
+
*/
|
|
58
|
+
fileData: z.literal(true).optional()
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// src/chat/deepseek-chat-language-model-options.ts
|
|
62
|
+
import { z as z2 } from "zod/v4";
|
|
63
|
+
var deepseekLanguageModelChatOptions = z2.object({
|
|
64
|
+
/**
|
|
65
|
+
* Whether to return log probabilities for generated tokens.
|
|
66
|
+
*/
|
|
67
|
+
logprobs: z2.boolean().optional(),
|
|
68
|
+
/**
|
|
69
|
+
* Number of most likely tokens to return at each token position.
|
|
70
|
+
*
|
|
71
|
+
* Setting this option automatically enables `logprobs`.
|
|
72
|
+
*/
|
|
73
|
+
topLogprobs: z2.number().int().min(0).max(20).optional(),
|
|
74
|
+
/**
|
|
75
|
+
* An opaque identifier for the end user. DeepSeek uses this identifier for
|
|
76
|
+
* content-safety tracing and request isolation.
|
|
77
|
+
*
|
|
78
|
+
* Must contain only ASCII letters, numbers, underscores, and hyphens, and
|
|
79
|
+
* must be at most 512 characters long.
|
|
80
|
+
*/
|
|
81
|
+
userId: z2.string().regex(/^[a-zA-Z0-9_-]+$/, "userId must match /^[a-zA-Z0-9_-]+$/").max(512, "userId must be at most 512 characters long").optional(),
|
|
82
|
+
/**
|
|
83
|
+
* Type of thinking to use. Defaults to `enabled`.
|
|
84
|
+
*/
|
|
85
|
+
thinking: z2.object({
|
|
86
|
+
// `adaptive` is accepted at runtime for backwards compatibility and
|
|
87
|
+
// mapped to `enabled`, but is intentionally excluded from the exported
|
|
88
|
+
// provider options type.
|
|
89
|
+
type: z2.enum(["adaptive", "enabled", "disabled"]).optional()
|
|
90
|
+
}).optional(),
|
|
91
|
+
/**
|
|
92
|
+
* Controls the thinking strength for DeepSeek V4 reasoning models.
|
|
93
|
+
*/
|
|
94
|
+
// `medium` and `xhigh` are accepted at runtime for backwards compatibility
|
|
95
|
+
// and mapped to canonical DeepSeek values, but are intentionally excluded
|
|
96
|
+
// from the exported provider options type.
|
|
97
|
+
reasoningEffort: z2.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
|
|
98
|
+
/**
|
|
99
|
+
* Whether to use strict JSON schema validation for structured outputs.
|
|
100
|
+
* Only applies when the serving endpoint supports JSON schema response
|
|
101
|
+
* formats (e.g. Azure). Defaults to `true`.
|
|
102
|
+
*/
|
|
103
|
+
strictJsonSchema: z2.boolean().optional()
|
|
104
|
+
});
|
|
105
|
+
var deepseekMessageProviderOptions = z2.object({
|
|
106
|
+
/**
|
|
107
|
+
* The name of the participant represented by the message.
|
|
108
|
+
*
|
|
109
|
+
* Supported on system, user, and assistant messages.
|
|
110
|
+
*/
|
|
111
|
+
name: z2.string().optional()
|
|
112
|
+
});
|
|
113
|
+
var deepseekAssistantMessageProviderOptions = deepseekMessageProviderOptions.extend({
|
|
114
|
+
/**
|
|
115
|
+
* Whether the assistant message content is a prefix that DeepSeek should
|
|
116
|
+
* continue. This beta feature is only supported on the final assistant
|
|
117
|
+
* message when using a beta base URL.
|
|
118
|
+
*/
|
|
119
|
+
prefix: z2.literal(true).optional()
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// src/chat/convert-to-deepseek-chat-messages.ts
|
|
123
|
+
var supportedImageMediaTypes = /* @__PURE__ */ new Set([
|
|
124
|
+
"image/gif",
|
|
125
|
+
"image/jpeg",
|
|
126
|
+
"image/jpg",
|
|
127
|
+
"image/png",
|
|
128
|
+
"image/webp"
|
|
129
|
+
]);
|
|
130
|
+
async function convertToDeepSeekChatMessages({
|
|
36
131
|
prompt,
|
|
37
132
|
responseFormat,
|
|
38
133
|
modelId,
|
|
134
|
+
providerOptionsName = "deepseek",
|
|
135
|
+
supportsAssistantPrefixCompletion = false,
|
|
39
136
|
supportsStructuredOutputs = false
|
|
40
137
|
}) {
|
|
41
138
|
var _a;
|
|
@@ -68,11 +165,28 @@ function convertToDeepSeekChatMessages({
|
|
|
68
165
|
}
|
|
69
166
|
}
|
|
70
167
|
let index = -1;
|
|
71
|
-
for (const { role, content } of prompt) {
|
|
168
|
+
for (const { role, content, providerOptions } of prompt) {
|
|
72
169
|
index++;
|
|
170
|
+
const deepseekMessageOptions = await parseProviderOptions({
|
|
171
|
+
provider: providerOptionsName,
|
|
172
|
+
providerOptions,
|
|
173
|
+
schema: deepseekAssistantMessageProviderOptions
|
|
174
|
+
});
|
|
175
|
+
if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true && role !== "assistant") {
|
|
176
|
+
throw new InvalidPromptError({
|
|
177
|
+
prompt,
|
|
178
|
+
message: "DeepSeek assistant prefix completion requires `prefix: true` on an assistant message."
|
|
179
|
+
});
|
|
180
|
+
}
|
|
73
181
|
switch (role) {
|
|
74
182
|
case "system": {
|
|
75
|
-
messages.push({
|
|
183
|
+
messages.push({
|
|
184
|
+
role: "system",
|
|
185
|
+
content,
|
|
186
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
|
|
187
|
+
name: deepseekMessageOptions.name
|
|
188
|
+
}
|
|
189
|
+
});
|
|
76
190
|
break;
|
|
77
191
|
}
|
|
78
192
|
case "user": {
|
|
@@ -91,7 +205,13 @@ function convertToDeepSeekChatMessages({
|
|
|
91
205
|
});
|
|
92
206
|
}
|
|
93
207
|
}
|
|
94
|
-
messages.push({
|
|
208
|
+
messages.push({
|
|
209
|
+
role: "user",
|
|
210
|
+
content: userContent2,
|
|
211
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
|
|
212
|
+
name: deepseekMessageOptions.name
|
|
213
|
+
}
|
|
214
|
+
});
|
|
95
215
|
break;
|
|
96
216
|
}
|
|
97
217
|
const userContent = [];
|
|
@@ -99,6 +219,11 @@ function convertToDeepSeekChatMessages({
|
|
|
99
219
|
if (part.type === "text") {
|
|
100
220
|
userContent.push({ type: "text", text: part.text });
|
|
101
221
|
} else if (part.type === "file" && getTopLevelMediaType(part.mediaType) === "image") {
|
|
222
|
+
const filePartOptions = await parseProviderOptions({
|
|
223
|
+
provider: providerOptionsName,
|
|
224
|
+
providerOptions: part.providerOptions,
|
|
225
|
+
schema: deepseekFilePartProviderOptions
|
|
226
|
+
});
|
|
102
227
|
if (part.data.type === "reference") {
|
|
103
228
|
userContent.push({
|
|
104
229
|
type: "file",
|
|
@@ -108,12 +233,62 @@ function convertToDeepSeekChatMessages({
|
|
|
108
233
|
})
|
|
109
234
|
});
|
|
110
235
|
} else if (part.data.type === "url" || part.data.type === "data") {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
236
|
+
const resolvedMediaType = resolveFullMediaType({ part });
|
|
237
|
+
if (!supportedImageMediaTypes.has(resolvedMediaType)) {
|
|
238
|
+
throw new UnsupportedFunctionalityError({
|
|
239
|
+
functionality: `DeepSeek image media type ${resolvedMediaType}`,
|
|
240
|
+
message: "DeepSeek supports JPEG, PNG, GIF, and WebP image inputs."
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (part.data.type === "url") {
|
|
244
|
+
const url = part.data.url.toString();
|
|
245
|
+
if (url.length > 8192) {
|
|
246
|
+
throw new InvalidPromptError({
|
|
247
|
+
prompt,
|
|
248
|
+
message: "DeepSeek image URLs must not exceed 8192 characters."
|
|
249
|
+
});
|
|
115
250
|
}
|
|
116
|
-
|
|
251
|
+
if ((filePartOptions == null ? void 0 : filePartOptions.fileData) === true) {
|
|
252
|
+
throw new InvalidPromptError({
|
|
253
|
+
prompt,
|
|
254
|
+
message: "DeepSeek `fileData` image parts require inline data, not a URL."
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
userContent.push({
|
|
258
|
+
type: "image_url",
|
|
259
|
+
image_url: {
|
|
260
|
+
url,
|
|
261
|
+
...(filePartOptions == null ? void 0 : filePartOptions.imageDetail) != null && {
|
|
262
|
+
detail: filePartOptions.imageDetail
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
} else {
|
|
267
|
+
const dataUrl = `data:${resolvedMediaType === "image/jpg" ? "image/jpeg" : resolvedMediaType};base64,${convertToBase64(part.data.data)}`;
|
|
268
|
+
if ((filePartOptions == null ? void 0 : filePartOptions.fileData) === true) {
|
|
269
|
+
if (filePartOptions.imageDetail != null) {
|
|
270
|
+
throw new InvalidPromptError({
|
|
271
|
+
prompt,
|
|
272
|
+
message: "DeepSeek `imageDetail` cannot be combined with `fileData`."
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
userContent.push({
|
|
276
|
+
type: "file",
|
|
277
|
+
file_data: dataUrl,
|
|
278
|
+
...part.filename != null && { filename: part.filename }
|
|
279
|
+
});
|
|
280
|
+
} else {
|
|
281
|
+
userContent.push({
|
|
282
|
+
type: "image_url",
|
|
283
|
+
image_url: {
|
|
284
|
+
url: dataUrl,
|
|
285
|
+
...(filePartOptions == null ? void 0 : filePartOptions.imageDetail) != null && {
|
|
286
|
+
detail: filePartOptions.imageDetail
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
117
292
|
} else {
|
|
118
293
|
warnings.push({
|
|
119
294
|
type: "unsupported",
|
|
@@ -129,11 +304,28 @@ function convertToDeepSeekChatMessages({
|
|
|
129
304
|
}
|
|
130
305
|
messages.push({
|
|
131
306
|
role: "user",
|
|
132
|
-
content: userContent
|
|
307
|
+
content: userContent,
|
|
308
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
|
|
309
|
+
name: deepseekMessageOptions.name
|
|
310
|
+
}
|
|
133
311
|
});
|
|
134
312
|
break;
|
|
135
313
|
}
|
|
136
314
|
case "assistant": {
|
|
315
|
+
if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true) {
|
|
316
|
+
if (index !== prompt.length - 1) {
|
|
317
|
+
throw new InvalidPromptError({
|
|
318
|
+
prompt,
|
|
319
|
+
message: "DeepSeek assistant prefix completion requires the prefixed assistant message to be the final message."
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
if (!supportsAssistantPrefixCompletion) {
|
|
323
|
+
throw new UnsupportedFunctionalityError({
|
|
324
|
+
functionality: "DeepSeek assistant prefix completion",
|
|
325
|
+
message: "DeepSeek assistant prefix completion requires a beta base URL ending in `/beta`."
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|
|
137
329
|
let text = "";
|
|
138
330
|
let reasoning;
|
|
139
331
|
const toolCalls = [];
|
|
@@ -170,12 +362,24 @@ function convertToDeepSeekChatMessages({
|
|
|
170
362
|
messages.push({
|
|
171
363
|
role: "assistant",
|
|
172
364
|
content: text,
|
|
365
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
|
|
366
|
+
name: deepseekMessageOptions.name
|
|
367
|
+
},
|
|
368
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true && {
|
|
369
|
+
prefix: true
|
|
370
|
+
},
|
|
173
371
|
reasoning_content: reasoning != null ? reasoning : isDeepSeekV4 ? "" : void 0,
|
|
174
372
|
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
|
|
175
373
|
});
|
|
176
374
|
break;
|
|
177
375
|
}
|
|
178
376
|
case "tool": {
|
|
377
|
+
if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null) {
|
|
378
|
+
warnings.push({
|
|
379
|
+
type: "unsupported",
|
|
380
|
+
feature: "message name on tool messages"
|
|
381
|
+
});
|
|
382
|
+
}
|
|
179
383
|
for (const toolResponse of content) {
|
|
180
384
|
if (toolResponse.type === "tool-approval-response") {
|
|
181
385
|
continue;
|
|
@@ -236,7 +440,7 @@ function convertDeepSeekUsage(usage) {
|
|
|
236
440
|
},
|
|
237
441
|
outputTokens: {
|
|
238
442
|
total: completionTokens,
|
|
239
|
-
text: completionTokens - reasoningTokens,
|
|
443
|
+
text: Math.max(0, completionTokens - reasoningTokens),
|
|
240
444
|
reasoning: reasoningTokens
|
|
241
445
|
},
|
|
242
446
|
raw: usage
|
|
@@ -245,75 +449,101 @@ function convertDeepSeekUsage(usage) {
|
|
|
245
449
|
|
|
246
450
|
// src/chat/deepseek-chat-api-types.ts
|
|
247
451
|
import { lazySchema, zodSchema } from "@ai-sdk/provider-utils";
|
|
248
|
-
import { z } from "zod/v4";
|
|
249
|
-
var tokenUsageSchema =
|
|
250
|
-
prompt_tokens:
|
|
251
|
-
completion_tokens:
|
|
252
|
-
prompt_cache_hit_tokens:
|
|
253
|
-
prompt_cache_miss_tokens:
|
|
254
|
-
total_tokens:
|
|
255
|
-
completion_tokens_details:
|
|
256
|
-
reasoning_tokens:
|
|
452
|
+
import { z as z3 } from "zod/v4";
|
|
453
|
+
var tokenUsageSchema = z3.object({
|
|
454
|
+
prompt_tokens: z3.number().nullish(),
|
|
455
|
+
completion_tokens: z3.number().nullish(),
|
|
456
|
+
prompt_cache_hit_tokens: z3.number().nullish(),
|
|
457
|
+
prompt_cache_miss_tokens: z3.number().nullish(),
|
|
458
|
+
total_tokens: z3.number().nullish(),
|
|
459
|
+
completion_tokens_details: z3.object({
|
|
460
|
+
reasoning_tokens: z3.number().nullish()
|
|
257
461
|
}).nullish()
|
|
258
462
|
}).nullish();
|
|
259
|
-
var deepSeekErrorSchema =
|
|
260
|
-
error:
|
|
261
|
-
message:
|
|
262
|
-
type:
|
|
263
|
-
param:
|
|
264
|
-
code:
|
|
463
|
+
var deepSeekErrorSchema = z3.object({
|
|
464
|
+
error: z3.object({
|
|
465
|
+
message: z3.string(),
|
|
466
|
+
type: z3.string().nullish(),
|
|
467
|
+
param: z3.any().nullish(),
|
|
468
|
+
code: z3.union([z3.string(), z3.number()]).nullish()
|
|
265
469
|
})
|
|
266
470
|
});
|
|
267
|
-
var
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
471
|
+
var deepseekChatLogprobSchema = z3.object({
|
|
472
|
+
token: z3.string(),
|
|
473
|
+
logprob: z3.number(),
|
|
474
|
+
bytes: z3.array(z3.number()).nullable(),
|
|
475
|
+
top_logprobs: z3.array(
|
|
476
|
+
z3.object({
|
|
477
|
+
token: z3.string(),
|
|
478
|
+
logprob: z3.number(),
|
|
479
|
+
bytes: z3.array(z3.number()).nullable()
|
|
480
|
+
})
|
|
481
|
+
)
|
|
482
|
+
});
|
|
483
|
+
var deepseekChatLogprobsSchema = z3.object({
|
|
484
|
+
content: z3.array(deepseekChatLogprobSchema).nullish(),
|
|
485
|
+
reasoning_content: z3.array(deepseekChatLogprobSchema).nullish()
|
|
486
|
+
}).nullish();
|
|
487
|
+
var deepseekChatResponseSchema = z3.object({
|
|
488
|
+
id: z3.string().nullish(),
|
|
489
|
+
created: z3.number().nullish(),
|
|
490
|
+
model: z3.string().nullish(),
|
|
491
|
+
object: z3.literal("chat.completion").nullish(),
|
|
492
|
+
system_fingerprint: z3.string().nullish(),
|
|
493
|
+
choices: z3.array(
|
|
494
|
+
z3.object({
|
|
495
|
+
index: z3.number().nullish(),
|
|
496
|
+
message: z3.object({
|
|
497
|
+
role: z3.literal("assistant").nullish(),
|
|
498
|
+
content: z3.string().nullish(),
|
|
499
|
+
reasoning_content: z3.string().nullish(),
|
|
500
|
+
tool_calls: z3.array(
|
|
501
|
+
z3.object({
|
|
502
|
+
id: z3.string().nullish(),
|
|
503
|
+
type: z3.literal("function").nullish(),
|
|
504
|
+
function: z3.object({
|
|
505
|
+
name: z3.string(),
|
|
506
|
+
arguments: z3.string()
|
|
283
507
|
})
|
|
284
508
|
})
|
|
285
509
|
).nullish()
|
|
286
510
|
}),
|
|
287
|
-
|
|
511
|
+
logprobs: deepseekChatLogprobsSchema,
|
|
512
|
+
finish_reason: z3.string().nullish()
|
|
288
513
|
})
|
|
289
514
|
),
|
|
290
515
|
usage: tokenUsageSchema
|
|
291
516
|
});
|
|
292
517
|
var deepseekChatChunkSchema = lazySchema(
|
|
293
518
|
() => zodSchema(
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
id:
|
|
297
|
-
created:
|
|
298
|
-
model:
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
519
|
+
z3.union([
|
|
520
|
+
z3.object({
|
|
521
|
+
id: z3.string().nullish(),
|
|
522
|
+
created: z3.number().nullish(),
|
|
523
|
+
model: z3.string().nullish(),
|
|
524
|
+
object: z3.literal("chat.completion.chunk").nullish(),
|
|
525
|
+
system_fingerprint: z3.string().nullish(),
|
|
526
|
+
choices: z3.array(
|
|
527
|
+
z3.object({
|
|
528
|
+
index: z3.number().nullish(),
|
|
529
|
+
delta: z3.object({
|
|
530
|
+
role: z3.enum(["assistant"]).nullish(),
|
|
531
|
+
content: z3.string().nullish(),
|
|
532
|
+
reasoning_content: z3.string().nullish(),
|
|
533
|
+
tool_calls: z3.array(
|
|
534
|
+
z3.object({
|
|
535
|
+
index: z3.number(),
|
|
536
|
+
id: z3.string().nullish(),
|
|
537
|
+
type: z3.literal("function").nullish(),
|
|
538
|
+
function: z3.object({
|
|
539
|
+
name: z3.string().nullish(),
|
|
540
|
+
arguments: z3.string().nullish()
|
|
312
541
|
})
|
|
313
542
|
})
|
|
314
543
|
).nullish()
|
|
315
544
|
}).nullish(),
|
|
316
|
-
|
|
545
|
+
logprobs: deepseekChatLogprobsSchema,
|
|
546
|
+
finish_reason: z3.string().nullish()
|
|
317
547
|
})
|
|
318
548
|
),
|
|
319
549
|
usage: tokenUsageSchema
|
|
@@ -323,44 +553,34 @@ var deepseekChatChunkSchema = lazySchema(
|
|
|
323
553
|
)
|
|
324
554
|
);
|
|
325
555
|
|
|
326
|
-
// src/chat/deepseek-chat-language-model-options.ts
|
|
327
|
-
import { z as z2 } from "zod/v4";
|
|
328
|
-
var deepseekLanguageModelChatOptions = z2.object({
|
|
329
|
-
/**
|
|
330
|
-
* Type of thinking to use. Defaults to `enabled`.
|
|
331
|
-
*
|
|
332
|
-
* See https://api-docs.deepseek.com/guides/thinking_mode for the
|
|
333
|
-
* `adaptive` option, which lets the model decide when to think.
|
|
334
|
-
*/
|
|
335
|
-
thinking: z2.object({
|
|
336
|
-
type: z2.enum(["adaptive", "enabled", "disabled"]).optional()
|
|
337
|
-
}).optional(),
|
|
338
|
-
/**
|
|
339
|
-
* Controls the thinking strength for DeepSeek V4 reasoning models.
|
|
340
|
-
*
|
|
341
|
-
* DeepSeek's API accepts `low`, `medium`, `high`, `xhigh`, and `max`.
|
|
342
|
-
* Per their docs, `low` and `medium` are mapped to `high`, and `xhigh`
|
|
343
|
-
* is mapped to `max` server-side for compatibility with other providers.
|
|
344
|
-
*/
|
|
345
|
-
reasoningEffort: z2.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
|
|
346
|
-
/**
|
|
347
|
-
* Whether to use strict JSON schema validation for structured outputs.
|
|
348
|
-
* Only applies when the serving endpoint supports JSON schema response
|
|
349
|
-
* formats (e.g. Azure). Defaults to `true`.
|
|
350
|
-
*/
|
|
351
|
-
strictJsonSchema: z2.boolean().optional()
|
|
352
|
-
});
|
|
353
|
-
|
|
354
556
|
// src/chat/deepseek-prepare-tools.ts
|
|
557
|
+
import {
|
|
558
|
+
UnsupportedFunctionalityError as UnsupportedFunctionalityError2
|
|
559
|
+
} from "@ai-sdk/provider";
|
|
355
560
|
function prepareTools({
|
|
356
561
|
tools,
|
|
357
|
-
toolChoice
|
|
562
|
+
toolChoice,
|
|
563
|
+
supportsStrictToolCalls
|
|
358
564
|
}) {
|
|
359
565
|
tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
|
|
360
566
|
const toolWarnings = [];
|
|
361
567
|
if (tools == null) {
|
|
362
568
|
return { tools: void 0, toolChoice: void 0, toolWarnings };
|
|
363
569
|
}
|
|
570
|
+
const functionTools = tools.filter((tool) => tool.type === "function");
|
|
571
|
+
const hasStrictTool = functionTools.some((tool) => tool.strict === true);
|
|
572
|
+
if (hasStrictTool && supportsStrictToolCalls === false) {
|
|
573
|
+
throw new UnsupportedFunctionalityError2({
|
|
574
|
+
functionality: "DeepSeek strict tool calls",
|
|
575
|
+
message: "DeepSeek strict tool calls require a beta base URL ending in `/beta`."
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
if (hasStrictTool && supportsStrictToolCalls === true && functionTools.some((tool) => tool.strict !== true)) {
|
|
579
|
+
throw new UnsupportedFunctionalityError2({
|
|
580
|
+
functionality: "mixed DeepSeek strict and non-strict tool calls",
|
|
581
|
+
message: "DeepSeek strict mode requires every function tool in the request to set `strict: true`."
|
|
582
|
+
});
|
|
583
|
+
}
|
|
364
584
|
const deepseekTools = [];
|
|
365
585
|
for (const tool of tools) {
|
|
366
586
|
if (tool.type === "provider") {
|
|
@@ -436,6 +656,20 @@ function mapDeepSeekFinishReason(finishReason) {
|
|
|
436
656
|
}
|
|
437
657
|
|
|
438
658
|
// src/chat/deepseek-chat-language-model.ts
|
|
659
|
+
function mapDeepSeekProviderReasoningEffort({
|
|
660
|
+
reasoningEffort,
|
|
661
|
+
warnings
|
|
662
|
+
}) {
|
|
663
|
+
const mapped = reasoningEffort === "medium" ? "high" : reasoningEffort === "xhigh" ? "max" : reasoningEffort;
|
|
664
|
+
if (mapped !== reasoningEffort) {
|
|
665
|
+
warnings.push({
|
|
666
|
+
type: "compatibility",
|
|
667
|
+
feature: "reasoningEffort",
|
|
668
|
+
details: `reasoningEffort "${reasoningEffort}" is not a canonical DeepSeek value. mapped to "${mapped}".`
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
return mapped;
|
|
672
|
+
}
|
|
439
673
|
var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
440
674
|
constructor(modelId, config) {
|
|
441
675
|
this.specificationVersion = "v4";
|
|
@@ -480,17 +714,20 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
480
714
|
toolChoice,
|
|
481
715
|
tools
|
|
482
716
|
}) {
|
|
483
|
-
var _a, _b, _c, _d
|
|
484
|
-
const deepseekOptions = (_a = await
|
|
717
|
+
var _a, _b, _c, _d;
|
|
718
|
+
const deepseekOptions = (_a = await parseProviderOptions2({
|
|
485
719
|
provider: this.providerOptionsName,
|
|
486
720
|
providerOptions,
|
|
487
721
|
schema: deepseekLanguageModelChatOptions
|
|
488
722
|
})) != null ? _a : {};
|
|
489
723
|
const supportsStructuredOutputs = this.config.supportsStructuredOutputs === true;
|
|
490
|
-
const
|
|
724
|
+
const supportsPenaltySampling = this.config.supportsPenaltySampling === true;
|
|
725
|
+
const { messages, warnings } = await convertToDeepSeekChatMessages({
|
|
491
726
|
prompt,
|
|
492
727
|
responseFormat,
|
|
493
728
|
modelId: this.modelId,
|
|
729
|
+
providerOptionsName: this.providerOptionsName,
|
|
730
|
+
supportsAssistantPrefixCompletion: this.config.supportsAssistantPrefixCompletion,
|
|
494
731
|
supportsStructuredOutputs
|
|
495
732
|
});
|
|
496
733
|
const allWarnings = [...warnings];
|
|
@@ -500,21 +737,62 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
500
737
|
if (seed != null) {
|
|
501
738
|
allWarnings.push({ type: "unsupported", feature: "seed" });
|
|
502
739
|
}
|
|
740
|
+
if (!supportsPenaltySampling && frequencyPenalty != null) {
|
|
741
|
+
allWarnings.push({
|
|
742
|
+
type: "deprecated",
|
|
743
|
+
setting: "frequencyPenalty",
|
|
744
|
+
message: "frequencyPenalty is deprecated by DeepSeek and has been omitted. Remove frequencyPenalty from the request."
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
if (!supportsPenaltySampling && presencePenalty != null) {
|
|
748
|
+
allWarnings.push({
|
|
749
|
+
type: "deprecated",
|
|
750
|
+
setting: "presencePenalty",
|
|
751
|
+
message: "presencePenalty is deprecated by DeepSeek and has been omitted. Remove presencePenalty from the request."
|
|
752
|
+
});
|
|
753
|
+
}
|
|
503
754
|
const {
|
|
504
755
|
tools: deepseekTools,
|
|
505
756
|
toolChoice: deepseekToolChoices,
|
|
506
757
|
toolWarnings
|
|
507
758
|
} = prepareTools({
|
|
508
759
|
tools,
|
|
509
|
-
toolChoice
|
|
760
|
+
toolChoice,
|
|
761
|
+
supportsStrictToolCalls: this.config.supportsStrictToolCalls
|
|
510
762
|
});
|
|
511
|
-
const
|
|
512
|
-
|
|
763
|
+
const thinkingType = (_b = deepseekOptions.thinking) == null ? void 0 : _b.type;
|
|
764
|
+
if (thinkingType === "adaptive") {
|
|
765
|
+
allWarnings.push({
|
|
766
|
+
type: "compatibility",
|
|
767
|
+
feature: "thinking.type",
|
|
768
|
+
details: 'thinking.type "adaptive" is not a canonical DeepSeek value. mapped to "enabled".'
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
const thinking = this.config.supportsThinking === false ? void 0 : thinkingType != null ? { type: thinkingType === "adaptive" ? "enabled" : thinkingType } : isCustomReasoning(reasoning) ? { type: reasoning === "none" ? "disabled" : "enabled" } : void 0;
|
|
772
|
+
const isThinkingEnabled = this.config.supportsThinking !== false && (thinking == null ? void 0 : thinking.type) !== "disabled" && (thinking != null || this.modelId === "deepseek-reasoner" || this.modelId.includes("deepseek-v4"));
|
|
773
|
+
if (isThinkingEnabled && temperature != null) {
|
|
774
|
+
allWarnings.push({
|
|
775
|
+
type: "unsupported",
|
|
776
|
+
feature: "temperature",
|
|
777
|
+
details: "temperature has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use temperature."
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
if (isThinkingEnabled && topP != null) {
|
|
781
|
+
allWarnings.push({
|
|
782
|
+
type: "unsupported",
|
|
783
|
+
feature: "topP",
|
|
784
|
+
details: "topP has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use topP."
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
const reasoningEffort = deepseekOptions.reasoningEffort != null ? mapDeepSeekProviderReasoningEffort({
|
|
788
|
+
reasoningEffort: deepseekOptions.reasoningEffort,
|
|
789
|
+
warnings: allWarnings
|
|
790
|
+
}) : isCustomReasoning(reasoning) && reasoning !== "none" ? mapReasoningToProviderEffort({
|
|
513
791
|
reasoning,
|
|
514
792
|
effortMap: {
|
|
515
793
|
minimal: "low",
|
|
516
794
|
low: "low",
|
|
517
|
-
medium: "
|
|
795
|
+
medium: "high",
|
|
518
796
|
high: "high",
|
|
519
797
|
xhigh: "max"
|
|
520
798
|
},
|
|
@@ -523,17 +801,21 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
523
801
|
return {
|
|
524
802
|
args: {
|
|
525
803
|
model: this.modelId,
|
|
804
|
+
...(deepseekOptions.logprobs === true || deepseekOptions.topLogprobs != null) && { logprobs: true },
|
|
805
|
+
...deepseekOptions.topLogprobs != null && {
|
|
806
|
+
top_logprobs: deepseekOptions.topLogprobs
|
|
807
|
+
},
|
|
526
808
|
max_tokens: maxOutputTokens,
|
|
527
|
-
temperature,
|
|
528
|
-
top_p: topP,
|
|
529
|
-
frequency_penalty: frequencyPenalty,
|
|
530
|
-
presence_penalty: presencePenalty,
|
|
809
|
+
temperature: isThinkingEnabled ? void 0 : temperature,
|
|
810
|
+
top_p: isThinkingEnabled ? void 0 : topP,
|
|
811
|
+
frequency_penalty: supportsPenaltySampling ? frequencyPenalty : void 0,
|
|
812
|
+
presence_penalty: supportsPenaltySampling ? presencePenalty : void 0,
|
|
531
813
|
response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? supportsStructuredOutputs && responseFormat.schema != null ? {
|
|
532
814
|
type: "json_schema",
|
|
533
815
|
json_schema: {
|
|
534
816
|
schema: responseFormat.schema,
|
|
535
|
-
strict: (
|
|
536
|
-
name: (
|
|
817
|
+
strict: (_c = deepseekOptions.strictJsonSchema) != null ? _c : true,
|
|
818
|
+
name: (_d = responseFormat.name) != null ? _d : "response",
|
|
537
819
|
description: responseFormat.description
|
|
538
820
|
}
|
|
539
821
|
} : { type: "json_object" } : void 0,
|
|
@@ -542,6 +824,9 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
542
824
|
tools: deepseekTools,
|
|
543
825
|
tool_choice: deepseekToolChoices,
|
|
544
826
|
thinking,
|
|
827
|
+
...deepseekOptions.userId != null && {
|
|
828
|
+
user_id: deepseekOptions.userId
|
|
829
|
+
},
|
|
545
830
|
...(thinking == null ? void 0 : thinking.type) !== "disabled" && reasoningEffort != null && {
|
|
546
831
|
reasoning_effort: reasoningEffort
|
|
547
832
|
}
|
|
@@ -603,7 +888,21 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
603
888
|
providerMetadata: {
|
|
604
889
|
[this.providerOptionsName]: {
|
|
605
890
|
promptCacheHitTokens: (_d = responseBody.usage) == null ? void 0 : _d.prompt_cache_hit_tokens,
|
|
606
|
-
promptCacheMissTokens: (_e = responseBody.usage) == null ? void 0 : _e.prompt_cache_miss_tokens
|
|
891
|
+
promptCacheMissTokens: (_e = responseBody.usage) == null ? void 0 : _e.prompt_cache_miss_tokens,
|
|
892
|
+
...responseBody.object != null && {
|
|
893
|
+
responseObject: responseBody.object
|
|
894
|
+
},
|
|
895
|
+
...choice.index != null && { choiceIndex: choice.index },
|
|
896
|
+
...choice.message.role != null && {
|
|
897
|
+
messageRole: choice.message.role
|
|
898
|
+
},
|
|
899
|
+
...choice.message.tool_calls != null && {
|
|
900
|
+
toolCallTypes: choice.message.tool_calls.map((toolCall) => toolCall.type).filter((type) => type != null)
|
|
901
|
+
},
|
|
902
|
+
...choice.logprobs != null && { logprobs: choice.logprobs },
|
|
903
|
+
...responseBody.system_fingerprint != null && {
|
|
904
|
+
systemFingerprint: responseBody.system_fingerprint
|
|
905
|
+
}
|
|
607
906
|
}
|
|
608
907
|
},
|
|
609
908
|
request: { body: args },
|
|
@@ -643,10 +942,17 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
643
942
|
raw: void 0
|
|
644
943
|
};
|
|
645
944
|
let usage = void 0;
|
|
945
|
+
let systemFingerprint = void 0;
|
|
646
946
|
let isFirstChunk = true;
|
|
647
947
|
const providerOptionsName = this.providerOptionsName;
|
|
648
948
|
let isActiveReasoning = false;
|
|
649
949
|
let isActiveText = false;
|
|
950
|
+
let responseObject;
|
|
951
|
+
let choiceIndex;
|
|
952
|
+
let messageRole;
|
|
953
|
+
const toolCallTypes = /* @__PURE__ */ new Map();
|
|
954
|
+
const contentLogprobs = [];
|
|
955
|
+
const reasoningLogprobs = [];
|
|
650
956
|
return {
|
|
651
957
|
stream: response.pipeThrough(
|
|
652
958
|
new TransformStream({
|
|
@@ -657,6 +963,7 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
657
963
|
controller.enqueue({ type: "stream-start", warnings });
|
|
658
964
|
},
|
|
659
965
|
transform(chunk, controller) {
|
|
966
|
+
var _a2, _b2;
|
|
660
967
|
if (options.includeRawChunks) {
|
|
661
968
|
controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
|
|
662
969
|
}
|
|
@@ -681,17 +988,35 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
681
988
|
if (value.usage != null) {
|
|
682
989
|
usage = value.usage;
|
|
683
990
|
}
|
|
991
|
+
if (value.object != null) {
|
|
992
|
+
responseObject = value.object;
|
|
993
|
+
}
|
|
994
|
+
if (value.system_fingerprint != null) {
|
|
995
|
+
systemFingerprint = value.system_fingerprint;
|
|
996
|
+
}
|
|
684
997
|
const choice = value.choices[0];
|
|
998
|
+
if ((choice == null ? void 0 : choice.index) != null) {
|
|
999
|
+
choiceIndex = choice.index;
|
|
1000
|
+
}
|
|
685
1001
|
if ((choice == null ? void 0 : choice.finish_reason) != null) {
|
|
686
1002
|
finishReason = {
|
|
687
1003
|
unified: mapDeepSeekFinishReason(choice.finish_reason),
|
|
688
1004
|
raw: choice.finish_reason
|
|
689
1005
|
};
|
|
690
1006
|
}
|
|
1007
|
+
if (((_a2 = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _a2.content) != null) {
|
|
1008
|
+
contentLogprobs.push(...choice.logprobs.content);
|
|
1009
|
+
}
|
|
1010
|
+
if (((_b2 = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _b2.reasoning_content) != null) {
|
|
1011
|
+
reasoningLogprobs.push(...choice.logprobs.reasoning_content);
|
|
1012
|
+
}
|
|
691
1013
|
if ((choice == null ? void 0 : choice.delta) == null) {
|
|
692
1014
|
return;
|
|
693
1015
|
}
|
|
694
1016
|
const delta = choice.delta;
|
|
1017
|
+
if (delta.role != null) {
|
|
1018
|
+
messageRole = delta.role;
|
|
1019
|
+
}
|
|
695
1020
|
const reasoningContent = delta.reasoning_content;
|
|
696
1021
|
if (reasoningContent) {
|
|
697
1022
|
if (!isActiveReasoning) {
|
|
@@ -734,6 +1059,9 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
734
1059
|
isActiveReasoning = false;
|
|
735
1060
|
}
|
|
736
1061
|
for (const toolCallDelta of delta.tool_calls) {
|
|
1062
|
+
if (toolCallDelta.type != null) {
|
|
1063
|
+
toolCallTypes.set(toolCallDelta.index, toolCallDelta.type);
|
|
1064
|
+
}
|
|
737
1065
|
toolCallTracker.processDelta(toolCallDelta);
|
|
738
1066
|
}
|
|
739
1067
|
}
|
|
@@ -754,7 +1082,24 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
754
1082
|
providerMetadata: {
|
|
755
1083
|
[providerOptionsName]: {
|
|
756
1084
|
promptCacheHitTokens: (_a2 = usage == null ? void 0 : usage.prompt_cache_hit_tokens) != null ? _a2 : void 0,
|
|
757
|
-
promptCacheMissTokens: (_b2 = usage == null ? void 0 : usage.prompt_cache_miss_tokens) != null ? _b2 : void 0
|
|
1085
|
+
promptCacheMissTokens: (_b2 = usage == null ? void 0 : usage.prompt_cache_miss_tokens) != null ? _b2 : void 0,
|
|
1086
|
+
...responseObject != null && { responseObject },
|
|
1087
|
+
...choiceIndex != null && { choiceIndex },
|
|
1088
|
+
...messageRole != null && { messageRole },
|
|
1089
|
+
...toolCallTypes.size > 0 && {
|
|
1090
|
+
toolCallTypes: [...toolCallTypes.entries()].sort(([left], [right]) => left - right).map(([, type]) => type)
|
|
1091
|
+
},
|
|
1092
|
+
...(contentLogprobs.length > 0 || reasoningLogprobs.length > 0) && {
|
|
1093
|
+
logprobs: {
|
|
1094
|
+
...contentLogprobs.length > 0 && {
|
|
1095
|
+
content: contentLogprobs
|
|
1096
|
+
},
|
|
1097
|
+
...reasoningLogprobs.length > 0 && {
|
|
1098
|
+
reasoning_content: reasoningLogprobs
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
},
|
|
1102
|
+
...systemFingerprint != null && { systemFingerprint }
|
|
758
1103
|
}
|
|
759
1104
|
}
|
|
760
1105
|
});
|
|
@@ -768,28 +1113,36 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
|
|
|
768
1113
|
};
|
|
769
1114
|
|
|
770
1115
|
// src/files/deepseek-files.ts
|
|
1116
|
+
import {
|
|
1117
|
+
InvalidArgumentError
|
|
1118
|
+
} from "@ai-sdk/provider";
|
|
771
1119
|
import {
|
|
772
1120
|
combineHeaders as combineHeaders2,
|
|
773
1121
|
convertInlineFileDataToUint8Array,
|
|
774
1122
|
createJsonErrorResponseHandler as createJsonErrorResponseHandler2,
|
|
775
1123
|
createJsonResponseHandler as createJsonResponseHandler2,
|
|
776
|
-
|
|
1124
|
+
detectMediaType,
|
|
1125
|
+
parseProviderOptions as parseProviderOptions3,
|
|
777
1126
|
postFormDataToApi
|
|
778
1127
|
} from "@ai-sdk/provider-utils";
|
|
779
1128
|
|
|
780
1129
|
// src/files/deepseek-files-api.ts
|
|
781
1130
|
import { lazySchema as lazySchema2, zodSchema as zodSchema2 } from "@ai-sdk/provider-utils";
|
|
782
|
-
import { z as
|
|
1131
|
+
import { z as z4 } from "zod/v4";
|
|
783
1132
|
var deepSeekFilesResponseSchema = lazySchema2(
|
|
784
1133
|
() => zodSchema2(
|
|
785
|
-
|
|
786
|
-
id:
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
1134
|
+
z4.object({
|
|
1135
|
+
id: z4.string(),
|
|
1136
|
+
// These fields are required by DeepSeek's OpenAPI schema, but they are
|
|
1137
|
+
// not needed to construct the provider reference. Keep them nullish so
|
|
1138
|
+
// uploads remain resilient to incomplete responses while validating any
|
|
1139
|
+
// returned values precisely enough to avoid misleading metadata.
|
|
1140
|
+
object: z4.literal("file").nullish(),
|
|
1141
|
+
bytes: z4.number().int().nonnegative().nullish(),
|
|
1142
|
+
created_at: z4.number().int().nonnegative().nullish(),
|
|
1143
|
+
filename: z4.string().nullish(),
|
|
1144
|
+
purpose: z4.literal("user_data").nullish(),
|
|
1145
|
+
expires_at: z4.number().int().nonnegative().nullish()
|
|
793
1146
|
})
|
|
794
1147
|
)
|
|
795
1148
|
);
|
|
@@ -799,15 +1152,15 @@ import {
|
|
|
799
1152
|
lazySchema as lazySchema3,
|
|
800
1153
|
zodSchema as zodSchema3
|
|
801
1154
|
} from "@ai-sdk/provider-utils";
|
|
802
|
-
import { z as
|
|
1155
|
+
import { z as z5 } from "zod/v4";
|
|
803
1156
|
var deepSeekFilesOptionsSchema = lazySchema3(
|
|
804
1157
|
() => zodSchema3(
|
|
805
|
-
|
|
1158
|
+
z5.object({
|
|
806
1159
|
/**
|
|
807
1160
|
* Number of seconds after creation before the file expires.
|
|
808
1161
|
* Must be between 1 hour and 30 days.
|
|
809
1162
|
*/
|
|
810
|
-
expiresAfter:
|
|
1163
|
+
expiresAfter: z5.number().int().min(3600).max(2592e3).optional()
|
|
811
1164
|
})
|
|
812
1165
|
)
|
|
813
1166
|
);
|
|
@@ -817,6 +1170,30 @@ var deepSeekFailedResponseHandler = createJsonErrorResponseHandler2({
|
|
|
817
1170
|
errorSchema: deepSeekErrorSchema,
|
|
818
1171
|
errorToMessage: (error) => error.error.message
|
|
819
1172
|
});
|
|
1173
|
+
var MAX_FILE_SIZE_BYTES = 64 * 1024 * 1024;
|
|
1174
|
+
var MAX_FILENAME_LENGTH = 512;
|
|
1175
|
+
var supportedMediaTypes = /* @__PURE__ */ new Set([
|
|
1176
|
+
"image/gif",
|
|
1177
|
+
"image/jpeg",
|
|
1178
|
+
"image/jpg",
|
|
1179
|
+
"image/png",
|
|
1180
|
+
"image/webp"
|
|
1181
|
+
]);
|
|
1182
|
+
var genericMediaTypes = /* @__PURE__ */ new Set([
|
|
1183
|
+
"",
|
|
1184
|
+
"application/binary",
|
|
1185
|
+
"application/octet-stream",
|
|
1186
|
+
"binary/octet-stream",
|
|
1187
|
+
"image",
|
|
1188
|
+
"image/*"
|
|
1189
|
+
]);
|
|
1190
|
+
var supportedFilenameExtensions = /* @__PURE__ */ new Set([
|
|
1191
|
+
"gif",
|
|
1192
|
+
"jpeg",
|
|
1193
|
+
"jpg",
|
|
1194
|
+
"png",
|
|
1195
|
+
"webp"
|
|
1196
|
+
]);
|
|
820
1197
|
var DeepSeekFiles = class {
|
|
821
1198
|
constructor(config) {
|
|
822
1199
|
this.config = config;
|
|
@@ -832,12 +1209,13 @@ var DeepSeekFiles = class {
|
|
|
832
1209
|
providerOptions
|
|
833
1210
|
}) {
|
|
834
1211
|
var _a, _b;
|
|
835
|
-
const deepSeekOptions = await
|
|
1212
|
+
const deepSeekOptions = await parseProviderOptions3({
|
|
836
1213
|
provider: "deepseek",
|
|
837
1214
|
providerOptions,
|
|
838
1215
|
schema: deepSeekFilesOptionsSchema
|
|
839
1216
|
});
|
|
840
1217
|
const fileBytes = convertInlineFileDataToUint8Array(data);
|
|
1218
|
+
validateFileUpload({ fileBytes, mediaType, filename });
|
|
841
1219
|
const blob = new Blob([fileBytes], { type: mediaType });
|
|
842
1220
|
const formData = new FormData();
|
|
843
1221
|
if (filename != null) {
|
|
@@ -870,6 +1248,7 @@ var DeepSeekFiles = class {
|
|
|
870
1248
|
...mediaType != null ? { mediaType } : {},
|
|
871
1249
|
providerMetadata: {
|
|
872
1250
|
deepseek: {
|
|
1251
|
+
...response.object != null ? { object: response.object } : {},
|
|
873
1252
|
...response.filename != null ? { filename: response.filename } : {},
|
|
874
1253
|
...response.purpose != null ? { purpose: response.purpose } : {},
|
|
875
1254
|
...response.bytes != null ? { bytes: response.bytes } : {},
|
|
@@ -880,9 +1259,66 @@ var DeepSeekFiles = class {
|
|
|
880
1259
|
};
|
|
881
1260
|
}
|
|
882
1261
|
};
|
|
1262
|
+
function validateFileUpload({
|
|
1263
|
+
fileBytes,
|
|
1264
|
+
mediaType,
|
|
1265
|
+
filename
|
|
1266
|
+
}) {
|
|
1267
|
+
if (fileBytes.length > MAX_FILE_SIZE_BYTES) {
|
|
1268
|
+
throw new InvalidArgumentError({
|
|
1269
|
+
argument: "data",
|
|
1270
|
+
message: `DeepSeek file uploads must not exceed 64 MiB (${MAX_FILE_SIZE_BYTES.toLocaleString("en-US")} bytes). Received ${fileBytes.length.toLocaleString("en-US")} bytes.`
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
if (filename != null) {
|
|
1274
|
+
const filenameLength = Array.from(filename).length;
|
|
1275
|
+
if (filenameLength > MAX_FILENAME_LENGTH) {
|
|
1276
|
+
throw new InvalidArgumentError({
|
|
1277
|
+
argument: "filename",
|
|
1278
|
+
message: `DeepSeek filenames must not exceed ${MAX_FILENAME_LENGTH} characters. Received ${filenameLength} characters.`
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
const normalizedMediaType = normalizeMediaType(mediaType);
|
|
1283
|
+
const detectedMediaType = detectMediaType({ data: fileBytes });
|
|
1284
|
+
if (detectedMediaType != null && !supportedMediaTypes.has(detectedMediaType)) {
|
|
1285
|
+
throw new InvalidArgumentError({
|
|
1286
|
+
argument: "data",
|
|
1287
|
+
message: `DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. Detected unsupported file content type "${detectedMediaType}".`
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
if (supportedMediaTypes.has(normalizedMediaType)) {
|
|
1291
|
+
return;
|
|
1292
|
+
}
|
|
1293
|
+
if (!genericMediaTypes.has(normalizedMediaType)) {
|
|
1294
|
+
throw new InvalidArgumentError({
|
|
1295
|
+
argument: "mediaType",
|
|
1296
|
+
message: `DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. Received unsupported media type "${mediaType}".`
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
if (detectedMediaType != null || hasSupportedFilenameExtension(filename)) {
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
throw new InvalidArgumentError({
|
|
1303
|
+
argument: "mediaType",
|
|
1304
|
+
message: `DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. Provide a supported media type or a filename ending in .jpg, .jpeg, .png, .gif, or .webp. Received "${mediaType}".`
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
function normalizeMediaType(mediaType) {
|
|
1308
|
+
return mediaType.split(";", 1)[0].trim().toLowerCase();
|
|
1309
|
+
}
|
|
1310
|
+
function hasSupportedFilenameExtension(filename) {
|
|
1311
|
+
if (filename == null) {
|
|
1312
|
+
return false;
|
|
1313
|
+
}
|
|
1314
|
+
const extensionSeparatorIndex = filename.lastIndexOf(".");
|
|
1315
|
+
return extensionSeparatorIndex !== -1 && supportedFilenameExtensions.has(
|
|
1316
|
+
filename.slice(extensionSeparatorIndex + 1).toLowerCase()
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
883
1319
|
|
|
884
1320
|
// src/version.ts
|
|
885
|
-
var VERSION = true ? "3.0.
|
|
1321
|
+
var VERSION = true ? "3.0.32" : "0.0.0-test";
|
|
886
1322
|
|
|
887
1323
|
// src/deepseek-provider.ts
|
|
888
1324
|
function createDeepSeek(options = {}) {
|
|
@@ -904,7 +1340,9 @@ function createDeepSeek(options = {}) {
|
|
|
904
1340
|
provider: `deepseek.chat`,
|
|
905
1341
|
url: ({ path }) => `${baseURL}${path}`,
|
|
906
1342
|
headers: getHeaders,
|
|
907
|
-
fetch: options.fetch
|
|
1343
|
+
fetch: options.fetch,
|
|
1344
|
+
supportsAssistantPrefixCompletion: baseURL.endsWith("/beta"),
|
|
1345
|
+
supportsStrictToolCalls: baseURL.endsWith("/beta")
|
|
908
1346
|
});
|
|
909
1347
|
};
|
|
910
1348
|
const createFiles = () => new DeepSeekFiles({
|