@ai-sdk/deepseek 3.0.31 → 3.0.34

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.
@@ -4,10 +4,11 @@ import {
4
4
  createEventSourceResponseHandler,
5
5
  createJsonErrorResponseHandler,
6
6
  createJsonResponseHandler,
7
+ createProviderStreamError,
7
8
  generateId,
8
9
  isCustomReasoning,
9
10
  mapReasoningToProviderEffort,
10
- parseProviderOptions,
11
+ parseProviderOptions as parseProviderOptions2,
11
12
  postJsonToApi,
12
13
  serializeModelOptions,
13
14
  StreamingToolCallTracker,
@@ -16,16 +17,113 @@ import {
16
17
  } from "@ai-sdk/provider-utils";
17
18
 
18
19
  // src/chat/convert-to-deepseek-chat-messages.ts
20
+ import {
21
+ InvalidPromptError,
22
+ UnsupportedFunctionalityError
23
+ } from "@ai-sdk/provider";
19
24
  import {
20
25
  convertToBase64,
21
26
  getTopLevelMediaType,
27
+ parseProviderOptions,
22
28
  resolveFullMediaType,
23
29
  resolveProviderReference
24
30
  } from "@ai-sdk/provider-utils";
25
- function convertToDeepSeekChatMessages({
31
+
32
+ // src/chat/deepseek-file-part-options.ts
33
+ import { z } from "zod/v4";
34
+ var deepseekFilePartProviderOptions = z.object({
35
+ /**
36
+ * Controls how DeepSeek processes an image sent as an `image_url` part.
37
+ *
38
+ * @see https://api-docs.deepseek.com/api/create-chat-completion/
39
+ */
40
+ imageDetail: z.enum(["low", "high", "original", "auto"]).optional(),
41
+ /**
42
+ * Sends inline image data as a DeepSeek `file` part using `file_data`
43
+ * instead of an `image_url` data URL. When set, the file part's filename
44
+ * is preserved.
45
+ *
46
+ * This option only applies to inline image data. It cannot be combined
47
+ * with `imageDetail`.
48
+ */
49
+ fileData: z.literal(true).optional()
50
+ });
51
+
52
+ // src/chat/deepseek-chat-language-model-options.ts
53
+ import { z as z2 } from "zod/v4";
54
+ var deepseekLanguageModelChatOptions = z2.object({
55
+ /**
56
+ * Whether to return log probabilities for generated tokens.
57
+ */
58
+ logprobs: z2.boolean().optional(),
59
+ /**
60
+ * Number of most likely tokens to return at each token position.
61
+ *
62
+ * Setting this option automatically enables `logprobs`.
63
+ */
64
+ topLogprobs: z2.number().int().min(0).max(20).optional(),
65
+ /**
66
+ * An opaque identifier for the end user. DeepSeek uses this identifier for
67
+ * content-safety tracing and request isolation.
68
+ *
69
+ * Must contain only ASCII letters, numbers, underscores, and hyphens, and
70
+ * must be at most 512 characters long.
71
+ */
72
+ 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(),
73
+ /**
74
+ * Type of thinking to use. Defaults to `enabled`.
75
+ */
76
+ thinking: z2.object({
77
+ // `adaptive` is accepted at runtime for backwards compatibility and
78
+ // mapped to `enabled`, but is intentionally excluded from the exported
79
+ // provider options type.
80
+ type: z2.enum(["adaptive", "enabled", "disabled"]).optional()
81
+ }).optional(),
82
+ /**
83
+ * Controls the thinking strength for DeepSeek V4 reasoning models.
84
+ */
85
+ // `medium` and `xhigh` are accepted at runtime for backwards compatibility
86
+ // and mapped to canonical DeepSeek values, but are intentionally excluded
87
+ // from the exported provider options type.
88
+ reasoningEffort: z2.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
89
+ /**
90
+ * Whether to use strict JSON schema validation for structured outputs.
91
+ * Only applies when the serving endpoint supports JSON schema response
92
+ * formats (e.g. Azure). Defaults to `true`.
93
+ */
94
+ strictJsonSchema: z2.boolean().optional()
95
+ });
96
+ var deepseekMessageProviderOptions = z2.object({
97
+ /**
98
+ * The name of the participant represented by the message.
99
+ *
100
+ * Supported on system, user, and assistant messages.
101
+ */
102
+ name: z2.string().optional()
103
+ });
104
+ var deepseekAssistantMessageProviderOptions = deepseekMessageProviderOptions.extend({
105
+ /**
106
+ * Whether the assistant message content is a prefix that DeepSeek should
107
+ * continue. This beta feature is only supported on the final assistant
108
+ * message when using a beta base URL.
109
+ */
110
+ prefix: z2.literal(true).optional()
111
+ });
112
+
113
+ // src/chat/convert-to-deepseek-chat-messages.ts
114
+ var supportedImageMediaTypes = /* @__PURE__ */ new Set([
115
+ "image/gif",
116
+ "image/jpeg",
117
+ "image/jpg",
118
+ "image/png",
119
+ "image/webp"
120
+ ]);
121
+ async function convertToDeepSeekChatMessages({
26
122
  prompt,
27
123
  responseFormat,
28
124
  modelId,
125
+ providerOptionsName = "deepseek",
126
+ supportsAssistantPrefixCompletion = false,
29
127
  supportsStructuredOutputs = false
30
128
  }) {
31
129
  var _a;
@@ -58,11 +156,28 @@ function convertToDeepSeekChatMessages({
58
156
  }
59
157
  }
60
158
  let index = -1;
61
- for (const { role, content } of prompt) {
159
+ for (const { role, content, providerOptions } of prompt) {
62
160
  index++;
161
+ const deepseekMessageOptions = await parseProviderOptions({
162
+ provider: providerOptionsName,
163
+ providerOptions,
164
+ schema: deepseekAssistantMessageProviderOptions
165
+ });
166
+ if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true && role !== "assistant") {
167
+ throw new InvalidPromptError({
168
+ prompt,
169
+ message: "DeepSeek assistant prefix completion requires `prefix: true` on an assistant message."
170
+ });
171
+ }
63
172
  switch (role) {
64
173
  case "system": {
65
- messages.push({ role: "system", content });
174
+ messages.push({
175
+ role: "system",
176
+ content,
177
+ ...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
178
+ name: deepseekMessageOptions.name
179
+ }
180
+ });
66
181
  break;
67
182
  }
68
183
  case "user": {
@@ -81,7 +196,13 @@ function convertToDeepSeekChatMessages({
81
196
  });
82
197
  }
83
198
  }
84
- messages.push({ role: "user", content: userContent2 });
199
+ messages.push({
200
+ role: "user",
201
+ content: userContent2,
202
+ ...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
203
+ name: deepseekMessageOptions.name
204
+ }
205
+ });
85
206
  break;
86
207
  }
87
208
  const userContent = [];
@@ -89,6 +210,11 @@ function convertToDeepSeekChatMessages({
89
210
  if (part.type === "text") {
90
211
  userContent.push({ type: "text", text: part.text });
91
212
  } else if (part.type === "file" && getTopLevelMediaType(part.mediaType) === "image") {
213
+ const filePartOptions = await parseProviderOptions({
214
+ provider: providerOptionsName,
215
+ providerOptions: part.providerOptions,
216
+ schema: deepseekFilePartProviderOptions
217
+ });
92
218
  if (part.data.type === "reference") {
93
219
  userContent.push({
94
220
  type: "file",
@@ -98,12 +224,62 @@ function convertToDeepSeekChatMessages({
98
224
  })
99
225
  });
100
226
  } else if (part.data.type === "url" || part.data.type === "data") {
101
- userContent.push({
102
- type: "image_url",
103
- image_url: {
104
- url: part.data.type === "url" ? part.data.url.toString() : `data:${resolveFullMediaType({ part })};base64,${convertToBase64(part.data.data)}`
227
+ const resolvedMediaType = resolveFullMediaType({ part });
228
+ if (!supportedImageMediaTypes.has(resolvedMediaType)) {
229
+ throw new UnsupportedFunctionalityError({
230
+ functionality: `DeepSeek image media type ${resolvedMediaType}`,
231
+ message: "DeepSeek supports JPEG, PNG, GIF, and WebP image inputs."
232
+ });
233
+ }
234
+ if (part.data.type === "url") {
235
+ const url = part.data.url.toString();
236
+ if (url.length > 8192) {
237
+ throw new InvalidPromptError({
238
+ prompt,
239
+ message: "DeepSeek image URLs must not exceed 8192 characters."
240
+ });
105
241
  }
106
- });
242
+ if ((filePartOptions == null ? void 0 : filePartOptions.fileData) === true) {
243
+ throw new InvalidPromptError({
244
+ prompt,
245
+ message: "DeepSeek `fileData` image parts require inline data, not a URL."
246
+ });
247
+ }
248
+ userContent.push({
249
+ type: "image_url",
250
+ image_url: {
251
+ url,
252
+ ...(filePartOptions == null ? void 0 : filePartOptions.imageDetail) != null && {
253
+ detail: filePartOptions.imageDetail
254
+ }
255
+ }
256
+ });
257
+ } else {
258
+ const dataUrl = `data:${resolvedMediaType === "image/jpg" ? "image/jpeg" : resolvedMediaType};base64,${convertToBase64(part.data.data)}`;
259
+ if ((filePartOptions == null ? void 0 : filePartOptions.fileData) === true) {
260
+ if (filePartOptions.imageDetail != null) {
261
+ throw new InvalidPromptError({
262
+ prompt,
263
+ message: "DeepSeek `imageDetail` cannot be combined with `fileData`."
264
+ });
265
+ }
266
+ userContent.push({
267
+ type: "file",
268
+ file_data: dataUrl,
269
+ ...part.filename != null && { filename: part.filename }
270
+ });
271
+ } else {
272
+ userContent.push({
273
+ type: "image_url",
274
+ image_url: {
275
+ url: dataUrl,
276
+ ...(filePartOptions == null ? void 0 : filePartOptions.imageDetail) != null && {
277
+ detail: filePartOptions.imageDetail
278
+ }
279
+ }
280
+ });
281
+ }
282
+ }
107
283
  } else {
108
284
  warnings.push({
109
285
  type: "unsupported",
@@ -119,11 +295,28 @@ function convertToDeepSeekChatMessages({
119
295
  }
120
296
  messages.push({
121
297
  role: "user",
122
- content: userContent
298
+ content: userContent,
299
+ ...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
300
+ name: deepseekMessageOptions.name
301
+ }
123
302
  });
124
303
  break;
125
304
  }
126
305
  case "assistant": {
306
+ if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true) {
307
+ if (index !== prompt.length - 1) {
308
+ throw new InvalidPromptError({
309
+ prompt,
310
+ message: "DeepSeek assistant prefix completion requires the prefixed assistant message to be the final message."
311
+ });
312
+ }
313
+ if (!supportsAssistantPrefixCompletion) {
314
+ throw new UnsupportedFunctionalityError({
315
+ functionality: "DeepSeek assistant prefix completion",
316
+ message: "DeepSeek assistant prefix completion requires a beta base URL ending in `/beta`."
317
+ });
318
+ }
319
+ }
127
320
  let text = "";
128
321
  let reasoning;
129
322
  const toolCalls = [];
@@ -160,12 +353,24 @@ function convertToDeepSeekChatMessages({
160
353
  messages.push({
161
354
  role: "assistant",
162
355
  content: text,
356
+ ...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
357
+ name: deepseekMessageOptions.name
358
+ },
359
+ ...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true && {
360
+ prefix: true
361
+ },
163
362
  reasoning_content: reasoning != null ? reasoning : isDeepSeekV4 ? "" : void 0,
164
363
  tool_calls: toolCalls.length > 0 ? toolCalls : void 0
165
364
  });
166
365
  break;
167
366
  }
168
367
  case "tool": {
368
+ if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null) {
369
+ warnings.push({
370
+ type: "unsupported",
371
+ feature: "message name on tool messages"
372
+ });
373
+ }
169
374
  for (const toolResponse of content) {
170
375
  if (toolResponse.type === "tool-approval-response") {
171
376
  continue;
@@ -226,7 +431,7 @@ function convertDeepSeekUsage(usage) {
226
431
  },
227
432
  outputTokens: {
228
433
  total: completionTokens,
229
- text: completionTokens - reasoningTokens,
434
+ text: Math.max(0, completionTokens - reasoningTokens),
230
435
  reasoning: reasoningTokens
231
436
  },
232
437
  raw: usage
@@ -235,75 +440,101 @@ function convertDeepSeekUsage(usage) {
235
440
 
236
441
  // src/chat/deepseek-chat-api-types.ts
237
442
  import { lazySchema, zodSchema } from "@ai-sdk/provider-utils";
238
- import { z } from "zod/v4";
239
- var tokenUsageSchema = z.object({
240
- prompt_tokens: z.number().nullish(),
241
- completion_tokens: z.number().nullish(),
242
- prompt_cache_hit_tokens: z.number().nullish(),
243
- prompt_cache_miss_tokens: z.number().nullish(),
244
- total_tokens: z.number().nullish(),
245
- completion_tokens_details: z.object({
246
- reasoning_tokens: z.number().nullish()
443
+ import { z as z3 } from "zod/v4";
444
+ var tokenUsageSchema = z3.object({
445
+ prompt_tokens: z3.number().nullish(),
446
+ completion_tokens: z3.number().nullish(),
447
+ prompt_cache_hit_tokens: z3.number().nullish(),
448
+ prompt_cache_miss_tokens: z3.number().nullish(),
449
+ total_tokens: z3.number().nullish(),
450
+ completion_tokens_details: z3.object({
451
+ reasoning_tokens: z3.number().nullish()
247
452
  }).nullish()
248
453
  }).nullish();
249
- var deepSeekErrorSchema = z.object({
250
- error: z.object({
251
- message: z.string(),
252
- type: z.string().nullish(),
253
- param: z.any().nullish(),
254
- code: z.union([z.string(), z.number()]).nullish()
454
+ var deepSeekErrorSchema = z3.object({
455
+ error: z3.object({
456
+ message: z3.string(),
457
+ type: z3.string().nullish(),
458
+ param: z3.any().nullish(),
459
+ code: z3.union([z3.string(), z3.number()]).nullish()
255
460
  })
256
461
  });
257
- var deepseekChatResponseSchema = z.object({
258
- id: z.string().nullish(),
259
- created: z.number().nullish(),
260
- model: z.string().nullish(),
261
- choices: z.array(
262
- z.object({
263
- message: z.object({
264
- role: z.literal("assistant").nullish(),
265
- content: z.string().nullish(),
266
- reasoning_content: z.string().nullish(),
267
- tool_calls: z.array(
268
- z.object({
269
- id: z.string().nullish(),
270
- function: z.object({
271
- name: z.string(),
272
- arguments: z.string()
462
+ var deepseekChatLogprobSchema = z3.object({
463
+ token: z3.string(),
464
+ logprob: z3.number(),
465
+ bytes: z3.array(z3.number()).nullable(),
466
+ top_logprobs: z3.array(
467
+ z3.object({
468
+ token: z3.string(),
469
+ logprob: z3.number(),
470
+ bytes: z3.array(z3.number()).nullable()
471
+ })
472
+ )
473
+ });
474
+ var deepseekChatLogprobsSchema = z3.object({
475
+ content: z3.array(deepseekChatLogprobSchema).nullish(),
476
+ reasoning_content: z3.array(deepseekChatLogprobSchema).nullish()
477
+ }).nullish();
478
+ var deepseekChatResponseSchema = z3.object({
479
+ id: z3.string().nullish(),
480
+ created: z3.number().nullish(),
481
+ model: z3.string().nullish(),
482
+ object: z3.literal("chat.completion").nullish(),
483
+ system_fingerprint: z3.string().nullish(),
484
+ choices: z3.array(
485
+ z3.object({
486
+ index: z3.number().nullish(),
487
+ message: z3.object({
488
+ role: z3.literal("assistant").nullish(),
489
+ content: z3.string().nullish(),
490
+ reasoning_content: z3.string().nullish(),
491
+ tool_calls: z3.array(
492
+ z3.object({
493
+ id: z3.string().nullish(),
494
+ type: z3.literal("function").nullish(),
495
+ function: z3.object({
496
+ name: z3.string(),
497
+ arguments: z3.string()
273
498
  })
274
499
  })
275
500
  ).nullish()
276
501
  }),
277
- finish_reason: z.string().nullish()
502
+ logprobs: deepseekChatLogprobsSchema,
503
+ finish_reason: z3.string().nullish()
278
504
  })
279
505
  ),
280
506
  usage: tokenUsageSchema
281
507
  });
282
508
  var deepseekChatChunkSchema = lazySchema(
283
509
  () => zodSchema(
284
- z.union([
285
- z.object({
286
- id: z.string().nullish(),
287
- created: z.number().nullish(),
288
- model: z.string().nullish(),
289
- choices: z.array(
290
- z.object({
291
- delta: z.object({
292
- role: z.enum(["assistant"]).nullish(),
293
- content: z.string().nullish(),
294
- reasoning_content: z.string().nullish(),
295
- tool_calls: z.array(
296
- z.object({
297
- index: z.number(),
298
- id: z.string().nullish(),
299
- function: z.object({
300
- name: z.string().nullish(),
301
- arguments: z.string().nullish()
510
+ z3.union([
511
+ z3.object({
512
+ id: z3.string().nullish(),
513
+ created: z3.number().nullish(),
514
+ model: z3.string().nullish(),
515
+ object: z3.literal("chat.completion.chunk").nullish(),
516
+ system_fingerprint: z3.string().nullish(),
517
+ choices: z3.array(
518
+ z3.object({
519
+ index: z3.number().nullish(),
520
+ delta: z3.object({
521
+ role: z3.enum(["assistant"]).nullish(),
522
+ content: z3.string().nullish(),
523
+ reasoning_content: z3.string().nullish(),
524
+ tool_calls: z3.array(
525
+ z3.object({
526
+ index: z3.number(),
527
+ id: z3.string().nullish(),
528
+ type: z3.literal("function").nullish(),
529
+ function: z3.object({
530
+ name: z3.string().nullish(),
531
+ arguments: z3.string().nullish()
302
532
  })
303
533
  })
304
534
  ).nullish()
305
535
  }).nullish(),
306
- finish_reason: z.string().nullish()
536
+ logprobs: deepseekChatLogprobsSchema,
537
+ finish_reason: z3.string().nullish()
307
538
  })
308
539
  ),
309
540
  usage: tokenUsageSchema
@@ -313,44 +544,34 @@ var deepseekChatChunkSchema = lazySchema(
313
544
  )
314
545
  );
315
546
 
316
- // src/chat/deepseek-chat-language-model-options.ts
317
- import { z as z2 } from "zod/v4";
318
- var deepseekLanguageModelChatOptions = z2.object({
319
- /**
320
- * Type of thinking to use. Defaults to `enabled`.
321
- *
322
- * See https://api-docs.deepseek.com/guides/thinking_mode for the
323
- * `adaptive` option, which lets the model decide when to think.
324
- */
325
- thinking: z2.object({
326
- type: z2.enum(["adaptive", "enabled", "disabled"]).optional()
327
- }).optional(),
328
- /**
329
- * Controls the thinking strength for DeepSeek V4 reasoning models.
330
- *
331
- * DeepSeek's API accepts `low`, `medium`, `high`, `xhigh`, and `max`.
332
- * Per their docs, `low` and `medium` are mapped to `high`, and `xhigh`
333
- * is mapped to `max` server-side for compatibility with other providers.
334
- */
335
- reasoningEffort: z2.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
336
- /**
337
- * Whether to use strict JSON schema validation for structured outputs.
338
- * Only applies when the serving endpoint supports JSON schema response
339
- * formats (e.g. Azure). Defaults to `true`.
340
- */
341
- strictJsonSchema: z2.boolean().optional()
342
- });
343
-
344
547
  // src/chat/deepseek-prepare-tools.ts
548
+ import {
549
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError2
550
+ } from "@ai-sdk/provider";
345
551
  function prepareTools({
346
552
  tools,
347
- toolChoice
553
+ toolChoice,
554
+ supportsStrictToolCalls
348
555
  }) {
349
556
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
350
557
  const toolWarnings = [];
351
558
  if (tools == null) {
352
559
  return { tools: void 0, toolChoice: void 0, toolWarnings };
353
560
  }
561
+ const functionTools = tools.filter((tool) => tool.type === "function");
562
+ const hasStrictTool = functionTools.some((tool) => tool.strict === true);
563
+ if (hasStrictTool && supportsStrictToolCalls === false) {
564
+ throw new UnsupportedFunctionalityError2({
565
+ functionality: "DeepSeek strict tool calls",
566
+ message: "DeepSeek strict tool calls require a beta base URL ending in `/beta`."
567
+ });
568
+ }
569
+ if (hasStrictTool && supportsStrictToolCalls === true && functionTools.some((tool) => tool.strict !== true)) {
570
+ throw new UnsupportedFunctionalityError2({
571
+ functionality: "mixed DeepSeek strict and non-strict tool calls",
572
+ message: "DeepSeek strict mode requires every function tool in the request to set `strict: true`."
573
+ });
574
+ }
354
575
  const deepseekTools = [];
355
576
  for (const tool of tools) {
356
577
  if (tool.type === "provider") {
@@ -426,6 +647,80 @@ function mapDeepSeekFinishReason(finishReason) {
426
647
  }
427
648
 
428
649
  // src/chat/deepseek-chat-language-model.ts
650
+ function createDeepSeekStreamError(error, data) {
651
+ var _a, _b;
652
+ const metadata = getDeepSeekStreamErrorMetadata(error);
653
+ return createProviderStreamError({
654
+ message: error.message,
655
+ type: (_a = error.type) != null ? _a : void 0,
656
+ code: (_b = error.code) != null ? _b : void 0,
657
+ ...metadata,
658
+ data
659
+ });
660
+ }
661
+ function getDeepSeekStreamErrorMetadata(error) {
662
+ if (error.code === "insufficient_quota" || error.type === "insufficient_quota") {
663
+ return { statusCode: 429, isRetryable: false };
664
+ }
665
+ const explicitStatusCode = getHttpStatusCode(error.code);
666
+ if (explicitStatusCode != null) {
667
+ return {
668
+ statusCode: explicitStatusCode,
669
+ isRetryable: isRetryableStatusCode(explicitStatusCode)
670
+ };
671
+ }
672
+ for (const discriminator of [error.code, error.type]) {
673
+ switch (discriminator) {
674
+ case "rate_limit_exceeded":
675
+ case "rate_limit_error":
676
+ return { statusCode: 429, isRetryable: true };
677
+ case "server_error":
678
+ case "api_error":
679
+ case "internal_server_error":
680
+ return { statusCode: 500, isRetryable: true };
681
+ case "overloaded_error":
682
+ case "service_unavailable":
683
+ return { statusCode: 503, isRetryable: true };
684
+ case "timeout":
685
+ case "timeout_error":
686
+ return { statusCode: 504, isRetryable: true };
687
+ case "authentication_error":
688
+ case "invalid_api_key":
689
+ return { statusCode: 401, isRetryable: false };
690
+ case "permission_error":
691
+ return { statusCode: 403, isRetryable: false };
692
+ case "not_found_error":
693
+ case "model_not_found":
694
+ return { statusCode: 404, isRetryable: false };
695
+ case "bad_request":
696
+ case "context_length_exceeded":
697
+ case "invalid_request_error":
698
+ return { statusCode: 400, isRetryable: false };
699
+ }
700
+ }
701
+ return {};
702
+ }
703
+ function getHttpStatusCode(value) {
704
+ const statusCode = typeof value === "string" && /^\d{3}$/.test(value) ? Number(value) : value;
705
+ return typeof statusCode === "number" && Number.isInteger(statusCode) && statusCode >= 400 && statusCode <= 599 ? statusCode : void 0;
706
+ }
707
+ function isRetryableStatusCode(statusCode) {
708
+ return statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500;
709
+ }
710
+ function mapDeepSeekProviderReasoningEffort({
711
+ reasoningEffort,
712
+ warnings
713
+ }) {
714
+ const mapped = reasoningEffort === "medium" ? "high" : reasoningEffort === "xhigh" ? "max" : reasoningEffort;
715
+ if (mapped !== reasoningEffort) {
716
+ warnings.push({
717
+ type: "compatibility",
718
+ feature: "reasoningEffort",
719
+ details: `reasoningEffort "${reasoningEffort}" is not a canonical DeepSeek value. mapped to "${mapped}".`
720
+ });
721
+ }
722
+ return mapped;
723
+ }
429
724
  var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
430
725
  constructor(modelId, config) {
431
726
  this.specificationVersion = "v4";
@@ -470,17 +765,20 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
470
765
  toolChoice,
471
766
  tools
472
767
  }) {
473
- var _a, _b, _c, _d, _e;
474
- const deepseekOptions = (_a = await parseProviderOptions({
768
+ var _a, _b, _c, _d;
769
+ const deepseekOptions = (_a = await parseProviderOptions2({
475
770
  provider: this.providerOptionsName,
476
771
  providerOptions,
477
772
  schema: deepseekLanguageModelChatOptions
478
773
  })) != null ? _a : {};
479
774
  const supportsStructuredOutputs = this.config.supportsStructuredOutputs === true;
480
- const { messages, warnings } = convertToDeepSeekChatMessages({
775
+ const supportsPenaltySampling = this.config.supportsPenaltySampling === true;
776
+ const { messages, warnings } = await convertToDeepSeekChatMessages({
481
777
  prompt,
482
778
  responseFormat,
483
779
  modelId: this.modelId,
780
+ providerOptionsName: this.providerOptionsName,
781
+ supportsAssistantPrefixCompletion: this.config.supportsAssistantPrefixCompletion,
484
782
  supportsStructuredOutputs
485
783
  });
486
784
  const allWarnings = [...warnings];
@@ -490,21 +788,62 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
490
788
  if (seed != null) {
491
789
  allWarnings.push({ type: "unsupported", feature: "seed" });
492
790
  }
791
+ if (!supportsPenaltySampling && frequencyPenalty != null) {
792
+ allWarnings.push({
793
+ type: "deprecated",
794
+ setting: "frequencyPenalty",
795
+ message: "frequencyPenalty is deprecated by DeepSeek and has been omitted. Remove frequencyPenalty from the request."
796
+ });
797
+ }
798
+ if (!supportsPenaltySampling && presencePenalty != null) {
799
+ allWarnings.push({
800
+ type: "deprecated",
801
+ setting: "presencePenalty",
802
+ message: "presencePenalty is deprecated by DeepSeek and has been omitted. Remove presencePenalty from the request."
803
+ });
804
+ }
493
805
  const {
494
806
  tools: deepseekTools,
495
807
  toolChoice: deepseekToolChoices,
496
808
  toolWarnings
497
809
  } = prepareTools({
498
810
  tools,
499
- toolChoice
811
+ toolChoice,
812
+ supportsStrictToolCalls: this.config.supportsStrictToolCalls
500
813
  });
501
- const thinking = this.config.supportsThinking === false ? void 0 : ((_b = deepseekOptions.thinking) == null ? void 0 : _b.type) != null ? { type: deepseekOptions.thinking.type } : isCustomReasoning(reasoning) ? { type: reasoning === "none" ? "disabled" : "enabled" } : void 0;
502
- const reasoningEffort = (_c = deepseekOptions.reasoningEffort) != null ? _c : isCustomReasoning(reasoning) && reasoning !== "none" ? mapReasoningToProviderEffort({
814
+ const thinkingType = (_b = deepseekOptions.thinking) == null ? void 0 : _b.type;
815
+ if (thinkingType === "adaptive") {
816
+ allWarnings.push({
817
+ type: "compatibility",
818
+ feature: "thinking.type",
819
+ details: 'thinking.type "adaptive" is not a canonical DeepSeek value. mapped to "enabled".'
820
+ });
821
+ }
822
+ const thinking = this.config.supportsThinking === false ? void 0 : thinkingType != null ? { type: thinkingType === "adaptive" ? "enabled" : thinkingType } : isCustomReasoning(reasoning) ? { type: reasoning === "none" ? "disabled" : "enabled" } : void 0;
823
+ const isThinkingEnabled = this.config.supportsThinking !== false && (thinking == null ? void 0 : thinking.type) !== "disabled" && (thinking != null || this.modelId === "deepseek-reasoner" || this.modelId.includes("deepseek-v4"));
824
+ if (isThinkingEnabled && temperature != null) {
825
+ allWarnings.push({
826
+ type: "unsupported",
827
+ feature: "temperature",
828
+ details: "temperature has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use temperature."
829
+ });
830
+ }
831
+ if (isThinkingEnabled && topP != null) {
832
+ allWarnings.push({
833
+ type: "unsupported",
834
+ feature: "topP",
835
+ details: "topP has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use topP."
836
+ });
837
+ }
838
+ const reasoningEffort = deepseekOptions.reasoningEffort != null ? mapDeepSeekProviderReasoningEffort({
839
+ reasoningEffort: deepseekOptions.reasoningEffort,
840
+ warnings: allWarnings
841
+ }) : isCustomReasoning(reasoning) && reasoning !== "none" ? mapReasoningToProviderEffort({
503
842
  reasoning,
504
843
  effortMap: {
505
844
  minimal: "low",
506
845
  low: "low",
507
- medium: "medium",
846
+ medium: "high",
508
847
  high: "high",
509
848
  xhigh: "max"
510
849
  },
@@ -513,17 +852,21 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
513
852
  return {
514
853
  args: {
515
854
  model: this.modelId,
855
+ ...(deepseekOptions.logprobs === true || deepseekOptions.topLogprobs != null) && { logprobs: true },
856
+ ...deepseekOptions.topLogprobs != null && {
857
+ top_logprobs: deepseekOptions.topLogprobs
858
+ },
516
859
  max_tokens: maxOutputTokens,
517
- temperature,
518
- top_p: topP,
519
- frequency_penalty: frequencyPenalty,
520
- presence_penalty: presencePenalty,
860
+ temperature: isThinkingEnabled ? void 0 : temperature,
861
+ top_p: isThinkingEnabled ? void 0 : topP,
862
+ frequency_penalty: supportsPenaltySampling ? frequencyPenalty : void 0,
863
+ presence_penalty: supportsPenaltySampling ? presencePenalty : void 0,
521
864
  response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? supportsStructuredOutputs && responseFormat.schema != null ? {
522
865
  type: "json_schema",
523
866
  json_schema: {
524
867
  schema: responseFormat.schema,
525
- strict: (_d = deepseekOptions.strictJsonSchema) != null ? _d : true,
526
- name: (_e = responseFormat.name) != null ? _e : "response",
868
+ strict: (_c = deepseekOptions.strictJsonSchema) != null ? _c : true,
869
+ name: (_d = responseFormat.name) != null ? _d : "response",
527
870
  description: responseFormat.description
528
871
  }
529
872
  } : { type: "json_object" } : void 0,
@@ -532,6 +875,9 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
532
875
  tools: deepseekTools,
533
876
  tool_choice: deepseekToolChoices,
534
877
  thinking,
878
+ ...deepseekOptions.userId != null && {
879
+ user_id: deepseekOptions.userId
880
+ },
535
881
  ...(thinking == null ? void 0 : thinking.type) !== "disabled" && reasoningEffort != null && {
536
882
  reasoning_effort: reasoningEffort
537
883
  }
@@ -593,7 +939,21 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
593
939
  providerMetadata: {
594
940
  [this.providerOptionsName]: {
595
941
  promptCacheHitTokens: (_d = responseBody.usage) == null ? void 0 : _d.prompt_cache_hit_tokens,
596
- promptCacheMissTokens: (_e = responseBody.usage) == null ? void 0 : _e.prompt_cache_miss_tokens
942
+ promptCacheMissTokens: (_e = responseBody.usage) == null ? void 0 : _e.prompt_cache_miss_tokens,
943
+ ...responseBody.object != null && {
944
+ responseObject: responseBody.object
945
+ },
946
+ ...choice.index != null && { choiceIndex: choice.index },
947
+ ...choice.message.role != null && {
948
+ messageRole: choice.message.role
949
+ },
950
+ ...choice.message.tool_calls != null && {
951
+ toolCallTypes: choice.message.tool_calls.map((toolCall) => toolCall.type).filter((type) => type != null)
952
+ },
953
+ ...choice.logprobs != null && { logprobs: choice.logprobs },
954
+ ...responseBody.system_fingerprint != null && {
955
+ systemFingerprint: responseBody.system_fingerprint
956
+ }
597
957
  }
598
958
  },
599
959
  request: { body: args },
@@ -633,10 +993,17 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
633
993
  raw: void 0
634
994
  };
635
995
  let usage = void 0;
996
+ let systemFingerprint = void 0;
636
997
  let isFirstChunk = true;
637
998
  const providerOptionsName = this.providerOptionsName;
638
999
  let isActiveReasoning = false;
639
1000
  let isActiveText = false;
1001
+ let responseObject;
1002
+ let choiceIndex;
1003
+ let messageRole;
1004
+ const toolCallTypes = /* @__PURE__ */ new Map();
1005
+ const contentLogprobs = [];
1006
+ const reasoningLogprobs = [];
640
1007
  return {
641
1008
  stream: response.pipeThrough(
642
1009
  new TransformStream({
@@ -647,6 +1014,7 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
647
1014
  controller.enqueue({ type: "stream-start", warnings });
648
1015
  },
649
1016
  transform(chunk, controller) {
1017
+ var _a2, _b2;
650
1018
  if (options.includeRawChunks) {
651
1019
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
652
1020
  }
@@ -658,7 +1026,10 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
658
1026
  const value = chunk.value;
659
1027
  if ("error" in value) {
660
1028
  finishReason = { unified: "error", raw: void 0 };
661
- controller.enqueue({ type: "error", error: value.error.message });
1029
+ controller.enqueue({
1030
+ type: "error",
1031
+ error: createDeepSeekStreamError(value.error, value)
1032
+ });
662
1033
  return;
663
1034
  }
664
1035
  if (isFirstChunk) {
@@ -671,17 +1042,35 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
671
1042
  if (value.usage != null) {
672
1043
  usage = value.usage;
673
1044
  }
1045
+ if (value.object != null) {
1046
+ responseObject = value.object;
1047
+ }
1048
+ if (value.system_fingerprint != null) {
1049
+ systemFingerprint = value.system_fingerprint;
1050
+ }
674
1051
  const choice = value.choices[0];
1052
+ if ((choice == null ? void 0 : choice.index) != null) {
1053
+ choiceIndex = choice.index;
1054
+ }
675
1055
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
676
1056
  finishReason = {
677
1057
  unified: mapDeepSeekFinishReason(choice.finish_reason),
678
1058
  raw: choice.finish_reason
679
1059
  };
680
1060
  }
1061
+ if (((_a2 = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _a2.content) != null) {
1062
+ contentLogprobs.push(...choice.logprobs.content);
1063
+ }
1064
+ if (((_b2 = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _b2.reasoning_content) != null) {
1065
+ reasoningLogprobs.push(...choice.logprobs.reasoning_content);
1066
+ }
681
1067
  if ((choice == null ? void 0 : choice.delta) == null) {
682
1068
  return;
683
1069
  }
684
1070
  const delta = choice.delta;
1071
+ if (delta.role != null) {
1072
+ messageRole = delta.role;
1073
+ }
685
1074
  const reasoningContent = delta.reasoning_content;
686
1075
  if (reasoningContent) {
687
1076
  if (!isActiveReasoning) {
@@ -724,6 +1113,9 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
724
1113
  isActiveReasoning = false;
725
1114
  }
726
1115
  for (const toolCallDelta of delta.tool_calls) {
1116
+ if (toolCallDelta.type != null) {
1117
+ toolCallTypes.set(toolCallDelta.index, toolCallDelta.type);
1118
+ }
727
1119
  toolCallTracker.processDelta(toolCallDelta);
728
1120
  }
729
1121
  }
@@ -744,7 +1136,24 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
744
1136
  providerMetadata: {
745
1137
  [providerOptionsName]: {
746
1138
  promptCacheHitTokens: (_a2 = usage == null ? void 0 : usage.prompt_cache_hit_tokens) != null ? _a2 : void 0,
747
- promptCacheMissTokens: (_b2 = usage == null ? void 0 : usage.prompt_cache_miss_tokens) != null ? _b2 : void 0
1139
+ promptCacheMissTokens: (_b2 = usage == null ? void 0 : usage.prompt_cache_miss_tokens) != null ? _b2 : void 0,
1140
+ ...responseObject != null && { responseObject },
1141
+ ...choiceIndex != null && { choiceIndex },
1142
+ ...messageRole != null && { messageRole },
1143
+ ...toolCallTypes.size > 0 && {
1144
+ toolCallTypes: [...toolCallTypes.entries()].sort(([left], [right]) => left - right).map(([, type]) => type)
1145
+ },
1146
+ ...(contentLogprobs.length > 0 || reasoningLogprobs.length > 0) && {
1147
+ logprobs: {
1148
+ ...contentLogprobs.length > 0 && {
1149
+ content: contentLogprobs
1150
+ },
1151
+ ...reasoningLogprobs.length > 0 && {
1152
+ reasoning_content: reasoningLogprobs
1153
+ }
1154
+ }
1155
+ },
1156
+ ...systemFingerprint != null && { systemFingerprint }
748
1157
  }
749
1158
  }
750
1159
  });
@@ -758,6 +1167,8 @@ var DeepSeekChatLanguageModel = class _DeepSeekChatLanguageModel {
758
1167
  };
759
1168
  export {
760
1169
  DeepSeekChatLanguageModel,
761
- deepseekLanguageModelChatOptions
1170
+ deepseekAssistantMessageProviderOptions,
1171
+ deepseekLanguageModelChatOptions,
1172
+ deepseekMessageProviderOptions
762
1173
  };
763
1174
  //# sourceMappingURL=index.js.map