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.
Files changed (44) hide show
  1. package/LICENSE +198 -0
  2. package/README.md +871 -0
  3. package/dist/index.d.mts +1317 -0
  4. package/dist/index.d.ts +1317 -0
  5. package/dist/index.js +2764 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +2734 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +70 -0
  10. package/src/__tests__/caching.test.ts +97 -0
  11. package/src/__tests__/chat.test.ts +386 -0
  12. package/src/__tests__/code-integration.test.ts +562 -0
  13. package/src/__tests__/code-provider.test.ts +289 -0
  14. package/src/__tests__/code.test.ts +427 -0
  15. package/src/__tests__/core.test.ts +172 -0
  16. package/src/__tests__/files.test.ts +185 -0
  17. package/src/__tests__/integration.test.ts +457 -0
  18. package/src/__tests__/provider.test.ts +188 -0
  19. package/src/__tests__/tools.test.ts +519 -0
  20. package/src/chat/index.ts +42 -0
  21. package/src/chat/kimi-chat-language-model.ts +829 -0
  22. package/src/chat/kimi-chat-messages.ts +297 -0
  23. package/src/chat/kimi-chat-response.ts +84 -0
  24. package/src/chat/kimi-chat-settings.ts +216 -0
  25. package/src/code/index.ts +66 -0
  26. package/src/code/kimi-code-language-model.ts +669 -0
  27. package/src/code/kimi-code-messages.ts +303 -0
  28. package/src/code/kimi-code-provider.ts +239 -0
  29. package/src/code/kimi-code-settings.ts +193 -0
  30. package/src/code/kimi-code-types.ts +354 -0
  31. package/src/core/errors.ts +140 -0
  32. package/src/core/index.ts +36 -0
  33. package/src/core/types.ts +148 -0
  34. package/src/core/utils.ts +210 -0
  35. package/src/files/attachment-processor.ts +276 -0
  36. package/src/files/file-utils.ts +257 -0
  37. package/src/files/index.ts +24 -0
  38. package/src/files/kimi-file-client.ts +292 -0
  39. package/src/index.ts +122 -0
  40. package/src/kimi-provider.ts +263 -0
  41. package/src/tools/builtin-tools.ts +273 -0
  42. package/src/tools/index.ts +33 -0
  43. package/src/tools/prepare-tools.ts +306 -0
  44. 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
+ }