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,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings for the Kimi Code provider.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Kimi Code is compatible with Claude Code and Roo Code agents.
|
|
6
|
+
* Default settings are based on Roo Code documentation:
|
|
7
|
+
* - Max Output Tokens: 32768
|
|
8
|
+
* - Context Window Size: 262144
|
|
9
|
+
* - Reasoning Effort: Medium
|
|
10
|
+
*
|
|
11
|
+
* @see https://www.kimi.com/code/docs/en/more/third-party-agents.html
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { ExtendedThinkingConfig, KimiCodeCapabilities, ReasoningEffort } from './kimi-code-types';
|
|
16
|
+
import { z } from 'zod/v4';
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Settings Interface
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Settings for creating a Kimi Code model instance.
|
|
24
|
+
*/
|
|
25
|
+
export interface KimiCodeSettings {
|
|
26
|
+
/**
|
|
27
|
+
* Override inferred model capabilities.
|
|
28
|
+
*/
|
|
29
|
+
capabilities?: KimiCodeCapabilities;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Extended thinking/reasoning configuration.
|
|
33
|
+
* When enabled, the model will show its reasoning process.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const model = kimiCode('kimi-for-coding', {
|
|
38
|
+
* extendedThinking: {
|
|
39
|
+
* enabled: true,
|
|
40
|
+
* effort: 'high'
|
|
41
|
+
* }
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
extendedThinking?: ExtendedThinkingConfig | boolean;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Whether to include usage in streaming responses.
|
|
49
|
+
*/
|
|
50
|
+
includeUsageInStream?: boolean;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Override supported URL patterns.
|
|
54
|
+
*/
|
|
55
|
+
supportedUrls?: Record<string, RegExp[]>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// Provider Options Schema
|
|
60
|
+
// ============================================================================
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Schema for Kimi Code provider options passed via providerOptions.
|
|
64
|
+
*/
|
|
65
|
+
export const kimiCodeProviderOptionsSchema = z.object({
|
|
66
|
+
/**
|
|
67
|
+
* Extended thinking configuration.
|
|
68
|
+
*/
|
|
69
|
+
extendedThinking: z
|
|
70
|
+
.union([
|
|
71
|
+
z.boolean(),
|
|
72
|
+
z.object({
|
|
73
|
+
enabled: z.boolean().optional(),
|
|
74
|
+
effort: z.enum(['low', 'medium', 'high']).optional(),
|
|
75
|
+
budgetTokens: z.number().optional()
|
|
76
|
+
})
|
|
77
|
+
])
|
|
78
|
+
.optional(),
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* System prompt to prepend.
|
|
82
|
+
*/
|
|
83
|
+
system: z.string().optional(),
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Custom stop sequences.
|
|
87
|
+
*/
|
|
88
|
+
stopSequences: z.array(z.string()).optional()
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Inferred type from the provider options schema.
|
|
93
|
+
*/
|
|
94
|
+
export type KimiCodeProviderOptions = z.infer<typeof kimiCodeProviderOptionsSchema>;
|
|
95
|
+
|
|
96
|
+
// ============================================================================
|
|
97
|
+
// Helper Functions
|
|
98
|
+
// ============================================================================
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Normalize extended thinking config to a consistent format.
|
|
102
|
+
*
|
|
103
|
+
* @param config - Boolean or config object
|
|
104
|
+
* @returns Normalized config object
|
|
105
|
+
*/
|
|
106
|
+
export function normalizeExtendedThinkingConfig(
|
|
107
|
+
config: ExtendedThinkingConfig | boolean | undefined
|
|
108
|
+
): ExtendedThinkingConfig | undefined {
|
|
109
|
+
if (config === undefined) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (typeof config === 'boolean') {
|
|
114
|
+
return config ? { enabled: true, effort: 'medium' } : { enabled: false };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
enabled: config.enabled ?? true,
|
|
119
|
+
effort: config.effort ?? 'medium',
|
|
120
|
+
budgetTokens: config.budgetTokens
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Convert reasoning effort to budget tokens.
|
|
126
|
+
*
|
|
127
|
+
* @param effort - Reasoning effort level
|
|
128
|
+
* @returns Approximate budget tokens for the effort level
|
|
129
|
+
*/
|
|
130
|
+
export function effortToBudgetTokens(effort: ReasoningEffort): number {
|
|
131
|
+
switch (effort) {
|
|
132
|
+
case 'low':
|
|
133
|
+
return 2048;
|
|
134
|
+
case 'medium':
|
|
135
|
+
return 8192;
|
|
136
|
+
case 'high':
|
|
137
|
+
return 16384;
|
|
138
|
+
default:
|
|
139
|
+
return 8192;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ============================================================================
|
|
144
|
+
// Anthropic API Conversion Helpers
|
|
145
|
+
// ============================================================================
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Convert ExtendedThinkingConfig to Anthropic API thinking parameter format.
|
|
149
|
+
*
|
|
150
|
+
* @remarks
|
|
151
|
+
* This converts our config to the Anthropic API format expected by Kimi Code:
|
|
152
|
+
* - `{ type: 'enabled', budget_tokens: number }` when enabled
|
|
153
|
+
* - `{ type: 'disabled' }` when disabled
|
|
154
|
+
* - `undefined` when not configured
|
|
155
|
+
*
|
|
156
|
+
* @param config - Extended thinking configuration (boolean or object)
|
|
157
|
+
* @returns Anthropic-compatible thinking parameter or undefined
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* // From boolean
|
|
162
|
+
* toAnthropicThinking(true)
|
|
163
|
+
* // => { type: 'enabled', budget_tokens: 8192 }
|
|
164
|
+
*
|
|
165
|
+
* // From config object
|
|
166
|
+
* toAnthropicThinking({ enabled: true, effort: 'high' })
|
|
167
|
+
* // => { type: 'enabled', budget_tokens: 16384 }
|
|
168
|
+
*
|
|
169
|
+
* // With explicit budget
|
|
170
|
+
* toAnthropicThinking({ enabled: true, budgetTokens: 10000 })
|
|
171
|
+
* // => { type: 'enabled', budget_tokens: 10000 }
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
export function toAnthropicThinking(
|
|
175
|
+
config: ExtendedThinkingConfig | boolean | undefined
|
|
176
|
+
): { type: 'enabled'; budget_tokens: number } | { type: 'disabled' } | undefined {
|
|
177
|
+
const normalized = normalizeExtendedThinkingConfig(config);
|
|
178
|
+
|
|
179
|
+
if (normalized === undefined) {
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (!normalized.enabled) {
|
|
184
|
+
return { type: 'disabled' };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const budgetTokens = normalized.budgetTokens ?? effortToBudgetTokens(normalized.effort ?? 'medium');
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
type: 'enabled',
|
|
191
|
+
budget_tokens: budgetTokens
|
|
192
|
+
};
|
|
193
|
+
}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the Kimi Code provider.
|
|
3
|
+
*
|
|
4
|
+
* Kimi Code is a premium coding service within the Kimi ecosystem that provides:
|
|
5
|
+
* - High-speed output (up to 100 tokens/s)
|
|
6
|
+
* - Extended thinking/reasoning support
|
|
7
|
+
* - Full compatibility with Claude Code and Roo Code
|
|
8
|
+
* - Anthropic-compatible API format
|
|
9
|
+
*
|
|
10
|
+
* @see https://www.kimi.com/code/docs/en/
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { LanguageModelV3 } from '@ai-sdk/provider';
|
|
15
|
+
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Constants
|
|
18
|
+
// ============================================================================
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Default Kimi Code API endpoint (Anthropic-compatible).
|
|
22
|
+
* Used with Claude Code - set as ANTHROPIC_BASE_URL
|
|
23
|
+
*/
|
|
24
|
+
export const KIMI_CODE_BASE_URL = 'https://api.kimi.com/coding/v1';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* OpenAI-compatible API endpoint.
|
|
28
|
+
* Used with Roo Code - set as OpenAI Compatible entrypoint
|
|
29
|
+
*/
|
|
30
|
+
export const KIMI_CODE_OPENAI_BASE_URL = 'https://api.kimi.com/coding/v1';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Default Kimi Code model ID.
|
|
34
|
+
* Primary coding model optimized for development tasks.
|
|
35
|
+
*/
|
|
36
|
+
export const KIMI_CODE_DEFAULT_MODEL = 'kimi-for-coding';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Alternative model with enhanced thinking/reasoning.
|
|
40
|
+
* Can be toggled with Tab key in Claude Code.
|
|
41
|
+
*/
|
|
42
|
+
export const KIMI_CODE_THINKING_MODEL = 'kimi-k2-thinking';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* All available Kimi Code models.
|
|
46
|
+
*/
|
|
47
|
+
export const KIMI_CODE_MODELS = [KIMI_CODE_DEFAULT_MODEL, KIMI_CODE_THINKING_MODEL] as const;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Default max output tokens for Kimi Code (per Roo Code docs).
|
|
51
|
+
*/
|
|
52
|
+
export const KIMI_CODE_DEFAULT_MAX_TOKENS = 32768;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Default context window size (per Roo Code docs).
|
|
56
|
+
*/
|
|
57
|
+
export const KIMI_CODE_DEFAULT_CONTEXT_WINDOW = 262144;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Anthropic API version header value.
|
|
61
|
+
*/
|
|
62
|
+
export const KIMI_CODE_ANTHROPIC_VERSION = '2023-06-01';
|
|
63
|
+
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// Model IDs
|
|
66
|
+
// ============================================================================
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Available Kimi Code model IDs.
|
|
70
|
+
*
|
|
71
|
+
* @remarks
|
|
72
|
+
* - `kimi-for-coding` - Primary coding model optimized for development tasks
|
|
73
|
+
* - `kimi-k2-thinking` - Model with extended thinking for complex reasoning (toggle with Tab in Claude Code)
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* // Default model
|
|
78
|
+
* const model = kimiCode('kimi-for-coding');
|
|
79
|
+
*
|
|
80
|
+
* // Thinking model
|
|
81
|
+
* const thinkingModel = kimiCode('kimi-k2-thinking');
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export type KimiCodeModelId = 'kimi-for-coding' | 'kimi-k2-thinking' | (string & {});
|
|
85
|
+
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Model Capabilities
|
|
88
|
+
// ============================================================================
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Capabilities specific to Kimi Code models.
|
|
92
|
+
* Based on Roo Code configuration documentation.
|
|
93
|
+
*/
|
|
94
|
+
export interface KimiCodeCapabilities {
|
|
95
|
+
/**
|
|
96
|
+
* Whether the model supports extended thinking/reasoning.
|
|
97
|
+
* When enabled, use `thinking.type: 'enabled'` with `budget_tokens`.
|
|
98
|
+
*/
|
|
99
|
+
extendedThinking?: boolean;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Maximum output tokens.
|
|
103
|
+
* Default: 32768 (per Roo Code docs)
|
|
104
|
+
*/
|
|
105
|
+
maxOutputTokens?: number;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Maximum context window size.
|
|
109
|
+
* Default: 262144 (per Roo Code docs)
|
|
110
|
+
*/
|
|
111
|
+
maxContextSize?: number;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Whether the model supports streaming.
|
|
115
|
+
* Always true for Kimi Code.
|
|
116
|
+
*/
|
|
117
|
+
streaming?: boolean;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Whether the model supports tool/function calling.
|
|
121
|
+
* Always true for Kimi Code.
|
|
122
|
+
*/
|
|
123
|
+
toolCalling?: boolean;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Whether the model supports image inputs.
|
|
127
|
+
*/
|
|
128
|
+
imageInput?: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Infer model capabilities from the model ID.
|
|
133
|
+
*
|
|
134
|
+
* @param modelId - The model identifier
|
|
135
|
+
* @returns Inferred capabilities based on model name patterns
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* const caps = inferKimiCodeCapabilities('kimi-k2-thinking');
|
|
140
|
+
* // caps.extendedThinking === true
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export function inferKimiCodeCapabilities(modelId: string): KimiCodeCapabilities {
|
|
144
|
+
const isThinkingModel = modelId.includes('-thinking') || modelId.includes('k2-thinking');
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
extendedThinking: isThinkingModel,
|
|
148
|
+
maxOutputTokens: KIMI_CODE_DEFAULT_MAX_TOKENS,
|
|
149
|
+
maxContextSize: KIMI_CODE_DEFAULT_CONTEXT_WINDOW,
|
|
150
|
+
streaming: true,
|
|
151
|
+
toolCalling: true,
|
|
152
|
+
imageInput: true
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ============================================================================
|
|
157
|
+
// Provider Configuration
|
|
158
|
+
// ============================================================================
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Configuration for the Kimi Code language model.
|
|
162
|
+
* @internal
|
|
163
|
+
*/
|
|
164
|
+
export interface KimiCodeConfig {
|
|
165
|
+
/**
|
|
166
|
+
* Provider identifier.
|
|
167
|
+
*/
|
|
168
|
+
provider: string;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Base URL for the API.
|
|
172
|
+
*/
|
|
173
|
+
baseURL: string;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Function to get headers for requests.
|
|
177
|
+
*/
|
|
178
|
+
headers: () => Record<string, string | undefined>;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Custom fetch implementation.
|
|
182
|
+
*/
|
|
183
|
+
fetch?: typeof globalThis.fetch;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* ID generator for tool call fallback IDs.
|
|
187
|
+
*/
|
|
188
|
+
generateId?: () => string;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Whether to include usage in streaming responses.
|
|
192
|
+
*/
|
|
193
|
+
includeUsageInStream?: boolean;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Override supported URL patterns.
|
|
197
|
+
*/
|
|
198
|
+
supportedUrls?: LanguageModelV3['supportedUrls'];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ============================================================================
|
|
202
|
+
// Extended Thinking Configuration
|
|
203
|
+
// ============================================================================
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Reasoning effort levels for extended thinking.
|
|
207
|
+
* Maps to budget_tokens for the thinking parameter.
|
|
208
|
+
*
|
|
209
|
+
* Per Roo Code docs: Enable Reasoning Effort: Medium
|
|
210
|
+
*/
|
|
211
|
+
export type ReasoningEffort = 'low' | 'medium' | 'high';
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Configuration for extended thinking/reasoning.
|
|
215
|
+
* Compatible with Anthropic's thinking parameter format.
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```ts
|
|
219
|
+
* // Enable thinking with medium effort
|
|
220
|
+
* const config: ExtendedThinkingConfig = {
|
|
221
|
+
* enabled: true,
|
|
222
|
+
* effort: 'medium'
|
|
223
|
+
* };
|
|
224
|
+
*
|
|
225
|
+
* // Or specify exact budget tokens
|
|
226
|
+
* const config: ExtendedThinkingConfig = {
|
|
227
|
+
* enabled: true,
|
|
228
|
+
* budgetTokens: 10000
|
|
229
|
+
* };
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export interface ExtendedThinkingConfig {
|
|
233
|
+
/**
|
|
234
|
+
* Enable extended thinking mode.
|
|
235
|
+
* @default false
|
|
236
|
+
*/
|
|
237
|
+
enabled?: boolean;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Reasoning effort level.
|
|
241
|
+
* Controls how much computation is spent on reasoning.
|
|
242
|
+
* - low: ~2048 tokens
|
|
243
|
+
* - medium: ~8192 tokens (default, recommended by Roo Code)
|
|
244
|
+
* - high: ~16384 tokens
|
|
245
|
+
* @default 'medium'
|
|
246
|
+
*/
|
|
247
|
+
effort?: ReasoningEffort;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Budget tokens for thinking (alternative to effort).
|
|
251
|
+
* Higher values allow for more complex reasoning.
|
|
252
|
+
* Takes precedence over effort if both are specified.
|
|
253
|
+
*/
|
|
254
|
+
budgetTokens?: number;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ============================================================================
|
|
258
|
+
// API Response Types (Anthropic-compatible)
|
|
259
|
+
// ============================================================================
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Token usage from Kimi Code API.
|
|
263
|
+
* Follows Anthropic's usage format.
|
|
264
|
+
*/
|
|
265
|
+
export interface KimiCodeTokenUsage {
|
|
266
|
+
input_tokens?: number | null;
|
|
267
|
+
output_tokens?: number | null;
|
|
268
|
+
cache_read_input_tokens?: number | null;
|
|
269
|
+
cache_creation_input_tokens?: number | null;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Response metadata from Kimi Code API.
|
|
274
|
+
* Follows Anthropic's message format.
|
|
275
|
+
*/
|
|
276
|
+
export interface KimiCodeResponseMetadata {
|
|
277
|
+
id?: string | null;
|
|
278
|
+
model?: string | null;
|
|
279
|
+
type?: string | null;
|
|
280
|
+
stop_reason?: string | null;
|
|
281
|
+
stop_sequence?: string | null;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Thinking block in response (for extended thinking).
|
|
286
|
+
* Appears when thinking is enabled.
|
|
287
|
+
*/
|
|
288
|
+
export interface KimiCodeThinkingBlock {
|
|
289
|
+
type: 'thinking';
|
|
290
|
+
thinking: string;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Text block in response.
|
|
295
|
+
*/
|
|
296
|
+
export interface KimiCodeTextBlock {
|
|
297
|
+
type: 'text';
|
|
298
|
+
text: string;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Tool use block in response.
|
|
303
|
+
* Follows Anthropic's tool_use format.
|
|
304
|
+
*/
|
|
305
|
+
export interface KimiCodeToolUseBlock {
|
|
306
|
+
type: 'tool_use';
|
|
307
|
+
id: string;
|
|
308
|
+
name: string;
|
|
309
|
+
input: Record<string, unknown>;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Content block types in Kimi Code responses.
|
|
314
|
+
*/
|
|
315
|
+
export type KimiCodeContentBlock = KimiCodeThinkingBlock | KimiCodeTextBlock | KimiCodeToolUseBlock;
|
|
316
|
+
|
|
317
|
+
// ============================================================================
|
|
318
|
+
// Streaming Event Types (Anthropic SSE format)
|
|
319
|
+
// ============================================================================
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Streaming event types from Kimi Code API.
|
|
323
|
+
* Follows Anthropic's SSE format.
|
|
324
|
+
*
|
|
325
|
+
* Event sequence:
|
|
326
|
+
* 1. message_start - Contains message metadata and initial usage
|
|
327
|
+
* 2. content_block_start - Start of a content block (text, thinking, tool_use)
|
|
328
|
+
* 3. content_block_delta - Incremental content updates
|
|
329
|
+
* 4. content_block_stop - End of a content block
|
|
330
|
+
* 5. message_delta - Final message updates (stop_reason, usage)
|
|
331
|
+
* 6. message_stop - End of message
|
|
332
|
+
*
|
|
333
|
+
* @see https://docs.anthropic.com/claude/reference/streaming
|
|
334
|
+
*/
|
|
335
|
+
export type KimiCodeStreamEventType =
|
|
336
|
+
| 'message_start'
|
|
337
|
+
| 'content_block_start'
|
|
338
|
+
| 'content_block_delta'
|
|
339
|
+
| 'content_block_stop'
|
|
340
|
+
| 'message_delta'
|
|
341
|
+
| 'message_stop'
|
|
342
|
+
| 'ping'
|
|
343
|
+
| 'error';
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Delta types for content_block_delta events.
|
|
347
|
+
*/
|
|
348
|
+
export type KimiCodeDeltaType = 'text_delta' | 'thinking_delta' | 'input_json_delta';
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Stop reasons from Kimi Code API.
|
|
352
|
+
* Follows Anthropic's stop_reason format.
|
|
353
|
+
*/
|
|
354
|
+
export type KimiCodeStopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | null;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for the Kimi provider.
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createJsonErrorResponseHandler } from '@ai-sdk/provider-utils';
|
|
7
|
+
import { z } from 'zod/v4';
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Error Schema
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Zod schema for Kimi API error responses.
|
|
15
|
+
* Handles both standard OpenAI-style errors and simple message errors.
|
|
16
|
+
*/
|
|
17
|
+
export const kimiErrorSchema = z.union([
|
|
18
|
+
z.object({
|
|
19
|
+
error: z.object({
|
|
20
|
+
message: z.string(),
|
|
21
|
+
type: z.string().nullish(),
|
|
22
|
+
param: z.any().nullish(),
|
|
23
|
+
code: z.union([z.string(), z.number()]).nullish(),
|
|
24
|
+
request_id: z.string().nullish()
|
|
25
|
+
})
|
|
26
|
+
}),
|
|
27
|
+
z.object({
|
|
28
|
+
message: z.string()
|
|
29
|
+
})
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Type for Kimi API error data.
|
|
34
|
+
*/
|
|
35
|
+
export type KimiErrorData = z.infer<typeof kimiErrorSchema>;
|
|
36
|
+
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Error Handler
|
|
39
|
+
// ============================================================================
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Failed response handler for Kimi API errors.
|
|
43
|
+
* Parses error responses and creates appropriate error objects.
|
|
44
|
+
*/
|
|
45
|
+
export const kimiFailedResponseHandler = createJsonErrorResponseHandler({
|
|
46
|
+
errorSchema: kimiErrorSchema,
|
|
47
|
+
errorToMessage: (error: KimiErrorData) => {
|
|
48
|
+
if ('error' in error) {
|
|
49
|
+
return error.error.message;
|
|
50
|
+
}
|
|
51
|
+
return error.message;
|
|
52
|
+
},
|
|
53
|
+
isRetryable: (response) =>
|
|
54
|
+
response.status === 408 || response.status === 409 || response.status === 429 || response.status >= 500
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// Custom Error Classes
|
|
59
|
+
// ============================================================================
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Base error class for Kimi provider errors.
|
|
63
|
+
*/
|
|
64
|
+
export class KimiError extends Error {
|
|
65
|
+
readonly code: string;
|
|
66
|
+
readonly statusCode?: number;
|
|
67
|
+
|
|
68
|
+
constructor(message: string, code: string, statusCode?: number) {
|
|
69
|
+
super(message);
|
|
70
|
+
this.name = 'KimiError';
|
|
71
|
+
this.code = code;
|
|
72
|
+
this.statusCode = statusCode;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Error thrown when authentication fails.
|
|
78
|
+
*/
|
|
79
|
+
export class KimiAuthenticationError extends KimiError {
|
|
80
|
+
constructor(message: string = 'Invalid API key or authentication failed') {
|
|
81
|
+
super(message, 'authentication_error', 401);
|
|
82
|
+
this.name = 'KimiAuthenticationError';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Error thrown when rate limit is exceeded.
|
|
88
|
+
*/
|
|
89
|
+
export class KimiRateLimitError extends KimiError {
|
|
90
|
+
readonly retryAfter?: number;
|
|
91
|
+
|
|
92
|
+
constructor(message: string = 'Rate limit exceeded', retryAfter?: number) {
|
|
93
|
+
super(message, 'rate_limit_error', 429);
|
|
94
|
+
this.name = 'KimiRateLimitError';
|
|
95
|
+
this.retryAfter = retryAfter;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Error thrown when the request is invalid.
|
|
101
|
+
*/
|
|
102
|
+
export class KimiValidationError extends KimiError {
|
|
103
|
+
constructor(message: string, param?: string) {
|
|
104
|
+
super(param ? `${message} (param: ${param})` : message, 'validation_error', 400);
|
|
105
|
+
this.name = 'KimiValidationError';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Error thrown when a model is not found.
|
|
111
|
+
*/
|
|
112
|
+
export class KimiModelNotFoundError extends KimiError {
|
|
113
|
+
readonly modelId: string;
|
|
114
|
+
|
|
115
|
+
constructor(modelId: string) {
|
|
116
|
+
super(`Model '${modelId}' not found`, 'model_not_found', 404);
|
|
117
|
+
this.name = 'KimiModelNotFoundError';
|
|
118
|
+
this.modelId = modelId;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Error thrown when content is filtered.
|
|
124
|
+
*/
|
|
125
|
+
export class KimiContentFilterError extends KimiError {
|
|
126
|
+
constructor(message: string = 'Content was filtered due to policy violation') {
|
|
127
|
+
super(message, 'content_filter', 400);
|
|
128
|
+
this.name = 'KimiContentFilterError';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Error thrown when context length is exceeded.
|
|
134
|
+
*/
|
|
135
|
+
export class KimiContextLengthError extends KimiError {
|
|
136
|
+
constructor(message: string = 'Context length exceeded') {
|
|
137
|
+
super(message, 'context_length_exceeded', 400);
|
|
138
|
+
this.name = 'KimiContextLengthError';
|
|
139
|
+
}
|
|
140
|
+
}
|