@ai-sdk/deepseek 2.0.58 → 2.0.60
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 +27 -0
- package/README.md +1 -1
- package/dist/index.d.mts +57 -19
- package/dist/index.d.ts +57 -19
- package/dist/index.js +465 -124
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +467 -121
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +54 -4
- package/dist/internal/index.d.ts +54 -4
- package/dist/internal/index.js +463 -118
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +465 -117
- package/dist/internal/index.mjs.map +1 -1
- package/docs/30-deepseek.mdx +294 -23
- package/package.json +2 -2
- package/src/chat/convert-to-deepseek-chat-messages.ts +169 -22
- package/src/chat/convert-to-deepseek-usage.ts +1 -1
- package/src/chat/deepseek-chat-api-types.ts +47 -2
- package/src/chat/deepseek-chat-language-model.ts +192 -12
- package/src/chat/deepseek-chat-options.ts +102 -11
- package/src/chat/deepseek-file-part-options.ts +24 -0
- package/src/chat/deepseek-prepare-tools.ts +29 -3
- package/src/deepseek-provider.ts +4 -3
- package/src/index.ts +3 -0
package/dist/internal/index.mjs
CHANGED
|
@@ -8,16 +8,112 @@ import {
|
|
|
8
8
|
createJsonErrorResponseHandler,
|
|
9
9
|
createJsonResponseHandler,
|
|
10
10
|
generateId,
|
|
11
|
-
parseProviderOptions,
|
|
11
|
+
parseProviderOptions as parseProviderOptions2,
|
|
12
12
|
postJsonToApi
|
|
13
13
|
} from "@ai-sdk/provider-utils";
|
|
14
14
|
|
|
15
15
|
// src/chat/convert-to-deepseek-chat-messages.ts
|
|
16
|
-
import {
|
|
17
|
-
|
|
16
|
+
import {
|
|
17
|
+
InvalidPromptError,
|
|
18
|
+
UnsupportedFunctionalityError
|
|
19
|
+
} from "@ai-sdk/provider";
|
|
20
|
+
import { convertToBase64, parseProviderOptions } from "@ai-sdk/provider-utils";
|
|
21
|
+
|
|
22
|
+
// src/chat/deepseek-chat-options.ts
|
|
23
|
+
import { z } from "zod/v4";
|
|
24
|
+
var deepseekLanguageModelOptions = z.object({
|
|
25
|
+
/**
|
|
26
|
+
* Whether to return log probabilities for generated tokens.
|
|
27
|
+
*/
|
|
28
|
+
logprobs: z.boolean().optional(),
|
|
29
|
+
/**
|
|
30
|
+
* Number of most likely tokens to return at each token position.
|
|
31
|
+
*
|
|
32
|
+
* Setting this option automatically enables `logprobs`.
|
|
33
|
+
*/
|
|
34
|
+
topLogprobs: z.number().int().min(0).max(20).optional(),
|
|
35
|
+
/**
|
|
36
|
+
* An opaque identifier for the end user. DeepSeek uses this identifier for
|
|
37
|
+
* content-safety tracing and request isolation.
|
|
38
|
+
*
|
|
39
|
+
* Must contain only ASCII letters, numbers, underscores, and hyphens, and
|
|
40
|
+
* must be at most 512 characters long.
|
|
41
|
+
*/
|
|
42
|
+
userId: z.string().regex(/^[a-zA-Z0-9_-]+$/, "userId must match /^[a-zA-Z0-9_-]+$/").max(512, "userId must be at most 512 characters long").optional(),
|
|
43
|
+
/**
|
|
44
|
+
* Type of thinking to use. Defaults to `enabled`.
|
|
45
|
+
*/
|
|
46
|
+
thinking: z.object({
|
|
47
|
+
// `adaptive` is accepted at runtime for backwards compatibility and
|
|
48
|
+
// mapped to `enabled`, but is intentionally excluded from the exported
|
|
49
|
+
// provider options type.
|
|
50
|
+
type: z.enum(["adaptive", "enabled", "disabled"]).optional()
|
|
51
|
+
}).optional(),
|
|
52
|
+
/**
|
|
53
|
+
* Controls the thinking strength for DeepSeek V4 reasoning models.
|
|
54
|
+
*/
|
|
55
|
+
// `medium` and `xhigh` are accepted at runtime for backwards compatibility
|
|
56
|
+
// and mapped to canonical DeepSeek values, but are intentionally excluded
|
|
57
|
+
// from the exported provider options type.
|
|
58
|
+
reasoningEffort: z.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
|
|
59
|
+
/**
|
|
60
|
+
* Whether to use strict JSON schema validation for structured outputs.
|
|
61
|
+
* Only applies when the serving endpoint supports JSON schema response
|
|
62
|
+
* formats (e.g. Azure). Defaults to `true`.
|
|
63
|
+
*/
|
|
64
|
+
strictJsonSchema: z.boolean().optional()
|
|
65
|
+
});
|
|
66
|
+
var deepseekMessageProviderOptions = z.object({
|
|
67
|
+
/**
|
|
68
|
+
* The name of the participant represented by the message.
|
|
69
|
+
*
|
|
70
|
+
* Supported on system, user, and assistant messages.
|
|
71
|
+
*/
|
|
72
|
+
name: z.string().optional()
|
|
73
|
+
});
|
|
74
|
+
var deepseekAssistantMessageProviderOptions = deepseekMessageProviderOptions.extend({
|
|
75
|
+
/**
|
|
76
|
+
* Whether the assistant message content is a prefix that DeepSeek should
|
|
77
|
+
* continue. This beta feature is only supported on the final assistant
|
|
78
|
+
* message when using a beta base URL.
|
|
79
|
+
*/
|
|
80
|
+
prefix: z.literal(true).optional()
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// src/chat/deepseek-file-part-options.ts
|
|
84
|
+
import { z as z2 } from "zod/v4";
|
|
85
|
+
var deepseekFilePartProviderOptions = z2.object({
|
|
86
|
+
/**
|
|
87
|
+
* Controls how DeepSeek processes an image sent as an `image_url` part.
|
|
88
|
+
*
|
|
89
|
+
* @see https://api-docs.deepseek.com/api/create-chat-completion/
|
|
90
|
+
*/
|
|
91
|
+
imageDetail: z2.enum(["low", "high", "original", "auto"]).optional(),
|
|
92
|
+
/**
|
|
93
|
+
* Sends inline image data as a DeepSeek `file` part using `file_data`
|
|
94
|
+
* instead of an `image_url` data URL. When set, the file part's filename
|
|
95
|
+
* is preserved.
|
|
96
|
+
*
|
|
97
|
+
* This option only applies to inline image data. It cannot be combined
|
|
98
|
+
* with `imageDetail`.
|
|
99
|
+
*/
|
|
100
|
+
fileData: z2.literal(true).optional()
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// src/chat/convert-to-deepseek-chat-messages.ts
|
|
104
|
+
var supportedImageMediaTypes = /* @__PURE__ */ new Set([
|
|
105
|
+
"image/gif",
|
|
106
|
+
"image/jpeg",
|
|
107
|
+
"image/jpg",
|
|
108
|
+
"image/png",
|
|
109
|
+
"image/webp"
|
|
110
|
+
]);
|
|
111
|
+
async function convertToDeepSeekChatMessages({
|
|
18
112
|
prompt,
|
|
19
113
|
responseFormat,
|
|
20
114
|
modelId,
|
|
115
|
+
providerOptionsName = "deepseek",
|
|
116
|
+
supportsAssistantPrefixCompletion = false,
|
|
21
117
|
supportsStructuredOutputs = false
|
|
22
118
|
}) {
|
|
23
119
|
var _a;
|
|
@@ -50,11 +146,28 @@ function convertToDeepSeekChatMessages({
|
|
|
50
146
|
}
|
|
51
147
|
}
|
|
52
148
|
let index = -1;
|
|
53
|
-
for (const { role, content } of prompt) {
|
|
149
|
+
for (const { role, content, providerOptions } of prompt) {
|
|
54
150
|
index++;
|
|
151
|
+
const deepseekMessageOptions = await parseProviderOptions({
|
|
152
|
+
provider: providerOptionsName,
|
|
153
|
+
providerOptions,
|
|
154
|
+
schema: deepseekAssistantMessageProviderOptions
|
|
155
|
+
});
|
|
156
|
+
if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true && role !== "assistant") {
|
|
157
|
+
throw new InvalidPromptError({
|
|
158
|
+
prompt,
|
|
159
|
+
message: "DeepSeek assistant prefix completion requires `prefix: true` on an assistant message."
|
|
160
|
+
});
|
|
161
|
+
}
|
|
55
162
|
switch (role) {
|
|
56
163
|
case "system": {
|
|
57
|
-
messages.push({
|
|
164
|
+
messages.push({
|
|
165
|
+
role: "system",
|
|
166
|
+
content,
|
|
167
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
|
|
168
|
+
name: deepseekMessageOptions.name
|
|
169
|
+
}
|
|
170
|
+
});
|
|
58
171
|
break;
|
|
59
172
|
}
|
|
60
173
|
case "user": {
|
|
@@ -73,7 +186,13 @@ function convertToDeepSeekChatMessages({
|
|
|
73
186
|
});
|
|
74
187
|
}
|
|
75
188
|
}
|
|
76
|
-
messages.push({
|
|
189
|
+
messages.push({
|
|
190
|
+
role: "user",
|
|
191
|
+
content: userContent2,
|
|
192
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
|
|
193
|
+
name: deepseekMessageOptions.name
|
|
194
|
+
}
|
|
195
|
+
});
|
|
77
196
|
break;
|
|
78
197
|
}
|
|
79
198
|
const userContent = [];
|
|
@@ -81,13 +200,67 @@ function convertToDeepSeekChatMessages({
|
|
|
81
200
|
if (part.type === "text") {
|
|
82
201
|
userContent.push({ type: "text", text: part.text });
|
|
83
202
|
} else if (part.type === "file" && (part.mediaType === "image" || part.mediaType.startsWith("image/"))) {
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
url: part.data instanceof URL ? part.data.toString() : `data:${mediaType};base64,${convertToBase64(part.data)}`
|
|
89
|
-
}
|
|
203
|
+
const filePartOptions = await parseProviderOptions({
|
|
204
|
+
provider: providerOptionsName,
|
|
205
|
+
providerOptions: part.providerOptions,
|
|
206
|
+
schema: deepseekFilePartProviderOptions
|
|
90
207
|
});
|
|
208
|
+
const resolvedMediaType = part.mediaType === "image" || part.mediaType === "image/*" ? "image/jpeg" : part.mediaType;
|
|
209
|
+
if (!supportedImageMediaTypes.has(resolvedMediaType)) {
|
|
210
|
+
throw new UnsupportedFunctionalityError({
|
|
211
|
+
functionality: `DeepSeek image media type ${resolvedMediaType}`,
|
|
212
|
+
message: "DeepSeek supports JPEG, PNG, GIF, and WebP image inputs."
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (part.data instanceof URL) {
|
|
216
|
+
const url = part.data.toString();
|
|
217
|
+
if (url.length > 8192) {
|
|
218
|
+
throw new InvalidPromptError({
|
|
219
|
+
prompt,
|
|
220
|
+
message: "DeepSeek image URLs must not exceed 8192 characters."
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
if ((filePartOptions == null ? void 0 : filePartOptions.fileData) === true) {
|
|
224
|
+
throw new InvalidPromptError({
|
|
225
|
+
prompt,
|
|
226
|
+
message: "DeepSeek `fileData` image parts require inline data, not a URL."
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
userContent.push({
|
|
230
|
+
type: "image_url",
|
|
231
|
+
image_url: {
|
|
232
|
+
url,
|
|
233
|
+
...(filePartOptions == null ? void 0 : filePartOptions.imageDetail) != null && {
|
|
234
|
+
detail: filePartOptions.imageDetail
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
} else {
|
|
239
|
+
const dataUrl = `data:${resolvedMediaType === "image/jpg" ? "image/jpeg" : resolvedMediaType};base64,${convertToBase64(part.data)}`;
|
|
240
|
+
if ((filePartOptions == null ? void 0 : filePartOptions.fileData) === true) {
|
|
241
|
+
if (filePartOptions.imageDetail != null) {
|
|
242
|
+
throw new InvalidPromptError({
|
|
243
|
+
prompt,
|
|
244
|
+
message: "DeepSeek `imageDetail` cannot be combined with `fileData`."
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
userContent.push({
|
|
248
|
+
type: "file",
|
|
249
|
+
file_data: dataUrl,
|
|
250
|
+
...part.filename != null && { filename: part.filename }
|
|
251
|
+
});
|
|
252
|
+
} else {
|
|
253
|
+
userContent.push({
|
|
254
|
+
type: "image_url",
|
|
255
|
+
image_url: {
|
|
256
|
+
url: dataUrl,
|
|
257
|
+
...(filePartOptions == null ? void 0 : filePartOptions.imageDetail) != null && {
|
|
258
|
+
detail: filePartOptions.imageDetail
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
91
264
|
} else {
|
|
92
265
|
warnings.push({
|
|
93
266
|
type: "unsupported",
|
|
@@ -95,10 +268,30 @@ function convertToDeepSeekChatMessages({
|
|
|
95
268
|
});
|
|
96
269
|
}
|
|
97
270
|
}
|
|
98
|
-
messages.push({
|
|
271
|
+
messages.push({
|
|
272
|
+
role: "user",
|
|
273
|
+
content: userContent,
|
|
274
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
|
|
275
|
+
name: deepseekMessageOptions.name
|
|
276
|
+
}
|
|
277
|
+
});
|
|
99
278
|
break;
|
|
100
279
|
}
|
|
101
280
|
case "assistant": {
|
|
281
|
+
if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true) {
|
|
282
|
+
if (index !== prompt.length - 1) {
|
|
283
|
+
throw new InvalidPromptError({
|
|
284
|
+
prompt,
|
|
285
|
+
message: "DeepSeek assistant prefix completion requires the prefixed assistant message to be the final message."
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
if (!supportsAssistantPrefixCompletion) {
|
|
289
|
+
throw new UnsupportedFunctionalityError({
|
|
290
|
+
functionality: "DeepSeek assistant prefix completion",
|
|
291
|
+
message: "DeepSeek assistant prefix completion requires a beta base URL ending in `/beta`."
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
102
295
|
let text = "";
|
|
103
296
|
let reasoning;
|
|
104
297
|
const toolCalls = [];
|
|
@@ -135,12 +328,24 @@ function convertToDeepSeekChatMessages({
|
|
|
135
328
|
messages.push({
|
|
136
329
|
role: "assistant",
|
|
137
330
|
content: text,
|
|
331
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
|
|
332
|
+
name: deepseekMessageOptions.name
|
|
333
|
+
},
|
|
334
|
+
...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true && {
|
|
335
|
+
prefix: true
|
|
336
|
+
},
|
|
138
337
|
reasoning_content: reasoning != null ? reasoning : isDeepSeekV4 ? "" : void 0,
|
|
139
338
|
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
|
|
140
339
|
});
|
|
141
340
|
break;
|
|
142
341
|
}
|
|
143
342
|
case "tool": {
|
|
343
|
+
if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null) {
|
|
344
|
+
warnings.push({
|
|
345
|
+
type: "unsupported",
|
|
346
|
+
feature: "message name on tool messages"
|
|
347
|
+
});
|
|
348
|
+
}
|
|
144
349
|
for (const toolResponse of content) {
|
|
145
350
|
if (toolResponse.type === "tool-approval-response") {
|
|
146
351
|
continue;
|
|
@@ -213,7 +418,7 @@ function convertDeepSeekUsage(usage) {
|
|
|
213
418
|
},
|
|
214
419
|
outputTokens: {
|
|
215
420
|
total: completionTokens,
|
|
216
|
-
text: completionTokens - reasoningTokens,
|
|
421
|
+
text: Math.max(0, completionTokens - reasoningTokens),
|
|
217
422
|
reasoning: reasoningTokens
|
|
218
423
|
},
|
|
219
424
|
raw: usage
|
|
@@ -222,75 +427,101 @@ function convertDeepSeekUsage(usage) {
|
|
|
222
427
|
|
|
223
428
|
// src/chat/deepseek-chat-api-types.ts
|
|
224
429
|
import { lazySchema, zodSchema } from "@ai-sdk/provider-utils";
|
|
225
|
-
import { z } from "zod/v4";
|
|
226
|
-
var tokenUsageSchema =
|
|
227
|
-
prompt_tokens:
|
|
228
|
-
completion_tokens:
|
|
229
|
-
prompt_cache_hit_tokens:
|
|
230
|
-
prompt_cache_miss_tokens:
|
|
231
|
-
total_tokens:
|
|
232
|
-
completion_tokens_details:
|
|
233
|
-
reasoning_tokens:
|
|
430
|
+
import { z as z3 } from "zod/v4";
|
|
431
|
+
var tokenUsageSchema = z3.object({
|
|
432
|
+
prompt_tokens: z3.number().nullish(),
|
|
433
|
+
completion_tokens: z3.number().nullish(),
|
|
434
|
+
prompt_cache_hit_tokens: z3.number().nullish(),
|
|
435
|
+
prompt_cache_miss_tokens: z3.number().nullish(),
|
|
436
|
+
total_tokens: z3.number().nullish(),
|
|
437
|
+
completion_tokens_details: z3.object({
|
|
438
|
+
reasoning_tokens: z3.number().nullish()
|
|
234
439
|
}).nullish()
|
|
235
440
|
}).nullish();
|
|
236
|
-
var deepSeekErrorSchema =
|
|
237
|
-
error:
|
|
238
|
-
message:
|
|
239
|
-
type:
|
|
240
|
-
param:
|
|
241
|
-
code:
|
|
441
|
+
var deepSeekErrorSchema = z3.object({
|
|
442
|
+
error: z3.object({
|
|
443
|
+
message: z3.string(),
|
|
444
|
+
type: z3.string().nullish(),
|
|
445
|
+
param: z3.any().nullish(),
|
|
446
|
+
code: z3.union([z3.string(), z3.number()]).nullish()
|
|
242
447
|
})
|
|
243
448
|
});
|
|
244
|
-
var
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
449
|
+
var deepseekChatLogprobSchema = z3.object({
|
|
450
|
+
token: z3.string(),
|
|
451
|
+
logprob: z3.number(),
|
|
452
|
+
bytes: z3.array(z3.number()).nullable(),
|
|
453
|
+
top_logprobs: z3.array(
|
|
454
|
+
z3.object({
|
|
455
|
+
token: z3.string(),
|
|
456
|
+
logprob: z3.number(),
|
|
457
|
+
bytes: z3.array(z3.number()).nullable()
|
|
458
|
+
})
|
|
459
|
+
)
|
|
460
|
+
});
|
|
461
|
+
var deepseekChatLogprobsSchema = z3.object({
|
|
462
|
+
content: z3.array(deepseekChatLogprobSchema).nullish(),
|
|
463
|
+
reasoning_content: z3.array(deepseekChatLogprobSchema).nullish()
|
|
464
|
+
}).nullish();
|
|
465
|
+
var deepseekChatResponseSchema = z3.object({
|
|
466
|
+
id: z3.string().nullish(),
|
|
467
|
+
created: z3.number().nullish(),
|
|
468
|
+
model: z3.string().nullish(),
|
|
469
|
+
object: z3.literal("chat.completion").nullish(),
|
|
470
|
+
system_fingerprint: z3.string().nullish(),
|
|
471
|
+
choices: z3.array(
|
|
472
|
+
z3.object({
|
|
473
|
+
index: z3.number().nullish(),
|
|
474
|
+
message: z3.object({
|
|
475
|
+
role: z3.literal("assistant").nullish(),
|
|
476
|
+
content: z3.string().nullish(),
|
|
477
|
+
reasoning_content: z3.string().nullish(),
|
|
478
|
+
tool_calls: z3.array(
|
|
479
|
+
z3.object({
|
|
480
|
+
id: z3.string().nullish(),
|
|
481
|
+
type: z3.literal("function").nullish(),
|
|
482
|
+
function: z3.object({
|
|
483
|
+
name: z3.string(),
|
|
484
|
+
arguments: z3.string()
|
|
260
485
|
})
|
|
261
486
|
})
|
|
262
487
|
).nullish()
|
|
263
488
|
}),
|
|
264
|
-
|
|
489
|
+
logprobs: deepseekChatLogprobsSchema,
|
|
490
|
+
finish_reason: z3.string().nullish()
|
|
265
491
|
})
|
|
266
492
|
),
|
|
267
493
|
usage: tokenUsageSchema
|
|
268
494
|
});
|
|
269
495
|
var deepseekChatChunkSchema = lazySchema(
|
|
270
496
|
() => zodSchema(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
id:
|
|
274
|
-
created:
|
|
275
|
-
model:
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
497
|
+
z3.union([
|
|
498
|
+
z3.object({
|
|
499
|
+
id: z3.string().nullish(),
|
|
500
|
+
created: z3.number().nullish(),
|
|
501
|
+
model: z3.string().nullish(),
|
|
502
|
+
object: z3.literal("chat.completion.chunk").nullish(),
|
|
503
|
+
system_fingerprint: z3.string().nullish(),
|
|
504
|
+
choices: z3.array(
|
|
505
|
+
z3.object({
|
|
506
|
+
index: z3.number().nullish(),
|
|
507
|
+
delta: z3.object({
|
|
508
|
+
role: z3.enum(["assistant"]).nullish(),
|
|
509
|
+
content: z3.string().nullish(),
|
|
510
|
+
reasoning_content: z3.string().nullish(),
|
|
511
|
+
tool_calls: z3.array(
|
|
512
|
+
z3.object({
|
|
513
|
+
index: z3.number(),
|
|
514
|
+
id: z3.string().nullish(),
|
|
515
|
+
type: z3.literal("function").nullish(),
|
|
516
|
+
function: z3.object({
|
|
517
|
+
name: z3.string().nullish(),
|
|
518
|
+
arguments: z3.string().nullish()
|
|
289
519
|
})
|
|
290
520
|
})
|
|
291
521
|
).nullish()
|
|
292
522
|
}).nullish(),
|
|
293
|
-
|
|
523
|
+
logprobs: deepseekChatLogprobsSchema,
|
|
524
|
+
finish_reason: z3.string().nullish()
|
|
294
525
|
})
|
|
295
526
|
),
|
|
296
527
|
usage: tokenUsageSchema
|
|
@@ -300,44 +531,34 @@ var deepseekChatChunkSchema = lazySchema(
|
|
|
300
531
|
)
|
|
301
532
|
);
|
|
302
533
|
|
|
303
|
-
// src/chat/deepseek-chat-options.ts
|
|
304
|
-
import { z as z2 } from "zod/v4";
|
|
305
|
-
var deepseekLanguageModelOptions = z2.object({
|
|
306
|
-
/**
|
|
307
|
-
* Type of thinking to use. Defaults to `enabled`.
|
|
308
|
-
*
|
|
309
|
-
* See https://api-docs.deepseek.com/guides/thinking_mode for the
|
|
310
|
-
* `adaptive` option, which lets the model decide when to think.
|
|
311
|
-
*/
|
|
312
|
-
thinking: z2.object({
|
|
313
|
-
type: z2.enum(["adaptive", "enabled", "disabled"]).optional()
|
|
314
|
-
}).optional(),
|
|
315
|
-
/**
|
|
316
|
-
* Controls the thinking strength for DeepSeek V4 reasoning models.
|
|
317
|
-
*
|
|
318
|
-
* DeepSeek's API accepts `low`, `medium`, `high`, `xhigh`, and `max`.
|
|
319
|
-
* Per their docs, `low` and `medium` are mapped to `high`, and `xhigh`
|
|
320
|
-
* is mapped to `max` server-side for compatibility with other providers.
|
|
321
|
-
*/
|
|
322
|
-
reasoningEffort: z2.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
|
|
323
|
-
/**
|
|
324
|
-
* Whether to use strict JSON schema validation for structured outputs.
|
|
325
|
-
* Only applies when the serving endpoint supports JSON schema response
|
|
326
|
-
* formats (e.g. Azure). Defaults to `true`.
|
|
327
|
-
*/
|
|
328
|
-
strictJsonSchema: z2.boolean().optional()
|
|
329
|
-
});
|
|
330
|
-
|
|
331
534
|
// src/chat/deepseek-prepare-tools.ts
|
|
535
|
+
import {
|
|
536
|
+
UnsupportedFunctionalityError as UnsupportedFunctionalityError2
|
|
537
|
+
} from "@ai-sdk/provider";
|
|
332
538
|
function prepareTools({
|
|
333
539
|
tools,
|
|
334
|
-
toolChoice
|
|
540
|
+
toolChoice,
|
|
541
|
+
supportsStrictToolCalls
|
|
335
542
|
}) {
|
|
336
543
|
tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
|
|
337
544
|
const toolWarnings = [];
|
|
338
545
|
if (tools == null) {
|
|
339
546
|
return { tools: void 0, toolChoice: void 0, toolWarnings };
|
|
340
547
|
}
|
|
548
|
+
const functionTools = tools.filter((tool) => tool.type === "function");
|
|
549
|
+
const hasStrictTool = functionTools.some((tool) => tool.strict === true);
|
|
550
|
+
if (hasStrictTool && supportsStrictToolCalls === false) {
|
|
551
|
+
throw new UnsupportedFunctionalityError2({
|
|
552
|
+
functionality: "DeepSeek strict tool calls",
|
|
553
|
+
message: "DeepSeek strict tool calls require a beta base URL ending in `/beta`."
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
if (hasStrictTool && supportsStrictToolCalls === true && functionTools.some((tool) => tool.strict !== true)) {
|
|
557
|
+
throw new UnsupportedFunctionalityError2({
|
|
558
|
+
functionality: "mixed DeepSeek strict and non-strict tool calls",
|
|
559
|
+
message: "DeepSeek strict mode requires every function tool in the request to set `strict: true`."
|
|
560
|
+
});
|
|
561
|
+
}
|
|
341
562
|
const deepseekTools = [];
|
|
342
563
|
for (const tool of tools) {
|
|
343
564
|
if (tool.type === "provider") {
|
|
@@ -423,6 +644,20 @@ function mapDeepSeekFinishReason(finishReason) {
|
|
|
423
644
|
}
|
|
424
645
|
|
|
425
646
|
// src/chat/deepseek-chat-language-model.ts
|
|
647
|
+
function mapDeepSeekProviderReasoningEffort({
|
|
648
|
+
reasoningEffort,
|
|
649
|
+
warnings
|
|
650
|
+
}) {
|
|
651
|
+
const mapped = reasoningEffort === "medium" ? "high" : reasoningEffort === "xhigh" ? "max" : reasoningEffort;
|
|
652
|
+
if (mapped !== reasoningEffort) {
|
|
653
|
+
warnings.push({
|
|
654
|
+
type: "compatibility",
|
|
655
|
+
feature: "reasoningEffort",
|
|
656
|
+
details: `reasoningEffort "${reasoningEffort}" is not a canonical DeepSeek value. mapped to "${mapped}".`
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
return mapped;
|
|
660
|
+
}
|
|
426
661
|
var DeepSeekChatLanguageModel = class {
|
|
427
662
|
constructor(modelId, config) {
|
|
428
663
|
this.specificationVersion = "v3";
|
|
@@ -458,23 +693,39 @@ var DeepSeekChatLanguageModel = class {
|
|
|
458
693
|
tools
|
|
459
694
|
}) {
|
|
460
695
|
var _a, _b, _c, _d;
|
|
461
|
-
const deepseekOptions = (_a = await
|
|
696
|
+
const deepseekOptions = (_a = await parseProviderOptions2({
|
|
462
697
|
provider: this.providerOptionsName,
|
|
463
698
|
providerOptions,
|
|
464
699
|
schema: deepseekLanguageModelOptions
|
|
465
700
|
})) != null ? _a : {};
|
|
466
701
|
const supportsStructuredOutputs = this.config.supportsStructuredOutputs === true;
|
|
467
|
-
const
|
|
702
|
+
const supportsPenaltySampling = this.config.supportsPenaltySampling === true;
|
|
703
|
+
const { messages, warnings } = await convertToDeepSeekChatMessages({
|
|
468
704
|
prompt,
|
|
469
705
|
responseFormat,
|
|
470
706
|
modelId: this.modelId,
|
|
707
|
+
providerOptionsName: this.providerOptionsName,
|
|
708
|
+
supportsAssistantPrefixCompletion: this.config.supportsAssistantPrefixCompletion,
|
|
471
709
|
supportsStructuredOutputs
|
|
472
710
|
});
|
|
711
|
+
const allWarnings = [...warnings];
|
|
473
712
|
if (topK != null) {
|
|
474
|
-
|
|
713
|
+
allWarnings.push({ type: "unsupported", feature: "topK" });
|
|
475
714
|
}
|
|
476
715
|
if (seed != null) {
|
|
477
|
-
|
|
716
|
+
allWarnings.push({ type: "unsupported", feature: "seed" });
|
|
717
|
+
}
|
|
718
|
+
if (!supportsPenaltySampling && frequencyPenalty != null) {
|
|
719
|
+
allWarnings.push({
|
|
720
|
+
type: "other",
|
|
721
|
+
message: "frequencyPenalty is deprecated by DeepSeek and has been omitted. Remove frequencyPenalty from the request."
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
if (!supportsPenaltySampling && presencePenalty != null) {
|
|
725
|
+
allWarnings.push({
|
|
726
|
+
type: "other",
|
|
727
|
+
message: "presencePenalty is deprecated by DeepSeek and has been omitted. Remove presencePenalty from the request."
|
|
728
|
+
});
|
|
478
729
|
}
|
|
479
730
|
const {
|
|
480
731
|
tools: deepseekTools,
|
|
@@ -482,17 +733,50 @@ var DeepSeekChatLanguageModel = class {
|
|
|
482
733
|
toolWarnings
|
|
483
734
|
} = prepareTools({
|
|
484
735
|
tools,
|
|
485
|
-
toolChoice
|
|
736
|
+
toolChoice,
|
|
737
|
+
supportsStrictToolCalls: this.config.supportsStrictToolCalls
|
|
486
738
|
});
|
|
487
|
-
|
|
739
|
+
allWarnings.push(...toolWarnings);
|
|
740
|
+
const thinkingType = (_b = deepseekOptions.thinking) == null ? void 0 : _b.type;
|
|
741
|
+
if (thinkingType === "adaptive") {
|
|
742
|
+
allWarnings.push({
|
|
743
|
+
type: "compatibility",
|
|
744
|
+
feature: "thinking.type",
|
|
745
|
+
details: 'thinking.type "adaptive" is not a canonical DeepSeek value. mapped to "enabled".'
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
const thinking = this.config.supportsThinking === false ? void 0 : thinkingType != null ? { type: thinkingType === "adaptive" ? "enabled" : thinkingType } : void 0;
|
|
749
|
+
const isThinkingEnabled = this.config.supportsThinking !== false && (thinking == null ? void 0 : thinking.type) !== "disabled" && (thinking != null || this.modelId === "deepseek-reasoner" || this.modelId.includes("deepseek-v4"));
|
|
750
|
+
if (isThinkingEnabled && temperature != null) {
|
|
751
|
+
allWarnings.push({
|
|
752
|
+
type: "unsupported",
|
|
753
|
+
feature: "temperature",
|
|
754
|
+
details: "temperature has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use temperature."
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
if (isThinkingEnabled && topP != null) {
|
|
758
|
+
allWarnings.push({
|
|
759
|
+
type: "unsupported",
|
|
760
|
+
feature: "topP",
|
|
761
|
+
details: "topP has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use topP."
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
const reasoningEffort = deepseekOptions.reasoningEffort != null ? mapDeepSeekProviderReasoningEffort({
|
|
765
|
+
reasoningEffort: deepseekOptions.reasoningEffort,
|
|
766
|
+
warnings: allWarnings
|
|
767
|
+
}) : void 0;
|
|
488
768
|
return {
|
|
489
769
|
args: {
|
|
490
770
|
model: this.modelId,
|
|
771
|
+
...(deepseekOptions.logprobs === true || deepseekOptions.topLogprobs != null) && { logprobs: true },
|
|
772
|
+
...deepseekOptions.topLogprobs != null && {
|
|
773
|
+
top_logprobs: deepseekOptions.topLogprobs
|
|
774
|
+
},
|
|
491
775
|
max_tokens: maxOutputTokens,
|
|
492
|
-
temperature,
|
|
493
|
-
top_p: topP,
|
|
494
|
-
frequency_penalty: frequencyPenalty,
|
|
495
|
-
presence_penalty: presencePenalty,
|
|
776
|
+
temperature: isThinkingEnabled ? void 0 : temperature,
|
|
777
|
+
top_p: isThinkingEnabled ? void 0 : topP,
|
|
778
|
+
frequency_penalty: supportsPenaltySampling ? frequencyPenalty : void 0,
|
|
779
|
+
presence_penalty: supportsPenaltySampling ? presencePenalty : void 0,
|
|
496
780
|
response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? supportsStructuredOutputs && responseFormat.schema != null ? {
|
|
497
781
|
type: "json_schema",
|
|
498
782
|
json_schema: {
|
|
@@ -507,11 +791,14 @@ var DeepSeekChatLanguageModel = class {
|
|
|
507
791
|
tools: deepseekTools,
|
|
508
792
|
tool_choice: deepseekToolChoices,
|
|
509
793
|
thinking,
|
|
510
|
-
...
|
|
511
|
-
|
|
794
|
+
...deepseekOptions.userId != null && {
|
|
795
|
+
user_id: deepseekOptions.userId
|
|
796
|
+
},
|
|
797
|
+
...(thinking == null ? void 0 : thinking.type) !== "disabled" && reasoningEffort != null && {
|
|
798
|
+
reasoning_effort: reasoningEffort
|
|
512
799
|
}
|
|
513
800
|
},
|
|
514
|
-
warnings:
|
|
801
|
+
warnings: allWarnings
|
|
515
802
|
};
|
|
516
803
|
}
|
|
517
804
|
async doGenerate(options) {
|
|
@@ -568,7 +855,21 @@ var DeepSeekChatLanguageModel = class {
|
|
|
568
855
|
providerMetadata: {
|
|
569
856
|
[this.providerOptionsName]: {
|
|
570
857
|
promptCacheHitTokens: (_c = responseBody.usage) == null ? void 0 : _c.prompt_cache_hit_tokens,
|
|
571
|
-
promptCacheMissTokens: (_d = responseBody.usage) == null ? void 0 : _d.prompt_cache_miss_tokens
|
|
858
|
+
promptCacheMissTokens: (_d = responseBody.usage) == null ? void 0 : _d.prompt_cache_miss_tokens,
|
|
859
|
+
...responseBody.object != null && {
|
|
860
|
+
responseObject: responseBody.object
|
|
861
|
+
},
|
|
862
|
+
...choice.index != null && { choiceIndex: choice.index },
|
|
863
|
+
...choice.message.role != null && {
|
|
864
|
+
messageRole: choice.message.role
|
|
865
|
+
},
|
|
866
|
+
...choice.message.tool_calls != null && {
|
|
867
|
+
toolCallTypes: choice.message.tool_calls.map((toolCall) => toolCall.type).filter((type) => type != null)
|
|
868
|
+
},
|
|
869
|
+
...choice.logprobs != null && { logprobs: choice.logprobs },
|
|
870
|
+
...responseBody.system_fingerprint != null && {
|
|
871
|
+
systemFingerprint: responseBody.system_fingerprint
|
|
872
|
+
}
|
|
572
873
|
}
|
|
573
874
|
},
|
|
574
875
|
request: { body: args },
|
|
@@ -607,10 +908,17 @@ var DeepSeekChatLanguageModel = class {
|
|
|
607
908
|
raw: void 0
|
|
608
909
|
};
|
|
609
910
|
let usage = void 0;
|
|
911
|
+
let systemFingerprint = void 0;
|
|
610
912
|
let isFirstChunk = true;
|
|
611
913
|
const providerOptionsName = this.providerOptionsName;
|
|
612
914
|
let isActiveReasoning = false;
|
|
613
915
|
let isActiveText = false;
|
|
916
|
+
let responseObject;
|
|
917
|
+
let choiceIndex;
|
|
918
|
+
let messageRole;
|
|
919
|
+
const toolCallTypes = /* @__PURE__ */ new Map();
|
|
920
|
+
const contentLogprobs = [];
|
|
921
|
+
const reasoningLogprobs = [];
|
|
614
922
|
return {
|
|
615
923
|
stream: response.pipeThrough(
|
|
616
924
|
new TransformStream({
|
|
@@ -618,7 +926,7 @@ var DeepSeekChatLanguageModel = class {
|
|
|
618
926
|
controller.enqueue({ type: "stream-start", warnings });
|
|
619
927
|
},
|
|
620
928
|
transform(chunk, controller) {
|
|
621
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
929
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
622
930
|
if (options.includeRawChunks) {
|
|
623
931
|
controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
|
|
624
932
|
}
|
|
@@ -643,17 +951,35 @@ var DeepSeekChatLanguageModel = class {
|
|
|
643
951
|
if (value.usage != null) {
|
|
644
952
|
usage = value.usage;
|
|
645
953
|
}
|
|
954
|
+
if (value.object != null) {
|
|
955
|
+
responseObject = value.object;
|
|
956
|
+
}
|
|
957
|
+
if (value.system_fingerprint != null) {
|
|
958
|
+
systemFingerprint = value.system_fingerprint;
|
|
959
|
+
}
|
|
646
960
|
const choice = value.choices[0];
|
|
961
|
+
if ((choice == null ? void 0 : choice.index) != null) {
|
|
962
|
+
choiceIndex = choice.index;
|
|
963
|
+
}
|
|
647
964
|
if ((choice == null ? void 0 : choice.finish_reason) != null) {
|
|
648
965
|
finishReason = {
|
|
649
966
|
unified: mapDeepSeekFinishReason(choice.finish_reason),
|
|
650
967
|
raw: choice.finish_reason
|
|
651
968
|
};
|
|
652
969
|
}
|
|
970
|
+
if (((_a = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _a.content) != null) {
|
|
971
|
+
contentLogprobs.push(...choice.logprobs.content);
|
|
972
|
+
}
|
|
973
|
+
if (((_b = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _b.reasoning_content) != null) {
|
|
974
|
+
reasoningLogprobs.push(...choice.logprobs.reasoning_content);
|
|
975
|
+
}
|
|
653
976
|
if ((choice == null ? void 0 : choice.delta) == null) {
|
|
654
977
|
return;
|
|
655
978
|
}
|
|
656
979
|
const delta = choice.delta;
|
|
980
|
+
if (delta.role != null) {
|
|
981
|
+
messageRole = delta.role;
|
|
982
|
+
}
|
|
657
983
|
const reasoningContent = delta.reasoning_content;
|
|
658
984
|
if (reasoningContent) {
|
|
659
985
|
if (!isActiveReasoning) {
|
|
@@ -696,6 +1022,9 @@ var DeepSeekChatLanguageModel = class {
|
|
|
696
1022
|
isActiveReasoning = false;
|
|
697
1023
|
}
|
|
698
1024
|
for (const toolCallDelta of delta.tool_calls) {
|
|
1025
|
+
if (toolCallDelta.type != null) {
|
|
1026
|
+
toolCallTypes.set(toolCallDelta.index, toolCallDelta.type);
|
|
1027
|
+
}
|
|
699
1028
|
const index = toolCallDelta.index;
|
|
700
1029
|
if (toolCalls[index] == null) {
|
|
701
1030
|
if (toolCallDelta.id == null) {
|
|
@@ -704,7 +1033,7 @@ var DeepSeekChatLanguageModel = class {
|
|
|
704
1033
|
message: `Expected 'id' to be a string.`
|
|
705
1034
|
});
|
|
706
1035
|
}
|
|
707
|
-
if (((
|
|
1036
|
+
if (((_c = toolCallDelta.function) == null ? void 0 : _c.name) == null) {
|
|
708
1037
|
throw new InvalidResponseDataError({
|
|
709
1038
|
data: toolCallDelta,
|
|
710
1039
|
message: `Expected 'function.name' to be a string.`
|
|
@@ -720,12 +1049,12 @@ var DeepSeekChatLanguageModel = class {
|
|
|
720
1049
|
type: "function",
|
|
721
1050
|
function: {
|
|
722
1051
|
name: toolCallDelta.function.name,
|
|
723
|
-
arguments: (
|
|
1052
|
+
arguments: (_d = toolCallDelta.function.arguments) != null ? _d : ""
|
|
724
1053
|
},
|
|
725
1054
|
hasFinished: false
|
|
726
1055
|
};
|
|
727
1056
|
const toolCall2 = toolCalls[index];
|
|
728
|
-
if (((
|
|
1057
|
+
if (((_e = toolCall2.function) == null ? void 0 : _e.name) != null && ((_f = toolCall2.function) == null ? void 0 : _f.arguments) != null) {
|
|
729
1058
|
if (toolCall2.function.arguments.length > 0) {
|
|
730
1059
|
controller.enqueue({
|
|
731
1060
|
type: "tool-input-delta",
|
|
@@ -740,13 +1069,13 @@ var DeepSeekChatLanguageModel = class {
|
|
|
740
1069
|
if (toolCall.hasFinished) {
|
|
741
1070
|
continue;
|
|
742
1071
|
}
|
|
743
|
-
if (((
|
|
744
|
-
toolCall.function.arguments += (
|
|
1072
|
+
if (((_g = toolCallDelta.function) == null ? void 0 : _g.arguments) != null) {
|
|
1073
|
+
toolCall.function.arguments += (_i = (_h = toolCallDelta.function) == null ? void 0 : _h.arguments) != null ? _i : "";
|
|
745
1074
|
}
|
|
746
1075
|
controller.enqueue({
|
|
747
1076
|
type: "tool-input-delta",
|
|
748
1077
|
id: toolCall.id,
|
|
749
|
-
delta: (
|
|
1078
|
+
delta: (_j = toolCallDelta.function.arguments) != null ? _j : ""
|
|
750
1079
|
});
|
|
751
1080
|
}
|
|
752
1081
|
}
|
|
@@ -780,7 +1109,24 @@ var DeepSeekChatLanguageModel = class {
|
|
|
780
1109
|
providerMetadata: {
|
|
781
1110
|
[providerOptionsName]: {
|
|
782
1111
|
promptCacheHitTokens: (_b = usage == null ? void 0 : usage.prompt_cache_hit_tokens) != null ? _b : void 0,
|
|
783
|
-
promptCacheMissTokens: (_c = usage == null ? void 0 : usage.prompt_cache_miss_tokens) != null ? _c : void 0
|
|
1112
|
+
promptCacheMissTokens: (_c = usage == null ? void 0 : usage.prompt_cache_miss_tokens) != null ? _c : void 0,
|
|
1113
|
+
...responseObject != null && { responseObject },
|
|
1114
|
+
...choiceIndex != null && { choiceIndex },
|
|
1115
|
+
...messageRole != null && { messageRole },
|
|
1116
|
+
...toolCallTypes.size > 0 && {
|
|
1117
|
+
toolCallTypes: [...toolCallTypes.entries()].sort(([left], [right]) => left - right).map(([, type]) => type)
|
|
1118
|
+
},
|
|
1119
|
+
...(contentLogprobs.length > 0 || reasoningLogprobs.length > 0) && {
|
|
1120
|
+
logprobs: {
|
|
1121
|
+
...contentLogprobs.length > 0 && {
|
|
1122
|
+
content: contentLogprobs
|
|
1123
|
+
},
|
|
1124
|
+
...reasoningLogprobs.length > 0 && {
|
|
1125
|
+
reasoning_content: reasoningLogprobs
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
},
|
|
1129
|
+
...systemFingerprint != null && { systemFingerprint }
|
|
784
1130
|
}
|
|
785
1131
|
}
|
|
786
1132
|
});
|
|
@@ -794,6 +1140,8 @@ var DeepSeekChatLanguageModel = class {
|
|
|
794
1140
|
};
|
|
795
1141
|
export {
|
|
796
1142
|
DeepSeekChatLanguageModel,
|
|
797
|
-
|
|
1143
|
+
deepseekAssistantMessageProviderOptions,
|
|
1144
|
+
deepseekLanguageModelOptions,
|
|
1145
|
+
deepseekMessageProviderOptions
|
|
798
1146
|
};
|
|
799
1147
|
//# sourceMappingURL=index.mjs.map
|