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
package/README.md
ADDED
|
@@ -0,0 +1,871 @@
|
|
|
1
|
+
# kimi-vercel-ai-sdk-provider
|
|
2
|
+
|
|
3
|
+
Native Kimi (Moonshot AI) provider for Vercel AI SDK.
|
|
4
|
+
|
|
5
|
+
This is a native implementation with full support for Kimi-specific features, not a generic OpenAI-compatible wrapper.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/kimi-vercel-ai-sdk-provider
|
|
9
|
+
)
|
|
10
|
+
[](https://bundlephobia.com/package/kimi-vercel-ai-sdk-provider
|
|
12
|
+
)
|
|
13
|
+
[](https://www.npmjs.com/package/kimi-vercel-ai-sdk-provider
|
|
15
|
+
)
|
|
16
|
+
[](https://github.com/aaroniker/kimi-vercel-ai-sdk-provider/blob/main/LICENSE)
|
|
18
|
+
|
|
19
|
+
## Table of Contents
|
|
20
|
+
|
|
21
|
+
- [Features](#features)
|
|
22
|
+
- [Install](#install)
|
|
23
|
+
- [Quick Start](#quick-start)
|
|
24
|
+
- [Kimi Code](#kimi-code)
|
|
25
|
+
- [Available Models](#available-models)
|
|
26
|
+
- [Extended Thinking](#extended-thinking)
|
|
27
|
+
- [Streaming with Thinking Blocks](#streaming-with-thinking-blocks)
|
|
28
|
+
- [Built-in Tools](#built-in-tools-kimi-chat)
|
|
29
|
+
- [Web Search](#web-search-web_search)
|
|
30
|
+
- [Code Interpreter](#code-interpreter-code)
|
|
31
|
+
- [Provider Tool Helpers](#provider-tool-helpers)
|
|
32
|
+
- [Native File & PDF Support](#native-file--pdf-support)
|
|
33
|
+
- [File Client](#file-client-simple)
|
|
34
|
+
- [Attachment Processing](#attachment-processing)
|
|
35
|
+
- [Supported File Types](#supported-file-types)
|
|
36
|
+
- [Tool Choice Polyfill](#tool-choice-polyfill)
|
|
37
|
+
- [Context Caching](#context-caching)
|
|
38
|
+
- [Token Tracking](#token-tracking)
|
|
39
|
+
- [Reasoning/Thinking Models](#reasoningthinking-models)
|
|
40
|
+
- [Video Input](#video-input-k25-models)
|
|
41
|
+
- [Model Capabilities](#model-capabilities)
|
|
42
|
+
- [Provider Options](#provider-options)
|
|
43
|
+
- [Available Models](#available-models-1)
|
|
44
|
+
- [Regional Endpoints](#regional-endpoints)
|
|
45
|
+
- [Environment Variables](#environment-variables)
|
|
46
|
+
- [Why Native vs OpenAI-Compatible?](#why-native-vs-openai-compatible)
|
|
47
|
+
- [API Reference](#api-reference)
|
|
48
|
+
- [License](#license)
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
### Kimi Chat (Standard API)
|
|
53
|
+
- Built-in web search (`$web_search`) for grounded responses
|
|
54
|
+
- Built-in code interpreter (`$code`) for programmatic reasoning
|
|
55
|
+
- Deep thinking/reasoning model streaming
|
|
56
|
+
- Video input support for K2.5 models
|
|
57
|
+
- 256k context window support
|
|
58
|
+
- Token tracking (cache hits, reasoning, web search, code interpreter)
|
|
59
|
+
- Regional endpoints (global and China)
|
|
60
|
+
- Provider tool helpers (`kimi.tools.*` and `kimiTools.*`)
|
|
61
|
+
- **Native File & PDF Support** - Automatic file upload and content extraction
|
|
62
|
+
- **Tool Choice Polyfill** - Simulates `required` and `tool` choices via system messages
|
|
63
|
+
- **Context Caching** - Reduce costs by up to 90% for repeated long prompts
|
|
64
|
+
|
|
65
|
+
### Kimi Code (Premium Coding API)
|
|
66
|
+
- High-speed output (up to 100 tokens/s)
|
|
67
|
+
- Extended thinking/reasoning support with configurable effort levels
|
|
68
|
+
- 262k context window
|
|
69
|
+
- Streaming with thinking blocks
|
|
70
|
+
|
|
71
|
+
## Install
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm install kimi-vercel-ai-sdk-provider
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Quick Start
|
|
78
|
+
|
|
79
|
+
### Kimi Chat (Standard)
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { createKimi } from 'kimi-vercel-ai-sdk-provider
|
|
83
|
+
';
|
|
84
|
+
import { generateText, streamText } from 'ai';
|
|
85
|
+
|
|
86
|
+
const kimi = createKimi({
|
|
87
|
+
// Uses MOONSHOT_API_KEY env var if not provided
|
|
88
|
+
endpoint: 'global',
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Basic usage
|
|
92
|
+
const result = await generateText({
|
|
93
|
+
model: kimi('kimi-k2.5'),
|
|
94
|
+
prompt: 'Explain quantum computing in one sentence.',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Streaming with reasoning model
|
|
98
|
+
const stream = await streamText({
|
|
99
|
+
model: kimi('kimi-k2.5-thinking', { includeUsageInStream: true }),
|
|
100
|
+
prompt: 'Solve this step by step: What is 17 * 23?',
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Kimi Code (Premium)
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import { kimiCode, createKimiCode } from 'kimi-vercel-ai-sdk-provider
|
|
108
|
+
';
|
|
109
|
+
import { generateText, streamText } from 'ai';
|
|
110
|
+
|
|
111
|
+
// Using default instance (uses KIMI_CODE_API_KEY or KIMI_API_KEY env var)
|
|
112
|
+
const result = await generateText({
|
|
113
|
+
model: kimiCode(), // Uses 'kimi-for-coding' by default
|
|
114
|
+
prompt: 'Write a TypeScript function to merge two sorted arrays',
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// With extended thinking enabled
|
|
118
|
+
const stream = await streamText({
|
|
119
|
+
model: kimiCode('kimi-k2-thinking', {
|
|
120
|
+
extendedThinking: {
|
|
121
|
+
enabled: true,
|
|
122
|
+
effort: 'high' // 'low' | 'medium' | 'high'
|
|
123
|
+
}
|
|
124
|
+
}),
|
|
125
|
+
prompt: 'Design a distributed cache system',
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Or with custom configuration
|
|
129
|
+
const customKimiCode = createKimiCode({
|
|
130
|
+
apiKey: 'sk-kimi-xxx',
|
|
131
|
+
baseURL: 'https://api.kimi.com/coding/v1', // default
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Kimi Code
|
|
136
|
+
|
|
137
|
+
Kimi Code is a premium coding service optimized for development tasks with high-speed output and extended thinking support.
|
|
138
|
+
|
|
139
|
+
### Available Models
|
|
140
|
+
|
|
141
|
+
| Model | Description |
|
|
142
|
+
|-------|-------------|
|
|
143
|
+
| `kimi-for-coding` | Primary coding model optimized for development tasks (default) |
|
|
144
|
+
| `kimi-k2-thinking` | Extended thinking model for complex reasoning |
|
|
145
|
+
|
|
146
|
+
### Extended Thinking
|
|
147
|
+
|
|
148
|
+
Enable extended thinking to see the model's reasoning process:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
// Simple boolean
|
|
152
|
+
const model = kimiCode('kimi-for-coding', { extendedThinking: true });
|
|
153
|
+
|
|
154
|
+
// With effort level
|
|
155
|
+
const model = kimiCode('kimi-for-coding', {
|
|
156
|
+
extendedThinking: {
|
|
157
|
+
enabled: true,
|
|
158
|
+
effort: 'high' // 'low' (~2k tokens), 'medium' (~8k tokens), 'high' (~16k tokens)
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// With explicit budget
|
|
163
|
+
const model = kimiCode('kimi-for-coding', {
|
|
164
|
+
extendedThinking: {
|
|
165
|
+
enabled: true,
|
|
166
|
+
budgetTokens: 10000
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Provider Options
|
|
172
|
+
|
|
173
|
+
Pass options via `providerOptions.kimiCode`:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const result = await generateText({
|
|
177
|
+
model: kimiCode('kimi-for-coding'),
|
|
178
|
+
prompt: 'Write a REST API',
|
|
179
|
+
providerOptions: {
|
|
180
|
+
kimiCode: {
|
|
181
|
+
extendedThinking: { enabled: true, effort: 'medium' },
|
|
182
|
+
system: 'You are an expert TypeScript developer',
|
|
183
|
+
stopSequences: ['```']
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Streaming with Thinking Blocks
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
const stream = await streamText({
|
|
193
|
+
model: kimiCode('kimi-k2-thinking'),
|
|
194
|
+
prompt: 'Design a microservices architecture',
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
for await (const part of stream.fullStream) {
|
|
198
|
+
switch (part.type) {
|
|
199
|
+
case 'reasoning-start':
|
|
200
|
+
console.log('--- Thinking ---');
|
|
201
|
+
break;
|
|
202
|
+
case 'reasoning-delta':
|
|
203
|
+
process.stdout.write(part.delta);
|
|
204
|
+
break;
|
|
205
|
+
case 'reasoning-end':
|
|
206
|
+
console.log('\n--- Answer ---');
|
|
207
|
+
break;
|
|
208
|
+
case 'text-delta':
|
|
209
|
+
process.stdout.write(part.delta);
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Built-in Tools (Kimi Chat)
|
|
216
|
+
|
|
217
|
+
Kimi provides server-side tools that can be enabled in three ways:
|
|
218
|
+
|
|
219
|
+
1. Model settings: `kimi('model', { webSearch: true })`
|
|
220
|
+
2. Provider options: `providerOptions.kimi.webSearch = true`
|
|
221
|
+
3. Provider tool helpers: `kimi.tools.webSearch()` or `kimiTools.webSearch()`
|
|
222
|
+
|
|
223
|
+
### Web Search (`$web_search`)
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
// Enable via model settings
|
|
227
|
+
const model = kimi('kimi-k2.5', { webSearch: true });
|
|
228
|
+
|
|
229
|
+
const result = await generateText({
|
|
230
|
+
model,
|
|
231
|
+
prompt: 'What are the latest AI news today?',
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Enable per request via provider options
|
|
235
|
+
const result = await generateText({
|
|
236
|
+
model: kimi('kimi-k2.5'),
|
|
237
|
+
prompt: 'What is the current Bitcoin price?',
|
|
238
|
+
providerOptions: {
|
|
239
|
+
kimi: {
|
|
240
|
+
webSearch: true,
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Advanced: Configure search behavior
|
|
246
|
+
const result = await generateText({
|
|
247
|
+
model: kimi('kimi-k2.5'),
|
|
248
|
+
prompt: 'Latest research on transformer architectures',
|
|
249
|
+
providerOptions: {
|
|
250
|
+
kimi: {
|
|
251
|
+
webSearch: {
|
|
252
|
+
enabled: true,
|
|
253
|
+
config: {
|
|
254
|
+
search_result: true,
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Code Interpreter (`$code`)
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
// Enable via model settings
|
|
266
|
+
const model = kimi('kimi-k2.5', { codeInterpreter: true });
|
|
267
|
+
|
|
268
|
+
const result = await generateText({
|
|
269
|
+
model,
|
|
270
|
+
prompt: 'Calculate the factorial of 20 and show your work.',
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Enable per request via provider options
|
|
274
|
+
const result = await generateText({
|
|
275
|
+
model: kimi('kimi-k2.5'),
|
|
276
|
+
prompt: 'Simulate 1000 coin flips and report the distribution.',
|
|
277
|
+
providerOptions: {
|
|
278
|
+
kimi: {
|
|
279
|
+
codeInterpreter: true,
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
// Advanced: Configure code execution
|
|
285
|
+
const result = await generateText({
|
|
286
|
+
model: kimi('kimi-k2.5'),
|
|
287
|
+
prompt: 'Generate a CSV of prime numbers under 1000.',
|
|
288
|
+
providerOptions: {
|
|
289
|
+
kimi: {
|
|
290
|
+
codeInterpreter: {
|
|
291
|
+
enabled: true,
|
|
292
|
+
config: {
|
|
293
|
+
timeout: 30,
|
|
294
|
+
include_output: true,
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Provider Tool Helpers
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
import { kimi, kimiTools } from 'kimi-vercel-ai-sdk-provider
|
|
306
|
+
';
|
|
307
|
+
|
|
308
|
+
const result = await generateText({
|
|
309
|
+
model: kimi('kimi-k2.5'),
|
|
310
|
+
tools: {
|
|
311
|
+
webSearch: kimi.tools.webSearch(),
|
|
312
|
+
codeInterpreter: kimi.tools.codeInterpreter(),
|
|
313
|
+
},
|
|
314
|
+
prompt: 'Summarize today\'s headlines and compute sentiment stats.',
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// Or use the named helper
|
|
318
|
+
const result = await generateText({
|
|
319
|
+
model: kimi('kimi-k2.5'),
|
|
320
|
+
tools: {
|
|
321
|
+
webSearch: kimiTools.webSearch(),
|
|
322
|
+
},
|
|
323
|
+
prompt: 'What is the weather in Tokyo?',
|
|
324
|
+
});
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Native File & PDF Support
|
|
328
|
+
|
|
329
|
+
Kimi excels at reading long documents. This provider includes a file handling module for automatic file upload and content extraction.
|
|
330
|
+
|
|
331
|
+
### File Client (Simple)
|
|
332
|
+
|
|
333
|
+
The provider includes a pre-configured file client:
|
|
334
|
+
|
|
335
|
+
```ts
|
|
336
|
+
import { createKimi } from 'kimi-vercel-ai-sdk-provider
|
|
337
|
+
';
|
|
338
|
+
|
|
339
|
+
const kimi = createKimi();
|
|
340
|
+
|
|
341
|
+
// Upload and extract content from a PDF - no config needed!
|
|
342
|
+
const result = await kimi.files.uploadAndExtract({
|
|
343
|
+
data: pdfBuffer,
|
|
344
|
+
filename: 'document.pdf',
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
console.log(result.content); // Extracted text content
|
|
348
|
+
console.log(result.file.id); // File ID for reference
|
|
349
|
+
|
|
350
|
+
// List all uploaded files
|
|
351
|
+
const files = await kimi.files.listFiles();
|
|
352
|
+
|
|
353
|
+
// Delete a file
|
|
354
|
+
await kimi.files.deleteFile(fileId);
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### File Client (Manual Configuration)
|
|
358
|
+
|
|
359
|
+
If you need custom configuration:
|
|
360
|
+
|
|
361
|
+
```ts
|
|
362
|
+
import { KimiFileClient } from 'kimi-vercel-ai-sdk-provider
|
|
363
|
+
';
|
|
364
|
+
|
|
365
|
+
const client = new KimiFileClient({
|
|
366
|
+
baseURL: 'https://api.moonshot.ai/v1',
|
|
367
|
+
headers: () => ({
|
|
368
|
+
Authorization: `Bearer ${process.env.MOONSHOT_API_KEY}`,
|
|
369
|
+
}),
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
const result = await client.uploadAndExtract({
|
|
373
|
+
data: pdfBuffer,
|
|
374
|
+
filename: 'document.pdf',
|
|
375
|
+
mediaType: 'application/pdf',
|
|
376
|
+
});
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Attachment Processing
|
|
380
|
+
|
|
381
|
+
Process experimental_attachments automatically:
|
|
382
|
+
|
|
383
|
+
```ts
|
|
384
|
+
import { processAttachments } from 'kimi-vercel-ai-sdk-provider
|
|
385
|
+
';
|
|
386
|
+
|
|
387
|
+
const processed = await processAttachments({
|
|
388
|
+
attachments: message.experimental_attachments ?? [],
|
|
389
|
+
clientConfig: {
|
|
390
|
+
baseURL: 'https://api.moonshot.ai/v1',
|
|
391
|
+
headers: () => ({ Authorization: `Bearer ${process.env.MOONSHOT_API_KEY}` }),
|
|
392
|
+
},
|
|
393
|
+
autoUploadDocuments: true,
|
|
394
|
+
cleanupAfterExtract: true, // Delete files after extraction
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
// Inject document content into messages
|
|
398
|
+
const documentContent = processed
|
|
399
|
+
.filter(p => p.type === 'text-inject' && p.textContent)
|
|
400
|
+
.map(p => p.textContent)
|
|
401
|
+
.join('\n');
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Supported File Types
|
|
405
|
+
|
|
406
|
+
Documents (extracted as text): PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT, MD, HTML, JSON, EPUB, CSV, and code files.
|
|
407
|
+
|
|
408
|
+
Images (for vision): JPEG, PNG, GIF, WebP, SVG, BMP, TIFF, AVIF.
|
|
409
|
+
|
|
410
|
+
Videos (K2.5 models): MP4, WebM, OGG.
|
|
411
|
+
|
|
412
|
+
## Tool Choice Polyfill
|
|
413
|
+
|
|
414
|
+
Kimi doesn't natively support `tool_choice: 'required'` or forcing a specific tool. This provider includes a polyfill that uses system message injection to simulate these behaviors.
|
|
415
|
+
|
|
416
|
+
### Automatic Polyfill (Default)
|
|
417
|
+
|
|
418
|
+
```ts
|
|
419
|
+
const result = await generateText({
|
|
420
|
+
model: kimi('kimi-k2.5'),
|
|
421
|
+
tools: { searchWeb: webSearchTool },
|
|
422
|
+
toolChoice: { type: 'required' }, // Polyfilled automatically
|
|
423
|
+
prompt: 'Find the weather in Tokyo',
|
|
424
|
+
});
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
The provider will inject a system message like:
|
|
428
|
+
> "IMPORTANT INSTRUCTION: You MUST use one of the available tools to respond..."
|
|
429
|
+
|
|
430
|
+
### Disable Polyfill
|
|
431
|
+
|
|
432
|
+
```ts
|
|
433
|
+
// Disable via model settings
|
|
434
|
+
const model = kimi('kimi-k2.5', { toolChoicePolyfill: false });
|
|
435
|
+
|
|
436
|
+
// Or per-request via provider options
|
|
437
|
+
const result = await generateText({
|
|
438
|
+
model: kimi('kimi-k2.5'),
|
|
439
|
+
tools: { searchWeb: webSearchTool },
|
|
440
|
+
toolChoice: { type: 'required' },
|
|
441
|
+
providerOptions: {
|
|
442
|
+
kimi: { toolChoicePolyfill: false }
|
|
443
|
+
},
|
|
444
|
+
prompt: 'Find the weather',
|
|
445
|
+
});
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
## Context Caching
|
|
449
|
+
|
|
450
|
+
Reduce costs by up to 90% for repeated long prompts (like analyzing documents or maintaining long conversations).
|
|
451
|
+
|
|
452
|
+
### Enable Caching
|
|
453
|
+
|
|
454
|
+
```ts
|
|
455
|
+
// Simple boolean
|
|
456
|
+
const result = await generateText({
|
|
457
|
+
model: kimi('kimi-k2.5', { caching: true }),
|
|
458
|
+
prompt: 'Analyze this long document...',
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// With configuration
|
|
462
|
+
const result = await generateText({
|
|
463
|
+
model: kimi('kimi-k2.5', {
|
|
464
|
+
caching: {
|
|
465
|
+
enabled: true,
|
|
466
|
+
cacheKey: 'book-analysis-v1', // Consistent key for cache hits
|
|
467
|
+
ttlSeconds: 7200, // 2 hours TTL
|
|
468
|
+
}
|
|
469
|
+
}),
|
|
470
|
+
prompt: 'What are the main themes?',
|
|
471
|
+
});
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Per-Request Caching
|
|
475
|
+
|
|
476
|
+
```ts
|
|
477
|
+
const result = await generateText({
|
|
478
|
+
model: kimi('kimi-k2.5'),
|
|
479
|
+
prompt: 'Continue analysis...',
|
|
480
|
+
providerOptions: {
|
|
481
|
+
kimi: {
|
|
482
|
+
caching: {
|
|
483
|
+
enabled: true,
|
|
484
|
+
cacheKey: 'book-analysis-v1',
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### Reset Cache
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
const result = await generateText({
|
|
495
|
+
model: kimi('kimi-k2.5'),
|
|
496
|
+
prompt: 'Re-analyze with new context...',
|
|
497
|
+
providerOptions: {
|
|
498
|
+
kimi: {
|
|
499
|
+
caching: {
|
|
500
|
+
enabled: true,
|
|
501
|
+
cacheKey: 'book-analysis-v1',
|
|
502
|
+
resetCache: true, // Force cache refresh
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
},
|
|
506
|
+
});
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
## Token Tracking
|
|
510
|
+
|
|
511
|
+
Token usage includes built-in tool usage when present:
|
|
512
|
+
|
|
513
|
+
```ts
|
|
514
|
+
const result = await generateText({
|
|
515
|
+
model: kimi('kimi-k2.5', { webSearch: true, codeInterpreter: true }),
|
|
516
|
+
prompt: 'Find today\'s EUR/USD rate and compute a 5% increase.',
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
console.log(result.usage);
|
|
520
|
+
// {
|
|
521
|
+
// inputTokens: { total: 150, cacheRead: 50, ... },
|
|
522
|
+
// outputTokens: { total: 200, reasoning: 0, ... },
|
|
523
|
+
// webSearchTokens: 1500,
|
|
524
|
+
// codeInterpreterTokens: 320,
|
|
525
|
+
// }
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## Reasoning/Thinking Models
|
|
529
|
+
|
|
530
|
+
Kimi's thinking models provide step-by-step reasoning:
|
|
531
|
+
|
|
532
|
+
```ts
|
|
533
|
+
const stream = await streamText({
|
|
534
|
+
model: kimi('kimi-k2.5-thinking'),
|
|
535
|
+
prompt: 'Prove that sqrt(2) is irrational.',
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
for await (const part of stream.fullStream) {
|
|
539
|
+
switch (part.type) {
|
|
540
|
+
case 'reasoning-start':
|
|
541
|
+
console.log('--- Reasoning ---');
|
|
542
|
+
break;
|
|
543
|
+
case 'reasoning-delta':
|
|
544
|
+
process.stdout.write(part.delta);
|
|
545
|
+
break;
|
|
546
|
+
case 'reasoning-end':
|
|
547
|
+
console.log('\n--- Answer ---');
|
|
548
|
+
break;
|
|
549
|
+
case 'text-delta':
|
|
550
|
+
process.stdout.write(part.delta);
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
## Video Input (K2.5 models)
|
|
557
|
+
|
|
558
|
+
K2.5 models support video URLs:
|
|
559
|
+
|
|
560
|
+
```ts
|
|
561
|
+
const result = await generateText({
|
|
562
|
+
model: kimi('kimi-k2.5'),
|
|
563
|
+
messages: [
|
|
564
|
+
{
|
|
565
|
+
role: 'user',
|
|
566
|
+
content: [
|
|
567
|
+
{ type: 'text', text: 'What is happening in this video?' },
|
|
568
|
+
{
|
|
569
|
+
type: 'file',
|
|
570
|
+
mediaType: 'video/mp4',
|
|
571
|
+
data: new URL('https://example.com/video.mp4'),
|
|
572
|
+
},
|
|
573
|
+
],
|
|
574
|
+
},
|
|
575
|
+
],
|
|
576
|
+
});
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
## Model Capabilities
|
|
580
|
+
|
|
581
|
+
The provider automatically infers capabilities from model IDs:
|
|
582
|
+
|
|
583
|
+
```ts
|
|
584
|
+
import { inferModelCapabilities, inferKimiCodeCapabilities } from 'kimi-vercel-ai-sdk-provider
|
|
585
|
+
';
|
|
586
|
+
|
|
587
|
+
// Kimi Chat models
|
|
588
|
+
const caps = inferModelCapabilities('kimi-k2.5-thinking');
|
|
589
|
+
// {
|
|
590
|
+
// thinking: true,
|
|
591
|
+
// alwaysThinking: true,
|
|
592
|
+
// imageInput: true,
|
|
593
|
+
// videoInput: true,
|
|
594
|
+
// maxContextSize: 256000,
|
|
595
|
+
// toolCalling: true,
|
|
596
|
+
// jsonMode: true,
|
|
597
|
+
// structuredOutputs: true,
|
|
598
|
+
// }
|
|
599
|
+
|
|
600
|
+
// Kimi Code models
|
|
601
|
+
const codeCaps = inferKimiCodeCapabilities('kimi-k2-thinking');
|
|
602
|
+
// {
|
|
603
|
+
// extendedThinking: true,
|
|
604
|
+
// maxOutputTokens: 32768,
|
|
605
|
+
// maxContextSize: 262144,
|
|
606
|
+
// streaming: true,
|
|
607
|
+
// toolCalling: true,
|
|
608
|
+
// imageInput: true,
|
|
609
|
+
// }
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
## Provider Options
|
|
613
|
+
|
|
614
|
+
### Kimi Chat Options
|
|
615
|
+
|
|
616
|
+
Pass Kimi-specific options via `providerOptions.kimi`:
|
|
617
|
+
|
|
618
|
+
```ts
|
|
619
|
+
const result = await generateText({
|
|
620
|
+
model: kimi('kimi-k2.5'),
|
|
621
|
+
prompt: 'Return JSON with name and version.',
|
|
622
|
+
responseFormat: { type: 'json' },
|
|
623
|
+
providerOptions: {
|
|
624
|
+
kimi: {
|
|
625
|
+
user: 'user-123',
|
|
626
|
+
requestId: 'trace-abc',
|
|
627
|
+
strictJsonSchema: true,
|
|
628
|
+
extraHeaders: { 'X-Custom': 'value' },
|
|
629
|
+
parallelToolCalls: true,
|
|
630
|
+
webSearch: true,
|
|
631
|
+
codeInterpreter: true,
|
|
632
|
+
},
|
|
633
|
+
},
|
|
634
|
+
});
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### Kimi Code Options
|
|
638
|
+
|
|
639
|
+
Pass options via `providerOptions.kimiCode`:
|
|
640
|
+
|
|
641
|
+
```ts
|
|
642
|
+
const result = await generateText({
|
|
643
|
+
model: kimiCode('kimi-for-coding'),
|
|
644
|
+
prompt: 'Write clean code',
|
|
645
|
+
providerOptions: {
|
|
646
|
+
kimiCode: {
|
|
647
|
+
extendedThinking: { enabled: true, effort: 'medium' },
|
|
648
|
+
system: 'Follow best practices',
|
|
649
|
+
stopSequences: ['---'],
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
});
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
## Available Models
|
|
656
|
+
|
|
657
|
+
### Kimi Chat
|
|
658
|
+
|
|
659
|
+
| Model | Features |
|
|
660
|
+
|-------|----------|
|
|
661
|
+
| `kimi-k2.5` | Latest, image/video input, built-in tools |
|
|
662
|
+
| `kimi-k2.5-thinking` | K2.5 + always-on deep reasoning |
|
|
663
|
+
| `kimi-k2-turbo` | Fast, cost-effective |
|
|
664
|
+
| `kimi-k2-thinking` | K2 + always-on deep reasoning |
|
|
665
|
+
|
|
666
|
+
### Kimi Code
|
|
667
|
+
|
|
668
|
+
| Model | Features |
|
|
669
|
+
|-------|----------|
|
|
670
|
+
| `kimi-for-coding` | Primary coding model (default) |
|
|
671
|
+
| `kimi-k2-thinking` | Extended thinking for complex tasks |
|
|
672
|
+
|
|
673
|
+
## Regional Endpoints
|
|
674
|
+
|
|
675
|
+
### Kimi Chat
|
|
676
|
+
|
|
677
|
+
```ts
|
|
678
|
+
// Global (default) - api.moonshot.ai
|
|
679
|
+
const kimiGlobal = createKimi({ endpoint: 'global' });
|
|
680
|
+
|
|
681
|
+
// China - api.moonshot.cn (lower latency in mainland China)
|
|
682
|
+
const kimiChina = createKimi({ endpoint: 'cn' });
|
|
683
|
+
|
|
684
|
+
// Custom endpoint
|
|
685
|
+
const kimiCustom = createKimi({
|
|
686
|
+
baseURL: 'https://your-proxy.example.com/v1',
|
|
687
|
+
});
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Kimi Code
|
|
691
|
+
|
|
692
|
+
```ts
|
|
693
|
+
// Default - api.kimi.com/coding/v1
|
|
694
|
+
const codeProvider = createKimiCode();
|
|
695
|
+
|
|
696
|
+
// Custom endpoint
|
|
697
|
+
const customCodeProvider = createKimiCode({
|
|
698
|
+
baseURL: 'https://your-proxy.example.com/v1',
|
|
699
|
+
});
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
## Environment Variables
|
|
703
|
+
|
|
704
|
+
Copy `.env.example` to `.env` and configure your API keys:
|
|
705
|
+
|
|
706
|
+
```bash
|
|
707
|
+
cp .env.example .env
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
### Kimi Chat
|
|
711
|
+
| Variable | Description |
|
|
712
|
+
|----------|-------------|
|
|
713
|
+
| `MOONSHOT_API_KEY` | Your Moonshot AI API key (required) |
|
|
714
|
+
| `MOONSHOT_BASE_URL` | Override the base URL (optional) |
|
|
715
|
+
|
|
716
|
+
### Kimi Code
|
|
717
|
+
| Variable | Description |
|
|
718
|
+
|----------|-------------|
|
|
719
|
+
| `KIMI_CODE_API_KEY` | Your Kimi Code API key (preferred) |
|
|
720
|
+
| `KIMI_API_KEY` | Fallback API key if `KIMI_CODE_API_KEY` not set |
|
|
721
|
+
| `KIMI_CODE_BASE_URL` | Override the base URL (optional) |
|
|
722
|
+
|
|
723
|
+
Get your API keys at: https://platform.moonshot.cn/console/api-keys
|
|
724
|
+
|
|
725
|
+
## Why Native vs OpenAI-Compatible?
|
|
726
|
+
|
|
727
|
+
This provider is built natively for Kimi rather than using `@ai-sdk/openai-compatible`. Benefits:
|
|
728
|
+
|
|
729
|
+
| Feature | Native Provider | OpenAI-Compatible |
|
|
730
|
+
|---------|-----------------|-------------------|
|
|
731
|
+
| `$web_search` built-in tool | Full support | Not available |
|
|
732
|
+
| `$code` code interpreter | Full support | Not available |
|
|
733
|
+
| Built-in tool token tracking | Included | Not available |
|
|
734
|
+
| Video input support | Automatic | Manual config |
|
|
735
|
+
| Reasoning content streaming | Native handling | May need config |
|
|
736
|
+
| Model capability inference | Automatic | Manual |
|
|
737
|
+
| Type-safe provider options | Full types | Partial |
|
|
738
|
+
| Error messages | Kimi-specific | Generic |
|
|
739
|
+
| Kimi Code extended thinking | Full support | Not available |
|
|
740
|
+
|
|
741
|
+
## API Reference
|
|
742
|
+
|
|
743
|
+
### Exports
|
|
744
|
+
|
|
745
|
+
```ts
|
|
746
|
+
// Kimi Chat Provider
|
|
747
|
+
import {
|
|
748
|
+
createKimi,
|
|
749
|
+
kimi,
|
|
750
|
+
KimiChatLanguageModel,
|
|
751
|
+
inferModelCapabilities,
|
|
752
|
+
kimiProviderOptionsSchema,
|
|
753
|
+
kimiCachingConfigSchema,
|
|
754
|
+
kimiTools,
|
|
755
|
+
// Types
|
|
756
|
+
KimiProvider,
|
|
757
|
+
KimiProviderSettings,
|
|
758
|
+
KimiChatSettings,
|
|
759
|
+
KimiChatModelId,
|
|
760
|
+
KimiProviderOptions,
|
|
761
|
+
KimiModelCapabilities,
|
|
762
|
+
KimiCachingConfig,
|
|
763
|
+
} from 'kimi-vercel-ai-sdk-provider
|
|
764
|
+
';
|
|
765
|
+
|
|
766
|
+
// Kimi Code Provider
|
|
767
|
+
import {
|
|
768
|
+
createKimiCode,
|
|
769
|
+
kimiCode,
|
|
770
|
+
KimiCodeLanguageModel,
|
|
771
|
+
inferKimiCodeCapabilities,
|
|
772
|
+
kimiCodeProviderOptionsSchema,
|
|
773
|
+
toAnthropicThinking,
|
|
774
|
+
// Constants
|
|
775
|
+
KIMI_CODE_BASE_URL,
|
|
776
|
+
KIMI_CODE_OPENAI_BASE_URL,
|
|
777
|
+
KIMI_CODE_DEFAULT_MODEL,
|
|
778
|
+
KIMI_CODE_THINKING_MODEL,
|
|
779
|
+
KIMI_CODE_MODELS,
|
|
780
|
+
KIMI_CODE_DEFAULT_MAX_TOKENS,
|
|
781
|
+
KIMI_CODE_DEFAULT_CONTEXT_WINDOW,
|
|
782
|
+
KIMI_CODE_ANTHROPIC_VERSION,
|
|
783
|
+
// Types
|
|
784
|
+
KimiCodeProvider,
|
|
785
|
+
KimiCodeProviderSettings,
|
|
786
|
+
KimiCodeSettings,
|
|
787
|
+
KimiCodeModelId,
|
|
788
|
+
KimiCodeCapabilities,
|
|
789
|
+
ExtendedThinkingConfig,
|
|
790
|
+
ReasoningEffort,
|
|
791
|
+
} from 'kimi-vercel-ai-sdk-provider';
|
|
792
|
+
|
|
793
|
+
// File Handling
|
|
794
|
+
import {
|
|
795
|
+
KimiFileClient,
|
|
796
|
+
processAttachments,
|
|
797
|
+
SUPPORTED_FILE_EXTENSIONS,
|
|
798
|
+
SUPPORTED_MIME_TYPES,
|
|
799
|
+
isImageMediaType,
|
|
800
|
+
isVideoMediaType,
|
|
801
|
+
isDocumentMediaType,
|
|
802
|
+
isFileExtractMediaType,
|
|
803
|
+
getMediaTypeFromExtension,
|
|
804
|
+
getPurposeFromMediaType,
|
|
805
|
+
// Types
|
|
806
|
+
KimiFile,
|
|
807
|
+
KimiFileClientConfig,
|
|
808
|
+
FileUploadOptions,
|
|
809
|
+
FileUploadResult,
|
|
810
|
+
Attachment,
|
|
811
|
+
ProcessedAttachment,
|
|
812
|
+
} from 'kimi-vercel-ai-sdk-provider
|
|
813
|
+
';
|
|
814
|
+
|
|
815
|
+
// Built-in Tools
|
|
816
|
+
import {
|
|
817
|
+
createWebSearchTool,
|
|
818
|
+
createKimiWebSearchTool,
|
|
819
|
+
createCodeInterpreterTool,
|
|
820
|
+
KIMI_WEB_SEARCH_TOOL_NAME,
|
|
821
|
+
KIMI_CODE_INTERPRETER_TOOL_NAME,
|
|
822
|
+
} from 'kimi-vercel-ai-sdk-provider
|
|
823
|
+
';
|
|
824
|
+
|
|
825
|
+
// Errors
|
|
826
|
+
import {
|
|
827
|
+
KimiError,
|
|
828
|
+
KimiAuthenticationError,
|
|
829
|
+
KimiRateLimitError,
|
|
830
|
+
KimiValidationError,
|
|
831
|
+
KimiContextLengthError,
|
|
832
|
+
KimiContentFilterError,
|
|
833
|
+
KimiModelNotFoundError,
|
|
834
|
+
} from 'kimi-vercel-ai-sdk-provider
|
|
835
|
+
';
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
### Feature Comparison
|
|
839
|
+
|
|
840
|
+
| Feature | Generic OpenAI Provider | Kimi Provider |
|
|
841
|
+
|---------|------------------------|---------------|
|
|
842
|
+
| Setup | Manual baseURL & Headers | Plug-and-play |
|
|
843
|
+
| PDF/Doc Analysis | Not supported (only Vision) | Auto-upload & Extract |
|
|
844
|
+
| Thinking Models | Mixed text / Unparsed | Mapped to SDK reasoning |
|
|
845
|
+
| Tool Reliability | Crashes on `tool_choice: required` | Auto-fixed / Polyfilled |
|
|
846
|
+
| Long Context | Full price | Cached (up to 90% cheaper) |
|
|
847
|
+
| Web Search | Manual tool definition | `webSearch: true` toggle |
|
|
848
|
+
| Code Interpreter | Not available | `codeInterpreter: true` toggle |
|
|
849
|
+
| Type Safety | Raw strings | TypeScript enums for models |
|
|
850
|
+
|
|
851
|
+
## License
|
|
852
|
+
|
|
853
|
+
Apache-2.0
|
|
854
|
+
|
|
855
|
+
## Authors
|
|
856
|
+
|
|
857
|
+
<p><strong>Aaron Iker</strong></p>
|
|
858
|
+
<p valign="center">
|
|
859
|
+
<a href="https://x.com/aaroniker">
|
|
860
|
+
<img valign="top" src="https://img.shields.io/badge/X-@aaroniker-black?style=flat-square&logo=x" alt="X">
|
|
861
|
+
</a>
|
|
862
|
+
<span valign="center"> • </span>
|
|
863
|
+
<a href="https://github.com/aaroniker">
|
|
864
|
+
<img valign="top" src="https://img.shields.io/badge/GitHub-aaroniker-black?style=flat-square&logo=github" alt="GitHub">
|
|
865
|
+
</a>
|
|
866
|
+
<span valign="center"> • </span>
|
|
867
|
+
<a href="https://www.linkedin.com/in/aaron-iker-15606897/">
|
|
868
|
+
<img valign="top" src="https://img.shields.io/badge/LinkedIn-aaroniker-blue?style=flat-square&logo=linkedin" alt="LinkedIn">
|
|
869
|
+
</a>
|
|
870
|
+
</p>
|
|
871
|
+
|