@shop-os/modelkit 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -21
- package/dist/index.cjs +408 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -3
- package/dist/index.d.ts +15 -3
- package/dist/index.js +408 -179
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -165,7 +165,18 @@ var Catalog = class _Catalog {
|
|
|
165
165
|
|
|
166
166
|
// src/catalog/image.ts
|
|
167
167
|
var IMAGE_USAGE = { unit: "images", modality: "IMAGE" };
|
|
168
|
-
var GEMINI_RATIOS = [
|
|
168
|
+
var GEMINI_RATIOS = [
|
|
169
|
+
"1:1",
|
|
170
|
+
"2:3",
|
|
171
|
+
"3:2",
|
|
172
|
+
"16:9",
|
|
173
|
+
"9:16",
|
|
174
|
+
"4:3",
|
|
175
|
+
"3:4",
|
|
176
|
+
"21:9",
|
|
177
|
+
"4:5",
|
|
178
|
+
"5:4"
|
|
179
|
+
];
|
|
169
180
|
function geminiImage(id, label, aliases, sizes) {
|
|
170
181
|
const model = {
|
|
171
182
|
id,
|
|
@@ -188,7 +199,8 @@ var IMAGE_MODELS = [
|
|
|
188
199
|
"gemini-3.1-flash-image-preview",
|
|
189
200
|
"Nano Banana Flash",
|
|
190
201
|
["nb-2"],
|
|
191
|
-
|
|
202
|
+
// Flash 3.1 is the only Gemini image model with the 512 tier.
|
|
203
|
+
["512", "1K", "2K", "4K"]
|
|
192
204
|
),
|
|
193
205
|
geminiImage("gemini-3.1-flash-lite-image", "Nano Banana Lite", ["nb-lite"], ["1K"]),
|
|
194
206
|
// trigger-workflows validates 1K only; pricing seeds 2K/4K rows so allow all three.
|
|
@@ -292,7 +304,10 @@ var IMAGE_MODELS = [
|
|
|
292
304
|
constraints: {
|
|
293
305
|
aspectRatios: ["1:1", "4:3", "3:4", "16:9", "9:16", "3:2", "2:3", "21:9", "4:5", "5:4"],
|
|
294
306
|
sizes: ["1K", "2K"],
|
|
295
|
-
references: { images: 10 }
|
|
307
|
+
references: { images: 10 },
|
|
308
|
+
// Ark's Images API has no output-format, quality or count field; only
|
|
309
|
+
// the seed is forwarded, so anything else must warn, not vanish.
|
|
310
|
+
supports: ["seed"]
|
|
296
311
|
},
|
|
297
312
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
298
313
|
usage: { ...IMAGE_USAGE },
|
|
@@ -307,21 +322,12 @@ var IMAGE_MODELS = [
|
|
|
307
322
|
providerModelId: "seedream-4-5-251128",
|
|
308
323
|
lifecycle: "active",
|
|
309
324
|
constraints: {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
"3:2",
|
|
314
|
-
"4:3",
|
|
315
|
-
"3:4",
|
|
316
|
-
"4:5",
|
|
317
|
-
"5:4",
|
|
318
|
-
"9:16",
|
|
319
|
-
"16:9",
|
|
320
|
-
"21:9",
|
|
321
|
-
"97:30"
|
|
322
|
-
],
|
|
325
|
+
// 97:30 has no Ark size spelling; the A+ flow pads inputs to 97:30 and
|
|
326
|
+
// omits the ratio instead. Advertise only sizes the adapter can send.
|
|
327
|
+
aspectRatios: ["1:1", "2:3", "3:2", "4:3", "3:4", "4:5", "5:4", "9:16", "16:9", "21:9"],
|
|
323
328
|
sizes: ["1K", "2K"],
|
|
324
|
-
references: { images: 10 }
|
|
329
|
+
references: { images: 10 },
|
|
330
|
+
supports: ["seed"]
|
|
325
331
|
},
|
|
326
332
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
327
333
|
usage: { ...IMAGE_USAGE },
|
|
@@ -345,6 +351,9 @@ var IMAGE_MODELS = [
|
|
|
345
351
|
pricingKind: "image_size"
|
|
346
352
|
},
|
|
347
353
|
{
|
|
354
|
+
// Prodia's gemini-3-pro jobs take aspect_ratio + resolution (1K/2K/4K), not
|
|
355
|
+
// width/height; 97:30 is outside its aspect_ratio enum.
|
|
356
|
+
// https://docs.prodia.com/models/gemini-3/
|
|
348
357
|
id: "prodia-nano-banana-pro",
|
|
349
358
|
aliases: [],
|
|
350
359
|
label: "Nano Banana Pro via Prodia",
|
|
@@ -353,19 +362,7 @@ var IMAGE_MODELS = [
|
|
|
353
362
|
providerModelId: "inference.gemini-3-pro.img2img.v1",
|
|
354
363
|
lifecycle: "active",
|
|
355
364
|
constraints: {
|
|
356
|
-
aspectRatios: [
|
|
357
|
-
"1:1",
|
|
358
|
-
"2:3",
|
|
359
|
-
"3:2",
|
|
360
|
-
"4:3",
|
|
361
|
-
"3:4",
|
|
362
|
-
"4:5",
|
|
363
|
-
"5:4",
|
|
364
|
-
"9:16",
|
|
365
|
-
"16:9",
|
|
366
|
-
"21:9",
|
|
367
|
-
"97:30"
|
|
368
|
-
],
|
|
365
|
+
aspectRatios: ["1:1", "2:3", "3:2", "4:3", "3:4", "4:5", "5:4", "9:16", "16:9", "21:9"],
|
|
369
366
|
sizes: ["1K", "2K", "4K"],
|
|
370
367
|
requires: ["references"]
|
|
371
368
|
},
|
|
@@ -374,6 +371,8 @@ var IMAGE_MODELS = [
|
|
|
374
371
|
pricingKind: "image_size"
|
|
375
372
|
},
|
|
376
373
|
{
|
|
374
|
+
// Nano Banana (img2img.v2) is flat-rate with aspect_ratio only; 3:2, 4:5,
|
|
375
|
+
// 5:4 and 97:30 are not in its enum. https://docs.prodia.com/models/nano-banana/
|
|
377
376
|
id: "prodia-nano-banana",
|
|
378
377
|
aliases: [],
|
|
379
378
|
label: "Nano Banana via Prodia",
|
|
@@ -382,19 +381,7 @@ var IMAGE_MODELS = [
|
|
|
382
381
|
providerModelId: "inference.nano-banana.img2img.v2",
|
|
383
382
|
lifecycle: "active",
|
|
384
383
|
constraints: {
|
|
385
|
-
aspectRatios: [
|
|
386
|
-
"1:1",
|
|
387
|
-
"2:3",
|
|
388
|
-
"3:2",
|
|
389
|
-
"4:3",
|
|
390
|
-
"3:4",
|
|
391
|
-
"4:5",
|
|
392
|
-
"5:4",
|
|
393
|
-
"9:16",
|
|
394
|
-
"16:9",
|
|
395
|
-
"21:9",
|
|
396
|
-
"97:30"
|
|
397
|
-
],
|
|
384
|
+
aspectRatios: ["1:1", "2:3", "3:4", "4:3", "9:16", "16:9", "21:9"],
|
|
398
385
|
sizes: ["1K"],
|
|
399
386
|
requires: ["references"]
|
|
400
387
|
},
|
|
@@ -403,6 +390,9 @@ var IMAGE_MODELS = [
|
|
|
403
390
|
pricingKind: "image_size"
|
|
404
391
|
},
|
|
405
392
|
{
|
|
393
|
+
// WAN 2.7 takes `images` (up to 9) and a `size` enum whose exact values
|
|
394
|
+
// cover 1:1/16:9/9:16/4:3/3:4 only; other ratios have no spelling.
|
|
395
|
+
// https://replicate.com/wan-video/wan-2.7-image-pro (input schema)
|
|
406
396
|
id: "wan-2.7-image-pro",
|
|
407
397
|
aliases: [],
|
|
408
398
|
label: "WAN 2.7 Image Pro",
|
|
@@ -411,19 +401,7 @@ var IMAGE_MODELS = [
|
|
|
411
401
|
providerModelId: "wan-video/wan-2.7-image-pro",
|
|
412
402
|
lifecycle: "active",
|
|
413
403
|
constraints: {
|
|
414
|
-
aspectRatios: [
|
|
415
|
-
"1:1",
|
|
416
|
-
"2:3",
|
|
417
|
-
"3:2",
|
|
418
|
-
"4:3",
|
|
419
|
-
"3:4",
|
|
420
|
-
"4:5",
|
|
421
|
-
"5:4",
|
|
422
|
-
"9:16",
|
|
423
|
-
"16:9",
|
|
424
|
-
"21:9",
|
|
425
|
-
"97:30"
|
|
426
|
-
],
|
|
404
|
+
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4"],
|
|
427
405
|
sizes: ["1K", "2K", "4K"],
|
|
428
406
|
references: { images: 9 }
|
|
429
407
|
},
|
|
@@ -432,6 +410,9 @@ var IMAGE_MODELS = [
|
|
|
432
410
|
pricingKind: "image_size"
|
|
433
411
|
},
|
|
434
412
|
{
|
|
413
|
+
// Qwen Image 2 Pro has aspect_ratio but no size input; resolution follows
|
|
414
|
+
// the reference image (match_input_image) or the provider default.
|
|
415
|
+
// https://replicate.com/qwen/qwen-image-2-pro (input schema)
|
|
435
416
|
id: "qwen-image-2-pro",
|
|
436
417
|
aliases: [],
|
|
437
418
|
label: "Qwen Image 2 Pro",
|
|
@@ -440,28 +421,19 @@ var IMAGE_MODELS = [
|
|
|
440
421
|
providerModelId: "qwen/qwen-image-2-pro",
|
|
441
422
|
lifecycle: "active",
|
|
442
423
|
constraints: {
|
|
443
|
-
aspectRatios: [
|
|
444
|
-
|
|
445
|
-
"2:3",
|
|
446
|
-
"3:2",
|
|
447
|
-
"4:3",
|
|
448
|
-
"3:4",
|
|
449
|
-
"4:5",
|
|
450
|
-
"5:4",
|
|
451
|
-
"9:16",
|
|
452
|
-
"16:9",
|
|
453
|
-
"21:9",
|
|
454
|
-
"97:30"
|
|
455
|
-
],
|
|
456
|
-
sizes: ["1K", "2K", "4K"],
|
|
424
|
+
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"],
|
|
425
|
+
sizes: [],
|
|
457
426
|
references: { images: 1 },
|
|
458
427
|
requires: ["references"]
|
|
459
428
|
},
|
|
460
|
-
defaults: {
|
|
429
|
+
defaults: { aspectRatio: "1:1" },
|
|
461
430
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
462
431
|
pricingKind: "image_size"
|
|
463
432
|
},
|
|
464
433
|
{
|
|
434
|
+
// Qwen Image Edit Plus takes aspect_ratio (or match_input_image) and
|
|
435
|
+
// output_format, but no size; no default ratio so edits keep following
|
|
436
|
+
// the input image. https://replicate.com/qwen-edit-apps/qwen-image-edit-plus-lora-skin
|
|
465
437
|
id: "qwen-image-edit-plus-lora-skin",
|
|
466
438
|
aliases: [],
|
|
467
439
|
label: "Qwen Image Edit Plus",
|
|
@@ -470,25 +442,13 @@ var IMAGE_MODELS = [
|
|
|
470
442
|
providerModelId: "qwen-edit-apps/qwen-image-edit-plus-lora-skin",
|
|
471
443
|
lifecycle: "active",
|
|
472
444
|
constraints: {
|
|
473
|
-
aspectRatios: [
|
|
474
|
-
|
|
475
|
-
"2:3",
|
|
476
|
-
"3:2",
|
|
477
|
-
"4:3",
|
|
478
|
-
"3:4",
|
|
479
|
-
"4:5",
|
|
480
|
-
"5:4",
|
|
481
|
-
"9:16",
|
|
482
|
-
"16:9",
|
|
483
|
-
"21:9",
|
|
484
|
-
"97:30"
|
|
485
|
-
],
|
|
486
|
-
sizes: ["1K", "2K", "4K"],
|
|
445
|
+
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4"],
|
|
446
|
+
sizes: [],
|
|
487
447
|
references: { images: 1 },
|
|
488
448
|
requires: ["references"],
|
|
489
449
|
supports: ["outputFormat"]
|
|
490
450
|
},
|
|
491
|
-
defaults: {
|
|
451
|
+
defaults: { outputFormat: "png" },
|
|
492
452
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
493
453
|
pricingKind: "image_size"
|
|
494
454
|
}
|
|
@@ -585,8 +545,12 @@ var OTHER_MODELS = [
|
|
|
585
545
|
adapter: "replicate",
|
|
586
546
|
providerModelId: "topazlabs/image-upscale",
|
|
587
547
|
lifecycle: "active",
|
|
588
|
-
constraints: {
|
|
589
|
-
|
|
548
|
+
constraints: {
|
|
549
|
+
references: { images: 1 },
|
|
550
|
+
requires: ["references"],
|
|
551
|
+
supports: ["scaleFactor", "outputFormat"]
|
|
552
|
+
},
|
|
553
|
+
defaults: { scaleFactor: 2, outputFormat: "png" },
|
|
590
554
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
591
555
|
pricingKind: "flat"
|
|
592
556
|
},
|
|
@@ -642,7 +606,7 @@ var TEXT_MODELS = [
|
|
|
642
606
|
text("gpt-5.6-sol", "GPT-5.6 Sol", "gpt-5.6-sol"),
|
|
643
607
|
// Library key "claude-sonnet-4.5" maps to the SDK id "claude-sonnet-4-5".
|
|
644
608
|
text("claude-sonnet-4-5", "Claude Sonnet 4.5", "claude-sonnet-4-5", {
|
|
645
|
-
aliases: ["claude-sonnet-4.5"]
|
|
609
|
+
aliases: ["claude-sonnet-4.5", "claude-sonnet-4-5-20250929"]
|
|
646
610
|
}),
|
|
647
611
|
// Anthropic retired the dated 4.0 ids; callers that still send them get 4.6.
|
|
648
612
|
text("claude-sonnet-4-6", "Claude Sonnet 4.6", "claude-sonnet-4-6", {
|
|
@@ -658,7 +622,7 @@ var TEXT_MODELS = [
|
|
|
658
622
|
aliases: ["claude-opus-4.8", "claude-opus-4", "claude-opus-4.0", "claude-opus-4-20250514"]
|
|
659
623
|
}),
|
|
660
624
|
text("claude-haiku-4-5", "Claude Haiku 4.5", "claude-haiku-4-5", {
|
|
661
|
-
aliases: ["claude-haiku-4.5", "claude-haiku-4-5-20251001"]
|
|
625
|
+
aliases: ["claude-haiku-4.5", "claude-haiku-4-5-20251001", "claude-haiku-4"]
|
|
662
626
|
}),
|
|
663
627
|
text("claude-opus-5", "Claude Opus 5", "claude-opus-5", {
|
|
664
628
|
aliases: ["claude-opus-5.0"]
|
|
@@ -1141,7 +1105,7 @@ var MODELS = [
|
|
|
1141
1105
|
];
|
|
1142
1106
|
|
|
1143
1107
|
// src/resolve-options.ts
|
|
1144
|
-
var SIZE_ORDER = ["1K", "2K", "4K"];
|
|
1108
|
+
var SIZE_ORDER = ["512", "1K", "2K", "4K"];
|
|
1145
1109
|
var RESOLUTION_ORDER = ["360p", "480p", "720p", "768p", "1080p", "2k", "4k"];
|
|
1146
1110
|
function ratioValue(r) {
|
|
1147
1111
|
if (r === "adaptive") return 1;
|
|
@@ -1273,7 +1237,13 @@ function resolveImageOptions(model, request, onUnsupported = "error") {
|
|
|
1273
1237
|
model: model.id
|
|
1274
1238
|
});
|
|
1275
1239
|
}
|
|
1276
|
-
dropUnsupported(merged, model, warnings, [
|
|
1240
|
+
dropUnsupported(merged, model, warnings, [
|
|
1241
|
+
"seed",
|
|
1242
|
+
"quality",
|
|
1243
|
+
"count",
|
|
1244
|
+
"outputFormat",
|
|
1245
|
+
"scaleFactor"
|
|
1246
|
+
]);
|
|
1277
1247
|
return { request: merged, warnings };
|
|
1278
1248
|
}
|
|
1279
1249
|
function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
@@ -1898,7 +1868,11 @@ var aiSdkTextAdapter = {
|
|
|
1898
1868
|
function requiredKeys(model, config) {
|
|
1899
1869
|
if (model.adapter === "fal" && config.routing?.fal === "cloudflare-passthrough")
|
|
1900
1870
|
return ["cloudflare"];
|
|
1901
|
-
if (model.adapter === "ai-sdk-text")
|
|
1871
|
+
if (model.adapter === "ai-sdk-text") {
|
|
1872
|
+
const names = [textKeyName(model, config.routing ?? {})];
|
|
1873
|
+
if (config.routing?.text === "cloudflare") names.push("cloudflare");
|
|
1874
|
+
return names;
|
|
1875
|
+
}
|
|
1902
1876
|
return ADAPTER_KEYS[model.adapter];
|
|
1903
1877
|
}
|
|
1904
1878
|
var IMAGE_OUTPUT_TYPES = /* @__PURE__ */ new Set(["image", "upscale", "bg-remove"]);
|
|
@@ -1956,6 +1930,20 @@ function sdkAspectRatio(ratio) {
|
|
|
1956
1930
|
const parsed = sdkRatio.safeParse(ratio);
|
|
1957
1931
|
return parsed.success ? parsed.data : void 0;
|
|
1958
1932
|
}
|
|
1933
|
+
function sdkDataContent(ref) {
|
|
1934
|
+
return "url" in ref ? ref.url : ref.bytes;
|
|
1935
|
+
}
|
|
1936
|
+
function sdkReference(ref) {
|
|
1937
|
+
return "url" in ref ? ref.url : { data: ref.bytes, mediaType: ref.mime };
|
|
1938
|
+
}
|
|
1939
|
+
function pushIgnored(warnings, field, from, modelId) {
|
|
1940
|
+
warnings.push({
|
|
1941
|
+
code: "option_ignored",
|
|
1942
|
+
field,
|
|
1943
|
+
from,
|
|
1944
|
+
message: `${modelId} provider instance does not support ${field}; ignored`
|
|
1945
|
+
});
|
|
1946
|
+
}
|
|
1959
1947
|
function createModelKit(config, adapters) {
|
|
1960
1948
|
const catalog = new Catalog(MODELS).withOverrides(config.catalogOverride ?? []);
|
|
1961
1949
|
const logger = config.logger ?? console;
|
|
@@ -1978,6 +1966,7 @@ function createModelKit(config, adapters) {
|
|
|
1978
1966
|
call,
|
|
1979
1967
|
warnings
|
|
1980
1968
|
};
|
|
1969
|
+
if (config.endpoints) ctx.endpoints = config.endpoints;
|
|
1981
1970
|
if (call.signal) ctx.signal = call.signal;
|
|
1982
1971
|
return { adapter, ctx };
|
|
1983
1972
|
}
|
|
@@ -2017,16 +2006,45 @@ function createModelKit(config, adapters) {
|
|
|
2017
2006
|
};
|
|
2018
2007
|
}
|
|
2019
2008
|
async function passthroughImage(req, call) {
|
|
2020
|
-
const {
|
|
2009
|
+
const {
|
|
2010
|
+
model,
|
|
2011
|
+
prompt,
|
|
2012
|
+
n,
|
|
2013
|
+
count,
|
|
2014
|
+
size,
|
|
2015
|
+
aspectRatio,
|
|
2016
|
+
seed,
|
|
2017
|
+
providerOptions,
|
|
2018
|
+
references,
|
|
2019
|
+
exactSize: exactSizeField,
|
|
2020
|
+
scaleFactor,
|
|
2021
|
+
quality: _quality,
|
|
2022
|
+
outputFormat: _outputFormat
|
|
2023
|
+
} = req;
|
|
2021
2024
|
const options = { model, prompt };
|
|
2025
|
+
const warnings = [];
|
|
2022
2026
|
const quantity = n ?? count;
|
|
2023
2027
|
if (quantity !== void 0) options.n = quantity;
|
|
2024
|
-
|
|
2025
|
-
|
|
2028
|
+
if (references !== void 0 && references.length > 0)
|
|
2029
|
+
options.prompt = { images: references.map(sdkDataContent), text: prompt };
|
|
2030
|
+
const exact = exactSizeField === void 0 ? void 0 : exactSize.safeParse(exactSizeField);
|
|
2031
|
+
if (exact?.success) options.size = exact.data;
|
|
2032
|
+
else if (exactSizeField !== void 0)
|
|
2033
|
+
pushIgnored(warnings, "exactSize", exactSizeField, model.modelId);
|
|
2034
|
+
const requested = size === void 0 ? void 0 : exactSize.safeParse(size);
|
|
2035
|
+
if (requested?.success) options.size ??= requested.data;
|
|
2036
|
+
else if (size !== void 0) pushIgnored(warnings, "size", size, model.modelId);
|
|
2026
2037
|
const ratio = sdkAspectRatio(aspectRatio);
|
|
2027
2038
|
if (ratio) options.aspectRatio = ratio;
|
|
2039
|
+
else if (aspectRatio !== void 0)
|
|
2040
|
+
pushIgnored(warnings, "aspectRatio", aspectRatio, model.modelId);
|
|
2028
2041
|
if (seed !== void 0) options.seed = seed;
|
|
2029
2042
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
2043
|
+
if (_quality !== void 0) pushIgnored(warnings, "quality", _quality, model.modelId);
|
|
2044
|
+
if (_outputFormat !== void 0)
|
|
2045
|
+
pushIgnored(warnings, "outputFormat", _outputFormat, model.modelId);
|
|
2046
|
+
if (scaleFactor !== void 0)
|
|
2047
|
+
pushIgnored(warnings, "scaleFactor", scaleFactor, model.modelId);
|
|
2030
2048
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
2031
2049
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
2032
2050
|
const result = await (0, import_ai2.generateImage)(options);
|
|
@@ -2041,17 +2059,73 @@ function createModelKit(config, adapters) {
|
|
|
2041
2059
|
quantity: images.length
|
|
2042
2060
|
};
|
|
2043
2061
|
await emit(usage2);
|
|
2044
|
-
return { image: images[0], images, usage: usage2, raw: result, warnings
|
|
2062
|
+
return { image: images[0], images, usage: usage2, raw: result, warnings };
|
|
2045
2063
|
}
|
|
2046
2064
|
function passthroughVideo(req, call) {
|
|
2047
|
-
const {
|
|
2065
|
+
const {
|
|
2066
|
+
model,
|
|
2067
|
+
prompt,
|
|
2068
|
+
aspectRatio,
|
|
2069
|
+
duration,
|
|
2070
|
+
durationSeconds,
|
|
2071
|
+
seed,
|
|
2072
|
+
providerOptions,
|
|
2073
|
+
firstFrame,
|
|
2074
|
+
lastFrame,
|
|
2075
|
+
sourceVideo,
|
|
2076
|
+
referenceImages,
|
|
2077
|
+
referenceVideos,
|
|
2078
|
+
referenceAudios,
|
|
2079
|
+
resolution,
|
|
2080
|
+
generateAudio: generateAudio2,
|
|
2081
|
+
negativePrompt: _negativePrompt,
|
|
2082
|
+
cfgScale: _cfgScale,
|
|
2083
|
+
promptExpansion: _promptExpansion,
|
|
2084
|
+
mode: _mode
|
|
2085
|
+
} = req;
|
|
2048
2086
|
const seconds = duration ?? durationSeconds;
|
|
2049
2087
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
2050
2088
|
const options = { model, prompt };
|
|
2051
|
-
const
|
|
2089
|
+
const warnings = [];
|
|
2090
|
+
const ratio = sdkAspectRatio(aspectRatio) ?? (aspectRatio === "adaptive" ? "adaptive" : void 0);
|
|
2052
2091
|
if (ratio) options.aspectRatio = ratio;
|
|
2092
|
+
else if (aspectRatio !== void 0)
|
|
2093
|
+
pushIgnored(warnings, "aspectRatio", aspectRatio, model.modelId);
|
|
2053
2094
|
if (seconds !== void 0) options.duration = seconds;
|
|
2054
2095
|
if (seed !== void 0) options.seed = seed;
|
|
2096
|
+
if (generateAudio2 !== void 0) options.generateAudio = generateAudio2;
|
|
2097
|
+
const frames = [
|
|
2098
|
+
...firstFrame ? [{ image: sdkDataContent(firstFrame), frameType: "first_frame" }] : [],
|
|
2099
|
+
...lastFrame ? [{ image: sdkDataContent(lastFrame), frameType: "last_frame" }] : []
|
|
2100
|
+
];
|
|
2101
|
+
if (frames.length > 0) options.frameImages = frames;
|
|
2102
|
+
const references = [
|
|
2103
|
+
...(referenceImages ?? []).map(sdkDataContent),
|
|
2104
|
+
...(referenceVideos ?? []).map(sdkReference)
|
|
2105
|
+
];
|
|
2106
|
+
if (references.length > 0) {
|
|
2107
|
+
if (frames.length > 0) {
|
|
2108
|
+
warnings.push({
|
|
2109
|
+
code: "option_ignored",
|
|
2110
|
+
field: "inputReferences",
|
|
2111
|
+
from: references.length,
|
|
2112
|
+
message: `${model.modelId} provider instance ignores references when frames are set`
|
|
2113
|
+
});
|
|
2114
|
+
} else {
|
|
2115
|
+
options.inputReferences = references;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
if (sourceVideo) pushIgnored(warnings, "sourceVideo", void 0, model.modelId);
|
|
2119
|
+
if (referenceAudios?.length)
|
|
2120
|
+
pushIgnored(warnings, "referenceAudios", referenceAudios.length, model.modelId);
|
|
2121
|
+
if (resolution !== void 0)
|
|
2122
|
+
pushIgnored(warnings, "resolution", resolution, model.modelId);
|
|
2123
|
+
if (_negativePrompt !== void 0)
|
|
2124
|
+
pushIgnored(warnings, "negativePrompt", void 0, model.modelId);
|
|
2125
|
+
if (_cfgScale !== void 0) pushIgnored(warnings, "cfgScale", _cfgScale, model.modelId);
|
|
2126
|
+
if (_promptExpansion !== void 0)
|
|
2127
|
+
pushIgnored(warnings, "promptExpansion", _promptExpansion, model.modelId);
|
|
2128
|
+
if (_mode !== void 0) pushIgnored(warnings, "mode", _mode, model.modelId);
|
|
2055
2129
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
2056
2130
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
2057
2131
|
const pending = (0, import_ai2.experimental_generateVideo)(options);
|
|
@@ -2079,7 +2153,7 @@ function createModelKit(config, adapters) {
|
|
|
2079
2153
|
});
|
|
2080
2154
|
return {
|
|
2081
2155
|
jobId: `ai-sdk:${model.provider}:${model.modelId}`,
|
|
2082
|
-
warnings
|
|
2156
|
+
warnings,
|
|
2083
2157
|
async poll() {
|
|
2084
2158
|
if (settled) return { status: "succeeded", raw: settled.raw };
|
|
2085
2159
|
if (failed) return { status: "failed" };
|
|
@@ -2303,6 +2377,9 @@ var SUBMIT_PATH = "/contents/generations/tasks";
|
|
|
2303
2377
|
var SEEDANCE_POLL_INTERVAL_MS = 15e3;
|
|
2304
2378
|
var RESULT_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
2305
2379
|
var VIDEO_URL_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
2380
|
+
function arkBaseUrl(ctx) {
|
|
2381
|
+
return ctx.endpoints?.ark ?? ARK_BASE_URL;
|
|
2382
|
+
}
|
|
2306
2383
|
var SEEDREAM_SIZES = {
|
|
2307
2384
|
"1K": {
|
|
2308
2385
|
"1:1": "1024x1024",
|
|
@@ -2313,7 +2390,8 @@ var SEEDREAM_SIZES = {
|
|
|
2313
2390
|
"3:2": "1248x832",
|
|
2314
2391
|
"2:3": "832x1248",
|
|
2315
2392
|
"21:9": "1568x672",
|
|
2316
|
-
"4:5": "864x1080"
|
|
2393
|
+
"4:5": "864x1080",
|
|
2394
|
+
"5:4": "1080x864"
|
|
2317
2395
|
},
|
|
2318
2396
|
"2K": {
|
|
2319
2397
|
"1:1": "2048x2048",
|
|
@@ -2324,7 +2402,8 @@ var SEEDREAM_SIZES = {
|
|
|
2324
2402
|
"3:2": "2496x1664",
|
|
2325
2403
|
"2:3": "1664x2496",
|
|
2326
2404
|
"21:9": "3136x1344",
|
|
2327
|
-
"4:5": "1728x2160"
|
|
2405
|
+
"4:5": "1728x2160",
|
|
2406
|
+
"5:4": "2160x1728"
|
|
2328
2407
|
}
|
|
2329
2408
|
};
|
|
2330
2409
|
var arkAdapter = {
|
|
@@ -2371,9 +2450,11 @@ function seedreamSize(aspect, size) {
|
|
|
2371
2450
|
const table = SEEDREAM_SIZES[tier];
|
|
2372
2451
|
return table[aspect ?? ""] ?? table["1:1"] ?? "2048x2048";
|
|
2373
2452
|
}
|
|
2374
|
-
function
|
|
2375
|
-
if (
|
|
2376
|
-
|
|
2453
|
+
function sniffedImageMime(bytes) {
|
|
2454
|
+
if (bytes.length >= 4 && bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71)
|
|
2455
|
+
return "image/png";
|
|
2456
|
+
if (bytes.length >= 12 && bytes[0] === 82 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 70 && bytes[8] === 87 && bytes[9] === 69 && bytes[10] === 66 && bytes[11] === 80)
|
|
2457
|
+
return "image/webp";
|
|
2377
2458
|
return "image/jpeg";
|
|
2378
2459
|
}
|
|
2379
2460
|
function arkUrl(ref) {
|
|
@@ -2415,7 +2496,7 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2415
2496
|
else if (refs.length > 1) body.image = refs;
|
|
2416
2497
|
const data = await withRetry(async () => {
|
|
2417
2498
|
const res = await ctx.fetch(
|
|
2418
|
-
`${
|
|
2499
|
+
`${arkBaseUrl(ctx)}/images/generations`,
|
|
2419
2500
|
fetchInitFor(ctx, {
|
|
2420
2501
|
method: "POST",
|
|
2421
2502
|
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
@@ -2454,7 +2535,7 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2454
2535
|
};
|
|
2455
2536
|
if (req.size !== void 0) usage2.imageSize = req.size;
|
|
2456
2537
|
if (req.quality !== void 0) usage2.imageQuality = req.quality;
|
|
2457
|
-
return { images: [{ bytes, mime:
|
|
2538
|
+
return { images: [{ bytes, mime: sniffedImageMime(bytes) }], usage: usage2, raw: data };
|
|
2458
2539
|
}
|
|
2459
2540
|
var SeedanceResponseSchema = import_zod4.z.object({
|
|
2460
2541
|
id: import_zod4.z.string().optional(),
|
|
@@ -2542,7 +2623,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2542
2623
|
if (req.seed !== void 0) body.seed = req.seed;
|
|
2543
2624
|
const submit = await withRetry(async () => {
|
|
2544
2625
|
const res = await ctx.fetch(
|
|
2545
|
-
`${
|
|
2626
|
+
`${arkBaseUrl(ctx)}${SUBMIT_PATH}`,
|
|
2546
2627
|
fetchInitFor(ctx, {
|
|
2547
2628
|
method: "POST",
|
|
2548
2629
|
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
@@ -2562,7 +2643,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2562
2643
|
const usage2 = seedanceUsage(ctx, req, duration);
|
|
2563
2644
|
const fetchStatus = async () => {
|
|
2564
2645
|
const res = await ctx.fetch(
|
|
2565
|
-
`${
|
|
2646
|
+
`${arkBaseUrl(ctx)}${SUBMIT_PATH}/${jobId}`,
|
|
2566
2647
|
fetchInitFor(ctx, {
|
|
2567
2648
|
headers: { Authorization: `Bearer ${key}` }
|
|
2568
2649
|
})
|
|
@@ -3621,60 +3702,6 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3621
3702
|
uploadedNames.push(file.fileName);
|
|
3622
3703
|
return file.fileUri;
|
|
3623
3704
|
};
|
|
3624
|
-
const parts = [];
|
|
3625
|
-
if (req.sourceVideo) {
|
|
3626
|
-
const media = await resolveMedia(
|
|
3627
|
-
req.sourceVideo,
|
|
3628
|
-
ctx.fetch,
|
|
3629
|
-
ctx.signal,
|
|
3630
|
-
"video/mp4",
|
|
3631
|
-
modelId
|
|
3632
|
-
);
|
|
3633
|
-
parts.push({
|
|
3634
|
-
type: "video",
|
|
3635
|
-
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3636
|
-
mime_type: media.mime
|
|
3637
|
-
});
|
|
3638
|
-
}
|
|
3639
|
-
for (const ref of videos) {
|
|
3640
|
-
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "video/mp4", modelId);
|
|
3641
|
-
parts.push({
|
|
3642
|
-
type: "video",
|
|
3643
|
-
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3644
|
-
mime_type: media.mime
|
|
3645
|
-
});
|
|
3646
|
-
}
|
|
3647
|
-
if (req.firstFrame) {
|
|
3648
|
-
const media = await resolveMedia(
|
|
3649
|
-
req.firstFrame,
|
|
3650
|
-
ctx.fetch,
|
|
3651
|
-
ctx.signal,
|
|
3652
|
-
"image/png",
|
|
3653
|
-
modelId
|
|
3654
|
-
);
|
|
3655
|
-
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3656
|
-
parts.push({
|
|
3657
|
-
type: "image",
|
|
3658
|
-
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3659
|
-
mime_type: media.mime
|
|
3660
|
-
});
|
|
3661
|
-
} else {
|
|
3662
|
-
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3663
|
-
}
|
|
3664
|
-
}
|
|
3665
|
-
for (const ref of images) {
|
|
3666
|
-
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "image/png", modelId);
|
|
3667
|
-
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3668
|
-
parts.push({
|
|
3669
|
-
type: "image",
|
|
3670
|
-
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3671
|
-
mime_type: media.mime
|
|
3672
|
-
});
|
|
3673
|
-
} else {
|
|
3674
|
-
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3675
|
-
}
|
|
3676
|
-
}
|
|
3677
|
-
parts.push({ type: "text", text: req.prompt });
|
|
3678
3705
|
const cleanupUploads = async () => {
|
|
3679
3706
|
for (const fileName of uploadedNames) await deleteGoogleFile(fileName, apiKey, ctx.fetch);
|
|
3680
3707
|
};
|
|
@@ -3688,6 +3715,60 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3688
3715
|
if (ctx.signal !== void 0) createRetryOptions.signal = ctx.signal;
|
|
3689
3716
|
let interaction;
|
|
3690
3717
|
try {
|
|
3718
|
+
const parts = [];
|
|
3719
|
+
if (req.sourceVideo) {
|
|
3720
|
+
const media = await resolveMedia(
|
|
3721
|
+
req.sourceVideo,
|
|
3722
|
+
ctx.fetch,
|
|
3723
|
+
ctx.signal,
|
|
3724
|
+
"video/mp4",
|
|
3725
|
+
modelId
|
|
3726
|
+
);
|
|
3727
|
+
parts.push({
|
|
3728
|
+
type: "video",
|
|
3729
|
+
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3730
|
+
mime_type: media.mime
|
|
3731
|
+
});
|
|
3732
|
+
}
|
|
3733
|
+
for (const ref of videos) {
|
|
3734
|
+
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "video/mp4", modelId);
|
|
3735
|
+
parts.push({
|
|
3736
|
+
type: "video",
|
|
3737
|
+
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3738
|
+
mime_type: media.mime
|
|
3739
|
+
});
|
|
3740
|
+
}
|
|
3741
|
+
if (req.firstFrame) {
|
|
3742
|
+
const media = await resolveMedia(
|
|
3743
|
+
req.firstFrame,
|
|
3744
|
+
ctx.fetch,
|
|
3745
|
+
ctx.signal,
|
|
3746
|
+
"image/png",
|
|
3747
|
+
modelId
|
|
3748
|
+
);
|
|
3749
|
+
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3750
|
+
parts.push({
|
|
3751
|
+
type: "image",
|
|
3752
|
+
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3753
|
+
mime_type: media.mime
|
|
3754
|
+
});
|
|
3755
|
+
} else {
|
|
3756
|
+
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3757
|
+
}
|
|
3758
|
+
}
|
|
3759
|
+
for (const ref of images) {
|
|
3760
|
+
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "image/png", modelId);
|
|
3761
|
+
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3762
|
+
parts.push({
|
|
3763
|
+
type: "image",
|
|
3764
|
+
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3765
|
+
mime_type: media.mime
|
|
3766
|
+
});
|
|
3767
|
+
} else {
|
|
3768
|
+
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3771
|
+
parts.push({ type: "text", text: req.prompt });
|
|
3691
3772
|
try {
|
|
3692
3773
|
interaction = await withRetry(async () => {
|
|
3693
3774
|
try {
|
|
@@ -4021,6 +4102,10 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
4021
4102
|
imageQuality: "auto"
|
|
4022
4103
|
};
|
|
4023
4104
|
if (req.size !== void 0) usage2.imageSize = req.size;
|
|
4105
|
+
if (result.usage?.inputTokens !== void 0)
|
|
4106
|
+
usage2.inputTokens = result.usage.inputTokens;
|
|
4107
|
+
if (result.usage?.outputTokens !== void 0)
|
|
4108
|
+
usage2.outputTokens = result.usage.outputTokens;
|
|
4024
4109
|
return { images, usage: usage2, raw: result };
|
|
4025
4110
|
}
|
|
4026
4111
|
};
|
|
@@ -4552,7 +4637,7 @@ function aspectRatioToSize(ratio, tier) {
|
|
|
4552
4637
|
};
|
|
4553
4638
|
const MIN_PIXELS = 655360;
|
|
4554
4639
|
const MAX_PIXELS = 8294400;
|
|
4555
|
-
const maxLong = TIER_LONG_EDGE[tier];
|
|
4640
|
+
const maxLong = TIER_LONG_EDGE[tier] ?? 1024;
|
|
4556
4641
|
const RATIO_MAP = /* @__PURE__ */ new Map([
|
|
4557
4642
|
["1:1", [1, 1]],
|
|
4558
4643
|
["16:9", [16, 9]],
|
|
@@ -4753,7 +4838,8 @@ var RATIO_TO_DIMS = {
|
|
|
4753
4838
|
"9:16": { width: 768, height: 1360 },
|
|
4754
4839
|
"3:4": { width: 768, height: 1024 },
|
|
4755
4840
|
"2:3": { width: 768, height: 1152 },
|
|
4756
|
-
"4:5": { width: 896, height: 1120 }
|
|
4841
|
+
"4:5": { width: 896, height: 1120 },
|
|
4842
|
+
"5:4": { width: 1120, height: 896 }
|
|
4757
4843
|
};
|
|
4758
4844
|
function dimsFor(aspectRatio) {
|
|
4759
4845
|
if (aspectRatio !== void 0) {
|
|
@@ -4762,6 +4848,27 @@ function dimsFor(aspectRatio) {
|
|
|
4762
4848
|
}
|
|
4763
4849
|
return { width: 1024, height: 1024 };
|
|
4764
4850
|
}
|
|
4851
|
+
var GEMINI_JOB_RATIOS = /* @__PURE__ */ new Set([
|
|
4852
|
+
"1:1",
|
|
4853
|
+
"2:3",
|
|
4854
|
+
"3:2",
|
|
4855
|
+
"3:4",
|
|
4856
|
+
"4:3",
|
|
4857
|
+
"4:5",
|
|
4858
|
+
"5:4",
|
|
4859
|
+
"9:16",
|
|
4860
|
+
"16:9",
|
|
4861
|
+
"21:9"
|
|
4862
|
+
]);
|
|
4863
|
+
var NANO_BANANA_RATIOS = /* @__PURE__ */ new Set([
|
|
4864
|
+
"1:1",
|
|
4865
|
+
"2:3",
|
|
4866
|
+
"3:4",
|
|
4867
|
+
"4:3",
|
|
4868
|
+
"9:16",
|
|
4869
|
+
"16:9",
|
|
4870
|
+
"21:9"
|
|
4871
|
+
]);
|
|
4765
4872
|
async function refToBytes(ctx, ref) {
|
|
4766
4873
|
if ("bytes" in ref) return { bytes: ref.bytes, mime: ref.mime };
|
|
4767
4874
|
const res = await ctx.fetch(ref.url);
|
|
@@ -4861,7 +4968,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4861
4968
|
inputs = refs.length > 0 && firstRef !== void 0 ? [firstRef] : [];
|
|
4862
4969
|
accept = req.outputFormat === "png" ? "image/png" : "image/jpeg";
|
|
4863
4970
|
mime = accept;
|
|
4864
|
-
} else if (providerModelId === "flux-2-pro" || providerModelId === FLUX_2_PRO_JOB
|
|
4971
|
+
} else if (providerModelId === "flux-2-pro" || providerModelId === FLUX_2_PRO_JOB) {
|
|
4865
4972
|
const dims = dimsFor(req.aspectRatio);
|
|
4866
4973
|
const config = {
|
|
4867
4974
|
prompt: req.prompt,
|
|
@@ -4870,8 +4977,30 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4870
4977
|
safety_tolerance: 5
|
|
4871
4978
|
};
|
|
4872
4979
|
if (req.seed !== void 0) config.seed = req.seed;
|
|
4873
|
-
|
|
4874
|
-
|
|
4980
|
+
job = { type: FLUX_2_PRO_JOB, config };
|
|
4981
|
+
inputs = refs;
|
|
4982
|
+
accept = "image/png";
|
|
4983
|
+
mime = "image/png";
|
|
4984
|
+
} else if (providerModelId === "inference.gemini-3-pro.img2img.v1" || providerModelId === "inference.nano-banana.img2img.v2") {
|
|
4985
|
+
const allowed = providerModelId === "inference.nano-banana.img2img.v2" ? NANO_BANANA_RATIOS : GEMINI_JOB_RATIOS;
|
|
4986
|
+
const config = {
|
|
4987
|
+
prompt: req.prompt,
|
|
4988
|
+
safety_tolerance: 5
|
|
4989
|
+
};
|
|
4990
|
+
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
4991
|
+
if (allowed.has(req.aspectRatio)) config.aspect_ratio = req.aspectRatio;
|
|
4992
|
+
else
|
|
4993
|
+
ctx.warnings.push({
|
|
4994
|
+
code: "option_ignored",
|
|
4995
|
+
field: "aspectRatio",
|
|
4996
|
+
from: req.aspectRatio,
|
|
4997
|
+
message: `${providerModelId} has no ${req.aspectRatio} aspect_ratio; using the provider default`
|
|
4998
|
+
});
|
|
4999
|
+
}
|
|
5000
|
+
if (providerModelId === "inference.gemini-3-pro.img2img.v1")
|
|
5001
|
+
config.resolution = req.size ?? "1K";
|
|
5002
|
+
if (req.seed !== void 0) config.seed = req.seed;
|
|
5003
|
+
job = { type: providerModelId, config };
|
|
4875
5004
|
inputs = refs;
|
|
4876
5005
|
accept = "image/png";
|
|
4877
5006
|
mime = "image/png";
|
|
@@ -5142,13 +5271,88 @@ function isUpscaler(providerModelId) {
|
|
|
5142
5271
|
const id = isLower(providerModelId);
|
|
5143
5272
|
return id.includes("upscal") || id.includes("crystal") || id.includes("topaz");
|
|
5144
5273
|
}
|
|
5274
|
+
function isTopazUpscaler(providerModelId) {
|
|
5275
|
+
return isLower(providerModelId).includes("topazlabs/image-upscale");
|
|
5276
|
+
}
|
|
5145
5277
|
function isQwen(providerModelId) {
|
|
5146
5278
|
return isLower(providerModelId).includes("qwen");
|
|
5147
5279
|
}
|
|
5280
|
+
function isWanImage(providerModelId) {
|
|
5281
|
+
return isLower(providerModelId).includes("wan-2.7");
|
|
5282
|
+
}
|
|
5283
|
+
function isQwenEditPlus(providerModelId) {
|
|
5284
|
+
return isLower(providerModelId).includes("edit");
|
|
5285
|
+
}
|
|
5286
|
+
var QWEN_IMAGE_RATIOS = /* @__PURE__ */ new Set([
|
|
5287
|
+
"1:1",
|
|
5288
|
+
"16:9",
|
|
5289
|
+
"9:16",
|
|
5290
|
+
"4:3",
|
|
5291
|
+
"3:4",
|
|
5292
|
+
"3:2",
|
|
5293
|
+
"2:3"
|
|
5294
|
+
]);
|
|
5295
|
+
var QWEN_EDIT_RATIOS = /* @__PURE__ */ new Set(["1:1", "16:9", "9:16", "4:3", "3:4"]);
|
|
5296
|
+
var WAN_IMAGE_SIZES = {
|
|
5297
|
+
"1K": {
|
|
5298
|
+
"1:1": "1024*1024",
|
|
5299
|
+
"16:9": "1280*720",
|
|
5300
|
+
"9:16": "720*1280",
|
|
5301
|
+
"4:3": "1024*768",
|
|
5302
|
+
"3:4": "768*1024"
|
|
5303
|
+
},
|
|
5304
|
+
"2K": {
|
|
5305
|
+
"1:1": "2048*2048",
|
|
5306
|
+
"16:9": "2048*1152",
|
|
5307
|
+
"9:16": "1152*2048",
|
|
5308
|
+
"4:3": "2048*1536",
|
|
5309
|
+
"3:4": "1536*2048"
|
|
5310
|
+
},
|
|
5311
|
+
"4K": {
|
|
5312
|
+
"1:1": "4096*4096",
|
|
5313
|
+
"16:9": "4096*2304",
|
|
5314
|
+
"9:16": "2304*4096",
|
|
5315
|
+
"4:3": "4096*3072",
|
|
5316
|
+
"3:4": "3072*4096"
|
|
5317
|
+
}
|
|
5318
|
+
};
|
|
5319
|
+
function wanImageSize(aspectRatio, size) {
|
|
5320
|
+
const tier = size === "2K" || size === "4K" ? size : "1K";
|
|
5321
|
+
const table = WAN_IMAGE_SIZES[tier];
|
|
5322
|
+
return table[aspectRatio ?? ""] ?? table["1:1"] ?? "1024*1024";
|
|
5323
|
+
}
|
|
5148
5324
|
async function generateReplicateImage(req, ctx, deps) {
|
|
5149
5325
|
const id = ctx.model.providerModelId;
|
|
5150
|
-
|
|
5151
|
-
if (
|
|
5326
|
+
let input;
|
|
5327
|
+
if (isTopazUpscaler(id)) {
|
|
5328
|
+
const first = (req.references ?? [])[0];
|
|
5329
|
+
if (!first) {
|
|
5330
|
+
throw new ModelKitError({
|
|
5331
|
+
code: "missing_input",
|
|
5332
|
+
message: `${ctx.model.id} requires a reference image to upscale`,
|
|
5333
|
+
provider: "replicate",
|
|
5334
|
+
model: ctx.model.id,
|
|
5335
|
+
retryable: false
|
|
5336
|
+
});
|
|
5337
|
+
}
|
|
5338
|
+
let format = req.outputFormat === "jpeg" ? "jpg" : req.outputFormat ?? "png";
|
|
5339
|
+
if (format !== "png" && format !== "jpg") {
|
|
5340
|
+
ctx.warnings.push({
|
|
5341
|
+
code: "option_ignored",
|
|
5342
|
+
field: "outputFormat",
|
|
5343
|
+
from: format,
|
|
5344
|
+
message: "topazlabs/image-upscale supports only png and jpg; using png"
|
|
5345
|
+
});
|
|
5346
|
+
format = "png";
|
|
5347
|
+
}
|
|
5348
|
+
input = {
|
|
5349
|
+
image: refToUrl3(first),
|
|
5350
|
+
enhance_model: "Standard V2",
|
|
5351
|
+
output_format: format,
|
|
5352
|
+
upscale_factor: `${req.scaleFactor ?? 2}x`,
|
|
5353
|
+
face_enhancement: true
|
|
5354
|
+
};
|
|
5355
|
+
} else if (isUpscaler(id)) {
|
|
5152
5356
|
const refs = req.references ?? [];
|
|
5153
5357
|
const first = refs[0];
|
|
5154
5358
|
if (!first) {
|
|
@@ -5160,28 +5364,53 @@ async function generateReplicateImage(req, ctx, deps) {
|
|
|
5160
5364
|
retryable: false
|
|
5161
5365
|
});
|
|
5162
5366
|
}
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5367
|
+
const imageInput = { prompt: req.prompt };
|
|
5368
|
+
imageInput.image = refToUrl3(first);
|
|
5369
|
+
imageInput.creativity = 0;
|
|
5370
|
+
imageInput.scale_factor = 2;
|
|
5371
|
+
imageInput.output_format = "png";
|
|
5372
|
+
input = imageInput;
|
|
5373
|
+
} else if (isWanImage(id)) {
|
|
5374
|
+
const refs = (req.references ?? []).map(refToUrl3);
|
|
5375
|
+
const imageInput = { prompt: req.prompt };
|
|
5376
|
+
if (refs.length > 0) imageInput.images = refs;
|
|
5377
|
+
imageInput.size = wanImageSize(req.aspectRatio, req.size);
|
|
5378
|
+
input = imageInput;
|
|
5167
5379
|
} else if (isQwen(id)) {
|
|
5168
5380
|
const refs = (req.references ?? []).map(refToUrl3);
|
|
5169
5381
|
const firstUrl = refs[0];
|
|
5382
|
+
const imageInput = { prompt: req.prompt };
|
|
5170
5383
|
if (firstUrl !== void 0) {
|
|
5171
|
-
|
|
5172
|
-
|
|
5384
|
+
imageInput.image = firstUrl;
|
|
5385
|
+
if (!isQwenEditPlus(id)) imageInput.match_input_image = true;
|
|
5386
|
+
}
|
|
5387
|
+
const ratios = isQwenEditPlus(id) ? QWEN_EDIT_RATIOS : QWEN_IMAGE_RATIOS;
|
|
5388
|
+
if (req.aspectRatio !== void 0) {
|
|
5389
|
+
if (ratios.has(req.aspectRatio)) imageInput.aspect_ratio = req.aspectRatio;
|
|
5390
|
+
else
|
|
5391
|
+
ctx.warnings.push({
|
|
5392
|
+
code: "option_ignored",
|
|
5393
|
+
field: "aspectRatio",
|
|
5394
|
+
from: req.aspectRatio,
|
|
5395
|
+
message: `${id} has no ${req.aspectRatio} aspect_ratio; using the provider default`
|
|
5396
|
+
});
|
|
5397
|
+
}
|
|
5398
|
+
if (isQwenEditPlus(id) && req.outputFormat !== void 0) {
|
|
5399
|
+
imageInput.output_format = req.outputFormat === "jpeg" ? "jpg" : req.outputFormat;
|
|
5173
5400
|
}
|
|
5174
|
-
|
|
5401
|
+
input = imageInput;
|
|
5175
5402
|
} else {
|
|
5176
5403
|
const refs = req.references ?? [];
|
|
5177
5404
|
const first = refs[0];
|
|
5178
|
-
|
|
5405
|
+
const imageInput = { prompt: req.prompt };
|
|
5406
|
+
if (first) imageInput.image = refToUrl3(first);
|
|
5407
|
+
input = imageInput;
|
|
5179
5408
|
}
|
|
5180
5409
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|
|
5181
5410
|
const file = await download(ctx, url);
|
|
5182
5411
|
const usage2 = imageUsage2(ctx, req);
|
|
5183
5412
|
usage2.quantity = predictTime;
|
|
5184
|
-
return { images: [{ bytes: file.bytes, mime: file.mime }], usage: usage2, raw };
|
|
5413
|
+
return { images: [{ bytes: file.bytes, mime: file.mime }], usage: usage2, raw, outputUrl: url };
|
|
5185
5414
|
}
|
|
5186
5415
|
function wanSize(aspectRatio) {
|
|
5187
5416
|
if (!aspectRatio || aspectRatio === "adaptive" || aspectRatio === "1:1") return "2K";
|