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,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message conversion utilities for Kimi API.
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
type LanguageModelV3Prompt,
|
|
8
|
+
type LanguageModelV3ToolResultPart,
|
|
9
|
+
UnsupportedFunctionalityError
|
|
10
|
+
} from '@ai-sdk/provider';
|
|
11
|
+
import { convertToBase64 } from '@ai-sdk/provider-utils';
|
|
12
|
+
import { isBuiltinToolName } from '../tools';
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Message Types
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A Kimi chat message.
|
|
20
|
+
*/
|
|
21
|
+
export type KimiChatMessage =
|
|
22
|
+
| {
|
|
23
|
+
role: 'system';
|
|
24
|
+
content: string;
|
|
25
|
+
}
|
|
26
|
+
| {
|
|
27
|
+
role: 'user';
|
|
28
|
+
content: string | Array<KimiChatContentPart>;
|
|
29
|
+
}
|
|
30
|
+
| {
|
|
31
|
+
role: 'assistant';
|
|
32
|
+
content: string | null;
|
|
33
|
+
reasoning_content?: string;
|
|
34
|
+
tool_calls?: Array<{
|
|
35
|
+
id: string;
|
|
36
|
+
type: 'function';
|
|
37
|
+
function: { name: string; arguments: string };
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
role: 'tool';
|
|
42
|
+
tool_call_id: string;
|
|
43
|
+
content: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A content part in a user message.
|
|
48
|
+
*/
|
|
49
|
+
export type KimiChatContentPart =
|
|
50
|
+
| { type: 'text'; text: string }
|
|
51
|
+
| { type: 'image_url'; image_url: { url: string } }
|
|
52
|
+
| { type: 'video_url'; video_url: { url: string } };
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A sequence of Kimi chat messages.
|
|
56
|
+
*/
|
|
57
|
+
export type KimiChatPrompt = Array<KimiChatMessage>;
|
|
58
|
+
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Supported Media Types
|
|
61
|
+
// ============================================================================
|
|
62
|
+
|
|
63
|
+
const SUPPORTED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/*'];
|
|
64
|
+
|
|
65
|
+
const SUPPORTED_VIDEO_TYPES = ['video/mp4', 'video/webm', 'video/ogg', 'video/*'];
|
|
66
|
+
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Message Conversion
|
|
69
|
+
// ============================================================================
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Convert AI SDK prompt format to Kimi chat messages.
|
|
73
|
+
*
|
|
74
|
+
* @param prompt - The AI SDK prompt
|
|
75
|
+
* @returns Kimi chat messages
|
|
76
|
+
*/
|
|
77
|
+
export function convertToKimiChatMessages(prompt: LanguageModelV3Prompt): KimiChatPrompt {
|
|
78
|
+
const messages: KimiChatPrompt = [];
|
|
79
|
+
|
|
80
|
+
for (const { role, content } of prompt) {
|
|
81
|
+
switch (role) {
|
|
82
|
+
case 'system': {
|
|
83
|
+
messages.push({ role: 'system', content });
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case 'user': {
|
|
87
|
+
if (content.length === 1 && content[0].type === 'text') {
|
|
88
|
+
messages.push({ role: 'user', content: content[0].text });
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
messages.push({
|
|
93
|
+
role: 'user',
|
|
94
|
+
content: content.map((part) => {
|
|
95
|
+
switch (part.type) {
|
|
96
|
+
case 'text':
|
|
97
|
+
return { type: 'text' as const, text: part.text };
|
|
98
|
+
case 'file': {
|
|
99
|
+
// Handle image files
|
|
100
|
+
if (isImageMediaType(part.mediaType)) {
|
|
101
|
+
return convertImagePart(part);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Handle video files (Kimi K2.5 supports video)
|
|
105
|
+
if (isVideoMediaType(part.mediaType)) {
|
|
106
|
+
return convertVideoPart(part);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Handle text files
|
|
110
|
+
if (part.mediaType.startsWith('text/')) {
|
|
111
|
+
const text =
|
|
112
|
+
part.data instanceof URL
|
|
113
|
+
? part.data.toString()
|
|
114
|
+
: typeof part.data === 'string'
|
|
115
|
+
? part.data
|
|
116
|
+
: new TextDecoder().decode(part.data);
|
|
117
|
+
|
|
118
|
+
return { type: 'text' as const, text };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
throw new UnsupportedFunctionalityError({
|
|
122
|
+
functionality: `file part media type ${part.mediaType}`
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
default: {
|
|
126
|
+
const _exhaustiveCheck: never = part;
|
|
127
|
+
throw new Error(`Unsupported part type: ${_exhaustiveCheck}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case 'assistant': {
|
|
135
|
+
let text = '';
|
|
136
|
+
let reasoning = '';
|
|
137
|
+
const toolCalls: Array<{
|
|
138
|
+
id: string;
|
|
139
|
+
type: 'function';
|
|
140
|
+
function: { name: string; arguments: string };
|
|
141
|
+
}> = [];
|
|
142
|
+
|
|
143
|
+
for (const part of content) {
|
|
144
|
+
switch (part.type) {
|
|
145
|
+
case 'text': {
|
|
146
|
+
text += part.text;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
case 'reasoning': {
|
|
150
|
+
reasoning += part.text;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case 'tool-call': {
|
|
154
|
+
toolCalls.push({
|
|
155
|
+
id: part.toolCallId,
|
|
156
|
+
type: 'function',
|
|
157
|
+
function: {
|
|
158
|
+
name: part.toolName,
|
|
159
|
+
arguments: JSON.stringify(part.input)
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case 'file': {
|
|
165
|
+
// Assistant file parts are not directly supported by Kimi API
|
|
166
|
+
// We could convert images to text descriptions, but for now skip
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
case 'tool-result': {
|
|
170
|
+
// Tool results in assistant messages are unusual but handle gracefully
|
|
171
|
+
// These would typically be in a 'tool' role message
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
default: {
|
|
175
|
+
const _exhaustiveCheck: never = part;
|
|
176
|
+
throw new Error(`Unsupported assistant part: ${_exhaustiveCheck}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
messages.push({
|
|
182
|
+
role: 'assistant',
|
|
183
|
+
content: text.length > 0 ? text : null,
|
|
184
|
+
...(reasoning.length > 0 ? { reasoning_content: reasoning } : {}),
|
|
185
|
+
...(toolCalls.length > 0 ? { tool_calls: toolCalls } : {})
|
|
186
|
+
});
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case 'tool': {
|
|
190
|
+
for (const toolResponse of content) {
|
|
191
|
+
if (toolResponse.type === 'tool-approval-response') {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
messages.push({
|
|
196
|
+
role: 'tool',
|
|
197
|
+
tool_call_id: toolResponse.toolCallId,
|
|
198
|
+
content: serializeToolResult(toolResponse)
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
default: {
|
|
204
|
+
const _exhaustiveCheck: never = role;
|
|
205
|
+
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return messages;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ============================================================================
|
|
214
|
+
// Helper Functions
|
|
215
|
+
// ============================================================================
|
|
216
|
+
|
|
217
|
+
function isImageMediaType(mediaType: string): boolean {
|
|
218
|
+
return mediaType.startsWith('image/') || SUPPORTED_IMAGE_TYPES.includes(mediaType);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function isVideoMediaType(mediaType: string): boolean {
|
|
222
|
+
return mediaType.startsWith('video/') || SUPPORTED_VIDEO_TYPES.includes(mediaType);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function convertImagePart(part: { mediaType: string; data: URL | Uint8Array | string }): {
|
|
226
|
+
type: 'image_url';
|
|
227
|
+
image_url: { url: string };
|
|
228
|
+
} {
|
|
229
|
+
const mediaType = part.mediaType === 'image/*' ? 'image/jpeg' : part.mediaType;
|
|
230
|
+
|
|
231
|
+
const url =
|
|
232
|
+
part.data instanceof URL ? part.data.toString() : `data:${mediaType};base64,${convertToBase64(part.data)}`;
|
|
233
|
+
|
|
234
|
+
return { type: 'image_url', image_url: { url } };
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function convertVideoPart(part: { mediaType: string; data: URL | Uint8Array | string }): {
|
|
238
|
+
type: 'video_url';
|
|
239
|
+
video_url: { url: string };
|
|
240
|
+
} {
|
|
241
|
+
// Video must be provided as a URL - base64 inline video is not practical
|
|
242
|
+
if (!(part.data instanceof URL)) {
|
|
243
|
+
throw new UnsupportedFunctionalityError({
|
|
244
|
+
functionality: 'inline video data (video must be provided as a URL)'
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return { type: 'video_url', video_url: { url: part.data.toString() } };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function serializeToolResult(toolResponse: LanguageModelV3ToolResultPart): string {
|
|
252
|
+
const { toolName } = toolResponse;
|
|
253
|
+
const output = toolResponse.output;
|
|
254
|
+
|
|
255
|
+
// For built-in tools like $web_search, just pass through the arguments
|
|
256
|
+
// The Kimi API expects the tool result to be the same as what was passed
|
|
257
|
+
if (isBuiltinToolName(toolName)) {
|
|
258
|
+
return serializeBuiltinToolResult(output);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Standard tool result serialization
|
|
262
|
+
switch (output.type) {
|
|
263
|
+
case 'text':
|
|
264
|
+
case 'error-text':
|
|
265
|
+
return output.value;
|
|
266
|
+
case 'execution-denied':
|
|
267
|
+
return output.reason ?? 'Tool execution denied.';
|
|
268
|
+
case 'json':
|
|
269
|
+
case 'error-json':
|
|
270
|
+
case 'content':
|
|
271
|
+
return JSON.stringify(output.value);
|
|
272
|
+
default: {
|
|
273
|
+
const _exhaustiveCheck: never = output;
|
|
274
|
+
return JSON.stringify(_exhaustiveCheck);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function serializeBuiltinToolResult(output: LanguageModelV3ToolResultPart['output']): string {
|
|
280
|
+
// For built-in tools, we need to pass through the result as-is
|
|
281
|
+
// The model expects the arguments it passed to be echoed back
|
|
282
|
+
switch (output.type) {
|
|
283
|
+
case 'text':
|
|
284
|
+
case 'error-text':
|
|
285
|
+
return output.value;
|
|
286
|
+
case 'json':
|
|
287
|
+
case 'error-json':
|
|
288
|
+
case 'content':
|
|
289
|
+
return JSON.stringify(output.value);
|
|
290
|
+
case 'execution-denied':
|
|
291
|
+
return output.reason ?? 'Tool execution denied.';
|
|
292
|
+
default: {
|
|
293
|
+
const _exhaustiveCheck: never = output;
|
|
294
|
+
return JSON.stringify(_exhaustiveCheck);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response processing utilities for Kimi API.
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { KIMI_CODE_INTERPRETER_TOOL_NAME, KIMI_WEB_SEARCH_TOOL_NAME } from '../tools';
|
|
7
|
+
|
|
8
|
+
export type { KimiExtendedUsage, KimiTokenUsage } from '../core';
|
|
9
|
+
export {
|
|
10
|
+
convertKimiUsage,
|
|
11
|
+
extractMessageContent,
|
|
12
|
+
getKimiRequestId,
|
|
13
|
+
getResponseMetadata,
|
|
14
|
+
mapKimiFinishReason
|
|
15
|
+
} from '../core';
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Built-in Tool Token Extraction
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Tool call structure for token extraction.
|
|
23
|
+
*/
|
|
24
|
+
interface ToolCallForTokens {
|
|
25
|
+
function: { name: string; arguments?: string | null };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Extract total_tokens from $web_search tool call arguments.
|
|
30
|
+
* The Kimi API includes usage information in the tool call arguments.
|
|
31
|
+
*
|
|
32
|
+
* @param toolCalls - The tool calls from the response
|
|
33
|
+
* @returns The total web search tokens, or undefined if no web search was used
|
|
34
|
+
*/
|
|
35
|
+
export function extractWebSearchTokens(toolCalls: Array<ToolCallForTokens> | null | undefined): number | undefined {
|
|
36
|
+
return extractBuiltinToolTokens(toolCalls, KIMI_WEB_SEARCH_TOOL_NAME);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Extract total_tokens from $code tool call arguments.
|
|
41
|
+
* The Kimi API includes usage information in the tool call arguments.
|
|
42
|
+
*
|
|
43
|
+
* @param toolCalls - The tool calls from the response
|
|
44
|
+
* @returns The total code interpreter tokens, or undefined if no code was executed
|
|
45
|
+
*/
|
|
46
|
+
export function extractCodeInterpreterTokens(
|
|
47
|
+
toolCalls: Array<ToolCallForTokens> | null | undefined
|
|
48
|
+
): number | undefined {
|
|
49
|
+
return extractBuiltinToolTokens(toolCalls, KIMI_CODE_INTERPRETER_TOOL_NAME);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Extract tokens from a specific built-in tool.
|
|
54
|
+
*/
|
|
55
|
+
function extractBuiltinToolTokens(
|
|
56
|
+
toolCalls: Array<ToolCallForTokens> | null | undefined,
|
|
57
|
+
toolName: string
|
|
58
|
+
): number | undefined {
|
|
59
|
+
if (!toolCalls) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let totalTokens = 0;
|
|
64
|
+
let foundTool = false;
|
|
65
|
+
|
|
66
|
+
for (const toolCall of toolCalls) {
|
|
67
|
+
if (toolCall.function.name === toolName) {
|
|
68
|
+
foundTool = true;
|
|
69
|
+
|
|
70
|
+
if (toolCall.function.arguments) {
|
|
71
|
+
try {
|
|
72
|
+
const args = JSON.parse(toolCall.function.arguments);
|
|
73
|
+
if (typeof args.total_tokens === 'number') {
|
|
74
|
+
totalTokens += args.total_tokens;
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
// Ignore parse errors
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return foundTool ? totalTokens : undefined;
|
|
84
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat model settings and provider options schema.
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { LanguageModelV3 } from '@ai-sdk/provider';
|
|
7
|
+
import type { KimiModelCapabilities } from '../core';
|
|
8
|
+
import type { KimiCodeInterpreterToolOptions, KimiWebSearchToolOptions } from '../tools';
|
|
9
|
+
import { z } from 'zod/v4';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Re-exports
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
export type {
|
|
16
|
+
KimiChatConfig,
|
|
17
|
+
KimiChatModelId,
|
|
18
|
+
KimiModelCapabilities
|
|
19
|
+
} from '../core';
|
|
20
|
+
export { inferModelCapabilities } from '../core';
|
|
21
|
+
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Context Caching Types
|
|
24
|
+
// ============================================================================
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Configuration for context caching.
|
|
28
|
+
* Enables cost reduction for long, repeated prompts.
|
|
29
|
+
*/
|
|
30
|
+
export interface KimiCachingConfig {
|
|
31
|
+
/**
|
|
32
|
+
* Enable context caching for this request.
|
|
33
|
+
*/
|
|
34
|
+
enabled: boolean;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Optional cache key for identifying cached context.
|
|
38
|
+
* Use the same key across requests to hit the same cache.
|
|
39
|
+
*/
|
|
40
|
+
cacheKey?: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Time-to-live for the cache in seconds.
|
|
44
|
+
* Defaults to API default (typically 3600 seconds / 1 hour).
|
|
45
|
+
*/
|
|
46
|
+
ttlSeconds?: number;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Reset the cache even if a matching cache exists.
|
|
50
|
+
*/
|
|
51
|
+
resetCache?: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// Chat Settings
|
|
56
|
+
// ============================================================================
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Settings for creating a Kimi chat model instance.
|
|
60
|
+
*/
|
|
61
|
+
export interface KimiChatSettings {
|
|
62
|
+
/**
|
|
63
|
+
* Enable JSON schema structured outputs when a schema is provided.
|
|
64
|
+
*/
|
|
65
|
+
supportsStructuredOutputs?: boolean;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Request usage metrics during streaming (if supported by the API).
|
|
69
|
+
*/
|
|
70
|
+
includeUsageInStream?: boolean;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Override supported URL patterns for file parts.
|
|
74
|
+
*/
|
|
75
|
+
supportedUrls?: LanguageModelV3['supportedUrls'];
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Enable the built-in web search tool.
|
|
79
|
+
* When true, Kimi can search the web to answer questions.
|
|
80
|
+
* You can also pass a configuration object for more control.
|
|
81
|
+
*/
|
|
82
|
+
webSearch?: boolean | KimiWebSearchToolOptions;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Enable the built-in code interpreter tool.
|
|
86
|
+
* When true, Kimi can execute code to solve problems.
|
|
87
|
+
* You can also pass a configuration object for more control.
|
|
88
|
+
*/
|
|
89
|
+
codeInterpreter?: boolean | KimiCodeInterpreterToolOptions;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Override inferred model capabilities.
|
|
93
|
+
*/
|
|
94
|
+
capabilities?: Partial<KimiModelCapabilities>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Enable tool choice polyfill for unsupported tool choice modes.
|
|
98
|
+
* When true (default), uses system message injection to simulate
|
|
99
|
+
* `required` and `tool` choices that Kimi doesn't natively support.
|
|
100
|
+
*
|
|
101
|
+
* @default true
|
|
102
|
+
*/
|
|
103
|
+
toolChoicePolyfill?: boolean;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Enable automatic file handling for experimental_attachments.
|
|
107
|
+
* When true, PDFs and documents will be automatically uploaded
|
|
108
|
+
* to Kimi's file API and their content injected into the context.
|
|
109
|
+
*
|
|
110
|
+
* @default false
|
|
111
|
+
*/
|
|
112
|
+
autoFileUpload?: boolean;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Context caching configuration.
|
|
116
|
+
* Reduces costs by up to 90% for repeated long prompts.
|
|
117
|
+
*/
|
|
118
|
+
caching?: boolean | KimiCachingConfig;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ============================================================================
|
|
122
|
+
// Provider Options Schema
|
|
123
|
+
// ============================================================================
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Zod schema for caching configuration.
|
|
127
|
+
*/
|
|
128
|
+
export const kimiCachingConfigSchema = z.object({
|
|
129
|
+
enabled: z.boolean(),
|
|
130
|
+
cacheKey: z.string().optional(),
|
|
131
|
+
ttlSeconds: z.number().optional(),
|
|
132
|
+
resetCache: z.boolean().optional()
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Zod schema for validating provider options passed to individual calls.
|
|
137
|
+
*/
|
|
138
|
+
export const kimiProviderOptionsSchema = z.object({
|
|
139
|
+
/**
|
|
140
|
+
* A unique identifier representing your end-user.
|
|
141
|
+
*/
|
|
142
|
+
user: z.string().optional(),
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Whether to use strict JSON schema validation when supported.
|
|
146
|
+
*/
|
|
147
|
+
strictJsonSchema: z.boolean().optional(),
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Optional request ID to correlate logs.
|
|
151
|
+
*/
|
|
152
|
+
requestId: z.string().optional(),
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Optional extra headers for this call.
|
|
156
|
+
*/
|
|
157
|
+
extraHeaders: z.record(z.string(), z.string()).optional(),
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Whether the provider should allow parallel tool calls.
|
|
161
|
+
*/
|
|
162
|
+
parallelToolCalls: z.boolean().optional(),
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Enable or configure the built-in web search tool for this request.
|
|
166
|
+
* This allows Kimi to search the web to help answer questions.
|
|
167
|
+
*/
|
|
168
|
+
webSearch: z
|
|
169
|
+
.union([
|
|
170
|
+
z.boolean(),
|
|
171
|
+
z.object({
|
|
172
|
+
enabled: z.boolean(),
|
|
173
|
+
config: z
|
|
174
|
+
.object({
|
|
175
|
+
search_result: z.boolean().optional()
|
|
176
|
+
})
|
|
177
|
+
.optional()
|
|
178
|
+
})
|
|
179
|
+
])
|
|
180
|
+
.optional(),
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Enable or configure the built-in code interpreter tool for this request.
|
|
184
|
+
* This allows Kimi to execute code to help solve problems.
|
|
185
|
+
*/
|
|
186
|
+
codeInterpreter: z
|
|
187
|
+
.union([
|
|
188
|
+
z.boolean(),
|
|
189
|
+
z.object({
|
|
190
|
+
enabled: z.boolean(),
|
|
191
|
+
config: z
|
|
192
|
+
.object({
|
|
193
|
+
timeout: z.number().optional(),
|
|
194
|
+
include_output: z.boolean().optional()
|
|
195
|
+
})
|
|
196
|
+
.optional()
|
|
197
|
+
})
|
|
198
|
+
])
|
|
199
|
+
.optional(),
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Enable or configure context caching for this request.
|
|
203
|
+
* Reduces costs for repeated long prompts.
|
|
204
|
+
*/
|
|
205
|
+
caching: z.union([z.boolean(), kimiCachingConfigSchema]).optional(),
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Enable tool choice polyfill for this request.
|
|
209
|
+
*/
|
|
210
|
+
toolChoicePolyfill: z.boolean().optional()
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Type for provider options passed to individual calls.
|
|
215
|
+
*/
|
|
216
|
+
export type KimiProviderOptions = z.infer<typeof kimiProviderOptionsSchema>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kimi Code module - Premium coding service with extended thinking support.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Kimi Code provides high-speed coding assistance (up to 100 tokens/s)
|
|
6
|
+
* with full compatibility for Claude Code and Roo Code agents.
|
|
7
|
+
*
|
|
8
|
+
* **Quick Start:**
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { kimiCode } from 'kimi-vercel-ai-sdk-provider
|
|
11
|
+
';
|
|
12
|
+
*
|
|
13
|
+
* const result = await generateText({
|
|
14
|
+
* model: kimiCode(), // Uses 'kimi-for-coding' by default
|
|
15
|
+
* prompt: 'Write a function to merge sorted arrays',
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @see https://www.kimi.com/code/docs/en/
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
// Messages
|
|
24
|
+
export type { KimiCodeContentPart, KimiCodeMessage, KimiCodePrompt } from './kimi-code-messages';
|
|
25
|
+
// Provider
|
|
26
|
+
export type { KimiCodeProvider, KimiCodeProviderSettings } from './kimi-code-provider';
|
|
27
|
+
// Settings
|
|
28
|
+
export type { KimiCodeProviderOptions, KimiCodeSettings } from './kimi-code-settings';
|
|
29
|
+
// Types
|
|
30
|
+
export type {
|
|
31
|
+
ExtendedThinkingConfig,
|
|
32
|
+
KimiCodeCapabilities,
|
|
33
|
+
KimiCodeConfig,
|
|
34
|
+
KimiCodeContentBlock,
|
|
35
|
+
KimiCodeDeltaType,
|
|
36
|
+
KimiCodeModelId,
|
|
37
|
+
KimiCodeResponseMetadata,
|
|
38
|
+
KimiCodeStopReason,
|
|
39
|
+
KimiCodeStreamEventType,
|
|
40
|
+
KimiCodeTextBlock,
|
|
41
|
+
KimiCodeThinkingBlock,
|
|
42
|
+
KimiCodeTokenUsage,
|
|
43
|
+
KimiCodeToolUseBlock,
|
|
44
|
+
ReasoningEffort
|
|
45
|
+
} from './kimi-code-types';
|
|
46
|
+
// Language Model
|
|
47
|
+
export { KimiCodeLanguageModel } from './kimi-code-language-model';
|
|
48
|
+
export { convertToKimiCodePrompt } from './kimi-code-messages';
|
|
49
|
+
export { createKimiCode, kimiCode } from './kimi-code-provider';
|
|
50
|
+
export {
|
|
51
|
+
effortToBudgetTokens,
|
|
52
|
+
kimiCodeProviderOptionsSchema,
|
|
53
|
+
normalizeExtendedThinkingConfig,
|
|
54
|
+
toAnthropicThinking
|
|
55
|
+
} from './kimi-code-settings';
|
|
56
|
+
export {
|
|
57
|
+
KIMI_CODE_ANTHROPIC_VERSION,
|
|
58
|
+
KIMI_CODE_BASE_URL,
|
|
59
|
+
KIMI_CODE_DEFAULT_CONTEXT_WINDOW,
|
|
60
|
+
KIMI_CODE_DEFAULT_MAX_TOKENS,
|
|
61
|
+
KIMI_CODE_DEFAULT_MODEL,
|
|
62
|
+
KIMI_CODE_MODELS,
|
|
63
|
+
KIMI_CODE_OPENAI_BASE_URL,
|
|
64
|
+
KIMI_CODE_THINKING_MODEL,
|
|
65
|
+
inferKimiCodeCapabilities
|
|
66
|
+
} from './kimi-code-types';
|