@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.
- package/CHANGELOG.md +41 -0
- package/README.md +1 -1
- package/dist/index.d.ts +57 -19
- package/dist/index.js +626 -124
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +54 -4
- package/dist/internal/index.js +520 -109
- package/dist/internal/index.js.map +1 -1
- package/docs/30-deepseek.mdx +306 -23
- package/package.json +6 -6
- package/src/chat/convert-to-deepseek-chat-messages.ts +166 -19
- package/src/chat/convert-to-deepseek-usage.ts +1 -1
- package/src/chat/deepseek-chat-api-types.ts +50 -5
- package/src/chat/deepseek-chat-language-model-options.ts +102 -11
- package/src/chat/deepseek-chat-language-model.ts +293 -20
- package/src/chat/deepseek-file-part-options.ts +24 -0
- package/src/chat/deepseek-prepare-tools.ts +29 -3
- package/src/deepseek-provider.ts +2 -0
- package/src/files/deepseek-files-api.ts +9 -5
- package/src/files/deepseek-files.ts +129 -4
- package/src/index.ts +3 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
InvalidArgumentError,
|
|
3
|
+
type FilesV4,
|
|
4
|
+
type FilesV4UploadFileCallOptions,
|
|
5
|
+
type FilesV4UploadFileResult,
|
|
5
6
|
} from '@ai-sdk/provider';
|
|
6
7
|
import {
|
|
7
8
|
combineHeaders,
|
|
8
9
|
convertInlineFileDataToUint8Array,
|
|
9
10
|
createJsonErrorResponseHandler,
|
|
10
11
|
createJsonResponseHandler,
|
|
12
|
+
detectMediaType,
|
|
11
13
|
parseProviderOptions,
|
|
12
14
|
postFormDataToApi,
|
|
13
15
|
type FetchFunction,
|
|
@@ -33,6 +35,34 @@ const deepSeekFailedResponseHandler = createJsonErrorResponseHandler({
|
|
|
33
35
|
error.error.message,
|
|
34
36
|
});
|
|
35
37
|
|
|
38
|
+
const MAX_FILE_SIZE_BYTES = 64 * 1024 * 1024;
|
|
39
|
+
const MAX_FILENAME_LENGTH = 512;
|
|
40
|
+
|
|
41
|
+
const supportedMediaTypes = new Set([
|
|
42
|
+
'image/gif',
|
|
43
|
+
'image/jpeg',
|
|
44
|
+
'image/jpg',
|
|
45
|
+
'image/png',
|
|
46
|
+
'image/webp',
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
const genericMediaTypes = new Set([
|
|
50
|
+
'',
|
|
51
|
+
'application/binary',
|
|
52
|
+
'application/octet-stream',
|
|
53
|
+
'binary/octet-stream',
|
|
54
|
+
'image',
|
|
55
|
+
'image/*',
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
const supportedFilenameExtensions = new Set([
|
|
59
|
+
'gif',
|
|
60
|
+
'jpeg',
|
|
61
|
+
'jpg',
|
|
62
|
+
'png',
|
|
63
|
+
'webp',
|
|
64
|
+
]);
|
|
65
|
+
|
|
36
66
|
export class DeepSeekFiles implements FilesV4 {
|
|
37
67
|
readonly specificationVersion = 'v4';
|
|
38
68
|
|
|
@@ -55,6 +85,8 @@ export class DeepSeekFiles implements FilesV4 {
|
|
|
55
85
|
})) as DeepSeekFilesOptions | undefined;
|
|
56
86
|
|
|
57
87
|
const fileBytes = convertInlineFileDataToUint8Array(data);
|
|
88
|
+
validateFileUpload({ fileBytes, mediaType, filename });
|
|
89
|
+
|
|
58
90
|
const blob = new Blob([fileBytes], { type: mediaType });
|
|
59
91
|
|
|
60
92
|
const formData = new FormData();
|
|
@@ -93,6 +125,7 @@ export class DeepSeekFiles implements FilesV4 {
|
|
|
93
125
|
...(mediaType != null ? { mediaType } : {}),
|
|
94
126
|
providerMetadata: {
|
|
95
127
|
deepseek: {
|
|
128
|
+
...(response.object != null ? { object: response.object } : {}),
|
|
96
129
|
...(response.filename != null ? { filename: response.filename } : {}),
|
|
97
130
|
...(response.purpose != null ? { purpose: response.purpose } : {}),
|
|
98
131
|
...(response.bytes != null ? { bytes: response.bytes } : {}),
|
|
@@ -107,3 +140,95 @@ export class DeepSeekFiles implements FilesV4 {
|
|
|
107
140
|
};
|
|
108
141
|
}
|
|
109
142
|
}
|
|
143
|
+
|
|
144
|
+
function validateFileUpload({
|
|
145
|
+
fileBytes,
|
|
146
|
+
mediaType,
|
|
147
|
+
filename,
|
|
148
|
+
}: {
|
|
149
|
+
fileBytes: Uint8Array;
|
|
150
|
+
mediaType: string;
|
|
151
|
+
filename: string | undefined;
|
|
152
|
+
}) {
|
|
153
|
+
if (fileBytes.length > MAX_FILE_SIZE_BYTES) {
|
|
154
|
+
throw new InvalidArgumentError({
|
|
155
|
+
argument: 'data',
|
|
156
|
+
message:
|
|
157
|
+
`DeepSeek file uploads must not exceed 64 MiB ` +
|
|
158
|
+
`(${MAX_FILE_SIZE_BYTES.toLocaleString('en-US')} bytes). ` +
|
|
159
|
+
`Received ${fileBytes.length.toLocaleString('en-US')} bytes.`,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (filename != null) {
|
|
164
|
+
const filenameLength = Array.from(filename).length;
|
|
165
|
+
|
|
166
|
+
if (filenameLength > MAX_FILENAME_LENGTH) {
|
|
167
|
+
throw new InvalidArgumentError({
|
|
168
|
+
argument: 'filename',
|
|
169
|
+
message:
|
|
170
|
+
`DeepSeek filenames must not exceed ${MAX_FILENAME_LENGTH} characters. ` +
|
|
171
|
+
`Received ${filenameLength} characters.`,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const normalizedMediaType = normalizeMediaType(mediaType);
|
|
177
|
+
const detectedMediaType = detectMediaType({ data: fileBytes });
|
|
178
|
+
|
|
179
|
+
if (
|
|
180
|
+
detectedMediaType != null &&
|
|
181
|
+
!supportedMediaTypes.has(detectedMediaType)
|
|
182
|
+
) {
|
|
183
|
+
throw new InvalidArgumentError({
|
|
184
|
+
argument: 'data',
|
|
185
|
+
message:
|
|
186
|
+
`DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. ` +
|
|
187
|
+
`Detected unsupported file content type "${detectedMediaType}".`,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (supportedMediaTypes.has(normalizedMediaType)) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (!genericMediaTypes.has(normalizedMediaType)) {
|
|
196
|
+
throw new InvalidArgumentError({
|
|
197
|
+
argument: 'mediaType',
|
|
198
|
+
message:
|
|
199
|
+
`DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. ` +
|
|
200
|
+
`Received unsupported media type "${mediaType}".`,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (detectedMediaType != null || hasSupportedFilenameExtension(filename)) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
throw new InvalidArgumentError({
|
|
209
|
+
argument: 'mediaType',
|
|
210
|
+
message:
|
|
211
|
+
`DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. ` +
|
|
212
|
+
`Provide a supported media type or a filename ending in ` +
|
|
213
|
+
`.jpg, .jpeg, .png, .gif, or .webp. Received "${mediaType}".`,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function normalizeMediaType(mediaType: string): string {
|
|
218
|
+
return mediaType.split(';', 1)[0].trim().toLowerCase();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function hasSupportedFilenameExtension(filename: string | undefined): boolean {
|
|
222
|
+
if (filename == null) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const extensionSeparatorIndex = filename.lastIndexOf('.');
|
|
227
|
+
|
|
228
|
+
return (
|
|
229
|
+
extensionSeparatorIndex !== -1 &&
|
|
230
|
+
supportedFilenameExtensions.has(
|
|
231
|
+
filename.slice(extensionSeparatorIndex + 1).toLowerCase(),
|
|
232
|
+
)
|
|
233
|
+
);
|
|
234
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -10,11 +10,14 @@ export type {
|
|
|
10
10
|
} from './deepseek-provider';
|
|
11
11
|
export { VERSION } from './version';
|
|
12
12
|
export type {
|
|
13
|
+
DeepSeekAssistantMessageProviderOptions,
|
|
13
14
|
DeepSeekLanguageModelChatOptions,
|
|
15
|
+
DeepSeekMessageProviderOptions,
|
|
14
16
|
/** @deprecated Use `DeepSeekLanguageModelChatOptions` instead. */
|
|
15
17
|
DeepSeekLanguageModelChatOptions as DeepSeekLanguageModelOptions,
|
|
16
18
|
/** @deprecated Use `DeepSeekLanguageModelChatOptions` instead. */
|
|
17
19
|
DeepSeekLanguageModelChatOptions as DeepSeekChatOptions,
|
|
18
20
|
} from './chat/deepseek-chat-language-model-options';
|
|
19
21
|
export type { DeepSeekErrorData } from './chat/deepseek-chat-api-types';
|
|
22
|
+
export type { DeepSeekFilePartProviderOptions } from './chat/deepseek-file-part-options';
|
|
20
23
|
export type { DeepSeekFilesOptions } from './files/deepseek-files-options';
|