@ottocode/sdk 0.1.311 → 0.1.313

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.
@@ -2170,6 +2170,32 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
2170
2170
  openrouter: {
2171
2171
  id: 'openrouter',
2172
2172
  models: [
2173
+ {
2174
+ id: '~anthropic/claude-fable-latest',
2175
+ ownedBy: 'anthropic',
2176
+ label: 'Claude Fable Latest',
2177
+ modalities: {
2178
+ input: ['text', 'image', 'pdf'],
2179
+ output: ['text'],
2180
+ },
2181
+ toolCall: true,
2182
+ reasoningText: true,
2183
+ attachment: true,
2184
+ temperature: false,
2185
+ releaseDate: '2026-06-09',
2186
+ lastUpdated: '2026-06-09',
2187
+ openWeights: false,
2188
+ cost: {
2189
+ input: 10,
2190
+ output: 50,
2191
+ cacheRead: 1,
2192
+ cacheWrite: 12.5,
2193
+ },
2194
+ limit: {
2195
+ context: 1000000,
2196
+ output: 128000,
2197
+ },
2198
+ },
2173
2199
  {
2174
2200
  id: '~anthropic/claude-haiku-latest',
2175
2201
  ownedBy: 'anthropic',
@@ -2575,6 +2601,33 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
2575
2601
  output: 8192,
2576
2602
  },
2577
2603
  },
2604
+ {
2605
+ id: 'anthropic/claude-fable-5',
2606
+ ownedBy: 'anthropic',
2607
+ label: 'Claude Fable 5',
2608
+ modalities: {
2609
+ input: ['text', 'image', 'pdf'],
2610
+ output: ['text'],
2611
+ },
2612
+ toolCall: true,
2613
+ reasoningText: true,
2614
+ attachment: true,
2615
+ temperature: false,
2616
+ knowledge: '2026-01-31',
2617
+ releaseDate: '2026-06-09',
2618
+ lastUpdated: '2026-06-09',
2619
+ openWeights: false,
2620
+ cost: {
2621
+ input: 10,
2622
+ output: 50,
2623
+ cacheRead: 1,
2624
+ cacheWrite: 12.5,
2625
+ },
2626
+ limit: {
2627
+ context: 1000000,
2628
+ output: 128000,
2629
+ },
2630
+ },
2578
2631
  {
2579
2632
  id: 'anthropic/claude-haiku-4.5',
2580
2633
  ownedBy: 'anthropic',
@@ -3345,12 +3398,12 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
3345
3398
  lastUpdated: '2026-04-24',
3346
3399
  openWeights: true,
3347
3400
  cost: {
3348
- input: 0.0983,
3349
- output: 0.1966,
3350
- cacheRead: 0.0197,
3401
+ input: 0.098,
3402
+ output: 0.196,
3403
+ cacheRead: 0.02,
3351
3404
  },
3352
3405
  limit: {
3353
- context: 1048576,
3406
+ context: 1048575,
3354
3407
  output: 131072,
3355
3408
  },
3356
3409
  },
@@ -3415,8 +3468,8 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
3415
3468
  attachment: true,
3416
3469
  temperature: true,
3417
3470
  knowledge: '2025-01',
3418
- releaseDate: '2025-03-20',
3419
- lastUpdated: '2025-06-05',
3471
+ releaseDate: '2025-06-17',
3472
+ lastUpdated: '2025-06-17',
3420
3473
  openWeights: false,
3421
3474
  cost: {
3422
3475
  input: 0.3,
@@ -3496,8 +3549,8 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
3496
3549
  attachment: true,
3497
3550
  temperature: true,
3498
3551
  knowledge: '2025-01',
3499
- releaseDate: '2025-03-20',
3500
- lastUpdated: '2025-06-05',
3552
+ releaseDate: '2025-06-17',
3553
+ lastUpdated: '2025-06-17',
3501
3554
  openWeights: false,
3502
3555
  cost: {
3503
3556
  input: 1.25,
@@ -3841,12 +3894,12 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
3841
3894
  openWeights: true,
3842
3895
  cost: {
3843
3896
  input: 0.12,
3844
- output: 0.36,
3897
+ output: 0.35,
3845
3898
  cacheRead: 0.09,
3846
3899
  },
3847
3900
  limit: {
3848
- context: 256000,
3849
- output: 8192,
3901
+ context: 262144,
3902
+ output: 262144,
3850
3903
  },
3851
3904
  },
3852
3905
  {
@@ -4253,7 +4306,8 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
4253
4306
  openWeights: true,
4254
4307
  cost: {
4255
4308
  input: 0.15,
4256
- output: 1.15,
4309
+ output: 0.9,
4310
+ cacheRead: 0.05,
4257
4311
  },
4258
4312
  limit: {
4259
4313
  context: 196608,
@@ -4276,12 +4330,13 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
4276
4330
  lastUpdated: '2026-03-18',
4277
4331
  openWeights: true,
4278
4332
  cost: {
4279
- input: 0.279,
4280
- output: 1.2,
4333
+ input: 0.25,
4334
+ output: 1,
4335
+ cacheRead: 0.05,
4281
4336
  },
4282
4337
  limit: {
4283
4338
  context: 196608,
4284
- output: 196608,
4339
+ output: 131072,
4285
4340
  },
4286
4341
  },
4287
4342
  {
@@ -4818,12 +4873,11 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
4818
4873
  lastUpdated: '2026-01',
4819
4874
  openWeights: true,
4820
4875
  cost: {
4821
- input: 0.4,
4822
- output: 1.9,
4823
- cacheRead: 0.09,
4876
+ input: 0.375,
4877
+ output: 2.025,
4824
4878
  },
4825
4879
  limit: {
4826
- context: 262144,
4880
+ context: 256000,
4827
4881
  output: 262144,
4828
4882
  },
4829
4883
  },
@@ -4854,9 +4908,9 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
4854
4908
  },
4855
4909
  },
4856
4910
  {
4857
- id: 'moonshotai/kimi-k2.6:free',
4911
+ id: 'moonshotai/kimi-k2.7-code',
4858
4912
  ownedBy: 'moonshot',
4859
- label: 'Kimi K2.6 (free)',
4913
+ label: 'Kimi K2.7 Code',
4860
4914
  modalities: {
4861
4915
  input: ['text', 'image'],
4862
4916
  output: ['text'],
@@ -4864,14 +4918,15 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
4864
4918
  toolCall: true,
4865
4919
  reasoningText: true,
4866
4920
  attachment: true,
4867
- temperature: false,
4921
+ temperature: true,
4868
4922
  knowledge: '2025-01',
4869
- releaseDate: '2026-04-21',
4870
- lastUpdated: '2026-04-21',
4923
+ releaseDate: '2026-06-12',
4924
+ lastUpdated: '2026-06-12',
4871
4925
  openWeights: true,
4872
4926
  cost: {
4873
- input: 0,
4874
- output: 0,
4927
+ input: 0.75,
4928
+ output: 3.5,
4929
+ cacheRead: 0.16,
4875
4930
  },
4876
4931
  limit: {
4877
4932
  context: 262144,
@@ -5109,29 +5164,6 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
5109
5164
  output: 128000,
5110
5165
  },
5111
5166
  },
5112
- {
5113
- id: 'nvidia/nemotron-nano-9b-v2',
5114
- label: 'Nemotron Nano 9B v2',
5115
- modalities: {
5116
- input: ['text'],
5117
- output: ['text'],
5118
- },
5119
- toolCall: true,
5120
- reasoningText: true,
5121
- attachment: false,
5122
- temperature: true,
5123
- releaseDate: '2025-08-18',
5124
- lastUpdated: '2025-08-18',
5125
- openWeights: true,
5126
- cost: {
5127
- input: 0.04,
5128
- output: 0.16,
5129
- },
5130
- limit: {
5131
- context: 131072,
5132
- output: 16384,
5133
- },
5134
- },
5135
5167
  {
5136
5168
  id: 'nvidia/nemotron-nano-9b-v2:free',
5137
5169
  label: 'Nemotron Nano 9B V2 (free)',
@@ -7626,12 +7658,12 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
7626
7658
  lastUpdated: '2026-04-22',
7627
7659
  openWeights: true,
7628
7660
  cost: {
7629
- input: 0.289,
7630
- output: 2.4,
7661
+ input: 0.2885,
7662
+ output: 3.17,
7631
7663
  },
7632
7664
  limit: {
7633
- context: 131072,
7634
- output: 131072,
7665
+ context: 262140,
7666
+ output: 262140,
7635
7667
  },
7636
7668
  },
7637
7669
  {
@@ -7649,12 +7681,13 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
7649
7681
  lastUpdated: '2026-04-17',
7650
7682
  openWeights: true,
7651
7683
  cost: {
7652
- input: 0.14,
7684
+ input: 0.15,
7653
7685
  output: 1,
7686
+ cacheRead: 0.05,
7654
7687
  },
7655
7688
  limit: {
7656
- context: 262140,
7657
- output: 262140,
7689
+ context: 262144,
7690
+ output: 262144,
7658
7691
  },
7659
7692
  },
7660
7693
  {
@@ -7772,10 +7805,10 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
7772
7805
  lastUpdated: '2026-06-02',
7773
7806
  openWeights: false,
7774
7807
  cost: {
7775
- input: 0.4,
7776
- output: 1.6,
7777
- cacheRead: 0.08,
7778
- cacheWrite: 0.5,
7808
+ input: 0.32,
7809
+ output: 1.28,
7810
+ cacheRead: 0.064,
7811
+ cacheWrite: 0.4,
7779
7812
  },
7780
7813
  limit: {
7781
7814
  context: 1000000,
@@ -8149,31 +8182,6 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
8149
8182
  output: 131072,
8150
8183
  },
8151
8184
  },
8152
- {
8153
- id: 'z-ai/glm-4-32b',
8154
- ownedBy: 'zai',
8155
- label: 'GLM 4 32B ',
8156
- modalities: {
8157
- input: ['text'],
8158
- output: ['text'],
8159
- },
8160
- toolCall: true,
8161
- reasoningText: false,
8162
- attachment: false,
8163
- temperature: true,
8164
- knowledge: '2024-06-30',
8165
- releaseDate: '2025-07-24',
8166
- lastUpdated: '2025-07-24',
8167
- openWeights: false,
8168
- cost: {
8169
- input: 0.1,
8170
- output: 0.1,
8171
- },
8172
- limit: {
8173
- context: 128000,
8174
- output: 128000,
8175
- },
8176
- },
8177
8185
  {
8178
8186
  id: 'z-ai/glm-4.5',
8179
8187
  ownedBy: 'zai',
@@ -8226,31 +8234,6 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
8226
8234
  output: 131070,
8227
8235
  },
8228
8236
  },
8229
- {
8230
- id: 'z-ai/glm-4.5-air:free',
8231
- ownedBy: 'zai',
8232
- label: 'GLM 4.5 Air (free)',
8233
- modalities: {
8234
- input: ['text'],
8235
- output: ['text'],
8236
- },
8237
- toolCall: true,
8238
- reasoningText: true,
8239
- attachment: false,
8240
- temperature: true,
8241
- knowledge: '2025-04',
8242
- releaseDate: '2025-07-28',
8243
- lastUpdated: '2025-07-28',
8244
- openWeights: true,
8245
- cost: {
8246
- input: 0,
8247
- output: 0,
8248
- },
8249
- limit: {
8250
- context: 131072,
8251
- output: 96000,
8252
- },
8253
- },
8254
8237
  {
8255
8238
  id: 'z-ai/glm-4.5v',
8256
8239
  ownedBy: 'zai',
@@ -8322,11 +8305,11 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
8322
8305
  cost: {
8323
8306
  input: 0.3,
8324
8307
  output: 0.9,
8325
- cacheRead: 0.05,
8308
+ cacheRead: 0.055,
8326
8309
  },
8327
8310
  limit: {
8328
8311
  context: 131072,
8329
- output: 24000,
8312
+ output: 32768,
8330
8313
  },
8331
8314
  },
8332
8315
  {
@@ -8427,7 +8410,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
8427
8410
  cacheRead: 0.24,
8428
8411
  },
8429
8412
  limit: {
8430
- context: 202752,
8413
+ context: 262144,
8431
8414
  output: 131072,
8432
8415
  },
8433
8416
  },
@@ -8456,31 +8439,6 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
8456
8439
  output: 131072,
8457
8440
  },
8458
8441
  },
8459
- {
8460
- id: 'z-ai/glm-5v-turbo',
8461
- ownedBy: 'zai',
8462
- label: 'GLM-5V-Turbo',
8463
- modalities: {
8464
- input: ['image', 'text', 'video'],
8465
- output: ['text'],
8466
- },
8467
- toolCall: true,
8468
- reasoningText: true,
8469
- attachment: true,
8470
- temperature: true,
8471
- releaseDate: '2026-04-01',
8472
- lastUpdated: '2026-04-01',
8473
- openWeights: false,
8474
- cost: {
8475
- input: 1.2,
8476
- output: 4,
8477
- cacheRead: 0.24,
8478
- },
8479
- limit: {
8480
- context: 202752,
8481
- output: 131072,
8482
- },
8483
- },
8484
8442
  ],
8485
8443
  label: 'OpenRouter',
8486
8444
  env: ['OPENROUTER_API_KEY'],
@@ -8547,6 +8505,36 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
8547
8505
  npm: '@ai-sdk/anthropic',
8548
8506
  },
8549
8507
  },
8508
+ {
8509
+ id: 'claude-fable-5',
8510
+ ownedBy: 'anthropic',
8511
+ label: 'Claude Fable 5',
8512
+ modalities: {
8513
+ input: ['text', 'image', 'pdf'],
8514
+ output: ['text'],
8515
+ },
8516
+ toolCall: true,
8517
+ reasoningText: true,
8518
+ attachment: true,
8519
+ temperature: false,
8520
+ knowledge: '2026-01-31',
8521
+ releaseDate: '2026-06-09',
8522
+ lastUpdated: '2026-06-09',
8523
+ openWeights: false,
8524
+ cost: {
8525
+ input: 10,
8526
+ output: 50,
8527
+ cacheRead: 1,
8528
+ cacheWrite: 12.5,
8529
+ },
8530
+ limit: {
8531
+ context: 1000000,
8532
+ output: 128000,
8533
+ },
8534
+ provider: {
8535
+ npm: '@ai-sdk/anthropic',
8536
+ },
8537
+ },
8550
8538
  {
8551
8539
  id: 'claude-haiku-4-5',
8552
8540
  ownedBy: 'anthropic',
@@ -8834,7 +8822,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
8834
8822
  cost: {
8835
8823
  input: 0.14,
8836
8824
  output: 0.28,
8837
- cacheRead: 0.03,
8825
+ cacheRead: 0.028,
8838
8826
  },
8839
8827
  limit: {
8840
8828
  context: 1000000,
@@ -8866,6 +8854,31 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
8866
8854
  output: 128000,
8867
8855
  },
8868
8856
  },
8857
+ {
8858
+ id: 'deepseek-v4-pro',
8859
+ label: 'DeepSeek V4 Pro',
8860
+ modalities: {
8861
+ input: ['text'],
8862
+ output: ['text'],
8863
+ },
8864
+ toolCall: true,
8865
+ reasoningText: true,
8866
+ attachment: false,
8867
+ temperature: true,
8868
+ knowledge: '2025-05',
8869
+ releaseDate: '2026-04-24',
8870
+ lastUpdated: '2026-04-24',
8871
+ openWeights: true,
8872
+ cost: {
8873
+ input: 1.74,
8874
+ output: 3.84,
8875
+ cacheRead: 0.145,
8876
+ },
8877
+ limit: {
8878
+ context: 1000000,
8879
+ output: 384000,
8880
+ },
8881
+ },
8869
8882
  {
8870
8883
  id: 'gemini-3-flash',
8871
8884
  ownedBy: 'google',
@@ -10936,6 +10949,32 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
10936
10949
  output: 131072,
10937
10950
  },
10938
10951
  },
10952
+ {
10953
+ id: 'glm-5.2',
10954
+ ownedBy: 'zai',
10955
+ label: 'GLM-5.2',
10956
+ modalities: {
10957
+ input: ['text'],
10958
+ output: ['text'],
10959
+ },
10960
+ toolCall: true,
10961
+ reasoningText: true,
10962
+ attachment: false,
10963
+ temperature: true,
10964
+ releaseDate: '2026-06-13',
10965
+ lastUpdated: '2026-06-13',
10966
+ openWeights: false,
10967
+ cost: {
10968
+ input: 0,
10969
+ output: 0,
10970
+ cacheRead: 0,
10971
+ cacheWrite: 0,
10972
+ },
10973
+ limit: {
10974
+ context: 1000000,
10975
+ output: 131072,
10976
+ },
10977
+ },
10939
10978
  {
10940
10979
  id: 'glm-5v-turbo',
10941
10980
  ownedBy: 'zai',
@@ -11154,12 +11193,38 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
11154
11193
  output: 262144,
11155
11194
  },
11156
11195
  },
11196
+ {
11197
+ id: 'kimi-k2.7-code',
11198
+ ownedBy: 'moonshot',
11199
+ label: 'Kimi K2.7 Code',
11200
+ modalities: {
11201
+ input: ['text', 'image', 'video'],
11202
+ output: ['text'],
11203
+ },
11204
+ toolCall: true,
11205
+ reasoningText: true,
11206
+ attachment: true,
11207
+ temperature: false,
11208
+ knowledge: '2025-01',
11209
+ releaseDate: '2026-06-12',
11210
+ lastUpdated: '2026-06-12',
11211
+ openWeights: true,
11212
+ cost: {
11213
+ input: 0.95,
11214
+ output: 4,
11215
+ cacheRead: 0.19,
11216
+ },
11217
+ limit: {
11218
+ context: 262144,
11219
+ output: 262144,
11220
+ },
11221
+ },
11157
11222
  ],
11158
- label: 'Moonshot AI',
11159
- env: ['MOONSHOT_API_KEY'],
11223
+ label: 'Kimi',
11224
+ env: ['KIMI_API_KEY', 'MOONSHOT_API_KEY'],
11160
11225
  npm: '@ai-sdk/openai-compatible',
11161
11226
  api: 'https://api.moonshot.ai/v1',
11162
- doc: 'https://platform.moonshot.ai/docs/api/chat',
11227
+ doc: 'https://platform.kimi.ai/docs/api/overview.md',
11163
11228
  },
11164
11229
  minimax: {
11165
11230
  id: 'minimax',
@@ -11351,6 +11416,33 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
11351
11416
  copilot: {
11352
11417
  id: 'copilot',
11353
11418
  models: [
11419
+ {
11420
+ id: 'claude-fable-5',
11421
+ ownedBy: 'anthropic',
11422
+ label: 'Claude Fable 5',
11423
+ modalities: {
11424
+ input: ['text', 'image', 'pdf'],
11425
+ output: ['text'],
11426
+ },
11427
+ toolCall: true,
11428
+ reasoningText: true,
11429
+ attachment: true,
11430
+ temperature: false,
11431
+ knowledge: '2026-01-31',
11432
+ releaseDate: '2026-06-09',
11433
+ lastUpdated: '2026-06-09',
11434
+ openWeights: false,
11435
+ cost: {
11436
+ input: 10,
11437
+ output: 50,
11438
+ cacheRead: 1,
11439
+ cacheWrite: 12.5,
11440
+ },
11441
+ limit: {
11442
+ context: 1000000,
11443
+ output: 128000,
11444
+ },
11445
+ },
11354
11446
  {
11355
11447
  id: 'claude-haiku-4.5',
11356
11448
  ownedBy: 'anthropic',
@@ -11579,8 +11671,8 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
11579
11671
  attachment: true,
11580
11672
  temperature: true,
11581
11673
  knowledge: '2025-01',
11582
- releaseDate: '2025-03-20',
11583
- lastUpdated: '2025-06-05',
11674
+ releaseDate: '2025-06-17',
11675
+ lastUpdated: '2025-06-17',
11584
11676
  openWeights: false,
11585
11677
  cost: {
11586
11678
  input: 1.25,
@@ -12297,6 +12389,27 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
12297
12389
  output: 262144,
12298
12390
  },
12299
12391
  },
12392
+ {
12393
+ id: 'kimi-k2.7-code',
12394
+ ownedBy: 'moonshot',
12395
+ label: 'kimi-k2.7-code',
12396
+ modalities: {
12397
+ input: ['text', 'image'],
12398
+ output: ['text'],
12399
+ },
12400
+ toolCall: true,
12401
+ reasoningText: true,
12402
+ attachment: true,
12403
+ temperature: false,
12404
+ knowledge: '2025-01',
12405
+ releaseDate: '2026-06-12',
12406
+ lastUpdated: '2026-06-12',
12407
+ openWeights: true,
12408
+ limit: {
12409
+ context: 262144,
12410
+ output: 262144,
12411
+ },
12412
+ },
12300
12413
  {
12301
12414
  id: 'minimax-m2',
12302
12415
  ownedBy: 'minimax',
@@ -1,4 +1,5 @@
1
1
  import type { BuiltInProviderId, ProviderId } from '../../types/src/index.ts';
2
+ import { readKimiApiKeyFromEnv } from './moonshot-client.ts';
2
3
 
3
4
  const ENV_VARS: Record<BuiltInProviderId, string> = {
4
5
  openai: 'OPENAI_API_KEY',
@@ -12,15 +13,22 @@ const ENV_VARS: Record<BuiltInProviderId, string> = {
12
13
  xai: 'XAI_API_KEY',
13
14
  zai: 'ZAI_API_KEY',
14
15
  'zai-coding': 'ZAI_CODING_API_KEY',
15
- moonshot: 'MOONSHOT_API_KEY',
16
+ moonshot: 'KIMI_API_KEY',
16
17
  minimax: 'MINIMAX_API_KEY',
17
18
  };
18
19
 
20
+ const KIMI_PROVIDER_IDS = new Set<ProviderId>(['kimi', 'moonshot']);
21
+
19
22
  export function providerEnvVar(provider: ProviderId): string | undefined {
23
+ if (provider === 'kimi') return 'KIMI_API_KEY';
20
24
  return ENV_VARS[provider as BuiltInProviderId];
21
25
  }
22
26
 
23
27
  export function readEnvKey(provider: ProviderId): string | undefined {
28
+ if (KIMI_PROVIDER_IDS.has(provider)) {
29
+ const value = readKimiApiKeyFromEnv();
30
+ return value.length ? value : undefined;
31
+ }
24
32
  if (!(provider in ENV_VARS) && provider !== 'copilot') {
25
33
  return undefined;
26
34
  }
@@ -39,8 +47,13 @@ export function readEnvKey(provider: ProviderId): string | undefined {
39
47
  }
40
48
 
41
49
  export function setEnvKey(provider: ProviderId, value: string | undefined) {
50
+ if (!value) return;
51
+ if (KIMI_PROVIDER_IDS.has(provider)) {
52
+ process.env.KIMI_API_KEY = value;
53
+ return;
54
+ }
42
55
  const key = providerEnvVar(provider);
43
- if (key && value) {
56
+ if (key) {
44
57
  process.env[key] = value;
45
58
  }
46
59
  }
@@ -123,8 +123,15 @@ export {
123
123
  export type { OpenRouterProviderConfig } from './openrouter-client.ts';
124
124
  export { createOpencodeModel } from './opencode-client.ts';
125
125
  export type { OpencodeProviderConfig } from './opencode-client.ts';
126
- export { createMoonshotModel } from './moonshot-client.ts';
127
- export type { MoonshotProviderConfig } from './moonshot-client.ts';
126
+ export {
127
+ createKimiModel,
128
+ createMoonshotModel,
129
+ readKimiApiKeyFromEnv,
130
+ } from './moonshot-client.ts';
131
+ export type {
132
+ KimiProviderConfig,
133
+ MoonshotProviderConfig,
134
+ } from './moonshot-client.ts';
128
135
  export { createMinimaxModel } from './minimax-client.ts';
129
136
  export type { MinimaxProviderConfig } from './minimax-client.ts';
130
137
  export { createCopilotFetch, createCopilotModel } from './copilot-client.ts';
@@ -0,0 +1,27 @@
1
+ import type { ModelInfo } from '../../types/src/index.ts';
2
+
3
+ /**
4
+ * Merge embedded/manual catalog models with cached (remote/local) models by id.
5
+ *
6
+ * Cached entries override fields for overlapping ids (so remote updates like
7
+ * pricing/limits still apply), while embedded/manual-only models (for example
8
+ * the manual xai grok-cli models) are always retained even when a stale cache
9
+ * does not include them.
10
+ */
11
+ export function mergeModelLists(
12
+ baseModels: ModelInfo[] | undefined,
13
+ cachedModels: ModelInfo[] | undefined,
14
+ ): ModelInfo[] {
15
+ const base = baseModels ?? [];
16
+ const cached = cachedModels ?? [];
17
+ if (!cached.length) return base;
18
+ if (!base.length) return cached;
19
+ const cachedById = new Map(cached.map((model) => [model.id, model]));
20
+ const merged = base.map((model) => {
21
+ const override = cachedById.get(model.id);
22
+ return override ? { ...model, ...override } : model;
23
+ });
24
+ const baseIds = new Set(base.map((model) => model.id));
25
+ const extras = cached.filter((model) => !baseIds.has(model.id));
26
+ return extras.length ? [...merged, ...extras] : merged;
27
+ }