@ai-sdk/deepseek 3.0.56 → 3.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.
package/dist/index.js CHANGED
@@ -1,1512 +1,1216 @@
1
- // src/deepseek-provider.ts
2
- import {
3
- NoSuchModelError
4
- } from "@ai-sdk/provider";
5
- import {
6
- loadApiKey,
7
- withoutTrailingSlash,
8
- withUserAgentSuffix
9
- } from "@ai-sdk/provider-utils";
10
-
11
- // src/chat/deepseek-chat-language-model.ts
12
- import {
13
- InvalidResponseDataError
14
- } from "@ai-sdk/provider";
15
- import {
16
- combineHeaders,
17
- createEventSourceResponseHandler,
18
- createJsonErrorResponseHandler,
19
- createJsonResponseHandler,
20
- createProviderStreamError,
21
- generateId,
22
- isCustomReasoning,
23
- mapReasoningToProviderEffort,
24
- parseProviderOptions as parseProviderOptions2,
25
- postJsonToApi,
26
- serializeModelOptions,
27
- StreamingToolCallTracker,
28
- WORKFLOW_SERIALIZE,
29
- WORKFLOW_DESERIALIZE
30
- } from "@ai-sdk/provider-utils";
31
-
32
- // src/chat/convert-to-deepseek-chat-messages.ts
33
- import {
34
- InvalidPromptError,
35
- UnsupportedFunctionalityError
36
- } from "@ai-sdk/provider";
37
- import {
38
- convertToBase64,
39
- getTopLevelMediaType,
40
- parseProviderOptions,
41
- resolveFullMediaType,
42
- resolveProviderReference
43
- } from "@ai-sdk/provider-utils";
44
-
45
- // src/chat/deepseek-file-part-options.ts
1
+ import { InvalidArgumentError, InvalidPromptError, InvalidResponseDataError, NoSuchModelError, UnsupportedFunctionalityError } from "@ai-sdk/provider";
2
+ import { StreamingToolCallTracker, WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, convertInlineFileDataToUint8Array, convertToBase64, createEventSourceResponseHandler, createJsonErrorResponseHandler, createJsonResponseHandler, createLanguageModelResponseMetadata as getResponseMetadata, createNullLanguageModelUsage, createProviderStreamError, detectMediaType, generateId, getTopLevelMediaType, isCustomReasoning, lazySchema, loadApiKey, mapReasoningToProviderEffort, parseProviderOptions, postFormDataToApi, postJsonToApi, resolveFullMediaType, resolveProviderReference, serializeModelOptions, withUserAgentSuffix, withoutTrailingSlash, zodSchema } from "@ai-sdk/provider-utils";
46
3
  import { z } from "zod/v4";
47
- var deepseekFilePartProviderOptions = z.object({
48
- /**
49
- * Controls how DeepSeek processes an image sent as an `image_url` part.
50
- *
51
- * @see https://api-docs.deepseek.com/api/create-chat-completion/
52
- */
53
- imageDetail: z.enum(["low", "high", "original", "auto"]).optional(),
54
- /**
55
- * Sends inline image data as a DeepSeek `file` part using `file_data`
56
- * instead of an `image_url` data URL. When set, the file part's filename
57
- * is preserved.
58
- *
59
- * This option only applies to inline image data. It cannot be combined
60
- * with `imageDetail`.
61
- */
62
- fileData: z.literal(true).optional()
63
- });
64
-
65
- // src/chat/deepseek-chat-language-model-options.ts
66
- import { z as z2 } from "zod/v4";
67
- var deepseekLanguageModelChatOptions = z2.object({
68
- /**
69
- * Whether to return log probabilities for generated tokens.
70
- */
71
- logprobs: z2.boolean().optional(),
72
- /**
73
- * Number of most likely tokens to return at each token position.
74
- *
75
- * Setting this option automatically enables `logprobs`.
76
- */
77
- topLogprobs: z2.number().int().min(0).max(20).optional(),
78
- /**
79
- * An opaque identifier for the end user. DeepSeek uses this identifier for
80
- * content-safety tracing and request isolation.
81
- *
82
- * Must contain only ASCII letters, numbers, underscores, and hyphens, and
83
- * must be at most 512 characters long.
84
- */
85
- 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(),
86
- /**
87
- * Type of thinking to use. Defaults to `enabled`.
88
- */
89
- thinking: z2.object({
90
- // `adaptive` is accepted at runtime for backwards compatibility and
91
- // mapped to `enabled`, but is intentionally excluded from the exported
92
- // provider options type.
93
- type: z2.enum(["adaptive", "enabled", "disabled"]).optional()
94
- }).optional(),
95
- /**
96
- * Controls the thinking strength for DeepSeek V4 reasoning models.
97
- */
98
- // `medium` and `xhigh` are accepted at runtime for backwards compatibility
99
- // and mapped to canonical DeepSeek values, but are intentionally excluded
100
- // from the exported provider options type.
101
- reasoningEffort: z2.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
102
- /**
103
- * Whether to use strict JSON schema validation for structured outputs.
104
- * Only applies when the serving endpoint supports JSON schema response
105
- * formats (e.g. Azure). Defaults to `true`.
106
- */
107
- strictJsonSchema: z2.boolean().optional()
108
- });
109
- var deepseekMessageProviderOptions = z2.object({
110
- /**
111
- * The name of the participant represented by the message.
112
- *
113
- * Supported on system, user, and assistant messages.
114
- */
115
- name: z2.string().optional()
4
+ //#region src/chat/deepseek-file-part-options.ts
5
+ const deepseekFilePartProviderOptions = z.object({
6
+ /**
7
+ * Controls how DeepSeek processes an image sent as an `image_url` part.
8
+ *
9
+ * @see https://api-docs.deepseek.com/api/create-chat-completion/
10
+ */
11
+ imageDetail: z.enum([
12
+ "low",
13
+ "high",
14
+ "original",
15
+ "auto"
16
+ ]).optional(),
17
+ /**
18
+ * Sends inline image data as a DeepSeek `file` part using `file_data`
19
+ * instead of an `image_url` data URL. When set, the file part's filename
20
+ * is preserved.
21
+ *
22
+ * This option only applies to inline image data. It cannot be combined
23
+ * with `imageDetail`.
24
+ */
25
+ fileData: z.literal(true).optional()
116
26
  });
117
- var deepseekAssistantMessageProviderOptions = deepseekMessageProviderOptions.extend({
118
- /**
119
- * Whether the assistant message content is a prefix that DeepSeek should
120
- * continue. This beta feature is only supported on the final assistant
121
- * message when using a beta base URL.
122
- */
123
- prefix: z2.literal(true).optional()
27
+ //#endregion
28
+ //#region src/chat/deepseek-chat-language-model-options.ts
29
+ const deepseekLanguageModelChatOptions = z.object({
30
+ /**
31
+ * Whether to return log probabilities for generated tokens.
32
+ */
33
+ logprobs: z.boolean().optional(),
34
+ /**
35
+ * Number of most likely tokens to return at each token position.
36
+ *
37
+ * Setting this option automatically enables `logprobs`.
38
+ */
39
+ topLogprobs: z.number().int().min(0).max(20).optional(),
40
+ /**
41
+ * An opaque identifier for the end user. DeepSeek uses this identifier for
42
+ * content-safety tracing and request isolation.
43
+ *
44
+ * Must contain only ASCII letters, numbers, underscores, and hyphens, and
45
+ * must be at most 512 characters long.
46
+ */
47
+ 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(),
48
+ /**
49
+ * Type of thinking to use. Defaults to `enabled`.
50
+ */
51
+ thinking: z.object({ type: z.enum([
52
+ "adaptive",
53
+ "enabled",
54
+ "disabled"
55
+ ]).optional() }).optional(),
56
+ /**
57
+ * Controls the thinking strength for DeepSeek V4 reasoning models.
58
+ */
59
+ reasoningEffort: z.enum([
60
+ "low",
61
+ "medium",
62
+ "high",
63
+ "xhigh",
64
+ "max"
65
+ ]).optional(),
66
+ /**
67
+ * Whether to use strict JSON schema validation for structured outputs.
68
+ * Only applies when the serving endpoint supports JSON schema response
69
+ * formats (e.g. Azure). Defaults to `true`.
70
+ */
71
+ strictJsonSchema: z.boolean().optional()
124
72
  });
125
-
126
- // src/chat/is-deepseek-v4-model.ts
73
+ const deepseekAssistantMessageProviderOptions = z.object({
74
+ /**
75
+ * The name of the participant represented by the message.
76
+ *
77
+ * Supported on system, user, and assistant messages.
78
+ */
79
+ name: z.string().optional() }).extend({
80
+ /**
81
+ * Whether the assistant message content is a prefix that DeepSeek should
82
+ * continue. This beta feature is only supported on the final assistant
83
+ * message when using a beta base URL.
84
+ */
85
+ prefix: z.literal(true).optional() });
86
+ //#endregion
87
+ //#region src/chat/is-deepseek-v4-model.ts
88
+ /**
89
+ * Whether a model id is a DeepSeek V4-generation model (thinking mode on by
90
+ * default, `reasoning_content` required on every assistant turn).
91
+ *
92
+ * DeepSeek publishes V4 models under both versioned ids (`deepseek-v4-pro`,
93
+ * `deepseek-v4-flash-*`) and unversioned aliases (`deepseek-flash`, currently
94
+ * serving V4.1 Flash). Only the legacy `deepseek-chat` / `deepseek-reasoner`
95
+ * ids predate V4.
96
+ */
127
97
  function isDeepSeekV4Model(modelId) {
128
- return modelId.includes("deepseek-v4") || modelId.startsWith("deepseek-flash") || modelId.startsWith("deepseek-pro");
98
+ return modelId.includes("deepseek-v4") || modelId.startsWith("deepseek-flash") || modelId.startsWith("deepseek-pro");
129
99
  }
130
-
131
- // src/chat/convert-to-deepseek-chat-messages.ts
132
- var supportedImageMediaTypes = /* @__PURE__ */ new Set([
133
- "image/gif",
134
- "image/jpeg",
135
- "image/jpg",
136
- "image/png",
137
- "image/webp"
100
+ //#endregion
101
+ //#region src/chat/convert-to-deepseek-chat-messages.ts
102
+ const supportedImageMediaTypes = /* @__PURE__ */ new Set([
103
+ "image/gif",
104
+ "image/jpeg",
105
+ "image/jpg",
106
+ "image/png",
107
+ "image/webp"
138
108
  ]);
139
109
  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;
110
+ const resolvedMediaType = resolveFullMediaType({ part });
111
+ if (!supportedImageMediaTypes.has(resolvedMediaType)) throw new UnsupportedFunctionalityError({
112
+ functionality: `DeepSeek image media type ${resolvedMediaType}`,
113
+ message: "DeepSeek supports JPEG, PNG, GIF, and WebP image inputs."
114
+ });
115
+ return resolvedMediaType;
148
116
  }
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
- }
117
+ function validateDeepSeekImageUrl({ url, prompt }) {
118
+ if (url.length > 8192) throw new InvalidPromptError({
119
+ prompt,
120
+ message: "DeepSeek image URLs must not exceed 8192 characters."
121
+ });
159
122
  }
160
- async function convertToDeepSeekChatMessages({
161
- prompt,
162
- responseFormat,
163
- modelId,
164
- providerOptionsName = "deepseek",
165
- supportsAssistantPrefixCompletion = false,
166
- supportsStructuredOutputs = false
167
- }) {
168
- const isDeepSeekV4 = isDeepSeekV4Model(modelId);
169
- const messages = [];
170
- const warnings = [];
171
- if (responseFormat?.type === "json") {
172
- if (responseFormat.schema == null) {
173
- messages.push({
174
- role: "system",
175
- content: "Return JSON."
176
- });
177
- } else if (!supportsStructuredOutputs) {
178
- messages.push({
179
- role: "system",
180
- content: "Return JSON that conforms to the following schema: " + JSON.stringify(responseFormat.schema)
181
- });
182
- warnings.push({
183
- type: "compatibility",
184
- feature: "responseFormat JSON schema",
185
- details: "JSON response schema is injected into the system message."
186
- });
187
- }
188
- }
189
- let lastUserMessageIndex = -1;
190
- for (let i = prompt.length - 1; i >= 0; i--) {
191
- if (prompt[i].role === "user") {
192
- lastUserMessageIndex = i;
193
- break;
194
- }
195
- }
196
- let index = -1;
197
- for (const { role, content, providerOptions } of prompt) {
198
- index++;
199
- const deepseekMessageOptions = await parseProviderOptions({
200
- provider: providerOptionsName,
201
- providerOptions,
202
- schema: deepseekAssistantMessageProviderOptions
203
- });
204
- if (deepseekMessageOptions?.prefix === true && role !== "assistant") {
205
- throw new InvalidPromptError({
206
- prompt,
207
- message: "DeepSeek assistant prefix completion requires `prefix: true` on an assistant message."
208
- });
209
- }
210
- switch (role) {
211
- case "system": {
212
- messages.push({
213
- role: "system",
214
- content,
215
- ...deepseekMessageOptions?.name != null && {
216
- name: deepseekMessageOptions.name
217
- }
218
- });
219
- break;
220
- }
221
- case "user": {
222
- const hasImagePart = content.some(
223
- (part) => part.type === "file" && (part.data.type === "reference" || part.data.type === "url" || part.data.type === "data") && getTopLevelMediaType(part.mediaType) === "image"
224
- );
225
- if (!hasImagePart) {
226
- let userContent2 = "";
227
- for (const part of content) {
228
- if (part.type === "text") {
229
- userContent2 += part.text;
230
- } else {
231
- warnings.push({
232
- type: "unsupported",
233
- feature: `user message part type: ${part.type}`
234
- });
235
- }
236
- }
237
- messages.push({
238
- role: "user",
239
- content: userContent2,
240
- ...deepseekMessageOptions?.name != null && {
241
- name: deepseekMessageOptions.name
242
- }
243
- });
244
- break;
245
- }
246
- const userContent = [];
247
- for (const part of content) {
248
- if (part.type === "text") {
249
- userContent.push({ type: "text", text: part.text });
250
- } else if (part.type === "file" && getTopLevelMediaType(part.mediaType) === "image") {
251
- const filePartOptions = await parseProviderOptions({
252
- provider: providerOptionsName,
253
- providerOptions: part.providerOptions,
254
- schema: deepseekFilePartProviderOptions
255
- });
256
- if (part.data.type === "reference") {
257
- userContent.push({
258
- type: "file",
259
- file_id: resolveProviderReference({
260
- reference: part.data.reference,
261
- provider: "deepseek"
262
- })
263
- });
264
- } else if (part.data.type === "url" || part.data.type === "data") {
265
- const resolvedMediaType = resolveDeepSeekImageMediaType(part);
266
- if (part.data.type === "url") {
267
- const url = part.data.url.toString();
268
- validateDeepSeekImageUrl({ url, prompt });
269
- if (filePartOptions?.fileData === true) {
270
- throw new InvalidPromptError({
271
- prompt,
272
- message: "DeepSeek `fileData` image parts require inline data, not a URL."
273
- });
274
- }
275
- userContent.push({
276
- type: "image_url",
277
- image_url: {
278
- url,
279
- ...filePartOptions?.imageDetail != null && {
280
- detail: filePartOptions.imageDetail
281
- }
282
- }
283
- });
284
- } else {
285
- const dataUrl = `data:${resolvedMediaType === "image/jpg" ? "image/jpeg" : resolvedMediaType};base64,${convertToBase64(part.data.data)}`;
286
- if (filePartOptions?.fileData === true) {
287
- if (filePartOptions.imageDetail != null) {
288
- throw new InvalidPromptError({
289
- prompt,
290
- message: "DeepSeek `imageDetail` cannot be combined with `fileData`."
291
- });
292
- }
293
- userContent.push({
294
- type: "file",
295
- file_data: dataUrl,
296
- ...part.filename != null && { filename: part.filename }
297
- });
298
- } else {
299
- userContent.push({
300
- type: "image_url",
301
- image_url: {
302
- url: dataUrl,
303
- ...filePartOptions?.imageDetail != null && {
304
- detail: filePartOptions.imageDetail
305
- }
306
- }
307
- });
308
- }
309
- }
310
- } else {
311
- warnings.push({
312
- type: "unsupported",
313
- feature: `user message part type: ${part.type}`
314
- });
315
- }
316
- } else {
317
- warnings.push({
318
- type: "unsupported",
319
- feature: `user message part type: ${part.type}`
320
- });
321
- }
322
- }
323
- messages.push({
324
- role: "user",
325
- content: userContent,
326
- ...deepseekMessageOptions?.name != null && {
327
- name: deepseekMessageOptions.name
328
- }
329
- });
330
- break;
331
- }
332
- case "assistant": {
333
- if (deepseekMessageOptions?.prefix === true) {
334
- if (index !== prompt.length - 1) {
335
- throw new InvalidPromptError({
336
- prompt,
337
- message: "DeepSeek assistant prefix completion requires the prefixed assistant message to be the final message."
338
- });
339
- }
340
- if (!supportsAssistantPrefixCompletion) {
341
- throw new UnsupportedFunctionalityError({
342
- functionality: "DeepSeek assistant prefix completion",
343
- message: "DeepSeek assistant prefix completion requires a beta base URL ending in `/beta`."
344
- });
345
- }
346
- }
347
- let text = "";
348
- let reasoning;
349
- const toolCalls = [];
350
- for (const part of content) {
351
- switch (part.type) {
352
- case "text": {
353
- text += part.text;
354
- break;
355
- }
356
- case "reasoning": {
357
- if (index <= lastUserMessageIndex && !isDeepSeekV4) {
358
- break;
359
- }
360
- if (reasoning == null) {
361
- reasoning = part.text;
362
- } else {
363
- reasoning += part.text;
364
- }
365
- break;
366
- }
367
- case "tool-call": {
368
- toolCalls.push({
369
- id: part.toolCallId,
370
- type: "function",
371
- function: {
372
- name: part.toolName,
373
- arguments: JSON.stringify(part.input)
374
- }
375
- });
376
- break;
377
- }
378
- }
379
- }
380
- messages.push({
381
- role: "assistant",
382
- content: text,
383
- ...deepseekMessageOptions?.name != null && {
384
- name: deepseekMessageOptions.name
385
- },
386
- ...deepseekMessageOptions?.prefix === true && {
387
- prefix: true
388
- },
389
- reasoning_content: reasoning ?? (isDeepSeekV4 ? "" : void 0),
390
- tool_calls: toolCalls.length > 0 ? toolCalls : void 0
391
- });
392
- break;
393
- }
394
- case "tool": {
395
- if (deepseekMessageOptions?.name != null) {
396
- warnings.push({
397
- type: "unsupported",
398
- feature: "message name on tool messages"
399
- });
400
- }
401
- for (const toolResponse of content) {
402
- if (toolResponse.type === "tool-approval-response") {
403
- continue;
404
- }
405
- const output = toolResponse.output;
406
- let contentValue;
407
- switch (output.type) {
408
- case "text":
409
- case "error-text":
410
- contentValue = output.value;
411
- break;
412
- case "execution-denied":
413
- contentValue = output.reason ?? "Tool call execution denied.";
414
- break;
415
- case "json":
416
- case "error-json":
417
- contentValue = JSON.stringify(output.value);
418
- break;
419
- case "content": {
420
- const hasImagePart = output.value.some(
421
- (part) => part.type === "file" && (part.data.type === "reference" || part.data.type === "url" || part.data.type === "data") && getTopLevelMediaType(part.mediaType) === "image"
422
- );
423
- if (!hasImagePart) {
424
- contentValue = JSON.stringify(output.value);
425
- break;
426
- }
427
- contentValue = [];
428
- for (const part of output.value) {
429
- if (part.type === "text") {
430
- contentValue.push({ type: "text", text: part.text });
431
- } else if (part.type === "file" && (part.data.type === "reference" || part.data.type === "url" || part.data.type === "data") && getTopLevelMediaType(part.mediaType) === "image") {
432
- if (part.data.type === "reference") {
433
- contentValue.push({
434
- type: "file",
435
- file_id: resolveProviderReference({
436
- reference: part.data.reference,
437
- provider: "deepseek"
438
- })
439
- });
440
- continue;
441
- }
442
- const filePartOptions = await parseProviderOptions({
443
- provider: providerOptionsName,
444
- providerOptions: part.providerOptions,
445
- schema: deepseekFilePartProviderOptions
446
- });
447
- const resolvedMediaType = resolveDeepSeekImageMediaType(part);
448
- let url;
449
- if (part.data.type === "url") {
450
- url = part.data.url.toString();
451
- validateDeepSeekImageUrl({ url, prompt });
452
- } else {
453
- url = `data:${resolvedMediaType === "image/jpg" ? "image/jpeg" : resolvedMediaType};base64,${convertToBase64(part.data.data)}`;
454
- }
455
- contentValue.push({
456
- type: "image_url",
457
- image_url: {
458
- url,
459
- ...filePartOptions?.imageDetail != null && {
460
- detail: filePartOptions.imageDetail
461
- }
462
- }
463
- });
464
- } else {
465
- warnings.push({
466
- type: "unsupported",
467
- feature: `tool result content part type: ${part.type}`
468
- });
469
- }
470
- }
471
- break;
472
- }
473
- }
474
- messages.push({
475
- role: "tool",
476
- tool_call_id: toolResponse.toolCallId,
477
- content: contentValue
478
- });
479
- }
480
- break;
481
- }
482
- default: {
483
- warnings.push({
484
- type: "unsupported",
485
- feature: `message role: ${role}`
486
- });
487
- break;
488
- }
489
- }
490
- }
491
- return { messages, warnings };
123
+ async function convertToDeepSeekChatMessages({ prompt, responseFormat, modelId, providerOptionsName = "deepseek", supportsAssistantPrefixCompletion = false, supportsStructuredOutputs = false }) {
124
+ const isDeepSeekV4 = isDeepSeekV4Model(modelId);
125
+ const messages = [];
126
+ const warnings = [];
127
+ if (responseFormat?.type === "json") {
128
+ if (responseFormat.schema == null) messages.push({
129
+ role: "system",
130
+ content: "Return JSON."
131
+ });
132
+ else if (!supportsStructuredOutputs) {
133
+ messages.push({
134
+ role: "system",
135
+ content: "Return JSON that conforms to the following schema: " + JSON.stringify(responseFormat.schema)
136
+ });
137
+ warnings.push({
138
+ type: "compatibility",
139
+ feature: "responseFormat JSON schema",
140
+ details: "JSON response schema is injected into the system message."
141
+ });
142
+ }
143
+ }
144
+ let lastUserMessageIndex = -1;
145
+ for (let i = prompt.length - 1; i >= 0; i--) if (prompt[i].role === "user") {
146
+ lastUserMessageIndex = i;
147
+ break;
148
+ }
149
+ let index = -1;
150
+ for (const { role, content, providerOptions } of prompt) {
151
+ index++;
152
+ const deepseekMessageOptions = await parseProviderOptions({
153
+ provider: providerOptionsName,
154
+ providerOptions,
155
+ schema: deepseekAssistantMessageProviderOptions
156
+ });
157
+ if (deepseekMessageOptions?.prefix === true && role !== "assistant") throw new InvalidPromptError({
158
+ prompt,
159
+ message: "DeepSeek assistant prefix completion requires `prefix: true` on an assistant message."
160
+ });
161
+ switch (role) {
162
+ case "system":
163
+ messages.push({
164
+ role: "system",
165
+ content,
166
+ ...deepseekMessageOptions?.name != null && { name: deepseekMessageOptions.name }
167
+ });
168
+ break;
169
+ case "user": {
170
+ if (!content.some((part) => part.type === "file" && (part.data.type === "reference" || part.data.type === "url" || part.data.type === "data") && getTopLevelMediaType(part.mediaType) === "image")) {
171
+ let userContent = "";
172
+ for (const part of content) if (part.type === "text") userContent += part.text;
173
+ else warnings.push({
174
+ type: "unsupported",
175
+ feature: `user message part type: ${part.type}`
176
+ });
177
+ messages.push({
178
+ role: "user",
179
+ content: userContent,
180
+ ...deepseekMessageOptions?.name != null && { name: deepseekMessageOptions.name }
181
+ });
182
+ break;
183
+ }
184
+ const userContent = [];
185
+ for (const part of content) if (part.type === "text") userContent.push({
186
+ type: "text",
187
+ text: part.text
188
+ });
189
+ else if (part.type === "file" && getTopLevelMediaType(part.mediaType) === "image") {
190
+ const filePartOptions = await parseProviderOptions({
191
+ provider: providerOptionsName,
192
+ providerOptions: part.providerOptions,
193
+ schema: deepseekFilePartProviderOptions
194
+ });
195
+ if (part.data.type === "reference") userContent.push({
196
+ type: "file",
197
+ file_id: resolveProviderReference({
198
+ reference: part.data.reference,
199
+ provider: "deepseek"
200
+ })
201
+ });
202
+ else if (part.data.type === "url" || part.data.type === "data") {
203
+ const resolvedMediaType = resolveDeepSeekImageMediaType(part);
204
+ if (part.data.type === "url") {
205
+ const url = part.data.url.toString();
206
+ validateDeepSeekImageUrl({
207
+ url,
208
+ prompt
209
+ });
210
+ if (filePartOptions?.fileData === true) throw new InvalidPromptError({
211
+ prompt,
212
+ message: "DeepSeek `fileData` image parts require inline data, not a URL."
213
+ });
214
+ userContent.push({
215
+ type: "image_url",
216
+ image_url: {
217
+ url,
218
+ ...filePartOptions?.imageDetail != null && { detail: filePartOptions.imageDetail }
219
+ }
220
+ });
221
+ } else {
222
+ const dataUrl = `data:${resolvedMediaType === "image/jpg" ? "image/jpeg" : resolvedMediaType};base64,${convertToBase64(part.data.data)}`;
223
+ if (filePartOptions?.fileData === true) {
224
+ if (filePartOptions.imageDetail != null) throw new InvalidPromptError({
225
+ prompt,
226
+ message: "DeepSeek `imageDetail` cannot be combined with `fileData`."
227
+ });
228
+ userContent.push({
229
+ type: "file",
230
+ file_data: dataUrl,
231
+ ...part.filename != null && { filename: part.filename }
232
+ });
233
+ } else userContent.push({
234
+ type: "image_url",
235
+ image_url: {
236
+ url: dataUrl,
237
+ ...filePartOptions?.imageDetail != null && { detail: filePartOptions.imageDetail }
238
+ }
239
+ });
240
+ }
241
+ } else warnings.push({
242
+ type: "unsupported",
243
+ feature: `user message part type: ${part.type}`
244
+ });
245
+ } else warnings.push({
246
+ type: "unsupported",
247
+ feature: `user message part type: ${part.type}`
248
+ });
249
+ messages.push({
250
+ role: "user",
251
+ content: userContent,
252
+ ...deepseekMessageOptions?.name != null && { name: deepseekMessageOptions.name }
253
+ });
254
+ break;
255
+ }
256
+ case "assistant": {
257
+ if (deepseekMessageOptions?.prefix === true) {
258
+ if (index !== prompt.length - 1) throw new InvalidPromptError({
259
+ prompt,
260
+ message: "DeepSeek assistant prefix completion requires the prefixed assistant message to be the final message."
261
+ });
262
+ if (!supportsAssistantPrefixCompletion) throw new UnsupportedFunctionalityError({
263
+ functionality: "DeepSeek assistant prefix completion",
264
+ message: "DeepSeek assistant prefix completion requires a beta base URL ending in `/beta`."
265
+ });
266
+ }
267
+ let text = "";
268
+ let reasoning;
269
+ const toolCalls = [];
270
+ for (const part of content) switch (part.type) {
271
+ case "text":
272
+ text += part.text;
273
+ break;
274
+ case "reasoning":
275
+ if (index <= lastUserMessageIndex && !isDeepSeekV4) break;
276
+ if (reasoning == null) reasoning = part.text;
277
+ else reasoning += part.text;
278
+ break;
279
+ case "tool-call": toolCalls.push({
280
+ id: part.toolCallId,
281
+ type: "function",
282
+ function: {
283
+ name: part.toolName,
284
+ arguments: JSON.stringify(part.input)
285
+ }
286
+ });
287
+ }
288
+ messages.push({
289
+ role: "assistant",
290
+ content: text,
291
+ ...deepseekMessageOptions?.name != null && { name: deepseekMessageOptions.name },
292
+ ...deepseekMessageOptions?.prefix === true && { prefix: true },
293
+ reasoning_content: reasoning ?? (isDeepSeekV4 ? "" : void 0),
294
+ tool_calls: toolCalls.length > 0 ? toolCalls : void 0
295
+ });
296
+ break;
297
+ }
298
+ case "tool":
299
+ if (deepseekMessageOptions?.name != null) warnings.push({
300
+ type: "unsupported",
301
+ feature: "message name on tool messages"
302
+ });
303
+ for (const toolResponse of content) {
304
+ if (toolResponse.type === "tool-approval-response") continue;
305
+ const output = toolResponse.output;
306
+ let contentValue;
307
+ switch (output.type) {
308
+ case "text":
309
+ case "error-text":
310
+ contentValue = output.value;
311
+ break;
312
+ case "execution-denied":
313
+ contentValue = output.reason ?? "Tool call execution denied.";
314
+ break;
315
+ case "json":
316
+ case "error-json":
317
+ contentValue = JSON.stringify(output.value);
318
+ break;
319
+ case "content":
320
+ if (!output.value.some((part) => part.type === "file" && (part.data.type === "reference" || part.data.type === "url" || part.data.type === "data") && getTopLevelMediaType(part.mediaType) === "image")) {
321
+ contentValue = JSON.stringify(output.value);
322
+ break;
323
+ }
324
+ contentValue = [];
325
+ for (const part of output.value) if (part.type === "text") contentValue.push({
326
+ type: "text",
327
+ text: part.text
328
+ });
329
+ else if (part.type === "file" && (part.data.type === "reference" || part.data.type === "url" || part.data.type === "data") && getTopLevelMediaType(part.mediaType) === "image") {
330
+ if (part.data.type === "reference") {
331
+ contentValue.push({
332
+ type: "file",
333
+ file_id: resolveProviderReference({
334
+ reference: part.data.reference,
335
+ provider: "deepseek"
336
+ })
337
+ });
338
+ continue;
339
+ }
340
+ const filePartOptions = await parseProviderOptions({
341
+ provider: providerOptionsName,
342
+ providerOptions: part.providerOptions,
343
+ schema: deepseekFilePartProviderOptions
344
+ });
345
+ const resolvedMediaType = resolveDeepSeekImageMediaType(part);
346
+ let url;
347
+ if (part.data.type === "url") {
348
+ url = part.data.url.toString();
349
+ validateDeepSeekImageUrl({
350
+ url,
351
+ prompt
352
+ });
353
+ } else url = `data:${resolvedMediaType === "image/jpg" ? "image/jpeg" : resolvedMediaType};base64,${convertToBase64(part.data.data)}`;
354
+ contentValue.push({
355
+ type: "image_url",
356
+ image_url: {
357
+ url,
358
+ ...filePartOptions?.imageDetail != null && { detail: filePartOptions.imageDetail }
359
+ }
360
+ });
361
+ } else warnings.push({
362
+ type: "unsupported",
363
+ feature: `tool result content part type: ${part.type}`
364
+ });
365
+ }
366
+ messages.push({
367
+ role: "tool",
368
+ tool_call_id: toolResponse.toolCallId,
369
+ content: contentValue
370
+ });
371
+ }
372
+ break;
373
+ default: warnings.push({
374
+ type: "unsupported",
375
+ feature: `message role: ${role}`
376
+ });
377
+ }
378
+ }
379
+ return {
380
+ messages,
381
+ warnings
382
+ };
492
383
  }
493
-
494
- // src/chat/convert-to-deepseek-usage.ts
495
- import { createNullLanguageModelUsage } from "@ai-sdk/provider-utils";
384
+ //#endregion
385
+ //#region src/chat/convert-to-deepseek-usage.ts
496
386
  function convertDeepSeekUsage(usage) {
497
- if (usage == null) {
498
- return createNullLanguageModelUsage();
499
- }
500
- const promptTokens = usage.prompt_tokens ?? 0;
501
- const completionTokens = usage.completion_tokens ?? 0;
502
- const cacheReadTokens = usage.prompt_cache_hit_tokens ?? 0;
503
- const reasoningTokens = usage.completion_tokens_details?.reasoning_tokens ?? 0;
504
- return {
505
- inputTokens: {
506
- total: promptTokens,
507
- noCache: promptTokens - cacheReadTokens,
508
- cacheRead: cacheReadTokens,
509
- cacheWrite: void 0
510
- },
511
- outputTokens: {
512
- total: completionTokens,
513
- text: Math.max(0, completionTokens - reasoningTokens),
514
- reasoning: reasoningTokens
515
- },
516
- raw: usage
517
- };
387
+ if (usage == null) return createNullLanguageModelUsage();
388
+ const promptTokens = usage.prompt_tokens ?? 0;
389
+ const completionTokens = usage.completion_tokens ?? 0;
390
+ const cacheReadTokens = usage.prompt_cache_hit_tokens ?? usage.prompt_tokens_details?.cached_tokens ?? 0;
391
+ const reasoningTokens = usage.completion_tokens_details?.reasoning_tokens ?? 0;
392
+ return {
393
+ inputTokens: {
394
+ total: promptTokens,
395
+ noCache: promptTokens - cacheReadTokens,
396
+ cacheRead: cacheReadTokens,
397
+ cacheWrite: void 0
398
+ },
399
+ outputTokens: {
400
+ total: completionTokens,
401
+ text: Math.max(0, completionTokens - reasoningTokens),
402
+ reasoning: reasoningTokens
403
+ },
404
+ raw: usage
405
+ };
518
406
  }
519
-
520
- // src/chat/deepseek-chat-api-types.ts
521
- import { lazySchema, zodSchema } from "@ai-sdk/provider-utils";
522
- import { z as z3 } from "zod/v4";
523
- var tokenUsageSchema = z3.looseObject({
524
- prompt_tokens: z3.number().nullish(),
525
- completion_tokens: z3.number().nullish(),
526
- prompt_cache_hit_tokens: z3.number().nullish(),
527
- prompt_cache_miss_tokens: z3.number().nullish(),
528
- total_tokens: z3.number().nullish(),
529
- prompt_tokens_details: z3.looseObject({
530
- cached_tokens: z3.number().nullish()
531
- }).nullish(),
532
- completion_tokens_details: z3.looseObject({
533
- reasoning_tokens: z3.number().nullish()
534
- }).nullish()
407
+ //#endregion
408
+ //#region src/chat/deepseek-chat-api-types.ts
409
+ const tokenUsageSchema = z.looseObject({
410
+ prompt_tokens: z.number().nullish(),
411
+ completion_tokens: z.number().nullish(),
412
+ prompt_cache_hit_tokens: z.number().nullish(),
413
+ prompt_cache_miss_tokens: z.number().nullish(),
414
+ total_tokens: z.number().nullish(),
415
+ prompt_tokens_details: z.looseObject({ cached_tokens: z.number().nullish() }).nullish(),
416
+ completion_tokens_details: z.looseObject({ reasoning_tokens: z.number().nullish() }).nullish()
535
417
  }).nullish();
536
- var deepSeekErrorSchema = z3.object({
537
- error: z3.object({
538
- message: z3.string(),
539
- type: z3.string().nullish(),
540
- param: z3.any().nullish(),
541
- code: z3.union([z3.string(), z3.number()]).nullish()
542
- })
543
- });
544
- var deepseekChatLogprobSchema = z3.object({
545
- token: z3.string(),
546
- logprob: z3.number(),
547
- bytes: z3.array(z3.number()).nullable(),
548
- top_logprobs: z3.array(
549
- z3.object({
550
- token: z3.string(),
551
- logprob: z3.number(),
552
- bytes: z3.array(z3.number()).nullable()
553
- })
554
- )
418
+ const deepSeekErrorSchema = z.object({ error: z.object({
419
+ message: z.string(),
420
+ type: z.string().nullish(),
421
+ param: z.any().nullish(),
422
+ code: z.union([z.string(), z.number()]).nullish()
423
+ }) });
424
+ const deepseekChatLogprobSchema = z.object({
425
+ token: z.string(),
426
+ logprob: z.number(),
427
+ bytes: z.array(z.number()).nullable(),
428
+ top_logprobs: z.array(z.object({
429
+ token: z.string(),
430
+ logprob: z.number(),
431
+ bytes: z.array(z.number()).nullable()
432
+ }))
555
433
  });
556
- var deepseekChatLogprobsSchema = z3.object({
557
- content: z3.array(deepseekChatLogprobSchema).nullish(),
558
- reasoning_content: z3.array(deepseekChatLogprobSchema).nullish()
434
+ const deepseekChatLogprobsSchema = z.object({
435
+ content: z.array(deepseekChatLogprobSchema).nullish(),
436
+ reasoning_content: z.array(deepseekChatLogprobSchema).nullish()
559
437
  }).nullish();
560
- var deepseekChatResponseSchema = z3.object({
561
- id: z3.string().nullish(),
562
- created: z3.number().nullish(),
563
- model: z3.string().nullish(),
564
- object: z3.literal("chat.completion").nullish(),
565
- system_fingerprint: z3.string().nullish(),
566
- choices: z3.array(
567
- z3.object({
568
- index: z3.number().nullish(),
569
- message: z3.object({
570
- role: z3.literal("assistant").nullish(),
571
- content: z3.string().nullish(),
572
- reasoning_content: z3.string().nullish(),
573
- tool_calls: z3.array(
574
- z3.object({
575
- id: z3.string().nullish(),
576
- type: z3.literal("function").nullish(),
577
- function: z3.object({
578
- name: z3.string(),
579
- arguments: z3.string()
580
- })
581
- })
582
- ).nullish()
583
- }),
584
- logprobs: deepseekChatLogprobsSchema,
585
- finish_reason: z3.string().nullish()
586
- })
587
- ),
588
- usage: tokenUsageSchema
438
+ const deepseekChatResponseSchema = z.object({
439
+ id: z.string().nullish(),
440
+ created: z.number().nullish(),
441
+ model: z.string().nullish(),
442
+ object: z.literal("chat.completion").nullish(),
443
+ system_fingerprint: z.string().nullish(),
444
+ choices: z.array(z.object({
445
+ index: z.number().nullish(),
446
+ message: z.object({
447
+ role: z.literal("assistant").nullish(),
448
+ content: z.string().nullish(),
449
+ reasoning_content: z.string().nullish(),
450
+ tool_calls: z.array(z.object({
451
+ id: z.string().nullish(),
452
+ type: z.literal("function").nullish(),
453
+ function: z.object({
454
+ name: z.string(),
455
+ arguments: z.string()
456
+ })
457
+ })).nullish()
458
+ }),
459
+ logprobs: deepseekChatLogprobsSchema,
460
+ finish_reason: z.string().nullish()
461
+ })),
462
+ usage: tokenUsageSchema
589
463
  });
590
- var deepseekChatChunkSchema = lazySchema(
591
- () => zodSchema(
592
- z3.union([
593
- z3.object({
594
- id: z3.string().nullish(),
595
- created: z3.number().nullish(),
596
- model: z3.string().nullish(),
597
- object: z3.literal("chat.completion.chunk").nullish(),
598
- system_fingerprint: z3.string().nullish(),
599
- choices: z3.array(
600
- z3.object({
601
- index: z3.number().nullish(),
602
- delta: z3.object({
603
- role: z3.enum(["assistant"]).nullish(),
604
- content: z3.string().nullish(),
605
- reasoning_content: z3.string().nullish(),
606
- tool_calls: z3.array(
607
- z3.object({
608
- index: z3.number(),
609
- id: z3.string().nullish(),
610
- type: z3.literal("function").nullish(),
611
- function: z3.object({
612
- name: z3.string().nullish(),
613
- arguments: z3.string().nullish()
614
- })
615
- })
616
- ).nullish()
617
- }).nullish(),
618
- logprobs: deepseekChatLogprobsSchema,
619
- finish_reason: z3.string().nullish()
620
- })
621
- ),
622
- usage: tokenUsageSchema
623
- }),
624
- deepSeekErrorSchema
625
- ])
626
- )
627
- );
628
-
629
- // src/chat/deepseek-prepare-tools.ts
630
- import {
631
- UnsupportedFunctionalityError as UnsupportedFunctionalityError2
632
- } from "@ai-sdk/provider";
633
- function prepareTools({
634
- tools,
635
- toolChoice,
636
- supportsStrictToolCalls
637
- }) {
638
- tools = tools?.length ? tools : void 0;
639
- const toolWarnings = [];
640
- if (tools == null) {
641
- return { tools: void 0, toolChoice: void 0, toolWarnings };
642
- }
643
- const functionTools = tools.filter((tool) => tool.type === "function");
644
- const hasStrictTool = functionTools.some((tool) => tool.strict === true);
645
- if (hasStrictTool && supportsStrictToolCalls === false) {
646
- throw new UnsupportedFunctionalityError2({
647
- functionality: "DeepSeek strict tool calls",
648
- message: "DeepSeek strict tool calls require a beta base URL ending in `/beta`."
649
- });
650
- }
651
- if (hasStrictTool && supportsStrictToolCalls === true && functionTools.some((tool) => tool.strict !== true)) {
652
- throw new UnsupportedFunctionalityError2({
653
- functionality: "mixed DeepSeek strict and non-strict tool calls",
654
- message: "DeepSeek strict mode requires every function tool in the request to set `strict: true`."
655
- });
656
- }
657
- const deepseekTools = [];
658
- for (const tool of tools) {
659
- if (tool.type === "provider") {
660
- toolWarnings.push({
661
- type: "unsupported",
662
- feature: `provider-defined tool ${tool.id}`
663
- });
664
- } else {
665
- deepseekTools.push({
666
- type: "function",
667
- function: {
668
- name: tool.name,
669
- description: tool.description,
670
- parameters: tool.inputSchema,
671
- ...tool.strict != null ? { strict: tool.strict } : {}
672
- }
673
- });
674
- }
675
- }
676
- if (toolChoice == null) {
677
- return { tools: deepseekTools, toolChoice: void 0, toolWarnings };
678
- }
679
- const type = toolChoice?.type;
680
- switch (type) {
681
- case "auto":
682
- case "none":
683
- case "required":
684
- return { tools: deepseekTools, toolChoice: type, toolWarnings };
685
- case "tool":
686
- return {
687
- tools: deepseekTools,
688
- toolChoice: {
689
- type: "function",
690
- function: { name: toolChoice.toolName }
691
- },
692
- toolWarnings
693
- };
694
- default: {
695
- return {
696
- tools: deepseekTools,
697
- toolChoice: void 0,
698
- toolWarnings: [
699
- ...toolWarnings,
700
- {
701
- type: "unsupported",
702
- feature: `tool choice type: ${type}`
703
- }
704
- ]
705
- };
706
- }
707
- }
464
+ const deepseekChatChunkSchema = lazySchema(() => zodSchema(z.union([z.object({
465
+ id: z.string().nullish(),
466
+ created: z.number().nullish(),
467
+ model: z.string().nullish(),
468
+ object: z.literal("chat.completion.chunk").nullish(),
469
+ system_fingerprint: z.string().nullish(),
470
+ choices: z.array(z.object({
471
+ index: z.number().nullish(),
472
+ delta: z.object({
473
+ role: z.enum(["assistant"]).nullish(),
474
+ content: z.string().nullish(),
475
+ reasoning_content: z.string().nullish(),
476
+ tool_calls: z.array(z.object({
477
+ index: z.number(),
478
+ id: z.string().nullish(),
479
+ type: z.literal("function").nullish(),
480
+ function: z.object({
481
+ name: z.string().nullish(),
482
+ arguments: z.string().nullish()
483
+ })
484
+ })).nullish()
485
+ }).nullish(),
486
+ logprobs: deepseekChatLogprobsSchema,
487
+ finish_reason: z.string().nullish()
488
+ })),
489
+ usage: tokenUsageSchema
490
+ }), deepSeekErrorSchema])));
491
+ //#endregion
492
+ //#region src/chat/deepseek-prepare-tools.ts
493
+ function prepareTools({ tools, toolChoice, supportsStrictToolCalls }) {
494
+ tools = tools?.length ? tools : void 0;
495
+ const toolWarnings = [];
496
+ if (tools == null) return {
497
+ tools: void 0,
498
+ toolChoice: void 0,
499
+ toolWarnings
500
+ };
501
+ const functionTools = tools.filter((tool) => tool.type === "function");
502
+ const hasStrictTool = functionTools.some((tool) => tool.strict === true);
503
+ if (hasStrictTool && supportsStrictToolCalls === false) throw new UnsupportedFunctionalityError({
504
+ functionality: "DeepSeek strict tool calls",
505
+ message: "DeepSeek strict tool calls require a beta base URL ending in `/beta`."
506
+ });
507
+ if (hasStrictTool && supportsStrictToolCalls === true && functionTools.some((tool) => tool.strict !== true)) throw new UnsupportedFunctionalityError({
508
+ functionality: "mixed DeepSeek strict and non-strict tool calls",
509
+ message: "DeepSeek strict mode requires every function tool in the request to set `strict: true`."
510
+ });
511
+ const deepseekTools = [];
512
+ for (const tool of tools) if (tool.type === "provider") toolWarnings.push({
513
+ type: "unsupported",
514
+ feature: `provider-defined tool ${tool.id}`
515
+ });
516
+ else deepseekTools.push({
517
+ type: "function",
518
+ function: {
519
+ name: tool.name,
520
+ description: tool.description,
521
+ parameters: tool.inputSchema,
522
+ ...tool.strict != null ? { strict: tool.strict } : {}
523
+ }
524
+ });
525
+ if (toolChoice == null) return {
526
+ tools: deepseekTools,
527
+ toolChoice: void 0,
528
+ toolWarnings
529
+ };
530
+ const type = toolChoice?.type;
531
+ switch (type) {
532
+ case "auto":
533
+ case "none":
534
+ case "required": return {
535
+ tools: deepseekTools,
536
+ toolChoice: type,
537
+ toolWarnings
538
+ };
539
+ case "tool": return {
540
+ tools: deepseekTools,
541
+ toolChoice: {
542
+ type: "function",
543
+ function: { name: toolChoice.toolName }
544
+ },
545
+ toolWarnings
546
+ };
547
+ default: return {
548
+ tools: deepseekTools,
549
+ toolChoice: void 0,
550
+ toolWarnings: [...toolWarnings, {
551
+ type: "unsupported",
552
+ feature: `tool choice type: ${type}`
553
+ }]
554
+ };
555
+ }
708
556
  }
709
-
710
- // src/chat/get-response-metadata.ts
711
- import { createLanguageModelResponseMetadata } from "@ai-sdk/provider-utils";
712
-
713
- // src/chat/map-deepseek-finish-reason.ts
557
+ //#endregion
558
+ //#region src/chat/map-deepseek-finish-reason.ts
714
559
  function mapDeepSeekFinishReason(finishReason) {
715
- switch (finishReason) {
716
- case "stop":
717
- return "stop";
718
- case "length":
719
- return "length";
720
- case "content_filter":
721
- return "content-filter";
722
- case "tool_calls":
723
- return "tool-calls";
724
- case "insufficient_system_resource":
725
- return "error";
726
- default:
727
- return "other";
728
- }
560
+ switch (finishReason) {
561
+ case "stop": return "stop";
562
+ case "length": return "length";
563
+ case "content_filter": return "content-filter";
564
+ case "tool_calls": return "tool-calls";
565
+ case "insufficient_system_resource": return "error";
566
+ default: return "other";
567
+ }
729
568
  }
730
-
731
- // src/chat/deepseek-chat-language-model.ts
569
+ //#endregion
570
+ //#region src/chat/deepseek-chat-language-model.ts
732
571
  function createDeepSeekStreamError(error, data) {
733
- const metadata = getDeepSeekStreamErrorMetadata(error);
734
- return createProviderStreamError({
735
- message: error.message,
736
- type: error.type ?? void 0,
737
- code: error.code ?? void 0,
738
- ...metadata,
739
- data
740
- });
572
+ const metadata = getDeepSeekStreamErrorMetadata(error);
573
+ return createProviderStreamError({
574
+ message: error.message,
575
+ type: error.type ?? void 0,
576
+ code: error.code ?? void 0,
577
+ ...metadata,
578
+ data
579
+ });
741
580
  }
742
581
  function getDeepSeekStreamErrorMetadata(error) {
743
- if (error.code === "insufficient_quota" || error.type === "insufficient_quota") {
744
- return { statusCode: 429, isRetryable: false };
745
- }
746
- const explicitStatusCode = getHttpStatusCode(error.code);
747
- if (explicitStatusCode != null) {
748
- return {
749
- statusCode: explicitStatusCode,
750
- isRetryable: isRetryableStatusCode(explicitStatusCode)
751
- };
752
- }
753
- for (const discriminator of [error.code, error.type]) {
754
- switch (discriminator) {
755
- case "rate_limit_exceeded":
756
- case "rate_limit_error":
757
- return { statusCode: 429, isRetryable: true };
758
- case "server_error":
759
- case "api_error":
760
- case "internal_server_error":
761
- return { statusCode: 500, isRetryable: true };
762
- case "overloaded_error":
763
- case "service_unavailable":
764
- return { statusCode: 503, isRetryable: true };
765
- case "timeout":
766
- case "timeout_error":
767
- return { statusCode: 504, isRetryable: true };
768
- case "authentication_error":
769
- case "invalid_api_key":
770
- return { statusCode: 401, isRetryable: false };
771
- case "permission_error":
772
- return { statusCode: 403, isRetryable: false };
773
- case "not_found_error":
774
- case "model_not_found":
775
- return { statusCode: 404, isRetryable: false };
776
- case "bad_request":
777
- case "context_length_exceeded":
778
- case "invalid_request_error":
779
- return { statusCode: 400, isRetryable: false };
780
- }
781
- }
782
- return {};
582
+ if (error.code === "insufficient_quota" || error.type === "insufficient_quota") return {
583
+ statusCode: 429,
584
+ isRetryable: false
585
+ };
586
+ const explicitStatusCode = getHttpStatusCode(error.code);
587
+ if (explicitStatusCode != null) return {
588
+ statusCode: explicitStatusCode,
589
+ isRetryable: isRetryableStatusCode(explicitStatusCode)
590
+ };
591
+ for (const discriminator of [error.code, error.type]) switch (discriminator) {
592
+ case "rate_limit_exceeded":
593
+ case "rate_limit_error": return {
594
+ statusCode: 429,
595
+ isRetryable: true
596
+ };
597
+ case "server_error":
598
+ case "api_error":
599
+ case "internal_server_error": return {
600
+ statusCode: 500,
601
+ isRetryable: true
602
+ };
603
+ case "overloaded_error":
604
+ case "service_unavailable": return {
605
+ statusCode: 503,
606
+ isRetryable: true
607
+ };
608
+ case "timeout":
609
+ case "timeout_error": return {
610
+ statusCode: 504,
611
+ isRetryable: true
612
+ };
613
+ case "authentication_error":
614
+ case "invalid_api_key": return {
615
+ statusCode: 401,
616
+ isRetryable: false
617
+ };
618
+ case "permission_error": return {
619
+ statusCode: 403,
620
+ isRetryable: false
621
+ };
622
+ case "not_found_error":
623
+ case "model_not_found": return {
624
+ statusCode: 404,
625
+ isRetryable: false
626
+ };
627
+ case "bad_request":
628
+ case "context_length_exceeded":
629
+ case "invalid_request_error": return {
630
+ statusCode: 400,
631
+ isRetryable: false
632
+ };
633
+ }
634
+ return {};
783
635
  }
784
636
  function getHttpStatusCode(value) {
785
- const statusCode = typeof value === "string" && /^\d{3}$/.test(value) ? Number(value) : value;
786
- return typeof statusCode === "number" && Number.isInteger(statusCode) && statusCode >= 400 && statusCode <= 599 ? statusCode : void 0;
637
+ const statusCode = typeof value === "string" && /^\d{3}$/.test(value) ? Number(value) : value;
638
+ return typeof statusCode === "number" && Number.isInteger(statusCode) && statusCode >= 400 && statusCode <= 599 ? statusCode : void 0;
787
639
  }
788
640
  function isRetryableStatusCode(statusCode) {
789
- return statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500;
641
+ return statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500;
790
642
  }
791
- function mapDeepSeekProviderReasoningEffort({
792
- reasoningEffort,
793
- warnings
794
- }) {
795
- const mapped = reasoningEffort === "medium" ? "high" : reasoningEffort === "xhigh" ? "max" : reasoningEffort;
796
- if (mapped !== reasoningEffort) {
797
- warnings.push({
798
- type: "compatibility",
799
- feature: "reasoningEffort",
800
- details: `reasoningEffort "${reasoningEffort}" is not a canonical DeepSeek value. mapped to "${mapped}".`
801
- });
802
- }
803
- return mapped;
643
+ function mapDeepSeekProviderReasoningEffort({ reasoningEffort, warnings }) {
644
+ const mapped = reasoningEffort === "medium" ? "high" : reasoningEffort === "xhigh" ? "max" : reasoningEffort;
645
+ if (mapped !== reasoningEffort) warnings.push({
646
+ type: "compatibility",
647
+ feature: "reasoningEffort",
648
+ details: `reasoningEffort "${reasoningEffort}" is not a canonical DeepSeek value. mapped to "${mapped}".`
649
+ });
650
+ return mapped;
804
651
  }
805
- var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
806
- constructor(modelId, config) {
807
- this.specificationVersion = "v4";
808
- this.supportedUrls = {
809
- "image/*": [/^https?:\/\/.*$/]
810
- };
811
- this.modelId = modelId;
812
- this.config = config;
813
- this.failedResponseHandler = createJsonErrorResponseHandler({
814
- errorSchema: deepSeekErrorSchema,
815
- errorToMessage: (error) => error.error.message
816
- });
817
- }
818
- static [WORKFLOW_SERIALIZE](model) {
819
- return serializeModelOptions({
820
- modelId: model.modelId,
821
- config: model.config
822
- });
823
- }
824
- static [WORKFLOW_DESERIALIZE](options) {
825
- return new _DeepSeekChatLanguageModel(options.modelId, options.config);
826
- }
827
- get provider() {
828
- return this.config.provider;
829
- }
830
- get providerOptionsName() {
831
- return this.config.provider.split(".")[0].trim();
832
- }
833
- async getArgs({
834
- prompt,
835
- maxOutputTokens,
836
- temperature,
837
- topP,
838
- topK,
839
- frequencyPenalty,
840
- presencePenalty,
841
- reasoning,
842
- providerOptions,
843
- stopSequences,
844
- responseFormat,
845
- seed,
846
- toolChoice,
847
- tools
848
- }) {
849
- const deepseekOptions = await parseProviderOptions2({
850
- provider: this.providerOptionsName,
851
- providerOptions,
852
- schema: deepseekLanguageModelChatOptions
853
- }) ?? {};
854
- const supportsStructuredOutputs = this.config.supportsStructuredOutputs === true;
855
- const supportsPenaltySampling = this.config.supportsPenaltySampling === true;
856
- const { messages, warnings } = await convertToDeepSeekChatMessages({
857
- prompt,
858
- responseFormat,
859
- modelId: this.modelId,
860
- providerOptionsName: this.providerOptionsName,
861
- supportsAssistantPrefixCompletion: this.config.supportsAssistantPrefixCompletion,
862
- supportsStructuredOutputs
863
- });
864
- const allWarnings = [...warnings];
865
- if (topK != null) {
866
- allWarnings.push({ type: "unsupported", feature: "topK" });
867
- }
868
- if (seed != null) {
869
- allWarnings.push({ type: "unsupported", feature: "seed" });
870
- }
871
- if (!supportsPenaltySampling && frequencyPenalty != null) {
872
- allWarnings.push({
873
- type: "deprecated",
874
- setting: "frequencyPenalty",
875
- message: "frequencyPenalty is deprecated by DeepSeek and has been omitted. Remove frequencyPenalty from the request."
876
- });
877
- }
878
- if (!supportsPenaltySampling && presencePenalty != null) {
879
- allWarnings.push({
880
- type: "deprecated",
881
- setting: "presencePenalty",
882
- message: "presencePenalty is deprecated by DeepSeek and has been omitted. Remove presencePenalty from the request."
883
- });
884
- }
885
- const {
886
- tools: deepseekTools,
887
- toolChoice: deepseekToolChoices,
888
- toolWarnings
889
- } = prepareTools({
890
- tools,
891
- toolChoice,
892
- supportsStrictToolCalls: this.config.supportsStrictToolCalls
893
- });
894
- const thinkingType = deepseekOptions.thinking?.type;
895
- if (thinkingType === "adaptive") {
896
- allWarnings.push({
897
- type: "compatibility",
898
- feature: "thinking.type",
899
- details: 'thinking.type "adaptive" is not a canonical DeepSeek value. mapped to "enabled".'
900
- });
901
- }
902
- const thinking = this.config.supportsThinking === false ? void 0 : thinkingType != null ? { type: thinkingType === "adaptive" ? "enabled" : thinkingType } : isCustomReasoning(reasoning) ? { type: reasoning === "none" ? "disabled" : "enabled" } : void 0;
903
- const isThinkingEnabled = this.config.supportsThinking !== false && thinking?.type !== "disabled" && (thinking != null || this.modelId === "deepseek-reasoner" || isDeepSeekV4Model(this.modelId));
904
- if (isThinkingEnabled && temperature != null) {
905
- allWarnings.push({
906
- type: "unsupported",
907
- feature: "temperature",
908
- details: "temperature has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use temperature."
909
- });
910
- }
911
- if (isThinkingEnabled && topP != null) {
912
- allWarnings.push({
913
- type: "unsupported",
914
- feature: "topP",
915
- details: "topP has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use topP."
916
- });
917
- }
918
- const reasoningEffort = deepseekOptions.reasoningEffort != null ? mapDeepSeekProviderReasoningEffort({
919
- reasoningEffort: deepseekOptions.reasoningEffort,
920
- warnings: allWarnings
921
- }) : isCustomReasoning(reasoning) && reasoning !== "none" ? mapReasoningToProviderEffort({
922
- reasoning,
923
- effortMap: {
924
- minimal: "low",
925
- low: "low",
926
- medium: "high",
927
- high: "high",
928
- xhigh: "max"
929
- },
930
- warnings: allWarnings
931
- }) : void 0;
932
- return {
933
- args: {
934
- model: this.modelId,
935
- ...(deepseekOptions.logprobs === true || deepseekOptions.topLogprobs != null) && { logprobs: true },
936
- ...deepseekOptions.topLogprobs != null && {
937
- top_logprobs: deepseekOptions.topLogprobs
938
- },
939
- max_tokens: maxOutputTokens,
940
- temperature: isThinkingEnabled ? void 0 : temperature,
941
- top_p: isThinkingEnabled ? void 0 : topP,
942
- frequency_penalty: supportsPenaltySampling ? frequencyPenalty : void 0,
943
- presence_penalty: supportsPenaltySampling ? presencePenalty : void 0,
944
- response_format: responseFormat?.type === "json" ? supportsStructuredOutputs && responseFormat.schema != null ? {
945
- type: "json_schema",
946
- json_schema: {
947
- schema: responseFormat.schema,
948
- strict: deepseekOptions.strictJsonSchema ?? true,
949
- name: responseFormat.name ?? "response",
950
- description: responseFormat.description
951
- }
952
- } : { type: "json_object" } : void 0,
953
- stop: stopSequences,
954
- messages,
955
- tools: deepseekTools,
956
- tool_choice: deepseekToolChoices,
957
- thinking,
958
- ...deepseekOptions.userId != null && {
959
- user_id: deepseekOptions.userId
960
- },
961
- ...thinking?.type !== "disabled" && reasoningEffort != null && {
962
- reasoning_effort: reasoningEffort
963
- }
964
- },
965
- warnings: [...allWarnings, ...toolWarnings]
966
- };
967
- }
968
- async doGenerate(options) {
969
- const { args, warnings } = await this.getArgs({ ...options });
970
- const {
971
- responseHeaders,
972
- value: responseBody,
973
- rawValue: rawResponse
974
- } = await postJsonToApi({
975
- url: this.config.url({
976
- path: "/chat/completions",
977
- modelId: this.modelId
978
- }),
979
- headers: combineHeaders(this.config.headers?.(), options.headers),
980
- body: args,
981
- failedResponseHandler: this.failedResponseHandler,
982
- successfulResponseHandler: createJsonResponseHandler(
983
- deepseekChatResponseSchema
984
- ),
985
- abortSignal: options.abortSignal,
986
- fetch: this.config.fetch
987
- });
988
- const choice = responseBody.choices[0];
989
- if (choice == null) {
990
- throw new InvalidResponseDataError({
991
- data: rawResponse,
992
- message: "Response did not contain any choices."
993
- });
994
- }
995
- const content = [];
996
- const reasoning = choice.message.reasoning_content;
997
- if (reasoning != null && reasoning.length > 0) {
998
- content.push({
999
- type: "reasoning",
1000
- text: reasoning
1001
- });
1002
- }
1003
- if (choice.message.tool_calls != null) {
1004
- for (const toolCall of choice.message.tool_calls) {
1005
- content.push({
1006
- type: "tool-call",
1007
- toolCallId: toolCall.id || generateId(),
1008
- toolName: toolCall.function.name,
1009
- input: toolCall.function.arguments
1010
- });
1011
- }
1012
- }
1013
- const text = choice.message.content;
1014
- if (text != null && text.length > 0) {
1015
- content.push({ type: "text", text });
1016
- }
1017
- return {
1018
- content,
1019
- finishReason: {
1020
- unified: mapDeepSeekFinishReason(choice.finish_reason),
1021
- raw: choice.finish_reason ?? void 0
1022
- },
1023
- usage: convertDeepSeekUsage(responseBody.usage),
1024
- providerMetadata: {
1025
- [this.providerOptionsName]: {
1026
- promptCacheHitTokens: responseBody.usage?.prompt_cache_hit_tokens,
1027
- promptCacheMissTokens: responseBody.usage?.prompt_cache_miss_tokens,
1028
- ...responseBody.object != null && {
1029
- responseObject: responseBody.object
1030
- },
1031
- ...choice.index != null && { choiceIndex: choice.index },
1032
- ...choice.message.role != null && {
1033
- messageRole: choice.message.role
1034
- },
1035
- ...choice.message.tool_calls != null && {
1036
- toolCallTypes: choice.message.tool_calls.map((toolCall) => toolCall.type).filter((type) => type != null)
1037
- },
1038
- ...choice.logprobs != null && { logprobs: choice.logprobs },
1039
- ...responseBody.system_fingerprint != null && {
1040
- systemFingerprint: responseBody.system_fingerprint
1041
- }
1042
- }
1043
- },
1044
- request: { body: args },
1045
- response: {
1046
- ...createLanguageModelResponseMetadata(responseBody),
1047
- headers: responseHeaders,
1048
- body: rawResponse
1049
- },
1050
- warnings
1051
- };
1052
- }
1053
- async doStream(options) {
1054
- const { args, warnings } = await this.getArgs({ ...options });
1055
- const body = {
1056
- ...args,
1057
- stream: true,
1058
- stream_options: { include_usage: true }
1059
- };
1060
- const { responseHeaders, value: response } = await postJsonToApi({
1061
- url: this.config.url({
1062
- path: "/chat/completions",
1063
- modelId: this.modelId
1064
- }),
1065
- headers: combineHeaders(this.config.headers?.(), options.headers),
1066
- body,
1067
- failedResponseHandler: this.failedResponseHandler,
1068
- successfulResponseHandler: createEventSourceResponseHandler(
1069
- deepseekChatChunkSchema
1070
- ),
1071
- abortSignal: options.abortSignal,
1072
- fetch: this.config.fetch
1073
- });
1074
- let toolCallTracker;
1075
- let finishReason = {
1076
- unified: "other",
1077
- raw: void 0
1078
- };
1079
- let usage = void 0;
1080
- let systemFingerprint = void 0;
1081
- let isFirstChunk = true;
1082
- const providerOptionsName = this.providerOptionsName;
1083
- let isActiveReasoning = false;
1084
- let isActiveText = false;
1085
- let responseObject;
1086
- let choiceIndex;
1087
- let messageRole;
1088
- const toolCallTypes = /* @__PURE__ */ new Map();
1089
- const contentLogprobs = [];
1090
- const reasoningLogprobs = [];
1091
- return {
1092
- stream: response.pipeThrough(
1093
- new TransformStream({
1094
- start(controller) {
1095
- toolCallTracker = new StreamingToolCallTracker(controller, {
1096
- generateId
1097
- });
1098
- controller.enqueue({ type: "stream-start", warnings });
1099
- },
1100
- transform(chunk, controller) {
1101
- if (options.includeRawChunks) {
1102
- controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
1103
- }
1104
- if (!chunk.success) {
1105
- finishReason = { unified: "error", raw: void 0 };
1106
- controller.enqueue({ type: "error", error: chunk.error });
1107
- return;
1108
- }
1109
- const value = chunk.value;
1110
- if ("error" in value) {
1111
- finishReason = { unified: "error", raw: void 0 };
1112
- controller.enqueue({
1113
- type: "error",
1114
- error: createDeepSeekStreamError(value.error, value)
1115
- });
1116
- return;
1117
- }
1118
- if (isFirstChunk) {
1119
- isFirstChunk = false;
1120
- controller.enqueue({
1121
- type: "response-metadata",
1122
- ...createLanguageModelResponseMetadata(value)
1123
- });
1124
- }
1125
- if (value.usage != null) {
1126
- usage = value.usage;
1127
- }
1128
- if (value.object != null) {
1129
- responseObject = value.object;
1130
- }
1131
- if (value.system_fingerprint != null) {
1132
- systemFingerprint = value.system_fingerprint;
1133
- }
1134
- const choice = value.choices[0];
1135
- if (choice?.index != null) {
1136
- choiceIndex = choice.index;
1137
- }
1138
- if (choice?.finish_reason != null) {
1139
- finishReason = {
1140
- unified: mapDeepSeekFinishReason(choice.finish_reason),
1141
- raw: choice.finish_reason
1142
- };
1143
- }
1144
- if (choice?.logprobs?.content != null) {
1145
- contentLogprobs.push(...choice.logprobs.content);
1146
- }
1147
- if (choice?.logprobs?.reasoning_content != null) {
1148
- reasoningLogprobs.push(...choice.logprobs.reasoning_content);
1149
- }
1150
- if (choice?.delta == null) {
1151
- return;
1152
- }
1153
- const delta = choice.delta;
1154
- if (delta.role != null) {
1155
- messageRole = delta.role;
1156
- }
1157
- const reasoningContent = delta.reasoning_content;
1158
- if (reasoningContent) {
1159
- if (!isActiveReasoning) {
1160
- controller.enqueue({
1161
- type: "reasoning-start",
1162
- id: "reasoning-0"
1163
- });
1164
- isActiveReasoning = true;
1165
- }
1166
- controller.enqueue({
1167
- type: "reasoning-delta",
1168
- id: "reasoning-0",
1169
- delta: reasoningContent
1170
- });
1171
- }
1172
- if (delta.content) {
1173
- if (!isActiveText) {
1174
- controller.enqueue({ type: "text-start", id: "txt-0" });
1175
- isActiveText = true;
1176
- }
1177
- if (isActiveReasoning) {
1178
- controller.enqueue({
1179
- type: "reasoning-end",
1180
- id: "reasoning-0"
1181
- });
1182
- isActiveReasoning = false;
1183
- }
1184
- controller.enqueue({
1185
- type: "text-delta",
1186
- id: "txt-0",
1187
- delta: delta.content
1188
- });
1189
- }
1190
- if (delta.tool_calls != null && delta.tool_calls.length > 0) {
1191
- if (isActiveReasoning) {
1192
- controller.enqueue({
1193
- type: "reasoning-end",
1194
- id: "reasoning-0"
1195
- });
1196
- isActiveReasoning = false;
1197
- }
1198
- for (const toolCallDelta of delta.tool_calls) {
1199
- if (toolCallDelta.type != null) {
1200
- toolCallTypes.set(toolCallDelta.index, toolCallDelta.type);
1201
- }
1202
- toolCallTracker.processDelta(toolCallDelta);
1203
- }
1204
- }
1205
- },
1206
- flush(controller) {
1207
- if (isActiveReasoning) {
1208
- controller.enqueue({ type: "reasoning-end", id: "reasoning-0" });
1209
- }
1210
- if (isActiveText) {
1211
- controller.enqueue({ type: "text-end", id: "txt-0" });
1212
- }
1213
- toolCallTracker.flush();
1214
- controller.enqueue({
1215
- type: "finish",
1216
- finishReason,
1217
- usage: convertDeepSeekUsage(usage),
1218
- providerMetadata: {
1219
- [providerOptionsName]: {
1220
- promptCacheHitTokens: usage?.prompt_cache_hit_tokens ?? void 0,
1221
- promptCacheMissTokens: usage?.prompt_cache_miss_tokens ?? void 0,
1222
- ...responseObject != null && { responseObject },
1223
- ...choiceIndex != null && { choiceIndex },
1224
- ...messageRole != null && { messageRole },
1225
- ...toolCallTypes.size > 0 && {
1226
- toolCallTypes: [...toolCallTypes.entries()].sort(([left], [right]) => left - right).map(([, type]) => type)
1227
- },
1228
- ...(contentLogprobs.length > 0 || reasoningLogprobs.length > 0) && {
1229
- logprobs: {
1230
- ...contentLogprobs.length > 0 && {
1231
- content: contentLogprobs
1232
- },
1233
- ...reasoningLogprobs.length > 0 && {
1234
- reasoning_content: reasoningLogprobs
1235
- }
1236
- }
1237
- },
1238
- ...systemFingerprint != null && { systemFingerprint }
1239
- }
1240
- }
1241
- });
1242
- }
1243
- })
1244
- ),
1245
- request: { body },
1246
- response: { headers: responseHeaders }
1247
- };
1248
- }
652
+ var DeepSeekChatLanguageModel = class DeepSeekChatLanguageModel {
653
+ static [WORKFLOW_SERIALIZE](model) {
654
+ return serializeModelOptions({
655
+ modelId: model.modelId,
656
+ config: model.config
657
+ });
658
+ }
659
+ static [WORKFLOW_DESERIALIZE](options) {
660
+ return new DeepSeekChatLanguageModel(options.modelId, options.config);
661
+ }
662
+ constructor(modelId, config) {
663
+ this.specificationVersion = "v4";
664
+ this.supportedUrls = { "image/*": [/^https?:\/\/.*$/] };
665
+ this.modelId = modelId;
666
+ this.config = config;
667
+ this.failedResponseHandler = createJsonErrorResponseHandler({
668
+ errorSchema: deepSeekErrorSchema,
669
+ errorToMessage: (error) => error.error.message
670
+ });
671
+ }
672
+ get provider() {
673
+ return this.config.provider;
674
+ }
675
+ get providerOptionsName() {
676
+ return this.config.provider.split(".")[0].trim();
677
+ }
678
+ async getArgs({ prompt, maxOutputTokens, temperature, topP, topK, frequencyPenalty, presencePenalty, reasoning, providerOptions, stopSequences, responseFormat, seed, toolChoice, tools }) {
679
+ const deepseekOptions = await parseProviderOptions({
680
+ provider: this.providerOptionsName,
681
+ providerOptions,
682
+ schema: deepseekLanguageModelChatOptions
683
+ }) ?? {};
684
+ const supportsStructuredOutputs = this.config.supportsStructuredOutputs === true;
685
+ const supportsPenaltySampling = this.config.supportsPenaltySampling === true;
686
+ const { messages, warnings } = await convertToDeepSeekChatMessages({
687
+ prompt,
688
+ responseFormat,
689
+ modelId: this.modelId,
690
+ providerOptionsName: this.providerOptionsName,
691
+ supportsAssistantPrefixCompletion: this.config.supportsAssistantPrefixCompletion,
692
+ supportsStructuredOutputs
693
+ });
694
+ const allWarnings = [...warnings];
695
+ if (topK != null) allWarnings.push({
696
+ type: "unsupported",
697
+ feature: "topK"
698
+ });
699
+ if (seed != null) allWarnings.push({
700
+ type: "unsupported",
701
+ feature: "seed"
702
+ });
703
+ if (!supportsPenaltySampling && frequencyPenalty != null) allWarnings.push({
704
+ type: "deprecated",
705
+ setting: "frequencyPenalty",
706
+ message: "frequencyPenalty is deprecated by DeepSeek and has been omitted. Remove frequencyPenalty from the request."
707
+ });
708
+ if (!supportsPenaltySampling && presencePenalty != null) allWarnings.push({
709
+ type: "deprecated",
710
+ setting: "presencePenalty",
711
+ message: "presencePenalty is deprecated by DeepSeek and has been omitted. Remove presencePenalty from the request."
712
+ });
713
+ const { tools: deepseekTools, toolChoice: deepseekToolChoices, toolWarnings } = prepareTools({
714
+ tools,
715
+ toolChoice,
716
+ supportsStrictToolCalls: this.config.supportsStrictToolCalls
717
+ });
718
+ const thinkingType = deepseekOptions.thinking?.type;
719
+ if (thinkingType === "adaptive") allWarnings.push({
720
+ type: "compatibility",
721
+ feature: "thinking.type",
722
+ details: "thinking.type \"adaptive\" is not a canonical DeepSeek value. mapped to \"enabled\"."
723
+ });
724
+ const thinking = this.config.supportsThinking === false ? void 0 : thinkingType != null ? { type: thinkingType === "adaptive" ? "enabled" : thinkingType } : isCustomReasoning(reasoning) ? { type: reasoning === "none" ? "disabled" : "enabled" } : void 0;
725
+ const isThinkingEnabled = this.config.supportsThinking !== false && thinking?.type !== "disabled" && (thinking != null || this.modelId === "deepseek-reasoner" || isDeepSeekV4Model(this.modelId));
726
+ if (isThinkingEnabled && temperature != null) allWarnings.push({
727
+ type: "unsupported",
728
+ feature: "temperature",
729
+ details: "temperature has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use temperature."
730
+ });
731
+ if (isThinkingEnabled && topP != null) allWarnings.push({
732
+ type: "unsupported",
733
+ feature: "topP",
734
+ details: "topP has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use topP."
735
+ });
736
+ const reasoningEffort = deepseekOptions.reasoningEffort != null ? mapDeepSeekProviderReasoningEffort({
737
+ reasoningEffort: deepseekOptions.reasoningEffort,
738
+ warnings: allWarnings
739
+ }) : isCustomReasoning(reasoning) && reasoning !== "none" ? mapReasoningToProviderEffort({
740
+ reasoning,
741
+ effortMap: {
742
+ minimal: "low",
743
+ low: "low",
744
+ medium: "high",
745
+ high: "high",
746
+ xhigh: "max"
747
+ },
748
+ warnings: allWarnings
749
+ }) : void 0;
750
+ return {
751
+ args: {
752
+ model: this.modelId,
753
+ ...(deepseekOptions.logprobs === true || deepseekOptions.topLogprobs != null) && { logprobs: true },
754
+ ...deepseekOptions.topLogprobs != null && { top_logprobs: deepseekOptions.topLogprobs },
755
+ max_tokens: maxOutputTokens,
756
+ temperature: isThinkingEnabled ? void 0 : temperature,
757
+ top_p: isThinkingEnabled ? void 0 : topP,
758
+ frequency_penalty: supportsPenaltySampling ? frequencyPenalty : void 0,
759
+ presence_penalty: supportsPenaltySampling ? presencePenalty : void 0,
760
+ response_format: responseFormat?.type === "json" ? supportsStructuredOutputs && responseFormat.schema != null ? {
761
+ type: "json_schema",
762
+ json_schema: {
763
+ schema: responseFormat.schema,
764
+ strict: deepseekOptions.strictJsonSchema ?? true,
765
+ name: responseFormat.name ?? "response",
766
+ description: responseFormat.description
767
+ }
768
+ } : { type: "json_object" } : void 0,
769
+ stop: stopSequences,
770
+ messages,
771
+ tools: deepseekTools,
772
+ tool_choice: deepseekToolChoices,
773
+ thinking,
774
+ ...deepseekOptions.userId != null && { user_id: deepseekOptions.userId },
775
+ ...thinking?.type !== "disabled" && reasoningEffort != null && { reasoning_effort: reasoningEffort }
776
+ },
777
+ warnings: [...allWarnings, ...toolWarnings]
778
+ };
779
+ }
780
+ async doGenerate(options) {
781
+ const { args, warnings } = await this.getArgs({ ...options });
782
+ const { responseHeaders, value: responseBody, rawValue: rawResponse } = await postJsonToApi({
783
+ url: this.config.url({
784
+ path: "/chat/completions",
785
+ modelId: this.modelId
786
+ }),
787
+ headers: combineHeaders(this.config.headers?.(), options.headers),
788
+ body: args,
789
+ failedResponseHandler: this.failedResponseHandler,
790
+ successfulResponseHandler: createJsonResponseHandler(deepseekChatResponseSchema),
791
+ abortSignal: options.abortSignal,
792
+ fetch: this.config.fetch
793
+ });
794
+ const choice = responseBody.choices[0];
795
+ if (choice == null) throw new InvalidResponseDataError({
796
+ data: rawResponse,
797
+ message: "Response did not contain any choices."
798
+ });
799
+ const content = [];
800
+ const reasoning = choice.message.reasoning_content;
801
+ if (reasoning != null && reasoning.length > 0) content.push({
802
+ type: "reasoning",
803
+ text: reasoning
804
+ });
805
+ if (choice.message.tool_calls != null) for (const toolCall of choice.message.tool_calls) content.push({
806
+ type: "tool-call",
807
+ toolCallId: toolCall.id || generateId(),
808
+ toolName: toolCall.function.name,
809
+ input: toolCall.function.arguments
810
+ });
811
+ const text = choice.message.content;
812
+ if (text != null && text.length > 0) content.push({
813
+ type: "text",
814
+ text
815
+ });
816
+ return {
817
+ content,
818
+ finishReason: {
819
+ unified: mapDeepSeekFinishReason(choice.finish_reason),
820
+ raw: choice.finish_reason ?? void 0
821
+ },
822
+ usage: convertDeepSeekUsage(responseBody.usage),
823
+ providerMetadata: { [this.providerOptionsName]: {
824
+ promptCacheHitTokens: responseBody.usage?.prompt_cache_hit_tokens,
825
+ promptCacheMissTokens: responseBody.usage?.prompt_cache_miss_tokens,
826
+ ...responseBody.object != null && { responseObject: responseBody.object },
827
+ ...choice.index != null && { choiceIndex: choice.index },
828
+ ...choice.message.role != null && { messageRole: choice.message.role },
829
+ ...choice.message.tool_calls != null && { toolCallTypes: choice.message.tool_calls.map((toolCall) => toolCall.type).filter((type) => type != null) },
830
+ ...choice.logprobs != null && { logprobs: choice.logprobs },
831
+ ...responseBody.system_fingerprint != null && { systemFingerprint: responseBody.system_fingerprint }
832
+ } },
833
+ request: { body: args },
834
+ response: {
835
+ ...getResponseMetadata(responseBody),
836
+ headers: responseHeaders,
837
+ body: rawResponse
838
+ },
839
+ warnings
840
+ };
841
+ }
842
+ async doStream(options) {
843
+ const { args, warnings } = await this.getArgs({ ...options });
844
+ const body = {
845
+ ...args,
846
+ stream: true,
847
+ stream_options: { include_usage: true }
848
+ };
849
+ const { responseHeaders, value: response } = await postJsonToApi({
850
+ url: this.config.url({
851
+ path: "/chat/completions",
852
+ modelId: this.modelId
853
+ }),
854
+ headers: combineHeaders(this.config.headers?.(), options.headers),
855
+ body,
856
+ failedResponseHandler: this.failedResponseHandler,
857
+ successfulResponseHandler: createEventSourceResponseHandler(deepseekChatChunkSchema),
858
+ abortSignal: options.abortSignal,
859
+ fetch: this.config.fetch
860
+ });
861
+ let toolCallTracker;
862
+ let finishReason = {
863
+ unified: "other",
864
+ raw: void 0
865
+ };
866
+ let usage = void 0;
867
+ let systemFingerprint = void 0;
868
+ let isFirstChunk = true;
869
+ const providerOptionsName = this.providerOptionsName;
870
+ let isActiveReasoning = false;
871
+ let isActiveText = false;
872
+ let responseObject;
873
+ let choiceIndex;
874
+ let messageRole;
875
+ const toolCallTypes = /* @__PURE__ */ new Map();
876
+ const contentLogprobs = [];
877
+ const reasoningLogprobs = [];
878
+ return {
879
+ stream: response.pipeThrough(new TransformStream({
880
+ start(controller) {
881
+ toolCallTracker = new StreamingToolCallTracker(controller, { generateId });
882
+ controller.enqueue({
883
+ type: "stream-start",
884
+ warnings
885
+ });
886
+ },
887
+ transform(chunk, controller) {
888
+ if (options.includeRawChunks) controller.enqueue({
889
+ type: "raw",
890
+ rawValue: chunk.rawValue
891
+ });
892
+ if (!chunk.success) {
893
+ finishReason = {
894
+ unified: "error",
895
+ raw: void 0
896
+ };
897
+ controller.enqueue({
898
+ type: "error",
899
+ error: chunk.error
900
+ });
901
+ return;
902
+ }
903
+ const value = chunk.value;
904
+ if ("error" in value) {
905
+ finishReason = {
906
+ unified: "error",
907
+ raw: void 0
908
+ };
909
+ controller.enqueue({
910
+ type: "error",
911
+ error: createDeepSeekStreamError(value.error, value)
912
+ });
913
+ return;
914
+ }
915
+ if (isFirstChunk) {
916
+ isFirstChunk = false;
917
+ controller.enqueue({
918
+ type: "response-metadata",
919
+ ...getResponseMetadata(value)
920
+ });
921
+ }
922
+ if (value.usage != null) usage = value.usage;
923
+ if (value.object != null) responseObject = value.object;
924
+ if (value.system_fingerprint != null) systemFingerprint = value.system_fingerprint;
925
+ const choice = value.choices[0];
926
+ if (choice?.index != null) choiceIndex = choice.index;
927
+ if (choice?.finish_reason != null) finishReason = {
928
+ unified: mapDeepSeekFinishReason(choice.finish_reason),
929
+ raw: choice.finish_reason
930
+ };
931
+ if (choice?.logprobs?.content != null) contentLogprobs.push(...choice.logprobs.content);
932
+ if (choice?.logprobs?.reasoning_content != null) reasoningLogprobs.push(...choice.logprobs.reasoning_content);
933
+ if (choice?.delta == null) return;
934
+ const delta = choice.delta;
935
+ if (delta.role != null) messageRole = delta.role;
936
+ const reasoningContent = delta.reasoning_content;
937
+ if (reasoningContent) {
938
+ if (!isActiveReasoning) {
939
+ controller.enqueue({
940
+ type: "reasoning-start",
941
+ id: "reasoning-0"
942
+ });
943
+ isActiveReasoning = true;
944
+ }
945
+ controller.enqueue({
946
+ type: "reasoning-delta",
947
+ id: "reasoning-0",
948
+ delta: reasoningContent
949
+ });
950
+ }
951
+ if (delta.content) {
952
+ if (!isActiveText) {
953
+ controller.enqueue({
954
+ type: "text-start",
955
+ id: "txt-0"
956
+ });
957
+ isActiveText = true;
958
+ }
959
+ if (isActiveReasoning) {
960
+ controller.enqueue({
961
+ type: "reasoning-end",
962
+ id: "reasoning-0"
963
+ });
964
+ isActiveReasoning = false;
965
+ }
966
+ controller.enqueue({
967
+ type: "text-delta",
968
+ id: "txt-0",
969
+ delta: delta.content
970
+ });
971
+ }
972
+ if (delta.tool_calls != null && delta.tool_calls.length > 0) {
973
+ if (isActiveReasoning) {
974
+ controller.enqueue({
975
+ type: "reasoning-end",
976
+ id: "reasoning-0"
977
+ });
978
+ isActiveReasoning = false;
979
+ }
980
+ for (const toolCallDelta of delta.tool_calls) {
981
+ if (toolCallDelta.type != null) toolCallTypes.set(toolCallDelta.index, toolCallDelta.type);
982
+ toolCallTracker.processDelta(toolCallDelta);
983
+ }
984
+ }
985
+ },
986
+ flush(controller) {
987
+ if (isActiveReasoning) controller.enqueue({
988
+ type: "reasoning-end",
989
+ id: "reasoning-0"
990
+ });
991
+ if (isActiveText) controller.enqueue({
992
+ type: "text-end",
993
+ id: "txt-0"
994
+ });
995
+ toolCallTracker.flush();
996
+ controller.enqueue({
997
+ type: "finish",
998
+ finishReason,
999
+ usage: convertDeepSeekUsage(usage),
1000
+ providerMetadata: { [providerOptionsName]: {
1001
+ promptCacheHitTokens: usage?.prompt_cache_hit_tokens ?? void 0,
1002
+ promptCacheMissTokens: usage?.prompt_cache_miss_tokens ?? void 0,
1003
+ ...responseObject != null && { responseObject },
1004
+ ...choiceIndex != null && { choiceIndex },
1005
+ ...messageRole != null && { messageRole },
1006
+ ...toolCallTypes.size > 0 && { toolCallTypes: [...toolCallTypes.entries()].sort(([left], [right]) => left - right).map(([, type]) => type) },
1007
+ ...(contentLogprobs.length > 0 || reasoningLogprobs.length > 0) && { logprobs: {
1008
+ ...contentLogprobs.length > 0 && { content: contentLogprobs },
1009
+ ...reasoningLogprobs.length > 0 && { reasoning_content: reasoningLogprobs }
1010
+ } },
1011
+ ...systemFingerprint != null && { systemFingerprint }
1012
+ } }
1013
+ });
1014
+ }
1015
+ })),
1016
+ request: { body },
1017
+ response: { headers: responseHeaders }
1018
+ };
1019
+ }
1249
1020
  };
1250
-
1251
- // src/files/deepseek-files.ts
1252
- import {
1253
- InvalidArgumentError
1254
- } from "@ai-sdk/provider";
1255
- import {
1256
- combineHeaders as combineHeaders2,
1257
- convertInlineFileDataToUint8Array,
1258
- createJsonErrorResponseHandler as createJsonErrorResponseHandler2,
1259
- createJsonResponseHandler as createJsonResponseHandler2,
1260
- detectMediaType,
1261
- parseProviderOptions as parseProviderOptions3,
1262
- postFormDataToApi
1263
- } from "@ai-sdk/provider-utils";
1264
-
1265
- // src/files/deepseek-files-api.ts
1266
- import { lazySchema as lazySchema2, zodSchema as zodSchema2 } from "@ai-sdk/provider-utils";
1267
- import { z as z4 } from "zod/v4";
1268
- var deepSeekFilesResponseSchema = lazySchema2(
1269
- () => zodSchema2(
1270
- z4.object({
1271
- id: z4.string(),
1272
- // These fields are required by DeepSeek's OpenAPI schema, but they are
1273
- // not needed to construct the provider reference. Keep them nullish so
1274
- // uploads remain resilient to incomplete responses while validating any
1275
- // returned values precisely enough to avoid misleading metadata.
1276
- object: z4.literal("file").nullish(),
1277
- bytes: z4.number().int().nonnegative().nullish(),
1278
- created_at: z4.number().int().nonnegative().nullish(),
1279
- filename: z4.string().nullish(),
1280
- purpose: z4.literal("user_data").nullish(),
1281
- expires_at: z4.number().int().nonnegative().nullish()
1282
- })
1283
- )
1284
- );
1285
-
1286
- // src/files/deepseek-files-options.ts
1287
- import {
1288
- lazySchema as lazySchema3,
1289
- zodSchema as zodSchema3
1290
- } from "@ai-sdk/provider-utils";
1291
- import { z as z5 } from "zod/v4";
1292
- var deepSeekFilesOptionsSchema = lazySchema3(
1293
- () => zodSchema3(
1294
- z5.object({
1295
- /**
1296
- * Number of seconds after creation before the file expires.
1297
- * Must be between 1 hour and 30 days.
1298
- */
1299
- expiresAfter: z5.number().int().min(3600).max(2592e3).optional()
1300
- })
1301
- )
1302
- );
1303
-
1304
- // src/files/deepseek-files.ts
1305
- var deepSeekFailedResponseHandler = createJsonErrorResponseHandler2({
1306
- errorSchema: deepSeekErrorSchema,
1307
- errorToMessage: (error) => error.error.message
1021
+ //#endregion
1022
+ //#region src/files/deepseek-files-api.ts
1023
+ const deepSeekFilesResponseSchema = lazySchema(() => zodSchema(z.object({
1024
+ id: z.string(),
1025
+ object: z.literal("file").nullish(),
1026
+ bytes: z.number().int().nonnegative().nullish(),
1027
+ created_at: z.number().int().nonnegative().nullish(),
1028
+ filename: z.string().nullish(),
1029
+ purpose: z.literal("user_data").nullish(),
1030
+ expires_at: z.number().int().nonnegative().nullish()
1031
+ })));
1032
+ //#endregion
1033
+ //#region src/files/deepseek-files-options.ts
1034
+ const deepSeekFilesOptionsSchema = lazySchema(() => zodSchema(z.object({
1035
+ /**
1036
+ * Number of seconds after creation before the file expires.
1037
+ * Must be between 1 hour and 30 days.
1038
+ */
1039
+ expiresAfter: z.number().int().min(3600).max(2592e3).optional() })));
1040
+ //#endregion
1041
+ //#region src/files/deepseek-files.ts
1042
+ const deepSeekFailedResponseHandler = createJsonErrorResponseHandler({
1043
+ errorSchema: deepSeekErrorSchema,
1044
+ errorToMessage: (error) => error.error.message
1308
1045
  });
1309
- var MAX_FILE_SIZE_BYTES = 64 * 1024 * 1024;
1310
- var MAX_FILENAME_LENGTH = 512;
1311
- var supportedMediaTypes = /* @__PURE__ */ new Set([
1312
- "image/gif",
1313
- "image/jpeg",
1314
- "image/jpg",
1315
- "image/png",
1316
- "image/webp"
1046
+ const MAX_FILE_SIZE_BYTES = 67108864;
1047
+ const MAX_FILENAME_LENGTH = 512;
1048
+ const supportedMediaTypes = /* @__PURE__ */ new Set([
1049
+ "image/gif",
1050
+ "image/jpeg",
1051
+ "image/jpg",
1052
+ "image/png",
1053
+ "image/webp"
1317
1054
  ]);
1318
- var genericMediaTypes = /* @__PURE__ */ new Set([
1319
- "",
1320
- "application/binary",
1321
- "application/octet-stream",
1322
- "binary/octet-stream",
1323
- "image",
1324
- "image/*"
1055
+ const genericMediaTypes = /* @__PURE__ */ new Set([
1056
+ "",
1057
+ "application/binary",
1058
+ "application/octet-stream",
1059
+ "binary/octet-stream",
1060
+ "image",
1061
+ "image/*"
1325
1062
  ]);
1326
- var supportedFilenameExtensions = /* @__PURE__ */ new Set([
1327
- "gif",
1328
- "jpeg",
1329
- "jpg",
1330
- "png",
1331
- "webp"
1063
+ const supportedFilenameExtensions = /* @__PURE__ */ new Set([
1064
+ "gif",
1065
+ "jpeg",
1066
+ "jpg",
1067
+ "png",
1068
+ "webp"
1332
1069
  ]);
1333
1070
  var DeepSeekFiles = class {
1334
- constructor(config) {
1335
- this.config = config;
1336
- this.specificationVersion = "v4";
1337
- }
1338
- get provider() {
1339
- return this.config.provider;
1340
- }
1341
- async uploadFile({
1342
- data,
1343
- mediaType,
1344
- filename,
1345
- abortSignal,
1346
- headers,
1347
- providerOptions
1348
- }) {
1349
- const deepSeekOptions = await parseProviderOptions3({
1350
- provider: "deepseek",
1351
- providerOptions,
1352
- schema: deepSeekFilesOptionsSchema
1353
- });
1354
- const fileBytes = convertInlineFileDataToUint8Array(data);
1355
- validateFileUpload({ fileBytes, mediaType, filename });
1356
- const blob = new Blob([fileBytes], { type: mediaType });
1357
- const formData = new FormData();
1358
- if (filename != null) {
1359
- formData.append("file", blob, filename);
1360
- } else {
1361
- formData.append("file", blob);
1362
- }
1363
- formData.append("purpose", "user_data");
1364
- if (deepSeekOptions?.expiresAfter != null) {
1365
- formData.append("expires_after[anchor]", "created_at");
1366
- formData.append(
1367
- "expires_after[seconds]",
1368
- String(deepSeekOptions.expiresAfter)
1369
- );
1370
- }
1371
- const { value: response } = await postFormDataToApi({
1372
- url: `${this.config.baseURL}/files`,
1373
- headers: combineHeaders2(this.config.headers(), headers),
1374
- formData,
1375
- failedResponseHandler: deepSeekFailedResponseHandler,
1376
- successfulResponseHandler: createJsonResponseHandler2(
1377
- deepSeekFilesResponseSchema
1378
- ),
1379
- abortSignal,
1380
- fetch: this.config.fetch
1381
- });
1382
- return {
1383
- warnings: [],
1384
- providerReference: { deepseek: response.id },
1385
- ...response.filename ?? filename ? { filename: response.filename ?? filename } : {},
1386
- ...mediaType != null ? { mediaType } : {},
1387
- providerMetadata: {
1388
- deepseek: {
1389
- ...response.object != null ? { object: response.object } : {},
1390
- ...response.filename != null ? { filename: response.filename } : {},
1391
- ...response.purpose != null ? { purpose: response.purpose } : {},
1392
- ...response.bytes != null ? { bytes: response.bytes } : {},
1393
- ...response.created_at != null ? { createdAt: response.created_at } : {},
1394
- ...response.expires_at != null ? { expiresAt: response.expires_at } : {}
1395
- }
1396
- }
1397
- };
1398
- }
1071
+ get provider() {
1072
+ return this.config.provider;
1073
+ }
1074
+ constructor(config) {
1075
+ this.config = config;
1076
+ this.specificationVersion = "v4";
1077
+ }
1078
+ async uploadFile({ data, mediaType, filename, abortSignal, headers, providerOptions }) {
1079
+ const deepSeekOptions = await parseProviderOptions({
1080
+ provider: "deepseek",
1081
+ providerOptions,
1082
+ schema: deepSeekFilesOptionsSchema
1083
+ });
1084
+ const fileBytes = convertInlineFileDataToUint8Array(data);
1085
+ validateFileUpload({
1086
+ fileBytes,
1087
+ mediaType,
1088
+ filename
1089
+ });
1090
+ const blob = new Blob([fileBytes], { type: mediaType });
1091
+ const formData = new FormData();
1092
+ if (filename != null) formData.append("file", blob, filename);
1093
+ else formData.append("file", blob);
1094
+ formData.append("purpose", "user_data");
1095
+ if (deepSeekOptions?.expiresAfter != null) {
1096
+ formData.append("expires_after[anchor]", "created_at");
1097
+ formData.append("expires_after[seconds]", String(deepSeekOptions.expiresAfter));
1098
+ }
1099
+ const { value: response } = await postFormDataToApi({
1100
+ url: `${this.config.baseURL}/files`,
1101
+ headers: combineHeaders(this.config.headers(), headers),
1102
+ formData,
1103
+ failedResponseHandler: deepSeekFailedResponseHandler,
1104
+ successfulResponseHandler: createJsonResponseHandler(deepSeekFilesResponseSchema),
1105
+ abortSignal,
1106
+ fetch: this.config.fetch
1107
+ });
1108
+ return {
1109
+ warnings: [],
1110
+ providerReference: { deepseek: response.id },
1111
+ ...response.filename ?? filename ? { filename: response.filename ?? filename } : {},
1112
+ ...mediaType != null ? { mediaType } : {},
1113
+ providerMetadata: { deepseek: {
1114
+ ...response.object != null ? { object: response.object } : {},
1115
+ ...response.filename != null ? { filename: response.filename } : {},
1116
+ ...response.purpose != null ? { purpose: response.purpose } : {},
1117
+ ...response.bytes != null ? { bytes: response.bytes } : {},
1118
+ ...response.created_at != null ? { createdAt: response.created_at } : {},
1119
+ ...response.expires_at != null ? { expiresAt: response.expires_at } : {}
1120
+ } }
1121
+ };
1122
+ }
1399
1123
  };
1400
- function validateFileUpload({
1401
- fileBytes,
1402
- mediaType,
1403
- filename
1404
- }) {
1405
- if (fileBytes.length > MAX_FILE_SIZE_BYTES) {
1406
- throw new InvalidArgumentError({
1407
- argument: "data",
1408
- message: `DeepSeek file uploads must not exceed 64 MiB (${MAX_FILE_SIZE_BYTES.toLocaleString("en-US")} bytes). Received ${fileBytes.length.toLocaleString("en-US")} bytes.`
1409
- });
1410
- }
1411
- if (filename != null) {
1412
- const filenameLength = Array.from(filename).length;
1413
- if (filenameLength > MAX_FILENAME_LENGTH) {
1414
- throw new InvalidArgumentError({
1415
- argument: "filename",
1416
- message: `DeepSeek filenames must not exceed ${MAX_FILENAME_LENGTH} characters. Received ${filenameLength} characters.`
1417
- });
1418
- }
1419
- }
1420
- const normalizedMediaType = normalizeMediaType(mediaType);
1421
- const detectedMediaType = detectMediaType({ data: fileBytes });
1422
- if (detectedMediaType != null && !supportedMediaTypes.has(detectedMediaType)) {
1423
- throw new InvalidArgumentError({
1424
- argument: "data",
1425
- message: `DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. Detected unsupported file content type "${detectedMediaType}".`
1426
- });
1427
- }
1428
- if (supportedMediaTypes.has(normalizedMediaType)) {
1429
- return;
1430
- }
1431
- if (!genericMediaTypes.has(normalizedMediaType)) {
1432
- throw new InvalidArgumentError({
1433
- argument: "mediaType",
1434
- message: `DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. Received unsupported media type "${mediaType}".`
1435
- });
1436
- }
1437
- if (detectedMediaType != null || hasSupportedFilenameExtension(filename)) {
1438
- return;
1439
- }
1440
- throw new InvalidArgumentError({
1441
- argument: "mediaType",
1442
- 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}".`
1443
- });
1124
+ function validateFileUpload({ fileBytes, mediaType, filename }) {
1125
+ if (fileBytes.length > MAX_FILE_SIZE_BYTES) throw new InvalidArgumentError({
1126
+ argument: "data",
1127
+ message: `DeepSeek file uploads must not exceed 64 MiB (${MAX_FILE_SIZE_BYTES.toLocaleString("en-US")} bytes). Received ${fileBytes.length.toLocaleString("en-US")} bytes.`
1128
+ });
1129
+ if (filename != null) {
1130
+ const filenameLength = Array.from(filename).length;
1131
+ if (filenameLength > MAX_FILENAME_LENGTH) throw new InvalidArgumentError({
1132
+ argument: "filename",
1133
+ message: `DeepSeek filenames must not exceed ${MAX_FILENAME_LENGTH} characters. Received ${filenameLength} characters.`
1134
+ });
1135
+ }
1136
+ const normalizedMediaType = normalizeMediaType(mediaType);
1137
+ const detectedMediaType = detectMediaType({ data: fileBytes });
1138
+ if (detectedMediaType != null && !supportedMediaTypes.has(detectedMediaType)) throw new InvalidArgumentError({
1139
+ argument: "data",
1140
+ message: `DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. Detected unsupported file content type "${detectedMediaType}".`
1141
+ });
1142
+ if (supportedMediaTypes.has(normalizedMediaType)) return;
1143
+ if (!genericMediaTypes.has(normalizedMediaType)) throw new InvalidArgumentError({
1144
+ argument: "mediaType",
1145
+ message: `DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. Received unsupported media type "${mediaType}".`
1146
+ });
1147
+ if (detectedMediaType != null || hasSupportedFilenameExtension(filename)) return;
1148
+ throw new InvalidArgumentError({
1149
+ argument: "mediaType",
1150
+ 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}".`
1151
+ });
1444
1152
  }
1445
1153
  function normalizeMediaType(mediaType) {
1446
- return mediaType.split(";", 1)[0].trim().toLowerCase();
1154
+ return mediaType.split(";", 1)[0].trim().toLowerCase();
1447
1155
  }
1448
1156
  function hasSupportedFilenameExtension(filename) {
1449
- if (filename == null) {
1450
- return false;
1451
- }
1452
- const extensionSeparatorIndex = filename.lastIndexOf(".");
1453
- return extensionSeparatorIndex !== -1 && supportedFilenameExtensions.has(
1454
- filename.slice(extensionSeparatorIndex + 1).toLowerCase()
1455
- );
1157
+ if (filename == null) return false;
1158
+ const extensionSeparatorIndex = filename.lastIndexOf(".");
1159
+ return extensionSeparatorIndex !== -1 && supportedFilenameExtensions.has(filename.slice(extensionSeparatorIndex + 1).toLowerCase());
1456
1160
  }
1457
-
1458
- // src/version.ts
1459
- var VERSION = true ? "3.0.56" : "0.0.0-test";
1460
-
1461
- // src/deepseek-provider.ts
1161
+ //#endregion
1162
+ //#region src/version.ts
1163
+ const VERSION = "3.0.57";
1164
+ //#endregion
1165
+ //#region src/deepseek-provider.ts
1462
1166
  function createDeepSeek(options = {}) {
1463
- const baseURL = withoutTrailingSlash(options.baseURL ?? "https://api.deepseek.com") ?? "https://api.deepseek.com";
1464
- const getHeaders = () => withUserAgentSuffix(
1465
- {
1466
- Authorization: `Bearer ${loadApiKey({
1467
- apiKey: options.apiKey,
1468
- environmentVariableName: "DEEPSEEK_API_KEY",
1469
- description: "DeepSeek API key"
1470
- })}`,
1471
- ...options.headers
1472
- },
1473
- `ai-sdk-deepseek/${VERSION}`
1474
- );
1475
- const createLanguageModel = (modelId) => {
1476
- return new DeepSeekChatLanguageModel(modelId, {
1477
- provider: `deepseek.chat`,
1478
- url: ({ path }) => `${baseURL}${path}`,
1479
- headers: getHeaders,
1480
- fetch: options.fetch,
1481
- supportsAssistantPrefixCompletion: baseURL.endsWith("/beta"),
1482
- supportsStrictToolCalls: baseURL.endsWith("/beta")
1483
- });
1484
- };
1485
- const createFiles = () => new DeepSeekFiles({
1486
- provider: "deepseek.files",
1487
- baseURL,
1488
- headers: getHeaders,
1489
- fetch: options.fetch
1490
- });
1491
- const provider = (modelId) => createLanguageModel(modelId);
1492
- provider.specificationVersion = "v4";
1493
- provider.languageModel = createLanguageModel;
1494
- provider.chat = createLanguageModel;
1495
- provider.files = createFiles;
1496
- provider.embeddingModel = (modelId) => {
1497
- throw new NoSuchModelError({ modelId, modelType: "embeddingModel" });
1498
- };
1499
- provider.textEmbeddingModel = provider.embeddingModel;
1500
- provider.imageModel = (modelId) => {
1501
- throw new NoSuchModelError({ modelId, modelType: "imageModel" });
1502
- };
1503
- return provider;
1167
+ const baseURL = withoutTrailingSlash(options.baseURL ?? "https://api.deepseek.com") ?? "https://api.deepseek.com";
1168
+ const getHeaders = () => withUserAgentSuffix({
1169
+ Authorization: `Bearer ${loadApiKey({
1170
+ apiKey: options.apiKey,
1171
+ environmentVariableName: "DEEPSEEK_API_KEY",
1172
+ description: "DeepSeek API key"
1173
+ })}`,
1174
+ ...options.headers
1175
+ }, `ai-sdk-deepseek/${VERSION}`);
1176
+ const createLanguageModel = (modelId) => {
1177
+ return new DeepSeekChatLanguageModel(modelId, {
1178
+ provider: `deepseek.chat`,
1179
+ url: ({ path }) => `${baseURL}${path}`,
1180
+ headers: getHeaders,
1181
+ fetch: options.fetch,
1182
+ supportsAssistantPrefixCompletion: baseURL.endsWith("/beta"),
1183
+ supportsStrictToolCalls: baseURL.endsWith("/beta")
1184
+ });
1185
+ };
1186
+ const createFiles = () => new DeepSeekFiles({
1187
+ provider: "deepseek.files",
1188
+ baseURL,
1189
+ headers: getHeaders,
1190
+ fetch: options.fetch
1191
+ });
1192
+ const provider = (modelId) => createLanguageModel(modelId);
1193
+ provider.specificationVersion = "v4";
1194
+ provider.languageModel = createLanguageModel;
1195
+ provider.chat = createLanguageModel;
1196
+ provider.files = createFiles;
1197
+ provider.embeddingModel = (modelId) => {
1198
+ throw new NoSuchModelError({
1199
+ modelId,
1200
+ modelType: "embeddingModel"
1201
+ });
1202
+ };
1203
+ provider.textEmbeddingModel = provider.embeddingModel;
1204
+ provider.imageModel = (modelId) => {
1205
+ throw new NoSuchModelError({
1206
+ modelId,
1207
+ modelType: "imageModel"
1208
+ });
1209
+ };
1210
+ return provider;
1504
1211
  }
1505
- var deepSeek = createDeepSeek();
1506
- export {
1507
- VERSION,
1508
- createDeepSeek,
1509
- deepSeek,
1510
- deepSeek as deepseek
1511
- };
1212
+ const deepSeek = createDeepSeek();
1213
+ //#endregion
1214
+ export { VERSION, createDeepSeek, deepSeek, deepSeek as deepseek };
1215
+
1512
1216
  //# sourceMappingURL=index.js.map