kimi-vercel-ai-sdk-provider 0.2.0 → 0.4.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/README.md +164 -15
- package/dist/index.d.mts +154 -7
- package/dist/index.d.ts +154 -7
- package/dist/index.js +278 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +278 -48
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
- package/src/__tests__/code-integration.test.ts +37 -31
- package/src/__tests__/code-provider.test.ts +5 -6
- package/src/__tests__/code.test.ts +1 -3
- package/src/__tests__/file-cache.test.ts +310 -0
- package/src/__tests__/model-config.test.ts +120 -0
- package/src/__tests__/provider.test.ts +3 -2
- package/src/__tests__/reasoning-utils.test.ts +164 -0
- package/src/__tests__/tools.test.ts +75 -7
- package/src/chat/kimi-chat-language-model.ts +42 -3
- package/src/core/errors.ts +1 -1
- package/src/core/index.ts +10 -3
- package/src/core/types.ts +57 -2
- package/src/core/utils.ts +138 -0
- package/src/files/attachment-processor.ts +53 -5
- package/src/files/file-cache.ts +260 -0
- package/src/files/index.ts +16 -1
- package/src/tools/prepare-tools.ts +88 -2
package/README.md
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
# kimi-vercel-ai-sdk-provider
|
|
2
2
|
|
|
3
|
+
<img width="1600" height="1278" alt="image" src="https://github.com/user-attachments/assets/fcde2cc0-73e2-4d32-b1bc-b4d9eaca5a6a" />
|
|
4
|
+
|
|
3
5
|
Native Kimi (Moonshot AI) provider for Vercel AI SDK.
|
|
4
6
|
|
|
5
7
|
This is a native implementation with full support for Kimi-specific features, not a generic OpenAI-compatible wrapper.
|
|
6
8
|
|
|
7
|
-
[
|
|
10
|
-
[
|
|
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)
|
|
9
|
+
[](https://www.npmjs.com/package/kimi-vercel-ai-sdk-provider)
|
|
10
|
+
[](https://bundlephobia.com/package/kimi-vercel-ai-sdk-provider)
|
|
11
|
+
[](https://www.npmjs.com/package/kimi-vercel-ai-sdk-provider)
|
|
12
|
+
[](https://github.com/aaroniker/kimi-vercel-ai-sdk-provider/blob/main/LICENSE)
|
|
18
13
|
|
|
19
14
|
## Table of Contents
|
|
20
15
|
|
|
@@ -39,6 +34,11 @@ This is a native implementation with full support for Kimi-specific features, no
|
|
|
39
34
|
- [Reasoning/Thinking Models](#reasoningthinking-models)
|
|
40
35
|
- [Video Input](#video-input-k25-models)
|
|
41
36
|
- [Model Capabilities](#model-capabilities)
|
|
37
|
+
- [Advanced Features](#advanced-features)
|
|
38
|
+
- [Temperature Locking](#temperature-locking-for-thinking-models)
|
|
39
|
+
- [File Content Caching](#file-content-caching)
|
|
40
|
+
- [Schema Sanitization](#schema-sanitization)
|
|
41
|
+
- [Reasoning Preservation](#reasoning-preservation-utilities)
|
|
42
42
|
- [Provider Options](#provider-options)
|
|
43
43
|
- [Available Models](#available-models-1)
|
|
44
44
|
- [Regional Endpoints](#regional-endpoints)
|
|
@@ -61,6 +61,9 @@ This is a native implementation with full support for Kimi-specific features, no
|
|
|
61
61
|
- **Native File & PDF Support** - Automatic file upload and content extraction
|
|
62
62
|
- **Tool Choice Polyfill** - Simulates `required` and `tool` choices via system messages
|
|
63
63
|
- **Context Caching** - Reduce costs by up to 90% for repeated long prompts
|
|
64
|
+
- **Temperature Locking** - Automatic temperature enforcement for thinking models
|
|
65
|
+
- **File Content Caching** - LRU cache to avoid re-uploading identical files
|
|
66
|
+
- **Schema Sanitization** - Automatic cleanup of unsupported JSON Schema keywords
|
|
64
67
|
|
|
65
68
|
### Kimi Code (Premium Coding API)
|
|
66
69
|
- High-speed output (up to 100 tokens/s)
|
|
@@ -79,8 +82,7 @@ npm install kimi-vercel-ai-sdk-provider
|
|
|
79
82
|
### Kimi Chat (Standard)
|
|
80
83
|
|
|
81
84
|
```ts
|
|
82
|
-
import { createKimi } from 'kimi-vercel-ai-sdk-provider
|
|
83
|
-
';
|
|
85
|
+
import { createKimi } from 'kimi-vercel-ai-sdk-provider';
|
|
84
86
|
import { generateText, streamText } from 'ai';
|
|
85
87
|
|
|
86
88
|
const kimi = createKimi({
|
|
@@ -609,6 +611,134 @@ const codeCaps = inferKimiCodeCapabilities('kimi-k2-thinking');
|
|
|
609
611
|
// }
|
|
610
612
|
```
|
|
611
613
|
|
|
614
|
+
## Advanced Features
|
|
615
|
+
|
|
616
|
+
### Temperature Locking for Thinking Models
|
|
617
|
+
|
|
618
|
+
Thinking models like `kimi-k2.5-thinking` require a fixed temperature of `1.0` for optimal reasoning. The provider automatically enforces this:
|
|
619
|
+
|
|
620
|
+
```ts
|
|
621
|
+
// Temperature is automatically set to 1.0 for thinking models
|
|
622
|
+
const result = await generateText({
|
|
623
|
+
model: kimi('kimi-k2.5-thinking'),
|
|
624
|
+
temperature: 0.7, // Will be ignored with a warning
|
|
625
|
+
prompt: 'Solve this complex problem...',
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
// Check the response for warnings
|
|
629
|
+
console.log(result.warnings);
|
|
630
|
+
// [{ type: 'compatibility', feature: 'temperature', details: 'Thinking models require temperature=1.0...' }]
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
Thinking models also default to 32k max tokens to prevent reasoning truncation:
|
|
634
|
+
|
|
635
|
+
```ts
|
|
636
|
+
// No need to set maxTokens - defaults to 32768 for thinking models
|
|
637
|
+
const result = await generateText({
|
|
638
|
+
model: kimi('kimi-k2.5-thinking'),
|
|
639
|
+
prompt: 'Explain quantum computing in detail...',
|
|
640
|
+
});
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### File Content Caching
|
|
644
|
+
|
|
645
|
+
Avoid re-uploading the same files by enabling the LRU cache:
|
|
646
|
+
|
|
647
|
+
```ts
|
|
648
|
+
import { processAttachments } from 'kimi-vercel-ai-sdk-provider';
|
|
649
|
+
|
|
650
|
+
// Enable caching (uses default global cache: 100 entries, 1 hour TTL)
|
|
651
|
+
const processed = await processAttachments({
|
|
652
|
+
attachments: message.experimental_attachments ?? [],
|
|
653
|
+
clientConfig: {
|
|
654
|
+
baseURL: 'https://api.moonshot.ai/v1',
|
|
655
|
+
headers: () => ({ Authorization: `Bearer ${process.env.MOONSHOT_API_KEY}` }),
|
|
656
|
+
},
|
|
657
|
+
cache: true, // Enable file caching
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
// Or provide a custom cache instance
|
|
661
|
+
import { FileCache } from 'kimi-vercel-ai-sdk-provider';
|
|
662
|
+
|
|
663
|
+
const customCache = new FileCache({
|
|
664
|
+
maxSize: 200, // Max 200 entries
|
|
665
|
+
ttlMs: 2 * 60 * 60 * 1000, // 2 hour TTL
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
const processed = await processAttachments({
|
|
669
|
+
attachments,
|
|
670
|
+
clientConfig,
|
|
671
|
+
cache: customCache,
|
|
672
|
+
});
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### Schema Sanitization
|
|
676
|
+
|
|
677
|
+
Tool parameters are automatically sanitized to remove JSON Schema keywords not supported by Kimi:
|
|
678
|
+
|
|
679
|
+
```ts
|
|
680
|
+
// This schema with advanced JSON Schema features...
|
|
681
|
+
const complexTool = {
|
|
682
|
+
name: 'search',
|
|
683
|
+
parameters: z.object({
|
|
684
|
+
query: z.string(),
|
|
685
|
+
filters: z.object({
|
|
686
|
+
$schema: 'http://json-schema.org/draft-07/schema#', // Removed
|
|
687
|
+
allOf: [{ minLength: 1 }], // Removed
|
|
688
|
+
anyOf: [{ type: 'string' }], // Removed
|
|
689
|
+
}),
|
|
690
|
+
}),
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
// ...is automatically sanitized before being sent to Kimi
|
|
694
|
+
// Only basic properties (type, properties, required, description) are kept
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
### Reasoning Preservation Utilities
|
|
698
|
+
|
|
699
|
+
Helpers for maintaining reasoning context in multi-turn conversations:
|
|
700
|
+
|
|
701
|
+
```ts
|
|
702
|
+
import {
|
|
703
|
+
analyzeReasoningPreservation,
|
|
704
|
+
recommendThinkingModel
|
|
705
|
+
} from 'kimi-vercel-ai-sdk-provider';
|
|
706
|
+
|
|
707
|
+
// Analyze if reasoning is properly preserved in a conversation
|
|
708
|
+
const messages = [
|
|
709
|
+
{ role: 'user', content: 'Solve this step by step: ...' },
|
|
710
|
+
{
|
|
711
|
+
role: 'assistant',
|
|
712
|
+
content: [
|
|
713
|
+
{ type: 'reasoning', text: 'First, I need to...' },
|
|
714
|
+
{ type: 'text', text: 'The answer is 42.' }
|
|
715
|
+
]
|
|
716
|
+
},
|
|
717
|
+
{ role: 'user', content: 'Explain step 2 more.' },
|
|
718
|
+
];
|
|
719
|
+
|
|
720
|
+
const analysis = analyzeReasoningPreservation(messages);
|
|
721
|
+
// {
|
|
722
|
+
// hasReasoningContent: true,
|
|
723
|
+
// reasoningPreserved: true,
|
|
724
|
+
// turnCount: 3,
|
|
725
|
+
// reasoningTurnCount: 1,
|
|
726
|
+
// recommendations: []
|
|
727
|
+
// }
|
|
728
|
+
|
|
729
|
+
// Get a recommendation on whether to use a thinking model
|
|
730
|
+
const recommendation = recommendThinkingModel({
|
|
731
|
+
taskDescription: 'Complex mathematical proof',
|
|
732
|
+
requiresStepByStep: true,
|
|
733
|
+
complexity: 'high',
|
|
734
|
+
});
|
|
735
|
+
// {
|
|
736
|
+
// recommended: true,
|
|
737
|
+
// reason: 'Task requires step-by-step reasoning with high complexity',
|
|
738
|
+
// suggestedModel: 'kimi-k2.5-thinking'
|
|
739
|
+
// }
|
|
740
|
+
```
|
|
741
|
+
|
|
612
742
|
## Provider Options
|
|
613
743
|
|
|
614
744
|
### Kimi Chat Options
|
|
@@ -794,6 +924,12 @@ import {
|
|
|
794
924
|
import {
|
|
795
925
|
KimiFileClient,
|
|
796
926
|
processAttachments,
|
|
927
|
+
FileCache,
|
|
928
|
+
generateContentHash,
|
|
929
|
+
generateCacheKey,
|
|
930
|
+
getDefaultFileCache,
|
|
931
|
+
setDefaultFileCache,
|
|
932
|
+
clearDefaultFileCache,
|
|
797
933
|
SUPPORTED_FILE_EXTENSIONS,
|
|
798
934
|
SUPPORTED_MIME_TYPES,
|
|
799
935
|
isImageMediaType,
|
|
@@ -809,8 +945,21 @@ import {
|
|
|
809
945
|
FileUploadResult,
|
|
810
946
|
Attachment,
|
|
811
947
|
ProcessedAttachment,
|
|
812
|
-
|
|
813
|
-
|
|
948
|
+
FileCacheOptions,
|
|
949
|
+
FileCacheEntry,
|
|
950
|
+
} from 'kimi-vercel-ai-sdk-provider';
|
|
951
|
+
|
|
952
|
+
// Utilities
|
|
953
|
+
import {
|
|
954
|
+
analyzeReasoningPreservation,
|
|
955
|
+
recommendThinkingModel,
|
|
956
|
+
// Constants
|
|
957
|
+
THINKING_MODEL_TEMPERATURE,
|
|
958
|
+
THINKING_MODEL_DEFAULT_MAX_TOKENS,
|
|
959
|
+
STANDARD_MODEL_DEFAULT_MAX_TOKENS,
|
|
960
|
+
// Types
|
|
961
|
+
ReasoningAnalysis,
|
|
962
|
+
} from 'kimi-vercel-ai-sdk-provider';
|
|
814
963
|
|
|
815
964
|
// Built-in Tools
|
|
816
965
|
import {
|
package/dist/index.d.mts
CHANGED
|
@@ -103,6 +103,21 @@ interface KimiModelCapabilities {
|
|
|
103
103
|
* Whether the model supports structured outputs.
|
|
104
104
|
*/
|
|
105
105
|
structuredOutputs?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Default temperature for the model.
|
|
108
|
+
* Thinking models require temperature=1.0 for optimal reasoning.
|
|
109
|
+
*/
|
|
110
|
+
defaultTemperature?: number;
|
|
111
|
+
/**
|
|
112
|
+
* Whether temperature is locked (cannot be changed).
|
|
113
|
+
* Thinking models have this set to true.
|
|
114
|
+
*/
|
|
115
|
+
temperatureLocked?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Default max output tokens for the model.
|
|
118
|
+
* Thinking models need higher limits to avoid truncated reasoning.
|
|
119
|
+
*/
|
|
120
|
+
defaultMaxOutputTokens?: number;
|
|
106
121
|
}
|
|
107
122
|
/**
|
|
108
123
|
* Infer model capabilities from the model ID.
|
|
@@ -110,10 +125,25 @@ interface KimiModelCapabilities {
|
|
|
110
125
|
* @param modelId - The model identifier
|
|
111
126
|
* @returns Inferred capabilities based on model name patterns
|
|
112
127
|
*
|
|
128
|
+
* @remarks
|
|
129
|
+
* This function automatically detects model capabilities and sets
|
|
130
|
+
* appropriate defaults:
|
|
131
|
+
* - Thinking models (`-thinking` suffix) get temperature=1.0 locked
|
|
132
|
+
* - Thinking models get 32k default max_tokens to avoid truncation
|
|
133
|
+
* - K2.5 models get video input support
|
|
134
|
+
*
|
|
113
135
|
* @example
|
|
114
136
|
* ```ts
|
|
115
137
|
* const caps = inferModelCapabilities('kimi-k2.5-thinking');
|
|
116
|
-
* // {
|
|
138
|
+
* // {
|
|
139
|
+
* // thinking: true,
|
|
140
|
+
* // alwaysThinking: true,
|
|
141
|
+
* // videoInput: true,
|
|
142
|
+
* // temperatureLocked: true,
|
|
143
|
+
* // defaultTemperature: 1.0,
|
|
144
|
+
* // defaultMaxOutputTokens: 32768,
|
|
145
|
+
* // ...
|
|
146
|
+
* // }
|
|
117
147
|
* ```
|
|
118
148
|
*/
|
|
119
149
|
declare function inferModelCapabilities(modelId: string): KimiModelCapabilities;
|
|
@@ -287,7 +317,8 @@ declare const kimiTools: {
|
|
|
287
317
|
*
|
|
288
318
|
* @example
|
|
289
319
|
* ```ts
|
|
290
|
-
* import { kimi, kimiTools } from 'ai-sdk-provider
|
|
320
|
+
* import { kimi, kimiTools } from 'kimi-vercel-ai-sdk-provider
|
|
321
|
+
';
|
|
291
322
|
*
|
|
292
323
|
* const result = await generateText({
|
|
293
324
|
* model: kimi('kimi-k2.5'),
|
|
@@ -311,7 +342,8 @@ declare const kimiTools: {
|
|
|
311
342
|
*
|
|
312
343
|
* @example
|
|
313
344
|
* ```ts
|
|
314
|
-
* import { kimi, kimiTools } from 'ai-sdk-provider
|
|
345
|
+
* import { kimi, kimiTools } from 'kimi-vercel-ai-sdk-provider
|
|
346
|
+
';
|
|
315
347
|
*
|
|
316
348
|
* const result = await generateText({
|
|
317
349
|
* model: kimi('kimi-k2.5'),
|
|
@@ -486,6 +518,9 @@ declare class KimiChatLanguageModel implements LanguageModelV3 {
|
|
|
486
518
|
toolCalling?: boolean;
|
|
487
519
|
jsonMode?: boolean;
|
|
488
520
|
structuredOutputs?: boolean;
|
|
521
|
+
defaultTemperature?: number;
|
|
522
|
+
temperatureLocked?: boolean;
|
|
523
|
+
defaultMaxOutputTokens?: number;
|
|
489
524
|
};
|
|
490
525
|
get supportedUrls(): Record<string, RegExp[]> | PromiseLike<Record<string, RegExp[]>>;
|
|
491
526
|
private getArgs;
|
|
@@ -493,6 +528,107 @@ declare class KimiChatLanguageModel implements LanguageModelV3 {
|
|
|
493
528
|
doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult>;
|
|
494
529
|
}
|
|
495
530
|
|
|
531
|
+
/**
|
|
532
|
+
* File content caching for efficient re-use of uploaded files.
|
|
533
|
+
* @module
|
|
534
|
+
*/
|
|
535
|
+
/**
|
|
536
|
+
* Entry in the file cache.
|
|
537
|
+
*/
|
|
538
|
+
interface FileCacheEntry {
|
|
539
|
+
/** The Kimi file ID */
|
|
540
|
+
fileId: string;
|
|
541
|
+
/** Extracted text content (for documents) */
|
|
542
|
+
content?: string;
|
|
543
|
+
/** Unix timestamp of creation */
|
|
544
|
+
createdAt: number;
|
|
545
|
+
/** File purpose */
|
|
546
|
+
purpose: 'file-extract' | 'image' | 'video';
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Options for configuring the file cache.
|
|
550
|
+
*/
|
|
551
|
+
interface FileCacheOptions {
|
|
552
|
+
/**
|
|
553
|
+
* Maximum number of entries in the cache.
|
|
554
|
+
* When exceeded, least recently used entries are evicted.
|
|
555
|
+
* @default 100
|
|
556
|
+
*/
|
|
557
|
+
maxSize?: number;
|
|
558
|
+
/**
|
|
559
|
+
* Time-to-live for cache entries in milliseconds.
|
|
560
|
+
* Entries older than this are considered stale.
|
|
561
|
+
* @default 3600000 (1 hour)
|
|
562
|
+
*/
|
|
563
|
+
ttlMs?: number;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* A simple LRU (Least Recently Used) cache for file content.
|
|
567
|
+
*
|
|
568
|
+
* This cache helps avoid re-uploading the same files multiple times
|
|
569
|
+
* by storing the mapping between content hashes and Kimi file IDs.
|
|
570
|
+
*
|
|
571
|
+
* @example
|
|
572
|
+
* ```ts
|
|
573
|
+
* const cache = new FileCache({ maxSize: 50, ttlMs: 30 * 60 * 1000 });
|
|
574
|
+
*
|
|
575
|
+
* // Check if we have this file cached
|
|
576
|
+
* const cached = cache.get(contentHash);
|
|
577
|
+
* if (cached) {
|
|
578
|
+
* console.log('Using cached file:', cached.fileId);
|
|
579
|
+
* }
|
|
580
|
+
*
|
|
581
|
+
* // Store a new file
|
|
582
|
+
* cache.set(contentHash, {
|
|
583
|
+
* fileId: 'file_abc123',
|
|
584
|
+
* content: 'extracted text...',
|
|
585
|
+
* purpose: 'file-extract',
|
|
586
|
+
* createdAt: Date.now()
|
|
587
|
+
* });
|
|
588
|
+
* ```
|
|
589
|
+
*/
|
|
590
|
+
declare class FileCache {
|
|
591
|
+
private readonly maxSize;
|
|
592
|
+
private readonly ttlMs;
|
|
593
|
+
private readonly cache;
|
|
594
|
+
constructor(options?: FileCacheOptions);
|
|
595
|
+
/**
|
|
596
|
+
* Get a cached entry by content hash.
|
|
597
|
+
* Returns undefined if not found or expired.
|
|
598
|
+
* Moves the entry to the end (most recently used).
|
|
599
|
+
*/
|
|
600
|
+
get(contentHash: string): FileCacheEntry | undefined;
|
|
601
|
+
/**
|
|
602
|
+
* Set a cache entry.
|
|
603
|
+
* Evicts the least recently used entry if cache is full.
|
|
604
|
+
*/
|
|
605
|
+
set(contentHash: string, entry: FileCacheEntry): void;
|
|
606
|
+
/**
|
|
607
|
+
* Check if an entry exists and is not expired.
|
|
608
|
+
*/
|
|
609
|
+
has(contentHash: string): boolean;
|
|
610
|
+
/**
|
|
611
|
+
* Delete a specific entry.
|
|
612
|
+
*/
|
|
613
|
+
delete(contentHash: string): boolean;
|
|
614
|
+
/**
|
|
615
|
+
* Clear all entries.
|
|
616
|
+
*/
|
|
617
|
+
clear(): void;
|
|
618
|
+
/**
|
|
619
|
+
* Get the current cache size.
|
|
620
|
+
*/
|
|
621
|
+
get size(): number;
|
|
622
|
+
/**
|
|
623
|
+
* Remove all expired entries.
|
|
624
|
+
*/
|
|
625
|
+
prune(): number;
|
|
626
|
+
/**
|
|
627
|
+
* Check if an entry is expired.
|
|
628
|
+
*/
|
|
629
|
+
private isExpired;
|
|
630
|
+
}
|
|
631
|
+
|
|
496
632
|
/**
|
|
497
633
|
* Kimi File API client for uploading and managing files.
|
|
498
634
|
* @module
|
|
@@ -657,6 +793,13 @@ interface ProcessAttachmentsOptions {
|
|
|
657
793
|
uploadImages?: boolean;
|
|
658
794
|
/** Whether to delete files after extraction (cleanup) */
|
|
659
795
|
cleanupAfterExtract?: boolean;
|
|
796
|
+
/**
|
|
797
|
+
* Enable caching of uploaded files.
|
|
798
|
+
* When true, uses the default global cache.
|
|
799
|
+
* When a FileCache instance, uses that cache.
|
|
800
|
+
* @default false
|
|
801
|
+
*/
|
|
802
|
+
cache?: boolean | FileCache;
|
|
660
803
|
}
|
|
661
804
|
/**
|
|
662
805
|
* Process experimental_attachments for Kimi.
|
|
@@ -861,7 +1004,8 @@ interface KimiProvider extends Omit<ProviderV3, 'specificationVersion'> {
|
|
|
861
1004
|
*
|
|
862
1005
|
* @example
|
|
863
1006
|
* ```ts
|
|
864
|
-
* import { createKimi } from 'ai-sdk-provider
|
|
1007
|
+
* import { createKimi } from 'kimi-vercel-ai-sdk-provider
|
|
1008
|
+
';
|
|
865
1009
|
*
|
|
866
1010
|
* const kimi = createKimi({
|
|
867
1011
|
* apiKey: process.env.MOONSHOT_API_KEY,
|
|
@@ -899,7 +1043,8 @@ declare function createKimi(options?: KimiProviderSettings): KimiProvider;
|
|
|
899
1043
|
*
|
|
900
1044
|
* @example
|
|
901
1045
|
* ```ts
|
|
902
|
-
* import { kimi } from 'ai-sdk-provider
|
|
1046
|
+
* import { kimi } from 'kimi-vercel-ai-sdk-provider
|
|
1047
|
+
';
|
|
903
1048
|
*
|
|
904
1049
|
* const result = await generateText({
|
|
905
1050
|
* model: kimi('kimi-k2.5'),
|
|
@@ -1222,7 +1367,8 @@ interface KimiCodeProvider extends Omit<ProviderV3, 'specificationVersion'> {
|
|
|
1222
1367
|
*
|
|
1223
1368
|
* @example
|
|
1224
1369
|
* ```ts
|
|
1225
|
-
* import { createKimiCode } from 'ai-sdk-provider
|
|
1370
|
+
* import { createKimiCode } from 'kimi-vercel-ai-sdk-provider
|
|
1371
|
+
';
|
|
1226
1372
|
*
|
|
1227
1373
|
* const kimiCode = createKimiCode({
|
|
1228
1374
|
* apiKey: process.env.KIMI_CODE_API_KEY,
|
|
@@ -1265,7 +1411,8 @@ declare function createKimiCode(options?: KimiCodeProviderSettings): KimiCodePro
|
|
|
1265
1411
|
*
|
|
1266
1412
|
* @example
|
|
1267
1413
|
* ```ts
|
|
1268
|
-
* import { kimiCode } from 'ai-sdk-provider
|
|
1414
|
+
* import { kimiCode } from 'kimi-vercel-ai-sdk-provider
|
|
1415
|
+
';
|
|
1269
1416
|
*
|
|
1270
1417
|
* const result = await generateText({
|
|
1271
1418
|
* model: kimiCode(), // Uses default model
|
package/dist/index.d.ts
CHANGED
|
@@ -103,6 +103,21 @@ interface KimiModelCapabilities {
|
|
|
103
103
|
* Whether the model supports structured outputs.
|
|
104
104
|
*/
|
|
105
105
|
structuredOutputs?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Default temperature for the model.
|
|
108
|
+
* Thinking models require temperature=1.0 for optimal reasoning.
|
|
109
|
+
*/
|
|
110
|
+
defaultTemperature?: number;
|
|
111
|
+
/**
|
|
112
|
+
* Whether temperature is locked (cannot be changed).
|
|
113
|
+
* Thinking models have this set to true.
|
|
114
|
+
*/
|
|
115
|
+
temperatureLocked?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Default max output tokens for the model.
|
|
118
|
+
* Thinking models need higher limits to avoid truncated reasoning.
|
|
119
|
+
*/
|
|
120
|
+
defaultMaxOutputTokens?: number;
|
|
106
121
|
}
|
|
107
122
|
/**
|
|
108
123
|
* Infer model capabilities from the model ID.
|
|
@@ -110,10 +125,25 @@ interface KimiModelCapabilities {
|
|
|
110
125
|
* @param modelId - The model identifier
|
|
111
126
|
* @returns Inferred capabilities based on model name patterns
|
|
112
127
|
*
|
|
128
|
+
* @remarks
|
|
129
|
+
* This function automatically detects model capabilities and sets
|
|
130
|
+
* appropriate defaults:
|
|
131
|
+
* - Thinking models (`-thinking` suffix) get temperature=1.0 locked
|
|
132
|
+
* - Thinking models get 32k default max_tokens to avoid truncation
|
|
133
|
+
* - K2.5 models get video input support
|
|
134
|
+
*
|
|
113
135
|
* @example
|
|
114
136
|
* ```ts
|
|
115
137
|
* const caps = inferModelCapabilities('kimi-k2.5-thinking');
|
|
116
|
-
* // {
|
|
138
|
+
* // {
|
|
139
|
+
* // thinking: true,
|
|
140
|
+
* // alwaysThinking: true,
|
|
141
|
+
* // videoInput: true,
|
|
142
|
+
* // temperatureLocked: true,
|
|
143
|
+
* // defaultTemperature: 1.0,
|
|
144
|
+
* // defaultMaxOutputTokens: 32768,
|
|
145
|
+
* // ...
|
|
146
|
+
* // }
|
|
117
147
|
* ```
|
|
118
148
|
*/
|
|
119
149
|
declare function inferModelCapabilities(modelId: string): KimiModelCapabilities;
|
|
@@ -287,7 +317,8 @@ declare const kimiTools: {
|
|
|
287
317
|
*
|
|
288
318
|
* @example
|
|
289
319
|
* ```ts
|
|
290
|
-
* import { kimi, kimiTools } from 'ai-sdk-provider
|
|
320
|
+
* import { kimi, kimiTools } from 'kimi-vercel-ai-sdk-provider
|
|
321
|
+
';
|
|
291
322
|
*
|
|
292
323
|
* const result = await generateText({
|
|
293
324
|
* model: kimi('kimi-k2.5'),
|
|
@@ -311,7 +342,8 @@ declare const kimiTools: {
|
|
|
311
342
|
*
|
|
312
343
|
* @example
|
|
313
344
|
* ```ts
|
|
314
|
-
* import { kimi, kimiTools } from 'ai-sdk-provider
|
|
345
|
+
* import { kimi, kimiTools } from 'kimi-vercel-ai-sdk-provider
|
|
346
|
+
';
|
|
315
347
|
*
|
|
316
348
|
* const result = await generateText({
|
|
317
349
|
* model: kimi('kimi-k2.5'),
|
|
@@ -486,6 +518,9 @@ declare class KimiChatLanguageModel implements LanguageModelV3 {
|
|
|
486
518
|
toolCalling?: boolean;
|
|
487
519
|
jsonMode?: boolean;
|
|
488
520
|
structuredOutputs?: boolean;
|
|
521
|
+
defaultTemperature?: number;
|
|
522
|
+
temperatureLocked?: boolean;
|
|
523
|
+
defaultMaxOutputTokens?: number;
|
|
489
524
|
};
|
|
490
525
|
get supportedUrls(): Record<string, RegExp[]> | PromiseLike<Record<string, RegExp[]>>;
|
|
491
526
|
private getArgs;
|
|
@@ -493,6 +528,107 @@ declare class KimiChatLanguageModel implements LanguageModelV3 {
|
|
|
493
528
|
doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult>;
|
|
494
529
|
}
|
|
495
530
|
|
|
531
|
+
/**
|
|
532
|
+
* File content caching for efficient re-use of uploaded files.
|
|
533
|
+
* @module
|
|
534
|
+
*/
|
|
535
|
+
/**
|
|
536
|
+
* Entry in the file cache.
|
|
537
|
+
*/
|
|
538
|
+
interface FileCacheEntry {
|
|
539
|
+
/** The Kimi file ID */
|
|
540
|
+
fileId: string;
|
|
541
|
+
/** Extracted text content (for documents) */
|
|
542
|
+
content?: string;
|
|
543
|
+
/** Unix timestamp of creation */
|
|
544
|
+
createdAt: number;
|
|
545
|
+
/** File purpose */
|
|
546
|
+
purpose: 'file-extract' | 'image' | 'video';
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Options for configuring the file cache.
|
|
550
|
+
*/
|
|
551
|
+
interface FileCacheOptions {
|
|
552
|
+
/**
|
|
553
|
+
* Maximum number of entries in the cache.
|
|
554
|
+
* When exceeded, least recently used entries are evicted.
|
|
555
|
+
* @default 100
|
|
556
|
+
*/
|
|
557
|
+
maxSize?: number;
|
|
558
|
+
/**
|
|
559
|
+
* Time-to-live for cache entries in milliseconds.
|
|
560
|
+
* Entries older than this are considered stale.
|
|
561
|
+
* @default 3600000 (1 hour)
|
|
562
|
+
*/
|
|
563
|
+
ttlMs?: number;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* A simple LRU (Least Recently Used) cache for file content.
|
|
567
|
+
*
|
|
568
|
+
* This cache helps avoid re-uploading the same files multiple times
|
|
569
|
+
* by storing the mapping between content hashes and Kimi file IDs.
|
|
570
|
+
*
|
|
571
|
+
* @example
|
|
572
|
+
* ```ts
|
|
573
|
+
* const cache = new FileCache({ maxSize: 50, ttlMs: 30 * 60 * 1000 });
|
|
574
|
+
*
|
|
575
|
+
* // Check if we have this file cached
|
|
576
|
+
* const cached = cache.get(contentHash);
|
|
577
|
+
* if (cached) {
|
|
578
|
+
* console.log('Using cached file:', cached.fileId);
|
|
579
|
+
* }
|
|
580
|
+
*
|
|
581
|
+
* // Store a new file
|
|
582
|
+
* cache.set(contentHash, {
|
|
583
|
+
* fileId: 'file_abc123',
|
|
584
|
+
* content: 'extracted text...',
|
|
585
|
+
* purpose: 'file-extract',
|
|
586
|
+
* createdAt: Date.now()
|
|
587
|
+
* });
|
|
588
|
+
* ```
|
|
589
|
+
*/
|
|
590
|
+
declare class FileCache {
|
|
591
|
+
private readonly maxSize;
|
|
592
|
+
private readonly ttlMs;
|
|
593
|
+
private readonly cache;
|
|
594
|
+
constructor(options?: FileCacheOptions);
|
|
595
|
+
/**
|
|
596
|
+
* Get a cached entry by content hash.
|
|
597
|
+
* Returns undefined if not found or expired.
|
|
598
|
+
* Moves the entry to the end (most recently used).
|
|
599
|
+
*/
|
|
600
|
+
get(contentHash: string): FileCacheEntry | undefined;
|
|
601
|
+
/**
|
|
602
|
+
* Set a cache entry.
|
|
603
|
+
* Evicts the least recently used entry if cache is full.
|
|
604
|
+
*/
|
|
605
|
+
set(contentHash: string, entry: FileCacheEntry): void;
|
|
606
|
+
/**
|
|
607
|
+
* Check if an entry exists and is not expired.
|
|
608
|
+
*/
|
|
609
|
+
has(contentHash: string): boolean;
|
|
610
|
+
/**
|
|
611
|
+
* Delete a specific entry.
|
|
612
|
+
*/
|
|
613
|
+
delete(contentHash: string): boolean;
|
|
614
|
+
/**
|
|
615
|
+
* Clear all entries.
|
|
616
|
+
*/
|
|
617
|
+
clear(): void;
|
|
618
|
+
/**
|
|
619
|
+
* Get the current cache size.
|
|
620
|
+
*/
|
|
621
|
+
get size(): number;
|
|
622
|
+
/**
|
|
623
|
+
* Remove all expired entries.
|
|
624
|
+
*/
|
|
625
|
+
prune(): number;
|
|
626
|
+
/**
|
|
627
|
+
* Check if an entry is expired.
|
|
628
|
+
*/
|
|
629
|
+
private isExpired;
|
|
630
|
+
}
|
|
631
|
+
|
|
496
632
|
/**
|
|
497
633
|
* Kimi File API client for uploading and managing files.
|
|
498
634
|
* @module
|
|
@@ -657,6 +793,13 @@ interface ProcessAttachmentsOptions {
|
|
|
657
793
|
uploadImages?: boolean;
|
|
658
794
|
/** Whether to delete files after extraction (cleanup) */
|
|
659
795
|
cleanupAfterExtract?: boolean;
|
|
796
|
+
/**
|
|
797
|
+
* Enable caching of uploaded files.
|
|
798
|
+
* When true, uses the default global cache.
|
|
799
|
+
* When a FileCache instance, uses that cache.
|
|
800
|
+
* @default false
|
|
801
|
+
*/
|
|
802
|
+
cache?: boolean | FileCache;
|
|
660
803
|
}
|
|
661
804
|
/**
|
|
662
805
|
* Process experimental_attachments for Kimi.
|
|
@@ -861,7 +1004,8 @@ interface KimiProvider extends Omit<ProviderV3, 'specificationVersion'> {
|
|
|
861
1004
|
*
|
|
862
1005
|
* @example
|
|
863
1006
|
* ```ts
|
|
864
|
-
* import { createKimi } from 'ai-sdk-provider
|
|
1007
|
+
* import { createKimi } from 'kimi-vercel-ai-sdk-provider
|
|
1008
|
+
';
|
|
865
1009
|
*
|
|
866
1010
|
* const kimi = createKimi({
|
|
867
1011
|
* apiKey: process.env.MOONSHOT_API_KEY,
|
|
@@ -899,7 +1043,8 @@ declare function createKimi(options?: KimiProviderSettings): KimiProvider;
|
|
|
899
1043
|
*
|
|
900
1044
|
* @example
|
|
901
1045
|
* ```ts
|
|
902
|
-
* import { kimi } from 'ai-sdk-provider
|
|
1046
|
+
* import { kimi } from 'kimi-vercel-ai-sdk-provider
|
|
1047
|
+
';
|
|
903
1048
|
*
|
|
904
1049
|
* const result = await generateText({
|
|
905
1050
|
* model: kimi('kimi-k2.5'),
|
|
@@ -1222,7 +1367,8 @@ interface KimiCodeProvider extends Omit<ProviderV3, 'specificationVersion'> {
|
|
|
1222
1367
|
*
|
|
1223
1368
|
* @example
|
|
1224
1369
|
* ```ts
|
|
1225
|
-
* import { createKimiCode } from 'ai-sdk-provider
|
|
1370
|
+
* import { createKimiCode } from 'kimi-vercel-ai-sdk-provider
|
|
1371
|
+
';
|
|
1226
1372
|
*
|
|
1227
1373
|
* const kimiCode = createKimiCode({
|
|
1228
1374
|
* apiKey: process.env.KIMI_CODE_API_KEY,
|
|
@@ -1265,7 +1411,8 @@ declare function createKimiCode(options?: KimiCodeProviderSettings): KimiCodePro
|
|
|
1265
1411
|
*
|
|
1266
1412
|
* @example
|
|
1267
1413
|
* ```ts
|
|
1268
|
-
* import { kimiCode } from 'ai-sdk-provider
|
|
1414
|
+
* import { kimiCode } from 'kimi-vercel-ai-sdk-provider
|
|
1415
|
+
';
|
|
1269
1416
|
*
|
|
1270
1417
|
* const result = await generateText({
|
|
1271
1418
|
* model: kimiCode(), // Uses default model
|