@ai-sdk/deepseek 2.0.58 → 2.0.59

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.mjs CHANGED
@@ -18,16 +18,112 @@ import {
18
18
  createJsonErrorResponseHandler,
19
19
  createJsonResponseHandler,
20
20
  generateId,
21
- parseProviderOptions,
21
+ parseProviderOptions as parseProviderOptions2,
22
22
  postJsonToApi
23
23
  } from "@ai-sdk/provider-utils";
24
24
 
25
25
  // src/chat/convert-to-deepseek-chat-messages.ts
26
- import { convertToBase64 } from "@ai-sdk/provider-utils";
27
- function convertToDeepSeekChatMessages({
26
+ import {
27
+ InvalidPromptError,
28
+ UnsupportedFunctionalityError
29
+ } from "@ai-sdk/provider";
30
+ import { convertToBase64, parseProviderOptions } from "@ai-sdk/provider-utils";
31
+
32
+ // src/chat/deepseek-chat-options.ts
33
+ import { z } from "zod/v4";
34
+ var deepseekLanguageModelOptions = z.object({
35
+ /**
36
+ * Whether to return log probabilities for generated tokens.
37
+ */
38
+ logprobs: z.boolean().optional(),
39
+ /**
40
+ * Number of most likely tokens to return at each token position.
41
+ *
42
+ * Setting this option automatically enables `logprobs`.
43
+ */
44
+ topLogprobs: z.number().int().min(0).max(20).optional(),
45
+ /**
46
+ * An opaque identifier for the end user. DeepSeek uses this identifier for
47
+ * content-safety tracing and request isolation.
48
+ *
49
+ * Must contain only ASCII letters, numbers, underscores, and hyphens, and
50
+ * must be at most 512 characters long.
51
+ */
52
+ 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(),
53
+ /**
54
+ * Type of thinking to use. Defaults to `enabled`.
55
+ */
56
+ thinking: z.object({
57
+ // `adaptive` is accepted at runtime for backwards compatibility and
58
+ // mapped to `enabled`, but is intentionally excluded from the exported
59
+ // provider options type.
60
+ type: z.enum(["adaptive", "enabled", "disabled"]).optional()
61
+ }).optional(),
62
+ /**
63
+ * Controls the thinking strength for DeepSeek V4 reasoning models.
64
+ */
65
+ // `medium` and `xhigh` are accepted at runtime for backwards compatibility
66
+ // and mapped to canonical DeepSeek values, but are intentionally excluded
67
+ // from the exported provider options type.
68
+ reasoningEffort: z.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
69
+ /**
70
+ * Whether to use strict JSON schema validation for structured outputs.
71
+ * Only applies when the serving endpoint supports JSON schema response
72
+ * formats (e.g. Azure). Defaults to `true`.
73
+ */
74
+ strictJsonSchema: z.boolean().optional()
75
+ });
76
+ var deepseekMessageProviderOptions = z.object({
77
+ /**
78
+ * The name of the participant represented by the message.
79
+ *
80
+ * Supported on system, user, and assistant messages.
81
+ */
82
+ name: z.string().optional()
83
+ });
84
+ var deepseekAssistantMessageProviderOptions = deepseekMessageProviderOptions.extend({
85
+ /**
86
+ * Whether the assistant message content is a prefix that DeepSeek should
87
+ * continue. This beta feature is only supported on the final assistant
88
+ * message when using a beta base URL.
89
+ */
90
+ prefix: z.literal(true).optional()
91
+ });
92
+
93
+ // src/chat/deepseek-file-part-options.ts
94
+ import { z as z2 } from "zod/v4";
95
+ var deepseekFilePartProviderOptions = z2.object({
96
+ /**
97
+ * Controls how DeepSeek processes an image sent as an `image_url` part.
98
+ *
99
+ * @see https://api-docs.deepseek.com/api/create-chat-completion/
100
+ */
101
+ imageDetail: z2.enum(["low", "high", "original", "auto"]).optional(),
102
+ /**
103
+ * Sends inline image data as a DeepSeek `file` part using `file_data`
104
+ * instead of an `image_url` data URL. When set, the file part's filename
105
+ * is preserved.
106
+ *
107
+ * This option only applies to inline image data. It cannot be combined
108
+ * with `imageDetail`.
109
+ */
110
+ fileData: 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({
28
122
  prompt,
29
123
  responseFormat,
30
124
  modelId,
125
+ providerOptionsName = "deepseek",
126
+ supportsAssistantPrefixCompletion = false,
31
127
  supportsStructuredOutputs = false
32
128
  }) {
33
129
  var _a;
@@ -60,11 +156,28 @@ function convertToDeepSeekChatMessages({
60
156
  }
61
157
  }
62
158
  let index = -1;
63
- for (const { role, content } of prompt) {
159
+ for (const { role, content, providerOptions } of prompt) {
64
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
+ }
65
172
  switch (role) {
66
173
  case "system": {
67
- 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
+ });
68
181
  break;
69
182
  }
70
183
  case "user": {
@@ -83,7 +196,13 @@ function convertToDeepSeekChatMessages({
83
196
  });
84
197
  }
85
198
  }
86
- 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
+ });
87
206
  break;
88
207
  }
89
208
  const userContent = [];
@@ -91,13 +210,67 @@ function convertToDeepSeekChatMessages({
91
210
  if (part.type === "text") {
92
211
  userContent.push({ type: "text", text: part.text });
93
212
  } else if (part.type === "file" && (part.mediaType === "image" || part.mediaType.startsWith("image/"))) {
94
- const mediaType = part.mediaType === "image" || part.mediaType === "image/*" ? "image/jpeg" : part.mediaType;
95
- userContent.push({
96
- type: "image_url",
97
- image_url: {
98
- url: part.data instanceof URL ? part.data.toString() : `data:${mediaType};base64,${convertToBase64(part.data)}`
99
- }
213
+ const filePartOptions = await parseProviderOptions({
214
+ provider: providerOptionsName,
215
+ providerOptions: part.providerOptions,
216
+ schema: deepseekFilePartProviderOptions
100
217
  });
218
+ const resolvedMediaType = part.mediaType === "image" || part.mediaType === "image/*" ? "image/jpeg" : part.mediaType;
219
+ if (!supportedImageMediaTypes.has(resolvedMediaType)) {
220
+ throw new UnsupportedFunctionalityError({
221
+ functionality: `DeepSeek image media type ${resolvedMediaType}`,
222
+ message: "DeepSeek supports JPEG, PNG, GIF, and WebP image inputs."
223
+ });
224
+ }
225
+ if (part.data instanceof URL) {
226
+ const url = part.data.toString();
227
+ if (url.length > 8192) {
228
+ throw new InvalidPromptError({
229
+ prompt,
230
+ message: "DeepSeek image URLs must not exceed 8192 characters."
231
+ });
232
+ }
233
+ if ((filePartOptions == null ? void 0 : filePartOptions.fileData) === true) {
234
+ throw new InvalidPromptError({
235
+ prompt,
236
+ message: "DeepSeek `fileData` image parts require inline data, not a URL."
237
+ });
238
+ }
239
+ userContent.push({
240
+ type: "image_url",
241
+ image_url: {
242
+ url,
243
+ ...(filePartOptions == null ? void 0 : filePartOptions.imageDetail) != null && {
244
+ detail: filePartOptions.imageDetail
245
+ }
246
+ }
247
+ });
248
+ } else {
249
+ const dataUrl = `data:${resolvedMediaType === "image/jpg" ? "image/jpeg" : resolvedMediaType};base64,${convertToBase64(part.data)}`;
250
+ if ((filePartOptions == null ? void 0 : filePartOptions.fileData) === true) {
251
+ if (filePartOptions.imageDetail != null) {
252
+ throw new InvalidPromptError({
253
+ prompt,
254
+ message: "DeepSeek `imageDetail` cannot be combined with `fileData`."
255
+ });
256
+ }
257
+ userContent.push({
258
+ type: "file",
259
+ file_data: dataUrl,
260
+ ...part.filename != null && { filename: part.filename }
261
+ });
262
+ } else {
263
+ userContent.push({
264
+ type: "image_url",
265
+ image_url: {
266
+ url: dataUrl,
267
+ ...(filePartOptions == null ? void 0 : filePartOptions.imageDetail) != null && {
268
+ detail: filePartOptions.imageDetail
269
+ }
270
+ }
271
+ });
272
+ }
273
+ }
101
274
  } else {
102
275
  warnings.push({
103
276
  type: "unsupported",
@@ -105,10 +278,30 @@ function convertToDeepSeekChatMessages({
105
278
  });
106
279
  }
107
280
  }
108
- messages.push({ role: "user", content: userContent });
281
+ messages.push({
282
+ role: "user",
283
+ content: userContent,
284
+ ...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
285
+ name: deepseekMessageOptions.name
286
+ }
287
+ });
109
288
  break;
110
289
  }
111
290
  case "assistant": {
291
+ if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true) {
292
+ if (index !== prompt.length - 1) {
293
+ throw new InvalidPromptError({
294
+ prompt,
295
+ message: "DeepSeek assistant prefix completion requires the prefixed assistant message to be the final message."
296
+ });
297
+ }
298
+ if (!supportsAssistantPrefixCompletion) {
299
+ throw new UnsupportedFunctionalityError({
300
+ functionality: "DeepSeek assistant prefix completion",
301
+ message: "DeepSeek assistant prefix completion requires a beta base URL ending in `/beta`."
302
+ });
303
+ }
304
+ }
112
305
  let text = "";
113
306
  let reasoning;
114
307
  const toolCalls = [];
@@ -145,12 +338,24 @@ function convertToDeepSeekChatMessages({
145
338
  messages.push({
146
339
  role: "assistant",
147
340
  content: text,
341
+ ...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null && {
342
+ name: deepseekMessageOptions.name
343
+ },
344
+ ...(deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.prefix) === true && {
345
+ prefix: true
346
+ },
148
347
  reasoning_content: reasoning != null ? reasoning : isDeepSeekV4 ? "" : void 0,
149
348
  tool_calls: toolCalls.length > 0 ? toolCalls : void 0
150
349
  });
151
350
  break;
152
351
  }
153
352
  case "tool": {
353
+ if ((deepseekMessageOptions == null ? void 0 : deepseekMessageOptions.name) != null) {
354
+ warnings.push({
355
+ type: "unsupported",
356
+ feature: "message name on tool messages"
357
+ });
358
+ }
154
359
  for (const toolResponse of content) {
155
360
  if (toolResponse.type === "tool-approval-response") {
156
361
  continue;
@@ -223,7 +428,7 @@ function convertDeepSeekUsage(usage) {
223
428
  },
224
429
  outputTokens: {
225
430
  total: completionTokens,
226
- text: completionTokens - reasoningTokens,
431
+ text: Math.max(0, completionTokens - reasoningTokens),
227
432
  reasoning: reasoningTokens
228
433
  },
229
434
  raw: usage
@@ -232,75 +437,101 @@ function convertDeepSeekUsage(usage) {
232
437
 
233
438
  // src/chat/deepseek-chat-api-types.ts
234
439
  import { lazySchema, zodSchema } from "@ai-sdk/provider-utils";
235
- import { z } from "zod/v4";
236
- var tokenUsageSchema = z.object({
237
- prompt_tokens: z.number().nullish(),
238
- completion_tokens: z.number().nullish(),
239
- prompt_cache_hit_tokens: z.number().nullish(),
240
- prompt_cache_miss_tokens: z.number().nullish(),
241
- total_tokens: z.number().nullish(),
242
- completion_tokens_details: z.object({
243
- reasoning_tokens: z.number().nullish()
440
+ import { z as z3 } from "zod/v4";
441
+ var tokenUsageSchema = z3.object({
442
+ prompt_tokens: z3.number().nullish(),
443
+ completion_tokens: z3.number().nullish(),
444
+ prompt_cache_hit_tokens: z3.number().nullish(),
445
+ prompt_cache_miss_tokens: z3.number().nullish(),
446
+ total_tokens: z3.number().nullish(),
447
+ completion_tokens_details: z3.object({
448
+ reasoning_tokens: z3.number().nullish()
244
449
  }).nullish()
245
450
  }).nullish();
246
- var deepSeekErrorSchema = z.object({
247
- error: z.object({
248
- message: z.string(),
249
- type: z.string().nullish(),
250
- param: z.any().nullish(),
251
- code: z.union([z.string(), z.number()]).nullish()
451
+ var deepSeekErrorSchema = z3.object({
452
+ error: z3.object({
453
+ message: z3.string(),
454
+ type: z3.string().nullish(),
455
+ param: z3.any().nullish(),
456
+ code: z3.union([z3.string(), z3.number()]).nullish()
252
457
  })
253
458
  });
254
- var deepseekChatResponseSchema = z.object({
255
- id: z.string().nullish(),
256
- created: z.number().nullish(),
257
- model: z.string().nullish(),
258
- choices: z.array(
259
- z.object({
260
- message: z.object({
261
- role: z.literal("assistant").nullish(),
262
- content: z.string().nullish(),
263
- reasoning_content: z.string().nullish(),
264
- tool_calls: z.array(
265
- z.object({
266
- id: z.string().nullish(),
267
- function: z.object({
268
- name: z.string(),
269
- arguments: z.string()
459
+ var deepseekChatLogprobSchema = z3.object({
460
+ token: z3.string(),
461
+ logprob: z3.number(),
462
+ bytes: z3.array(z3.number()).nullable(),
463
+ top_logprobs: z3.array(
464
+ z3.object({
465
+ token: z3.string(),
466
+ logprob: z3.number(),
467
+ bytes: z3.array(z3.number()).nullable()
468
+ })
469
+ )
470
+ });
471
+ var deepseekChatLogprobsSchema = z3.object({
472
+ content: z3.array(deepseekChatLogprobSchema).nullish(),
473
+ reasoning_content: z3.array(deepseekChatLogprobSchema).nullish()
474
+ }).nullish();
475
+ var deepseekChatResponseSchema = z3.object({
476
+ id: z3.string().nullish(),
477
+ created: z3.number().nullish(),
478
+ model: z3.string().nullish(),
479
+ object: z3.literal("chat.completion").nullish(),
480
+ system_fingerprint: z3.string().nullish(),
481
+ choices: z3.array(
482
+ z3.object({
483
+ index: z3.number().nullish(),
484
+ message: z3.object({
485
+ role: z3.literal("assistant").nullish(),
486
+ content: z3.string().nullish(),
487
+ reasoning_content: z3.string().nullish(),
488
+ tool_calls: z3.array(
489
+ z3.object({
490
+ id: z3.string().nullish(),
491
+ type: z3.literal("function").nullish(),
492
+ function: z3.object({
493
+ name: z3.string(),
494
+ arguments: z3.string()
270
495
  })
271
496
  })
272
497
  ).nullish()
273
498
  }),
274
- finish_reason: z.string().nullish()
499
+ logprobs: deepseekChatLogprobsSchema,
500
+ finish_reason: z3.string().nullish()
275
501
  })
276
502
  ),
277
503
  usage: tokenUsageSchema
278
504
  });
279
505
  var deepseekChatChunkSchema = lazySchema(
280
506
  () => zodSchema(
281
- z.union([
282
- z.object({
283
- id: z.string().nullish(),
284
- created: z.number().nullish(),
285
- model: z.string().nullish(),
286
- choices: z.array(
287
- z.object({
288
- delta: z.object({
289
- role: z.enum(["assistant"]).nullish(),
290
- content: z.string().nullish(),
291
- reasoning_content: z.string().nullish(),
292
- tool_calls: z.array(
293
- z.object({
294
- index: z.number(),
295
- id: z.string().nullish(),
296
- function: z.object({
297
- name: z.string().nullish(),
298
- arguments: z.string().nullish()
507
+ z3.union([
508
+ z3.object({
509
+ id: z3.string().nullish(),
510
+ created: z3.number().nullish(),
511
+ model: z3.string().nullish(),
512
+ object: z3.literal("chat.completion.chunk").nullish(),
513
+ system_fingerprint: z3.string().nullish(),
514
+ choices: z3.array(
515
+ z3.object({
516
+ index: z3.number().nullish(),
517
+ delta: z3.object({
518
+ role: z3.enum(["assistant"]).nullish(),
519
+ content: z3.string().nullish(),
520
+ reasoning_content: z3.string().nullish(),
521
+ tool_calls: z3.array(
522
+ z3.object({
523
+ index: z3.number(),
524
+ id: z3.string().nullish(),
525
+ type: z3.literal("function").nullish(),
526
+ function: z3.object({
527
+ name: z3.string().nullish(),
528
+ arguments: z3.string().nullish()
299
529
  })
300
530
  })
301
531
  ).nullish()
302
532
  }).nullish(),
303
- finish_reason: z.string().nullish()
533
+ logprobs: deepseekChatLogprobsSchema,
534
+ finish_reason: z3.string().nullish()
304
535
  })
305
536
  ),
306
537
  usage: tokenUsageSchema
@@ -310,44 +541,34 @@ var deepseekChatChunkSchema = lazySchema(
310
541
  )
311
542
  );
312
543
 
313
- // src/chat/deepseek-chat-options.ts
314
- import { z as z2 } from "zod/v4";
315
- var deepseekLanguageModelOptions = z2.object({
316
- /**
317
- * Type of thinking to use. Defaults to `enabled`.
318
- *
319
- * See https://api-docs.deepseek.com/guides/thinking_mode for the
320
- * `adaptive` option, which lets the model decide when to think.
321
- */
322
- thinking: z2.object({
323
- type: z2.enum(["adaptive", "enabled", "disabled"]).optional()
324
- }).optional(),
325
- /**
326
- * Controls the thinking strength for DeepSeek V4 reasoning models.
327
- *
328
- * DeepSeek's API accepts `low`, `medium`, `high`, `xhigh`, and `max`.
329
- * Per their docs, `low` and `medium` are mapped to `high`, and `xhigh`
330
- * is mapped to `max` server-side for compatibility with other providers.
331
- */
332
- reasoningEffort: z2.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
333
- /**
334
- * Whether to use strict JSON schema validation for structured outputs.
335
- * Only applies when the serving endpoint supports JSON schema response
336
- * formats (e.g. Azure). Defaults to `true`.
337
- */
338
- strictJsonSchema: z2.boolean().optional()
339
- });
340
-
341
544
  // src/chat/deepseek-prepare-tools.ts
545
+ import {
546
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError2
547
+ } from "@ai-sdk/provider";
342
548
  function prepareTools({
343
549
  tools,
344
- toolChoice
550
+ toolChoice,
551
+ supportsStrictToolCalls
345
552
  }) {
346
553
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
347
554
  const toolWarnings = [];
348
555
  if (tools == null) {
349
556
  return { tools: void 0, toolChoice: void 0, toolWarnings };
350
557
  }
558
+ const functionTools = tools.filter((tool) => tool.type === "function");
559
+ const hasStrictTool = functionTools.some((tool) => tool.strict === true);
560
+ if (hasStrictTool && supportsStrictToolCalls === false) {
561
+ throw new UnsupportedFunctionalityError2({
562
+ functionality: "DeepSeek strict tool calls",
563
+ message: "DeepSeek strict tool calls require a beta base URL ending in `/beta`."
564
+ });
565
+ }
566
+ if (hasStrictTool && supportsStrictToolCalls === true && functionTools.some((tool) => tool.strict !== true)) {
567
+ throw new UnsupportedFunctionalityError2({
568
+ functionality: "mixed DeepSeek strict and non-strict tool calls",
569
+ message: "DeepSeek strict mode requires every function tool in the request to set `strict: true`."
570
+ });
571
+ }
351
572
  const deepseekTools = [];
352
573
  for (const tool of tools) {
353
574
  if (tool.type === "provider") {
@@ -433,6 +654,20 @@ function mapDeepSeekFinishReason(finishReason) {
433
654
  }
434
655
 
435
656
  // src/chat/deepseek-chat-language-model.ts
657
+ function mapDeepSeekProviderReasoningEffort({
658
+ reasoningEffort,
659
+ warnings
660
+ }) {
661
+ const mapped = reasoningEffort === "medium" ? "high" : reasoningEffort === "xhigh" ? "max" : reasoningEffort;
662
+ if (mapped !== reasoningEffort) {
663
+ warnings.push({
664
+ type: "compatibility",
665
+ feature: "reasoningEffort",
666
+ details: `reasoningEffort "${reasoningEffort}" is not a canonical DeepSeek value. mapped to "${mapped}".`
667
+ });
668
+ }
669
+ return mapped;
670
+ }
436
671
  var DeepSeekChatLanguageModel = class {
437
672
  constructor(modelId, config) {
438
673
  this.specificationVersion = "v3";
@@ -468,23 +703,39 @@ var DeepSeekChatLanguageModel = class {
468
703
  tools
469
704
  }) {
470
705
  var _a, _b, _c, _d;
471
- const deepseekOptions = (_a = await parseProviderOptions({
706
+ const deepseekOptions = (_a = await parseProviderOptions2({
472
707
  provider: this.providerOptionsName,
473
708
  providerOptions,
474
709
  schema: deepseekLanguageModelOptions
475
710
  })) != null ? _a : {};
476
711
  const supportsStructuredOutputs = this.config.supportsStructuredOutputs === true;
477
- const { messages, warnings } = convertToDeepSeekChatMessages({
712
+ const supportsPenaltySampling = this.config.supportsPenaltySampling === true;
713
+ const { messages, warnings } = await convertToDeepSeekChatMessages({
478
714
  prompt,
479
715
  responseFormat,
480
716
  modelId: this.modelId,
717
+ providerOptionsName: this.providerOptionsName,
718
+ supportsAssistantPrefixCompletion: this.config.supportsAssistantPrefixCompletion,
481
719
  supportsStructuredOutputs
482
720
  });
721
+ const allWarnings = [...warnings];
483
722
  if (topK != null) {
484
- warnings.push({ type: "unsupported", feature: "topK" });
723
+ allWarnings.push({ type: "unsupported", feature: "topK" });
485
724
  }
486
725
  if (seed != null) {
487
- warnings.push({ type: "unsupported", feature: "seed" });
726
+ allWarnings.push({ type: "unsupported", feature: "seed" });
727
+ }
728
+ if (!supportsPenaltySampling && frequencyPenalty != null) {
729
+ allWarnings.push({
730
+ type: "other",
731
+ message: "frequencyPenalty is deprecated by DeepSeek and has been omitted. Remove frequencyPenalty from the request."
732
+ });
733
+ }
734
+ if (!supportsPenaltySampling && presencePenalty != null) {
735
+ allWarnings.push({
736
+ type: "other",
737
+ message: "presencePenalty is deprecated by DeepSeek and has been omitted. Remove presencePenalty from the request."
738
+ });
488
739
  }
489
740
  const {
490
741
  tools: deepseekTools,
@@ -492,17 +743,50 @@ var DeepSeekChatLanguageModel = class {
492
743
  toolWarnings
493
744
  } = prepareTools({
494
745
  tools,
495
- toolChoice
746
+ toolChoice,
747
+ supportsStrictToolCalls: this.config.supportsStrictToolCalls
496
748
  });
497
- const thinking = this.config.supportsThinking === false ? void 0 : ((_b = deepseekOptions.thinking) == null ? void 0 : _b.type) != null ? { type: deepseekOptions.thinking.type } : void 0;
749
+ allWarnings.push(...toolWarnings);
750
+ const thinkingType = (_b = deepseekOptions.thinking) == null ? void 0 : _b.type;
751
+ if (thinkingType === "adaptive") {
752
+ allWarnings.push({
753
+ type: "compatibility",
754
+ feature: "thinking.type",
755
+ details: 'thinking.type "adaptive" is not a canonical DeepSeek value. mapped to "enabled".'
756
+ });
757
+ }
758
+ const thinking = this.config.supportsThinking === false ? void 0 : thinkingType != null ? { type: thinkingType === "adaptive" ? "enabled" : thinkingType } : void 0;
759
+ const isThinkingEnabled = this.config.supportsThinking !== false && (thinking == null ? void 0 : thinking.type) !== "disabled" && (thinking != null || this.modelId === "deepseek-reasoner" || this.modelId.includes("deepseek-v4"));
760
+ if (isThinkingEnabled && temperature != null) {
761
+ allWarnings.push({
762
+ type: "unsupported",
763
+ feature: "temperature",
764
+ details: "temperature has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use temperature."
765
+ });
766
+ }
767
+ if (isThinkingEnabled && topP != null) {
768
+ allWarnings.push({
769
+ type: "unsupported",
770
+ feature: "topP",
771
+ details: "topP has no effect when DeepSeek thinking is enabled. Set providerOptions.deepseek.thinking.type to 'disabled' to use topP."
772
+ });
773
+ }
774
+ const reasoningEffort = deepseekOptions.reasoningEffort != null ? mapDeepSeekProviderReasoningEffort({
775
+ reasoningEffort: deepseekOptions.reasoningEffort,
776
+ warnings: allWarnings
777
+ }) : void 0;
498
778
  return {
499
779
  args: {
500
780
  model: this.modelId,
781
+ ...(deepseekOptions.logprobs === true || deepseekOptions.topLogprobs != null) && { logprobs: true },
782
+ ...deepseekOptions.topLogprobs != null && {
783
+ top_logprobs: deepseekOptions.topLogprobs
784
+ },
501
785
  max_tokens: maxOutputTokens,
502
- temperature,
503
- top_p: topP,
504
- frequency_penalty: frequencyPenalty,
505
- presence_penalty: presencePenalty,
786
+ temperature: isThinkingEnabled ? void 0 : temperature,
787
+ top_p: isThinkingEnabled ? void 0 : topP,
788
+ frequency_penalty: supportsPenaltySampling ? frequencyPenalty : void 0,
789
+ presence_penalty: supportsPenaltySampling ? presencePenalty : void 0,
506
790
  response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? supportsStructuredOutputs && responseFormat.schema != null ? {
507
791
  type: "json_schema",
508
792
  json_schema: {
@@ -517,11 +801,14 @@ var DeepSeekChatLanguageModel = class {
517
801
  tools: deepseekTools,
518
802
  tool_choice: deepseekToolChoices,
519
803
  thinking,
520
- ...(thinking == null ? void 0 : thinking.type) !== "disabled" && deepseekOptions.reasoningEffort != null && {
521
- reasoning_effort: deepseekOptions.reasoningEffort
804
+ ...deepseekOptions.userId != null && {
805
+ user_id: deepseekOptions.userId
806
+ },
807
+ ...(thinking == null ? void 0 : thinking.type) !== "disabled" && reasoningEffort != null && {
808
+ reasoning_effort: reasoningEffort
522
809
  }
523
810
  },
524
- warnings: [...warnings, ...toolWarnings]
811
+ warnings: allWarnings
525
812
  };
526
813
  }
527
814
  async doGenerate(options) {
@@ -578,7 +865,21 @@ var DeepSeekChatLanguageModel = class {
578
865
  providerMetadata: {
579
866
  [this.providerOptionsName]: {
580
867
  promptCacheHitTokens: (_c = responseBody.usage) == null ? void 0 : _c.prompt_cache_hit_tokens,
581
- promptCacheMissTokens: (_d = responseBody.usage) == null ? void 0 : _d.prompt_cache_miss_tokens
868
+ promptCacheMissTokens: (_d = responseBody.usage) == null ? void 0 : _d.prompt_cache_miss_tokens,
869
+ ...responseBody.object != null && {
870
+ responseObject: responseBody.object
871
+ },
872
+ ...choice.index != null && { choiceIndex: choice.index },
873
+ ...choice.message.role != null && {
874
+ messageRole: choice.message.role
875
+ },
876
+ ...choice.message.tool_calls != null && {
877
+ toolCallTypes: choice.message.tool_calls.map((toolCall) => toolCall.type).filter((type) => type != null)
878
+ },
879
+ ...choice.logprobs != null && { logprobs: choice.logprobs },
880
+ ...responseBody.system_fingerprint != null && {
881
+ systemFingerprint: responseBody.system_fingerprint
882
+ }
582
883
  }
583
884
  },
584
885
  request: { body: args },
@@ -617,10 +918,17 @@ var DeepSeekChatLanguageModel = class {
617
918
  raw: void 0
618
919
  };
619
920
  let usage = void 0;
921
+ let systemFingerprint = void 0;
620
922
  let isFirstChunk = true;
621
923
  const providerOptionsName = this.providerOptionsName;
622
924
  let isActiveReasoning = false;
623
925
  let isActiveText = false;
926
+ let responseObject;
927
+ let choiceIndex;
928
+ let messageRole;
929
+ const toolCallTypes = /* @__PURE__ */ new Map();
930
+ const contentLogprobs = [];
931
+ const reasoningLogprobs = [];
624
932
  return {
625
933
  stream: response.pipeThrough(
626
934
  new TransformStream({
@@ -628,7 +936,7 @@ var DeepSeekChatLanguageModel = class {
628
936
  controller.enqueue({ type: "stream-start", warnings });
629
937
  },
630
938
  transform(chunk, controller) {
631
- var _a, _b, _c, _d, _e, _f, _g, _h;
939
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
632
940
  if (options.includeRawChunks) {
633
941
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
634
942
  }
@@ -653,17 +961,35 @@ var DeepSeekChatLanguageModel = class {
653
961
  if (value.usage != null) {
654
962
  usage = value.usage;
655
963
  }
964
+ if (value.object != null) {
965
+ responseObject = value.object;
966
+ }
967
+ if (value.system_fingerprint != null) {
968
+ systemFingerprint = value.system_fingerprint;
969
+ }
656
970
  const choice = value.choices[0];
971
+ if ((choice == null ? void 0 : choice.index) != null) {
972
+ choiceIndex = choice.index;
973
+ }
657
974
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
658
975
  finishReason = {
659
976
  unified: mapDeepSeekFinishReason(choice.finish_reason),
660
977
  raw: choice.finish_reason
661
978
  };
662
979
  }
980
+ if (((_a = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _a.content) != null) {
981
+ contentLogprobs.push(...choice.logprobs.content);
982
+ }
983
+ if (((_b = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _b.reasoning_content) != null) {
984
+ reasoningLogprobs.push(...choice.logprobs.reasoning_content);
985
+ }
663
986
  if ((choice == null ? void 0 : choice.delta) == null) {
664
987
  return;
665
988
  }
666
989
  const delta = choice.delta;
990
+ if (delta.role != null) {
991
+ messageRole = delta.role;
992
+ }
667
993
  const reasoningContent = delta.reasoning_content;
668
994
  if (reasoningContent) {
669
995
  if (!isActiveReasoning) {
@@ -706,6 +1032,9 @@ var DeepSeekChatLanguageModel = class {
706
1032
  isActiveReasoning = false;
707
1033
  }
708
1034
  for (const toolCallDelta of delta.tool_calls) {
1035
+ if (toolCallDelta.type != null) {
1036
+ toolCallTypes.set(toolCallDelta.index, toolCallDelta.type);
1037
+ }
709
1038
  const index = toolCallDelta.index;
710
1039
  if (toolCalls[index] == null) {
711
1040
  if (toolCallDelta.id == null) {
@@ -714,7 +1043,7 @@ var DeepSeekChatLanguageModel = class {
714
1043
  message: `Expected 'id' to be a string.`
715
1044
  });
716
1045
  }
717
- if (((_a = toolCallDelta.function) == null ? void 0 : _a.name) == null) {
1046
+ if (((_c = toolCallDelta.function) == null ? void 0 : _c.name) == null) {
718
1047
  throw new InvalidResponseDataError({
719
1048
  data: toolCallDelta,
720
1049
  message: `Expected 'function.name' to be a string.`
@@ -730,12 +1059,12 @@ var DeepSeekChatLanguageModel = class {
730
1059
  type: "function",
731
1060
  function: {
732
1061
  name: toolCallDelta.function.name,
733
- arguments: (_b = toolCallDelta.function.arguments) != null ? _b : ""
1062
+ arguments: (_d = toolCallDelta.function.arguments) != null ? _d : ""
734
1063
  },
735
1064
  hasFinished: false
736
1065
  };
737
1066
  const toolCall2 = toolCalls[index];
738
- if (((_c = toolCall2.function) == null ? void 0 : _c.name) != null && ((_d = toolCall2.function) == null ? void 0 : _d.arguments) != null) {
1067
+ if (((_e = toolCall2.function) == null ? void 0 : _e.name) != null && ((_f = toolCall2.function) == null ? void 0 : _f.arguments) != null) {
739
1068
  if (toolCall2.function.arguments.length > 0) {
740
1069
  controller.enqueue({
741
1070
  type: "tool-input-delta",
@@ -750,13 +1079,13 @@ var DeepSeekChatLanguageModel = class {
750
1079
  if (toolCall.hasFinished) {
751
1080
  continue;
752
1081
  }
753
- if (((_e = toolCallDelta.function) == null ? void 0 : _e.arguments) != null) {
754
- toolCall.function.arguments += (_g = (_f = toolCallDelta.function) == null ? void 0 : _f.arguments) != null ? _g : "";
1082
+ if (((_g = toolCallDelta.function) == null ? void 0 : _g.arguments) != null) {
1083
+ toolCall.function.arguments += (_i = (_h = toolCallDelta.function) == null ? void 0 : _h.arguments) != null ? _i : "";
755
1084
  }
756
1085
  controller.enqueue({
757
1086
  type: "tool-input-delta",
758
1087
  id: toolCall.id,
759
- delta: (_h = toolCallDelta.function.arguments) != null ? _h : ""
1088
+ delta: (_j = toolCallDelta.function.arguments) != null ? _j : ""
760
1089
  });
761
1090
  }
762
1091
  }
@@ -790,7 +1119,24 @@ var DeepSeekChatLanguageModel = class {
790
1119
  providerMetadata: {
791
1120
  [providerOptionsName]: {
792
1121
  promptCacheHitTokens: (_b = usage == null ? void 0 : usage.prompt_cache_hit_tokens) != null ? _b : void 0,
793
- promptCacheMissTokens: (_c = usage == null ? void 0 : usage.prompt_cache_miss_tokens) != null ? _c : void 0
1122
+ promptCacheMissTokens: (_c = usage == null ? void 0 : usage.prompt_cache_miss_tokens) != null ? _c : void 0,
1123
+ ...responseObject != null && { responseObject },
1124
+ ...choiceIndex != null && { choiceIndex },
1125
+ ...messageRole != null && { messageRole },
1126
+ ...toolCallTypes.size > 0 && {
1127
+ toolCallTypes: [...toolCallTypes.entries()].sort(([left], [right]) => left - right).map(([, type]) => type)
1128
+ },
1129
+ ...(contentLogprobs.length > 0 || reasoningLogprobs.length > 0) && {
1130
+ logprobs: {
1131
+ ...contentLogprobs.length > 0 && {
1132
+ content: contentLogprobs
1133
+ },
1134
+ ...reasoningLogprobs.length > 0 && {
1135
+ reasoning_content: reasoningLogprobs
1136
+ }
1137
+ }
1138
+ },
1139
+ ...systemFingerprint != null && { systemFingerprint }
794
1140
  }
795
1141
  }
796
1142
  });
@@ -804,14 +1150,12 @@ var DeepSeekChatLanguageModel = class {
804
1150
  };
805
1151
 
806
1152
  // src/version.ts
807
- var VERSION = true ? "2.0.58" : "0.0.0-test";
1153
+ var VERSION = true ? "2.0.59" : "0.0.0-test";
808
1154
 
809
1155
  // src/deepseek-provider.ts
810
1156
  function createDeepSeek(options = {}) {
811
1157
  var _a;
812
- const baseURL = withoutTrailingSlash(
813
- (_a = options.baseURL) != null ? _a : "https://api.deepseek.com"
814
- );
1158
+ const baseURL = (_a = withoutTrailingSlash(options.baseURL)) != null ? _a : "https://api.deepseek.com";
815
1159
  const getHeaders = () => withUserAgentSuffix(
816
1160
  {
817
1161
  Authorization: `Bearer ${loadApiKey({
@@ -828,7 +1172,9 @@ function createDeepSeek(options = {}) {
828
1172
  provider: `deepseek.chat`,
829
1173
  url: ({ path }) => `${baseURL}${path}`,
830
1174
  headers: getHeaders,
831
- fetch: options.fetch
1175
+ fetch: options.fetch,
1176
+ supportsAssistantPrefixCompletion: baseURL.endsWith("/beta"),
1177
+ supportsStrictToolCalls: baseURL.endsWith("/beta")
832
1178
  });
833
1179
  };
834
1180
  const provider = (modelId) => createLanguageModel(modelId);