@jeffreycao/copilot-api 2.0.2 → 2.1.1

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.
@@ -412,6 +412,413 @@ var EventBus = class {
412
412
  };
413
413
  }
414
414
  };
415
+ const builtinProviderModelRegistry = new class BuiltinProviderModelRegistry {
416
+ static catalog = {
417
+ codex: {
418
+ "gpt-5.3-codex": { pricing: {
419
+ cachedInput: .175,
420
+ input: 1.75,
421
+ output: 14
422
+ } },
423
+ "gpt-5.4": { pricing: { tiers: [{
424
+ cachedInput: .25,
425
+ input: 2.5,
426
+ maxInputTokens: 272e3,
427
+ output: 15
428
+ }, {
429
+ cachedInput: .5,
430
+ input: 5,
431
+ output: 22.5
432
+ }] } },
433
+ "gpt-5.4-mini": { pricing: { tiers: [{
434
+ cachedInput: .075,
435
+ input: .75,
436
+ maxInputTokens: 272e3,
437
+ output: 4.5
438
+ }, {
439
+ cachedInput: .15,
440
+ input: 1.5,
441
+ output: 6.75
442
+ }] } },
443
+ "gpt-5.5": { pricing: { tiers: [{
444
+ cachedInput: .5,
445
+ input: 5,
446
+ maxInputTokens: 272e3,
447
+ output: 30
448
+ }, {
449
+ cachedInput: 1,
450
+ input: 10,
451
+ output: 45
452
+ }] } },
453
+ "gpt-5.6-sol": { pricing: { tiers: [{
454
+ cacheCreationInput: 6.25,
455
+ cachedInput: .5,
456
+ input: 5,
457
+ maxInputTokens: 272e3,
458
+ output: 30
459
+ }, {
460
+ cacheCreationInput: 12.5,
461
+ cachedInput: 1,
462
+ input: 10,
463
+ output: 45
464
+ }] } },
465
+ "gpt-5.6-terra": { pricing: { tiers: [{
466
+ cacheCreationInput: 2.5,
467
+ cachedInput: .2,
468
+ input: 2,
469
+ maxInputTokens: 272e3,
470
+ output: 12
471
+ }, {
472
+ cacheCreationInput: 5,
473
+ cachedInput: .4,
474
+ input: 4,
475
+ output: 18
476
+ }] } },
477
+ "gpt-5.6-luna": { pricing: { tiers: [{
478
+ cacheCreationInput: .25,
479
+ cachedInput: .02,
480
+ input: .2,
481
+ maxInputTokens: 272e3,
482
+ output: 1.2
483
+ }, {
484
+ cacheCreationInput: .5,
485
+ cachedInput: .04,
486
+ input: .4,
487
+ output: 1.8
488
+ }] } }
489
+ },
490
+ dashscope: {
491
+ "glm-5.1": {
492
+ contextWindow: 202752,
493
+ inputModalities: ["text"],
494
+ maxOutputTokens: 64e3,
495
+ pricing: { tiers: [{
496
+ cachedInput: 1.2,
497
+ cacheCreationInput: 7.5,
498
+ explicitCachedInput: .6,
499
+ input: 6,
500
+ maxInputTokens: 32e3,
501
+ output: 24
502
+ }, {
503
+ cachedInput: 1.6,
504
+ cacheCreationInput: 10,
505
+ explicitCachedInput: .8,
506
+ input: 8,
507
+ maxInputTokens: 2e5,
508
+ output: 28
509
+ }] }
510
+ },
511
+ "glm-5.2": {
512
+ contextWindow: 1e6,
513
+ inputModalities: ["text"],
514
+ maxOutputTokens: 64e3,
515
+ pricing: {
516
+ cachedInput: 2,
517
+ cacheCreationInput: 10,
518
+ explicitCachedInput: .8,
519
+ input: 8,
520
+ output: 28
521
+ }
522
+ },
523
+ "qwen3.7-max": {
524
+ contextWindow: 1e6,
525
+ inputModalities: ["text"],
526
+ maxOutputTokens: 64e3,
527
+ pricing: {
528
+ cachedInput: 2.4,
529
+ cacheCreationInput: 15,
530
+ explicitCachedInput: 1.2,
531
+ input: 12,
532
+ output: 36
533
+ }
534
+ },
535
+ "qwen3.8-max": {
536
+ contextWindow: 1e6,
537
+ inputModalities: ["text", "image"],
538
+ maxOutputTokens: 64e3,
539
+ pricing: {
540
+ cachedInput: 1.5,
541
+ cacheCreationInput: 15,
542
+ explicitCachedInput: 1,
543
+ input: 12,
544
+ output: 36
545
+ }
546
+ },
547
+ "deepseek-v4-flash-0731": {
548
+ contextWindow: 1e6,
549
+ inputModalities: ["text"],
550
+ maxOutputTokens: 64e3,
551
+ pricing: {
552
+ cachedInput: .2,
553
+ input: 1,
554
+ output: 2
555
+ }
556
+ },
557
+ "qwen3.7-plus": {
558
+ contextWindow: 1e6,
559
+ inputModalities: ["text", "image"],
560
+ maxOutputTokens: 64e3,
561
+ pricing: { tiers: [{
562
+ cachedInput: .4,
563
+ cacheCreationInput: 2.5,
564
+ explicitCachedInput: .2,
565
+ input: 2,
566
+ maxInputTokens: 256e3,
567
+ output: 8
568
+ }, {
569
+ cachedInput: 1.2,
570
+ cacheCreationInput: 7.5,
571
+ explicitCachedInput: .6,
572
+ input: 6,
573
+ maxInputTokens: 1e6,
574
+ output: 24
575
+ }] }
576
+ },
577
+ "kimi/kimi-k3": {
578
+ contextWindow: 1048576,
579
+ inputModalities: ["text", "image"],
580
+ maxOutputTokens: 64e3,
581
+ pricing: {
582
+ cachedInput: 2,
583
+ input: 20,
584
+ output: 100
585
+ }
586
+ }
587
+ },
588
+ deepseek: {
589
+ "deepseek-v4-flash": {
590
+ contextWindow: 1e6,
591
+ inputModalities: ["text"],
592
+ maxOutputTokens: 64e3,
593
+ pricing: {
594
+ cachedInput: .02,
595
+ input: 1,
596
+ output: 2
597
+ }
598
+ },
599
+ "deepseek-v4-pro": {
600
+ contextWindow: 1e6,
601
+ inputModalities: ["text"],
602
+ maxOutputTokens: 64e3,
603
+ pricing: {
604
+ cachedInput: .025,
605
+ input: 3,
606
+ output: 6
607
+ }
608
+ }
609
+ },
610
+ "opencode-go": {
611
+ hy3: {
612
+ contextWindow: 256e3,
613
+ inputModalities: ["text"],
614
+ maxOutputTokens: 64e3,
615
+ pricing: {
616
+ cachedInput: .035,
617
+ input: .14,
618
+ output: .58
619
+ }
620
+ },
621
+ "gpt-5.6-luna": { pricing: { tiers: [{
622
+ cacheCreationInput: .125,
623
+ cachedInput: .01,
624
+ input: .1,
625
+ maxInputTokens: 272e3,
626
+ output: .6
627
+ }, {
628
+ cacheCreationInput: .25,
629
+ cachedInput: .02,
630
+ input: .2,
631
+ output: .9
632
+ }] } },
633
+ "glm-5.2": {
634
+ contextWindow: 1e6,
635
+ inputModalities: ["text"],
636
+ maxOutputTokens: 64e3,
637
+ pricing: {
638
+ cachedInput: .26,
639
+ input: 1.4,
640
+ output: 4.4
641
+ }
642
+ },
643
+ "grok-4.5": {
644
+ contextWindow: 5e5,
645
+ inputModalities: ["text", "image"],
646
+ maxOutputTokens: 64e3,
647
+ pricing: { tiers: [{
648
+ cachedInput: .5,
649
+ input: 2,
650
+ maxInputTokens: 2e5,
651
+ output: 6
652
+ }, {
653
+ cachedInput: 1,
654
+ input: 4,
655
+ output: 12
656
+ }] }
657
+ },
658
+ "deepseek-v4-flash": {
659
+ contextWindow: 1e6,
660
+ inputModalities: ["text"],
661
+ maxOutputTokens: 64e3,
662
+ pricing: {
663
+ cachedInput: .0028,
664
+ input: .14,
665
+ output: .28
666
+ }
667
+ },
668
+ "deepseek-v4-pro": {
669
+ contextWindow: 1e6,
670
+ inputModalities: ["text"],
671
+ maxOutputTokens: 64e3,
672
+ pricing: {
673
+ cachedInput: .0145,
674
+ input: 1.74,
675
+ output: 3.48
676
+ }
677
+ },
678
+ "kimi-k2.7-code": {
679
+ contextWindow: 262144,
680
+ inputModalities: ["text", "image"],
681
+ maxOutputTokens: 64e3,
682
+ pricing: {
683
+ cachedInput: .19,
684
+ input: .95,
685
+ output: 4
686
+ }
687
+ },
688
+ "kimi-k3": {
689
+ contextWindow: 1048576,
690
+ inputModalities: ["text", "image"],
691
+ maxOutputTokens: 64e3,
692
+ pricing: {
693
+ cachedInput: .3,
694
+ input: 3,
695
+ output: 15
696
+ }
697
+ },
698
+ "mimo-v2.5": {
699
+ contextWindow: 1e6,
700
+ inputModalities: ["text", "image"],
701
+ maxOutputTokens: 64e3,
702
+ pricing: {
703
+ cachedInput: .0028,
704
+ input: .14,
705
+ output: .28
706
+ }
707
+ },
708
+ "mimo-v2.5-pro": {
709
+ contextWindow: 1048576,
710
+ inputModalities: ["text"],
711
+ maxOutputTokens: 64e3,
712
+ pricing: {
713
+ cachedInput: .0145,
714
+ input: 1.74,
715
+ output: 3.48
716
+ }
717
+ },
718
+ "qwen3.7-plus": {
719
+ contextWindow: 1e6,
720
+ inputModalities: ["text", "image"],
721
+ maxOutputTokens: 64e3,
722
+ pricing: { tiers: [{
723
+ cacheCreationInput: .5,
724
+ cachedInput: .04,
725
+ input: .4,
726
+ maxInputTokens: 2e5,
727
+ output: 1.6
728
+ }, {
729
+ cacheCreationInput: 1.5,
730
+ cachedInput: .12,
731
+ input: 1.2,
732
+ maxInputTokens: 256e3,
733
+ output: 4.8
734
+ }] }
735
+ },
736
+ "qwen3.7-max": {
737
+ contextWindow: 1e6,
738
+ inputModalities: ["text"],
739
+ maxOutputTokens: 64e3,
740
+ pricing: {
741
+ cacheCreationInput: 3.125,
742
+ cachedInput: .5,
743
+ input: 2.5,
744
+ output: 7.5
745
+ }
746
+ },
747
+ "qwen3.8-max": {
748
+ contextWindow: 1e6,
749
+ inputModalities: ["text", "image"],
750
+ maxOutputTokens: 64e3,
751
+ pricing: {
752
+ cacheCreationInput: 2.5,
753
+ cachedInput: .25,
754
+ input: 2,
755
+ output: 6
756
+ }
757
+ },
758
+ "minimax-m2.7": {
759
+ contextWindow: 204800,
760
+ inputModalities: ["text"],
761
+ maxOutputTokens: 64e3,
762
+ pricing: {
763
+ cachedInput: .06,
764
+ input: .3,
765
+ output: 1.2
766
+ }
767
+ },
768
+ "minimax-m3": {
769
+ contextWindow: 1e6,
770
+ inputModalities: ["text", "image"],
771
+ maxOutputTokens: 64e3,
772
+ pricing: { tiers: [{
773
+ cachedInput: .06,
774
+ input: .3,
775
+ maxInputTokens: 2e5,
776
+ output: 1.2
777
+ }, {
778
+ cachedInput: .12,
779
+ input: .6,
780
+ maxInputTokens: 512e3,
781
+ output: 2.4
782
+ }] }
783
+ }
784
+ },
785
+ kimi: {
786
+ k3: {
787
+ contextWindow: 1048576,
788
+ inputModalities: ["text", "image"],
789
+ maxOutputTokens: 64e3,
790
+ pricing: {
791
+ cachedInput: .3,
792
+ input: 3,
793
+ output: 15
794
+ }
795
+ },
796
+ "k3-256k": {
797
+ contextWindow: 262144,
798
+ inputModalities: ["text", "image"],
799
+ maxOutputTokens: 64e3,
800
+ pricing: {
801
+ cachedInput: .3,
802
+ input: 3,
803
+ output: 15
804
+ }
805
+ }
806
+ }
807
+ };
808
+ modelCatalog;
809
+ constructor() {
810
+ this.modelCatalog = BuiltinProviderModelRegistry.catalog;
811
+ }
812
+ getModelConfig(providerName, modelName) {
813
+ return this.modelCatalog[this.normalizeKey(providerName)]?.[this.normalizeKey(modelName)];
814
+ }
815
+ getModelIds(providerName) {
816
+ return Object.keys(this.modelCatalog[this.normalizeKey(providerName)] ?? {});
817
+ }
818
+ normalizeKey(value) {
819
+ return value.trim().toLowerCase();
820
+ }
821
+ }();
415
822
  //#endregion
416
823
  //#region src/lib/sqlite.ts
417
824
  const MINIMUM_NODE_SQLITE_VERSION = "22.13.0";
@@ -1042,273 +1449,6 @@ const BUILTIN_PROVIDER_CURRENCIES = {
1042
1449
  kimi: "USD",
1043
1450
  "opencode-go": "USD"
1044
1451
  };
1045
- const BUILTIN_PROVIDER_PRICING = {
1046
- codex: {
1047
- "gpt-5.3-codex": {
1048
- cachedInput: .175,
1049
- input: 1.75,
1050
- output: 14
1051
- },
1052
- "gpt-5.4": { tiers: [{
1053
- cachedInput: .25,
1054
- input: 2.5,
1055
- maxInputTokens: 272e3,
1056
- output: 15
1057
- }, {
1058
- cachedInput: .5,
1059
- input: 5,
1060
- output: 22.5
1061
- }] },
1062
- "gpt-5.4-mini": { tiers: [{
1063
- cachedInput: .075,
1064
- input: .75,
1065
- maxInputTokens: 272e3,
1066
- output: 4.5
1067
- }, {
1068
- cachedInput: .15,
1069
- input: 1.5,
1070
- output: 6.75
1071
- }] },
1072
- "gpt-5.5": { tiers: [{
1073
- cachedInput: .5,
1074
- input: 5,
1075
- maxInputTokens: 272e3,
1076
- output: 30
1077
- }, {
1078
- cachedInput: 1,
1079
- input: 10,
1080
- output: 45
1081
- }] },
1082
- "gpt-5.6-sol": { tiers: [{
1083
- cacheCreationInput: 6.25,
1084
- cachedInput: .5,
1085
- input: 5,
1086
- maxInputTokens: 272e3,
1087
- output: 30
1088
- }, {
1089
- cacheCreationInput: 12.5,
1090
- cachedInput: 1,
1091
- input: 10,
1092
- output: 45
1093
- }] },
1094
- "gpt-5.6-terra": { tiers: [{
1095
- cacheCreationInput: 2.5,
1096
- cachedInput: .2,
1097
- input: 2,
1098
- maxInputTokens: 272e3,
1099
- output: 12
1100
- }, {
1101
- cacheCreationInput: 5,
1102
- cachedInput: .4,
1103
- input: 4,
1104
- output: 18
1105
- }] },
1106
- "gpt-5.6-luna": { tiers: [{
1107
- cacheCreationInput: .25,
1108
- cachedInput: .02,
1109
- input: .2,
1110
- maxInputTokens: 272e3,
1111
- output: 1.2
1112
- }, {
1113
- cacheCreationInput: .5,
1114
- cachedInput: .04,
1115
- input: .4,
1116
- output: 1.8
1117
- }] }
1118
- },
1119
- dashscope: {
1120
- "glm-5.1": { tiers: [{
1121
- cachedInput: 1.2,
1122
- cacheCreationInput: 7.5,
1123
- explicitCachedInput: .6,
1124
- input: 6,
1125
- maxInputTokens: 32e3,
1126
- output: 24
1127
- }, {
1128
- cachedInput: 1.6,
1129
- cacheCreationInput: 10,
1130
- explicitCachedInput: .8,
1131
- input: 8,
1132
- maxInputTokens: 2e5,
1133
- output: 28
1134
- }] },
1135
- "glm-5.2": {
1136
- cachedInput: 2,
1137
- cacheCreationInput: 10,
1138
- explicitCachedInput: .8,
1139
- input: 8,
1140
- output: 28
1141
- },
1142
- "qwen3.7-max": {
1143
- cachedInput: 2.4,
1144
- cacheCreationInput: 15,
1145
- explicitCachedInput: 1.2,
1146
- input: 12,
1147
- output: 36
1148
- },
1149
- "qwen3.8-max": {
1150
- cachedInput: 1.5,
1151
- cacheCreationInput: 15,
1152
- explicitCachedInput: 1,
1153
- input: 12,
1154
- output: 36
1155
- },
1156
- "deepseek-v4-flash-0731": {
1157
- cachedInput: .2,
1158
- input: 1,
1159
- output: 2
1160
- },
1161
- "qwen3.7-plus": { tiers: [{
1162
- cachedInput: .4,
1163
- cacheCreationInput: 2.5,
1164
- explicitCachedInput: .2,
1165
- input: 2,
1166
- maxInputTokens: 256e3,
1167
- output: 8
1168
- }, {
1169
- cachedInput: 1.2,
1170
- cacheCreationInput: 7.5,
1171
- explicitCachedInput: .6,
1172
- input: 6,
1173
- maxInputTokens: 1e6,
1174
- output: 24
1175
- }] },
1176
- "kimi/kimi-k3": {
1177
- cachedInput: 2,
1178
- input: 20,
1179
- output: 100
1180
- }
1181
- },
1182
- deepseek: {
1183
- "deepseek-v4-flash": {
1184
- cachedInput: .02,
1185
- input: 1,
1186
- output: 2
1187
- },
1188
- "deepseek-v4-pro": {
1189
- cachedInput: .025,
1190
- input: 3,
1191
- output: 6
1192
- }
1193
- },
1194
- "opencode-go": {
1195
- hy3: {
1196
- cachedInput: .035,
1197
- input: .14,
1198
- output: .58
1199
- },
1200
- "gpt-5.6-luna": { tiers: [{
1201
- cacheCreationInput: .125,
1202
- cachedInput: .01,
1203
- input: .1,
1204
- maxInputTokens: 272e3,
1205
- output: .6
1206
- }, {
1207
- cacheCreationInput: .25,
1208
- cachedInput: .02,
1209
- input: .2,
1210
- output: .9
1211
- }] },
1212
- "glm-5.2": {
1213
- cachedInput: .26,
1214
- input: 1.4,
1215
- output: 4.4
1216
- },
1217
- "grok-4.5": { tiers: [{
1218
- cachedInput: .5,
1219
- input: 2,
1220
- maxInputTokens: 2e5,
1221
- output: 6
1222
- }, {
1223
- cachedInput: 1,
1224
- input: 4,
1225
- output: 12
1226
- }] },
1227
- "deepseek-v4-flash": {
1228
- cachedInput: .0028,
1229
- input: .14,
1230
- output: .28
1231
- },
1232
- "deepseek-v4-pro": {
1233
- cachedInput: .0145,
1234
- input: 1.74,
1235
- output: 3.48
1236
- },
1237
- "kimi-k2.7-code": {
1238
- cachedInput: .19,
1239
- input: .95,
1240
- output: 4
1241
- },
1242
- "kimi-k3": {
1243
- cachedInput: .3,
1244
- input: 3,
1245
- output: 15
1246
- },
1247
- "mimo-v2.5": {
1248
- cachedInput: .0028,
1249
- input: .14,
1250
- output: .28
1251
- },
1252
- "mimo-v2.5-pro": {
1253
- cachedInput: .0145,
1254
- input: 1.74,
1255
- output: 3.48
1256
- },
1257
- "qwen3.7-plus": { tiers: [{
1258
- cacheCreationInput: .5,
1259
- cachedInput: .04,
1260
- input: .4,
1261
- maxInputTokens: 2e5,
1262
- output: 1.6
1263
- }, {
1264
- cacheCreationInput: 1.5,
1265
- cachedInput: .12,
1266
- input: 1.2,
1267
- maxInputTokens: 256e3,
1268
- output: 4.8
1269
- }] },
1270
- "qwen3.7-max": {
1271
- cacheCreationInput: 3.125,
1272
- cachedInput: .5,
1273
- input: 2.5,
1274
- output: 7.5
1275
- },
1276
- "qwen3.8-max": {
1277
- cacheCreationInput: 2.5,
1278
- cachedInput: .25,
1279
- input: 2,
1280
- output: 6
1281
- },
1282
- "minimax-m2.7": {
1283
- cachedInput: .06,
1284
- input: .3,
1285
- output: 1.2
1286
- },
1287
- "minimax-m3": { tiers: [{
1288
- cachedInput: .06,
1289
- input: .3,
1290
- maxInputTokens: 2e5,
1291
- output: 1.2
1292
- }, {
1293
- cachedInput: .12,
1294
- input: .6,
1295
- maxInputTokens: 512e3,
1296
- output: 2.4
1297
- }] }
1298
- },
1299
- kimi: {
1300
- k3: {
1301
- cachedInput: .3,
1302
- input: 3,
1303
- output: 15
1304
- },
1305
- "k3-256k": {
1306
- cachedInput: .3,
1307
- input: 3,
1308
- output: 15
1309
- }
1310
- }
1311
- };
1312
1452
  function resolveTokenUsageCost(input) {
1313
1453
  if (input.source === "provider" && input.providerName?.trim().toLowerCase() === "openrouter") {
1314
1454
  const reportedCost = resolveReportedProviderCost(input);
@@ -1361,7 +1501,7 @@ function resolveProviderPricing(providerName, model, configuredPricing) {
1361
1501
  pricing: configuredPricing,
1362
1502
  source: "config"
1363
1503
  };
1364
- const builtinPricing = BUILTIN_PROVIDER_PRICING[providerName.toLowerCase()]?.[model.toLowerCase()];
1504
+ const builtinPricing = builtinProviderModelRegistry.getModelConfig(providerName, model)?.pricing;
1365
1505
  if (!builtinPricing) return null;
1366
1506
  return {
1367
1507
  pricing: builtinPricing,
@@ -7629,7 +7769,7 @@ function createSyntheticCodexModel(candidate, template, priority) {
7629
7769
  experimental_supported_tools: [],
7630
7770
  input_modalities: inputModalities,
7631
7771
  supports_image_detail_original: false,
7632
- supports_parallel_tool_calls: candidate.supportsParallelToolCalls,
7772
+ supports_parallel_tool_calls: true,
7633
7773
  context_window: candidate.contextWindow,
7634
7774
  max_context_window: candidate.contextWindow,
7635
7775
  max_output_tokens: candidate.maxOutputTokens,
@@ -7720,6 +7860,22 @@ function getStringField$1(model, field) {
7720
7860
  const value = model[field];
7721
7861
  return typeof value === "string" && value.trim() ? value : void 0;
7722
7862
  }
7863
+ function getBuiltinProviderModelRecords(provider) {
7864
+ return builtinProviderModelRegistry.getModelIds(provider).map((id) => ({
7865
+ id,
7866
+ name: id,
7867
+ object: "model"
7868
+ }));
7869
+ }
7870
+ function getFallbackProviderModelRecords(provider, reason, details = {}) {
7871
+ const fallbackModels = getBuiltinProviderModelRecords(provider);
7872
+ logger$7.warn(`models.provider.fallback_${reason}`, {
7873
+ provider,
7874
+ ...details,
7875
+ fallbackModelCount: fallbackModels.length
7876
+ });
7877
+ return fallbackModels;
7878
+ }
7723
7879
  function normalizeProviderModel(provider, model) {
7724
7880
  if (!isRecord$1(model)) return null;
7725
7881
  const rawId = getStringField$1(model, "id");
@@ -7738,31 +7894,36 @@ function normalizeProviderModel(provider, model) {
7738
7894
  display_name: name
7739
7895
  };
7740
7896
  }
7897
+ function normalizeProviderModels(provider, models) {
7898
+ return models.map((model) => normalizeProviderModel(provider, model)).filter((model) => model !== null);
7899
+ }
7900
+ async function getProviderModelRecords(providerConfig, requestHeaders) {
7901
+ try {
7902
+ const response = await forwardProviderModels(providerConfig, requestHeaders);
7903
+ if (!response.ok) return getFallbackProviderModelRecords(providerConfig.name, "non_ok", { statusCode: response.status });
7904
+ const body = await response.json();
7905
+ if (!isRecord$1(body) || !Array.isArray(body.data)) return getFallbackProviderModelRecords(providerConfig.name, "invalid_body");
7906
+ return body.data.filter(isRecord$1);
7907
+ } catch (error) {
7908
+ return getFallbackProviderModelRecords(providerConfig.name, "error", { error });
7909
+ }
7910
+ }
7741
7911
  async function getProviderModels(provider, requestHeaders) {
7742
7912
  try {
7743
7913
  const providerConfig = await resolveProviderConfig(provider);
7744
7914
  if (!providerConfig) return [];
7745
- if (providerConfig.name === "codex") return getModels().data.map((model) => normalizeProviderModel(providerConfig.name, model)).filter((model) => model !== null);
7746
- const response = await forwardProviderModels(providerConfig, requestHeaders);
7747
- if (!response.ok) {
7748
- logger$7.warn("models.provider.skip_non_ok", {
7915
+ if (providerConfig.name === "codex") return normalizeProviderModels(providerConfig.name, getModels().data);
7916
+ const models = await getProviderModelRecords(providerConfig, requestHeaders);
7917
+ return normalizeProviderModels(providerConfig.name, models);
7918
+ } catch (error) {
7919
+ if (provider === "codex") {
7920
+ logger$7.warn("models.provider.skip_error", {
7749
7921
  provider,
7750
- statusCode: response.status
7922
+ error
7751
7923
  });
7752
7924
  return [];
7753
7925
  }
7754
- const body = await response.json();
7755
- if (!isRecord$1(body) || !Array.isArray(body.data)) {
7756
- logger$7.warn("models.provider.skip_invalid_body", { provider });
7757
- return [];
7758
- }
7759
- return body.data.map((model) => normalizeProviderModel(providerConfig.name, model)).filter((model) => model !== null);
7760
- } catch (error) {
7761
- logger$7.warn("models.provider.skip_error", {
7762
- provider,
7763
- error
7764
- });
7765
- return [];
7926
+ return normalizeProviderModels(provider, getFallbackProviderModelRecords(provider, "error", { error }));
7766
7927
  }
7767
7928
  }
7768
7929
  async function getAggregatedModels(requestHeaders) {
@@ -7823,8 +7984,7 @@ function createCopilotCodexCandidate(model) {
7823
7984
  maxOutputTokens: positiveNumber(model.capabilities.limits.max_output_tokens, 32e3),
7824
7985
  inputModalities: model.capabilities.supports.vision ? ["text", "image"] : ["text"],
7825
7986
  reasoningEfforts,
7826
- defaultReasoningEffort: selectDefaultReasoningEffort(reasoningEfforts),
7827
- supportsParallelToolCalls: Boolean(model.capabilities.supports.parallel_tool_calls)
7987
+ defaultReasoningEffort: selectDefaultReasoningEffort(reasoningEfforts)
7828
7988
  };
7829
7989
  }
7830
7990
  async function getProviderCodexCandidates(provider, requestHeaders) {
@@ -7843,7 +8003,6 @@ async function getProviderCodexCandidates(provider, requestHeaders) {
7843
8003
  const effectiveType = resolveEffectiveProviderType(providerConfig, modelId);
7844
8004
  if (!isMessagesFallbackProviderType(effectiveType) && effectiveType !== "openai-responses") continue;
7845
8005
  const modelConfig = providerConfig.models?.[modelId];
7846
- if (modelConfig?.codex?.enabled === false) continue;
7847
8006
  candidates.push(createProviderCodexCandidate(providerConfig, modelId, remoteById.get(modelId), modelConfig, effectiveType));
7848
8007
  }
7849
8008
  return candidates;
@@ -7858,33 +8017,13 @@ async function getProviderCodexCandidates(provider, requestHeaders) {
7858
8017
  function isMessagesFallbackProviderType(type) {
7859
8018
  return type === "anthropic" || type === "openai-compatible";
7860
8019
  }
7861
- async function getProviderModelRecords(providerConfig, requestHeaders) {
7862
- try {
7863
- const response = await forwardProviderModels(providerConfig, requestHeaders);
7864
- if (!response.ok) {
7865
- logger$7.warn("models.codex.provider_skip_non_ok", {
7866
- provider: providerConfig.name,
7867
- statusCode: response.status
7868
- });
7869
- return [];
7870
- }
7871
- const body = await response.json();
7872
- if (!isRecord$1(body) || !Array.isArray(body.data)) return [];
7873
- return body.data.filter(isRecord$1);
7874
- } catch (error) {
7875
- logger$7.warn("models.codex.provider_models_error", {
7876
- provider: providerConfig.name,
7877
- error
7878
- });
7879
- return [];
7880
- }
7881
- }
7882
8020
  function createProviderCodexCandidate(providerConfig, modelId, remoteModel, modelConfig, effectiveType) {
7883
- const codexConfig = modelConfig?.codex;
7884
- const configuredReasoningEfforts = normalizeReasoningEfforts(codexConfig?.reasoningEfforts);
8021
+ const builtinModelConfig = builtinProviderModelRegistry.getModelConfig(providerConfig.name, modelId);
8022
+ const configuredReasoningEfforts = normalizeReasoningEfforts(modelConfig?.reasoningEfforts);
7885
8023
  const reasoningEfforts = configuredReasoningEfforts.length > 0 ? configuredReasoningEfforts : normalizeRemoteReasoningEfforts(remoteModel);
7886
- const configuredModalities = normalizeInputModalities(codexConfig?.inputModalities);
8024
+ const configuredModalities = normalizeInputModalities(modelConfig?.inputModalities);
7887
8025
  const remoteModalities = normalizeInputModalities(remoteModel?.input_modalities ?? remoteModel?.modalities);
8026
+ const builtinModalities = normalizeInputModalities(builtinModelConfig?.inputModalities);
7888
8027
  const displayName = getStringField$1(remoteModel ?? {}, "display_name") ?? getStringField$1(remoteModel ?? {}, "name") ?? modelId;
7889
8028
  const adapterName = effectiveType === "anthropic" ? "Messages" : "Messages-to-Chat";
7890
8029
  return {
@@ -7894,17 +8033,16 @@ function createProviderCodexCandidate(providerConfig, modelId, remoteModel, mode
7894
8033
  providerName: providerConfig.name,
7895
8034
  displayName: `${displayName} (${providerConfig.name})`,
7896
8035
  description: `${displayName} through the ${providerConfig.name} ${adapterName} adapter.`,
7897
- contextWindow: positiveNumber(codexConfig?.contextWindow ?? getFirstPositiveNumber(remoteModel, [
8036
+ contextWindow: positiveNumber(modelConfig?.contextWindow ?? getFirstPositiveNumber(remoteModel, [
7898
8037
  "context_window",
7899
8038
  "context_length",
7900
8039
  "max_context_length",
7901
8040
  "max_model_len"
7902
- ]), 256e3),
7903
- maxOutputTokens: positiveNumber(codexConfig?.maxOutputTokens ?? getFirstPositiveNumber(remoteModel, ["max_output_tokens"]), 32e3),
7904
- inputModalities: resolveInputModalities(providerConfig.name, configuredModalities, remoteModalities),
8041
+ ]) ?? builtinModelConfig?.contextWindow, 256e3),
8042
+ maxOutputTokens: positiveNumber(modelConfig?.maxOutputTokens ?? getFirstPositiveNumber(remoteModel, ["max_output_tokens"]) ?? builtinModelConfig?.maxOutputTokens, 32e3),
8043
+ inputModalities: resolveInputModalities(providerConfig.name, configuredModalities, remoteModalities, builtinModalities),
7905
8044
  reasoningEfforts,
7906
- defaultReasoningEffort: selectDefaultReasoningEffort(reasoningEfforts, codexConfig?.defaultReasoningEffort),
7907
- supportsParallelToolCalls: codexConfig?.supportsParallelToolCalls ?? getBooleanField(remoteModel, "supports_parallel_tool_calls") ?? false
8045
+ defaultReasoningEffort: selectDefaultReasoningEffort(reasoningEfforts, modelConfig?.defaultReasoningEffort)
7908
8046
  };
7909
8047
  }
7910
8048
  function normalizeRemoteReasoningEfforts(model) {
@@ -7921,13 +8059,14 @@ function normalizeInputModalities(value) {
7921
8059
  if (!Array.isArray(value)) return [];
7922
8060
  return [...new Set(value.filter((modality) => modality === "text" || modality === "image"))];
7923
8061
  }
7924
- function resolveInputModalities(providerName, configuredModalities, remoteModalities) {
8062
+ function resolveInputModalities(providerName, configuredModalities, remoteModalities, builtinModalities) {
7925
8063
  if (configuredModalities.length > 0) return configuredModalities;
7926
8064
  if (providerName === "kimi") {
7927
- const modalities = remoteModalities.length > 0 ? remoteModalities : ["text"];
8065
+ const modalities = remoteModalities.length > 0 ? remoteModalities : builtinModalities.length > 0 ? builtinModalities : ["text"];
7928
8066
  return [...new Set([...modalities, "image"])];
7929
8067
  }
7930
- return remoteModalities.length > 0 ? remoteModalities : ["text"];
8068
+ if (remoteModalities.length > 0) return remoteModalities;
8069
+ return builtinModalities.length > 0 ? builtinModalities : ["text"];
7931
8070
  }
7932
8071
  function selectDefaultReasoningEffort(efforts, configured) {
7933
8072
  if (configured && efforts.includes(configured)) return configured;
@@ -7944,10 +8083,6 @@ function getFirstPositiveNumber(model, fields) {
7944
8083
  if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
7945
8084
  }
7946
8085
  }
7947
- function getBooleanField(model, field) {
7948
- const value = model?.[field];
7949
- return typeof value === "boolean" ? value : void 0;
7950
- }
7951
8086
  modelRoutes.get("/", async (c) => {
7952
8087
  try {
7953
8088
  if (isCodexUserAgent(c.req.header("user-agent"))) {
@@ -8139,6 +8274,7 @@ function translateResponsesToMessages(payload, options) {
8139
8274
  content: MESSAGES_COMPACTION_PROMPT
8140
8275
  });
8141
8276
  if (messages.length === 0) throw new ResponsesMessagesTranslationError("Responses input must contain at least one translatable message");
8277
+ applyEphemeralCacheControl(messages, system);
8142
8278
  const reasoningEffort = translateReasoningEffort(payload.reasoning?.effort);
8143
8279
  const messagesPayload = {
8144
8280
  model: options.model,
@@ -8665,6 +8801,24 @@ function resolveMetadataUserId(payload) {
8665
8801
  if (payload.safety_identifier?.trim()) return payload.safety_identifier;
8666
8802
  if (payload.prompt_cache_key?.trim()) return payload.prompt_cache_key;
8667
8803
  }
8804
+ const EPHEMERAL_CACHE_CONTROL = { type: "ephemeral" };
8805
+ function applyEphemeralCacheControl(messages, system) {
8806
+ const lastSystemBlock = system.at(-1);
8807
+ if (lastSystemBlock) lastSystemBlock.cache_control = { ...EPHEMERAL_CACHE_CONTROL };
8808
+ const lastMessage = messages.at(-1);
8809
+ if (!lastMessage) return;
8810
+ if (typeof lastMessage.content === "string") {
8811
+ lastMessage.content = [{
8812
+ type: "text",
8813
+ text: lastMessage.content,
8814
+ cache_control: { ...EPHEMERAL_CACHE_CONTROL }
8815
+ }];
8816
+ return;
8817
+ }
8818
+ const lastBlock = lastMessage.content.at(-1);
8819
+ if (!lastBlock || lastBlock.type === "thinking") return;
8820
+ lastBlock.cache_control = { ...EPHEMERAL_CACHE_CONTROL };
8821
+ }
8668
8822
  function appendAssistantBlock(messages, block) {
8669
8823
  const last = messages.at(-1);
8670
8824
  if (last?.role === "assistant" && Array.isArray(last.content)) {
@@ -8911,7 +9065,7 @@ function isJsonWhitespace(char) {
8911
9065
  }
8912
9066
  //#endregion
8913
9067
  //#region src/routes/responses/messages-stream-translation.ts
8914
- const EMPTY_SIGNATURE_ENCRYPTED_CONTENT = "Y29waWxvdC1hcGk6bWVzc2FnZXMtZW1wdHktc2lnbmF0dXJlOnYx";
9068
+ const EMPTY_SIGNATURE_ENCRYPTED_CONTENT = "";
8915
9069
  async function* translateMessagesStream(chunks, context) {
8916
9070
  const state = createTranslationState(context);
8917
9071
  try {
@@ -10104,4 +10258,4 @@ server.route("/:provider/images", providerImageRoutes);
10104
10258
  //#endregion
10105
10259
  export { server };
10106
10260
 
10107
- //# sourceMappingURL=server-0udg5DWI.js.map
10261
+ //# sourceMappingURL=server---R3M8xj.js.map