@shop-os/modelkit 0.6.0 → 0.7.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/CHANGELOG.md +17 -0
- package/README.md +3 -3
- package/dist/catalog.cjs +241 -46
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +6 -3
- package/dist/catalog.d.ts +6 -3
- package/dist/catalog.js +241 -46
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +895 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -5
- package/dist/index.d.ts +10 -5
- package/dist/index.js +894 -114
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -88,6 +88,7 @@ __export(index_exports, {
|
|
|
88
88
|
languageModel: () => languageModel,
|
|
89
89
|
liveCatalog: () => liveCatalog,
|
|
90
90
|
liveState: () => liveState,
|
|
91
|
+
lumaAdapter: () => lumaAdapter,
|
|
91
92
|
mergeTextProviderOptions: () => mergeTextProviderOptions,
|
|
92
93
|
missingTierKeys: () => missingTierKeys,
|
|
93
94
|
model3dCall: () => model3dCall,
|
|
@@ -510,8 +511,59 @@ var FAL_IMAGE_MODELS = [
|
|
|
510
511
|
}
|
|
511
512
|
];
|
|
512
513
|
|
|
513
|
-
// src/catalog/image.ts
|
|
514
|
+
// src/catalog/image-luma.ts
|
|
514
515
|
var IMAGE_USAGE2 = { unit: "images" };
|
|
516
|
+
var EXPOSURE2 = ["cowork", "space_builder"];
|
|
517
|
+
var LOBE2 = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light";
|
|
518
|
+
var LUMA_LOGO = `${LOBE2}/luma-color.png`;
|
|
519
|
+
var UNI_RATIOS = ["adaptive", "16:9", "3:2", "1:1", "2:3", "9:16"];
|
|
520
|
+
function uniImage(id, label, providerModelId, description) {
|
|
521
|
+
return {
|
|
522
|
+
// https://docs.agents.lumalabs.ai: type "image" without references, else
|
|
523
|
+
// "image_edit" with the first reference as source and up to 8 more as
|
|
524
|
+
// image_ref. The output is always 2048 px on the long side.
|
|
525
|
+
id,
|
|
526
|
+
aliases: [],
|
|
527
|
+
label,
|
|
528
|
+
type: "image",
|
|
529
|
+
adapter: "luma",
|
|
530
|
+
providerModelId,
|
|
531
|
+
lifecycle: "active",
|
|
532
|
+
exposure: EXPOSURE2,
|
|
533
|
+
constraints: {
|
|
534
|
+
aspectRatios: [...UNI_RATIOS],
|
|
535
|
+
sizes: ["2K"],
|
|
536
|
+
references: { images: 9 },
|
|
537
|
+
supports: ["outputFormat"],
|
|
538
|
+
prompt: { referenceSyntax: "numbered", maxChars: 6e3 }
|
|
539
|
+
},
|
|
540
|
+
defaults: { size: "2K", aspectRatio: "adaptive" },
|
|
541
|
+
usage: { ...IMAGE_USAGE2 },
|
|
542
|
+
pricingKind: "image_size",
|
|
543
|
+
display: {
|
|
544
|
+
provider: "luma",
|
|
545
|
+
description,
|
|
546
|
+
logo: LUMA_LOGO
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
var LUMA_IMAGE_MODELS = [
|
|
551
|
+
uniImage(
|
|
552
|
+
"uni-1",
|
|
553
|
+
"Uni-1",
|
|
554
|
+
"uni-1",
|
|
555
|
+
"Luma Uni-1 fast image generation and editing; takes a prompt and up to 9 reference images and outputs 2K."
|
|
556
|
+
),
|
|
557
|
+
uniImage(
|
|
558
|
+
"uni-1-max",
|
|
559
|
+
"Uni-1 Max",
|
|
560
|
+
"uni-1-max",
|
|
561
|
+
"Luma Uni-1 Max higher-quality image generation and editing; takes a prompt and up to 9 reference images and outputs 2K."
|
|
562
|
+
)
|
|
563
|
+
];
|
|
564
|
+
|
|
565
|
+
// src/catalog/image.ts
|
|
566
|
+
var IMAGE_USAGE3 = { unit: "images" };
|
|
515
567
|
var GEMINI_RATIOS = [
|
|
516
568
|
"1:1",
|
|
517
569
|
"2:3",
|
|
@@ -556,7 +608,7 @@ function geminiImage(id, label, aliases, sizes, display, exposure, references, p
|
|
|
556
608
|
exposure,
|
|
557
609
|
constraints,
|
|
558
610
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
559
|
-
usage: { ...
|
|
611
|
+
usage: { ...IMAGE_USAGE3, slug: "gemini" },
|
|
560
612
|
pricingKind: "image_size",
|
|
561
613
|
display
|
|
562
614
|
};
|
|
@@ -669,7 +721,7 @@ var IMAGE_MODELS = [
|
|
|
669
721
|
prompt: GPT_IMAGE_PROMPT
|
|
670
722
|
},
|
|
671
723
|
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
672
|
-
usage: { ...
|
|
724
|
+
usage: { ...IMAGE_USAGE3, slug: "gpt" },
|
|
673
725
|
pricingKind: "image_size",
|
|
674
726
|
display: {
|
|
675
727
|
provider: "openai",
|
|
@@ -705,7 +757,7 @@ var IMAGE_MODELS = [
|
|
|
705
757
|
prompt: GPT_IMAGE_PROMPT
|
|
706
758
|
},
|
|
707
759
|
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
708
|
-
usage: { ...
|
|
760
|
+
usage: { ...IMAGE_USAGE3 },
|
|
709
761
|
pricingKind: "image_size",
|
|
710
762
|
display: {
|
|
711
763
|
provider: "openai",
|
|
@@ -740,7 +792,7 @@ var IMAGE_MODELS = [
|
|
|
740
792
|
prompt: GPT_IMAGE_PROMPT
|
|
741
793
|
},
|
|
742
794
|
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
743
|
-
usage: { ...
|
|
795
|
+
usage: { ...IMAGE_USAGE3 },
|
|
744
796
|
pricingKind: "image_size",
|
|
745
797
|
display: {
|
|
746
798
|
provider: "openai",
|
|
@@ -775,7 +827,7 @@ var IMAGE_MODELS = [
|
|
|
775
827
|
supports: ["count", "outputFormat"]
|
|
776
828
|
},
|
|
777
829
|
defaults: { size: "1K", aspectRatio: "1:1", outputFormat: "png", count: 1 },
|
|
778
|
-
usage: { ...
|
|
830
|
+
usage: { ...IMAGE_USAGE3, slug: "muse" },
|
|
779
831
|
pricingKind: "image_size",
|
|
780
832
|
display: {
|
|
781
833
|
provider: "meta",
|
|
@@ -802,7 +854,7 @@ var IMAGE_MODELS = [
|
|
|
802
854
|
supports: ["quality", "count", "seed"]
|
|
803
855
|
},
|
|
804
856
|
defaults: { size: "2K", aspectRatio: "1:1", quality: "medium", count: 1 },
|
|
805
|
-
usage: { ...
|
|
857
|
+
usage: { ...IMAGE_USAGE3, slug: "ideogram" },
|
|
806
858
|
pricingKind: "image_size",
|
|
807
859
|
display: {
|
|
808
860
|
provider: "ideogram",
|
|
@@ -827,7 +879,7 @@ var IMAGE_MODELS = [
|
|
|
827
879
|
supports: ["seed", "outputFormat"]
|
|
828
880
|
},
|
|
829
881
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
830
|
-
usage: { ...
|
|
882
|
+
usage: { ...IMAGE_USAGE3 },
|
|
831
883
|
pricingKind: "image_size",
|
|
832
884
|
display: {
|
|
833
885
|
provider: "bytedance",
|
|
@@ -865,7 +917,7 @@ var IMAGE_MODELS = [
|
|
|
865
917
|
supports: ["seed"]
|
|
866
918
|
},
|
|
867
919
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
868
|
-
usage: { ...
|
|
920
|
+
usage: { ...IMAGE_USAGE3 },
|
|
869
921
|
pricingKind: "image_size",
|
|
870
922
|
display: {
|
|
871
923
|
provider: "bytedance",
|
|
@@ -891,7 +943,7 @@ var IMAGE_MODELS = [
|
|
|
891
943
|
prompt: { referenceSyntax: "numbered", maxChars: 32768 }
|
|
892
944
|
},
|
|
893
945
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
894
|
-
usage: { ...
|
|
946
|
+
usage: { ...IMAGE_USAGE3 },
|
|
895
947
|
pricingKind: "image_size",
|
|
896
948
|
display: {
|
|
897
949
|
provider: "black-forest-labs",
|
|
@@ -918,7 +970,7 @@ var IMAGE_MODELS = [
|
|
|
918
970
|
supports: []
|
|
919
971
|
},
|
|
920
972
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
921
|
-
usage: { ...
|
|
973
|
+
usage: { ...IMAGE_USAGE3 },
|
|
922
974
|
pricingKind: "image_size",
|
|
923
975
|
display: {
|
|
924
976
|
provider: "google",
|
|
@@ -943,7 +995,7 @@ var IMAGE_MODELS = [
|
|
|
943
995
|
supports: []
|
|
944
996
|
},
|
|
945
997
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
946
|
-
usage: { ...
|
|
998
|
+
usage: { ...IMAGE_USAGE3 },
|
|
947
999
|
pricingKind: "image_size",
|
|
948
1000
|
display: {
|
|
949
1001
|
provider: "google",
|
|
@@ -1029,7 +1081,8 @@ var IMAGE_MODELS = [
|
|
|
1029
1081
|
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."
|
|
1030
1082
|
}
|
|
1031
1083
|
},
|
|
1032
|
-
...FAL_IMAGE_MODELS
|
|
1084
|
+
...FAL_IMAGE_MODELS,
|
|
1085
|
+
...LUMA_IMAGE_MODELS
|
|
1033
1086
|
];
|
|
1034
1087
|
|
|
1035
1088
|
// src/catalog/audio-formats.ts
|
|
@@ -1225,7 +1278,7 @@ var VEED_SUBTITLE_LANGUAGES = [
|
|
|
1225
1278
|
];
|
|
1226
1279
|
|
|
1227
1280
|
// src/catalog/canvas-tools.ts
|
|
1228
|
-
var
|
|
1281
|
+
var EXPOSURE3 = ["cowork", "space_builder"];
|
|
1229
1282
|
var META_LOGO = "https://d31vvfpk2ppdyq.cloudfront.net/assets/characters/1787909065794-k9a7zz.png";
|
|
1230
1283
|
var VEED_SUBTITLE_PRESETS = [
|
|
1231
1284
|
"simple",
|
|
@@ -1267,7 +1320,7 @@ var SAM_3_IMAGE = {
|
|
|
1267
1320
|
adapter: "fal",
|
|
1268
1321
|
providerModelId: "fal-ai/sam-3/image",
|
|
1269
1322
|
lifecycle: "active",
|
|
1270
|
-
exposure:
|
|
1323
|
+
exposure: EXPOSURE3,
|
|
1271
1324
|
constraints: {
|
|
1272
1325
|
references: { images: 1 },
|
|
1273
1326
|
requires: ["references"],
|
|
@@ -1290,7 +1343,7 @@ var VEED_SUBTITLES = {
|
|
|
1290
1343
|
adapter: "fal",
|
|
1291
1344
|
providerModelId: "veed/subtitles",
|
|
1292
1345
|
lifecycle: "active",
|
|
1293
|
-
exposure:
|
|
1346
|
+
exposure: EXPOSURE3,
|
|
1294
1347
|
constraints: {
|
|
1295
1348
|
supports: [],
|
|
1296
1349
|
// fal: up to 2 hours at 1080p or below, 1 hour above.
|
|
@@ -3395,7 +3448,7 @@ var GOOGLE_LOGO = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a
|
|
|
3395
3448
|
var MINIMAX_LOGO = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/f4c2e906-28b7-4a4a-b491-df8fef7808ed.png";
|
|
3396
3449
|
var SYNC_LOGO = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/sync.png";
|
|
3397
3450
|
var PER_CALL = { unit: "images" };
|
|
3398
|
-
var
|
|
3451
|
+
var EXPOSURE4 = ["cowork", "space_builder"];
|
|
3399
3452
|
var LIPSYNC_AUDIO = { audioSeconds: { max: 30 } };
|
|
3400
3453
|
function elevenLabsTts(tts) {
|
|
3401
3454
|
return {
|
|
@@ -3406,7 +3459,7 @@ function elevenLabsTts(tts) {
|
|
|
3406
3459
|
adapter: "fal",
|
|
3407
3460
|
providerModelId: tts.providerModelId,
|
|
3408
3461
|
lifecycle: "active",
|
|
3409
|
-
exposure:
|
|
3462
|
+
exposure: EXPOSURE4,
|
|
3410
3463
|
constraints: {
|
|
3411
3464
|
voices: ELEVENLABS_VOICES,
|
|
3412
3465
|
languages: tts.languages,
|
|
@@ -3431,7 +3484,7 @@ function geminiTts(id, label, description) {
|
|
|
3431
3484
|
adapter: "fal",
|
|
3432
3485
|
providerModelId,
|
|
3433
3486
|
lifecycle: "active",
|
|
3434
|
-
exposure:
|
|
3487
|
+
exposure: EXPOSURE4,
|
|
3435
3488
|
constraints: {
|
|
3436
3489
|
voices: GEMINI_TTS_VOICES,
|
|
3437
3490
|
supports: ["style"],
|
|
@@ -3454,7 +3507,7 @@ function syncLipsync(id, label, providerModelId, syncModel, description) {
|
|
|
3454
3507
|
adapter: "fal",
|
|
3455
3508
|
providerModelId,
|
|
3456
3509
|
lifecycle: "active",
|
|
3457
|
-
exposure:
|
|
3510
|
+
exposure: EXPOSURE4,
|
|
3458
3511
|
constraints: {
|
|
3459
3512
|
requires: ["sourceVideo", "sourceAudio"],
|
|
3460
3513
|
references: LIPSYNC_AUDIO,
|
|
@@ -3515,7 +3568,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3515
3568
|
adapter: "fal",
|
|
3516
3569
|
providerModelId: "fal-ai/minimax/speech-2.8-hd",
|
|
3517
3570
|
lifecycle: "active",
|
|
3518
|
-
exposure:
|
|
3571
|
+
exposure: EXPOSURE4,
|
|
3519
3572
|
constraints: {
|
|
3520
3573
|
voices: MINIMAX_VOICES,
|
|
3521
3574
|
languages: MINIMAX_SPEECH_LANGUAGES,
|
|
@@ -3540,7 +3593,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3540
3593
|
adapter: "fal",
|
|
3541
3594
|
providerModelId: "fal-ai/elevenlabs/voice-changer",
|
|
3542
3595
|
lifecycle: "active",
|
|
3543
|
-
exposure:
|
|
3596
|
+
exposure: EXPOSURE4,
|
|
3544
3597
|
constraints: {
|
|
3545
3598
|
requires: ["sourceAudio"],
|
|
3546
3599
|
// The flat price assumes at most a minute of speech.
|
|
@@ -3567,7 +3620,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3567
3620
|
adapter: "fal",
|
|
3568
3621
|
providerModelId: "fal-ai/elevenlabs/dubbing",
|
|
3569
3622
|
lifecycle: "active",
|
|
3570
|
-
exposure:
|
|
3623
|
+
exposure: EXPOSURE4,
|
|
3571
3624
|
constraints: {
|
|
3572
3625
|
requiresOneOf: ["sourceVideo", "sourceAudio"],
|
|
3573
3626
|
// The flat price covers 60 s of source.
|
|
@@ -3615,7 +3668,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3615
3668
|
adapter: "fal",
|
|
3616
3669
|
providerModelId: "veed/lipsync/v2",
|
|
3617
3670
|
lifecycle: "active",
|
|
3618
|
-
exposure:
|
|
3671
|
+
exposure: EXPOSURE4,
|
|
3619
3672
|
constraints: {
|
|
3620
3673
|
requires: ["sourceVideo", "sourceAudio"],
|
|
3621
3674
|
references: LIPSYNC_AUDIO,
|
|
@@ -3641,7 +3694,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3641
3694
|
adapter: "fal",
|
|
3642
3695
|
providerModelId: "minimax/h3-max/lip-sync/image-to-video",
|
|
3643
3696
|
lifecycle: "active",
|
|
3644
|
-
exposure:
|
|
3697
|
+
exposure: EXPOSURE4,
|
|
3645
3698
|
constraints: {
|
|
3646
3699
|
requires: ["firstFrame", "sourceAudio"],
|
|
3647
3700
|
resolutions: ["480p", "768p", "1080p", "2k"],
|
|
@@ -3667,7 +3720,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3667
3720
|
adapter: "fal",
|
|
3668
3721
|
providerModelId: "fal-ai/elevenlabs/speech-to-text/scribe-v2",
|
|
3669
3722
|
lifecycle: "active",
|
|
3670
|
-
exposure:
|
|
3723
|
+
exposure: EXPOSURE4,
|
|
3671
3724
|
constraints: {
|
|
3672
3725
|
requires: ["sourceAudio"],
|
|
3673
3726
|
// The flat price covers 10 minutes of audio.
|
|
@@ -5203,8 +5256,113 @@ var VIDEO_FAMILY_MODELS = [
|
|
|
5203
5256
|
}
|
|
5204
5257
|
];
|
|
5205
5258
|
|
|
5206
|
-
// src/catalog/video.ts
|
|
5259
|
+
// src/catalog/video-luma.ts
|
|
5207
5260
|
var VIDEO_USAGE2 = { unit: "seconds" };
|
|
5261
|
+
var EXPOSURE5 = ["cowork", "space_builder"];
|
|
5262
|
+
var LUMA_LOGO2 = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/luma-color.png";
|
|
5263
|
+
var RAY_RATIOS = ["9:16", "3:4", "1:1", "4:3", "16:9", "21:9"];
|
|
5264
|
+
var RAY_RESOLUTIONS = ["360p", "720p", "1080p"];
|
|
5265
|
+
var RAY_PROMPT = { referenceSyntax: "numbered", maxChars: 6e3 };
|
|
5266
|
+
var LUMA_VIDEO_MODELS = [
|
|
5267
|
+
{
|
|
5268
|
+
// https://docs.agents.lumalabs.ai: type "video" with a fixed 5 s duration;
|
|
5269
|
+
// firstFrame and lastFrame ride as start_frame and end_frame.
|
|
5270
|
+
id: "ray-3.2",
|
|
5271
|
+
aliases: [],
|
|
5272
|
+
label: "Ray 3.2",
|
|
5273
|
+
type: "video",
|
|
5274
|
+
adapter: "luma",
|
|
5275
|
+
providerModelId: "ray-3.2",
|
|
5276
|
+
lifecycle: "active",
|
|
5277
|
+
exposure: EXPOSURE5,
|
|
5278
|
+
constraints: {
|
|
5279
|
+
aspectRatios: ["adaptive", ...RAY_RATIOS],
|
|
5280
|
+
resolutions: [...RAY_RESOLUTIONS],
|
|
5281
|
+
durations: [5],
|
|
5282
|
+
supports: ["lastFrame"],
|
|
5283
|
+
prompt: { ...RAY_PROMPT },
|
|
5284
|
+
audio: "never"
|
|
5285
|
+
},
|
|
5286
|
+
defaults: { durationSeconds: 5, resolution: "720p", aspectRatio: "adaptive" },
|
|
5287
|
+
usage: { ...VIDEO_USAGE2 },
|
|
5288
|
+
pricingKind: "video_per_second",
|
|
5289
|
+
display: {
|
|
5290
|
+
provider: "luma",
|
|
5291
|
+
description: "Luma Ray 3.2 text- and image-to-video with optional first and last frames, 5-second clips at up to 1080p.",
|
|
5292
|
+
logo: LUMA_LOGO2
|
|
5293
|
+
},
|
|
5294
|
+
capabilities: {}
|
|
5295
|
+
},
|
|
5296
|
+
{
|
|
5297
|
+
// https://docs.agents.lumalabs.ai: type "video_edit" with a source video of
|
|
5298
|
+
// up to 18 s; the output keeps the source length, so there is no durations
|
|
5299
|
+
// knob, no aspect_ratio and no end frame. Luma bills its 5 s price for any
|
|
5300
|
+
// source (live, 2026-10-21) and the row is priced per source second, so a
|
|
5301
|
+
// source under 5 s is refused: it would be billed below Luma's charge.
|
|
5302
|
+
id: "ray-3.2-edit",
|
|
5303
|
+
aliases: [],
|
|
5304
|
+
label: "Ray 3.2 Edit",
|
|
5305
|
+
type: "video",
|
|
5306
|
+
adapter: "luma",
|
|
5307
|
+
providerModelId: "ray-3.2",
|
|
5308
|
+
lifecycle: "active",
|
|
5309
|
+
exposure: EXPOSURE5,
|
|
5310
|
+
constraints: {
|
|
5311
|
+
resolutions: [...RAY_RESOLUTIONS],
|
|
5312
|
+
requires: ["sourceVideo"],
|
|
5313
|
+
sourceVideoSeconds: { min: 5, max: 18 },
|
|
5314
|
+
supports: [],
|
|
5315
|
+
prompt: { ...RAY_PROMPT },
|
|
5316
|
+
audio: "never"
|
|
5317
|
+
},
|
|
5318
|
+
defaults: { resolution: "720p" },
|
|
5319
|
+
usage: { ...VIDEO_USAGE2 },
|
|
5320
|
+
pricingKind: "video_per_second",
|
|
5321
|
+
display: {
|
|
5322
|
+
provider: "luma",
|
|
5323
|
+
description: "Luma Ray 3.2 video edit: changes a 5-18 second clip from a prompt, keeping its length.",
|
|
5324
|
+
logo: LUMA_LOGO2
|
|
5325
|
+
},
|
|
5326
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: true }
|
|
5327
|
+
},
|
|
5328
|
+
{
|
|
5329
|
+
// https://docs.agents.lumalabs.ai: type "video_reframe" with a required
|
|
5330
|
+
// target aspect_ratio; the source is up to 10 s and the output keeps its
|
|
5331
|
+
// length whatever video.duration says, while Luma bills that duration
|
|
5332
|
+
// (live, 2026-10-21). So there is no durations knob, and a source under
|
|
5333
|
+
// 5 s is refused, as on ray-3.2-edit. 1080p is not offered for the
|
|
5334
|
+
// vertical targets 9:16 and 3:4.
|
|
5335
|
+
id: "ray-3.2-reframe",
|
|
5336
|
+
aliases: [],
|
|
5337
|
+
label: "Ray 3.2 Reframe",
|
|
5338
|
+
type: "video",
|
|
5339
|
+
adapter: "luma",
|
|
5340
|
+
providerModelId: "ray-3.2",
|
|
5341
|
+
lifecycle: "active",
|
|
5342
|
+
exposure: EXPOSURE5,
|
|
5343
|
+
constraints: {
|
|
5344
|
+
aspectRatios: [...RAY_RATIOS],
|
|
5345
|
+
resolutions: [...RAY_RESOLUTIONS],
|
|
5346
|
+
requires: ["sourceVideo"],
|
|
5347
|
+
sourceVideoSeconds: { min: 5, max: 10 },
|
|
5348
|
+
supports: [],
|
|
5349
|
+
prompt: { ...RAY_PROMPT },
|
|
5350
|
+
audio: "never"
|
|
5351
|
+
},
|
|
5352
|
+
defaults: { resolution: "720p", aspectRatio: "16:9" },
|
|
5353
|
+
usage: { ...VIDEO_USAGE2 },
|
|
5354
|
+
pricingKind: "video_per_second",
|
|
5355
|
+
display: {
|
|
5356
|
+
provider: "luma",
|
|
5357
|
+
description: "Luma Ray 3.2 Reframe: changes a 5-10 second clip to a new aspect ratio and fills the new area from the prompt.",
|
|
5358
|
+
logo: LUMA_LOGO2
|
|
5359
|
+
},
|
|
5360
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: true }
|
|
5361
|
+
}
|
|
5362
|
+
];
|
|
5363
|
+
|
|
5364
|
+
// src/catalog/video.ts
|
|
5365
|
+
var VIDEO_USAGE3 = { unit: "seconds" };
|
|
5208
5366
|
var SEEDANCE_RATIOS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16", "adaptive"];
|
|
5209
5367
|
var KLING_RATIOS2 = ["16:9", "9:16", "1:1", "adaptive"];
|
|
5210
5368
|
var KLING_OMNI_RATIOS = ["16:9", "9:16", "1:1"];
|
|
@@ -5257,7 +5415,7 @@ var VIDEO_MODELS = [
|
|
|
5257
5415
|
audio: "always"
|
|
5258
5416
|
},
|
|
5259
5417
|
defaults: { durationSeconds: 8, resolution: "720p", aspectRatio: "16:9" },
|
|
5260
|
-
usage: { ...
|
|
5418
|
+
usage: { ...VIDEO_USAGE3, slug: "veo" },
|
|
5261
5419
|
pricingKind: "video_per_second",
|
|
5262
5420
|
display: {
|
|
5263
5421
|
provider: "google",
|
|
@@ -5290,7 +5448,7 @@ var VIDEO_MODELS = [
|
|
|
5290
5448
|
audio: "always"
|
|
5291
5449
|
},
|
|
5292
5450
|
defaults: { durationSeconds: 8, resolution: "720p", aspectRatio: "16:9" },
|
|
5293
|
-
usage: { ...
|
|
5451
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5294
5452
|
pricingKind: "video_per_second",
|
|
5295
5453
|
display: {
|
|
5296
5454
|
provider: "google",
|
|
@@ -5320,7 +5478,7 @@ var VIDEO_MODELS = [
|
|
|
5320
5478
|
audio: "always"
|
|
5321
5479
|
},
|
|
5322
5480
|
defaults: { durationSeconds: 8, resolution: "720p", aspectRatio: "16:9" },
|
|
5323
|
-
usage: { ...
|
|
5481
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5324
5482
|
pricingKind: "video_per_second",
|
|
5325
5483
|
display: {
|
|
5326
5484
|
provider: "google",
|
|
@@ -5357,7 +5515,7 @@ var VIDEO_MODELS = [
|
|
|
5357
5515
|
audio: "always"
|
|
5358
5516
|
},
|
|
5359
5517
|
defaults: {},
|
|
5360
|
-
usage: { ...
|
|
5518
|
+
usage: { ...VIDEO_USAGE3, slug: "gemini_omni" },
|
|
5361
5519
|
pricingKind: "video_per_second",
|
|
5362
5520
|
display: {
|
|
5363
5521
|
provider: "google",
|
|
@@ -5394,7 +5552,7 @@ var VIDEO_MODELS = [
|
|
|
5394
5552
|
audio: "always"
|
|
5395
5553
|
},
|
|
5396
5554
|
defaults: {},
|
|
5397
|
-
usage: { ...
|
|
5555
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5398
5556
|
pricingKind: "video_per_second",
|
|
5399
5557
|
display: {
|
|
5400
5558
|
provider: "google",
|
|
@@ -5443,7 +5601,7 @@ var VIDEO_MODELS = [
|
|
|
5443
5601
|
aspectRatio: "16:9",
|
|
5444
5602
|
generateAudio: true
|
|
5445
5603
|
},
|
|
5446
|
-
usage: { ...
|
|
5604
|
+
usage: { ...VIDEO_USAGE3, slug: "seedance2", providerLabel: "byteplus" },
|
|
5447
5605
|
pricingKind: "video_per_second",
|
|
5448
5606
|
display: {
|
|
5449
5607
|
provider: "bytedance",
|
|
@@ -5486,7 +5644,7 @@ var VIDEO_MODELS = [
|
|
|
5486
5644
|
aspectRatio: "16:9",
|
|
5487
5645
|
generateAudio: true
|
|
5488
5646
|
},
|
|
5489
|
-
usage: { ...
|
|
5647
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5490
5648
|
pricingKind: "video_per_second",
|
|
5491
5649
|
display: {
|
|
5492
5650
|
provider: "bytedance",
|
|
@@ -5536,7 +5694,7 @@ var VIDEO_MODELS = [
|
|
|
5536
5694
|
aspectRatio: "16:9",
|
|
5537
5695
|
generateAudio: true
|
|
5538
5696
|
},
|
|
5539
|
-
usage: { ...
|
|
5697
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5540
5698
|
pricingKind: "video_per_second",
|
|
5541
5699
|
display: {
|
|
5542
5700
|
provider: "bytedance",
|
|
@@ -5598,7 +5756,7 @@ var VIDEO_MODELS = [
|
|
|
5598
5756
|
cfgScale: 0.5,
|
|
5599
5757
|
negativePrompt: NEGATIVE_PROMPT
|
|
5600
5758
|
},
|
|
5601
|
-
usage: { ...
|
|
5759
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5602
5760
|
pricingKind: "video_per_second",
|
|
5603
5761
|
display: {
|
|
5604
5762
|
provider: "kuaishou",
|
|
@@ -5630,7 +5788,7 @@ var VIDEO_MODELS = [
|
|
|
5630
5788
|
cfgScale: 0.5,
|
|
5631
5789
|
generateAudio: true
|
|
5632
5790
|
},
|
|
5633
|
-
usage: { ...
|
|
5791
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5634
5792
|
pricingKind: "video_per_second",
|
|
5635
5793
|
display: {
|
|
5636
5794
|
provider: "kuaishou",
|
|
@@ -5698,7 +5856,7 @@ var VIDEO_MODELS = [
|
|
|
5698
5856
|
aspectRatio: "16:9",
|
|
5699
5857
|
promptExpansion: "balanced"
|
|
5700
5858
|
},
|
|
5701
|
-
usage: { ...
|
|
5859
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5702
5860
|
pricingKind: "video_per_second",
|
|
5703
5861
|
display: {
|
|
5704
5862
|
provider: "minimax",
|
|
@@ -5732,7 +5890,7 @@ var VIDEO_MODELS = [
|
|
|
5732
5890
|
aspectRatio: "16:9",
|
|
5733
5891
|
promptExpansion: "balanced"
|
|
5734
5892
|
},
|
|
5735
|
-
usage: { ...
|
|
5893
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5736
5894
|
pricingKind: "video_per_second",
|
|
5737
5895
|
display: {
|
|
5738
5896
|
provider: "minimax",
|
|
@@ -5774,7 +5932,7 @@ var VIDEO_MODELS = [
|
|
|
5774
5932
|
aspectRatio: "adaptive",
|
|
5775
5933
|
promptExpansion: "balanced"
|
|
5776
5934
|
},
|
|
5777
|
-
usage: { ...
|
|
5935
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5778
5936
|
pricingKind: "video_per_second",
|
|
5779
5937
|
display: {
|
|
5780
5938
|
provider: "minimax",
|
|
@@ -5818,7 +5976,7 @@ var VIDEO_MODELS = [
|
|
|
5818
5976
|
aspectRatio: "adaptive",
|
|
5819
5977
|
promptExpansion: "balanced"
|
|
5820
5978
|
},
|
|
5821
|
-
usage: { ...
|
|
5979
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5822
5980
|
pricingKind: "video_per_second",
|
|
5823
5981
|
display: {
|
|
5824
5982
|
provider: "minimax",
|
|
@@ -5863,7 +6021,7 @@ var VIDEO_MODELS = [
|
|
|
5863
6021
|
aspectRatio: "adaptive",
|
|
5864
6022
|
generateAudio: true
|
|
5865
6023
|
},
|
|
5866
|
-
usage: { ...
|
|
6024
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5867
6025
|
pricingKind: "video_per_second",
|
|
5868
6026
|
display: {
|
|
5869
6027
|
provider: "alibaba",
|
|
@@ -5890,7 +6048,7 @@ var VIDEO_MODELS = [
|
|
|
5890
6048
|
audio: "never"
|
|
5891
6049
|
},
|
|
5892
6050
|
defaults: { durationSeconds: 5, aspectRatio: "16:9" },
|
|
5893
|
-
usage: { ...
|
|
6051
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5894
6052
|
pricingKind: "video_per_second",
|
|
5895
6053
|
display: {
|
|
5896
6054
|
provider: "kuaishou",
|
|
@@ -5939,7 +6097,7 @@ var VIDEO_MODELS = [
|
|
|
5939
6097
|
audio: "never"
|
|
5940
6098
|
},
|
|
5941
6099
|
defaults: {},
|
|
5942
|
-
usage: { ...
|
|
6100
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5943
6101
|
// Higgsfield bills DoP per generation: a fixed-length clip with no duration knob.
|
|
5944
6102
|
pricingKind: "flat",
|
|
5945
6103
|
display: {
|
|
@@ -5948,7 +6106,8 @@ var VIDEO_MODELS = [
|
|
|
5948
6106
|
},
|
|
5949
6107
|
capabilities: {}
|
|
5950
6108
|
},
|
|
5951
|
-
...VIDEO_FAMILY_MODELS
|
|
6109
|
+
...VIDEO_FAMILY_MODELS,
|
|
6110
|
+
...LUMA_VIDEO_MODELS
|
|
5952
6111
|
];
|
|
5953
6112
|
|
|
5954
6113
|
// src/catalog/video-tools.ts
|
|
@@ -6922,7 +7081,8 @@ var ADAPTER_IDS = [
|
|
|
6922
7081
|
"replicate",
|
|
6923
7082
|
"prodia",
|
|
6924
7083
|
"higgsfield",
|
|
6925
|
-
"xai-video"
|
|
7084
|
+
"xai-video",
|
|
7085
|
+
"luma"
|
|
6926
7086
|
];
|
|
6927
7087
|
var ModelTypeSchema = import_zod3.z.enum([
|
|
6928
7088
|
"text",
|
|
@@ -11052,6 +11212,30 @@ var klingV3Family = {
|
|
|
11052
11212
|
}
|
|
11053
11213
|
};
|
|
11054
11214
|
|
|
11215
|
+
// src/replicate-video-kinds.ts
|
|
11216
|
+
function replicateBaseModelId(providerModelId) {
|
|
11217
|
+
const colon = providerModelId.indexOf(":");
|
|
11218
|
+
return colon === -1 ? providerModelId : providerModelId.slice(0, colon);
|
|
11219
|
+
}
|
|
11220
|
+
var REPLICATE_VIDEO_KINDS = /* @__PURE__ */ new Map([
|
|
11221
|
+
["kling-video/v2.5-turbo/pro/image-to-video", "kling"],
|
|
11222
|
+
["kling-video/v3.0/pro/image-to-video", "kling"],
|
|
11223
|
+
["kwaivgi/kling-v3-video", "kling"],
|
|
11224
|
+
["kwaivgi/kling-v3-omni-video", "kling-omni"],
|
|
11225
|
+
["minimax/hailuo-02", "hailuo"]
|
|
11226
|
+
]);
|
|
11227
|
+
function videoKind(providerModelId) {
|
|
11228
|
+
return REPLICATE_VIDEO_KINDS.get(replicateBaseModelId(providerModelId));
|
|
11229
|
+
}
|
|
11230
|
+
var KLING_TIERS = [
|
|
11231
|
+
{ mode: "standard", resolution: "720p" },
|
|
11232
|
+
{ mode: "pro", resolution: "1080p" },
|
|
11233
|
+
{ mode: "4k", resolution: "4k" }
|
|
11234
|
+
];
|
|
11235
|
+
function klingTier(req) {
|
|
11236
|
+
return KLING_TIERS.find((tier) => tier.resolution === req.resolution) ?? KLING_TIERS.find((tier) => tier.mode === req.mode) ?? KLING_TIERS[0];
|
|
11237
|
+
}
|
|
11238
|
+
|
|
11055
11239
|
// src/resolve-video-rules.ts
|
|
11056
11240
|
var MOTION_PRO2 = "fal-ai/kling-video/v3/pro/motion-control";
|
|
11057
11241
|
var MOTION_STANDARD2 = "fal-ai/kling-video/v3/standard/motion-control";
|
|
@@ -11225,6 +11409,16 @@ function h3EndFrameRatioWarning(model, ratio) {
|
|
|
11225
11409
|
message: `${model.id} follows the end frame's aspect ratio`
|
|
11226
11410
|
};
|
|
11227
11411
|
}
|
|
11412
|
+
function isReplicateKling(model) {
|
|
11413
|
+
if (model.adapter !== "replicate") return false;
|
|
11414
|
+
const kind = videoKind(model.providerModelId);
|
|
11415
|
+
return kind === "kling" || kind === "kling-omni";
|
|
11416
|
+
}
|
|
11417
|
+
function fillReplicateKlingResolution(model, req) {
|
|
11418
|
+
if (isReplicateKling(model) && req.resolution === void 0) {
|
|
11419
|
+
req.resolution = klingTier(req).resolution;
|
|
11420
|
+
}
|
|
11421
|
+
}
|
|
11228
11422
|
function applyFalVideoRules(model, req, callerRatio, warnings) {
|
|
11229
11423
|
if (model.adapter !== "fal") return;
|
|
11230
11424
|
const problem = falVideoProblem(model.providerModelId, withPromptForResolve(req));
|
|
@@ -13551,9 +13745,608 @@ var higgsfieldAdapter = {
|
|
|
13551
13745
|
}
|
|
13552
13746
|
};
|
|
13553
13747
|
|
|
13748
|
+
// src/adapters/luma.ts
|
|
13749
|
+
var import_zod25 = require("zod");
|
|
13750
|
+
|
|
13751
|
+
// src/adapters/mp4-duration.ts
|
|
13752
|
+
function mp4DurationSeconds(bytes) {
|
|
13753
|
+
const moov = findBox(bytes, 0, bytes.length, "moov");
|
|
13754
|
+
if (!moov) return void 0;
|
|
13755
|
+
const mvhd = findBox(bytes, moov.start + 8, moov.end, "mvhd");
|
|
13756
|
+
if (!mvhd) return void 0;
|
|
13757
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
13758
|
+
const size = mvhd.end - mvhd.start;
|
|
13759
|
+
if (size < 8 + 4) return void 0;
|
|
13760
|
+
const version = view.getUint8(mvhd.start + 8);
|
|
13761
|
+
if (version === 0) {
|
|
13762
|
+
if (size < 8 + 4 + 4 + 4 + 4 + 4) return void 0;
|
|
13763
|
+
const timescale = view.getUint32(mvhd.start + 8 + 4 + 4 + 4);
|
|
13764
|
+
const duration = view.getUint32(mvhd.start + 8 + 4 + 4 + 4 + 4);
|
|
13765
|
+
if (timescale === 0) return void 0;
|
|
13766
|
+
return duration / timescale;
|
|
13767
|
+
}
|
|
13768
|
+
if (version === 1) {
|
|
13769
|
+
if (size < 8 + 4 + 8 + 8 + 4 + 8) return void 0;
|
|
13770
|
+
const timescale = view.getUint32(mvhd.start + 8 + 4 + 8 + 8);
|
|
13771
|
+
const high = view.getUint32(mvhd.start + 8 + 4 + 8 + 8 + 4);
|
|
13772
|
+
const low = view.getUint32(mvhd.start + 8 + 4 + 8 + 8 + 4 + 4);
|
|
13773
|
+
if (timescale === 0) return void 0;
|
|
13774
|
+
return (high * 2 ** 32 + low) / timescale;
|
|
13775
|
+
}
|
|
13776
|
+
return void 0;
|
|
13777
|
+
}
|
|
13778
|
+
function findBox(bytes, from, to, type) {
|
|
13779
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
13780
|
+
let offset = from;
|
|
13781
|
+
while (offset + 8 <= to) {
|
|
13782
|
+
const size = view.getUint32(offset);
|
|
13783
|
+
const name = String.fromCharCode(
|
|
13784
|
+
view.getUint8(offset + 4),
|
|
13785
|
+
view.getUint8(offset + 5),
|
|
13786
|
+
view.getUint8(offset + 6),
|
|
13787
|
+
view.getUint8(offset + 7)
|
|
13788
|
+
);
|
|
13789
|
+
if (size < 8 || offset + size > to) return void 0;
|
|
13790
|
+
if (name === type) return { start: offset, end: offset + size };
|
|
13791
|
+
offset += size;
|
|
13792
|
+
}
|
|
13793
|
+
return void 0;
|
|
13794
|
+
}
|
|
13795
|
+
|
|
13796
|
+
// src/adapters/luma.ts
|
|
13797
|
+
var DEFAULT_BASE_URL = "https://agents.lumalabs.ai";
|
|
13798
|
+
var IMAGE_POLL_INTERVAL_MS = 3e3;
|
|
13799
|
+
var IMAGE_TIMEOUT_MS = 5 * 6e4;
|
|
13800
|
+
var VIDEO_POLL_INTERVAL_MS = 5e3;
|
|
13801
|
+
var VIDEO_TIMEOUT_MS = 20 * 6e4;
|
|
13802
|
+
var PROMPT_MAX_CHARS = 6e3;
|
|
13803
|
+
var LUMA_IMAGE_MODEL_IDS = /* @__PURE__ */ new Set(["uni-1", "uni-1-max"]);
|
|
13804
|
+
var LUMA_VIDEO_MODEL_ID = "ray-3.2";
|
|
13805
|
+
var LUMA_VIDEO_MODES = /* @__PURE__ */ new Map([
|
|
13806
|
+
["ray-3.2", "generate"],
|
|
13807
|
+
["ray-3.2-edit", "edit"],
|
|
13808
|
+
["ray-3.2-reframe", "reframe"]
|
|
13809
|
+
]);
|
|
13810
|
+
function lumaRowRefusal(row2) {
|
|
13811
|
+
const provider = row2.providerModelId.toLowerCase();
|
|
13812
|
+
if (row2.type === "image") {
|
|
13813
|
+
return LUMA_IMAGE_MODEL_IDS.has(provider) ? void 0 : "luma image rows need providerModelId uni-1 or uni-1-max";
|
|
13814
|
+
}
|
|
13815
|
+
if (row2.type === "video") {
|
|
13816
|
+
if (provider !== LUMA_VIDEO_MODEL_ID) return "luma video rows need providerModelId ray-3.2";
|
|
13817
|
+
return !LUMA_VIDEO_MODES.has(row2.id) ? `luma routes ray-3.2 rows by catalog id; it knows ${[...LUMA_VIDEO_MODES.keys()].join(", ")}` : void 0;
|
|
13818
|
+
}
|
|
13819
|
+
return `luma has no ${row2.type} rows`;
|
|
13820
|
+
}
|
|
13821
|
+
function lumaBase(ctx) {
|
|
13822
|
+
return ctx.endpoints?.luma ?? DEFAULT_BASE_URL;
|
|
13823
|
+
}
|
|
13824
|
+
function lumaKey(ctx) {
|
|
13825
|
+
const key = ctx.keys.luma;
|
|
13826
|
+
if (!key) {
|
|
13827
|
+
throw new ModelKitError({
|
|
13828
|
+
code: "auth",
|
|
13829
|
+
message: "Missing API key for luma",
|
|
13830
|
+
provider: "luma",
|
|
13831
|
+
model: ctx.model.id,
|
|
13832
|
+
retryable: false
|
|
13833
|
+
});
|
|
13834
|
+
}
|
|
13835
|
+
return key;
|
|
13836
|
+
}
|
|
13837
|
+
function checkPrompt(req, ctx) {
|
|
13838
|
+
const prompt = req.prompt.trim();
|
|
13839
|
+
if (prompt.length === 0) {
|
|
13840
|
+
throw new ModelKitError({
|
|
13841
|
+
code: "missing_input",
|
|
13842
|
+
message: `${ctx.model.id} needs a prompt`,
|
|
13843
|
+
provider: "luma",
|
|
13844
|
+
model: ctx.model.id,
|
|
13845
|
+
retryable: false
|
|
13846
|
+
});
|
|
13847
|
+
}
|
|
13848
|
+
if (req.prompt.length > PROMPT_MAX_CHARS) {
|
|
13849
|
+
throw new ModelKitError({
|
|
13850
|
+
code: "unsupported_option",
|
|
13851
|
+
message: `${ctx.model.id} takes a prompt of at most ${PROMPT_MAX_CHARS} characters`,
|
|
13852
|
+
provider: "luma",
|
|
13853
|
+
model: ctx.model.id,
|
|
13854
|
+
retryable: false
|
|
13855
|
+
});
|
|
13856
|
+
}
|
|
13857
|
+
return req.prompt;
|
|
13858
|
+
}
|
|
13859
|
+
function imageRef(ref) {
|
|
13860
|
+
if ("url" in ref) return { url: ref.url };
|
|
13861
|
+
return { data: mediaRefToBase64(ref.bytes), media_type: ref.mime };
|
|
13862
|
+
}
|
|
13863
|
+
function videoRef(ref) {
|
|
13864
|
+
if ("url" in ref) return { url: ref.url, media_type: "video/mp4" };
|
|
13865
|
+
const mediaType = ref.mime.startsWith("video/") ? ref.mime : "video/mp4";
|
|
13866
|
+
return { data: mediaRefToBase64(ref.bytes), media_type: mediaType };
|
|
13867
|
+
}
|
|
13868
|
+
function lumaOutputFormat(req, ctx) {
|
|
13869
|
+
const format = req.outputFormat;
|
|
13870
|
+
if (format === void 0 || format === "png" || format === "jpeg") return format;
|
|
13871
|
+
if ((ctx.call.onUnsupported ?? "error") === "error") {
|
|
13872
|
+
throw new ModelKitError({
|
|
13873
|
+
code: "unsupported_option",
|
|
13874
|
+
message: `${ctx.model.id} has no outputFormat "${format}". Supported: png, jpeg.`,
|
|
13875
|
+
provider: "luma",
|
|
13876
|
+
model: ctx.model.id,
|
|
13877
|
+
retryable: false
|
|
13878
|
+
});
|
|
13879
|
+
}
|
|
13880
|
+
ctx.warnings.push({
|
|
13881
|
+
code: "option_ignored",
|
|
13882
|
+
field: "outputFormat",
|
|
13883
|
+
from: format,
|
|
13884
|
+
to: "png",
|
|
13885
|
+
message: `${ctx.model.id} has no outputFormat "${format}"; using png`
|
|
13886
|
+
});
|
|
13887
|
+
return "png";
|
|
13888
|
+
}
|
|
13889
|
+
function refuseOrDrop(ctx, field, message) {
|
|
13890
|
+
if ((ctx.call.onUnsupported ?? "error") === "error") {
|
|
13891
|
+
throw new ModelKitError({
|
|
13892
|
+
code: "unsupported_option",
|
|
13893
|
+
message,
|
|
13894
|
+
provider: "luma",
|
|
13895
|
+
model: ctx.model.id,
|
|
13896
|
+
retryable: false
|
|
13897
|
+
});
|
|
13898
|
+
}
|
|
13899
|
+
ctx.warnings.push({ code: "option_ignored", field, message });
|
|
13900
|
+
}
|
|
13901
|
+
function lumaVideoMode(ctx) {
|
|
13902
|
+
const mode = LUMA_VIDEO_MODES.get(ctx.model.id);
|
|
13903
|
+
if (mode === void 0) {
|
|
13904
|
+
throw new ModelKitError({
|
|
13905
|
+
code: "unsupported_option",
|
|
13906
|
+
message: `luma routes ray-3.2 rows by catalog id; "${ctx.model.id}" is not a luma video row`,
|
|
13907
|
+
provider: "luma",
|
|
13908
|
+
model: ctx.model.id,
|
|
13909
|
+
retryable: false
|
|
13910
|
+
});
|
|
13911
|
+
}
|
|
13912
|
+
return mode;
|
|
13913
|
+
}
|
|
13914
|
+
function reframeTooTall(req) {
|
|
13915
|
+
const vertical = req.aspectRatio === "9:16" || req.aspectRatio === "3:4";
|
|
13916
|
+
return vertical && req.resolution === "1080p";
|
|
13917
|
+
}
|
|
13918
|
+
function sentResolution(req, mode) {
|
|
13919
|
+
return mode === "reframe" && reframeTooTall(req) ? "720p" : req.resolution;
|
|
13920
|
+
}
|
|
13921
|
+
function lumaReframeResolution(req, ctx) {
|
|
13922
|
+
const requested = req.resolution;
|
|
13923
|
+
if (requested === void 0 || !reframeTooTall(req)) return requested;
|
|
13924
|
+
const message = `${ctx.model.id} renders 9:16 and 3:4 reframes at up to 720p`;
|
|
13925
|
+
if ((ctx.call.onUnsupported ?? "error") === "error") {
|
|
13926
|
+
throw new ModelKitError({
|
|
13927
|
+
code: "unsupported_option",
|
|
13928
|
+
message,
|
|
13929
|
+
provider: "luma",
|
|
13930
|
+
model: ctx.model.id,
|
|
13931
|
+
retryable: false
|
|
13932
|
+
});
|
|
13933
|
+
}
|
|
13934
|
+
ctx.warnings.push({
|
|
13935
|
+
code: "resolution_coerced",
|
|
13936
|
+
field: "resolution",
|
|
13937
|
+
from: requested,
|
|
13938
|
+
to: "720p",
|
|
13939
|
+
message
|
|
13940
|
+
});
|
|
13941
|
+
return "720p";
|
|
13942
|
+
}
|
|
13943
|
+
var lumaGenerationSchema = import_zod25.z.looseObject({
|
|
13944
|
+
id: import_zod25.z.string(),
|
|
13945
|
+
state: import_zod25.z.string().optional(),
|
|
13946
|
+
output: import_zod25.z.array(
|
|
13947
|
+
import_zod25.z.looseObject({
|
|
13948
|
+
type: import_zod25.z.string().optional(),
|
|
13949
|
+
url: import_zod25.z.string().optional()
|
|
13950
|
+
})
|
|
13951
|
+
).optional(),
|
|
13952
|
+
failure_reason: import_zod25.z.string().optional().nullable(),
|
|
13953
|
+
failure_code: import_zod25.z.string().optional().nullable()
|
|
13954
|
+
});
|
|
13955
|
+
function lumaFailure(ctx, code, reason) {
|
|
13956
|
+
const detail = reason ?? code ?? "unknown_error";
|
|
13957
|
+
const message = `Luma generation failed: ${detail}`;
|
|
13958
|
+
switch (code) {
|
|
13959
|
+
case "content_moderated":
|
|
13960
|
+
return new ModelKitError({
|
|
13961
|
+
code: "content_blocked",
|
|
13962
|
+
message,
|
|
13963
|
+
provider: "luma",
|
|
13964
|
+
model: ctx.model.id,
|
|
13965
|
+
retryable: false
|
|
13966
|
+
});
|
|
13967
|
+
case "rate_limited":
|
|
13968
|
+
return new ModelKitError({
|
|
13969
|
+
code: "rate_limited",
|
|
13970
|
+
message,
|
|
13971
|
+
provider: "luma",
|
|
13972
|
+
model: ctx.model.id
|
|
13973
|
+
});
|
|
13974
|
+
case "generation_failed":
|
|
13975
|
+
case "output_not_found":
|
|
13976
|
+
return new ModelKitError({
|
|
13977
|
+
code: "provider_rejected",
|
|
13978
|
+
message,
|
|
13979
|
+
provider: "luma",
|
|
13980
|
+
model: ctx.model.id,
|
|
13981
|
+
retryable: true
|
|
13982
|
+
});
|
|
13983
|
+
case "budget_exhausted":
|
|
13984
|
+
return new ModelKitError({
|
|
13985
|
+
code: "provider_billing",
|
|
13986
|
+
message,
|
|
13987
|
+
provider: "luma",
|
|
13988
|
+
model: ctx.model.id,
|
|
13989
|
+
retryable: false
|
|
13990
|
+
});
|
|
13991
|
+
case "image_too_large":
|
|
13992
|
+
case "unsupported_format":
|
|
13993
|
+
return new ModelKitError({
|
|
13994
|
+
code: "unsupported_option",
|
|
13995
|
+
message,
|
|
13996
|
+
provider: "luma",
|
|
13997
|
+
model: ctx.model.id,
|
|
13998
|
+
retryable: false
|
|
13999
|
+
});
|
|
14000
|
+
default:
|
|
14001
|
+
return new ModelKitError({
|
|
14002
|
+
code: "provider_rejected",
|
|
14003
|
+
message,
|
|
14004
|
+
provider: "luma",
|
|
14005
|
+
model: ctx.model.id,
|
|
14006
|
+
retryable: false
|
|
14007
|
+
});
|
|
14008
|
+
}
|
|
14009
|
+
}
|
|
14010
|
+
function requestInit2(ctx, key, body) {
|
|
14011
|
+
const init = {
|
|
14012
|
+
method: body !== void 0 ? "POST" : "GET",
|
|
14013
|
+
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" }
|
|
14014
|
+
};
|
|
14015
|
+
if (body !== void 0) init.body = body;
|
|
14016
|
+
if (ctx.signal !== void 0) init.signal = ctx.signal;
|
|
14017
|
+
return init;
|
|
14018
|
+
}
|
|
14019
|
+
async function lumaRequest(ctx, url, body) {
|
|
14020
|
+
const key = lumaKey(ctx);
|
|
14021
|
+
let res;
|
|
14022
|
+
try {
|
|
14023
|
+
res = await ctx.fetch(url, requestInit2(ctx, key, body));
|
|
14024
|
+
} catch (cause) {
|
|
14025
|
+
throw classifyThrown("luma", cause, ctx.model.id);
|
|
14026
|
+
}
|
|
14027
|
+
if (!res.ok) {
|
|
14028
|
+
throw classifyHttpError(res.status, await readBody(res), "luma", ctx.model.id);
|
|
14029
|
+
}
|
|
14030
|
+
return res;
|
|
14031
|
+
}
|
|
14032
|
+
async function submitGeneration(ctx, body) {
|
|
14033
|
+
const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
|
|
14034
|
+
const res = await withRetry(
|
|
14035
|
+
() => lumaRequest(ctx, `${lumaBase(ctx)}/v1/generations`, JSON.stringify(body)),
|
|
14036
|
+
retryOptions
|
|
14037
|
+
);
|
|
14038
|
+
const parsed = lumaGenerationSchema.safeParse(await res.json());
|
|
14039
|
+
if (!parsed.success) {
|
|
14040
|
+
throw new ModelKitError({
|
|
14041
|
+
code: "provider_rejected",
|
|
14042
|
+
message: "Luma submit returned no generation id",
|
|
14043
|
+
provider: "luma",
|
|
14044
|
+
model: ctx.model.id,
|
|
14045
|
+
retryable: false
|
|
14046
|
+
});
|
|
14047
|
+
}
|
|
14048
|
+
return parsed.data;
|
|
14049
|
+
}
|
|
14050
|
+
async function readGeneration(ctx, id) {
|
|
14051
|
+
const res = await lumaRequest(ctx, `${lumaBase(ctx)}/v1/generations/${id}`);
|
|
14052
|
+
const payload = JsonValueSchema.parse(await res.json());
|
|
14053
|
+
const parsed = lumaGenerationSchema.safeParse(payload);
|
|
14054
|
+
if (!parsed.success) {
|
|
14055
|
+
throw new ModelKitError({
|
|
14056
|
+
code: "provider_rejected",
|
|
14057
|
+
message: "Luma returned an unreadable generation",
|
|
14058
|
+
provider: "luma",
|
|
14059
|
+
model: ctx.model.id,
|
|
14060
|
+
retryable: false
|
|
14061
|
+
});
|
|
14062
|
+
}
|
|
14063
|
+
return parsed.data;
|
|
14064
|
+
}
|
|
14065
|
+
function outputUrl(generation, type) {
|
|
14066
|
+
const outputs = generation.output ?? [];
|
|
14067
|
+
const match = outputs.find((item) => item.type === type && item.url);
|
|
14068
|
+
if (match?.url) return match.url;
|
|
14069
|
+
const fallback = outputs.find((item) => item.url);
|
|
14070
|
+
return fallback?.url;
|
|
14071
|
+
}
|
|
14072
|
+
async function readGenerationOnce(ctx, id) {
|
|
14073
|
+
try {
|
|
14074
|
+
return await readGeneration(ctx, id);
|
|
14075
|
+
} catch (cause) {
|
|
14076
|
+
if (ctx.call.maxRetries === 0) throw cause;
|
|
14077
|
+
if (isModelKitError(cause) && (cause.code === "network" || cause.status === 429 || (cause.status ?? 0) >= 500)) {
|
|
14078
|
+
return void 0;
|
|
14079
|
+
}
|
|
14080
|
+
throw cause;
|
|
14081
|
+
}
|
|
14082
|
+
}
|
|
14083
|
+
async function checkGeneration(ctx, id, type) {
|
|
14084
|
+
const generation = await readGenerationOnce(ctx, id);
|
|
14085
|
+
if (generation === void 0) return void 0;
|
|
14086
|
+
if (generation.state === "completed") {
|
|
14087
|
+
const url = outputUrl(generation, type);
|
|
14088
|
+
if (!url) {
|
|
14089
|
+
throw new ModelKitError({
|
|
14090
|
+
code: "provider_rejected",
|
|
14091
|
+
message: "Luma completed without an output URL",
|
|
14092
|
+
provider: "luma",
|
|
14093
|
+
model: ctx.model.id,
|
|
14094
|
+
retryable: false
|
|
14095
|
+
});
|
|
14096
|
+
}
|
|
14097
|
+
return url;
|
|
14098
|
+
}
|
|
14099
|
+
if (generation.state === "failed") {
|
|
14100
|
+
throw lumaFailure(
|
|
14101
|
+
ctx,
|
|
14102
|
+
generation.failure_code ?? void 0,
|
|
14103
|
+
generation.failure_reason ?? void 0
|
|
14104
|
+
);
|
|
14105
|
+
}
|
|
14106
|
+
return void 0;
|
|
14107
|
+
}
|
|
14108
|
+
async function downloadBytes(ctx, url, fallback) {
|
|
14109
|
+
let bytes;
|
|
14110
|
+
let header;
|
|
14111
|
+
try {
|
|
14112
|
+
const out = await mediaRefToBytes({ url }, ctx.fetch, {
|
|
14113
|
+
...ctx.signal !== void 0 && { signal: ctx.signal },
|
|
14114
|
+
provider: "luma",
|
|
14115
|
+
model: ctx.model.id
|
|
14116
|
+
});
|
|
14117
|
+
bytes = out.bytes;
|
|
14118
|
+
header = out.mime;
|
|
14119
|
+
} catch (cause) {
|
|
14120
|
+
throw classifyThrown("luma", cause, ctx.model.id);
|
|
14121
|
+
}
|
|
14122
|
+
const kind = fallback.split("/")[0];
|
|
14123
|
+
const usable = header !== void 0 && header.startsWith(`${kind}/`);
|
|
14124
|
+
return { bytes, mime: usable ? header : fallback };
|
|
14125
|
+
}
|
|
14126
|
+
function imageUsage2(ctx) {
|
|
14127
|
+
return {
|
|
14128
|
+
model: ctx.model.id,
|
|
14129
|
+
provider: "luma",
|
|
14130
|
+
modality: "IMAGE",
|
|
14131
|
+
unit: "images",
|
|
14132
|
+
quantity: 1,
|
|
14133
|
+
imageSize: "2K"
|
|
14134
|
+
};
|
|
14135
|
+
}
|
|
14136
|
+
var GENERATE_SECONDS = 5;
|
|
14137
|
+
var MAX_PLAUSIBLE_SECONDS = 60;
|
|
14138
|
+
function billedSeconds(req, mode, bytes) {
|
|
14139
|
+
if (mode === "generate") return GENERATE_SECONDS;
|
|
14140
|
+
const measured = mp4DurationSeconds(bytes);
|
|
14141
|
+
const source2 = req.sourceVideo;
|
|
14142
|
+
const length = measured !== void 0 && measured > 0 && measured <= MAX_PLAUSIBLE_SECONDS ? measured : source2 !== void 0 && "url" in source2 ? source2.durationSeconds : void 0;
|
|
14143
|
+
return Math.max(length ?? 0, GENERATE_SECONDS);
|
|
14144
|
+
}
|
|
14145
|
+
function videoUsage4(ctx, req, mode, bytes) {
|
|
14146
|
+
const seconds3 = billedSeconds(req, mode, bytes);
|
|
14147
|
+
const event = {
|
|
14148
|
+
model: ctx.model.id,
|
|
14149
|
+
provider: "luma",
|
|
14150
|
+
modality: "VIDEO",
|
|
14151
|
+
unit: "seconds",
|
|
14152
|
+
quantity: seconds3,
|
|
14153
|
+
durationSeconds: seconds3
|
|
14154
|
+
};
|
|
14155
|
+
const resolution = sentResolution(req, mode);
|
|
14156
|
+
if (resolution !== void 0) event.resolution = resolution;
|
|
14157
|
+
return event;
|
|
14158
|
+
}
|
|
14159
|
+
function imageBody(req, ctx, outputFormat) {
|
|
14160
|
+
const prompt = checkPrompt(req, ctx);
|
|
14161
|
+
const model = ctx.model.providerModelId;
|
|
14162
|
+
const ratio = req.aspectRatio !== "adaptive" ? req.aspectRatio : void 0;
|
|
14163
|
+
const [source2, ...rest] = req.references ?? [];
|
|
14164
|
+
if (source2 === void 0) {
|
|
14165
|
+
const body2 = { model, type: "image", prompt };
|
|
14166
|
+
if (ratio !== void 0) body2["aspect_ratio"] = ratio;
|
|
14167
|
+
if (outputFormat !== void 0) body2["output_format"] = outputFormat;
|
|
14168
|
+
return body2;
|
|
14169
|
+
}
|
|
14170
|
+
if (ratio !== void 0) {
|
|
14171
|
+
ctx.warnings.push({
|
|
14172
|
+
code: "option_ignored",
|
|
14173
|
+
field: "aspectRatio",
|
|
14174
|
+
message: `${ctx.model.id} keeps the source image's aspect ratio on an edit`
|
|
14175
|
+
});
|
|
14176
|
+
}
|
|
14177
|
+
const body = {
|
|
14178
|
+
model,
|
|
14179
|
+
type: "image_edit",
|
|
14180
|
+
prompt,
|
|
14181
|
+
source: imageRef(source2)
|
|
14182
|
+
};
|
|
14183
|
+
if (rest.length > 0) body["image_ref"] = rest.map(imageRef);
|
|
14184
|
+
if (outputFormat !== void 0) body["output_format"] = outputFormat;
|
|
14185
|
+
return body;
|
|
14186
|
+
}
|
|
14187
|
+
function videoBody(req, ctx, mode) {
|
|
14188
|
+
const prompt = checkPrompt(req, ctx);
|
|
14189
|
+
const model = ctx.model.providerModelId;
|
|
14190
|
+
const hasReferences = (req.referenceImages ?? []).length + (req.referenceVideos ?? []).length + (req.referenceAudios ?? []).length > 0;
|
|
14191
|
+
if (hasReferences) {
|
|
14192
|
+
refuseOrDrop(
|
|
14193
|
+
ctx,
|
|
14194
|
+
"referenceImages",
|
|
14195
|
+
`${ctx.model.id} takes no reference images, videos or audio`
|
|
14196
|
+
);
|
|
14197
|
+
}
|
|
14198
|
+
if (mode === "generate") {
|
|
14199
|
+
const body = {
|
|
14200
|
+
model,
|
|
14201
|
+
type: "video",
|
|
14202
|
+
prompt,
|
|
14203
|
+
video: {
|
|
14204
|
+
...req.resolution !== void 0 && { resolution: req.resolution },
|
|
14205
|
+
duration: "5s",
|
|
14206
|
+
...req.firstFrame !== void 0 && { start_frame: imageRef(req.firstFrame) },
|
|
14207
|
+
...req.lastFrame !== void 0 && { end_frame: imageRef(req.lastFrame) }
|
|
14208
|
+
}
|
|
14209
|
+
};
|
|
14210
|
+
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
14211
|
+
body["aspect_ratio"] = req.aspectRatio;
|
|
14212
|
+
}
|
|
14213
|
+
return body;
|
|
14214
|
+
}
|
|
14215
|
+
const sourceVideo = req.sourceVideo;
|
|
14216
|
+
if (!sourceVideo) {
|
|
14217
|
+
throw new ModelKitError({
|
|
14218
|
+
code: "missing_input",
|
|
14219
|
+
message: `${ctx.model.id} requires sourceVideo`,
|
|
14220
|
+
provider: "luma",
|
|
14221
|
+
model: ctx.model.id,
|
|
14222
|
+
retryable: false
|
|
14223
|
+
});
|
|
14224
|
+
}
|
|
14225
|
+
if (mode === "edit") {
|
|
14226
|
+
if (req.lastFrame !== void 0) {
|
|
14227
|
+
refuseOrDrop(ctx, "lastFrame", `${ctx.model.id} takes no end frame`);
|
|
14228
|
+
}
|
|
14229
|
+
const body = {
|
|
14230
|
+
model,
|
|
14231
|
+
type: "video_edit",
|
|
14232
|
+
prompt,
|
|
14233
|
+
source: videoRef(sourceVideo),
|
|
14234
|
+
video: {
|
|
14235
|
+
...req.resolution !== void 0 && { resolution: req.resolution },
|
|
14236
|
+
...req.firstFrame !== void 0 && { start_frame: imageRef(req.firstFrame) },
|
|
14237
|
+
edit: { auto_controls: true }
|
|
14238
|
+
}
|
|
14239
|
+
};
|
|
14240
|
+
return body;
|
|
14241
|
+
}
|
|
14242
|
+
if (req.firstFrame !== void 0) {
|
|
14243
|
+
refuseOrDrop(ctx, "firstFrame", `${ctx.model.id} takes no start frame`);
|
|
14244
|
+
}
|
|
14245
|
+
if (req.lastFrame !== void 0) {
|
|
14246
|
+
refuseOrDrop(ctx, "lastFrame", `${ctx.model.id} takes no end frame`);
|
|
14247
|
+
}
|
|
14248
|
+
const aspectRatio = req.aspectRatio;
|
|
14249
|
+
if (aspectRatio === void 0 || aspectRatio === "adaptive") {
|
|
14250
|
+
throw new ModelKitError({
|
|
14251
|
+
code: "missing_input",
|
|
14252
|
+
message: `${ctx.model.id} needs an aspectRatio target`,
|
|
14253
|
+
provider: "luma",
|
|
14254
|
+
model: ctx.model.id,
|
|
14255
|
+
retryable: false
|
|
14256
|
+
});
|
|
14257
|
+
}
|
|
14258
|
+
const resolution = lumaReframeResolution(req, ctx);
|
|
14259
|
+
return {
|
|
14260
|
+
model,
|
|
14261
|
+
type: "video_reframe",
|
|
14262
|
+
prompt,
|
|
14263
|
+
aspect_ratio: aspectRatio,
|
|
14264
|
+
source: videoRef(sourceVideo),
|
|
14265
|
+
video: { ...resolution !== void 0 && { resolution } }
|
|
14266
|
+
};
|
|
14267
|
+
}
|
|
14268
|
+
async function generateLumaImage(req, ctx) {
|
|
14269
|
+
throwIfAborted(ctx.signal);
|
|
14270
|
+
lumaKey(ctx);
|
|
14271
|
+
if (!LUMA_IMAGE_MODEL_IDS.has(ctx.model.providerModelId.toLowerCase())) {
|
|
14272
|
+
throw new ModelKitError({
|
|
14273
|
+
code: "unsupported_option",
|
|
14274
|
+
message: `luma has no image mapping for "${ctx.model.providerModelId}"`,
|
|
14275
|
+
provider: "luma",
|
|
14276
|
+
model: ctx.model.id,
|
|
14277
|
+
retryable: false
|
|
14278
|
+
});
|
|
14279
|
+
}
|
|
14280
|
+
const format = lumaOutputFormat(req, ctx);
|
|
14281
|
+
const created = await submitGeneration(ctx, imageBody(req, ctx, format));
|
|
14282
|
+
const url = await pollUntil(checkGeneration.bind(null, ctx, created.id, "image"), {
|
|
14283
|
+
intervalMs: IMAGE_POLL_INTERVAL_MS,
|
|
14284
|
+
timeoutMs: IMAGE_TIMEOUT_MS,
|
|
14285
|
+
...ctx.signal !== void 0 && { signal: ctx.signal }
|
|
14286
|
+
});
|
|
14287
|
+
const image = await downloadBytes(ctx, url, format === "jpeg" ? "image/jpeg" : "image/png");
|
|
14288
|
+
return {
|
|
14289
|
+
images: [image],
|
|
14290
|
+
usage: imageUsage2(ctx),
|
|
14291
|
+
raw: created
|
|
14292
|
+
};
|
|
14293
|
+
}
|
|
14294
|
+
function lumaVideoJob(ctx, req, mode, id) {
|
|
14295
|
+
return {
|
|
14296
|
+
jobId: id,
|
|
14297
|
+
async poll() {
|
|
14298
|
+
const generation = await readGenerationOnce(ctx, id);
|
|
14299
|
+
if (generation?.state === "failed") return { status: "failed" };
|
|
14300
|
+
if (generation?.state === "completed") return { status: "succeeded" };
|
|
14301
|
+
return { status: "pending" };
|
|
14302
|
+
},
|
|
14303
|
+
async result(opts) {
|
|
14304
|
+
const signal = opts?.signal ?? ctx.signal;
|
|
14305
|
+
const url = await pollUntil(checkGeneration.bind(null, ctx, id, "video"), {
|
|
14306
|
+
intervalMs: opts?.pollIntervalMs ?? VIDEO_POLL_INTERVAL_MS,
|
|
14307
|
+
timeoutMs: opts?.timeoutMs ?? VIDEO_TIMEOUT_MS,
|
|
14308
|
+
...signal !== void 0 && { signal }
|
|
14309
|
+
});
|
|
14310
|
+
const video = await downloadBytes(ctx, url, "video/mp4");
|
|
14311
|
+
const result = {
|
|
14312
|
+
video,
|
|
14313
|
+
usage: videoUsage4(ctx, req, mode, video.bytes),
|
|
14314
|
+
raw: { id }
|
|
14315
|
+
};
|
|
14316
|
+
return result;
|
|
14317
|
+
}
|
|
14318
|
+
};
|
|
14319
|
+
}
|
|
14320
|
+
async function generateLumaVideo(req, ctx) {
|
|
14321
|
+
throwIfAborted(ctx.signal);
|
|
14322
|
+
lumaKey(ctx);
|
|
14323
|
+
if (ctx.model.providerModelId.toLowerCase() !== LUMA_VIDEO_MODEL_ID) {
|
|
14324
|
+
throw new ModelKitError({
|
|
14325
|
+
code: "unsupported_option",
|
|
14326
|
+
message: `luma has no video mapping for "${ctx.model.providerModelId}"`,
|
|
14327
|
+
provider: "luma",
|
|
14328
|
+
model: ctx.model.id,
|
|
14329
|
+
retryable: false
|
|
14330
|
+
});
|
|
14331
|
+
}
|
|
14332
|
+
const mode = lumaVideoMode(ctx);
|
|
14333
|
+
const created = await submitGeneration(ctx, videoBody(req, ctx, mode));
|
|
14334
|
+
return lumaVideoJob(ctx, req, mode, created.id);
|
|
14335
|
+
}
|
|
14336
|
+
var lumaAdapter = {
|
|
14337
|
+
id: "luma",
|
|
14338
|
+
generateImage: generateLumaImage,
|
|
14339
|
+
generateVideo: generateLumaVideo,
|
|
14340
|
+
resumeVideo: (req, jobId, ctx) => {
|
|
14341
|
+
throwIfAborted(ctx.signal);
|
|
14342
|
+
lumaKey(ctx);
|
|
14343
|
+
return lumaVideoJob(ctx, req, lumaVideoMode(ctx), jobId);
|
|
14344
|
+
}
|
|
14345
|
+
};
|
|
14346
|
+
|
|
13554
14347
|
// src/adapters/openai-image.ts
|
|
13555
14348
|
var import_openai2 = __toESM(require("openai"), 1);
|
|
13556
|
-
var
|
|
14349
|
+
var import_zod26 = require("zod");
|
|
13557
14350
|
var MAX_EDIT_REFERENCES = 16;
|
|
13558
14351
|
function aspectRatioToSize(ratio, tier) {
|
|
13559
14352
|
const TIER_LONG_EDGE = {
|
|
@@ -13636,9 +14429,9 @@ function toProviderError2(cause, ctx) {
|
|
|
13636
14429
|
ctx.model.id
|
|
13637
14430
|
);
|
|
13638
14431
|
}
|
|
13639
|
-
var openaiUsageSchema =
|
|
13640
|
-
input_tokens:
|
|
13641
|
-
output_tokens:
|
|
14432
|
+
var openaiUsageSchema = import_zod26.z.object({
|
|
14433
|
+
input_tokens: import_zod26.z.number().optional(),
|
|
14434
|
+
output_tokens: import_zod26.z.number().optional()
|
|
13642
14435
|
});
|
|
13643
14436
|
var openaiImageAdapter = {
|
|
13644
14437
|
id: "openai-image",
|
|
@@ -14050,13 +14843,13 @@ var prodiaAdapter = {
|
|
|
14050
14843
|
var import_replicate = __toESM(require("replicate"), 1);
|
|
14051
14844
|
|
|
14052
14845
|
// src/adapters/replicate-http.ts
|
|
14053
|
-
var
|
|
14054
|
-
var predictionSchema =
|
|
14055
|
-
id:
|
|
14056
|
-
status:
|
|
14846
|
+
var import_zod27 = require("zod");
|
|
14847
|
+
var predictionSchema = import_zod27.z.object({
|
|
14848
|
+
id: import_zod27.z.string(),
|
|
14849
|
+
status: import_zod27.z.string(),
|
|
14057
14850
|
output: JsonValueSchema.optional(),
|
|
14058
14851
|
error: JsonValueSchema.optional(),
|
|
14059
|
-
metrics:
|
|
14852
|
+
metrics: import_zod27.z.object({ predict_time: import_zod27.z.number().optional() }).optional()
|
|
14060
14853
|
});
|
|
14061
14854
|
function createReplicateHttpClient(opts) {
|
|
14062
14855
|
async function request(path, body, signal) {
|
|
@@ -14107,7 +14900,7 @@ function createReplicateHttpClient(opts) {
|
|
|
14107
14900
|
}
|
|
14108
14901
|
|
|
14109
14902
|
// src/adapters/replicate.ts
|
|
14110
|
-
var
|
|
14903
|
+
var import_zod28 = require("zod");
|
|
14111
14904
|
var POLL_INTERVAL_MS = 1e3;
|
|
14112
14905
|
var POLL_TIMEOUT_MS = 15 * 6e4;
|
|
14113
14906
|
var defaultReplicateDeps = {
|
|
@@ -14147,8 +14940,8 @@ function route(providerModelId) {
|
|
|
14147
14940
|
if (!providerModelId.includes("/")) return { version: providerModelId };
|
|
14148
14941
|
return { model: providerModelId };
|
|
14149
14942
|
}
|
|
14150
|
-
var replicateResponseStatusSchema =
|
|
14151
|
-
response:
|
|
14943
|
+
var replicateResponseStatusSchema = import_zod28.z.object({
|
|
14944
|
+
response: import_zod28.z.object({ status: import_zod28.z.number() }).partial()
|
|
14152
14945
|
});
|
|
14153
14946
|
function replicateError(cause, ctx) {
|
|
14154
14947
|
if (isModelKitError(cause)) return cause;
|
|
@@ -14157,10 +14950,6 @@ function replicateError(cause, ctx) {
|
|
|
14157
14950
|
const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
|
|
14158
14951
|
return classifyThrown("replicate", cause, ctx.model.id, { status, body: info.body });
|
|
14159
14952
|
}
|
|
14160
|
-
function baseModelId(providerModelId) {
|
|
14161
|
-
const colon = providerModelId.indexOf(":");
|
|
14162
|
-
return colon === -1 ? providerModelId : providerModelId.slice(0, colon);
|
|
14163
|
-
}
|
|
14164
14953
|
function predictionErrorBody(cause) {
|
|
14165
14954
|
const parsed = JsonValueSchema.safeParse(cause);
|
|
14166
14955
|
if (parsed.success) return parsed.data;
|
|
@@ -14175,7 +14964,7 @@ function isUrlFn(value) {
|
|
|
14175
14964
|
function extractOutputUrl(output) {
|
|
14176
14965
|
const root = Array.isArray(output) ? output[0] : output;
|
|
14177
14966
|
if (root === void 0) throw noOutput();
|
|
14178
|
-
const asString =
|
|
14967
|
+
const asString = import_zod28.z.string().safeParse(root);
|
|
14179
14968
|
if (asString.success && asString.data) return asString.data;
|
|
14180
14969
|
if (root instanceof URL) return root.href;
|
|
14181
14970
|
if (isObjectOutput(root)) {
|
|
@@ -14184,15 +14973,15 @@ function extractOutputUrl(output) {
|
|
|
14184
14973
|
if (urlValue !== void 0 && isUrlFn(urlValue)) {
|
|
14185
14974
|
const called = urlValue();
|
|
14186
14975
|
if (called instanceof URL) return called.href;
|
|
14187
|
-
const calledString =
|
|
14976
|
+
const calledString = import_zod28.z.string().safeParse(called);
|
|
14188
14977
|
if (calledString.success && calledString.data) return calledString.data;
|
|
14189
14978
|
} else {
|
|
14190
|
-
const direct =
|
|
14979
|
+
const direct = import_zod28.z.string().safeParse(urlValue);
|
|
14191
14980
|
if (direct.success && direct.data) return direct.data;
|
|
14192
14981
|
}
|
|
14193
14982
|
}
|
|
14194
14983
|
if ("default" in root) {
|
|
14195
|
-
const fallback =
|
|
14984
|
+
const fallback = import_zod28.z.string().safeParse(root.default);
|
|
14196
14985
|
if (fallback.success && fallback.data) return fallback.data;
|
|
14197
14986
|
}
|
|
14198
14987
|
}
|
|
@@ -14253,7 +15042,7 @@ async function runPrediction(ctx, input, deps) {
|
|
|
14253
15042
|
}
|
|
14254
15043
|
return void 0;
|
|
14255
15044
|
}, pollOpts);
|
|
14256
|
-
const predictTime =
|
|
15045
|
+
const predictTime = import_zod28.z.number().safeParse(done.metrics?.predict_time);
|
|
14257
15046
|
if (done.output === void 0) throw noOutput();
|
|
14258
15047
|
return {
|
|
14259
15048
|
url: extractOutputUrl(done.output),
|
|
@@ -14261,7 +15050,7 @@ async function runPrediction(ctx, input, deps) {
|
|
|
14261
15050
|
raw: done
|
|
14262
15051
|
};
|
|
14263
15052
|
}
|
|
14264
|
-
function
|
|
15053
|
+
function imageUsage3(ctx, req) {
|
|
14265
15054
|
const event = {
|
|
14266
15055
|
model: ctx.model.id,
|
|
14267
15056
|
provider: "replicate",
|
|
@@ -14273,7 +15062,7 @@ function imageUsage2(ctx, req) {
|
|
|
14273
15062
|
if (req.quality !== void 0) event.imageQuality = req.quality;
|
|
14274
15063
|
return event;
|
|
14275
15064
|
}
|
|
14276
|
-
function
|
|
15065
|
+
function videoUsage5(ctx, req) {
|
|
14277
15066
|
const event = {
|
|
14278
15067
|
model: ctx.model.id,
|
|
14279
15068
|
provider: "replicate",
|
|
@@ -14314,17 +15103,7 @@ var REPLICATE_IMAGE_KINDS = {
|
|
|
14314
15103
|
"qwen-edit-apps/qwen-image-edit-plus-lora-skin": "qwen-edit"
|
|
14315
15104
|
};
|
|
14316
15105
|
function imageKind(providerModelId) {
|
|
14317
|
-
return REPLICATE_IMAGE_KINDS[
|
|
14318
|
-
}
|
|
14319
|
-
var REPLICATE_VIDEO_KINDS = {
|
|
14320
|
-
"kling-video/v2.5-turbo/pro/image-to-video": "kling",
|
|
14321
|
-
"kling-video/v3.0/pro/image-to-video": "kling",
|
|
14322
|
-
"kwaivgi/kling-v3-video": "kling",
|
|
14323
|
-
"kwaivgi/kling-v3-omni-video": "kling-omni",
|
|
14324
|
-
"minimax/hailuo-02": "hailuo"
|
|
14325
|
-
};
|
|
14326
|
-
function videoKind(providerModelId) {
|
|
14327
|
-
return REPLICATE_VIDEO_KINDS[baseModelId(providerModelId)];
|
|
15106
|
+
return REPLICATE_IMAGE_KINDS[replicateBaseModelId(providerModelId)] ?? "generic";
|
|
14328
15107
|
}
|
|
14329
15108
|
function isReplicateVideoKnown(providerModelId) {
|
|
14330
15109
|
return videoKind(providerModelId) !== void 0;
|
|
@@ -14335,7 +15114,7 @@ var REPLICATE_AUDIO_KINDS = {
|
|
|
14335
15114
|
"google/lyria-2": "lyria"
|
|
14336
15115
|
};
|
|
14337
15116
|
function audioKind(providerModelId) {
|
|
14338
|
-
return REPLICATE_AUDIO_KINDS[
|
|
15117
|
+
return REPLICATE_AUDIO_KINDS[replicateBaseModelId(providerModelId)];
|
|
14339
15118
|
}
|
|
14340
15119
|
function isReplicateAudioKnown(providerModelId) {
|
|
14341
15120
|
return audioKind(providerModelId) !== void 0;
|
|
@@ -14509,7 +15288,7 @@ async function generateReplicateImage(req, ctx, deps) {
|
|
|
14509
15288
|
}
|
|
14510
15289
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|
|
14511
15290
|
const file = await download(ctx, url);
|
|
14512
|
-
const usage3 =
|
|
15291
|
+
const usage3 = imageUsage3(ctx, req);
|
|
14513
15292
|
usage3.quantity = predictTime;
|
|
14514
15293
|
return { images: [{ bytes: file.bytes, mime: file.mime }], usage: usage3, raw, outputUrl: url };
|
|
14515
15294
|
}
|
|
@@ -14539,14 +15318,6 @@ function replicateVideoResolution(providerModelId, req) {
|
|
|
14539
15318
|
if (kind === "hailuo") return hailuoResolution(req);
|
|
14540
15319
|
return req.resolution;
|
|
14541
15320
|
}
|
|
14542
|
-
var KLING_TIERS = [
|
|
14543
|
-
{ mode: "standard", resolution: "720p" },
|
|
14544
|
-
{ mode: "pro", resolution: "1080p" },
|
|
14545
|
-
{ mode: "4k", resolution: "4k" }
|
|
14546
|
-
];
|
|
14547
|
-
function klingTier(req) {
|
|
14548
|
-
return KLING_TIERS.find((tier) => tier.resolution === req.resolution) ?? KLING_TIERS.find((tier) => tier.mode === req.mode) ?? KLING_TIERS[0];
|
|
14549
|
-
}
|
|
14550
15321
|
function klingOmniInput(req) {
|
|
14551
15322
|
const input = {
|
|
14552
15323
|
prompt: req.prompt,
|
|
@@ -14624,7 +15395,7 @@ async function generateReplicateVideo(req, ctx, deps) {
|
|
|
14624
15395
|
throw replicateError(cause, ctx);
|
|
14625
15396
|
}
|
|
14626
15397
|
if (current.status === "succeeded") {
|
|
14627
|
-
const predictTime =
|
|
15398
|
+
const predictTime = import_zod28.z.number().safeParse(current.metrics?.predict_time);
|
|
14628
15399
|
if (current.output === void 0) throw noOutput();
|
|
14629
15400
|
return {
|
|
14630
15401
|
url: extractOutputUrl(current.output),
|
|
@@ -14643,7 +15414,7 @@ async function generateReplicateVideo(req, ctx, deps) {
|
|
|
14643
15414
|
return void 0;
|
|
14644
15415
|
};
|
|
14645
15416
|
const toResult = (done) => {
|
|
14646
|
-
const usage3 =
|
|
15417
|
+
const usage3 = videoUsage5(ctx, req);
|
|
14647
15418
|
usage3.quantity = done.predictTime;
|
|
14648
15419
|
return { video: { url: done.url }, usage: usage3, raw: done.raw };
|
|
14649
15420
|
};
|
|
@@ -14766,7 +15537,7 @@ async function generateReplicateAudio(req, ctx, deps) {
|
|
|
14766
15537
|
// src/adapters/xai-video.ts
|
|
14767
15538
|
var import_ai3 = require("ai");
|
|
14768
15539
|
var import_xai2 = require("@ai-sdk/xai");
|
|
14769
|
-
var
|
|
15540
|
+
var import_zod29 = require("zod");
|
|
14770
15541
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
14771
15542
|
var POLL_TIMEOUT_MS2 = 15 * 6e4;
|
|
14772
15543
|
var defaultXaiDeps = {
|
|
@@ -14779,8 +15550,8 @@ function createXaiVideoAdapter(deps = defaultXaiDeps) {
|
|
|
14779
15550
|
};
|
|
14780
15551
|
}
|
|
14781
15552
|
var xaiVideoAdapter = createXaiVideoAdapter();
|
|
14782
|
-
var xaiResponseStatusSchema =
|
|
14783
|
-
response:
|
|
15553
|
+
var xaiResponseStatusSchema = import_zod29.z.object({
|
|
15554
|
+
response: import_zod29.z.object({ status: import_zod29.z.number() }).partial()
|
|
14784
15555
|
});
|
|
14785
15556
|
function xaiError(cause, ctx) {
|
|
14786
15557
|
const info = describeThrown(cause);
|
|
@@ -14788,12 +15559,12 @@ function xaiError(cause, ctx) {
|
|
|
14788
15559
|
const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
|
|
14789
15560
|
return classifyThrown("xai-video", cause, ctx.model.id, { status, body: info.body });
|
|
14790
15561
|
}
|
|
14791
|
-
var xaiMetaSchema =
|
|
15562
|
+
var xaiMetaSchema = import_zod29.z.object({
|
|
14792
15563
|
videoUrl: JsonValueSchema.optional(),
|
|
14793
15564
|
costInUsdTicks: JsonValueSchema.optional(),
|
|
14794
15565
|
duration: JsonValueSchema.optional()
|
|
14795
15566
|
});
|
|
14796
|
-
var xaiProviderMetadataSchema =
|
|
15567
|
+
var xaiProviderMetadataSchema = import_zod29.z.object({ xai: xaiMetaSchema });
|
|
14797
15568
|
function metaOf(result) {
|
|
14798
15569
|
const parsed = xaiProviderMetadataSchema.partial().safeParse(result.providerMetadata);
|
|
14799
15570
|
if (!parsed.success) return {};
|
|
@@ -14909,7 +15680,7 @@ async function mapResult(ctx, req, result) {
|
|
|
14909
15680
|
};
|
|
14910
15681
|
}
|
|
14911
15682
|
const meta = metaOf(result);
|
|
14912
|
-
const videoUrl =
|
|
15683
|
+
const videoUrl = import_zod29.z.string().safeParse(meta.videoUrl);
|
|
14913
15684
|
if (videoUrl.success && videoUrl.data) {
|
|
14914
15685
|
const res = await ctx.fetch(videoUrl.data);
|
|
14915
15686
|
if (!res.ok) {
|
|
@@ -14932,7 +15703,7 @@ async function mapResult(ctx, req, result) {
|
|
|
14932
15703
|
});
|
|
14933
15704
|
}
|
|
14934
15705
|
function usage2(ctx, req, meta) {
|
|
14935
|
-
const costTicks =
|
|
15706
|
+
const costTicks = import_zod29.z.number().safeParse(meta.costInUsdTicks);
|
|
14936
15707
|
const cost = costTicks.success ? costTicks.data / 1e10 : void 0;
|
|
14937
15708
|
const event = {
|
|
14938
15709
|
model: ctx.model.id,
|
|
@@ -14980,7 +15751,8 @@ var DEFAULT_ADAPTERS = {
|
|
|
14980
15751
|
replicate: replicateAdapter,
|
|
14981
15752
|
prodia: prodiaAdapter,
|
|
14982
15753
|
higgsfield: higgsfieldAdapter,
|
|
14983
|
-
"xai-video": xaiVideoAdapter
|
|
15754
|
+
"xai-video": xaiVideoAdapter,
|
|
15755
|
+
luma: lumaAdapter
|
|
14984
15756
|
};
|
|
14985
15757
|
|
|
14986
15758
|
// src/catalog/data-only.ts
|
|
@@ -15096,6 +15868,10 @@ function dataOnlyCapable(row2) {
|
|
|
15096
15868
|
reason: "higgsfield providerModelId must be a platform path, not a URL"
|
|
15097
15869
|
};
|
|
15098
15870
|
}
|
|
15871
|
+
case "luma": {
|
|
15872
|
+
const reason = lumaRowRefusal(row2);
|
|
15873
|
+
return reason === void 0 ? { ok: true } : { ok: false, reason };
|
|
15874
|
+
}
|
|
15099
15875
|
default: {
|
|
15100
15876
|
return assertNever(row2.adapter);
|
|
15101
15877
|
}
|
|
@@ -15115,22 +15891,22 @@ var liveState = store[KEY] ??= {
|
|
|
15115
15891
|
var liveCatalog = liveState.catalog;
|
|
15116
15892
|
|
|
15117
15893
|
// src/catalog/load.ts
|
|
15118
|
-
var
|
|
15894
|
+
var import_zod30 = require("zod");
|
|
15119
15895
|
function rowCount() {
|
|
15120
15896
|
return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
|
|
15121
15897
|
}
|
|
15122
15898
|
function authHeaders(auth) {
|
|
15123
15899
|
return "bearer" in auth ? { Authorization: `Bearer ${auth.bearer}` } : { "x-api-key": auth.apiKey };
|
|
15124
15900
|
}
|
|
15125
|
-
var EnvelopeSchema =
|
|
15126
|
-
rows:
|
|
15127
|
-
revision:
|
|
15901
|
+
var EnvelopeSchema = import_zod30.z.object({
|
|
15902
|
+
rows: import_zod30.z.array(JsonValueSchema),
|
|
15903
|
+
revision: import_zod30.z.string().optional()
|
|
15128
15904
|
});
|
|
15129
15905
|
function dropReason(path, message) {
|
|
15130
15906
|
return path.length === 0 ? message : `${path.map((part) => String(part)).join(".")} ${message}`;
|
|
15131
15907
|
}
|
|
15132
15908
|
function rowId(raw) {
|
|
15133
|
-
const parsed =
|
|
15909
|
+
const parsed = import_zod30.z.object({ id: import_zod30.z.string().min(1) }).loose().safeParse(raw);
|
|
15134
15910
|
if (!parsed.success) return "?";
|
|
15135
15911
|
return parsed.data.id;
|
|
15136
15912
|
}
|
|
@@ -15774,8 +16550,10 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
15774
16550
|
warnings
|
|
15775
16551
|
);
|
|
15776
16552
|
if (aspectRatio !== void 0) merged.aspectRatio = aspectRatio;
|
|
16553
|
+
fillReplicateKlingResolution(model, merged);
|
|
15777
16554
|
const resolution = resolveVideoResolution(merged.resolution, model, onUnsupported, warnings);
|
|
15778
16555
|
if (resolution !== void 0) merged.resolution = resolution;
|
|
16556
|
+
if (isReplicateKling(model)) delete merged.mode;
|
|
15779
16557
|
const duration = resolveDuration(
|
|
15780
16558
|
merged.durationSeconds,
|
|
15781
16559
|
c.durations,
|
|
@@ -16177,7 +16955,8 @@ var ADAPTER_KEYS = {
|
|
|
16177
16955
|
replicate: ["replicate"],
|
|
16178
16956
|
prodia: ["prodia"],
|
|
16179
16957
|
higgsfield: ["higgsfield"],
|
|
16180
|
-
"xai-video": ["xai"]
|
|
16958
|
+
"xai-video": ["xai"],
|
|
16959
|
+
luma: ["luma"]
|
|
16181
16960
|
};
|
|
16182
16961
|
function hasAll(keys, names) {
|
|
16183
16962
|
if (!keys) return false;
|
|
@@ -16235,6 +17014,7 @@ function keysFromEnv(env, prefix = "") {
|
|
|
16235
17014
|
set("prodia", pick2("PRODIA_API_KEY", "PRODIA_TOKEN"));
|
|
16236
17015
|
set("higgsfield", pick2("HIGGSFIELD_API_KEY"));
|
|
16237
17016
|
set("higgsfieldSecret", pick2("HIGGSFIELD_API_SECRET"));
|
|
17017
|
+
set("luma", pick2("LUMA_API_KEY", "LUMA_AGENTS_API_KEY"));
|
|
16238
17018
|
set("cloudflare", pick2("CLOUDFLARE_AI_GATEWAY_TOKEN", "CF_AIG_TOKEN"));
|
|
16239
17019
|
const bearer = pick2("AWS_BEARER_TOKEN_BEDROCK");
|
|
16240
17020
|
const accessKeyId = pick2("AWS_ACCESS_KEY_ID");
|
|
@@ -16257,7 +17037,7 @@ function keysFromEnv(env, prefix = "") {
|
|
|
16257
17037
|
|
|
16258
17038
|
// src/text.ts
|
|
16259
17039
|
var import_ai4 = require("ai");
|
|
16260
|
-
var
|
|
17040
|
+
var import_zod31 = require("zod");
|
|
16261
17041
|
function mergeTextProviderOptions(catalog, caller) {
|
|
16262
17042
|
const merged = {};
|
|
16263
17043
|
const catalogOptions = catalog.providerOptions ?? {};
|
|
@@ -16296,8 +17076,8 @@ function passthroughTextModel(model) {
|
|
|
16296
17076
|
pricingKind: "token"
|
|
16297
17077
|
};
|
|
16298
17078
|
}
|
|
16299
|
-
var perplexityCostSchema =
|
|
16300
|
-
perplexity:
|
|
17079
|
+
var perplexityCostSchema = import_zod31.z.object({
|
|
17080
|
+
perplexity: import_zod31.z.object({ cost: import_zod31.z.object({ totalCost: import_zod31.z.number().finite().nonnegative() }) })
|
|
16301
17081
|
});
|
|
16302
17082
|
function reportedCostUsd(metadata) {
|
|
16303
17083
|
const parsed = perplexityCostSchema.safeParse(metadata);
|
|
@@ -16370,7 +17150,7 @@ function createTextSteps(initial, resolve, callerProviderOptions) {
|
|
|
16370
17150
|
|
|
16371
17151
|
// src/client.ts
|
|
16372
17152
|
var import_ai5 = require("ai");
|
|
16373
|
-
var
|
|
17153
|
+
var import_zod32 = require("zod");
|
|
16374
17154
|
|
|
16375
17155
|
// src/generated-image.ts
|
|
16376
17156
|
function toGeneratedImage(image) {
|
|
@@ -16719,10 +17499,10 @@ function textAbortOptions(sdk, context) {
|
|
|
16719
17499
|
if (abortSignal) return { abortSignal };
|
|
16720
17500
|
return {};
|
|
16721
17501
|
}
|
|
16722
|
-
var catalogId =
|
|
16723
|
-
var exactSize =
|
|
16724
|
-
var sdkRatio =
|
|
16725
|
-
var sizeTier =
|
|
17502
|
+
var catalogId = import_zod32.z.string();
|
|
17503
|
+
var exactSize = import_zod32.z.templateLiteral([import_zod32.z.number(), "x", import_zod32.z.number()]);
|
|
17504
|
+
var sdkRatio = import_zod32.z.templateLiteral([import_zod32.z.number(), ":", import_zod32.z.number()]);
|
|
17505
|
+
var sizeTier = import_zod32.z.enum(["512", "1K", "2K", "4K"]);
|
|
16726
17506
|
function isCatalogId(model) {
|
|
16727
17507
|
return catalogId.safeParse(model).success;
|
|
16728
17508
|
}
|
|
@@ -17467,6 +18247,7 @@ var describe = (modelId) => createDefaultModelKit().describe(modelId);
|
|
|
17467
18247
|
languageModel,
|
|
17468
18248
|
liveCatalog,
|
|
17469
18249
|
liveState,
|
|
18250
|
+
lumaAdapter,
|
|
17470
18251
|
mergeTextProviderOptions,
|
|
17471
18252
|
missingTierKeys,
|
|
17472
18253
|
model3dCall,
|