opencode-kimi-rotator 1.0.0 → 1.1.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 +432 -26
- package/bin/cli.js +340 -8
- package/dist/accounts.d.ts +7 -1
- package/dist/accounts.d.ts.map +1 -1
- package/dist/accounts.js +61 -7
- package/dist/accounts.js.map +1 -1
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +26 -10
- package/dist/plugin.js.map +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +5 -5
- package/dist/storage.js.map +1 -1
- package/dist/types.d.ts +22 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -1
- package/package.json +16 -5
- package/src/plugin.ts +47 -24
package/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Kimi API Key Rotator for OpenCode
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/opencode-kimi-rotator)
|
|
4
|
-
[](https://www.npmjs.com/package/opencode-kimi-rotator)
|
|
4
|
+
[](https://www.npmjs.com/package/opencode-kimi-rotator)
|
|
6
5
|
[](LICENSE)
|
|
7
6
|
|
|
8
7
|
Automatically rotate between multiple Kimi API keys to handle rate limits and distribute load across accounts.
|
|
@@ -26,7 +25,19 @@ Automatically rotate between multiple Kimi API keys to handle rate limits and di
|
|
|
26
25
|
<details open>
|
|
27
26
|
<summary><b>For Humans</b></summary>
|
|
28
27
|
|
|
29
|
-
**Option A:
|
|
28
|
+
**Option A: NPM (One-line installation)**
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g opencode-kimi-rotator
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
That's it! The plugin is automatically built and installed. Now add your API keys:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
opencode-kimi add-key sk-kimi-your-key-here "My Account"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Option B: Automatic Install Script**
|
|
30
41
|
|
|
31
42
|
```bash
|
|
32
43
|
curl -fsSL https://raw.githubusercontent.com/deyndev/opencode-kimi-rotator/main/scripts/install.sh | bash
|
|
@@ -38,7 +49,7 @@ Or for Windows (PowerShell):
|
|
|
38
49
|
irm https://raw.githubusercontent.com/deyndev/opencode-kimi-rotator/main/scripts/install.ps1 | iex
|
|
39
50
|
```
|
|
40
51
|
|
|
41
|
-
**Option
|
|
52
|
+
**Option C: Manual setup**
|
|
42
53
|
|
|
43
54
|
1. **Clone and build the plugin**:
|
|
44
55
|
|
|
@@ -60,9 +71,14 @@ irm https://raw.githubusercontent.com/deyndev/opencode-kimi-rotator/main/scripts
|
|
|
60
71
|
"models": {
|
|
61
72
|
"kimi-for-coding": {
|
|
62
73
|
"name": "Kimi K2.5 (via Kimi API)",
|
|
74
|
+
"attachment": true,
|
|
63
75
|
"limit": {
|
|
64
76
|
"context": 262144,
|
|
65
77
|
"output": 32768
|
|
78
|
+
},
|
|
79
|
+
"modalities": {
|
|
80
|
+
"input": ["text", "image", "video", "pdf"],
|
|
81
|
+
"output": ["text"]
|
|
66
82
|
}
|
|
67
83
|
}
|
|
68
84
|
}
|
|
@@ -106,16 +122,22 @@ Add the plugin to your existing config. The plugin path must use the full absolu
|
|
|
106
122
|
|
|
107
123
|
```json
|
|
108
124
|
{
|
|
109
|
-
"plugin": [
|
|
110
|
-
"file:///Users/YOUR_USERNAME/.config/opencode/plugins/kimi-rotator.js"
|
|
111
|
-
],
|
|
125
|
+
"plugin": ["file:///Users/YOUR_USERNAME/.config/opencode/plugins/kimi-rotator.js"],
|
|
112
126
|
"provider": {
|
|
113
127
|
"anthropic": {
|
|
114
128
|
"name": "Anthropic",
|
|
115
129
|
"models": {
|
|
116
130
|
"kimi-for-coding": {
|
|
117
131
|
"name": "Kimi K2.5 (via Kimi API)",
|
|
118
|
-
"
|
|
132
|
+
"attachment": true,
|
|
133
|
+
"limit": {
|
|
134
|
+
"context": 262144,
|
|
135
|
+
"output": 32768
|
|
136
|
+
},
|
|
137
|
+
"modalities": {
|
|
138
|
+
"input": ["text", "image", "video", "pdf"],
|
|
139
|
+
"output": ["text"]
|
|
140
|
+
}
|
|
119
141
|
}
|
|
120
142
|
}
|
|
121
143
|
}
|
|
@@ -124,6 +146,7 @@ Add the plugin to your existing config. The plugin path must use the full absolu
|
|
|
124
146
|
```
|
|
125
147
|
|
|
126
148
|
> **Important**: Replace `YOUR_USERNAME` with your actual username. Example paths:
|
|
149
|
+
>
|
|
127
150
|
> - macOS: `file:///Users/john/.config/opencode/plugins/kimi-rotator.js`
|
|
128
151
|
> - Linux: `file:///home/john/.config/opencode/plugins/kimi-rotator.js`
|
|
129
152
|
|
|
@@ -167,6 +190,7 @@ opencode-kimi list-keys
|
|
|
167
190
|
```
|
|
168
191
|
|
|
169
192
|
### What the plugin does automatically:
|
|
193
|
+
|
|
170
194
|
- Sets `ANTHROPIC_BASE_URL` to Kimi's API endpoint
|
|
171
195
|
- Intercepts fetch requests to `api.kimi.com`
|
|
172
196
|
- Rotates API keys based on health scores
|
|
@@ -174,7 +198,6 @@ opencode-kimi list-keys
|
|
|
174
198
|
|
|
175
199
|
</details>
|
|
176
200
|
|
|
177
|
-
|
|
178
201
|
---
|
|
179
202
|
|
|
180
203
|
## Models
|
|
@@ -183,13 +206,12 @@ opencode-kimi list-keys
|
|
|
183
206
|
|
|
184
207
|
The Kimi Coding API provides a single flagship model:
|
|
185
208
|
|
|
186
|
-
| Model ID
|
|
187
|
-
|
|
209
|
+
| Model ID | Name | Context | Output |
|
|
210
|
+
| ----------------- | --------- | ------- | ------ |
|
|
188
211
|
| `kimi-for-coding` | Kimi K2.5 | 262,144 | 32,768 |
|
|
189
212
|
|
|
190
213
|
Use it as: `anthropic/kimi-for-coding`
|
|
191
214
|
|
|
192
|
-
|
|
193
215
|
<details>
|
|
194
216
|
<summary><b>Full configuration (copy-paste ready)</b></summary>
|
|
195
217
|
|
|
@@ -198,21 +220,20 @@ Add this to your `~/.config/opencode/opencode.json`:
|
|
|
198
220
|
```json
|
|
199
221
|
{
|
|
200
222
|
"$schema": "https://opencode.ai/config.json",
|
|
201
|
-
"plugin": [
|
|
202
|
-
"file:///Users/YOUR_USERNAME/.config/opencode/plugins/kimi-rotator.js"
|
|
203
|
-
],
|
|
223
|
+
"plugin": ["file:///Users/YOUR_USERNAME/.config/opencode/plugins/kimi-rotator.js"],
|
|
204
224
|
"provider": {
|
|
205
225
|
"anthropic": {
|
|
206
226
|
"name": "Anthropic",
|
|
207
227
|
"models": {
|
|
208
228
|
"kimi-for-coding": {
|
|
209
229
|
"name": "Kimi K2.5 (via Kimi API)",
|
|
230
|
+
"attachment": true,
|
|
210
231
|
"limit": {
|
|
211
232
|
"context": 262144,
|
|
212
233
|
"output": 32768
|
|
213
234
|
},
|
|
214
235
|
"modalities": {
|
|
215
|
-
"input": ["text", "image", "video"],
|
|
236
|
+
"input": ["text", "image", "video", "pdf"],
|
|
216
237
|
"output": ["text"]
|
|
217
238
|
}
|
|
218
239
|
}
|
|
@@ -243,6 +264,7 @@ opencode-kimi list-keys
|
|
|
243
264
|
```
|
|
244
265
|
|
|
245
266
|
Output:
|
|
267
|
+
|
|
246
268
|
```
|
|
247
269
|
Kimi API Keys (2 total, strategy: health-based):
|
|
248
270
|
|
|
@@ -284,6 +306,64 @@ opencode-kimi set-strategy health-based
|
|
|
284
306
|
opencode-kimi set-strategy sticky
|
|
285
307
|
```
|
|
286
308
|
|
|
309
|
+
### View Usage Statistics
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
opencode-kimi stats
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Output:
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
📊 Usage Statistics
|
|
319
|
+
|
|
320
|
+
[0] My Account 1
|
|
321
|
+
Total Requests: 1425
|
|
322
|
+
Successful: 1227
|
|
323
|
+
Failed: 198
|
|
324
|
+
Success Rate: 86.1%
|
|
325
|
+
Avg Response Time: 245ms
|
|
326
|
+
Requests Today: 12
|
|
327
|
+
Requests Last 7 Days: 89
|
|
328
|
+
|
|
329
|
+
[1] My Account 2
|
|
330
|
+
Total Requests: 811
|
|
331
|
+
Successful: 793
|
|
332
|
+
Failed: 18
|
|
333
|
+
Success Rate: 97.8%
|
|
334
|
+
Avg Response Time: 198ms
|
|
335
|
+
Requests Today: 5
|
|
336
|
+
Requests Last 7 Days: 42
|
|
337
|
+
|
|
338
|
+
──────────────────────────────────────────────────
|
|
339
|
+
📈 Aggregate Statistics
|
|
340
|
+
Total Requests (All Keys): 2236
|
|
341
|
+
Total Successful: 2020
|
|
342
|
+
Overall Success Rate: 90.3%
|
|
343
|
+
Overall Avg Response Time: 221ms
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Health Auto-Refresh
|
|
347
|
+
|
|
348
|
+
Automatically restore health scores for rate-limited keys after a cooldown period.
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
# Check current auto-refresh settings
|
|
352
|
+
opencode-kimi list-keys
|
|
353
|
+
|
|
354
|
+
# Enable/disable auto-refresh (default: enabled)
|
|
355
|
+
opencode-kimi set-auto-refresh true
|
|
356
|
+
opencode-kimi set-auto-refresh false
|
|
357
|
+
|
|
358
|
+
# Set cooldown period in minutes (default: 30, range: 1-1440)
|
|
359
|
+
opencode-kimi set-cooldown 30
|
|
360
|
+
opencode-kimi set-cooldown 60 # 1 hour
|
|
361
|
+
opencode-kimi set-cooldown 180 # 3 hours
|
|
362
|
+
|
|
363
|
+
# Manually trigger health refresh
|
|
364
|
+
opencode-kimi refresh-health
|
|
365
|
+
```
|
|
366
|
+
|
|
287
367
|
---
|
|
288
368
|
|
|
289
369
|
## How It Works
|
|
@@ -291,6 +371,7 @@ opencode-kimi set-strategy sticky
|
|
|
291
371
|
### Health Score System
|
|
292
372
|
|
|
293
373
|
Each API key has a health score (0-100):
|
|
374
|
+
|
|
294
375
|
- **Initial**: 100
|
|
295
376
|
- **Success**: +2 points
|
|
296
377
|
- **Rate Limited**: -15 points
|
|
@@ -301,6 +382,7 @@ Keys with health score < 30 are temporarily skipped.
|
|
|
301
382
|
### Rate Limit Handling
|
|
302
383
|
|
|
303
384
|
When a key is rate limited:
|
|
385
|
+
|
|
304
386
|
1. Health score decreases
|
|
305
387
|
2. Key is marked as rate limited with reset time
|
|
306
388
|
3. Next request automatically uses next available key
|
|
@@ -309,6 +391,7 @@ When a key is rate limited:
|
|
|
309
391
|
### Data Storage
|
|
310
392
|
|
|
311
393
|
Keys are stored in `~/.config/opencode/kimi-accounts.json`:
|
|
394
|
+
|
|
312
395
|
```json
|
|
313
396
|
{
|
|
314
397
|
"version": 1,
|
|
@@ -322,14 +405,55 @@ Keys are stored in `~/.config/opencode/kimi-accounts.json`:
|
|
|
322
405
|
"healthScore": 100,
|
|
323
406
|
"consecutiveFailures": 0,
|
|
324
407
|
"totalRequests": 50,
|
|
325
|
-
"successfulRequests": 45
|
|
408
|
+
"successfulRequests": 45,
|
|
409
|
+
"responseTimes": [245, 198, 210],
|
|
410
|
+
"dailyRequests": {
|
|
411
|
+
"2026-01-31": 12,
|
|
412
|
+
"2026-02-01": 5
|
|
413
|
+
}
|
|
326
414
|
}
|
|
327
415
|
],
|
|
328
416
|
"activeIndex": 0,
|
|
329
|
-
"rotationStrategy": "health-based"
|
|
417
|
+
"rotationStrategy": "health-based",
|
|
418
|
+
"autoRefreshHealth": true,
|
|
419
|
+
"healthRefreshCooldownMinutes": 30
|
|
330
420
|
}
|
|
331
421
|
```
|
|
332
422
|
|
|
423
|
+
### Account Tracking
|
|
424
|
+
|
|
425
|
+
Each account tracks additional metrics for health-based rotation:
|
|
426
|
+
|
|
427
|
+
- **responseTimes** — Array of the last 100 response times (in milliseconds)
|
|
428
|
+
- **dailyRequests** — Record of request counts by date (YYYY-MM-DD format)
|
|
429
|
+
|
|
430
|
+
### Health Auto-Refresh Settings
|
|
431
|
+
|
|
432
|
+
- **autoRefreshHealth** — Whether to automatically refresh health scores after cooldown (default: `true`)
|
|
433
|
+
- **healthRefreshCooldownMinutes** — Minutes to wait before health can be refreshed (default: `30`, range: 1-1440)
|
|
434
|
+
|
|
435
|
+
When enabled, keys that were rate-limited will have their health score gradually restored (+10 points) after the cooldown period passes, making them available for rotation again.
|
|
436
|
+
|
|
437
|
+
### Export/Import Keys
|
|
438
|
+
|
|
439
|
+
Backup and migrate your API keys between machines using encrypted files.
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
# Export all keys to an encrypted file
|
|
443
|
+
opencode-kimi export-keys
|
|
444
|
+
opencode-kimi export-keys my-backup.json.enc
|
|
445
|
+
|
|
446
|
+
# Import keys from an encrypted file
|
|
447
|
+
opencode-kimi import-keys my-backup.json.enc
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
**Features:**
|
|
451
|
+
|
|
452
|
+
- AES-256-GCM encryption with password protection
|
|
453
|
+
- Exports all keys, settings, and statistics
|
|
454
|
+
- Duplicate keys are skipped during import
|
|
455
|
+
- Rotation strategy and auto-refresh settings are preserved
|
|
456
|
+
|
|
333
457
|
---
|
|
334
458
|
|
|
335
459
|
## Configuration
|
|
@@ -338,10 +462,10 @@ Keys are stored in `~/.config/opencode/kimi-accounts.json`:
|
|
|
338
462
|
|
|
339
463
|
OpenCode uses `~/.config/opencode/` on **all platforms** including Windows.
|
|
340
464
|
|
|
341
|
-
| File
|
|
342
|
-
|
|
343
|
-
| Main config | `~/.config/opencode/opencode.json`
|
|
344
|
-
| Accounts
|
|
465
|
+
| File | Path |
|
|
466
|
+
| ----------- | --------------------------------------- |
|
|
467
|
+
| Main config | `~/.config/opencode/opencode.json` |
|
|
468
|
+
| Accounts | `~/.config/opencode/kimi-accounts.json` |
|
|
345
469
|
|
|
346
470
|
> **Windows users**: `~` resolves to your user home directory (e.g., `C:\Users\YourName`). Do NOT use `%APPDATA%`.
|
|
347
471
|
|
|
@@ -377,6 +501,7 @@ To use Kimi models with Oh My OpenCode agents, update `~/.config/opencode/oh-my-
|
|
|
377
501
|
### "No Kimi API keys configured"
|
|
378
502
|
|
|
379
503
|
Run:
|
|
504
|
+
|
|
380
505
|
```bash
|
|
381
506
|
opencode-kimi add-key your-api-key
|
|
382
507
|
```
|
|
@@ -384,6 +509,7 @@ opencode-kimi add-key your-api-key
|
|
|
384
509
|
### All keys rate limited
|
|
385
510
|
|
|
386
511
|
The plugin will wait for the soonest available key. You can:
|
|
512
|
+
|
|
387
513
|
1. Wait for rate limits to reset
|
|
388
514
|
2. Add more API keys
|
|
389
515
|
3. Check status with `opencode-kimi list-keys`
|
|
@@ -397,6 +523,7 @@ The plugin will wait for the soonest available key. You can:
|
|
|
397
523
|
### Reset Everything
|
|
398
524
|
|
|
399
525
|
If you need to start fresh:
|
|
526
|
+
|
|
400
527
|
```bash
|
|
401
528
|
rm ~/.config/opencode/kimi-accounts.json
|
|
402
529
|
opencode-kimi add-key your-new-api-key
|
|
@@ -412,10 +539,7 @@ Both plugins can work together. List them in your preferred order:
|
|
|
412
539
|
|
|
413
540
|
```json
|
|
414
541
|
{
|
|
415
|
-
"plugin": [
|
|
416
|
-
"opencode-kimi-rotator@latest",
|
|
417
|
-
"opencode-antigravity-auth@latest"
|
|
418
|
-
]
|
|
542
|
+
"plugin": ["opencode-kimi-rotator@latest", "opencode-antigravity-auth@latest"]
|
|
419
543
|
}
|
|
420
544
|
```
|
|
421
545
|
|
|
@@ -458,23 +582,27 @@ irm https://raw.githubusercontent.com/deyndev/opencode-kimi-rotator/main/scripts
|
|
|
458
582
|
### Local Development Setup
|
|
459
583
|
|
|
460
584
|
1. Clone the repository:
|
|
585
|
+
|
|
461
586
|
```bash
|
|
462
587
|
git clone https://github.com/deyndev/opencode-kimi-rotator.git
|
|
463
588
|
cd opencode-kimi-rotator
|
|
464
589
|
```
|
|
465
590
|
|
|
466
591
|
2. Install dependencies and build:
|
|
592
|
+
|
|
467
593
|
```bash
|
|
468
594
|
npm install
|
|
469
595
|
npm run build
|
|
470
596
|
```
|
|
471
597
|
|
|
472
598
|
3. Link for local testing:
|
|
599
|
+
|
|
473
600
|
```bash
|
|
474
601
|
npm link
|
|
475
602
|
```
|
|
476
603
|
|
|
477
604
|
4. Add to your OpenCode config:
|
|
605
|
+
|
|
478
606
|
```json
|
|
479
607
|
{
|
|
480
608
|
"plugin": ["opencode-kimi-rotator"]
|
|
@@ -483,6 +611,284 @@ npm link
|
|
|
483
611
|
|
|
484
612
|
---
|
|
485
613
|
|
|
614
|
+
## Public API
|
|
615
|
+
|
|
616
|
+
### `KimiAccountManager`
|
|
617
|
+
|
|
618
|
+
Main class for managing Kimi API key rotation.
|
|
619
|
+
|
|
620
|
+
#### Methods
|
|
621
|
+
|
|
622
|
+
##### `markAccountSuccess(index, responseTime?, date?)`
|
|
623
|
+
|
|
624
|
+
Marks an account as successfully used and updates health metrics.
|
|
625
|
+
|
|
626
|
+
```typescript
|
|
627
|
+
async markAccountSuccess(
|
|
628
|
+
index: number,
|
|
629
|
+
responseTime?: number,
|
|
630
|
+
date?: string
|
|
631
|
+
): Promise<void>
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
- **index** — Account index in the accounts array
|
|
635
|
+
- **responseTime** — Optional response time in milliseconds (tracked in rolling window of 100)
|
|
636
|
+
- **date** — Optional date string (YYYY-MM-DD) for daily request tracking
|
|
637
|
+
|
|
638
|
+
##### `setAutoRefreshHealth(enabled)`
|
|
639
|
+
|
|
640
|
+
Enables or disables automatic health score refresh.
|
|
641
|
+
|
|
642
|
+
```typescript
|
|
643
|
+
async setAutoRefreshHealth(enabled: boolean): Promise<void>
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
##### `setHealthRefreshCooldown(minutes)`
|
|
647
|
+
|
|
648
|
+
Sets the cooldown period for health refresh.
|
|
649
|
+
|
|
650
|
+
```typescript
|
|
651
|
+
async setHealthRefreshCooldown(minutes: number): Promise<void>
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
- **minutes** — Cooldown duration (1-1440, default: 30)
|
|
655
|
+
- **Throws** — Error if minutes is outside valid range
|
|
656
|
+
|
|
657
|
+
##### `refreshHealthScores()`
|
|
658
|
+
|
|
659
|
+
Manually triggers health score refresh for eligible accounts.
|
|
660
|
+
|
|
661
|
+
```typescript
|
|
662
|
+
async refreshHealthScores(): Promise<{
|
|
663
|
+
refreshed: number;
|
|
664
|
+
details: string[];
|
|
665
|
+
}>
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
Returns the number of accounts refreshed and detailed change log.
|
|
669
|
+
|
|
670
|
+
### `KimiStorage`
|
|
671
|
+
|
|
672
|
+
Handles persistent storage of account configuration with file locking.
|
|
673
|
+
|
|
674
|
+
#### Constructor
|
|
675
|
+
|
|
676
|
+
```typescript
|
|
677
|
+
constructor();
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
Creates a new storage instance. The config directory is automatically set to `~/.config/opencode/`.
|
|
681
|
+
|
|
682
|
+
#### Methods
|
|
683
|
+
|
|
684
|
+
##### `init()`
|
|
685
|
+
|
|
686
|
+
Initializes the storage directory and files.
|
|
687
|
+
|
|
688
|
+
```typescript
|
|
689
|
+
async init(): Promise<void>
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
Creates the config directory if it doesn't exist and initializes an empty accounts file.
|
|
693
|
+
|
|
694
|
+
##### `loadConfig()`
|
|
695
|
+
|
|
696
|
+
Loads and validates the accounts configuration.
|
|
697
|
+
|
|
698
|
+
```typescript
|
|
699
|
+
async loadConfig(): Promise<KimiAccountsConfig>
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
- **Returns** — Parsed and validated configuration
|
|
703
|
+
- **Throws** — Error if file cannot be read or parsed
|
|
704
|
+
|
|
705
|
+
##### `saveConfig(config)`
|
|
706
|
+
|
|
707
|
+
Saves the configuration to disk with file locking.
|
|
708
|
+
|
|
709
|
+
```typescript
|
|
710
|
+
async saveConfig(config: KimiAccountsConfig): Promise<void>
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
- **config** — Configuration object to save
|
|
714
|
+
- **Throws** — Error if validation fails or file cannot be written
|
|
715
|
+
|
|
716
|
+
##### `addAccount(key, name?)`
|
|
717
|
+
|
|
718
|
+
Adds a new API key account.
|
|
719
|
+
|
|
720
|
+
```typescript
|
|
721
|
+
async addAccount(key: string, name?: string): Promise<KimiAccount>
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
- **key** — The API key to store
|
|
725
|
+
- **name** — Optional display name for the account
|
|
726
|
+
- **Returns** — The created account object
|
|
727
|
+
- **Throws** — Error if the key already exists
|
|
728
|
+
|
|
729
|
+
##### `removeAccount(index)`
|
|
730
|
+
|
|
731
|
+
Removes an account by index.
|
|
732
|
+
|
|
733
|
+
```typescript
|
|
734
|
+
async removeAccount(index: number): Promise<void>
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
- **index** — Account index to remove
|
|
738
|
+
- **Throws** — Error if index is invalid
|
|
739
|
+
|
|
740
|
+
##### `listAccounts()`
|
|
741
|
+
|
|
742
|
+
Returns all stored accounts.
|
|
743
|
+
|
|
744
|
+
```typescript
|
|
745
|
+
async listAccounts(): Promise<KimiAccount[]>
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
##### `getActiveAccount()`
|
|
749
|
+
|
|
750
|
+
Returns the currently active account.
|
|
751
|
+
|
|
752
|
+
```typescript
|
|
753
|
+
async getActiveAccount(): Promise<KimiAccount | null>
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
- **Returns** — The active account or `null` if no accounts exist
|
|
757
|
+
|
|
758
|
+
##### `setActiveIndex(index)`
|
|
759
|
+
|
|
760
|
+
Sets the active account index.
|
|
761
|
+
|
|
762
|
+
```typescript
|
|
763
|
+
async setActiveIndex(index: number): Promise<void>
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
- **index** — Account index to set as active
|
|
767
|
+
- **Throws** — Error if index is invalid
|
|
768
|
+
|
|
769
|
+
##### `updateAccount(index, updates)`
|
|
770
|
+
|
|
771
|
+
Updates specific fields of an account.
|
|
772
|
+
|
|
773
|
+
```typescript
|
|
774
|
+
async updateAccount(index: number, updates: Partial<KimiAccount>): Promise<void>
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
- **index** — Account index to update
|
|
778
|
+
- **updates** — Partial account object with fields to update
|
|
779
|
+
- **Throws** — Error if index is invalid
|
|
780
|
+
|
|
781
|
+
### Schemas
|
|
782
|
+
|
|
783
|
+
#### `KimiAccountSchema`
|
|
784
|
+
|
|
785
|
+
Zod schema for validating Kimi account objects:
|
|
786
|
+
|
|
787
|
+
```javascript
|
|
788
|
+
{
|
|
789
|
+
key: string, // API key (required)
|
|
790
|
+
name: string, // Optional account name
|
|
791
|
+
addedAt: number, // Timestamp when added
|
|
792
|
+
lastUsed: number, // Timestamp of last use
|
|
793
|
+
rateLimitResetTime: number, // Default: 0
|
|
794
|
+
healthScore: number, // 0-100, default: 100
|
|
795
|
+
consecutiveFailures: number, // Default: 0
|
|
796
|
+
totalRequests: number, // Default: 0
|
|
797
|
+
successfulRequests: number, // Default: 0
|
|
798
|
+
responseTimes: number[], // Array of response times (ms)
|
|
799
|
+
dailyRequests: Record<string, number> // Requests per day
|
|
800
|
+
}
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
#### `KimiAccountsConfigSchema`
|
|
804
|
+
|
|
805
|
+
Zod schema for the accounts configuration:
|
|
806
|
+
|
|
807
|
+
```javascript
|
|
808
|
+
{
|
|
809
|
+
version: number, // Default: 1
|
|
810
|
+
accounts: KimiAccount[], // Array of accounts
|
|
811
|
+
activeIndex: number, // Default: 0
|
|
812
|
+
rotationStrategy: 'round-robin' | 'health-based' | 'sticky',
|
|
813
|
+
autoRefreshHealth: boolean, // Default: true
|
|
814
|
+
healthRefreshCooldownMinutes: number // Default: 30, range: 1-1440
|
|
815
|
+
}
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
### Types
|
|
819
|
+
|
|
820
|
+
- `KimiAccount` — Inferred type from `KimiAccountSchema`
|
|
821
|
+
- `KimiAccountsConfig` — Inferred type from `KimiAccountsConfigSchema`
|
|
822
|
+
|
|
823
|
+
### Constants
|
|
824
|
+
|
|
825
|
+
#### `DEFAULT_ACCOUNT`
|
|
826
|
+
|
|
827
|
+
Default values for new accounts (excludes `key`, `addedAt`, `lastUsed`):
|
|
828
|
+
|
|
829
|
+
```javascript
|
|
830
|
+
{
|
|
831
|
+
rateLimitResetTime: 0,
|
|
832
|
+
healthScore: 100,
|
|
833
|
+
consecutiveFailures: 0,
|
|
834
|
+
totalRequests: 0,
|
|
835
|
+
successfulRequests: 0,
|
|
836
|
+
responseTimes: [],
|
|
837
|
+
dailyRequests: {}
|
|
838
|
+
}
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
#### `DEFAULT_CONFIG`
|
|
842
|
+
|
|
843
|
+
Default configuration values (excludes `accounts`):
|
|
844
|
+
|
|
845
|
+
```javascript
|
|
846
|
+
{
|
|
847
|
+
version: 1,
|
|
848
|
+
activeIndex: 0,
|
|
849
|
+
rotationStrategy: 'health-based',
|
|
850
|
+
autoRefreshHealth: true,
|
|
851
|
+
healthRefreshCooldownMinutes: 30
|
|
852
|
+
}
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
---
|
|
856
|
+
|
|
486
857
|
## License
|
|
487
858
|
|
|
488
859
|
MIT License. See [LICENSE](LICENSE) for details.
|
|
860
|
+
|
|
861
|
+
<details>
|
|
862
|
+
<summary><b>Legal</b></summary>
|
|
863
|
+
|
|
864
|
+
### Intended Use
|
|
865
|
+
|
|
866
|
+
- Personal / internal development only
|
|
867
|
+
- Respect internal quotas and data handling policies
|
|
868
|
+
- Not for production services or bypassing intended limits
|
|
869
|
+
|
|
870
|
+
### Warning
|
|
871
|
+
|
|
872
|
+
By using this plugin, you acknowledge:
|
|
873
|
+
|
|
874
|
+
- **Terms of Service risk** — This approach may violate ToS of AI model providers
|
|
875
|
+
- **Account risk** — Providers may suspend or ban accounts
|
|
876
|
+
- **No guarantees** — APIs may change without notice
|
|
877
|
+
- **Assumption of risk** — You assume all legal, financial, and technical risks
|
|
878
|
+
|
|
879
|
+
### Disclaimer
|
|
880
|
+
|
|
881
|
+
- Not affiliated with Moonshot AI. This is an independent open-source project.
|
|
882
|
+
- "Kimi", "Moonshot", and "Moonshot AI" are trademarks of Moonshot AI.
|
|
883
|
+
|
|
884
|
+
</details>
|
|
885
|
+
|
|
886
|
+
---
|
|
887
|
+
|
|
888
|
+
## Contributors
|
|
889
|
+
|
|
890
|
+
Thanks to all the people who already contributed!
|
|
891
|
+
|
|
892
|
+
<a href="https://github.com/deyndev/opencode-kimi-rotator/graphs/contributors">
|
|
893
|
+
<img src="https://contributors-img.web.app/image?repo=deyndev/opencode-kimi-rotator&max=750&columns=20" />
|
|
894
|
+
</a>
|