@ai-sdk/deepseek 3.0.0-beta.4 → 3.0.0-beta.55

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.
@@ -30,10 +30,10 @@ The DeepSeek provider is available via the `@ai-sdk/deepseek` module. You can in
30
30
 
31
31
  ## Provider Instance
32
32
 
33
- You can import the default provider instance `deepseek` from `@ai-sdk/deepseek`:
33
+ You can import the default provider instance `deepSeek` from `@ai-sdk/deepseek`:
34
34
 
35
35
  ```ts
36
- import { deepseek } from '@ai-sdk/deepseek';
36
+ import { deepSeek } from '@ai-sdk/deepseek';
37
37
  ```
38
38
 
39
39
  For custom configuration, you can import `createDeepSeek` and create a provider instance with your settings:
@@ -41,7 +41,7 @@ For custom configuration, you can import `createDeepSeek` and create a provider
41
41
  ```ts
42
42
  import { createDeepSeek } from '@ai-sdk/deepseek';
43
43
 
44
- const deepseek = createDeepSeek({
44
+ const deepSeek = createDeepSeek({
45
45
  apiKey: process.env.DEEPSEEK_API_KEY ?? '',
46
46
  });
47
47
  ```
@@ -71,11 +71,11 @@ You can use the following optional settings to customize the DeepSeek provider i
71
71
  You can create language models using a provider instance:
72
72
 
73
73
  ```ts
74
- import { deepseek } from '@ai-sdk/deepseek';
74
+ import { deepSeek } from '@ai-sdk/deepseek';
75
75
  import { generateText } from 'ai';
76
76
 
77
77
  const { text } = await generateText({
78
- model: deepseek('deepseek-chat'),
78
+ model: deepSeek('deepseek-chat'),
79
79
  prompt: 'Write a vegetarian lasagna recipe for 4 people.',
80
80
  });
81
81
  ```
@@ -83,9 +83,9 @@ const { text } = await generateText({
83
83
  You can also use the `.chat()` or `.languageModel()` factory methods:
84
84
 
85
85
  ```ts
86
- const model = deepseek.chat('deepseek-chat');
86
+ const model = deepSeek.chat('deepseek-chat');
87
87
  // or
88
- const model = deepseek.languageModel('deepseek-chat');
88
+ const model = deepSeek.languageModel('deepseek-chat');
89
89
  ```
90
90
 
91
91
  DeepSeek language models can be used in the `streamText` function
@@ -96,20 +96,32 @@ The following optional provider options are available for DeepSeek models:
96
96
  - `thinking` _object_
97
97
 
98
98
  Optional. Controls thinking mode (chain-of-thought reasoning). You can enable thinking mode either by using the `deepseek-reasoner` model or by setting this option.
99
-
100
- - `type`: `'enabled' | 'disabled'` - Enable or disable thinking mode.
101
-
102
- ```ts highlight="7-11"
103
- import { deepseek, type DeepSeekLanguageModelOptions } from '@ai-sdk/deepseek';
99
+ - `type`: `'adaptive' | 'enabled' | 'disabled'` - Enable, disable, or let the model decide (`adaptive`) when to think. See [DeepSeek's thinking mode docs](https://api-docs.deepseek.com/guides/thinking_mode).
100
+
101
+ - `reasoningEffort` _'low' | 'medium' | 'high' | 'xhigh' | 'max'_
102
+
103
+ Optional. Controls thinking strength for DeepSeek V4 reasoning models. Per
104
+ DeepSeek's docs, `low` and `medium` are mapped to `high`, and `xhigh` is
105
+ mapped to `max` server-side for compatibility with other providers. When
106
+ using the top-level `reasoning` setting, `minimal` is sent as `low`, and
107
+ `low`, `medium`, `high`, and `xhigh` pass through to DeepSeek's native
108
+ effort values.
109
+
110
+ ```ts highlight="7-12"
111
+ import {
112
+ deepSeek,
113
+ type DeepSeekLanguageModelChatOptions,
114
+ } from '@ai-sdk/deepseek';
104
115
  import { generateText } from 'ai';
105
116
 
106
117
  const { text, reasoning } = await generateText({
107
- model: deepseek('deepseek-chat'),
118
+ model: deepSeek('deepseek-chat'),
108
119
  prompt: 'How many "r"s are in the word "strawberry"?',
109
120
  providerOptions: {
110
121
  deepseek: {
111
122
  thinking: { type: 'enabled' },
112
- } satisfies DeepSeekLanguageModelOptions,
123
+ reasoningEffort: 'high',
124
+ } satisfies DeepSeekLanguageModelChatOptions,
113
125
  },
114
126
  });
115
127
  ```
@@ -119,15 +131,15 @@ const { text, reasoning } = await generateText({
119
131
  DeepSeek has reasoning support for the `deepseek-reasoner` model. The reasoning is exposed through streaming:
120
132
 
121
133
  ```ts
122
- import { deepseek } from '@ai-sdk/deepseek';
134
+ import { deepSeek } from '@ai-sdk/deepseek';
123
135
  import { streamText } from 'ai';
124
136
 
125
137
  const result = streamText({
126
- model: deepseek('deepseek-reasoner'),
138
+ model: deepSeek('deepseek-reasoner'),
127
139
  prompt: 'How many "r"s are in the word "strawberry"?',
128
140
  });
129
141
 
130
- for await (const part of result.fullStream) {
142
+ for await (const part of result.stream) {
131
143
  if (part.type === 'reasoning') {
132
144
  // This is the reasoning text
133
145
  console.log('Reasoning:', part.text);
@@ -146,11 +158,11 @@ on how to integrate reasoning into your chatbot.
146
158
  DeepSeek provides context caching on disk technology that can significantly reduce token costs for repeated content. You can access the cache hit/miss metrics through the `providerMetadata` property in the response:
147
159
 
148
160
  ```ts
149
- import { deepseek } from '@ai-sdk/deepseek';
161
+ import { deepSeek } from '@ai-sdk/deepseek';
150
162
  import { generateText } from 'ai';
151
163
 
152
164
  const result = await generateText({
153
- model: deepseek('deepseek-chat'),
165
+ model: deepSeek('deepseek-chat'),
154
166
  prompt: 'Your prompt here',
155
167
  });
156
168
 
package/internal.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/internal';
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@ai-sdk/deepseek",
3
- "version": "3.0.0-beta.4",
3
+ "version": "3.0.0-beta.55",
4
+ "type": "module",
4
5
  "license": "Apache-2.0",
5
6
  "sideEffects": false,
6
7
  "main": "./dist/index.js",
7
- "module": "./dist/index.mjs",
8
8
  "types": "./dist/index.d.ts",
9
9
  "files": [
10
10
  "dist/**/*",
@@ -15,7 +15,8 @@
15
15
  "!src/**/__snapshots__",
16
16
  "!src/**/__fixtures__",
17
17
  "CHANGELOG.md",
18
- "README.md"
18
+ "README.md",
19
+ "internal.d.ts"
19
20
  ],
20
21
  "directories": {
21
22
  "doc": "./docs"
@@ -24,35 +25,42 @@
24
25
  "./package.json": "./package.json",
25
26
  ".": {
26
27
  "types": "./dist/index.d.ts",
27
- "import": "./dist/index.mjs",
28
- "require": "./dist/index.js"
28
+ "import": "./dist/index.js",
29
+ "default": "./dist/index.js"
30
+ },
31
+ "./internal": {
32
+ "types": "./dist/internal/index.d.ts",
33
+ "import": "./dist/internal/index.js",
34
+ "default": "./dist/internal/index.js"
29
35
  }
30
36
  },
31
37
  "dependencies": {
32
- "@ai-sdk/provider": "4.0.0-beta.2",
33
- "@ai-sdk/provider-utils": "5.0.0-beta.3"
38
+ "@ai-sdk/provider": "4.0.0-beta.19",
39
+ "@ai-sdk/provider-utils": "5.0.0-beta.49"
34
40
  },
35
41
  "devDependencies": {
36
- "@types/node": "20.17.24",
37
- "tsup": "^8",
42
+ "@types/node": "22.19.19",
43
+ "tsup": "^8.5.1",
38
44
  "typescript": "5.8.3",
39
45
  "zod": "3.25.76",
40
- "@ai-sdk/test-server": "2.0.0-beta.0",
46
+ "@ai-sdk/test-server": "2.0.0-beta.7",
41
47
  "@vercel/ai-tsconfig": "0.0.0"
42
48
  },
43
49
  "peerDependencies": {
44
50
  "zod": "^3.25.76 || ^4.1.8"
45
51
  },
46
52
  "engines": {
47
- "node": ">=18"
53
+ "node": ">=22"
48
54
  },
49
55
  "publishConfig": {
50
- "access": "public"
56
+ "access": "public",
57
+ "provenance": true
51
58
  },
52
59
  "homepage": "https://ai-sdk.dev/docs",
53
60
  "repository": {
54
61
  "type": "git",
55
- "url": "git+https://github.com/vercel/ai.git"
62
+ "url": "https://github.com/vercel/ai",
63
+ "directory": "packages/deepseek"
56
64
  },
57
65
  "bugs": {
58
66
  "url": "https://github.com/vercel/ai/issues"
@@ -64,9 +72,7 @@
64
72
  "build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
65
73
  "build:watch": "pnpm clean && tsup --watch",
66
74
  "clean": "del-cli dist docs *.tsbuildinfo",
67
- "lint": "eslint \"./**/*.ts*\"",
68
75
  "type-check": "tsc --build",
69
- "prettier-check": "prettier --check \"./**/*.ts*\"",
70
76
  "test": "pnpm test:node && pnpm test:edge",
71
77
  "test:update": "pnpm test:node -u",
72
78
  "test:watch": "vitest --config vitest.node.config.js",
@@ -1,22 +1,25 @@
1
- import {
2
- LanguageModelV3CallOptions,
3
- LanguageModelV3Prompt,
4
- SharedV3Warning,
1
+ import type {
2
+ LanguageModelV4CallOptions,
3
+ LanguageModelV4Prompt,
4
+ SharedV4Warning,
5
5
  } from '@ai-sdk/provider';
6
- import { DeepSeekChatPrompt } from './deepseek-chat-api-types';
6
+ import type { DeepSeekChatPrompt } from './deepseek-chat-api-types';
7
7
 
8
8
  export function convertToDeepSeekChatMessages({
9
9
  prompt,
10
10
  responseFormat,
11
+ modelId,
11
12
  }: {
12
- prompt: LanguageModelV3Prompt;
13
- responseFormat: LanguageModelV3CallOptions['responseFormat'];
13
+ prompt: LanguageModelV4Prompt;
14
+ responseFormat: LanguageModelV4CallOptions['responseFormat'];
15
+ modelId: string;
14
16
  }): {
15
17
  messages: DeepSeekChatPrompt;
16
- warnings: Array<SharedV3Warning>;
18
+ warnings: Array<SharedV4Warning>;
17
19
  } {
20
+ const isDeepSeekV4 = modelId.includes('deepseek-v4');
18
21
  const messages: DeepSeekChatPrompt = [];
19
- const warnings: Array<SharedV3Warning> = [];
22
+ const warnings: Array<SharedV4Warning> = [];
20
23
 
21
24
  // Inject system message if response format is JSON
22
25
  if (responseFormat?.type === 'json') {
@@ -96,7 +99,8 @@ export function convertToDeepSeekChatMessages({
96
99
  break;
97
100
  }
98
101
  case 'reasoning': {
99
- if (index <= lastUserMessageIndex) {
102
+ // R1 must not receive prior reasoning; V4 requires it.
103
+ if (index <= lastUserMessageIndex && !isDeepSeekV4) {
100
104
  break;
101
105
  }
102
106
 
@@ -121,10 +125,12 @@ export function convertToDeepSeekChatMessages({
121
125
  }
122
126
  }
123
127
 
128
+ // V4 demands the field on every assistant turn — back-fill an empty
129
+ // string when the source message had no reasoning part at all.
124
130
  messages.push({
125
131
  role: 'assistant',
126
132
  content: text,
127
- reasoning_content: reasoning,
133
+ reasoning_content: reasoning ?? (isDeepSeekV4 ? '' : undefined),
128
134
  tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
129
135
  });
130
136
 
@@ -145,7 +151,7 @@ export function convertToDeepSeekChatMessages({
145
151
  contentValue = output.value;
146
152
  break;
147
153
  case 'execution-denied':
148
- contentValue = output.reason ?? 'Tool execution denied.';
154
+ contentValue = output.reason ?? 'Tool call execution denied.';
149
155
  break;
150
156
  case 'content':
151
157
  case 'json':
@@ -1,4 +1,4 @@
1
- import { LanguageModelV3Usage } from '@ai-sdk/provider';
1
+ import type { LanguageModelV4Usage } from '@ai-sdk/provider';
2
2
 
3
3
  export function convertDeepSeekUsage(
4
4
  usage:
@@ -15,7 +15,7 @@ export function convertDeepSeekUsage(
15
15
  }
16
16
  | undefined
17
17
  | null,
18
- ): LanguageModelV3Usage {
18
+ ): LanguageModelV4Usage {
19
19
  if (usage == null) {
20
20
  return {
21
21
  inputTokens: {
@@ -0,0 +1,34 @@
1
+ import { z } from 'zod/v4';
2
+
3
+ // https://api-docs.deepseek.com/quick_start/pricing
4
+ export type DeepSeekChatModelId =
5
+ | 'deepseek-chat'
6
+ | 'deepseek-reasoner'
7
+ | (string & {});
8
+
9
+ export const deepseekLanguageModelChatOptions = z.object({
10
+ /**
11
+ * Type of thinking to use. Defaults to `enabled`.
12
+ *
13
+ * See https://api-docs.deepseek.com/guides/thinking_mode for the
14
+ * `adaptive` option, which lets the model decide when to think.
15
+ */
16
+ thinking: z
17
+ .object({
18
+ type: z.enum(['adaptive', 'enabled', 'disabled']).optional(),
19
+ })
20
+ .optional(),
21
+
22
+ /**
23
+ * Controls the thinking strength for DeepSeek V4 reasoning models.
24
+ *
25
+ * DeepSeek's API accepts `low`, `medium`, `high`, `xhigh`, and `max`.
26
+ * Per their docs, `low` and `medium` are mapped to `high`, and `xhigh`
27
+ * is mapped to `max` server-side for compatibility with other providers.
28
+ */
29
+ reasoningEffort: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
30
+ });
31
+
32
+ export type DeepSeekLanguageModelChatOptions = z.infer<
33
+ typeof deepseekLanguageModelChatOptions
34
+ >;