@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.
- package/CHANGELOG.md +417 -4
- package/README.md +2 -0
- package/dist/index.d.ts +17 -9
- package/dist/index.js +171 -227
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +57 -0
- package/dist/{index.mjs → internal/index.js} +84 -183
- package/dist/internal/index.js.map +1 -0
- package/docs/30-deepseek.mdx +31 -19
- package/internal.d.ts +1 -0
- package/package.json +21 -15
- package/src/chat/convert-to-deepseek-chat-messages.ts +18 -12
- package/src/chat/convert-to-deepseek-usage.ts +2 -2
- package/src/chat/deepseek-chat-language-model-options.ts +34 -0
- package/src/chat/deepseek-chat-language-model.ts +95 -172
- package/src/chat/deepseek-prepare-tools.ts +9 -6
- package/src/chat/map-deepseek-finish-reason.ts +2 -2
- package/src/deepseek-provider.ts +10 -10
- package/src/index.ts +12 -5
- package/src/internal/index.ts +2 -0
- package/dist/index.d.mts +0 -68
- package/dist/index.mjs.map +0 -1
- package/src/chat/deepseek-chat-options.ts +0 -22
package/docs/30-deepseek.mdx
CHANGED
|
@@ -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 `
|
|
33
|
+
You can import the default provider instance `deepSeek` from `@ai-sdk/deepseek`:
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
|
-
import {
|
|
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
|
|
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 {
|
|
74
|
+
import { deepSeek } from '@ai-sdk/deepseek';
|
|
75
75
|
import { generateText } from 'ai';
|
|
76
76
|
|
|
77
77
|
const { text } = await generateText({
|
|
78
|
-
model:
|
|
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 =
|
|
86
|
+
const model = deepSeek.chat('deepseek-chat');
|
|
87
87
|
// or
|
|
88
|
-
const model =
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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:
|
|
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
|
-
|
|
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 {
|
|
134
|
+
import { deepSeek } from '@ai-sdk/deepseek';
|
|
123
135
|
import { streamText } from 'ai';
|
|
124
136
|
|
|
125
137
|
const result = streamText({
|
|
126
|
-
model:
|
|
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.
|
|
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 {
|
|
161
|
+
import { deepSeek } from '@ai-sdk/deepseek';
|
|
150
162
|
import { generateText } from 'ai';
|
|
151
163
|
|
|
152
164
|
const result = await generateText({
|
|
153
|
-
model:
|
|
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.
|
|
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.
|
|
28
|
-
"
|
|
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.
|
|
33
|
-
"@ai-sdk/provider-utils": "5.0.0-beta.
|
|
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": "
|
|
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.
|
|
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": ">=
|
|
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": "
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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:
|
|
13
|
-
responseFormat:
|
|
13
|
+
prompt: LanguageModelV4Prompt;
|
|
14
|
+
responseFormat: LanguageModelV4CallOptions['responseFormat'];
|
|
15
|
+
modelId: string;
|
|
14
16
|
}): {
|
|
15
17
|
messages: DeepSeekChatPrompt;
|
|
16
|
-
warnings: Array<
|
|
18
|
+
warnings: Array<SharedV4Warning>;
|
|
17
19
|
} {
|
|
20
|
+
const isDeepSeekV4 = modelId.includes('deepseek-v4');
|
|
18
21
|
const messages: DeepSeekChatPrompt = [];
|
|
19
|
-
const warnings: Array<
|
|
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
|
-
|
|
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 {
|
|
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
|
-
):
|
|
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
|
+
>;
|