@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.js
CHANGED
|
@@ -210,7 +210,10 @@ var IMAGE_MODELS = [
|
|
|
210
210
|
constraints: {
|
|
211
211
|
aspectRatios: ["1:1", "4:3", "3:4", "16:9", "9:16", "3:2", "2:3", "21:9", "4:5", "5:4"],
|
|
212
212
|
sizes: ["1K", "2K"],
|
|
213
|
-
references: { images: 10 }
|
|
213
|
+
references: { images: 10 },
|
|
214
|
+
// Ark's Images API has no output-format, quality or count field; only
|
|
215
|
+
// the seed is forwarded, so anything else must warn, not vanish.
|
|
216
|
+
supports: ["seed"]
|
|
214
217
|
},
|
|
215
218
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
216
219
|
usage: { ...IMAGE_USAGE },
|
|
@@ -225,21 +228,12 @@ var IMAGE_MODELS = [
|
|
|
225
228
|
providerModelId: "seedream-4-5-251128",
|
|
226
229
|
lifecycle: "active",
|
|
227
230
|
constraints: {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
"3:2",
|
|
232
|
-
"4:3",
|
|
233
|
-
"3:4",
|
|
234
|
-
"4:5",
|
|
235
|
-
"5:4",
|
|
236
|
-
"9:16",
|
|
237
|
-
"16:9",
|
|
238
|
-
"21:9",
|
|
239
|
-
"97:30"
|
|
240
|
-
],
|
|
231
|
+
// 97:30 has no Ark size spelling; the A+ flow pads inputs to 97:30 and
|
|
232
|
+
// omits the ratio instead. Advertise only sizes the adapter can send.
|
|
233
|
+
aspectRatios: ["1:1", "2:3", "3:2", "4:3", "3:4", "4:5", "5:4", "9:16", "16:9", "21:9"],
|
|
241
234
|
sizes: ["1K", "2K"],
|
|
242
|
-
references: { images: 10 }
|
|
235
|
+
references: { images: 10 },
|
|
236
|
+
supports: ["seed"]
|
|
243
237
|
},
|
|
244
238
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
245
239
|
usage: { ...IMAGE_USAGE },
|
|
@@ -263,6 +257,9 @@ var IMAGE_MODELS = [
|
|
|
263
257
|
pricingKind: "image_size"
|
|
264
258
|
},
|
|
265
259
|
{
|
|
260
|
+
// Prodia's gemini-3-pro jobs take aspect_ratio + resolution (1K/2K/4K), not
|
|
261
|
+
// width/height; 97:30 is outside its aspect_ratio enum.
|
|
262
|
+
// https://docs.prodia.com/models/gemini-3/
|
|
266
263
|
id: "prodia-nano-banana-pro",
|
|
267
264
|
aliases: [],
|
|
268
265
|
label: "Nano Banana Pro via Prodia",
|
|
@@ -271,19 +268,7 @@ var IMAGE_MODELS = [
|
|
|
271
268
|
providerModelId: "inference.gemini-3-pro.img2img.v1",
|
|
272
269
|
lifecycle: "active",
|
|
273
270
|
constraints: {
|
|
274
|
-
aspectRatios: [
|
|
275
|
-
"1:1",
|
|
276
|
-
"2:3",
|
|
277
|
-
"3:2",
|
|
278
|
-
"4:3",
|
|
279
|
-
"3:4",
|
|
280
|
-
"4:5",
|
|
281
|
-
"5:4",
|
|
282
|
-
"9:16",
|
|
283
|
-
"16:9",
|
|
284
|
-
"21:9",
|
|
285
|
-
"97:30"
|
|
286
|
-
],
|
|
271
|
+
aspectRatios: ["1:1", "2:3", "3:2", "4:3", "3:4", "4:5", "5:4", "9:16", "16:9", "21:9"],
|
|
287
272
|
sizes: ["1K", "2K", "4K"],
|
|
288
273
|
requires: ["references"]
|
|
289
274
|
},
|
|
@@ -292,6 +277,8 @@ var IMAGE_MODELS = [
|
|
|
292
277
|
pricingKind: "image_size"
|
|
293
278
|
},
|
|
294
279
|
{
|
|
280
|
+
// Nano Banana (img2img.v2) is flat-rate with aspect_ratio only; 3:2, 4:5,
|
|
281
|
+
// 5:4 and 97:30 are not in its enum. https://docs.prodia.com/models/nano-banana/
|
|
295
282
|
id: "prodia-nano-banana",
|
|
296
283
|
aliases: [],
|
|
297
284
|
label: "Nano Banana via Prodia",
|
|
@@ -300,19 +287,7 @@ var IMAGE_MODELS = [
|
|
|
300
287
|
providerModelId: "inference.nano-banana.img2img.v2",
|
|
301
288
|
lifecycle: "active",
|
|
302
289
|
constraints: {
|
|
303
|
-
aspectRatios: [
|
|
304
|
-
"1:1",
|
|
305
|
-
"2:3",
|
|
306
|
-
"3:2",
|
|
307
|
-
"4:3",
|
|
308
|
-
"3:4",
|
|
309
|
-
"4:5",
|
|
310
|
-
"5:4",
|
|
311
|
-
"9:16",
|
|
312
|
-
"16:9",
|
|
313
|
-
"21:9",
|
|
314
|
-
"97:30"
|
|
315
|
-
],
|
|
290
|
+
aspectRatios: ["1:1", "2:3", "3:4", "4:3", "9:16", "16:9", "21:9"],
|
|
316
291
|
sizes: ["1K"],
|
|
317
292
|
requires: ["references"]
|
|
318
293
|
},
|
|
@@ -321,6 +296,9 @@ var IMAGE_MODELS = [
|
|
|
321
296
|
pricingKind: "image_size"
|
|
322
297
|
},
|
|
323
298
|
{
|
|
299
|
+
// WAN 2.7 takes `images` (up to 9) and a `size` enum whose exact values
|
|
300
|
+
// cover 1:1/16:9/9:16/4:3/3:4 only; other ratios have no spelling.
|
|
301
|
+
// https://replicate.com/wan-video/wan-2.7-image-pro (input schema)
|
|
324
302
|
id: "wan-2.7-image-pro",
|
|
325
303
|
aliases: [],
|
|
326
304
|
label: "WAN 2.7 Image Pro",
|
|
@@ -329,19 +307,7 @@ var IMAGE_MODELS = [
|
|
|
329
307
|
providerModelId: "wan-video/wan-2.7-image-pro",
|
|
330
308
|
lifecycle: "active",
|
|
331
309
|
constraints: {
|
|
332
|
-
aspectRatios: [
|
|
333
|
-
"1:1",
|
|
334
|
-
"2:3",
|
|
335
|
-
"3:2",
|
|
336
|
-
"4:3",
|
|
337
|
-
"3:4",
|
|
338
|
-
"4:5",
|
|
339
|
-
"5:4",
|
|
340
|
-
"9:16",
|
|
341
|
-
"16:9",
|
|
342
|
-
"21:9",
|
|
343
|
-
"97:30"
|
|
344
|
-
],
|
|
310
|
+
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4"],
|
|
345
311
|
sizes: ["1K", "2K", "4K"],
|
|
346
312
|
references: { images: 9 }
|
|
347
313
|
},
|
|
@@ -350,6 +316,9 @@ var IMAGE_MODELS = [
|
|
|
350
316
|
pricingKind: "image_size"
|
|
351
317
|
},
|
|
352
318
|
{
|
|
319
|
+
// Qwen Image 2 Pro has aspect_ratio but no size input; resolution follows
|
|
320
|
+
// the reference image (match_input_image) or the provider default.
|
|
321
|
+
// https://replicate.com/qwen/qwen-image-2-pro (input schema)
|
|
353
322
|
id: "qwen-image-2-pro",
|
|
354
323
|
aliases: [],
|
|
355
324
|
label: "Qwen Image 2 Pro",
|
|
@@ -358,28 +327,19 @@ var IMAGE_MODELS = [
|
|
|
358
327
|
providerModelId: "qwen/qwen-image-2-pro",
|
|
359
328
|
lifecycle: "active",
|
|
360
329
|
constraints: {
|
|
361
|
-
aspectRatios: [
|
|
362
|
-
|
|
363
|
-
"2:3",
|
|
364
|
-
"3:2",
|
|
365
|
-
"4:3",
|
|
366
|
-
"3:4",
|
|
367
|
-
"4:5",
|
|
368
|
-
"5:4",
|
|
369
|
-
"9:16",
|
|
370
|
-
"16:9",
|
|
371
|
-
"21:9",
|
|
372
|
-
"97:30"
|
|
373
|
-
],
|
|
374
|
-
sizes: ["1K", "2K", "4K"],
|
|
330
|
+
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"],
|
|
331
|
+
sizes: [],
|
|
375
332
|
references: { images: 1 },
|
|
376
333
|
requires: ["references"]
|
|
377
334
|
},
|
|
378
|
-
defaults: {
|
|
335
|
+
defaults: { aspectRatio: "1:1" },
|
|
379
336
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
380
337
|
pricingKind: "image_size"
|
|
381
338
|
},
|
|
382
339
|
{
|
|
340
|
+
// Qwen Image Edit Plus takes aspect_ratio (or match_input_image) and
|
|
341
|
+
// output_format, but no size; no default ratio so edits keep following
|
|
342
|
+
// the input image. https://replicate.com/qwen-edit-apps/qwen-image-edit-plus-lora-skin
|
|
383
343
|
id: "qwen-image-edit-plus-lora-skin",
|
|
384
344
|
aliases: [],
|
|
385
345
|
label: "Qwen Image Edit Plus",
|
|
@@ -388,25 +348,13 @@ var IMAGE_MODELS = [
|
|
|
388
348
|
providerModelId: "qwen-edit-apps/qwen-image-edit-plus-lora-skin",
|
|
389
349
|
lifecycle: "active",
|
|
390
350
|
constraints: {
|
|
391
|
-
aspectRatios: [
|
|
392
|
-
|
|
393
|
-
"2:3",
|
|
394
|
-
"3:2",
|
|
395
|
-
"4:3",
|
|
396
|
-
"3:4",
|
|
397
|
-
"4:5",
|
|
398
|
-
"5:4",
|
|
399
|
-
"9:16",
|
|
400
|
-
"16:9",
|
|
401
|
-
"21:9",
|
|
402
|
-
"97:30"
|
|
403
|
-
],
|
|
404
|
-
sizes: ["1K", "2K", "4K"],
|
|
351
|
+
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4"],
|
|
352
|
+
sizes: [],
|
|
405
353
|
references: { images: 1 },
|
|
406
354
|
requires: ["references"],
|
|
407
355
|
supports: ["outputFormat"]
|
|
408
356
|
},
|
|
409
|
-
defaults: {
|
|
357
|
+
defaults: { outputFormat: "png" },
|
|
410
358
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
411
359
|
pricingKind: "image_size"
|
|
412
360
|
}
|
|
@@ -1823,7 +1771,11 @@ var aiSdkTextAdapter = {
|
|
|
1823
1771
|
function requiredKeys(model, config) {
|
|
1824
1772
|
if (model.adapter === "fal" && config.routing?.fal === "cloudflare-passthrough")
|
|
1825
1773
|
return ["cloudflare"];
|
|
1826
|
-
if (model.adapter === "ai-sdk-text")
|
|
1774
|
+
if (model.adapter === "ai-sdk-text") {
|
|
1775
|
+
const names = [textKeyName(model, config.routing ?? {})];
|
|
1776
|
+
if (config.routing?.text === "cloudflare") names.push("cloudflare");
|
|
1777
|
+
return names;
|
|
1778
|
+
}
|
|
1827
1779
|
return ADAPTER_KEYS[model.adapter];
|
|
1828
1780
|
}
|
|
1829
1781
|
var IMAGE_OUTPUT_TYPES = /* @__PURE__ */ new Set(["image", "upscale", "bg-remove"]);
|
|
@@ -1881,6 +1833,20 @@ function sdkAspectRatio(ratio) {
|
|
|
1881
1833
|
const parsed = sdkRatio.safeParse(ratio);
|
|
1882
1834
|
return parsed.success ? parsed.data : void 0;
|
|
1883
1835
|
}
|
|
1836
|
+
function sdkDataContent(ref) {
|
|
1837
|
+
return "url" in ref ? ref.url : ref.bytes;
|
|
1838
|
+
}
|
|
1839
|
+
function sdkReference(ref) {
|
|
1840
|
+
return "url" in ref ? ref.url : { data: ref.bytes, mediaType: ref.mime };
|
|
1841
|
+
}
|
|
1842
|
+
function pushIgnored(warnings, field, from, modelId) {
|
|
1843
|
+
warnings.push({
|
|
1844
|
+
code: "option_ignored",
|
|
1845
|
+
field,
|
|
1846
|
+
from,
|
|
1847
|
+
message: `${modelId} provider instance does not support ${field}; ignored`
|
|
1848
|
+
});
|
|
1849
|
+
}
|
|
1884
1850
|
function createModelKit(config, adapters) {
|
|
1885
1851
|
const catalog = new Catalog(MODELS).withOverrides(config.catalogOverride ?? []);
|
|
1886
1852
|
const logger = config.logger ?? console;
|
|
@@ -1903,6 +1869,7 @@ function createModelKit(config, adapters) {
|
|
|
1903
1869
|
call,
|
|
1904
1870
|
warnings
|
|
1905
1871
|
};
|
|
1872
|
+
if (config.endpoints) ctx.endpoints = config.endpoints;
|
|
1906
1873
|
if (call.signal) ctx.signal = call.signal;
|
|
1907
1874
|
return { adapter, ctx };
|
|
1908
1875
|
}
|
|
@@ -1942,16 +1909,42 @@ function createModelKit(config, adapters) {
|
|
|
1942
1909
|
};
|
|
1943
1910
|
}
|
|
1944
1911
|
async function passthroughImage(req, call) {
|
|
1945
|
-
const {
|
|
1912
|
+
const {
|
|
1913
|
+
model,
|
|
1914
|
+
prompt,
|
|
1915
|
+
n,
|
|
1916
|
+
count,
|
|
1917
|
+
size,
|
|
1918
|
+
aspectRatio,
|
|
1919
|
+
seed,
|
|
1920
|
+
providerOptions,
|
|
1921
|
+
references,
|
|
1922
|
+
exactSize: exactSizeField,
|
|
1923
|
+
quality: _quality,
|
|
1924
|
+
outputFormat: _outputFormat
|
|
1925
|
+
} = req;
|
|
1946
1926
|
const options = { model, prompt };
|
|
1927
|
+
const warnings = [];
|
|
1947
1928
|
const quantity = n ?? count;
|
|
1948
1929
|
if (quantity !== void 0) options.n = quantity;
|
|
1949
|
-
|
|
1950
|
-
|
|
1930
|
+
if (references !== void 0 && references.length > 0)
|
|
1931
|
+
options.prompt = { images: references.map(sdkDataContent), text: prompt };
|
|
1932
|
+
const exact = exactSizeField === void 0 ? void 0 : exactSize.safeParse(exactSizeField);
|
|
1933
|
+
if (exact?.success) options.size = exact.data;
|
|
1934
|
+
else if (exactSizeField !== void 0)
|
|
1935
|
+
pushIgnored(warnings, "exactSize", exactSizeField, model.modelId);
|
|
1936
|
+
const requested = size === void 0 ? void 0 : exactSize.safeParse(size);
|
|
1937
|
+
if (requested?.success) options.size ??= requested.data;
|
|
1938
|
+
else if (size !== void 0) pushIgnored(warnings, "size", size, model.modelId);
|
|
1951
1939
|
const ratio = sdkAspectRatio(aspectRatio);
|
|
1952
1940
|
if (ratio) options.aspectRatio = ratio;
|
|
1941
|
+
else if (aspectRatio !== void 0)
|
|
1942
|
+
pushIgnored(warnings, "aspectRatio", aspectRatio, model.modelId);
|
|
1953
1943
|
if (seed !== void 0) options.seed = seed;
|
|
1954
1944
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
1945
|
+
if (_quality !== void 0) pushIgnored(warnings, "quality", _quality, model.modelId);
|
|
1946
|
+
if (_outputFormat !== void 0)
|
|
1947
|
+
pushIgnored(warnings, "outputFormat", _outputFormat, model.modelId);
|
|
1955
1948
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
1956
1949
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
1957
1950
|
const result = await aiGenerateImage(options);
|
|
@@ -1966,17 +1959,73 @@ function createModelKit(config, adapters) {
|
|
|
1966
1959
|
quantity: images.length
|
|
1967
1960
|
};
|
|
1968
1961
|
await emit(usage2);
|
|
1969
|
-
return { image: images[0], images, usage: usage2, raw: result, warnings
|
|
1962
|
+
return { image: images[0], images, usage: usage2, raw: result, warnings };
|
|
1970
1963
|
}
|
|
1971
1964
|
function passthroughVideo(req, call) {
|
|
1972
|
-
const {
|
|
1965
|
+
const {
|
|
1966
|
+
model,
|
|
1967
|
+
prompt,
|
|
1968
|
+
aspectRatio,
|
|
1969
|
+
duration,
|
|
1970
|
+
durationSeconds,
|
|
1971
|
+
seed,
|
|
1972
|
+
providerOptions,
|
|
1973
|
+
firstFrame,
|
|
1974
|
+
lastFrame,
|
|
1975
|
+
sourceVideo,
|
|
1976
|
+
referenceImages,
|
|
1977
|
+
referenceVideos,
|
|
1978
|
+
referenceAudios,
|
|
1979
|
+
resolution,
|
|
1980
|
+
generateAudio: generateAudio2,
|
|
1981
|
+
negativePrompt: _negativePrompt,
|
|
1982
|
+
cfgScale: _cfgScale,
|
|
1983
|
+
promptExpansion: _promptExpansion,
|
|
1984
|
+
mode: _mode
|
|
1985
|
+
} = req;
|
|
1973
1986
|
const seconds = duration ?? durationSeconds;
|
|
1974
1987
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
1975
1988
|
const options = { model, prompt };
|
|
1976
|
-
const
|
|
1989
|
+
const warnings = [];
|
|
1990
|
+
const ratio = sdkAspectRatio(aspectRatio) ?? (aspectRatio === "adaptive" ? "adaptive" : void 0);
|
|
1977
1991
|
if (ratio) options.aspectRatio = ratio;
|
|
1992
|
+
else if (aspectRatio !== void 0)
|
|
1993
|
+
pushIgnored(warnings, "aspectRatio", aspectRatio, model.modelId);
|
|
1978
1994
|
if (seconds !== void 0) options.duration = seconds;
|
|
1979
1995
|
if (seed !== void 0) options.seed = seed;
|
|
1996
|
+
if (generateAudio2 !== void 0) options.generateAudio = generateAudio2;
|
|
1997
|
+
const frames = [
|
|
1998
|
+
...firstFrame ? [{ image: sdkDataContent(firstFrame), frameType: "first_frame" }] : [],
|
|
1999
|
+
...lastFrame ? [{ image: sdkDataContent(lastFrame), frameType: "last_frame" }] : []
|
|
2000
|
+
];
|
|
2001
|
+
if (frames.length > 0) options.frameImages = frames;
|
|
2002
|
+
const references = [
|
|
2003
|
+
...(referenceImages ?? []).map(sdkDataContent),
|
|
2004
|
+
...(referenceVideos ?? []).map(sdkReference)
|
|
2005
|
+
];
|
|
2006
|
+
if (references.length > 0) {
|
|
2007
|
+
if (frames.length > 0) {
|
|
2008
|
+
warnings.push({
|
|
2009
|
+
code: "option_ignored",
|
|
2010
|
+
field: "inputReferences",
|
|
2011
|
+
from: references.length,
|
|
2012
|
+
message: `${model.modelId} provider instance ignores references when frames are set`
|
|
2013
|
+
});
|
|
2014
|
+
} else {
|
|
2015
|
+
options.inputReferences = references;
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
if (sourceVideo) pushIgnored(warnings, "sourceVideo", void 0, model.modelId);
|
|
2019
|
+
if (referenceAudios?.length)
|
|
2020
|
+
pushIgnored(warnings, "referenceAudios", referenceAudios.length, model.modelId);
|
|
2021
|
+
if (resolution !== void 0)
|
|
2022
|
+
pushIgnored(warnings, "resolution", resolution, model.modelId);
|
|
2023
|
+
if (_negativePrompt !== void 0)
|
|
2024
|
+
pushIgnored(warnings, "negativePrompt", void 0, model.modelId);
|
|
2025
|
+
if (_cfgScale !== void 0) pushIgnored(warnings, "cfgScale", _cfgScale, model.modelId);
|
|
2026
|
+
if (_promptExpansion !== void 0)
|
|
2027
|
+
pushIgnored(warnings, "promptExpansion", _promptExpansion, model.modelId);
|
|
2028
|
+
if (_mode !== void 0) pushIgnored(warnings, "mode", _mode, model.modelId);
|
|
1980
2029
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
1981
2030
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
1982
2031
|
const pending = aiGenerateVideo(options);
|
|
@@ -2004,7 +2053,7 @@ function createModelKit(config, adapters) {
|
|
|
2004
2053
|
});
|
|
2005
2054
|
return {
|
|
2006
2055
|
jobId: `ai-sdk:${model.provider}:${model.modelId}`,
|
|
2007
|
-
warnings
|
|
2056
|
+
warnings,
|
|
2008
2057
|
async poll() {
|
|
2009
2058
|
if (settled) return { status: "succeeded", raw: settled.raw };
|
|
2010
2059
|
if (failed) return { status: "failed" };
|
|
@@ -2228,6 +2277,9 @@ var SUBMIT_PATH = "/contents/generations/tasks";
|
|
|
2228
2277
|
var SEEDANCE_POLL_INTERVAL_MS = 15e3;
|
|
2229
2278
|
var RESULT_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
2230
2279
|
var VIDEO_URL_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
2280
|
+
function arkBaseUrl(ctx) {
|
|
2281
|
+
return ctx.endpoints?.ark ?? ARK_BASE_URL;
|
|
2282
|
+
}
|
|
2231
2283
|
var SEEDREAM_SIZES = {
|
|
2232
2284
|
"1K": {
|
|
2233
2285
|
"1:1": "1024x1024",
|
|
@@ -2238,7 +2290,8 @@ var SEEDREAM_SIZES = {
|
|
|
2238
2290
|
"3:2": "1248x832",
|
|
2239
2291
|
"2:3": "832x1248",
|
|
2240
2292
|
"21:9": "1568x672",
|
|
2241
|
-
"4:5": "864x1080"
|
|
2293
|
+
"4:5": "864x1080",
|
|
2294
|
+
"5:4": "1080x864"
|
|
2242
2295
|
},
|
|
2243
2296
|
"2K": {
|
|
2244
2297
|
"1:1": "2048x2048",
|
|
@@ -2249,7 +2302,8 @@ var SEEDREAM_SIZES = {
|
|
|
2249
2302
|
"3:2": "2496x1664",
|
|
2250
2303
|
"2:3": "1664x2496",
|
|
2251
2304
|
"21:9": "3136x1344",
|
|
2252
|
-
"4:5": "1728x2160"
|
|
2305
|
+
"4:5": "1728x2160",
|
|
2306
|
+
"5:4": "2160x1728"
|
|
2253
2307
|
}
|
|
2254
2308
|
};
|
|
2255
2309
|
var arkAdapter = {
|
|
@@ -2296,9 +2350,11 @@ function seedreamSize(aspect, size) {
|
|
|
2296
2350
|
const table = SEEDREAM_SIZES[tier];
|
|
2297
2351
|
return table[aspect ?? ""] ?? table["1:1"] ?? "2048x2048";
|
|
2298
2352
|
}
|
|
2299
|
-
function
|
|
2300
|
-
if (
|
|
2301
|
-
|
|
2353
|
+
function sniffedImageMime(bytes) {
|
|
2354
|
+
if (bytes.length >= 4 && bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71)
|
|
2355
|
+
return "image/png";
|
|
2356
|
+
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)
|
|
2357
|
+
return "image/webp";
|
|
2302
2358
|
return "image/jpeg";
|
|
2303
2359
|
}
|
|
2304
2360
|
function arkUrl(ref) {
|
|
@@ -2340,7 +2396,7 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2340
2396
|
else if (refs.length > 1) body.image = refs;
|
|
2341
2397
|
const data = await withRetry(async () => {
|
|
2342
2398
|
const res = await ctx.fetch(
|
|
2343
|
-
`${
|
|
2399
|
+
`${arkBaseUrl(ctx)}/images/generations`,
|
|
2344
2400
|
fetchInitFor(ctx, {
|
|
2345
2401
|
method: "POST",
|
|
2346
2402
|
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
@@ -2379,7 +2435,7 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2379
2435
|
};
|
|
2380
2436
|
if (req.size !== void 0) usage2.imageSize = req.size;
|
|
2381
2437
|
if (req.quality !== void 0) usage2.imageQuality = req.quality;
|
|
2382
|
-
return { images: [{ bytes, mime:
|
|
2438
|
+
return { images: [{ bytes, mime: sniffedImageMime(bytes) }], usage: usage2, raw: data };
|
|
2383
2439
|
}
|
|
2384
2440
|
var SeedanceResponseSchema = z4.object({
|
|
2385
2441
|
id: z4.string().optional(),
|
|
@@ -2467,7 +2523,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2467
2523
|
if (req.seed !== void 0) body.seed = req.seed;
|
|
2468
2524
|
const submit = await withRetry(async () => {
|
|
2469
2525
|
const res = await ctx.fetch(
|
|
2470
|
-
`${
|
|
2526
|
+
`${arkBaseUrl(ctx)}${SUBMIT_PATH}`,
|
|
2471
2527
|
fetchInitFor(ctx, {
|
|
2472
2528
|
method: "POST",
|
|
2473
2529
|
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
@@ -2487,7 +2543,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2487
2543
|
const usage2 = seedanceUsage(ctx, req, duration);
|
|
2488
2544
|
const fetchStatus = async () => {
|
|
2489
2545
|
const res = await ctx.fetch(
|
|
2490
|
-
`${
|
|
2546
|
+
`${arkBaseUrl(ctx)}${SUBMIT_PATH}/${jobId}`,
|
|
2491
2547
|
fetchInitFor(ctx, {
|
|
2492
2548
|
headers: { Authorization: `Bearer ${key}` }
|
|
2493
2549
|
})
|
|
@@ -3548,60 +3604,6 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3548
3604
|
uploadedNames.push(file.fileName);
|
|
3549
3605
|
return file.fileUri;
|
|
3550
3606
|
};
|
|
3551
|
-
const parts = [];
|
|
3552
|
-
if (req.sourceVideo) {
|
|
3553
|
-
const media = await resolveMedia(
|
|
3554
|
-
req.sourceVideo,
|
|
3555
|
-
ctx.fetch,
|
|
3556
|
-
ctx.signal,
|
|
3557
|
-
"video/mp4",
|
|
3558
|
-
modelId
|
|
3559
|
-
);
|
|
3560
|
-
parts.push({
|
|
3561
|
-
type: "video",
|
|
3562
|
-
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3563
|
-
mime_type: media.mime
|
|
3564
|
-
});
|
|
3565
|
-
}
|
|
3566
|
-
for (const ref of videos) {
|
|
3567
|
-
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "video/mp4", modelId);
|
|
3568
|
-
parts.push({
|
|
3569
|
-
type: "video",
|
|
3570
|
-
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3571
|
-
mime_type: media.mime
|
|
3572
|
-
});
|
|
3573
|
-
}
|
|
3574
|
-
if (req.firstFrame) {
|
|
3575
|
-
const media = await resolveMedia(
|
|
3576
|
-
req.firstFrame,
|
|
3577
|
-
ctx.fetch,
|
|
3578
|
-
ctx.signal,
|
|
3579
|
-
"image/png",
|
|
3580
|
-
modelId
|
|
3581
|
-
);
|
|
3582
|
-
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3583
|
-
parts.push({
|
|
3584
|
-
type: "image",
|
|
3585
|
-
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3586
|
-
mime_type: media.mime
|
|
3587
|
-
});
|
|
3588
|
-
} else {
|
|
3589
|
-
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3590
|
-
}
|
|
3591
|
-
}
|
|
3592
|
-
for (const ref of images) {
|
|
3593
|
-
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "image/png", modelId);
|
|
3594
|
-
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3595
|
-
parts.push({
|
|
3596
|
-
type: "image",
|
|
3597
|
-
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3598
|
-
mime_type: media.mime
|
|
3599
|
-
});
|
|
3600
|
-
} else {
|
|
3601
|
-
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3602
|
-
}
|
|
3603
|
-
}
|
|
3604
|
-
parts.push({ type: "text", text: req.prompt });
|
|
3605
3607
|
const cleanupUploads = async () => {
|
|
3606
3608
|
for (const fileName of uploadedNames) await deleteGoogleFile(fileName, apiKey, ctx.fetch);
|
|
3607
3609
|
};
|
|
@@ -3615,6 +3617,60 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3615
3617
|
if (ctx.signal !== void 0) createRetryOptions.signal = ctx.signal;
|
|
3616
3618
|
let interaction;
|
|
3617
3619
|
try {
|
|
3620
|
+
const parts = [];
|
|
3621
|
+
if (req.sourceVideo) {
|
|
3622
|
+
const media = await resolveMedia(
|
|
3623
|
+
req.sourceVideo,
|
|
3624
|
+
ctx.fetch,
|
|
3625
|
+
ctx.signal,
|
|
3626
|
+
"video/mp4",
|
|
3627
|
+
modelId
|
|
3628
|
+
);
|
|
3629
|
+
parts.push({
|
|
3630
|
+
type: "video",
|
|
3631
|
+
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3632
|
+
mime_type: media.mime
|
|
3633
|
+
});
|
|
3634
|
+
}
|
|
3635
|
+
for (const ref of videos) {
|
|
3636
|
+
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "video/mp4", modelId);
|
|
3637
|
+
parts.push({
|
|
3638
|
+
type: "video",
|
|
3639
|
+
uri: await uploadOne("video", media.bytes, media.mime),
|
|
3640
|
+
mime_type: media.mime
|
|
3641
|
+
});
|
|
3642
|
+
}
|
|
3643
|
+
if (req.firstFrame) {
|
|
3644
|
+
const media = await resolveMedia(
|
|
3645
|
+
req.firstFrame,
|
|
3646
|
+
ctx.fetch,
|
|
3647
|
+
ctx.signal,
|
|
3648
|
+
"image/png",
|
|
3649
|
+
modelId
|
|
3650
|
+
);
|
|
3651
|
+
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3652
|
+
parts.push({
|
|
3653
|
+
type: "image",
|
|
3654
|
+
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3655
|
+
mime_type: media.mime
|
|
3656
|
+
});
|
|
3657
|
+
} else {
|
|
3658
|
+
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
for (const ref of images) {
|
|
3662
|
+
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "image/png", modelId);
|
|
3663
|
+
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3664
|
+
parts.push({
|
|
3665
|
+
type: "image",
|
|
3666
|
+
uri: await uploadOne("image", media.bytes, media.mime),
|
|
3667
|
+
mime_type: media.mime
|
|
3668
|
+
});
|
|
3669
|
+
} else {
|
|
3670
|
+
parts.push({ type: "image", data: toBase64(media.bytes), mime_type: media.mime });
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
parts.push({ type: "text", text: req.prompt });
|
|
3618
3674
|
try {
|
|
3619
3675
|
interaction = await withRetry(async () => {
|
|
3620
3676
|
try {
|
|
@@ -4680,7 +4736,8 @@ var RATIO_TO_DIMS = {
|
|
|
4680
4736
|
"9:16": { width: 768, height: 1360 },
|
|
4681
4737
|
"3:4": { width: 768, height: 1024 },
|
|
4682
4738
|
"2:3": { width: 768, height: 1152 },
|
|
4683
|
-
"4:5": { width: 896, height: 1120 }
|
|
4739
|
+
"4:5": { width: 896, height: 1120 },
|
|
4740
|
+
"5:4": { width: 1120, height: 896 }
|
|
4684
4741
|
};
|
|
4685
4742
|
function dimsFor(aspectRatio) {
|
|
4686
4743
|
if (aspectRatio !== void 0) {
|
|
@@ -4689,6 +4746,27 @@ function dimsFor(aspectRatio) {
|
|
|
4689
4746
|
}
|
|
4690
4747
|
return { width: 1024, height: 1024 };
|
|
4691
4748
|
}
|
|
4749
|
+
var GEMINI_JOB_RATIOS = /* @__PURE__ */ new Set([
|
|
4750
|
+
"1:1",
|
|
4751
|
+
"2:3",
|
|
4752
|
+
"3:2",
|
|
4753
|
+
"3:4",
|
|
4754
|
+
"4:3",
|
|
4755
|
+
"4:5",
|
|
4756
|
+
"5:4",
|
|
4757
|
+
"9:16",
|
|
4758
|
+
"16:9",
|
|
4759
|
+
"21:9"
|
|
4760
|
+
]);
|
|
4761
|
+
var NANO_BANANA_RATIOS = /* @__PURE__ */ new Set([
|
|
4762
|
+
"1:1",
|
|
4763
|
+
"2:3",
|
|
4764
|
+
"3:4",
|
|
4765
|
+
"4:3",
|
|
4766
|
+
"9:16",
|
|
4767
|
+
"16:9",
|
|
4768
|
+
"21:9"
|
|
4769
|
+
]);
|
|
4692
4770
|
async function refToBytes(ctx, ref) {
|
|
4693
4771
|
if ("bytes" in ref) return { bytes: ref.bytes, mime: ref.mime };
|
|
4694
4772
|
const res = await ctx.fetch(ref.url);
|
|
@@ -4788,7 +4866,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4788
4866
|
inputs = refs.length > 0 && firstRef !== void 0 ? [firstRef] : [];
|
|
4789
4867
|
accept = req.outputFormat === "png" ? "image/png" : "image/jpeg";
|
|
4790
4868
|
mime = accept;
|
|
4791
|
-
} else if (providerModelId === "flux-2-pro" || providerModelId === FLUX_2_PRO_JOB
|
|
4869
|
+
} else if (providerModelId === "flux-2-pro" || providerModelId === FLUX_2_PRO_JOB) {
|
|
4792
4870
|
const dims = dimsFor(req.aspectRatio);
|
|
4793
4871
|
const config = {
|
|
4794
4872
|
prompt: req.prompt,
|
|
@@ -4797,8 +4875,30 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4797
4875
|
safety_tolerance: 5
|
|
4798
4876
|
};
|
|
4799
4877
|
if (req.seed !== void 0) config.seed = req.seed;
|
|
4800
|
-
|
|
4801
|
-
|
|
4878
|
+
job = { type: FLUX_2_PRO_JOB, config };
|
|
4879
|
+
inputs = refs;
|
|
4880
|
+
accept = "image/png";
|
|
4881
|
+
mime = "image/png";
|
|
4882
|
+
} else if (providerModelId === "inference.gemini-3-pro.img2img.v1" || providerModelId === "inference.nano-banana.img2img.v2") {
|
|
4883
|
+
const allowed = providerModelId === "inference.nano-banana.img2img.v2" ? NANO_BANANA_RATIOS : GEMINI_JOB_RATIOS;
|
|
4884
|
+
const config = {
|
|
4885
|
+
prompt: req.prompt,
|
|
4886
|
+
safety_tolerance: 5
|
|
4887
|
+
};
|
|
4888
|
+
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
4889
|
+
if (allowed.has(req.aspectRatio)) config.aspect_ratio = req.aspectRatio;
|
|
4890
|
+
else
|
|
4891
|
+
ctx.warnings.push({
|
|
4892
|
+
code: "option_ignored",
|
|
4893
|
+
field: "aspectRatio",
|
|
4894
|
+
from: req.aspectRatio,
|
|
4895
|
+
message: `${providerModelId} has no ${req.aspectRatio} aspect_ratio; using the provider default`
|
|
4896
|
+
});
|
|
4897
|
+
}
|
|
4898
|
+
if (providerModelId === "inference.gemini-3-pro.img2img.v1")
|
|
4899
|
+
config.resolution = req.size ?? "1K";
|
|
4900
|
+
if (req.seed !== void 0) config.seed = req.seed;
|
|
4901
|
+
job = { type: providerModelId, config };
|
|
4802
4902
|
inputs = refs;
|
|
4803
4903
|
accept = "image/png";
|
|
4804
4904
|
mime = "image/png";
|
|
@@ -5072,6 +5172,50 @@ function isUpscaler(providerModelId) {
|
|
|
5072
5172
|
function isQwen(providerModelId) {
|
|
5073
5173
|
return isLower(providerModelId).includes("qwen");
|
|
5074
5174
|
}
|
|
5175
|
+
function isWanImage(providerModelId) {
|
|
5176
|
+
return isLower(providerModelId).includes("wan-2.7");
|
|
5177
|
+
}
|
|
5178
|
+
function isQwenEditPlus(providerModelId) {
|
|
5179
|
+
return isLower(providerModelId).includes("edit");
|
|
5180
|
+
}
|
|
5181
|
+
var QWEN_IMAGE_RATIOS = /* @__PURE__ */ new Set([
|
|
5182
|
+
"1:1",
|
|
5183
|
+
"16:9",
|
|
5184
|
+
"9:16",
|
|
5185
|
+
"4:3",
|
|
5186
|
+
"3:4",
|
|
5187
|
+
"3:2",
|
|
5188
|
+
"2:3"
|
|
5189
|
+
]);
|
|
5190
|
+
var QWEN_EDIT_RATIOS = /* @__PURE__ */ new Set(["1:1", "16:9", "9:16", "4:3", "3:4"]);
|
|
5191
|
+
var WAN_IMAGE_SIZES = {
|
|
5192
|
+
"1K": {
|
|
5193
|
+
"1:1": "1024*1024",
|
|
5194
|
+
"16:9": "1280*720",
|
|
5195
|
+
"9:16": "720*1280",
|
|
5196
|
+
"4:3": "1024*768",
|
|
5197
|
+
"3:4": "768*1024"
|
|
5198
|
+
},
|
|
5199
|
+
"2K": {
|
|
5200
|
+
"1:1": "2048*2048",
|
|
5201
|
+
"16:9": "2048*1152",
|
|
5202
|
+
"9:16": "1152*2048",
|
|
5203
|
+
"4:3": "2048*1536",
|
|
5204
|
+
"3:4": "1536*2048"
|
|
5205
|
+
},
|
|
5206
|
+
"4K": {
|
|
5207
|
+
"1:1": "4096*4096",
|
|
5208
|
+
"16:9": "4096*2304",
|
|
5209
|
+
"9:16": "2304*4096",
|
|
5210
|
+
"4:3": "4096*3072",
|
|
5211
|
+
"3:4": "3072*4096"
|
|
5212
|
+
}
|
|
5213
|
+
};
|
|
5214
|
+
function wanImageSize(aspectRatio, size) {
|
|
5215
|
+
const tier = size === "2K" || size === "4K" ? size : "1K";
|
|
5216
|
+
const table = WAN_IMAGE_SIZES[tier];
|
|
5217
|
+
return table[aspectRatio ?? ""] ?? table["1:1"] ?? "1024*1024";
|
|
5218
|
+
}
|
|
5075
5219
|
async function generateReplicateImage(req, ctx, deps) {
|
|
5076
5220
|
const id = ctx.model.providerModelId;
|
|
5077
5221
|
const input = { prompt: req.prompt };
|
|
@@ -5091,14 +5235,31 @@ async function generateReplicateImage(req, ctx, deps) {
|
|
|
5091
5235
|
input.creativity = 0;
|
|
5092
5236
|
input.scale_factor = 2;
|
|
5093
5237
|
input.output_format = "png";
|
|
5238
|
+
} else if (isWanImage(id)) {
|
|
5239
|
+
const refs = (req.references ?? []).map(refToUrl3);
|
|
5240
|
+
if (refs.length > 0) input.images = refs;
|
|
5241
|
+
input.size = wanImageSize(req.aspectRatio, req.size);
|
|
5094
5242
|
} else if (isQwen(id)) {
|
|
5095
5243
|
const refs = (req.references ?? []).map(refToUrl3);
|
|
5096
5244
|
const firstUrl = refs[0];
|
|
5097
5245
|
if (firstUrl !== void 0) {
|
|
5098
5246
|
input.image = firstUrl;
|
|
5099
|
-
input.match_input_image = true;
|
|
5247
|
+
if (!isQwenEditPlus(id)) input.match_input_image = true;
|
|
5248
|
+
}
|
|
5249
|
+
const ratios = isQwenEditPlus(id) ? QWEN_EDIT_RATIOS : QWEN_IMAGE_RATIOS;
|
|
5250
|
+
if (req.aspectRatio !== void 0) {
|
|
5251
|
+
if (ratios.has(req.aspectRatio)) input.aspect_ratio = req.aspectRatio;
|
|
5252
|
+
else
|
|
5253
|
+
ctx.warnings.push({
|
|
5254
|
+
code: "option_ignored",
|
|
5255
|
+
field: "aspectRatio",
|
|
5256
|
+
from: req.aspectRatio,
|
|
5257
|
+
message: `${id} has no ${req.aspectRatio} aspect_ratio; using the provider default`
|
|
5258
|
+
});
|
|
5259
|
+
}
|
|
5260
|
+
if (isQwenEditPlus(id) && req.outputFormat !== void 0) {
|
|
5261
|
+
input.output_format = req.outputFormat === "jpeg" ? "jpg" : req.outputFormat;
|
|
5100
5262
|
}
|
|
5101
|
-
if (req.outputFormat !== void 0) input.output_format = req.outputFormat;
|
|
5102
5263
|
} else {
|
|
5103
5264
|
const refs = req.references ?? [];
|
|
5104
5265
|
const first = refs[0];
|