@shop-os/modelkit 0.1.10 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -96,11 +96,18 @@ var Catalog = class _Catalog {
96
96
  ...rows
97
97
  ]);
98
98
  }
99
+ /** Atomically swap every row. Builds the maps first so a bad batch throws before anything changes. */
100
+ replace(rows) {
101
+ const next = new _Catalog(rows);
102
+ this.byId.clear();
103
+ this.byAlias.clear();
104
+ for (const [id, model] of next.byId) this.byId.set(id, model);
105
+ for (const [alias, id] of next.byAlias) this.byAlias.set(alias, id);
106
+ }
99
107
  };
100
108
 
101
109
  // src/catalog/image.ts
102
- var IMAGE_USAGE = { unit: "images", modality: "IMAGE" };
103
- var IMAGE_GENERATE_EDIT = { imageGenerate: true, imageEdit: true };
110
+ var IMAGE_USAGE = { unit: "images" };
104
111
  var GEMINI_RATIOS = [
105
112
  "1:1",
106
113
  "2:3",
@@ -132,8 +139,7 @@ function geminiImage(id, label, aliases, sizes, display, exposure) {
132
139
  defaults: { size: "1K", aspectRatio: "1:1" },
133
140
  usage: { ...IMAGE_USAGE, slug: "gemini" },
134
141
  pricingKind: "image_size",
135
- display,
136
- capabilities: { ...IMAGE_GENERATE_EDIT }
142
+ display
137
143
  };
138
144
  return model;
139
145
  }
@@ -220,8 +226,7 @@ var IMAGE_MODELS = [
220
226
  provider: "openai",
221
227
  description: "The most capable model for image editing and complex creative instructions. Excels at text rendering, visual consistency, design generation, and iterative refinement.",
222
228
  logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/1204b494-8962-4f7f-af5e-699a8bdc98e3_compressed.png"
223
- },
224
- capabilities: { ...IMAGE_GENERATE_EDIT }
229
+ }
225
230
  },
226
231
  {
227
232
  // Same Images API surface as gpt-image-2 plus the "xhigh" and "max" quality tiers.
@@ -255,8 +260,7 @@ var IMAGE_MODELS = [
255
260
  display: {
256
261
  provider: "openai",
257
262
  description: "OpenAI's most capable GPT Image 2.5 tier, built for editing precision; takes text and image input and outputs images in low, medium, high, xhigh, or max quality."
258
- },
259
- capabilities: { ...IMAGE_GENERATE_EDIT }
263
+ }
260
264
  },
261
265
  {
262
266
  // Same Images API surface as gpt-image-2 plus the "xhigh" and "max" quality tiers.
@@ -290,8 +294,7 @@ var IMAGE_MODELS = [
290
294
  display: {
291
295
  provider: "openai",
292
296
  description: "OpenAI's fastest GPT Image 2.5 tier for high-quality everyday image generation and editing; takes text and image input and outputs images."
293
- },
294
- capabilities: { ...IMAGE_GENERATE_EDIT }
297
+ }
295
298
  },
296
299
  {
297
300
  // Cowork allows 7 ratios; trigger-workflows allows 9 (adds 3:2, 9:21, drops 4:5/5:4).
@@ -329,8 +332,7 @@ var IMAGE_MODELS = [
329
332
  provider: "meta",
330
333
  description: "Meta's image model with built-in world knowledge and strong prompt adherence. Great for concept-rich scenes, realistic compositions, and reference-guided edits.",
331
334
  logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/characters/1787909065794-k9a7zz.png"
332
- },
333
- capabilities: { ...IMAGE_GENERATE_EDIT }
335
+ }
334
336
  },
335
337
  {
336
338
  id: "seedream-5-0-pro",
@@ -356,8 +358,7 @@ var IMAGE_MODELS = [
356
358
  provider: "bytedance",
357
359
  logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/3bba5d81-4e57-4e71-911b-cdfa05acca2c_compressed.png",
358
360
  description: "ByteDance Seedream 5.0 Pro text-to-image and multi-reference image-to-image (up to 10 inputs) with region editing; outputs 1K, 1.5K, or 2K."
359
- },
360
- capabilities: { ...IMAGE_GENERATE_EDIT }
361
+ }
361
362
  },
362
363
  {
363
364
  id: "seedream-4.5",
@@ -394,8 +395,7 @@ var IMAGE_MODELS = [
394
395
  display: {
395
396
  provider: "bytedance",
396
397
  description: "ByteDance Seedream 4.5 text-to-image and image-to-image with up to 14 reference images and batch image-set generation; outputs 2K or 4K."
397
- },
398
- capabilities: { ...IMAGE_GENERATE_EDIT }
398
+ }
399
399
  },
400
400
  {
401
401
  id: "flux-2-pro",
@@ -417,9 +417,9 @@ var IMAGE_MODELS = [
417
417
  pricingKind: "image_size",
418
418
  display: {
419
419
  provider: "black-forest-labs",
420
+ logo: "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/flux.png",
420
421
  description: "Black Forest Labs FLUX.2 [pro] text-to-image and multi-reference editing model served via Prodia; takes a prompt and up to 8 input images and outputs up to 4096x4096."
421
- },
422
- capabilities: { ...IMAGE_GENERATE_EDIT }
422
+ }
423
423
  },
424
424
  {
425
425
  // Prodia's gemini-3-pro jobs take aspect_ratio + resolution (1K/2K/4K), not
@@ -445,8 +445,7 @@ var IMAGE_MODELS = [
445
445
  display: {
446
446
  provider: "google",
447
447
  description: "Google Gemini 3 Pro image generation and editing served via Prodia; takes a prompt plus up to 3 reference images and outputs 1K, 2K, or 4K."
448
- },
449
- capabilities: { ...IMAGE_GENERATE_EDIT }
448
+ }
450
449
  },
451
450
  {
452
451
  // Nano Banana (img2img.v2) is flat-rate with aspect_ratio only; 3:2, 4:5,
@@ -471,8 +470,7 @@ var IMAGE_MODELS = [
471
470
  display: {
472
471
  provider: "google",
473
472
  description: "Google Nano Banana image generation and editing served via Prodia; takes a prompt plus 1-3 input images and matches the first input's aspect ratio in roughly 8 seconds."
474
- },
475
- capabilities: { ...IMAGE_GENERATE_EDIT }
473
+ }
476
474
  },
477
475
  {
478
476
  // WAN 2.7 takes `images` (up to 9) and a `size` enum whose exact values
@@ -493,13 +491,12 @@ var IMAGE_MODELS = [
493
491
  supports: []
494
492
  },
495
493
  defaults: { size: "1K", aspectRatio: "1:1" },
496
- usage: { unit: "compute_seconds", modality: "IMAGE" },
494
+ usage: { unit: "compute_seconds" },
497
495
  pricingKind: "image_size",
498
496
  display: {
499
497
  provider: "alibaba",
500
498
  description: "Alibaba Wan 2.7 Image Pro text-to-image and image-editing model; takes a prompt plus up to 9 reference images and generates up to 4K (4096x4096)."
501
- },
502
- capabilities: { ...IMAGE_GENERATE_EDIT }
499
+ }
503
500
  },
504
501
  {
505
502
  // Qwen Image 2 Pro has aspect_ratio but no size input; resolution follows
@@ -521,13 +518,12 @@ var IMAGE_MODELS = [
521
518
  supports: []
522
519
  },
523
520
  defaults: { aspectRatio: "1:1" },
524
- usage: { unit: "compute_seconds", modality: "IMAGE" },
521
+ usage: { unit: "compute_seconds" },
525
522
  pricingKind: "image_size",
526
523
  display: {
527
524
  provider: "alibaba",
528
525
  description: "Alibaba Qwen Image 2 Pro unified text-to-image and editing model; takes a prompt plus an optional single reference image and generates native 2K output."
529
- },
530
- capabilities: { ...IMAGE_GENERATE_EDIT }
526
+ }
531
527
  },
532
528
  {
533
529
  // Qwen Image Edit Plus takes aspect_ratio (or match_input_image) and
@@ -549,13 +545,12 @@ var IMAGE_MODELS = [
549
545
  supports: ["outputFormat"]
550
546
  },
551
547
  defaults: { outputFormat: "png" },
552
- usage: { unit: "compute_seconds", modality: "IMAGE" },
548
+ usage: { unit: "compute_seconds" },
553
549
  pricingKind: "image_size",
554
550
  display: {
555
551
  provider: "alibaba",
556
552
  description: "Alibaba Qwen Image Edit Plus with Lightning and a skin-retouching LoRA; takes one or more reference images plus an edit prompt and outputs webp, jpg, or png."
557
- },
558
- capabilities: { ...IMAGE_GENERATE_EDIT }
553
+ }
559
554
  }
560
555
  ];
561
556
 
@@ -577,7 +572,7 @@ var OTHER_MODELS = [
577
572
  supports: []
578
573
  },
579
574
  defaults: {},
580
- usage: { unit: "images", modality: "AUDIO" },
575
+ usage: { unit: "images" },
581
576
  pricingKind: "flat",
582
577
  display: {
583
578
  provider: "google",
@@ -600,7 +595,7 @@ var OTHER_MODELS = [
600
595
  supports: []
601
596
  },
602
597
  defaults: {},
603
- usage: { unit: "images", modality: "AUDIO" },
598
+ usage: { unit: "images" },
604
599
  pricingKind: "flat",
605
600
  display: {
606
601
  provider: "google",
@@ -623,7 +618,7 @@ var OTHER_MODELS = [
623
618
  supports: ["seed", "negativePrompt"]
624
619
  },
625
620
  defaults: {},
626
- usage: { unit: "compute_seconds", modality: "AUDIO" },
621
+ usage: { unit: "compute_seconds" },
627
622
  pricingKind: "flat",
628
623
  display: {
629
624
  provider: "google",
@@ -646,7 +641,7 @@ var OTHER_MODELS = [
646
641
  supports: ["seed", "negativePrompt"]
647
642
  },
648
643
  defaults: { durationSeconds: 8 },
649
- usage: { unit: "compute_seconds", modality: "AUDIO" },
644
+ usage: { unit: "compute_seconds" },
650
645
  pricingKind: "flat",
651
646
  display: {
652
647
  provider: "mmaudio",
@@ -669,7 +664,7 @@ var OTHER_MODELS = [
669
664
  },
670
665
  defaults: { durationSeconds: 15, instrumental: true },
671
666
  // Replicate's run() does not report predict_time; billed by generated length.
672
- usage: { unit: "seconds", modality: "AUDIO" },
667
+ usage: { unit: "seconds" },
673
668
  pricingKind: "flat",
674
669
  display: {
675
670
  provider: "elevenlabs",
@@ -692,13 +687,13 @@ var OTHER_MODELS = [
692
687
  supports: ["scaleFactor", "outputFormat", "upscale"]
693
688
  },
694
689
  defaults: { scaleFactor: 2, outputFormat: "png" },
695
- usage: { unit: "compute_seconds", modality: "IMAGE" },
690
+ usage: { unit: "compute_seconds" },
696
691
  pricingKind: "flat",
697
692
  display: {
698
693
  provider: "topaz",
694
+ logo: "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/topazlabs.png",
699
695
  description: "Topaz Labs AI image upscaling on Replicate; takes one input image and upscales up to 6x with selectable enhancement models and optional face enhancement."
700
- },
701
- capabilities: { imageEdit: true }
696
+ }
702
697
  },
703
698
  {
704
699
  id: "bg-remove",
@@ -715,19 +710,30 @@ var OTHER_MODELS = [
715
710
  supports: []
716
711
  },
717
712
  defaults: {},
718
- usage: { unit: "images", modality: "IMAGE" },
713
+ usage: { unit: "images" },
719
714
  pricingKind: "flat",
720
715
  display: {
721
716
  provider: "prodia",
722
717
  description: "Prodia background removal; takes one input image and returns a PNG cut-out of the subject plus an optional black-and-white mask."
723
- },
724
- capabilities: { imageEdit: true }
718
+ }
725
719
  }
726
720
  ];
727
721
 
728
722
  // src/catalog/text.ts
729
- var TEXT_USAGE = { unit: "tokens", modality: "TEXT" };
723
+ var TEXT_USAGE = { unit: "tokens" };
724
+ var CDN = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image";
725
+ var PROVIDER_LOGOS = {
726
+ anthropic: `${CDN}/25fad392-188c-4829-a3d0-c4fa02d1c8cd.png`,
727
+ openai: `${CDN}/1204b494-8962-4f7f-af5e-699a8bdc98e3.png`,
728
+ google: `${CDN}/192485d2-a76a-4657-9c06-930b2c70badd.png`,
729
+ deepseek: `${CDN}/9b7406d2-a696-4558-ab79-90a37e3f4574.png`,
730
+ xai: `${CDN}/858b7fcc-9bd5-411d-aea1-a7b35ecfffab.png`,
731
+ moonshot: `${CDN}/5a1e2eae-3474-4fac-9c74-a93f41ee6f67.png`,
732
+ minimax: `${CDN}/f4c2e906-28b7-4a4a-b491-df8fef7808ed.png`
733
+ };
730
734
  function text(id, label, providerModelId, extra) {
735
+ const display = extra?.display;
736
+ const logo = display && !display.logo ? PROVIDER_LOGOS[display.provider] : void 0;
731
737
  return {
732
738
  id,
733
739
  aliases: [],
@@ -741,7 +747,8 @@ function text(id, label, providerModelId, extra) {
741
747
  defaults: {},
742
748
  usage: { ...TEXT_USAGE },
743
749
  pricingKind: "token",
744
- ...extra
750
+ ...extra,
751
+ ...display && logo ? { display: { ...display, logo } } : {}
745
752
  };
746
753
  }
747
754
  var ANTHROPIC_THINKING = {
@@ -760,7 +767,7 @@ var TEXT_MODELS = [
760
767
  costTier: 2,
761
768
  description: "OpenAI GPT-4o flagship multimodal model; text and image input, 128K-token context."
762
769
  },
763
- capabilities: { vision: true, tools: true, structuredOutput: true, contextWindow: 128e3 }
770
+ capabilities: { vision: true, contextWindow: 128e3 }
764
771
  }),
765
772
  text("gpt-4o-mini", "GPT-4o mini", "gpt-4o-mini", {
766
773
  exposure: "internal",
@@ -769,7 +776,7 @@ var TEXT_MODELS = [
769
776
  costTier: 1,
770
777
  description: "OpenAI GPT-4o mini fast, low-cost multimodal model; text and image input, 128K-token context."
771
778
  },
772
- capabilities: { vision: true, tools: true, structuredOutput: true, contextWindow: 128e3 }
779
+ capabilities: { vision: true, contextWindow: 128e3 }
773
780
  }),
774
781
  text("gpt-5.1", "GPT-5.1", "gpt-5.1", {
775
782
  exposure: "catalog",
@@ -778,7 +785,7 @@ var TEXT_MODELS = [
778
785
  costTier: 3,
779
786
  description: "OpenAI GPT-5.1 reasoning model for coding and agentic tasks; text and image input, 400K-token context."
780
787
  },
781
- capabilities: { vision: true, tools: true, structuredOutput: true, contextWindow: 4e5 }
788
+ capabilities: { vision: true, contextWindow: 4e5 }
782
789
  }),
783
790
  text("gpt-5.2", "GPT-5.2", "gpt-5.2", {
784
791
  exposure: "catalog",
@@ -787,7 +794,7 @@ var TEXT_MODELS = [
787
794
  costTier: 3,
788
795
  description: "OpenAI GPT-5.2 reasoning model for complex professional work; text and image input, 400K-token context."
789
796
  },
790
- capabilities: { vision: true, tools: true, structuredOutput: true, contextWindow: 4e5 }
797
+ capabilities: { vision: true, contextWindow: 4e5 }
791
798
  }),
792
799
  // 1.05M-token context: https://platform.openai.com/docs/models/gpt-5.4
793
800
  text("gpt-5.4", "GPT-5.4", "gpt-5.4", {
@@ -799,8 +806,6 @@ var TEXT_MODELS = [
799
806
  },
800
807
  capabilities: {
801
808
  vision: true,
802
- tools: true,
803
- structuredOutput: true,
804
809
  contextWindow: 105e4
805
810
  }
806
811
  }),
@@ -813,7 +818,7 @@ var TEXT_MODELS = [
813
818
  costTier: 1,
814
819
  description: "OpenAI GPT-5.4 mini efficient reasoning model for high-volume workloads; text and image input, 400K-token context."
815
820
  },
816
- capabilities: { vision: true, tools: true, structuredOutput: true, contextWindow: 4e5 }
821
+ capabilities: { vision: true, contextWindow: 4e5 }
817
822
  }),
818
823
  text("gpt-5.5", "GPT-5.5", "gpt-5.5", {
819
824
  exposure: "catalog",
@@ -824,8 +829,6 @@ var TEXT_MODELS = [
824
829
  },
825
830
  capabilities: {
826
831
  vision: true,
827
- tools: true,
828
- structuredOutput: true,
829
832
  contextWindow: 105e4
830
833
  }
831
834
  }),
@@ -840,8 +843,6 @@ var TEXT_MODELS = [
840
843
  capabilities: {
841
844
  reasoning: true,
842
845
  vision: true,
843
- tools: true,
844
- structuredOutput: true,
845
846
  contextWindow: 105e4
846
847
  }
847
848
  }),
@@ -856,8 +857,6 @@ var TEXT_MODELS = [
856
857
  capabilities: {
857
858
  reasoning: true,
858
859
  vision: true,
859
- tools: true,
860
- structuredOutput: true,
861
860
  contextWindow: 105e4
862
861
  }
863
862
  }),
@@ -872,8 +871,6 @@ var TEXT_MODELS = [
872
871
  capabilities: {
873
872
  reasoning: true,
874
873
  vision: true,
875
- tools: true,
876
- structuredOutput: true,
877
874
  contextWindow: 105e4
878
875
  }
879
876
  }),
@@ -886,7 +883,7 @@ var TEXT_MODELS = [
886
883
  costTier: 2,
887
884
  description: "Anthropic Claude Sonnet 4.5 (legacy) balanced model; text and image input, 200K-token context."
888
885
  },
889
- capabilities: { vision: true, tools: true, structuredOutput: true, contextWindow: 2e5 }
886
+ capabilities: { vision: true, contextWindow: 2e5 }
890
887
  }),
891
888
  // Anthropic retired the dated 4.0 ids; callers that still send them get 4.6.
892
889
  text("claude-sonnet-4-6", "Claude Sonnet 4.6", "claude-sonnet-4-6", {
@@ -906,8 +903,6 @@ var TEXT_MODELS = [
906
903
  capabilities: {
907
904
  reasoning: true,
908
905
  vision: true,
909
- tools: true,
910
- structuredOutput: true,
911
906
  contextWindow: 1e6
912
907
  }
913
908
  }),
@@ -922,8 +917,6 @@ var TEXT_MODELS = [
922
917
  capabilities: {
923
918
  reasoning: true,
924
919
  vision: true,
925
- tools: true,
926
- structuredOutput: true,
927
920
  contextWindow: 1e6
928
921
  }
929
922
  }),
@@ -939,8 +932,6 @@ var TEXT_MODELS = [
939
932
  capabilities: {
940
933
  reasoning: true,
941
934
  vision: true,
942
- tools: true,
943
- structuredOutput: true,
944
935
  contextWindow: 1e6
945
936
  }
946
937
  }),
@@ -956,8 +947,6 @@ var TEXT_MODELS = [
956
947
  capabilities: {
957
948
  reasoning: true,
958
949
  vision: true,
959
- tools: true,
960
- structuredOutput: true,
961
950
  contextWindow: 2e5
962
951
  }
963
952
  }),
@@ -971,8 +960,6 @@ var TEXT_MODELS = [
971
960
  },
972
961
  capabilities: {
973
962
  vision: true,
974
- tools: true,
975
- structuredOutput: true,
976
963
  contextWindow: 1e6
977
964
  }
978
965
  }),
@@ -985,8 +972,6 @@ var TEXT_MODELS = [
985
972
  },
986
973
  capabilities: {
987
974
  vision: true,
988
- tools: true,
989
- structuredOutput: true,
990
975
  contextWindow: 1e6
991
976
  }
992
977
  }),
@@ -999,8 +984,6 @@ var TEXT_MODELS = [
999
984
  },
1000
985
  capabilities: {
1001
986
  vision: true,
1002
- tools: true,
1003
- structuredOutput: true,
1004
987
  contextWindow: 1048576
1005
988
  }
1006
989
  }),
@@ -1013,8 +996,6 @@ var TEXT_MODELS = [
1013
996
  },
1014
997
  capabilities: {
1015
998
  vision: true,
1016
- tools: true,
1017
- structuredOutput: true,
1018
999
  contextWindow: 1048576
1019
1000
  }
1020
1001
  }),
@@ -1027,8 +1008,6 @@ var TEXT_MODELS = [
1027
1008
  },
1028
1009
  capabilities: {
1029
1010
  vision: true,
1030
- tools: true,
1031
- structuredOutput: true,
1032
1011
  contextWindow: 1048576
1033
1012
  }
1034
1013
  }),
@@ -1041,8 +1020,6 @@ var TEXT_MODELS = [
1041
1020
  },
1042
1021
  capabilities: {
1043
1022
  vision: true,
1044
- tools: true,
1045
- structuredOutput: true,
1046
1023
  contextWindow: 1048576
1047
1024
  }
1048
1025
  }),
@@ -1055,8 +1032,6 @@ var TEXT_MODELS = [
1055
1032
  },
1056
1033
  capabilities: {
1057
1034
  vision: true,
1058
- tools: true,
1059
- structuredOutput: true,
1060
1035
  contextWindow: 1048576
1061
1036
  }
1062
1037
  }),
@@ -1070,8 +1045,6 @@ var TEXT_MODELS = [
1070
1045
  },
1071
1046
  capabilities: {
1072
1047
  vision: true,
1073
- tools: true,
1074
- structuredOutput: true,
1075
1048
  contextWindow: 1048576
1076
1049
  }
1077
1050
  }),
@@ -1084,8 +1057,6 @@ var TEXT_MODELS = [
1084
1057
  },
1085
1058
  capabilities: {
1086
1059
  vision: true,
1087
- tools: true,
1088
- structuredOutput: true,
1089
1060
  contextWindow: 1048576
1090
1061
  }
1091
1062
  }),
@@ -1104,8 +1075,6 @@ var TEXT_MODELS = [
1104
1075
  },
1105
1076
  capabilities: {
1106
1077
  vision: true,
1107
- tools: true,
1108
- structuredOutput: true,
1109
1078
  contextWindow: 1048576
1110
1079
  }
1111
1080
  }),
@@ -1118,8 +1087,6 @@ var TEXT_MODELS = [
1118
1087
  },
1119
1088
  capabilities: {
1120
1089
  vision: true,
1121
- tools: false,
1122
- structuredOutput: true,
1123
1090
  contextWindow: 128e3
1124
1091
  }
1125
1092
  }),
@@ -1132,8 +1099,6 @@ var TEXT_MODELS = [
1132
1099
  },
1133
1100
  capabilities: {
1134
1101
  vision: true,
1135
- tools: false,
1136
- structuredOutput: true,
1137
1102
  contextWindow: 2e5
1138
1103
  }
1139
1104
  }),
@@ -1146,8 +1111,6 @@ var TEXT_MODELS = [
1146
1111
  },
1147
1112
  capabilities: {
1148
1113
  vision: true,
1149
- tools: false,
1150
- structuredOutput: true,
1151
1114
  contextWindow: 128e3
1152
1115
  }
1153
1116
  }),
@@ -1167,8 +1130,6 @@ var TEXT_MODELS = [
1167
1130
  capabilities: {
1168
1131
  reasoning: true,
1169
1132
  vision: true,
1170
- tools: true,
1171
- structuredOutput: true,
1172
1133
  contextWindow: 1e6
1173
1134
  }
1174
1135
  }),
@@ -1183,8 +1144,6 @@ var TEXT_MODELS = [
1183
1144
  capabilities: {
1184
1145
  reasoning: true,
1185
1146
  vision: false,
1186
- tools: true,
1187
- structuredOutput: true,
1188
1147
  contextWindow: 1e6
1189
1148
  }
1190
1149
  }),
@@ -1198,14 +1157,14 @@ var TEXT_MODELS = [
1198
1157
  },
1199
1158
  capabilities: {
1200
1159
  vision: true,
1201
- tools: true,
1202
- structuredOutput: true,
1203
1160
  contextWindow: 1e6
1204
1161
  }
1205
1162
  }),
1206
1163
  // Moonshot retired kimi-k2.5 on 2026-08-31 and no longer publishes its specs.
1207
1164
  text("kimi-k2.5", "Kimi K2.5", "kimi-k2.5", {
1208
- exposure: "catalog",
1165
+ lifecycle: "deprecated",
1166
+ replacedBy: "kimi-k3",
1167
+ exposure: "internal",
1209
1168
  display: {
1210
1169
  chat: { temperature: 1 },
1211
1170
  provider: "moonshot",
@@ -1225,8 +1184,6 @@ var TEXT_MODELS = [
1225
1184
  capabilities: {
1226
1185
  reasoning: true,
1227
1186
  vision: true,
1228
- tools: true,
1229
- structuredOutput: true,
1230
1187
  contextWindow: 1e6
1231
1188
  }
1232
1189
  }),
@@ -1240,12 +1197,12 @@ var TEXT_MODELS = [
1240
1197
  costTier: 2,
1241
1198
  description: "MiniMax M3 frontier multimodal model for agentic reasoning, tool use, and coding; text, image, and video input, 1M-token context."
1242
1199
  },
1243
- capabilities: { vision: true, tools: true, contextWindow: 1e6 }
1200
+ capabilities: { vision: true, contextWindow: 1e6 }
1244
1201
  })
1245
1202
  ];
1246
1203
 
1247
1204
  // src/catalog/video.ts
1248
- var VIDEO_USAGE = { unit: "seconds", modality: "VIDEO" };
1205
+ var VIDEO_USAGE = { unit: "seconds" };
1249
1206
  var SEEDANCE_RATIOS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16", "adaptive"];
1250
1207
  var KLING_RATIOS = ["16:9", "9:16", "1:1", "adaptive"];
1251
1208
  var OMNI_RATIOS = ["16:9", "9:16"];
@@ -1419,7 +1376,7 @@ var VIDEO_MODELS = [
1419
1376
  constraints: {
1420
1377
  aspectRatios: [...SEEDANCE_RATIOS],
1421
1378
  resolutions: ["480p", "720p", "1080p", "4k"],
1422
- durations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
1379
+ durations: { min: 4, max: 15 },
1423
1380
  durationPresets: [4, 6, 8, 10, 12, 15],
1424
1381
  references: { images: 9, videos: 3, audios: 3, audioOnly: false },
1425
1382
  ratioIgnoredWith: ["firstFrame"],
@@ -1452,7 +1409,7 @@ var VIDEO_MODELS = [
1452
1409
  constraints: {
1453
1410
  aspectRatios: [...SEEDANCE_RATIOS],
1454
1411
  resolutions: ["480p", "720p"],
1455
- durations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
1412
+ durations: { min: 4, max: 15 },
1456
1413
  references: { images: 9, videos: 3, audios: 3, audioOnly: false },
1457
1414
  ratioIgnoredWith: ["firstFrame"],
1458
1415
  supports: ["generateAudio", "seed", "lastFrame", "watermark"]
@@ -1525,7 +1482,7 @@ var VIDEO_MODELS = [
1525
1482
  },
1526
1483
  // No resolution default: xAI picks its own unless the caller asks.
1527
1484
  defaults: { durationSeconds: 8, aspectRatio: "16:9" },
1528
- usage: { unit: "reported_cost_usd", modality: "VIDEO", slug: "grok" },
1485
+ usage: { unit: "reported_cost_usd", slug: "grok" },
1529
1486
  pricingKind: "video_per_second",
1530
1487
  display: {
1531
1488
  provider: "xai",
@@ -1559,6 +1516,7 @@ var VIDEO_MODELS = [
1559
1516
  pricingKind: "video_per_second",
1560
1517
  display: {
1561
1518
  provider: "kuaishou",
1519
+ logo: "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/kling-color.png",
1562
1520
  description: "Kuaishou Kling 2.5 Turbo Pro image-to-video; animates a single input image from a text prompt with an optional end image, 5- or 10-second clips."
1563
1521
  },
1564
1522
  capabilities: { ...FRAMES_EXCLUDE_REFERENCES }
@@ -1589,6 +1547,7 @@ var VIDEO_MODELS = [
1589
1547
  pricingKind: "video_per_second",
1590
1548
  display: {
1591
1549
  provider: "kuaishou",
1550
+ logo: "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/kling-color.png",
1592
1551
  description: "Kuaishou Kling 3.0 Pro image-to-video; a required start image plus a text prompt (or multi-shot prompts) with optional end image and native audio, 3-15 second clips."
1593
1552
  },
1594
1553
  capabilities: { ...FRAMES_EXCLUDE_REFERENCES }
@@ -1622,10 +1581,11 @@ var VIDEO_MODELS = [
1622
1581
  supports: ["generateAudio", "lastFrame"]
1623
1582
  },
1624
1583
  defaults: { durationSeconds: 5, aspectRatio: "16:9", generateAudio: false, mode: "pro" },
1625
- usage: { unit: "compute_seconds", modality: "VIDEO" },
1584
+ usage: { unit: "compute_seconds" },
1626
1585
  pricingKind: "video_per_second",
1627
1586
  display: {
1628
1587
  provider: "kuaishou",
1588
+ logo: "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/kling-color.png",
1629
1589
  description: "Kuaishou Kling Video 3.0 Omni unified generation and editing from text, start/end images, up to 7 reference images, and reference video; up to 15 seconds at up to 1080p."
1630
1590
  },
1631
1591
  capabilities: {}
@@ -1655,6 +1615,7 @@ var VIDEO_MODELS = [
1655
1615
  pricingKind: "video_per_second",
1656
1616
  display: {
1657
1617
  provider: "minimax",
1618
+ logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/f4c2e906-28b7-4a4a-b491-df8fef7808ed.png",
1658
1619
  description: "MiniMax H3 multimodal video model for text-to-video, image-to-video (first/last frame), and reference-to-video with native audio, up to 2K."
1659
1620
  },
1660
1621
  capabilities: { ...FRAMES_EXCLUDE_REFERENCES }
@@ -1684,6 +1645,7 @@ var VIDEO_MODELS = [
1684
1645
  pricingKind: "video_per_second",
1685
1646
  display: {
1686
1647
  provider: "minimax",
1648
+ logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/f4c2e906-28b7-4a4a-b491-df8fef7808ed.png",
1687
1649
  description: "High-speed MiniMax H3 Max variant for text-to-video and image-to-video (first/last frame) only, up to 768p."
1688
1650
  },
1689
1651
  capabilities: { ...FRAMES_EXCLUDE_REFERENCES }
@@ -1714,6 +1676,7 @@ var VIDEO_MODELS = [
1714
1676
  pricingKind: "video_per_second",
1715
1677
  display: {
1716
1678
  provider: "minimax",
1679
+ logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/f4c2e906-28b7-4a4a-b491-df8fef7808ed.png",
1717
1680
  description: "MiniMax H3 reference-to-video mode guided by up to 9 reference images, 3 reference videos, and 3 audio clips; reference and image-to-video inputs cannot be mixed."
1718
1681
  },
1719
1682
  capabilities: {}
@@ -1744,6 +1707,7 @@ var VIDEO_MODELS = [
1744
1707
  pricingKind: "video_per_second",
1745
1708
  display: {
1746
1709
  provider: "minimax",
1710
+ logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/f4c2e906-28b7-4a4a-b491-df8fef7808ed.png",
1747
1711
  description: "MiniMax H3 Max reference-to-video on fal; conditions on reference images, videos, and audio. MiniMax's own docs do not list a reference mode for H3 Max."
1748
1712
  },
1749
1713
  capabilities: {}
@@ -1769,6 +1733,7 @@ var VIDEO_MODELS = [
1769
1733
  pricingKind: "video_per_second",
1770
1734
  display: {
1771
1735
  provider: "kuaishou",
1736
+ logo: "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/kling-color.png",
1772
1737
  description: "Kuaishou Kling O1 Reference Video-to-Video; a prompt plus a 3-10 second reference video (optional reference images) generates 3-10 second clips preserving motion and camera language."
1773
1738
  },
1774
1739
  capabilities: { acceptsSourceVideo: true }
@@ -1788,10 +1753,11 @@ var VIDEO_MODELS = [
1788
1753
  supports: ["lastFrame"]
1789
1754
  },
1790
1755
  defaults: { durationSeconds: 6, resolution: "768p" },
1791
- usage: { unit: "compute_seconds", modality: "VIDEO" },
1756
+ usage: { unit: "compute_seconds" },
1792
1757
  pricingKind: "video_per_second",
1793
1758
  display: {
1794
1759
  provider: "minimax",
1760
+ logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/f4c2e906-28b7-4a4a-b491-df8fef7808ed.png",
1795
1761
  description: "MiniMax Hailuo 02 text-to-video and image-to-video model with realistic physics and strong prompt following; outputs 768p at 6 or 10 seconds."
1796
1762
  },
1797
1763
  capabilities: {}
@@ -1828,6 +1794,407 @@ var MODELS = [
1828
1794
  ...OTHER_MODELS
1829
1795
  ];
1830
1796
 
1797
+ // src/catalog/schema.ts
1798
+ import { z } from "zod";
1799
+ var ADAPTER_IDS = [
1800
+ "ai-sdk-text",
1801
+ "google-image",
1802
+ "openai-image",
1803
+ "google-genai",
1804
+ "ark",
1805
+ "fal",
1806
+ "replicate",
1807
+ "prodia",
1808
+ "higgsfield",
1809
+ "xai-video"
1810
+ ];
1811
+ var ModelTypeSchema = z.enum(["text", "image", "video", "audio", "upscale", "bg-remove"]);
1812
+ var LifecycleSchema = z.enum(["active", "deprecated", "retired"]);
1813
+ var AdapterSchema = z.enum(ADAPTER_IDS);
1814
+ var AspectRatioSchema = z.enum([
1815
+ "1:1",
1816
+ "16:9",
1817
+ "9:16",
1818
+ "4:3",
1819
+ "3:4",
1820
+ "3:2",
1821
+ "2:3",
1822
+ "4:5",
1823
+ "5:4",
1824
+ "21:9",
1825
+ "9:21",
1826
+ "97:30",
1827
+ "adaptive"
1828
+ ]);
1829
+ var ImageSizeSchema = z.enum(["512", "1K", "2K", "4K"]);
1830
+ var VideoResolutionSchema = z.enum(["360p", "480p", "720p", "768p", "1080p", "2k", "4k"]);
1831
+ var ImageQualitySchema = z.enum(["auto", "low", "medium", "high", "xhigh", "max"]);
1832
+ var OutputFormatSchema = z.enum(["png", "jpeg", "webp"]);
1833
+ var RequiredInputSchema = z.enum(["firstFrame", "sourceVideo", "references"]);
1834
+ var SupportedOptionSchema = z.enum([
1835
+ "seed",
1836
+ "quality",
1837
+ "negativePrompt",
1838
+ "cfgScale",
1839
+ "generateAudio",
1840
+ "promptExpansion",
1841
+ "lastFrame",
1842
+ "count",
1843
+ "outputFormat",
1844
+ "scaleFactor",
1845
+ "safetySettings",
1846
+ "temperature",
1847
+ "upscale",
1848
+ "watermark",
1849
+ "safetyChecker",
1850
+ "instrumental"
1851
+ ]);
1852
+ var UsageUnitSchema = z.enum([
1853
+ "tokens",
1854
+ "images",
1855
+ "seconds",
1856
+ "reported_cost_usd",
1857
+ "compute_seconds"
1858
+ ]);
1859
+ var PricingKindSchema = z.enum(["token", "image_size", "video_per_second", "flat"]);
1860
+ var ProviderOptionValueSchema = z.lazy(
1861
+ () => z.union([
1862
+ z.string(),
1863
+ z.number(),
1864
+ z.boolean(),
1865
+ z.array(ProviderOptionValueSchema),
1866
+ z.record(z.string(), ProviderOptionValueSchema)
1867
+ ])
1868
+ );
1869
+ var ProviderOptionsSchema = z.record(z.string(), z.record(z.string(), ProviderOptionValueSchema));
1870
+ var ReferenceLimitsSchema = z.looseObject({
1871
+ images: z.number().optional(),
1872
+ videos: z.number().optional(),
1873
+ audios: z.number().optional(),
1874
+ total: z.number().optional(),
1875
+ audioOnly: z.boolean().optional()
1876
+ });
1877
+ var ModelConstraintsSchema = z.looseObject({
1878
+ aspectRatios: z.array(AspectRatioSchema).optional(),
1879
+ sizes: z.array(ImageSizeSchema).optional(),
1880
+ resolutions: z.array(VideoResolutionSchema).optional(),
1881
+ durations: z.union([z.looseObject({ min: z.number(), max: z.number() }), z.array(z.number())]).optional(),
1882
+ durationPresets: z.array(z.number()).optional(),
1883
+ qualityOptions: z.array(z.string()).optional(),
1884
+ exactSizes: z.record(z.string(), z.string()).optional(),
1885
+ references: ReferenceLimitsSchema.optional(),
1886
+ requires: z.array(RequiredInputSchema).optional(),
1887
+ supports: z.array(SupportedOptionSchema).optional(),
1888
+ ratioIgnoredWith: z.array(z.enum(["firstFrame", "sourceVideo"])).optional()
1889
+ });
1890
+ var MediaRefSchema = z.union([
1891
+ z.looseObject({ url: z.string(), label: z.string().optional() }),
1892
+ z.looseObject({
1893
+ bytes: z.instanceof(Uint8Array),
1894
+ mime: z.string(),
1895
+ label: z.string().optional()
1896
+ })
1897
+ ]);
1898
+ var ImageSafetySettingSchema = z.looseObject({ category: z.string(), threshold: z.string() });
1899
+ var UpscaleOptionsSchema = z.looseObject({
1900
+ enhanceModel: z.string().optional(),
1901
+ subjectDetection: z.string().optional(),
1902
+ faceEnhancement: z.boolean().optional(),
1903
+ faceEnhancementCreativity: z.number().optional(),
1904
+ faceEnhancementStrength: z.number().optional()
1905
+ });
1906
+ var DefaultsSchema = z.looseObject({
1907
+ references: z.array(MediaRefSchema).optional(),
1908
+ aspectRatio: AspectRatioSchema.optional(),
1909
+ size: ImageSizeSchema.optional(),
1910
+ exactSize: z.string().optional(),
1911
+ quality: ImageQualitySchema.optional(),
1912
+ seed: z.number().optional(),
1913
+ count: z.number().optional(),
1914
+ outputFormat: OutputFormatSchema.optional(),
1915
+ scaleFactor: z.number().optional(),
1916
+ safetySettings: z.array(ImageSafetySettingSchema).optional(),
1917
+ temperature: z.number().optional(),
1918
+ upscale: UpscaleOptionsSchema.optional(),
1919
+ firstFrame: MediaRefSchema.optional(),
1920
+ lastFrame: MediaRefSchema.optional(),
1921
+ sourceVideo: MediaRefSchema.optional(),
1922
+ referenceImages: z.array(MediaRefSchema).optional(),
1923
+ referenceVideos: z.array(MediaRefSchema).optional(),
1924
+ referenceAudios: z.array(MediaRefSchema).optional(),
1925
+ resolution: VideoResolutionSchema.optional(),
1926
+ durationSeconds: z.number().optional(),
1927
+ generateAudio: z.boolean().optional(),
1928
+ negativePrompt: z.string().optional(),
1929
+ cfgScale: z.number().optional(),
1930
+ promptExpansion: z.enum(["fast", "balanced", "quality"]).optional(),
1931
+ watermark: z.boolean().optional(),
1932
+ safetyChecker: z.boolean().optional(),
1933
+ mode: z.enum(["standard", "pro"]).optional(),
1934
+ instrumental: z.boolean().optional()
1935
+ });
1936
+ var CatalogDisplaySchema = z.looseObject({
1937
+ provider: z.string(),
1938
+ description: z.string(),
1939
+ logo: z.string().optional(),
1940
+ costTier: z.union([z.literal(1), z.literal(2), z.literal(3)]).optional(),
1941
+ recommended: z.boolean().optional(),
1942
+ sortOrder: z.number().optional(),
1943
+ chat: z.looseObject({
1944
+ providerOptions: ProviderOptionsSchema.optional(),
1945
+ temperature: z.number().optional()
1946
+ }).optional()
1947
+ });
1948
+ var CatalogCapabilitiesSchema = z.looseObject({
1949
+ acceptsSourceVideo: z.boolean().optional(),
1950
+ framesExcludeReferences: z.boolean().optional(),
1951
+ reasoning: z.boolean().optional(),
1952
+ vision: z.boolean().optional(),
1953
+ contextWindow: z.number().optional()
1954
+ });
1955
+ var CatalogModelSchemaBase = z.looseObject({
1956
+ id: z.string().min(1),
1957
+ aliases: z.array(z.string()).default([]),
1958
+ label: z.string().min(1),
1959
+ type: ModelTypeSchema,
1960
+ adapter: AdapterSchema,
1961
+ providerModelId: z.string().min(1),
1962
+ lifecycle: LifecycleSchema,
1963
+ replacedBy: z.string().optional(),
1964
+ exposure: z.enum(["catalog", "internal"]),
1965
+ constraints: ModelConstraintsSchema,
1966
+ defaults: DefaultsSchema,
1967
+ providerOptions: ProviderOptionsSchema.optional(),
1968
+ usage: z.looseObject({
1969
+ unit: UsageUnitSchema,
1970
+ slug: z.string().optional(),
1971
+ providerLabel: z.string().optional()
1972
+ }),
1973
+ pricingKind: PricingKindSchema,
1974
+ display: CatalogDisplaySchema.optional(),
1975
+ capabilities: CatalogCapabilitiesSchema.optional()
1976
+ }).superRefine((row, ctx) => {
1977
+ if (row.lifecycle === "active" && !row.display) {
1978
+ ctx.addIssue({
1979
+ code: "custom",
1980
+ path: ["display"],
1981
+ message: "active rows need display"
1982
+ });
1983
+ }
1984
+ if (row.lifecycle === "active" && row.type === "text" && !row.capabilities?.contextWindow) {
1985
+ ctx.addIssue({
1986
+ code: "custom",
1987
+ path: ["capabilities", "contextWindow"],
1988
+ message: "active text rows need contextWindow"
1989
+ });
1990
+ }
1991
+ if (row.replacedBy !== void 0 && row.replacedBy === row.id) {
1992
+ ctx.addIssue({
1993
+ code: "custom",
1994
+ path: ["replacedBy"],
1995
+ message: "replacedBy must not equal id"
1996
+ });
1997
+ }
1998
+ });
1999
+ var CatalogModelSchema = CatalogModelSchemaBase;
2000
+ var CatalogSchema = z.array(CatalogModelSchemaBase).superRefine((rows, ctx) => {
2001
+ const seenIds = /* @__PURE__ */ new Map();
2002
+ rows.forEach((row, index) => {
2003
+ if (seenIds.has(row.id)) {
2004
+ ctx.addIssue({
2005
+ code: "custom",
2006
+ path: [index, "id"],
2007
+ message: `Duplicate model id "${row.id}"`
2008
+ });
2009
+ } else {
2010
+ seenIds.set(row.id, index);
2011
+ }
2012
+ });
2013
+ const seenAliases = /* @__PURE__ */ new Map();
2014
+ rows.forEach((row, index) => {
2015
+ row.aliases.forEach((alias, aliasIndex) => {
2016
+ const path = [index, "aliases", aliasIndex];
2017
+ if (alias === row.id || seenIds.has(alias)) {
2018
+ ctx.addIssue({
2019
+ code: "custom",
2020
+ path,
2021
+ message: `Alias "${alias}" collides with a model id`
2022
+ });
2023
+ return;
2024
+ }
2025
+ if (seenAliases.has(alias)) {
2026
+ ctx.addIssue({
2027
+ code: "custom",
2028
+ path,
2029
+ message: `Duplicate alias "${alias}"`
2030
+ });
2031
+ } else {
2032
+ seenAliases.set(alias, index);
2033
+ }
2034
+ });
2035
+ });
2036
+ });
2037
+
2038
+ // src/catalog/live.ts
2039
+ var liveCatalog = new Catalog(MODELS);
2040
+
2041
+ // src/catalog/load.ts
2042
+ var memo;
2043
+ var timer;
2044
+ var revision;
2045
+ var origin = "snapshot";
2046
+ function rowCount() {
2047
+ return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
2048
+ }
2049
+ function authHeaders(auth) {
2050
+ return "bearer" in auth ? { Authorization: `Bearer ${auth.bearer}` } : { "x-api-key": auth.apiKey };
2051
+ }
2052
+ function describeError(err) {
2053
+ return err instanceof Error ? err.message : String(err);
2054
+ }
2055
+ function parseEnvelope(json) {
2056
+ if (typeof json !== "object" || json === null || !("rows" in json)) {
2057
+ throw new Error("invalid catalog response: missing rows");
2058
+ }
2059
+ const rows = CatalogSchema.parse(json.rows);
2060
+ const rev = json.revision;
2061
+ if (typeof rev === "string") return { rows, revision: rev };
2062
+ return { rows };
2063
+ }
2064
+ function logPrimed(logger, result) {
2065
+ const { origin: loggedOrigin, rowCount: loggedCount, revision: loggedRevision } = result;
2066
+ logger.info("[modelkit] catalog primed", {
2067
+ origin: loggedOrigin,
2068
+ rowCount: loggedCount,
2069
+ revision: loggedRevision
2070
+ });
2071
+ }
2072
+ async function fetchRemote(source, logger) {
2073
+ const fetchImpl = source.fetch ?? globalThis.fetch;
2074
+ const headers2 = authHeaders(source.auth);
2075
+ if (revision !== void 0) headers2["If-None-Match"] = `"${revision}"`;
2076
+ const res = await fetchImpl(`${source.baseUrl}/models/catalog`, {
2077
+ headers: headers2,
2078
+ signal: AbortSignal.timeout(source.timeoutMs ?? 1e4)
2079
+ });
2080
+ if (res.status === 304) return { kept: true };
2081
+ if (!res.ok) throw new Error(`catalog fetch failed with status ${res.status}`);
2082
+ const json = await res.json();
2083
+ const { rows, revision: rev } = parseEnvelope(json);
2084
+ if (rev === void 0) return { rows, fromCache: false };
2085
+ return { rows, revision: rev, fromCache: false };
2086
+ }
2087
+ async function writeCache(source, logger, rows, rev) {
2088
+ if (!source.cache) return;
2089
+ try {
2090
+ await source.cache.set(JSON.stringify({ rows, revision: rev }));
2091
+ } catch (err) {
2092
+ logger.warn("[modelkit] catalog cache write failed", err);
2093
+ }
2094
+ }
2095
+ async function prime(source, logger) {
2096
+ try {
2097
+ const fetched = await fetchRemote(source, logger);
2098
+ if ("kept" in fetched) {
2099
+ const result2 = { origin, rowCount: rowCount() };
2100
+ if (revision !== void 0) result2.revision = revision;
2101
+ logPrimed(logger, result2);
2102
+ return result2;
2103
+ }
2104
+ liveCatalog.replace(fetched.rows);
2105
+ origin = "remote";
2106
+ revision = fetched.revision;
2107
+ await writeCache(source, logger, fetched.rows, fetched.revision);
2108
+ const result = { origin, rowCount: rowCount() };
2109
+ if (fetched.revision !== void 0) result.revision = fetched.revision;
2110
+ logPrimed(logger, result);
2111
+ return result;
2112
+ } catch (err) {
2113
+ logger.warn("[modelkit] catalog remote failed, trying cache", err);
2114
+ const error = describeError(err);
2115
+ try {
2116
+ const cached = await source.cache?.get();
2117
+ if (!cached) throw new Error("no cached catalog");
2118
+ const { rows, revision: rev } = parseEnvelope(JSON.parse(cached));
2119
+ liveCatalog.replace(rows);
2120
+ origin = "last-good";
2121
+ revision = rev;
2122
+ const result = { origin, rowCount: rowCount(), error };
2123
+ if (rev !== void 0) result.revision = rev;
2124
+ logPrimed(logger, result);
2125
+ return result;
2126
+ } catch (cacheErr) {
2127
+ logger.warn("[modelkit] catalog cache failed, using snapshot", cacheErr);
2128
+ liveCatalog.replace([...MODELS]);
2129
+ origin = "snapshot";
2130
+ revision = void 0;
2131
+ const result = {
2132
+ origin,
2133
+ rowCount: rowCount(),
2134
+ error
2135
+ };
2136
+ logPrimed(logger, result);
2137
+ return result;
2138
+ }
2139
+ }
2140
+ }
2141
+ async function refresh(source, logger) {
2142
+ try {
2143
+ const fetched = await fetchRemote(source, logger);
2144
+ if ("kept" in fetched) return;
2145
+ liveCatalog.replace(fetched.rows);
2146
+ origin = "remote";
2147
+ revision = fetched.revision;
2148
+ await writeCache(source, logger, fetched.rows, fetched.revision);
2149
+ } catch (err) {
2150
+ logger.warn("[modelkit] catalog refresh failed, keeping current rows", err);
2151
+ }
2152
+ }
2153
+ function primeCatalog(source) {
2154
+ if (memo) return memo;
2155
+ const logger = source.logger ?? console;
2156
+ memo = prime(source, logger).then((result) => {
2157
+ const ttlMs = source.ttlMs ?? 3e5;
2158
+ if (ttlMs > 0 && timer === void 0) {
2159
+ timer = setInterval(() => void refresh(source, logger), ttlMs);
2160
+ const maybeUnref = timer;
2161
+ maybeUnref.unref?.();
2162
+ }
2163
+ return result;
2164
+ });
2165
+ return memo;
2166
+ }
2167
+ function resetLiveCatalog() {
2168
+ if (timer !== void 0) {
2169
+ clearInterval(timer);
2170
+ timer = void 0;
2171
+ }
2172
+ memo = void 0;
2173
+ revision = void 0;
2174
+ origin = "snapshot";
2175
+ liveCatalog.replace([...MODELS]);
2176
+ }
2177
+
2178
+ // src/catalog/file-cache.ts
2179
+ import { readFile, rename, writeFile } from "fs/promises";
2180
+ function fileCatalogCache(path) {
2181
+ return {
2182
+ async get() {
2183
+ try {
2184
+ return await readFile(path, "utf8");
2185
+ } catch (err) {
2186
+ if (err?.code === "ENOENT") return null;
2187
+ throw err;
2188
+ }
2189
+ },
2190
+ async set(json) {
2191
+ const tmp = `${path}.tmp`;
2192
+ await writeFile(tmp, json, "utf8");
2193
+ await rename(tmp, path);
2194
+ }
2195
+ };
2196
+ }
2197
+
1831
2198
  // src/resolve-options.ts
1832
2199
  var SIZE_ORDER = ["512", "1K", "2K", "4K"];
1833
2200
  var RESOLUTION_ORDER = ["360p", "480p", "720p", "768p", "1080p", "2k", "4k"];
@@ -2253,21 +2620,21 @@ function keysFromEnv(env, prefix = "") {
2253
2620
  }
2254
2621
 
2255
2622
  // src/retry.ts
2256
- import { z as z2 } from "zod";
2623
+ import { z as z3 } from "zod";
2257
2624
 
2258
2625
  // src/json.ts
2259
- import { z } from "zod";
2260
- var JsonValueSchema = z.lazy(
2261
- () => z.union([
2262
- z.string(),
2263
- z.number(),
2264
- z.boolean(),
2265
- z.null(),
2266
- z.array(JsonValueSchema),
2267
- z.record(z.string(), JsonValueSchema)
2626
+ import { z as z2 } from "zod";
2627
+ var JsonValueSchema = z2.lazy(
2628
+ () => z2.union([
2629
+ z2.string(),
2630
+ z2.number(),
2631
+ z2.boolean(),
2632
+ z2.null(),
2633
+ z2.array(JsonValueSchema),
2634
+ z2.record(z2.string(), JsonValueSchema)
2268
2635
  ])
2269
2636
  );
2270
- var JsonObjectSchema = z.record(z.string(), JsonValueSchema);
2637
+ var JsonObjectSchema = z2.record(z2.string(), JsonValueSchema);
2271
2638
  async function readErrorBody(res) {
2272
2639
  const text2 = await res.text().catch(() => "");
2273
2640
  try {
@@ -2276,11 +2643,11 @@ async function readErrorBody(res) {
2276
2643
  return text2;
2277
2644
  }
2278
2645
  }
2279
- var thrownErrorSchema = z.object({
2280
- message: z.string().optional(),
2281
- status: z.number().optional(),
2282
- statusCode: z.number().optional(),
2283
- responseBody: z.string().optional()
2646
+ var thrownErrorSchema = z2.object({
2647
+ message: z2.string().optional(),
2648
+ status: z2.number().optional(),
2649
+ statusCode: z2.number().optional(),
2650
+ responseBody: z2.string().optional()
2284
2651
  });
2285
2652
  function describeThrown(cause) {
2286
2653
  const parsed = thrownErrorSchema.safeParse(cause);
@@ -2291,7 +2658,7 @@ function describeThrown(cause) {
2291
2658
  }
2292
2659
 
2293
2660
  // src/retry.ts
2294
- var textBody = z2.string();
2661
+ var textBody = z3.string();
2295
2662
  function classifyHttpError(status, body, provider, model) {
2296
2663
  const asText = textBody.safeParse(body);
2297
2664
  const text2 = asText.success ? asText.data : JSON.stringify(body);
@@ -2348,12 +2715,12 @@ function sleep(ms, signal) {
2348
2715
  rejectAborted();
2349
2716
  return;
2350
2717
  }
2351
- let timer;
2718
+ let timer2;
2352
2719
  const onAbort = () => {
2353
- if (timer !== void 0) clearTimeout(timer);
2720
+ if (timer2 !== void 0) clearTimeout(timer2);
2354
2721
  rejectAborted();
2355
2722
  };
2356
- timer = setTimeout(() => {
2723
+ timer2 = setTimeout(() => {
2357
2724
  signal?.removeEventListener("abort", onAbort);
2358
2725
  resolve();
2359
2726
  }, ms);
@@ -2439,7 +2806,7 @@ function passthroughTextModel(model) {
2439
2806
  exposure: "internal",
2440
2807
  constraints: {},
2441
2808
  defaults: {},
2442
- usage: { unit: "tokens", modality: "TEXT" },
2809
+ usage: { unit: "tokens" },
2443
2810
  pricingKind: "token"
2444
2811
  };
2445
2812
  }
@@ -2506,7 +2873,7 @@ import {
2506
2873
  streamObject as aiStreamObject2,
2507
2874
  streamText as aiStreamText2
2508
2875
  } from "ai";
2509
- import { z as z4 } from "zod";
2876
+ import { z as z5 } from "zod";
2510
2877
 
2511
2878
  // src/adapters/media-ref.ts
2512
2879
  function isUrlRef(ref) {
@@ -2591,7 +2958,7 @@ import { createPerplexity } from "@ai-sdk/perplexity";
2591
2958
  import { createXai } from "@ai-sdk/xai";
2592
2959
  import { createDeepSeek } from "@ai-sdk/deepseek";
2593
2960
  import { createMoonshotAI } from "@ai-sdk/moonshotai";
2594
- import { z as z3 } from "zod";
2961
+ import { z as z4 } from "zod";
2595
2962
  var TEXT_PROVIDERS = [
2596
2963
  "openai",
2597
2964
  "anthropic",
@@ -2602,7 +2969,7 @@ var TEXT_PROVIDERS = [
2602
2969
  "moonshot",
2603
2970
  "minimax"
2604
2971
  ];
2605
- var textProviderSchema = z3.enum(TEXT_PROVIDERS);
2972
+ var textProviderSchema = z4.enum(TEXT_PROVIDERS);
2606
2973
  function isTextProvider(value) {
2607
2974
  return textProviderSchema.safeParse(value).success;
2608
2975
  }
@@ -2772,10 +3139,10 @@ function textAbortOptions(sdk, context) {
2772
3139
  if (abortSignal) return { abortSignal };
2773
3140
  return {};
2774
3141
  }
2775
- var catalogId = z4.string();
2776
- var exactSize = z4.templateLiteral([z4.number(), "x", z4.number()]);
2777
- var sdkRatio = z4.templateLiteral([z4.number(), ":", z4.number()]);
2778
- var sizeTier = z4.enum(["512", "1K", "2K", "4K"]);
3142
+ var catalogId = z5.string();
3143
+ var exactSize = z5.templateLiteral([z5.number(), "x", z5.number()]);
3144
+ var sdkRatio = z5.templateLiteral([z5.number(), ":", z5.number()]);
3145
+ var sizeTier = z5.enum(["512", "1K", "2K", "4K"]);
2779
3146
  function isCatalogId(model) {
2780
3147
  return catalogId.safeParse(model).success;
2781
3148
  }
@@ -2842,7 +3209,7 @@ function logCoercions(logger, modelId, warnings) {
2842
3209
  logger.warn(`[modelkit] ${modelId} request coerced`, { model: modelId, warnings });
2843
3210
  }
2844
3211
  function createModelKit(config, adapters) {
2845
- const catalog = new Catalog(MODELS).withOverrides(config.catalogOverride ?? []);
3212
+ const catalog = config.catalogOverride ? liveCatalog.withOverrides(config.catalogOverride) : liveCatalog;
2846
3213
  const logger = config.logger ?? console;
2847
3214
  const fetchImpl = config.fetch ?? globalThis.fetch;
2848
3215
  function context(model, call, warnings) {
@@ -3296,7 +3663,7 @@ function createModelKit(config, adapters) {
3296
3663
  }
3297
3664
 
3298
3665
  // src/adapters/ark.ts
3299
- import { z as z5 } from "zod";
3666
+ import { z as z6 } from "zod";
3300
3667
  var ARK_BASE_URL = "https://ark.ap-southeast.bytepluses.com/api/v3";
3301
3668
  var SUBMIT_PATH = "/contents/generations/tasks";
3302
3669
  var SEEDANCE_POLL_INTERVAL_MS = 15e3;
@@ -3373,7 +3740,7 @@ function arkKey(ctx) {
3373
3740
  return key;
3374
3741
  }
3375
3742
  function throwArkError(status, body, model) {
3376
- const parsed = z5.string().safeParse(body);
3743
+ const parsed = z6.string().safeParse(body);
3377
3744
  const text2 = parsed.success ? parsed.data : JSON.stringify(body ?? "");
3378
3745
  if (/sensitive.?content|human.?face/i.test(text2)) {
3379
3746
  const init = {
@@ -3411,13 +3778,13 @@ function sniffedImageMime(bytes) {
3411
3778
  return "image/webp";
3412
3779
  return "image/jpeg";
3413
3780
  }
3414
- var SeedreamImageSchema = z5.object({
3415
- url: z5.string().optional(),
3416
- b64_json: z5.string().optional()
3781
+ var SeedreamImageSchema = z6.object({
3782
+ url: z6.string().optional(),
3783
+ b64_json: z6.string().optional()
3417
3784
  });
3418
- var SeedreamResponseSchema = z5.object({
3419
- data: z5.array(SeedreamImageSchema).optional(),
3420
- error: z5.object({ message: z5.string().optional(), code: z5.string().optional() }).optional()
3785
+ var SeedreamResponseSchema = z6.object({
3786
+ data: z6.array(SeedreamImageSchema).optional(),
3787
+ error: z6.object({ message: z6.string().optional(), code: z6.string().optional() }).optional()
3421
3788
  });
3422
3789
  function retryOptsFor(ctx, attempts = 3) {
3423
3790
  const opts = { attempts };
@@ -3489,21 +3856,21 @@ async function generateSeedreamImage(req, ctx) {
3489
3856
  if (req.quality !== void 0) usage2.imageQuality = req.quality;
3490
3857
  return { images: [{ bytes, mime: sniffedImageMime(bytes) }], usage: usage2, raw: data };
3491
3858
  }
3492
- var SeedanceUsageSchema = z5.object({
3493
- total_tokens: z5.number().optional(),
3494
- completion_tokens: z5.number().optional()
3859
+ var SeedanceUsageSchema = z6.object({
3860
+ total_tokens: z6.number().optional(),
3861
+ completion_tokens: z6.number().optional()
3495
3862
  });
3496
- var SeedanceResponseSchema = z5.object({
3497
- id: z5.string().optional(),
3498
- status: z5.string().optional(),
3499
- content: z5.object({ video_url: z5.string().optional() }).optional(),
3863
+ var SeedanceResponseSchema = z6.object({
3864
+ id: z6.string().optional(),
3865
+ status: z6.string().optional(),
3866
+ content: z6.object({ video_url: z6.string().optional() }).optional(),
3500
3867
  usage: SeedanceUsageSchema.optional(),
3501
- duration: z5.number().optional(),
3502
- framespersecond: z5.number().optional(),
3503
- resolution: z5.string().optional(),
3504
- error: z5.union([z5.string(), z5.object({ message: z5.string().optional() })]).optional()
3868
+ duration: z6.number().optional(),
3869
+ framespersecond: z6.number().optional(),
3870
+ resolution: z6.string().optional(),
3871
+ error: z6.union([z6.string(), z6.object({ message: z6.string().optional() })]).optional()
3505
3872
  });
3506
- var SeedanceErrorMessageSchema = z5.object({ message: z5.string().optional() });
3873
+ var SeedanceErrorMessageSchema = z6.object({ message: z6.string().optional() });
3507
3874
  function seedanceUsage(ctx, req, duration) {
3508
3875
  const usage2 = {
3509
3876
  model: ctx.model.id,
@@ -3517,7 +3884,7 @@ function seedanceUsage(ctx, req, duration) {
3517
3884
  return usage2;
3518
3885
  }
3519
3886
  function seedanceErrorMessage(error, status) {
3520
- const asString = z5.string().safeParse(error);
3887
+ const asString = z6.string().safeParse(error);
3521
3888
  if (asString.success) return asString.data;
3522
3889
  const asObject = SeedanceErrorMessageSchema.safeParse(error);
3523
3890
  if (asObject.success && asObject.data.message !== void 0) return asObject.data.message;
@@ -3666,7 +4033,7 @@ async function generateSeedanceVideo(req, ctx) {
3666
4033
  }
3667
4034
 
3668
4035
  // src/adapters/fal.ts
3669
- import { z as z6 } from "zod";
4036
+ import { z as z7 } from "zod";
3670
4037
  import { createFalClient } from "@fal-ai/client";
3671
4038
  var MUSE_T2I_ENDPOINT = "meta/muse-image/text-to-image";
3672
4039
  var MUSE_EDIT_ENDPOINT = "meta/muse-image/edit";
@@ -3674,7 +4041,7 @@ var KLING_O1_ENDPOINT = "fal-ai/kling-video/o1/video-to-video/reference";
3674
4041
  var FAL_QUEUE_HOST = "https://queue.fal.run";
3675
4042
  var PASSTHROUGH_POLL_MS = 2e3;
3676
4043
  var PASSTHROUGH_MAX_WAIT_MS = 18e4;
3677
- var falSubscribePayloadSchema = z6.object({ data: JsonValueSchema });
4044
+ var falSubscribePayloadSchema = z7.object({ data: JsonValueSchema });
3678
4045
  function defaultCreateFalClient(opts) {
3679
4046
  const client2 = createFalClient(opts);
3680
4047
  return {
@@ -3724,7 +4091,7 @@ function createFalAdapter(deps = defaultDeps) {
3724
4091
  };
3725
4092
  }
3726
4093
  var falAdapter = createFalAdapter();
3727
- var falDetailSchema = z6.object({ detail: JsonValueSchema });
4094
+ var falDetailSchema = z7.object({ detail: JsonValueSchema });
3728
4095
  function liftDetail(body) {
3729
4096
  const parsed = falDetailSchema.safeParse(body);
3730
4097
  const detail = parsed.success ? parsed.data.detail : void 0;
@@ -3733,11 +4100,11 @@ function liftDetail(body) {
3733
4100
  function falError(status, body, model) {
3734
4101
  return classifyHttpError(status, liftDetail(body), "fal", model);
3735
4102
  }
3736
- var falSdkThrownSchema = z6.object({
3737
- status: z6.number().optional(),
3738
- statusCode: z6.number().optional(),
4103
+ var falSdkThrownSchema = z7.object({
4104
+ status: z7.number().optional(),
4105
+ statusCode: z7.number().optional(),
3739
4106
  body: JsonValueSchema.optional(),
3740
- message: z6.string().optional()
4107
+ message: z7.string().optional()
3741
4108
  });
3742
4109
  function falSdkError(cause, model) {
3743
4110
  const parsed = falSdkThrownSchema.safeParse(cause);
@@ -3781,12 +4148,12 @@ async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
3781
4148
  if (init.body !== void 0) request.body = init.body;
3782
4149
  return fetchImpl(cfg.baseUrl, request);
3783
4150
  }
3784
- var falQueueSubmitSchema = z6.object({
3785
- request_id: z6.string(),
3786
- status_url: z6.string(),
3787
- response_url: z6.string()
4151
+ var falQueueSubmitSchema = z7.object({
4152
+ request_id: z7.string(),
4153
+ status_url: z7.string(),
4154
+ response_url: z7.string()
3788
4155
  });
3789
- var falQueueStatusSchema = z6.object({ status: z6.string() });
4156
+ var falQueueStatusSchema = z7.object({ status: z7.string() });
3790
4157
  async function passthroughRequest(ctx, endpoint, input) {
3791
4158
  const cfg = gatewayConfig(ctx);
3792
4159
  const submitRes = await gatewayFetch(cfg, ctx.fetch, `${FAL_QUEUE_HOST}/${endpoint}`, {
@@ -3912,11 +4279,11 @@ async function decodeImage(ctx, url, contentType) {
3912
4279
  const mime = res.headers.get("content-type") ?? contentType ?? "image/png";
3913
4280
  return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
3914
4281
  }
3915
- var museImageResultSchema = z6.object({
3916
- images: z6.array(
3917
- z6.object({
3918
- url: z6.string().optional(),
3919
- content_type: z6.string().nullable().optional()
4282
+ var museImageResultSchema = z7.object({
4283
+ images: z7.array(
4284
+ z7.object({
4285
+ url: z7.string().optional(),
4286
+ content_type: z7.string().nullable().optional()
3920
4287
  })
3921
4288
  ).optional()
3922
4289
  });
@@ -4008,8 +4375,8 @@ function klingO1Input(req) {
4008
4375
  if (refs.length > 0) input.image_urls = refs;
4009
4376
  return input;
4010
4377
  }
4011
- var falVideoResultSchema = z6.object({
4012
- video: z6.object({ url: z6.string().optional() }).optional()
4378
+ var falVideoResultSchema = z7.object({
4379
+ video: z7.object({ url: z7.string().optional() }).optional()
4013
4380
  });
4014
4381
  function extractVideoUrl(result, endpoint, model) {
4015
4382
  const parsed = falVideoResultSchema.safeParse(result);
@@ -4199,13 +4566,13 @@ async function passthroughVideoJob(ctx, req, endpoint, input) {
4199
4566
  }
4200
4567
 
4201
4568
  // src/adapters/google-genai.ts
4202
- import { z as z8 } from "zod";
4569
+ import { z as z9 } from "zod";
4203
4570
  import {
4204
4571
  GoogleGenAI
4205
4572
  } from "@google/genai";
4206
4573
 
4207
4574
  // src/adapters/google-files.ts
4208
- import { z as z7 } from "zod";
4575
+ import { z as z8 } from "zod";
4209
4576
  var GOOGLE_FILES_BASE = "https://generativelanguage.googleapis.com";
4210
4577
  var GOOGLE_FILES_POLL_INTERVAL_MS = 2e3;
4211
4578
  var GOOGLE_FILES_POLL_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -4215,17 +4582,17 @@ var GENERIC_MEDIA_TYPES = /* @__PURE__ */ new Set([
4215
4582
  "binary/octet-stream",
4216
4583
  "application/binary"
4217
4584
  ]);
4218
- var uploadedFileSchema = z7.object({
4219
- file: z7.object({
4220
- uri: z7.string().optional(),
4221
- name: z7.string().optional(),
4222
- state: z7.string().optional(),
4223
- mimeType: z7.string().optional()
4585
+ var uploadedFileSchema = z8.object({
4586
+ file: z8.object({
4587
+ uri: z8.string().optional(),
4588
+ name: z8.string().optional(),
4589
+ state: z8.string().optional(),
4590
+ mimeType: z8.string().optional()
4224
4591
  }).optional()
4225
4592
  });
4226
- var fileStateSchema = z7.object({
4227
- state: z7.string().optional(),
4228
- error: z7.object({ message: z7.string().optional() }).optional()
4593
+ var fileStateSchema = z8.object({
4594
+ state: z8.string().optional(),
4595
+ error: z8.object({ message: z8.string().optional() }).optional()
4229
4596
  });
4230
4597
  function resolveMime(declared, fallback) {
4231
4598
  const clean = declared?.split(";")[0]?.trim().toLowerCase();
@@ -4438,7 +4805,7 @@ var OMNI_POLL_INTERVAL_MS = 1e4;
4438
4805
  var RESULT_TIMEOUT_MS2 = 15 * 60 * 1e3;
4439
4806
  var OMNI_INLINE_LIMIT_BYTES = 4 * 1024 * 1024;
4440
4807
  var MEDIA_PART_INLINE_LIMIT_BYTES = 20 * 1024 * 1024;
4441
- var errorTextSchema = z8.string();
4808
+ var errorTextSchema = z9.string();
4442
4809
  function createGoogleGenaiAdapter(deps = defaultDeps2) {
4443
4810
  const { createGenAIClient } = deps;
4444
4811
  return {
@@ -4996,15 +5363,15 @@ async function prepareGoogleMediaPart(ref, mediaType, ctx) {
4996
5363
  // src/adapters/google-image.ts
4997
5364
  import { createGoogleGenerativeAI as createGoogleGenerativeAI2 } from "@ai-sdk/google";
4998
5365
  import { generateText } from "ai";
4999
- import { z as z9 } from "zod";
5366
+ import { z as z10 } from "zod";
5000
5367
  var GEMINI_IMAGE_TIMEOUT_MS = 6e5;
5001
5368
  var defaultGoogleImageDeps = {
5002
5369
  createGoogleClient: (opts) => createGoogleGenerativeAI2(opts),
5003
5370
  runTextGeneration: (opts) => generateText(opts)
5004
5371
  };
5005
- var causeChainNodeSchema = z9.object({
5006
- message: z9.string().optional(),
5007
- cause: z9.unknown().optional()
5372
+ var causeChainNodeSchema = z10.object({
5373
+ message: z10.string().optional(),
5374
+ cause: z10.unknown().optional()
5008
5375
  });
5009
5376
  function extractBlockReason(cause) {
5010
5377
  let current = cause;
@@ -5125,7 +5492,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
5125
5492
  var googleImageAdapter = createGoogleImageAdapter();
5126
5493
 
5127
5494
  // src/adapters/higgsfield.ts
5128
- import { z as z10 } from "zod";
5495
+ import { z as z11 } from "zod";
5129
5496
 
5130
5497
  // src/adapters/higgsfield-motions.ts
5131
5498
  var MOTION_MAP = {
@@ -5313,14 +5680,14 @@ function videoUsage3(ctx, req, duration) {
5313
5680
  if (req.durationSeconds !== void 0) event.durationSeconds = req.durationSeconds;
5314
5681
  return event;
5315
5682
  }
5316
- var klingCreateSchema = z10.object({ status_url: z10.string() });
5317
- var klingStatusSchema = z10.object({
5318
- status: z10.string().optional(),
5319
- video: z10.object({ url: z10.string().optional() }).optional(),
5683
+ var klingCreateSchema = z11.object({ status_url: z11.string() });
5684
+ var klingStatusSchema = z11.object({
5685
+ status: z11.string().optional(),
5686
+ video: z11.object({ url: z11.string().optional() }).optional(),
5320
5687
  error: JsonValueSchema.optional()
5321
5688
  });
5322
- var errorMessageSchema = z10.object({ message: z10.string().optional() });
5323
- var textValueSchema = z10.string();
5689
+ var errorMessageSchema = z11.object({ message: z11.string().optional() });
5690
+ var textValueSchema = z11.string();
5324
5691
  function klingErrorDetail(error) {
5325
5692
  if (error === void 0) return "unknown_error";
5326
5693
  const asText = textValueSchema.safeParse(error);
@@ -5454,8 +5821,8 @@ async function generateKlingVideo(req, ctx) {
5454
5821
  }
5455
5822
  };
5456
5823
  }
5457
- var dopMotionOptionsSchema = z10.object({
5458
- modelkit: z10.object({ motion: z10.string().optional() }).optional()
5824
+ var dopMotionOptionsSchema = z11.object({
5825
+ modelkit: z11.object({ motion: z11.string().optional() }).optional()
5459
5826
  });
5460
5827
  function dopMotionId(ctx) {
5461
5828
  const parsed = dopMotionOptionsSchema.safeParse(ctx.model.providerOptions);
@@ -5471,7 +5838,7 @@ function dopMotionId(ctx) {
5471
5838
  });
5472
5839
  return id;
5473
5840
  }
5474
- var jsonRecordSchema = z10.record(z10.string(), JsonValueSchema);
5841
+ var jsonRecordSchema = z11.record(z11.string(), JsonValueSchema);
5475
5842
  var DOP_URL_KEYS = ["url", "video_url", "output_url", "result_url", "download_url"];
5476
5843
  var DOP_NESTED_KEYS = ["video", "result", "results"];
5477
5844
  function dopUrl(body) {
@@ -5499,8 +5866,8 @@ function dopUrl(body) {
5499
5866
  }
5500
5867
  return void 0;
5501
5868
  }
5502
- var dopCreateSchema = z10.object({ id: z10.string() });
5503
- var dopStatusSchema = z10.object({ status: z10.string().optional() });
5869
+ var dopCreateSchema = z11.object({ id: z11.string() });
5870
+ var dopStatusSchema = z11.object({ status: z11.string().optional() });
5504
5871
  async function generateDopVideo(req, ctx) {
5505
5872
  const firstFrame = req.firstFrame ? refToUrl(req.firstFrame) : void 0;
5506
5873
  if (!firstFrame) {
@@ -5620,7 +5987,7 @@ var higgsfieldAdapter = {
5620
5987
 
5621
5988
  // src/adapters/openai-image.ts
5622
5989
  import OpenAI from "openai";
5623
- import { z as z11 } from "zod";
5990
+ import { z as z12 } from "zod";
5624
5991
  var MAX_EDIT_REFERENCES = 16;
5625
5992
  function aspectRatioToSize(ratio, tier) {
5626
5993
  const TIER_LONG_EDGE = {
@@ -5703,9 +6070,9 @@ function toProviderError2(cause, ctx) {
5703
6070
  ctx.model.id
5704
6071
  );
5705
6072
  }
5706
- var openaiUsageSchema = z11.object({
5707
- input_tokens: z11.number().optional(),
5708
- output_tokens: z11.number().optional()
6073
+ var openaiUsageSchema = z12.object({
6074
+ input_tokens: z12.number().optional(),
6075
+ output_tokens: z12.number().optional()
5709
6076
  });
5710
6077
  var openaiImageAdapter = {
5711
6078
  id: "openai-image",
@@ -6095,7 +6462,7 @@ var prodiaAdapter = {
6095
6462
 
6096
6463
  // src/adapters/replicate.ts
6097
6464
  import Replicate from "replicate";
6098
- import { z as z12 } from "zod";
6465
+ import { z as z13 } from "zod";
6099
6466
  var POLL_INTERVAL_MS = 1e3;
6100
6467
  var POLL_TIMEOUT_MS = 15 * 6e4;
6101
6468
  var defaultReplicateDeps = {
@@ -6131,8 +6498,8 @@ function route(providerModelId) {
6131
6498
  if (!providerModelId.includes("/")) return { version: providerModelId };
6132
6499
  return { model: providerModelId };
6133
6500
  }
6134
- var replicateResponseStatusSchema = z12.object({
6135
- response: z12.object({ status: z12.number() }).partial()
6501
+ var replicateResponseStatusSchema = z13.object({
6502
+ response: z13.object({ status: z13.number() }).partial()
6136
6503
  });
6137
6504
  function replicateError(cause, ctx) {
6138
6505
  if (isModelKitError(cause)) return cause;
@@ -6159,7 +6526,7 @@ function isUrlFn(value) {
6159
6526
  function extractOutputUrl(output) {
6160
6527
  const root = Array.isArray(output) ? output[0] : output;
6161
6528
  if (root === void 0) throw noOutput();
6162
- const asString = z12.string().safeParse(root);
6529
+ const asString = z13.string().safeParse(root);
6163
6530
  if (asString.success && asString.data) return asString.data;
6164
6531
  if (root instanceof URL) return root.href;
6165
6532
  if (isObjectOutput(root)) {
@@ -6168,15 +6535,15 @@ function extractOutputUrl(output) {
6168
6535
  if (urlValue !== void 0 && isUrlFn(urlValue)) {
6169
6536
  const called = urlValue();
6170
6537
  if (called instanceof URL) return called.href;
6171
- const calledString = z12.string().safeParse(called);
6538
+ const calledString = z13.string().safeParse(called);
6172
6539
  if (calledString.success && calledString.data) return calledString.data;
6173
6540
  } else {
6174
- const direct = z12.string().safeParse(urlValue);
6541
+ const direct = z13.string().safeParse(urlValue);
6175
6542
  if (direct.success && direct.data) return direct.data;
6176
6543
  }
6177
6544
  }
6178
6545
  if ("default" in root) {
6179
- const fallback = z12.string().safeParse(root.default);
6546
+ const fallback = z13.string().safeParse(root.default);
6180
6547
  if (fallback.success && fallback.data) return fallback.data;
6181
6548
  }
6182
6549
  }
@@ -6237,7 +6604,7 @@ async function runPrediction(ctx, input, deps) {
6237
6604
  }
6238
6605
  return void 0;
6239
6606
  }, pollOpts);
6240
- const predictTime = z12.number().safeParse(done.metrics?.predict_time);
6607
+ const predictTime = z13.number().safeParse(done.metrics?.predict_time);
6241
6608
  if (done.output === void 0) throw noOutput();
6242
6609
  return {
6243
6610
  url: extractOutputUrl(done.output),
@@ -6580,7 +6947,7 @@ async function generateReplicateVideo(req, ctx, deps) {
6580
6947
  throw replicateError(cause, ctx);
6581
6948
  }
6582
6949
  if (current.status === "succeeded") {
6583
- const predictTime = z12.number().safeParse(current.metrics?.predict_time);
6950
+ const predictTime = z13.number().safeParse(current.metrics?.predict_time);
6584
6951
  if (current.output === void 0) throw noOutput();
6585
6952
  return {
6586
6953
  url: extractOutputUrl(current.output),
@@ -6712,7 +7079,7 @@ async function generateReplicateAudio(req, ctx, deps) {
6712
7079
  // src/adapters/xai-video.ts
6713
7080
  import { experimental_generateVideo } from "ai";
6714
7081
  import { createXai as createXai2 } from "@ai-sdk/xai";
6715
- import { z as z13 } from "zod";
7082
+ import { z as z14 } from "zod";
6716
7083
  var POLL_INTERVAL_MS2 = 1e4;
6717
7084
  var POLL_TIMEOUT_MS2 = 15 * 6e4;
6718
7085
  var defaultXaiDeps = {
@@ -6725,8 +7092,8 @@ function createXaiVideoAdapter(deps = defaultXaiDeps) {
6725
7092
  };
6726
7093
  }
6727
7094
  var xaiVideoAdapter = createXaiVideoAdapter();
6728
- var xaiResponseStatusSchema = z13.object({
6729
- response: z13.object({ status: z13.number() }).partial()
7095
+ var xaiResponseStatusSchema = z14.object({
7096
+ response: z14.object({ status: z14.number() }).partial()
6730
7097
  });
6731
7098
  function xaiError(cause, ctx) {
6732
7099
  const info = describeThrown(cause);
@@ -6734,12 +7101,12 @@ function xaiError(cause, ctx) {
6734
7101
  const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
6735
7102
  return classifyThrown("xai-video", cause, ctx.model.id, { status, body: info.body });
6736
7103
  }
6737
- var xaiMetaSchema = z13.object({
7104
+ var xaiMetaSchema = z14.object({
6738
7105
  videoUrl: JsonValueSchema.optional(),
6739
7106
  costInUsdTicks: JsonValueSchema.optional(),
6740
7107
  duration: JsonValueSchema.optional()
6741
7108
  });
6742
- var xaiProviderMetadataSchema = z13.object({ xai: xaiMetaSchema });
7109
+ var xaiProviderMetadataSchema = z14.object({ xai: xaiMetaSchema });
6743
7110
  function metaOf(result) {
6744
7111
  const parsed = xaiProviderMetadataSchema.partial().safeParse(result.providerMetadata);
6745
7112
  if (!parsed.success) return {};
@@ -6846,7 +7213,7 @@ async function mapResult(ctx, req, result) {
6846
7213
  };
6847
7214
  }
6848
7215
  const meta = metaOf(result);
6849
- const videoUrl = z13.string().safeParse(meta.videoUrl);
7216
+ const videoUrl = z14.string().safeParse(meta.videoUrl);
6850
7217
  if (videoUrl.success && videoUrl.data) {
6851
7218
  const res = await ctx.fetch(videoUrl.data);
6852
7219
  if (!res.ok) {
@@ -6869,7 +7236,7 @@ async function mapResult(ctx, req, result) {
6869
7236
  });
6870
7237
  }
6871
7238
  function usage(ctx, req, meta) {
6872
- const costTicks = z13.number().safeParse(meta.costInUsdTicks);
7239
+ const costTicks = z14.number().safeParse(meta.costInUsdTicks);
6873
7240
  const cost = costTicks.success ? costTicks.data / 1e10 : void 0;
6874
7241
  const event = {
6875
7242
  model: ctx.model.id,
@@ -6917,8 +7284,11 @@ var prepareMediaPart = (modelId, ref, mediaType, call) => createDefaultModelKit(
6917
7284
  var languageModel = (modelId, call) => createDefaultModelKit().languageModel(modelId, call);
6918
7285
  var describe = (modelId) => createDefaultModelKit().describe(modelId);
6919
7286
  export {
7287
+ ADAPTER_IDS,
6920
7288
  ADAPTER_KEYS,
6921
7289
  Catalog,
7290
+ CatalogModelSchema,
7291
+ CatalogSchema,
6922
7292
  DEFAULT_ADAPTERS,
6923
7293
  JsonObjectSchema,
6924
7294
  JsonValueSchema,
@@ -6934,6 +7304,7 @@ export {
6934
7304
  describeThrown,
6935
7305
  generateImage as experimental_generateImage,
6936
7306
  falAdapter,
7307
+ fileCatalogCache,
6937
7308
  generateAudio,
6938
7309
  generateImage,
6939
7310
  generateObject,
@@ -6945,15 +7316,18 @@ export {
6945
7316
  isModelKitError,
6946
7317
  keysFromEnv,
6947
7318
  languageModel,
7319
+ liveCatalog,
6948
7320
  mergeTextProviderOptions,
6949
7321
  nearestAspectRatio,
6950
7322
  openaiImageAdapter,
6951
7323
  passthroughTextModel,
6952
7324
  pollUntil,
6953
7325
  prepareMediaPart,
7326
+ primeCatalog,
6954
7327
  prodiaAdapter,
6955
7328
  readErrorBody,
6956
7329
  replicateAdapter,
7330
+ resetLiveCatalog,
6957
7331
  resolveAudioOptions,
6958
7332
  resolveImageOptions,
6959
7333
  resolveKeys,