kimi-vercel-ai-sdk-provider 0.2.0
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/LICENSE +198 -0
- package/README.md +871 -0
- package/dist/index.d.mts +1317 -0
- package/dist/index.d.ts +1317 -0
- package/dist/index.js +2764 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2734 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +70 -0
- package/src/__tests__/caching.test.ts +97 -0
- package/src/__tests__/chat.test.ts +386 -0
- package/src/__tests__/code-integration.test.ts +562 -0
- package/src/__tests__/code-provider.test.ts +289 -0
- package/src/__tests__/code.test.ts +427 -0
- package/src/__tests__/core.test.ts +172 -0
- package/src/__tests__/files.test.ts +185 -0
- package/src/__tests__/integration.test.ts +457 -0
- package/src/__tests__/provider.test.ts +188 -0
- package/src/__tests__/tools.test.ts +519 -0
- package/src/chat/index.ts +42 -0
- package/src/chat/kimi-chat-language-model.ts +829 -0
- package/src/chat/kimi-chat-messages.ts +297 -0
- package/src/chat/kimi-chat-response.ts +84 -0
- package/src/chat/kimi-chat-settings.ts +216 -0
- package/src/code/index.ts +66 -0
- package/src/code/kimi-code-language-model.ts +669 -0
- package/src/code/kimi-code-messages.ts +303 -0
- package/src/code/kimi-code-provider.ts +239 -0
- package/src/code/kimi-code-settings.ts +193 -0
- package/src/code/kimi-code-types.ts +354 -0
- package/src/core/errors.ts +140 -0
- package/src/core/index.ts +36 -0
- package/src/core/types.ts +148 -0
- package/src/core/utils.ts +210 -0
- package/src/files/attachment-processor.ts +276 -0
- package/src/files/file-utils.ts +257 -0
- package/src/files/index.ts +24 -0
- package/src/files/kimi-file-client.ts +292 -0
- package/src/index.ts +122 -0
- package/src/kimi-provider.ts +263 -0
- package/src/tools/builtin-tools.ts +273 -0
- package/src/tools/index.ts +33 -0
- package/src/tools/prepare-tools.ts +306 -0
- package/src/version.ts +4 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message conversion for Kimi Code API.
|
|
3
|
+
* Converts AI SDK messages to Anthropic-compatible format used by Kimi Code.
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { LanguageModelV3FilePart, LanguageModelV3Prompt } from '@ai-sdk/provider';
|
|
8
|
+
import { UnsupportedFunctionalityError } from '@ai-sdk/provider';
|
|
9
|
+
import { convertToBase64 } from '@ai-sdk/provider-utils';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Types
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Kimi Code message content part types.
|
|
17
|
+
*/
|
|
18
|
+
export type KimiCodeContentPart =
|
|
19
|
+
| { type: 'text'; text: string }
|
|
20
|
+
| { type: 'image'; source: { type: 'base64'; media_type: string; data: string } }
|
|
21
|
+
| { type: 'image'; source: { type: 'url'; url: string } }
|
|
22
|
+
| { type: 'tool_use'; id: string; name: string; input: Record<string, unknown> }
|
|
23
|
+
| { type: 'tool_result'; tool_use_id: string; content: string | KimiCodeContentPart[]; is_error?: boolean };
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Kimi Code message format (Anthropic-compatible).
|
|
27
|
+
*/
|
|
28
|
+
export interface KimiCodeMessage {
|
|
29
|
+
role: 'user' | 'assistant';
|
|
30
|
+
content: string | KimiCodeContentPart[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Kimi Code prompt structure.
|
|
35
|
+
*/
|
|
36
|
+
export interface KimiCodePrompt {
|
|
37
|
+
system?: string;
|
|
38
|
+
messages: KimiCodeMessage[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// Conversion Functions
|
|
43
|
+
// ============================================================================
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Convert AI SDK prompt to Kimi Code message format.
|
|
47
|
+
*
|
|
48
|
+
* @param prompt - AI SDK prompt
|
|
49
|
+
* @returns Kimi Code formatted prompt with system and messages
|
|
50
|
+
*/
|
|
51
|
+
export async function convertToKimiCodePrompt(prompt: LanguageModelV3Prompt): Promise<KimiCodePrompt> {
|
|
52
|
+
let systemMessage: string | undefined;
|
|
53
|
+
const messages: KimiCodeMessage[] = [];
|
|
54
|
+
|
|
55
|
+
for (const message of prompt) {
|
|
56
|
+
switch (message.role) {
|
|
57
|
+
case 'system': {
|
|
58
|
+
// System messages have content as string in V3
|
|
59
|
+
const systemText = typeof message.content === 'string' ? message.content : '';
|
|
60
|
+
systemMessage = systemMessage ? `${systemMessage}\n\n${systemText}` : systemText;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
case 'user': {
|
|
65
|
+
const content: KimiCodeContentPart[] = [];
|
|
66
|
+
|
|
67
|
+
for (const part of message.content) {
|
|
68
|
+
switch (part.type) {
|
|
69
|
+
case 'text':
|
|
70
|
+
content.push({ type: 'text', text: part.text });
|
|
71
|
+
break;
|
|
72
|
+
|
|
73
|
+
case 'file':
|
|
74
|
+
// Check if it's an image file
|
|
75
|
+
if (part.mediaType?.startsWith('image/')) {
|
|
76
|
+
content.push(await convertFilePart(part));
|
|
77
|
+
} else {
|
|
78
|
+
throw new UnsupportedFunctionalityError({
|
|
79
|
+
functionality: `file type: ${part.mediaType}`
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
|
|
84
|
+
default:
|
|
85
|
+
throw new UnsupportedFunctionalityError({
|
|
86
|
+
functionality: `user content part type: ${(part as { type: string }).type}`
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
messages.push({
|
|
92
|
+
role: 'user',
|
|
93
|
+
content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
|
|
94
|
+
});
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
case 'assistant': {
|
|
99
|
+
const content: KimiCodeContentPart[] = [];
|
|
100
|
+
|
|
101
|
+
for (const part of message.content) {
|
|
102
|
+
switch (part.type) {
|
|
103
|
+
case 'text':
|
|
104
|
+
content.push({ type: 'text', text: part.text });
|
|
105
|
+
break;
|
|
106
|
+
|
|
107
|
+
case 'tool-call':
|
|
108
|
+
content.push({
|
|
109
|
+
type: 'tool_use',
|
|
110
|
+
id: part.toolCallId,
|
|
111
|
+
name: part.toolName,
|
|
112
|
+
input: typeof part.input === 'string' ? JSON.parse(part.input) : (part.input as Record<string, unknown>)
|
|
113
|
+
});
|
|
114
|
+
break;
|
|
115
|
+
|
|
116
|
+
case 'reasoning':
|
|
117
|
+
// Include reasoning as text (Kimi Code handles thinking blocks)
|
|
118
|
+
if (part.text) {
|
|
119
|
+
content.push({ type: 'text', text: `<thinking>${part.text}</thinking>` });
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
|
|
123
|
+
default:
|
|
124
|
+
throw new UnsupportedFunctionalityError({
|
|
125
|
+
functionality: `assistant content part type: ${(part as { type: string }).type}`
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (content.length > 0) {
|
|
131
|
+
messages.push({
|
|
132
|
+
role: 'assistant',
|
|
133
|
+
content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
case 'tool': {
|
|
140
|
+
// Tool results need to be part of a user message in Anthropic format
|
|
141
|
+
const toolResults: KimiCodeContentPart[] = [];
|
|
142
|
+
|
|
143
|
+
for (const part of message.content) {
|
|
144
|
+
if (part.type === 'tool-result') {
|
|
145
|
+
toolResults.push(convertToolResultPart(part));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// If the last message is from the assistant, add tool results as user message
|
|
150
|
+
if (messages.length > 0 && messages[messages.length - 1].role === 'assistant') {
|
|
151
|
+
messages.push({
|
|
152
|
+
role: 'user',
|
|
153
|
+
content: toolResults
|
|
154
|
+
});
|
|
155
|
+
} else {
|
|
156
|
+
// Merge with existing user message or create new one
|
|
157
|
+
const lastMessage = messages[messages.length - 1];
|
|
158
|
+
if (lastMessage?.role === 'user' && Array.isArray(lastMessage.content)) {
|
|
159
|
+
lastMessage.content.push(...toolResults);
|
|
160
|
+
} else {
|
|
161
|
+
messages.push({
|
|
162
|
+
role: 'user',
|
|
163
|
+
content: toolResults
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
default:
|
|
171
|
+
throw new UnsupportedFunctionalityError({
|
|
172
|
+
functionality: `message role: ${(message as { role: string }).role}`
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
system: systemMessage,
|
|
179
|
+
messages
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Convert a file part to Kimi Code format.
|
|
185
|
+
*/
|
|
186
|
+
async function convertFilePart(part: LanguageModelV3FilePart): Promise<KimiCodeContentPart> {
|
|
187
|
+
const mediaType = part.mediaType ?? 'image/png';
|
|
188
|
+
|
|
189
|
+
// Handle URL data
|
|
190
|
+
if (part.data instanceof URL) {
|
|
191
|
+
return {
|
|
192
|
+
type: 'image',
|
|
193
|
+
source: {
|
|
194
|
+
type: 'url',
|
|
195
|
+
url: part.data.toString()
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Handle string data
|
|
201
|
+
if (typeof part.data === 'string') {
|
|
202
|
+
// Check if it's a URL string
|
|
203
|
+
if (part.data.startsWith('http://') || part.data.startsWith('https://')) {
|
|
204
|
+
return {
|
|
205
|
+
type: 'image',
|
|
206
|
+
source: {
|
|
207
|
+
type: 'url',
|
|
208
|
+
url: part.data
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Check if it's a data URL
|
|
214
|
+
if (part.data.startsWith('data:')) {
|
|
215
|
+
const [header, data] = part.data.split(',');
|
|
216
|
+
const extractedMimeType = header.match(/data:([^;]+)/)?.[1] ?? mediaType;
|
|
217
|
+
return {
|
|
218
|
+
type: 'image',
|
|
219
|
+
source: {
|
|
220
|
+
type: 'base64',
|
|
221
|
+
media_type: extractedMimeType,
|
|
222
|
+
data
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Assume it's base64 encoded
|
|
228
|
+
return {
|
|
229
|
+
type: 'image',
|
|
230
|
+
source: {
|
|
231
|
+
type: 'base64',
|
|
232
|
+
media_type: mediaType,
|
|
233
|
+
data: part.data
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Handle Uint8Array - convert to base64
|
|
239
|
+
const base64 = convertToBase64(part.data);
|
|
240
|
+
return {
|
|
241
|
+
type: 'image',
|
|
242
|
+
source: {
|
|
243
|
+
type: 'base64',
|
|
244
|
+
media_type: mediaType,
|
|
245
|
+
data: base64
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Tool result output type from LanguageModelV3.
|
|
252
|
+
*/
|
|
253
|
+
interface ToolResultOutput {
|
|
254
|
+
type: 'text' | 'error-text' | 'json' | 'error-json' | 'content' | 'execution-denied';
|
|
255
|
+
value?: unknown;
|
|
256
|
+
reason?: string;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Convert a tool result part to Kimi Code format.
|
|
261
|
+
*/
|
|
262
|
+
function convertToolResultPart(part: {
|
|
263
|
+
type: 'tool-result';
|
|
264
|
+
toolCallId: string;
|
|
265
|
+
toolName: string;
|
|
266
|
+
output: ToolResultOutput;
|
|
267
|
+
}): KimiCodeContentPart {
|
|
268
|
+
// Handle different output types based on the discriminated union
|
|
269
|
+
const output = part.output;
|
|
270
|
+
let content: string;
|
|
271
|
+
let isError = false;
|
|
272
|
+
|
|
273
|
+
switch (output.type) {
|
|
274
|
+
case 'text':
|
|
275
|
+
content = String(output.value ?? '');
|
|
276
|
+
break;
|
|
277
|
+
case 'error-text':
|
|
278
|
+
content = String(output.value ?? '');
|
|
279
|
+
isError = true;
|
|
280
|
+
break;
|
|
281
|
+
case 'execution-denied':
|
|
282
|
+
content = output.reason ?? 'Tool execution denied.';
|
|
283
|
+
isError = true;
|
|
284
|
+
break;
|
|
285
|
+
case 'json':
|
|
286
|
+
case 'content':
|
|
287
|
+
content = JSON.stringify(output.value);
|
|
288
|
+
break;
|
|
289
|
+
case 'error-json':
|
|
290
|
+
content = JSON.stringify(output.value);
|
|
291
|
+
isError = true;
|
|
292
|
+
break;
|
|
293
|
+
default:
|
|
294
|
+
content = JSON.stringify(output);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return {
|
|
298
|
+
type: 'tool_result',
|
|
299
|
+
tool_use_id: part.toolCallId,
|
|
300
|
+
content,
|
|
301
|
+
is_error: isError || undefined
|
|
302
|
+
};
|
|
303
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kimi Code provider factory.
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { KimiCodeSettings } from './kimi-code-settings';
|
|
7
|
+
import { type LanguageModelV3, NoSuchModelError, type ProviderV3 } from '@ai-sdk/provider';
|
|
8
|
+
import {
|
|
9
|
+
type FetchFunction,
|
|
10
|
+
loadOptionalSetting,
|
|
11
|
+
withUserAgentSuffix,
|
|
12
|
+
withoutTrailingSlash
|
|
13
|
+
} from '@ai-sdk/provider-utils';
|
|
14
|
+
import { VERSION } from '../version';
|
|
15
|
+
import { KimiCodeLanguageModel } from './kimi-code-language-model';
|
|
16
|
+
import { KIMI_CODE_BASE_URL, KIMI_CODE_DEFAULT_MODEL, type KimiCodeModelId } from './kimi-code-types';
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Provider Settings
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Settings for creating a Kimi Code provider instance.
|
|
24
|
+
*/
|
|
25
|
+
export interface KimiCodeProviderSettings {
|
|
26
|
+
/**
|
|
27
|
+
* Kimi Code API key. Defaults to the KIMI_CODE_API_KEY or KIMI_API_KEY environment variable.
|
|
28
|
+
*/
|
|
29
|
+
apiKey?: string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Base URL override. Defaults to https://api.kimi.com/coding/v1
|
|
33
|
+
*/
|
|
34
|
+
baseURL?: string;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Default headers for all requests.
|
|
38
|
+
*/
|
|
39
|
+
headers?: Record<string, string | undefined>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Custom fetch implementation.
|
|
43
|
+
*/
|
|
44
|
+
fetch?: FetchFunction;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* ID generator for tool call fallback IDs.
|
|
48
|
+
*/
|
|
49
|
+
generateId?: () => string;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Include usage details in streaming responses.
|
|
53
|
+
*/
|
|
54
|
+
includeUsageInStream?: boolean;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Override supported URL patterns for file parts.
|
|
58
|
+
*/
|
|
59
|
+
supportedUrls?: LanguageModelV3['supportedUrls'];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// Provider Interface
|
|
64
|
+
// ============================================================================
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The Kimi Code provider interface.
|
|
68
|
+
*/
|
|
69
|
+
export interface KimiCodeProvider extends Omit<ProviderV3, 'specificationVersion'> {
|
|
70
|
+
specificationVersion: 'v3';
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates a Kimi Code language model.
|
|
74
|
+
* @param modelId - The model identifier (defaults to 'kimi-for-coding')
|
|
75
|
+
* @param settings - Optional model settings
|
|
76
|
+
*/
|
|
77
|
+
(modelId?: KimiCodeModelId, settings?: KimiCodeSettings): LanguageModelV3;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Creates a Kimi Code language model.
|
|
81
|
+
* @param modelId - The model identifier
|
|
82
|
+
* @param settings - Optional model settings
|
|
83
|
+
*/
|
|
84
|
+
languageModel(modelId: KimiCodeModelId, settings?: KimiCodeSettings): LanguageModelV3;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Creates a Kimi Code language model (alias for languageModel).
|
|
88
|
+
* @param modelId - The model identifier
|
|
89
|
+
* @param settings - Optional model settings
|
|
90
|
+
*/
|
|
91
|
+
chat(modelId: KimiCodeModelId, settings?: KimiCodeSettings): LanguageModelV3;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ============================================================================
|
|
95
|
+
// Provider Factory
|
|
96
|
+
// ============================================================================
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Create a Kimi Code provider instance.
|
|
100
|
+
*
|
|
101
|
+
* @param options - Provider settings
|
|
102
|
+
* @returns A configured Kimi Code provider
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* import { createKimiCode } from 'kimi-vercel-ai-sdk-provider
|
|
107
|
+
';
|
|
108
|
+
*
|
|
109
|
+
* const kimiCode = createKimiCode({
|
|
110
|
+
* apiKey: process.env.KIMI_CODE_API_KEY,
|
|
111
|
+
* });
|
|
112
|
+
*
|
|
113
|
+
* const result = await generateText({
|
|
114
|
+
* model: kimiCode(), // Uses default 'kimi-for-coding' model
|
|
115
|
+
* prompt: 'Write a TypeScript function to merge two sorted arrays',
|
|
116
|
+
* });
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* // With extended thinking enabled
|
|
122
|
+
* const result = await generateText({
|
|
123
|
+
* model: kimiCode('kimi-for-coding', {
|
|
124
|
+
* extendedThinking: {
|
|
125
|
+
* enabled: true,
|
|
126
|
+
* effort: 'high'
|
|
127
|
+
* }
|
|
128
|
+
* }),
|
|
129
|
+
* prompt: 'Design a distributed cache system',
|
|
130
|
+
* });
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* // Using with Claude Code compatible settings
|
|
136
|
+
* const result = await generateText({
|
|
137
|
+
* model: kimiCode('kimi-k2-thinking'),
|
|
138
|
+
* prompt: 'Explain and fix this bug',
|
|
139
|
+
* });
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
export function createKimiCode(options: KimiCodeProviderSettings = {}): KimiCodeProvider {
|
|
143
|
+
const resolvedBaseURL =
|
|
144
|
+
loadOptionalSetting({
|
|
145
|
+
settingValue: options.baseURL,
|
|
146
|
+
environmentVariableName: 'KIMI_CODE_BASE_URL'
|
|
147
|
+
}) ?? KIMI_CODE_BASE_URL;
|
|
148
|
+
|
|
149
|
+
const baseURL = withoutTrailingSlash(resolvedBaseURL) ?? KIMI_CODE_BASE_URL;
|
|
150
|
+
|
|
151
|
+
const getHeaders = () => {
|
|
152
|
+
// Try KIMI_CODE_API_KEY first, fall back to KIMI_API_KEY
|
|
153
|
+
let apiKey = options.apiKey;
|
|
154
|
+
if (!apiKey) {
|
|
155
|
+
apiKey = process.env.KIMI_CODE_API_KEY ?? process.env.KIMI_API_KEY;
|
|
156
|
+
}
|
|
157
|
+
if (!apiKey) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
'Kimi Code API key is required. Set the KIMI_CODE_API_KEY or KIMI_API_KEY environment variable, or pass the apiKey option.'
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return withUserAgentSuffix(
|
|
164
|
+
{
|
|
165
|
+
'x-api-key': apiKey,
|
|
166
|
+
'anthropic-version': '2023-06-01',
|
|
167
|
+
...options.headers
|
|
168
|
+
},
|
|
169
|
+
`ai-sdk/kimi-code/${VERSION}`
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const createCodeModel = (modelId: KimiCodeModelId = KIMI_CODE_DEFAULT_MODEL, settings: KimiCodeSettings = {}) =>
|
|
174
|
+
new KimiCodeLanguageModel(modelId, settings, {
|
|
175
|
+
provider: 'kimi.code',
|
|
176
|
+
baseURL,
|
|
177
|
+
headers: getHeaders,
|
|
178
|
+
fetch: options.fetch,
|
|
179
|
+
generateId: options.generateId,
|
|
180
|
+
includeUsageInStream: settings.includeUsageInStream ?? options.includeUsageInStream,
|
|
181
|
+
supportedUrls: settings.supportedUrls ?? options.supportedUrls
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const provider: KimiCodeProvider = (
|
|
185
|
+
modelId: KimiCodeModelId = KIMI_CODE_DEFAULT_MODEL,
|
|
186
|
+
settings?: KimiCodeSettings
|
|
187
|
+
): KimiCodeLanguageModel => {
|
|
188
|
+
if (new.target) {
|
|
189
|
+
throw new Error('The Kimi Code provider function cannot be called with new.');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return createCodeModel(modelId, settings);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
provider.specificationVersion = 'v3';
|
|
196
|
+
provider.languageModel = createCodeModel;
|
|
197
|
+
provider.chat = createCodeModel;
|
|
198
|
+
|
|
199
|
+
provider.embeddingModel = (modelId: string) => {
|
|
200
|
+
throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
provider.imageModel = (modelId: string) => {
|
|
204
|
+
throw new NoSuchModelError({ modelId, modelType: 'imageModel' });
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
provider.rerankingModel = (modelId: string) => {
|
|
208
|
+
throw new NoSuchModelError({ modelId, modelType: 'rerankingModel' });
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
return provider;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Default Kimi Code provider instance.
|
|
216
|
+
*
|
|
217
|
+
* Uses the KIMI_CODE_API_KEY or KIMI_API_KEY environment variable for authentication.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```ts
|
|
221
|
+
* import { kimiCode } from 'kimi-vercel-ai-sdk-provider
|
|
222
|
+
';
|
|
223
|
+
*
|
|
224
|
+
* const result = await generateText({
|
|
225
|
+
* model: kimiCode(), // Uses default model
|
|
226
|
+
* prompt: 'Implement a binary search tree',
|
|
227
|
+
* });
|
|
228
|
+
* ```
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* // With extended thinking
|
|
233
|
+
* const result = await generateText({
|
|
234
|
+
* model: kimiCode('kimi-for-coding', { extendedThinking: true }),
|
|
235
|
+
* prompt: 'Design a microservices architecture',
|
|
236
|
+
* });
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
export const kimiCode = createKimiCode();
|