@shop-os/modelkit 0.1.2 → 0.1.3
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 +10 -4
- package/dist/index.cjs +322 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +322 -161
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -292,7 +292,10 @@ var IMAGE_MODELS = [
|
|
|
292
292
|
constraints: {
|
|
293
293
|
aspectRatios: ["1:1", "4:3", "3:4", "16:9", "9:16", "3:2", "2:3", "21:9", "4:5", "5:4"],
|
|
294
294
|
sizes: ["1K", "2K"],
|
|
295
|
-
references: { images: 10 }
|
|
295
|
+
references: { images: 10 },
|
|
296
|
+
// Ark's Images API has no output-format, quality or count field; only
|
|
297
|
+
// the seed is forwarded, so anything else must warn, not vanish.
|
|
298
|
+
supports: ["seed"]
|
|
296
299
|
},
|
|
297
300
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
298
301
|
usage: { ...IMAGE_USAGE },
|
|
@@ -307,21 +310,12 @@ var IMAGE_MODELS = [
|
|
|
307
310
|
providerModelId: "seedream-4-5-251128",
|
|
308
311
|
lifecycle: "active",
|
|
309
312
|
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
|
-
],
|
|
313
|
+
// 97:30 has no Ark size spelling; the A+ flow pads inputs to 97:30 and
|
|
314
|
+
// omits the ratio instead. Advertise only sizes the adapter can send.
|
|
315
|
+
aspectRatios: ["1:1", "2:3", "3:2", "4:3", "3:4", "4:5", "5:4", "9:16", "16:9", "21:9"],
|
|
323
316
|
sizes: ["1K", "2K"],
|
|
324
|
-
references: { images: 10 }
|
|
317
|
+
references: { images: 10 },
|
|
318
|
+
supports: ["seed"]
|
|
325
319
|
},
|
|
326
320
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
327
321
|
usage: { ...IMAGE_USAGE },
|
|
@@ -345,6 +339,9 @@ var IMAGE_MODELS = [
|
|
|
345
339
|
pricingKind: "image_size"
|
|
346
340
|
},
|
|
347
341
|
{
|
|
342
|
+
// Prodia's gemini-3-pro jobs take aspect_ratio + resolution (1K/2K/4K), not
|
|
343
|
+
// width/height; 97:30 is outside its aspect_ratio enum.
|
|
344
|
+
// https://docs.prodia.com/models/gemini-3/
|
|
348
345
|
id: "prodia-nano-banana-pro",
|
|
349
346
|
aliases: [],
|
|
350
347
|
label: "Nano Banana Pro via Prodia",
|
|
@@ -353,19 +350,7 @@ var IMAGE_MODELS = [
|
|
|
353
350
|
providerModelId: "inference.gemini-3-pro.img2img.v1",
|
|
354
351
|
lifecycle: "active",
|
|
355
352
|
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
|
-
],
|
|
353
|
+
aspectRatios: ["1:1", "2:3", "3:2", "4:3", "3:4", "4:5", "5:4", "9:16", "16:9", "21:9"],
|
|
369
354
|
sizes: ["1K", "2K", "4K"],
|
|
370
355
|
requires: ["references"]
|
|
371
356
|
},
|
|
@@ -374,6 +359,8 @@ var IMAGE_MODELS = [
|
|
|
374
359
|
pricingKind: "image_size"
|
|
375
360
|
},
|
|
376
361
|
{
|
|
362
|
+
// Nano Banana (img2img.v2) is flat-rate with aspect_ratio only; 3:2, 4:5,
|
|
363
|
+
// 5:4 and 97:30 are not in its enum. https://docs.prodia.com/models/nano-banana/
|
|
377
364
|
id: "prodia-nano-banana",
|
|
378
365
|
aliases: [],
|
|
379
366
|
label: "Nano Banana via Prodia",
|
|
@@ -382,19 +369,7 @@ var IMAGE_MODELS = [
|
|
|
382
369
|
providerModelId: "inference.nano-banana.img2img.v2",
|
|
383
370
|
lifecycle: "active",
|
|
384
371
|
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
|
-
],
|
|
372
|
+
aspectRatios: ["1:1", "2:3", "3:4", "4:3", "9:16", "16:9", "21:9"],
|
|
398
373
|
sizes: ["1K"],
|
|
399
374
|
requires: ["references"]
|
|
400
375
|
},
|
|
@@ -403,6 +378,9 @@ var IMAGE_MODELS = [
|
|
|
403
378
|
pricingKind: "image_size"
|
|
404
379
|
},
|
|
405
380
|
{
|
|
381
|
+
// WAN 2.7 takes `images` (up to 9) and a `size` enum whose exact values
|
|
382
|
+
// cover 1:1/16:9/9:16/4:3/3:4 only; other ratios have no spelling.
|
|
383
|
+
// https://replicate.com/wan-video/wan-2.7-image-pro (input schema)
|
|
406
384
|
id: "wan-2.7-image-pro",
|
|
407
385
|
aliases: [],
|
|
408
386
|
label: "WAN 2.7 Image Pro",
|
|
@@ -411,19 +389,7 @@ var IMAGE_MODELS = [
|
|
|
411
389
|
providerModelId: "wan-video/wan-2.7-image-pro",
|
|
412
390
|
lifecycle: "active",
|
|
413
391
|
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
|
-
],
|
|
392
|
+
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4"],
|
|
427
393
|
sizes: ["1K", "2K", "4K"],
|
|
428
394
|
references: { images: 9 }
|
|
429
395
|
},
|
|
@@ -432,6 +398,9 @@ var IMAGE_MODELS = [
|
|
|
432
398
|
pricingKind: "image_size"
|
|
433
399
|
},
|
|
434
400
|
{
|
|
401
|
+
// Qwen Image 2 Pro has aspect_ratio but no size input; resolution follows
|
|
402
|
+
// the reference image (match_input_image) or the provider default.
|
|
403
|
+
// https://replicate.com/qwen/qwen-image-2-pro (input schema)
|
|
435
404
|
id: "qwen-image-2-pro",
|
|
436
405
|
aliases: [],
|
|
437
406
|
label: "Qwen Image 2 Pro",
|
|
@@ -440,28 +409,19 @@ var IMAGE_MODELS = [
|
|
|
440
409
|
providerModelId: "qwen/qwen-image-2-pro",
|
|
441
410
|
lifecycle: "active",
|
|
442
411
|
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"],
|
|
412
|
+
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"],
|
|
413
|
+
sizes: [],
|
|
457
414
|
references: { images: 1 },
|
|
458
415
|
requires: ["references"]
|
|
459
416
|
},
|
|
460
|
-
defaults: {
|
|
417
|
+
defaults: { aspectRatio: "1:1" },
|
|
461
418
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
462
419
|
pricingKind: "image_size"
|
|
463
420
|
},
|
|
464
421
|
{
|
|
422
|
+
// Qwen Image Edit Plus takes aspect_ratio (or match_input_image) and
|
|
423
|
+
// output_format, but no size; no default ratio so edits keep following
|
|
424
|
+
// the input image. https://replicate.com/qwen-edit-apps/qwen-image-edit-plus-lora-skin
|
|
465
425
|
id: "qwen-image-edit-plus-lora-skin",
|
|
466
426
|
aliases: [],
|
|
467
427
|
label: "Qwen Image Edit Plus",
|
|
@@ -470,25 +430,13 @@ var IMAGE_MODELS = [
|
|
|
470
430
|
providerModelId: "qwen-edit-apps/qwen-image-edit-plus-lora-skin",
|
|
471
431
|
lifecycle: "active",
|
|
472
432
|
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"],
|
|
433
|
+
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4"],
|
|
434
|
+
sizes: [],
|
|
487
435
|
references: { images: 1 },
|
|
488
436
|
requires: ["references"],
|
|
489
437
|
supports: ["outputFormat"]
|
|
490
438
|
},
|
|
491
|
-
defaults: {
|
|
439
|
+
defaults: { outputFormat: "png" },
|
|
492
440
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
493
441
|
pricingKind: "image_size"
|
|
494
442
|
}
|
|
@@ -1898,7 +1846,11 @@ var aiSdkTextAdapter = {
|
|
|
1898
1846
|
function requiredKeys(model, config) {
|
|
1899
1847
|
if (model.adapter === "fal" && config.routing?.fal === "cloudflare-passthrough")
|
|
1900
1848
|
return ["cloudflare"];
|
|
1901
|
-
if (model.adapter === "ai-sdk-text")
|
|
1849
|
+
if (model.adapter === "ai-sdk-text") {
|
|
1850
|
+
const names = [textKeyName(model, config.routing ?? {})];
|
|
1851
|
+
if (config.routing?.text === "cloudflare") names.push("cloudflare");
|
|
1852
|
+
return names;
|
|
1853
|
+
}
|
|
1902
1854
|
return ADAPTER_KEYS[model.adapter];
|
|
1903
1855
|
}
|
|
1904
1856
|
var IMAGE_OUTPUT_TYPES = /* @__PURE__ */ new Set(["image", "upscale", "bg-remove"]);
|
|
@@ -1956,6 +1908,20 @@ function sdkAspectRatio(ratio) {
|
|
|
1956
1908
|
const parsed = sdkRatio.safeParse(ratio);
|
|
1957
1909
|
return parsed.success ? parsed.data : void 0;
|
|
1958
1910
|
}
|
|
1911
|
+
function sdkDataContent(ref) {
|
|
1912
|
+
return "url" in ref ? ref.url : ref.bytes;
|
|
1913
|
+
}
|
|
1914
|
+
function sdkReference(ref) {
|
|
1915
|
+
return "url" in ref ? ref.url : { data: ref.bytes, mediaType: ref.mime };
|
|
1916
|
+
}
|
|
1917
|
+
function pushIgnored(warnings, field, from, modelId) {
|
|
1918
|
+
warnings.push({
|
|
1919
|
+
code: "option_ignored",
|
|
1920
|
+
field,
|
|
1921
|
+
from,
|
|
1922
|
+
message: `${modelId} provider instance does not support ${field}; ignored`
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1959
1925
|
function createModelKit(config, adapters) {
|
|
1960
1926
|
const catalog = new Catalog(MODELS).withOverrides(config.catalogOverride ?? []);
|
|
1961
1927
|
const logger = config.logger ?? console;
|
|
@@ -1978,6 +1944,7 @@ function createModelKit(config, adapters) {
|
|
|
1978
1944
|
call,
|
|
1979
1945
|
warnings
|
|
1980
1946
|
};
|
|
1947
|
+
if (config.endpoints) ctx.endpoints = config.endpoints;
|
|
1981
1948
|
if (call.signal) ctx.signal = call.signal;
|
|
1982
1949
|
return { adapter, ctx };
|
|
1983
1950
|
}
|
|
@@ -2017,16 +1984,42 @@ function createModelKit(config, adapters) {
|
|
|
2017
1984
|
};
|
|
2018
1985
|
}
|
|
2019
1986
|
async function passthroughImage(req, call) {
|
|
2020
|
-
const {
|
|
1987
|
+
const {
|
|
1988
|
+
model,
|
|
1989
|
+
prompt,
|
|
1990
|
+
n,
|
|
1991
|
+
count,
|
|
1992
|
+
size,
|
|
1993
|
+
aspectRatio,
|
|
1994
|
+
seed,
|
|
1995
|
+
providerOptions,
|
|
1996
|
+
references,
|
|
1997
|
+
exactSize: exactSizeField,
|
|
1998
|
+
quality: _quality,
|
|
1999
|
+
outputFormat: _outputFormat
|
|
2000
|
+
} = req;
|
|
2021
2001
|
const options = { model, prompt };
|
|
2002
|
+
const warnings = [];
|
|
2022
2003
|
const quantity = n ?? count;
|
|
2023
2004
|
if (quantity !== void 0) options.n = quantity;
|
|
2024
|
-
|
|
2025
|
-
|
|
2005
|
+
if (references !== void 0 && references.length > 0)
|
|
2006
|
+
options.prompt = { images: references.map(sdkDataContent), text: prompt };
|
|
2007
|
+
const exact = exactSizeField === void 0 ? void 0 : exactSize.safeParse(exactSizeField);
|
|
2008
|
+
if (exact?.success) options.size = exact.data;
|
|
2009
|
+
else if (exactSizeField !== void 0)
|
|
2010
|
+
pushIgnored(warnings, "exactSize", exactSizeField, model.modelId);
|
|
2011
|
+
const requested = size === void 0 ? void 0 : exactSize.safeParse(size);
|
|
2012
|
+
if (requested?.success) options.size ??= requested.data;
|
|
2013
|
+
else if (size !== void 0) pushIgnored(warnings, "size", size, model.modelId);
|
|
2026
2014
|
const ratio = sdkAspectRatio(aspectRatio);
|
|
2027
2015
|
if (ratio) options.aspectRatio = ratio;
|
|
2016
|
+
else if (aspectRatio !== void 0)
|
|
2017
|
+
pushIgnored(warnings, "aspectRatio", aspectRatio, model.modelId);
|
|
2028
2018
|
if (seed !== void 0) options.seed = seed;
|
|
2029
2019
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
2020
|
+
if (_quality !== void 0) pushIgnored(warnings, "quality", _quality, model.modelId);
|
|
2021
|
+
if (_outputFormat !== void 0)
|
|
2022
|
+
pushIgnored(warnings, "outputFormat", _outputFormat, model.modelId);
|
|
2030
2023
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
2031
2024
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
2032
2025
|
const result = await (0, import_ai2.generateImage)(options);
|
|
@@ -2041,17 +2034,73 @@ function createModelKit(config, adapters) {
|
|
|
2041
2034
|
quantity: images.length
|
|
2042
2035
|
};
|
|
2043
2036
|
await emit(usage2);
|
|
2044
|
-
return { image: images[0], images, usage: usage2, raw: result, warnings
|
|
2037
|
+
return { image: images[0], images, usage: usage2, raw: result, warnings };
|
|
2045
2038
|
}
|
|
2046
2039
|
function passthroughVideo(req, call) {
|
|
2047
|
-
const {
|
|
2040
|
+
const {
|
|
2041
|
+
model,
|
|
2042
|
+
prompt,
|
|
2043
|
+
aspectRatio,
|
|
2044
|
+
duration,
|
|
2045
|
+
durationSeconds,
|
|
2046
|
+
seed,
|
|
2047
|
+
providerOptions,
|
|
2048
|
+
firstFrame,
|
|
2049
|
+
lastFrame,
|
|
2050
|
+
sourceVideo,
|
|
2051
|
+
referenceImages,
|
|
2052
|
+
referenceVideos,
|
|
2053
|
+
referenceAudios,
|
|
2054
|
+
resolution,
|
|
2055
|
+
generateAudio: generateAudio2,
|
|
2056
|
+
negativePrompt: _negativePrompt,
|
|
2057
|
+
cfgScale: _cfgScale,
|
|
2058
|
+
promptExpansion: _promptExpansion,
|
|
2059
|
+
mode: _mode
|
|
2060
|
+
} = req;
|
|
2048
2061
|
const seconds = duration ?? durationSeconds;
|
|
2049
2062
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
2050
2063
|
const options = { model, prompt };
|
|
2051
|
-
const
|
|
2064
|
+
const warnings = [];
|
|
2065
|
+
const ratio = sdkAspectRatio(aspectRatio) ?? (aspectRatio === "adaptive" ? "adaptive" : void 0);
|
|
2052
2066
|
if (ratio) options.aspectRatio = ratio;
|
|
2067
|
+
else if (aspectRatio !== void 0)
|
|
2068
|
+
pushIgnored(warnings, "aspectRatio", aspectRatio, model.modelId);
|
|
2053
2069
|
if (seconds !== void 0) options.duration = seconds;
|
|
2054
2070
|
if (seed !== void 0) options.seed = seed;
|
|
2071
|
+
if (generateAudio2 !== void 0) options.generateAudio = generateAudio2;
|
|
2072
|
+
const frames = [
|
|
2073
|
+
...firstFrame ? [{ image: sdkDataContent(firstFrame), frameType: "first_frame" }] : [],
|
|
2074
|
+
...lastFrame ? [{ image: sdkDataContent(lastFrame), frameType: "last_frame" }] : []
|
|
2075
|
+
];
|
|
2076
|
+
if (frames.length > 0) options.frameImages = frames;
|
|
2077
|
+
const references = [
|
|
2078
|
+
...(referenceImages ?? []).map(sdkDataContent),
|
|
2079
|
+
...(referenceVideos ?? []).map(sdkReference)
|
|
2080
|
+
];
|
|
2081
|
+
if (references.length > 0) {
|
|
2082
|
+
if (frames.length > 0) {
|
|
2083
|
+
warnings.push({
|
|
2084
|
+
code: "option_ignored",
|
|
2085
|
+
field: "inputReferences",
|
|
2086
|
+
from: references.length,
|
|
2087
|
+
message: `${model.modelId} provider instance ignores references when frames are set`
|
|
2088
|
+
});
|
|
2089
|
+
} else {
|
|
2090
|
+
options.inputReferences = references;
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
if (sourceVideo) pushIgnored(warnings, "sourceVideo", void 0, model.modelId);
|
|
2094
|
+
if (referenceAudios?.length)
|
|
2095
|
+
pushIgnored(warnings, "referenceAudios", referenceAudios.length, model.modelId);
|
|
2096
|
+
if (resolution !== void 0)
|
|
2097
|
+
pushIgnored(warnings, "resolution", resolution, model.modelId);
|
|
2098
|
+
if (_negativePrompt !== void 0)
|
|
2099
|
+
pushIgnored(warnings, "negativePrompt", void 0, model.modelId);
|
|
2100
|
+
if (_cfgScale !== void 0) pushIgnored(warnings, "cfgScale", _cfgScale, model.modelId);
|
|
2101
|
+
if (_promptExpansion !== void 0)
|
|
2102
|
+
pushIgnored(warnings, "promptExpansion", _promptExpansion, model.modelId);
|
|
2103
|
+
if (_mode !== void 0) pushIgnored(warnings, "mode", _mode, model.modelId);
|
|
2055
2104
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
2056
2105
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
2057
2106
|
const pending = (0, import_ai2.experimental_generateVideo)(options);
|
|
@@ -2079,7 +2128,7 @@ function createModelKit(config, adapters) {
|
|
|
2079
2128
|
});
|
|
2080
2129
|
return {
|
|
2081
2130
|
jobId: `ai-sdk:${model.provider}:${model.modelId}`,
|
|
2082
|
-
warnings
|
|
2131
|
+
warnings,
|
|
2083
2132
|
async poll() {
|
|
2084
2133
|
if (settled) return { status: "succeeded", raw: settled.raw };
|
|
2085
2134
|
if (failed) return { status: "failed" };
|
|
@@ -2303,6 +2352,9 @@ var SUBMIT_PATH = "/contents/generations/tasks";
|
|
|
2303
2352
|
var SEEDANCE_POLL_INTERVAL_MS = 15e3;
|
|
2304
2353
|
var RESULT_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
2305
2354
|
var VIDEO_URL_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
2355
|
+
function arkBaseUrl(ctx) {
|
|
2356
|
+
return ctx.endpoints?.ark ?? ARK_BASE_URL;
|
|
2357
|
+
}
|
|
2306
2358
|
var SEEDREAM_SIZES = {
|
|
2307
2359
|
"1K": {
|
|
2308
2360
|
"1:1": "1024x1024",
|
|
@@ -2313,7 +2365,8 @@ var SEEDREAM_SIZES = {
|
|
|
2313
2365
|
"3:2": "1248x832",
|
|
2314
2366
|
"2:3": "832x1248",
|
|
2315
2367
|
"21:9": "1568x672",
|
|
2316
|
-
"4:5": "864x1080"
|
|
2368
|
+
"4:5": "864x1080",
|
|
2369
|
+
"5:4": "1080x864"
|
|
2317
2370
|
},
|
|
2318
2371
|
"2K": {
|
|
2319
2372
|
"1:1": "2048x2048",
|
|
@@ -2324,7 +2377,8 @@ var SEEDREAM_SIZES = {
|
|
|
2324
2377
|
"3:2": "2496x1664",
|
|
2325
2378
|
"2:3": "1664x2496",
|
|
2326
2379
|
"21:9": "3136x1344",
|
|
2327
|
-
"4:5": "1728x2160"
|
|
2380
|
+
"4:5": "1728x2160",
|
|
2381
|
+
"5:4": "2160x1728"
|
|
2328
2382
|
}
|
|
2329
2383
|
};
|
|
2330
2384
|
var arkAdapter = {
|
|
@@ -2371,9 +2425,11 @@ function seedreamSize(aspect, size) {
|
|
|
2371
2425
|
const table = SEEDREAM_SIZES[tier];
|
|
2372
2426
|
return table[aspect ?? ""] ?? table["1:1"] ?? "2048x2048";
|
|
2373
2427
|
}
|
|
2374
|
-
function
|
|
2375
|
-
if (
|
|
2376
|
-
|
|
2428
|
+
function sniffedImageMime(bytes) {
|
|
2429
|
+
if (bytes.length >= 4 && bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71)
|
|
2430
|
+
return "image/png";
|
|
2431
|
+
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)
|
|
2432
|
+
return "image/webp";
|
|
2377
2433
|
return "image/jpeg";
|
|
2378
2434
|
}
|
|
2379
2435
|
function arkUrl(ref) {
|
|
@@ -2415,7 +2471,7 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2415
2471
|
else if (refs.length > 1) body.image = refs;
|
|
2416
2472
|
const data = await withRetry(async () => {
|
|
2417
2473
|
const res = await ctx.fetch(
|
|
2418
|
-
`${
|
|
2474
|
+
`${arkBaseUrl(ctx)}/images/generations`,
|
|
2419
2475
|
fetchInitFor(ctx, {
|
|
2420
2476
|
method: "POST",
|
|
2421
2477
|
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
@@ -2454,7 +2510,7 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2454
2510
|
};
|
|
2455
2511
|
if (req.size !== void 0) usage2.imageSize = req.size;
|
|
2456
2512
|
if (req.quality !== void 0) usage2.imageQuality = req.quality;
|
|
2457
|
-
return { images: [{ bytes, mime:
|
|
2513
|
+
return { images: [{ bytes, mime: sniffedImageMime(bytes) }], usage: usage2, raw: data };
|
|
2458
2514
|
}
|
|
2459
2515
|
var SeedanceResponseSchema = import_zod4.z.object({
|
|
2460
2516
|
id: import_zod4.z.string().optional(),
|
|
@@ -2542,7 +2598,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2542
2598
|
if (req.seed !== void 0) body.seed = req.seed;
|
|
2543
2599
|
const submit = await withRetry(async () => {
|
|
2544
2600
|
const res = await ctx.fetch(
|
|
2545
|
-
`${
|
|
2601
|
+
`${arkBaseUrl(ctx)}${SUBMIT_PATH}`,
|
|
2546
2602
|
fetchInitFor(ctx, {
|
|
2547
2603
|
method: "POST",
|
|
2548
2604
|
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
@@ -2562,7 +2618,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2562
2618
|
const usage2 = seedanceUsage(ctx, req, duration);
|
|
2563
2619
|
const fetchStatus = async () => {
|
|
2564
2620
|
const res = await ctx.fetch(
|
|
2565
|
-
`${
|
|
2621
|
+
`${arkBaseUrl(ctx)}${SUBMIT_PATH}/${jobId}`,
|
|
2566
2622
|
fetchInitFor(ctx, {
|
|
2567
2623
|
headers: { Authorization: `Bearer ${key}` }
|
|
2568
2624
|
})
|
|
@@ -3621,60 +3677,6 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3621
3677
|
uploadedNames.push(file.fileName);
|
|
3622
3678
|
return file.fileUri;
|
|
3623
3679
|
};
|
|
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
3680
|
const cleanupUploads = async () => {
|
|
3679
3681
|
for (const fileName of uploadedNames) await deleteGoogleFile(fileName, apiKey, ctx.fetch);
|
|
3680
3682
|
};
|
|
@@ -3688,6 +3690,60 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3688
3690
|
if (ctx.signal !== void 0) createRetryOptions.signal = ctx.signal;
|
|
3689
3691
|
let interaction;
|
|
3690
3692
|
try {
|
|
3693
|
+
const parts = [];
|
|
3694
|
+
if (req.sourceVideo) {
|
|
3695
|
+
const media = await resolveMedia(
|
|
3696
|
+
req.sourceVideo,
|
|
3697
|
+
ctx.fetch,
|
|
3698
|
+
ctx.signal,
|
|
3699
|
+
"video/mp4",
|
|
3700
|
+
modelId
|
|
3701
|
+
);
|
|
3702
|
+
parts.push({
|
|
3703
|
+
type: "video",
|
|
3704
|
+
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3705
|
+
mime_type: media.mime
|
|
3706
|
+
});
|
|
3707
|
+
}
|
|
3708
|
+
for (const ref of videos) {
|
|
3709
|
+
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "video/mp4", modelId);
|
|
3710
|
+
parts.push({
|
|
3711
|
+
type: "video",
|
|
3712
|
+
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3713
|
+
mime_type: media.mime
|
|
3714
|
+
});
|
|
3715
|
+
}
|
|
3716
|
+
if (req.firstFrame) {
|
|
3717
|
+
const media = await resolveMedia(
|
|
3718
|
+
req.firstFrame,
|
|
3719
|
+
ctx.fetch,
|
|
3720
|
+
ctx.signal,
|
|
3721
|
+
"image/png",
|
|
3722
|
+
modelId
|
|
3723
|
+
);
|
|
3724
|
+
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3725
|
+
parts.push({
|
|
3726
|
+
type: "image",
|
|
3727
|
+
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3728
|
+
mime_type: media.mime
|
|
3729
|
+
});
|
|
3730
|
+
} else {
|
|
3731
|
+
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
for (const ref of images) {
|
|
3735
|
+
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "image/png", modelId);
|
|
3736
|
+
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3737
|
+
parts.push({
|
|
3738
|
+
type: "image",
|
|
3739
|
+
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3740
|
+
mime_type: media.mime
|
|
3741
|
+
});
|
|
3742
|
+
} else {
|
|
3743
|
+
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
parts.push({ type: "text", text: req.prompt });
|
|
3691
3747
|
try {
|
|
3692
3748
|
interaction = await withRetry(async () => {
|
|
3693
3749
|
try {
|
|
@@ -4753,7 +4809,8 @@ var RATIO_TO_DIMS = {
|
|
|
4753
4809
|
"9:16": { width: 768, height: 1360 },
|
|
4754
4810
|
"3:4": { width: 768, height: 1024 },
|
|
4755
4811
|
"2:3": { width: 768, height: 1152 },
|
|
4756
|
-
"4:5": { width: 896, height: 1120 }
|
|
4812
|
+
"4:5": { width: 896, height: 1120 },
|
|
4813
|
+
"5:4": { width: 1120, height: 896 }
|
|
4757
4814
|
};
|
|
4758
4815
|
function dimsFor(aspectRatio) {
|
|
4759
4816
|
if (aspectRatio !== void 0) {
|
|
@@ -4762,6 +4819,27 @@ function dimsFor(aspectRatio) {
|
|
|
4762
4819
|
}
|
|
4763
4820
|
return { width: 1024, height: 1024 };
|
|
4764
4821
|
}
|
|
4822
|
+
var GEMINI_JOB_RATIOS = /* @__PURE__ */ new Set([
|
|
4823
|
+
"1:1",
|
|
4824
|
+
"2:3",
|
|
4825
|
+
"3:2",
|
|
4826
|
+
"3:4",
|
|
4827
|
+
"4:3",
|
|
4828
|
+
"4:5",
|
|
4829
|
+
"5:4",
|
|
4830
|
+
"9:16",
|
|
4831
|
+
"16:9",
|
|
4832
|
+
"21:9"
|
|
4833
|
+
]);
|
|
4834
|
+
var NANO_BANANA_RATIOS = /* @__PURE__ */ new Set([
|
|
4835
|
+
"1:1",
|
|
4836
|
+
"2:3",
|
|
4837
|
+
"3:4",
|
|
4838
|
+
"4:3",
|
|
4839
|
+
"9:16",
|
|
4840
|
+
"16:9",
|
|
4841
|
+
"21:9"
|
|
4842
|
+
]);
|
|
4765
4843
|
async function refToBytes(ctx, ref) {
|
|
4766
4844
|
if ("bytes" in ref) return { bytes: ref.bytes, mime: ref.mime };
|
|
4767
4845
|
const res = await ctx.fetch(ref.url);
|
|
@@ -4861,7 +4939,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4861
4939
|
inputs = refs.length > 0 && firstRef !== void 0 ? [firstRef] : [];
|
|
4862
4940
|
accept = req.outputFormat === "png" ? "image/png" : "image/jpeg";
|
|
4863
4941
|
mime = accept;
|
|
4864
|
-
} else if (providerModelId === "flux-2-pro" || providerModelId === FLUX_2_PRO_JOB
|
|
4942
|
+
} else if (providerModelId === "flux-2-pro" || providerModelId === FLUX_2_PRO_JOB) {
|
|
4865
4943
|
const dims = dimsFor(req.aspectRatio);
|
|
4866
4944
|
const config = {
|
|
4867
4945
|
prompt: req.prompt,
|
|
@@ -4870,8 +4948,30 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4870
4948
|
safety_tolerance: 5
|
|
4871
4949
|
};
|
|
4872
4950
|
if (req.seed !== void 0) config.seed = req.seed;
|
|
4873
|
-
|
|
4874
|
-
|
|
4951
|
+
job = { type: FLUX_2_PRO_JOB, config };
|
|
4952
|
+
inputs = refs;
|
|
4953
|
+
accept = "image/png";
|
|
4954
|
+
mime = "image/png";
|
|
4955
|
+
} else if (providerModelId === "inference.gemini-3-pro.img2img.v1" || providerModelId === "inference.nano-banana.img2img.v2") {
|
|
4956
|
+
const allowed = providerModelId === "inference.nano-banana.img2img.v2" ? NANO_BANANA_RATIOS : GEMINI_JOB_RATIOS;
|
|
4957
|
+
const config = {
|
|
4958
|
+
prompt: req.prompt,
|
|
4959
|
+
safety_tolerance: 5
|
|
4960
|
+
};
|
|
4961
|
+
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
4962
|
+
if (allowed.has(req.aspectRatio)) config.aspect_ratio = req.aspectRatio;
|
|
4963
|
+
else
|
|
4964
|
+
ctx.warnings.push({
|
|
4965
|
+
code: "option_ignored",
|
|
4966
|
+
field: "aspectRatio",
|
|
4967
|
+
from: req.aspectRatio,
|
|
4968
|
+
message: `${providerModelId} has no ${req.aspectRatio} aspect_ratio; using the provider default`
|
|
4969
|
+
});
|
|
4970
|
+
}
|
|
4971
|
+
if (providerModelId === "inference.gemini-3-pro.img2img.v1")
|
|
4972
|
+
config.resolution = req.size ?? "1K";
|
|
4973
|
+
if (req.seed !== void 0) config.seed = req.seed;
|
|
4974
|
+
job = { type: providerModelId, config };
|
|
4875
4975
|
inputs = refs;
|
|
4876
4976
|
accept = "image/png";
|
|
4877
4977
|
mime = "image/png";
|
|
@@ -5145,6 +5245,50 @@ function isUpscaler(providerModelId) {
|
|
|
5145
5245
|
function isQwen(providerModelId) {
|
|
5146
5246
|
return isLower(providerModelId).includes("qwen");
|
|
5147
5247
|
}
|
|
5248
|
+
function isWanImage(providerModelId) {
|
|
5249
|
+
return isLower(providerModelId).includes("wan-2.7");
|
|
5250
|
+
}
|
|
5251
|
+
function isQwenEditPlus(providerModelId) {
|
|
5252
|
+
return isLower(providerModelId).includes("edit");
|
|
5253
|
+
}
|
|
5254
|
+
var QWEN_IMAGE_RATIOS = /* @__PURE__ */ new Set([
|
|
5255
|
+
"1:1",
|
|
5256
|
+
"16:9",
|
|
5257
|
+
"9:16",
|
|
5258
|
+
"4:3",
|
|
5259
|
+
"3:4",
|
|
5260
|
+
"3:2",
|
|
5261
|
+
"2:3"
|
|
5262
|
+
]);
|
|
5263
|
+
var QWEN_EDIT_RATIOS = /* @__PURE__ */ new Set(["1:1", "16:9", "9:16", "4:3", "3:4"]);
|
|
5264
|
+
var WAN_IMAGE_SIZES = {
|
|
5265
|
+
"1K": {
|
|
5266
|
+
"1:1": "1024*1024",
|
|
5267
|
+
"16:9": "1280*720",
|
|
5268
|
+
"9:16": "720*1280",
|
|
5269
|
+
"4:3": "1024*768",
|
|
5270
|
+
"3:4": "768*1024"
|
|
5271
|
+
},
|
|
5272
|
+
"2K": {
|
|
5273
|
+
"1:1": "2048*2048",
|
|
5274
|
+
"16:9": "2048*1152",
|
|
5275
|
+
"9:16": "1152*2048",
|
|
5276
|
+
"4:3": "2048*1536",
|
|
5277
|
+
"3:4": "1536*2048"
|
|
5278
|
+
},
|
|
5279
|
+
"4K": {
|
|
5280
|
+
"1:1": "4096*4096",
|
|
5281
|
+
"16:9": "4096*2304",
|
|
5282
|
+
"9:16": "2304*4096",
|
|
5283
|
+
"4:3": "4096*3072",
|
|
5284
|
+
"3:4": "3072*4096"
|
|
5285
|
+
}
|
|
5286
|
+
};
|
|
5287
|
+
function wanImageSize(aspectRatio, size) {
|
|
5288
|
+
const tier = size === "2K" || size === "4K" ? size : "1K";
|
|
5289
|
+
const table = WAN_IMAGE_SIZES[tier];
|
|
5290
|
+
return table[aspectRatio ?? ""] ?? table["1:1"] ?? "1024*1024";
|
|
5291
|
+
}
|
|
5148
5292
|
async function generateReplicateImage(req, ctx, deps) {
|
|
5149
5293
|
const id = ctx.model.providerModelId;
|
|
5150
5294
|
const input = { prompt: req.prompt };
|
|
@@ -5164,14 +5308,31 @@ async function generateReplicateImage(req, ctx, deps) {
|
|
|
5164
5308
|
input.creativity = 0;
|
|
5165
5309
|
input.scale_factor = 2;
|
|
5166
5310
|
input.output_format = "png";
|
|
5311
|
+
} else if (isWanImage(id)) {
|
|
5312
|
+
const refs = (req.references ?? []).map(refToUrl3);
|
|
5313
|
+
if (refs.length > 0) input.images = refs;
|
|
5314
|
+
input.size = wanImageSize(req.aspectRatio, req.size);
|
|
5167
5315
|
} else if (isQwen(id)) {
|
|
5168
5316
|
const refs = (req.references ?? []).map(refToUrl3);
|
|
5169
5317
|
const firstUrl = refs[0];
|
|
5170
5318
|
if (firstUrl !== void 0) {
|
|
5171
5319
|
input.image = firstUrl;
|
|
5172
|
-
input.match_input_image = true;
|
|
5320
|
+
if (!isQwenEditPlus(id)) input.match_input_image = true;
|
|
5321
|
+
}
|
|
5322
|
+
const ratios = isQwenEditPlus(id) ? QWEN_EDIT_RATIOS : QWEN_IMAGE_RATIOS;
|
|
5323
|
+
if (req.aspectRatio !== void 0) {
|
|
5324
|
+
if (ratios.has(req.aspectRatio)) input.aspect_ratio = req.aspectRatio;
|
|
5325
|
+
else
|
|
5326
|
+
ctx.warnings.push({
|
|
5327
|
+
code: "option_ignored",
|
|
5328
|
+
field: "aspectRatio",
|
|
5329
|
+
from: req.aspectRatio,
|
|
5330
|
+
message: `${id} has no ${req.aspectRatio} aspect_ratio; using the provider default`
|
|
5331
|
+
});
|
|
5332
|
+
}
|
|
5333
|
+
if (isQwenEditPlus(id) && req.outputFormat !== void 0) {
|
|
5334
|
+
input.output_format = req.outputFormat === "jpeg" ? "jpg" : req.outputFormat;
|
|
5173
5335
|
}
|
|
5174
|
-
if (req.outputFormat !== void 0) input.output_format = req.outputFormat;
|
|
5175
5336
|
} else {
|
|
5176
5337
|
const refs = req.references ?? [];
|
|
5177
5338
|
const first = refs[0];
|