@shop-os/modelkit 0.1.0 → 0.1.2
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 +5 -0
- package/dist/index.cjs +172 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +172 -114
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -14,7 +14,8 @@ type VideoModel = Parameters<typeof experimental_generateVideo>[0]["model"];
|
|
|
14
14
|
type AspectRatio = "1:1" | "16:9" | "9:16" | "4:3" | "3:4" | "3:2" | "2:3" | "4:5" | "5:4" | "21:9" | "9:21" | "97:30" | "adaptive";
|
|
15
15
|
type ImageSize = "1K" | "2K" | "4K";
|
|
16
16
|
type VideoResolution = "360p" | "480p" | "720p" | "768p" | "1080p" | "2k" | "4k";
|
|
17
|
-
|
|
17
|
+
/** "xhigh" and "max" exist only on gpt-image-2.5; gpt-image-2 rejects them at the provider. */
|
|
18
|
+
type ImageQuality = "auto" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
18
19
|
type OutputFormat = "png" | "jpeg" | "webp";
|
|
19
20
|
type MediaRef = {
|
|
20
21
|
url: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,8 @@ type VideoModel = Parameters<typeof experimental_generateVideo>[0]["model"];
|
|
|
14
14
|
type AspectRatio = "1:1" | "16:9" | "9:16" | "4:3" | "3:4" | "3:2" | "2:3" | "4:5" | "5:4" | "21:9" | "9:21" | "97:30" | "adaptive";
|
|
15
15
|
type ImageSize = "1K" | "2K" | "4K";
|
|
16
16
|
type VideoResolution = "360p" | "480p" | "720p" | "768p" | "1080p" | "2k" | "4k";
|
|
17
|
-
|
|
17
|
+
/** "xhigh" and "max" exist only on gpt-image-2.5; gpt-image-2 rejects them at the provider. */
|
|
18
|
+
type ImageQuality = "auto" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
18
19
|
type OutputFormat = "png" | "jpeg" | "webp";
|
|
19
20
|
type MediaRef = {
|
|
20
21
|
url: string;
|
package/dist/index.js
CHANGED
|
@@ -130,6 +130,44 @@ var IMAGE_MODELS = [
|
|
|
130
130
|
usage: { ...IMAGE_USAGE },
|
|
131
131
|
pricingKind: "image_size"
|
|
132
132
|
},
|
|
133
|
+
{
|
|
134
|
+
// Same Images API surface as gpt-image-2 plus the "xhigh" and "max" quality tiers.
|
|
135
|
+
id: "gpt-image-2.5-sunburst",
|
|
136
|
+
aliases: [],
|
|
137
|
+
label: "GPT Image 2.5 Sunburst",
|
|
138
|
+
type: "image",
|
|
139
|
+
adapter: "openai-image",
|
|
140
|
+
providerModelId: "gpt-image-2.5-sunburst",
|
|
141
|
+
lifecycle: "active",
|
|
142
|
+
constraints: {
|
|
143
|
+
aspectRatios: ["1:1", "3:2", "2:3", "16:9", "9:16", "4:5", "5:4", "adaptive"],
|
|
144
|
+
sizes: ["1K", "2K", "4K"],
|
|
145
|
+
references: { images: 16 },
|
|
146
|
+
supports: ["quality", "count"]
|
|
147
|
+
},
|
|
148
|
+
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
149
|
+
usage: { ...IMAGE_USAGE },
|
|
150
|
+
pricingKind: "image_size"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
// Same Images API surface as gpt-image-2 plus the "xhigh" and "max" quality tiers.
|
|
154
|
+
id: "gpt-image-2.5-flare",
|
|
155
|
+
aliases: [],
|
|
156
|
+
label: "GPT Image 2.5 Flare",
|
|
157
|
+
type: "image",
|
|
158
|
+
adapter: "openai-image",
|
|
159
|
+
providerModelId: "gpt-image-2.5-flare",
|
|
160
|
+
lifecycle: "active",
|
|
161
|
+
constraints: {
|
|
162
|
+
aspectRatios: ["1:1", "3:2", "2:3", "16:9", "9:16", "4:5", "5:4", "adaptive"],
|
|
163
|
+
sizes: ["1K", "2K", "4K"],
|
|
164
|
+
references: { images: 16 },
|
|
165
|
+
supports: ["quality", "count"]
|
|
166
|
+
},
|
|
167
|
+
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
168
|
+
usage: { ...IMAGE_USAGE },
|
|
169
|
+
pricingKind: "image_size"
|
|
170
|
+
},
|
|
133
171
|
{
|
|
134
172
|
// Cowork allows 7 ratios; trigger-workflows allows 9 (adds 3:2, 9:21, drops 4:5/5:4).
|
|
135
173
|
id: "muse-image-1.0",
|
|
@@ -506,77 +544,42 @@ function text(id, label, providerModelId, extra) {
|
|
|
506
544
|
...extra
|
|
507
545
|
};
|
|
508
546
|
}
|
|
509
|
-
var ANTHROPIC_THINKING = {
|
|
510
|
-
anthropic: {
|
|
511
|
-
thinking: { type: "enabled", budgetTokens: 4e3 },
|
|
512
|
-
sendReasoning: true
|
|
513
|
-
}
|
|
514
|
-
};
|
|
515
|
-
var ANTHROPIC_ADAPTIVE = {
|
|
516
|
-
anthropic: {
|
|
517
|
-
thinking: { type: "adaptive", display: "summarized" },
|
|
518
|
-
sendReasoning: true
|
|
519
|
-
}
|
|
520
|
-
};
|
|
521
|
-
var OPENAI_REASONING = {
|
|
522
|
-
openai: {
|
|
523
|
-
reasoningEffort: "medium",
|
|
524
|
-
reasoningSummary: "auto"
|
|
525
|
-
}
|
|
526
|
-
};
|
|
527
|
-
var DEEPSEEK_THINKING = {
|
|
528
|
-
deepseek: {
|
|
529
|
-
thinking: { type: "enabled" }
|
|
530
|
-
}
|
|
531
|
-
};
|
|
532
547
|
var TEXT_MODELS = [
|
|
533
548
|
text("gpt-4o", "GPT-4o", "gpt-4o"),
|
|
534
549
|
text("gpt-4o-mini", "GPT-4o mini", "gpt-4o-mini"),
|
|
535
550
|
text("gpt-5.1", "GPT-5.1", "gpt-5.1"),
|
|
536
|
-
text("gpt-5.1-mini", "GPT-5.1 mini", "gpt-5.1-mini"),
|
|
537
551
|
text("gpt-5.2", "GPT-5.2", "gpt-5.2"),
|
|
538
|
-
text("gpt-5.2-mini", "GPT-5.2 mini", "gpt-5.2-mini"),
|
|
539
552
|
text("gpt-5.4", "GPT-5.4", "gpt-5.4"),
|
|
540
|
-
|
|
541
|
-
text("gpt-5.
|
|
542
|
-
|
|
543
|
-
providerOptions: { ...OPENAI_REASONING }
|
|
544
|
-
}),
|
|
545
|
-
text("gpt-5.6-terra", "GPT-5.6 Terra", "gpt-5.6-terra", {
|
|
546
|
-
providerOptions: { ...OPENAI_REASONING }
|
|
547
|
-
}),
|
|
548
|
-
text("gpt-5.6-sol", "GPT-5.6 Sol", "gpt-5.6-sol", {
|
|
549
|
-
providerOptions: { ...OPENAI_REASONING }
|
|
550
|
-
}),
|
|
551
|
-
// Dated 4.0 ids are what vibe-api, pro-admin and the TW geo agents still send.
|
|
552
|
-
text("claude-sonnet-4", "Claude Sonnet 4", "claude-sonnet-4-20250514", {
|
|
553
|
-
aliases: ["claude-sonnet-4.0", "claude-sonnet-4-20250514"]
|
|
554
|
-
}),
|
|
555
|
-
text("claude-opus-4", "Claude Opus 4", "claude-opus-4-20250514", {
|
|
556
|
-
aliases: ["claude-opus-4.0", "claude-opus-4-20250514"]
|
|
553
|
+
// OpenAI never shipped gpt-5.1-mini or gpt-5.2-mini; callers that still send them get 5.4 mini.
|
|
554
|
+
text("gpt-5.4-mini", "GPT-5.4 mini", "gpt-5.4-mini", {
|
|
555
|
+
aliases: ["gpt-5.1-mini", "gpt-5.2-mini"]
|
|
557
556
|
}),
|
|
557
|
+
text("gpt-5.5", "GPT-5.5", "gpt-5.5"),
|
|
558
|
+
text("gpt-5.6-luna", "GPT-5.6 Luna", "gpt-5.6-luna"),
|
|
559
|
+
text("gpt-5.6-terra", "GPT-5.6 Terra", "gpt-5.6-terra"),
|
|
560
|
+
text("gpt-5.6-sol", "GPT-5.6 Sol", "gpt-5.6-sol"),
|
|
558
561
|
// Library key "claude-sonnet-4.5" maps to the SDK id "claude-sonnet-4-5".
|
|
559
562
|
text("claude-sonnet-4-5", "Claude Sonnet 4.5", "claude-sonnet-4-5", {
|
|
560
563
|
aliases: ["claude-sonnet-4.5"]
|
|
561
564
|
}),
|
|
565
|
+
// Anthropic retired the dated 4.0 ids; callers that still send them get 4.6.
|
|
562
566
|
text("claude-sonnet-4-6", "Claude Sonnet 4.6", "claude-sonnet-4-6", {
|
|
563
|
-
aliases: [
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
567
|
+
aliases: [
|
|
568
|
+
"claude-sonnet-4.6",
|
|
569
|
+
"claude-sonnet-4",
|
|
570
|
+
"claude-sonnet-4.0",
|
|
571
|
+
"claude-sonnet-4-20250514"
|
|
572
|
+
]
|
|
568
573
|
}),
|
|
574
|
+
text("claude-sonnet-5", "Claude Sonnet 5", "claude-sonnet-5"),
|
|
569
575
|
text("claude-opus-4-8", "Claude Opus 4.8", "claude-opus-4-8", {
|
|
570
|
-
aliases: ["claude-opus-4.8"]
|
|
571
|
-
providerOptions: { ...ANTHROPIC_ADAPTIVE }
|
|
576
|
+
aliases: ["claude-opus-4.8", "claude-opus-4", "claude-opus-4.0", "claude-opus-4-20250514"]
|
|
572
577
|
}),
|
|
573
578
|
text("claude-haiku-4-5", "Claude Haiku 4.5", "claude-haiku-4-5", {
|
|
574
|
-
aliases: ["claude-haiku-4.5", "claude-haiku-4-5-20251001"]
|
|
575
|
-
providerOptions: { ...ANTHROPIC_THINKING }
|
|
579
|
+
aliases: ["claude-haiku-4.5", "claude-haiku-4-5-20251001"]
|
|
576
580
|
}),
|
|
577
581
|
text("claude-opus-5", "Claude Opus 5", "claude-opus-5", {
|
|
578
|
-
aliases: ["claude-opus-5.0"]
|
|
579
|
-
providerOptions: { ...ANTHROPIC_ADAPTIVE }
|
|
582
|
+
aliases: ["claude-opus-5.0"]
|
|
580
583
|
}),
|
|
581
584
|
text("claude-fable-5", "Claude Fable 5", "claude-fable-5"),
|
|
582
585
|
text("gemini-2.5-flash", "Gemini 2.5 Flash", "gemini-2.5-flash"),
|
|
@@ -595,12 +598,8 @@ var TEXT_MODELS = [
|
|
|
595
598
|
text("sonar", "Sonar", "sonar"),
|
|
596
599
|
text("sonar-pro", "Sonar Pro", "sonar-pro"),
|
|
597
600
|
text("sonar-reasoning-pro", "Sonar Reasoning Pro", "sonar-reasoning-pro"),
|
|
598
|
-
text("deepseek-v4-flash", "DeepSeek V4 Flash", "deepseek-v4-flash",
|
|
599
|
-
|
|
600
|
-
}),
|
|
601
|
-
text("deepseek-v4-pro", "DeepSeek V4 Pro", "deepseek-v4-pro", {
|
|
602
|
-
providerOptions: { ...DEEPSEEK_THINKING }
|
|
603
|
-
}),
|
|
601
|
+
text("deepseek-v4-flash", "DeepSeek V4 Flash", "deepseek-v4-flash"),
|
|
602
|
+
text("deepseek-v4-pro", "DeepSeek V4 Pro", "deepseek-v4-pro"),
|
|
604
603
|
text("grok-4.3", "Grok 4.3", "grok-4.3"),
|
|
605
604
|
text("kimi-k2.5", "Kimi K2.5", "kimi-k2.5"),
|
|
606
605
|
text("kimi-k3", "Kimi K3", "kimi-k3"),
|
|
@@ -745,7 +744,7 @@ var VIDEO_MODELS = [
|
|
|
745
744
|
durations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
746
745
|
references: { images: 9, videos: 3, audios: 3, audioOnly: false },
|
|
747
746
|
ratioIgnoredWith: ["firstFrame"],
|
|
748
|
-
supports: ["generateAudio", "seed"]
|
|
747
|
+
supports: ["generateAudio", "seed", "lastFrame"]
|
|
749
748
|
},
|
|
750
749
|
defaults: {
|
|
751
750
|
durationSeconds: 5,
|
|
@@ -770,7 +769,7 @@ var VIDEO_MODELS = [
|
|
|
770
769
|
durations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
771
770
|
references: { images: 9, videos: 3, audios: 3, audioOnly: false },
|
|
772
771
|
ratioIgnoredWith: ["firstFrame"],
|
|
773
|
-
supports: ["generateAudio", "seed"]
|
|
772
|
+
supports: ["generateAudio", "seed", "lastFrame"]
|
|
774
773
|
},
|
|
775
774
|
defaults: {
|
|
776
775
|
durationSeconds: 5,
|
|
@@ -796,7 +795,7 @@ var VIDEO_MODELS = [
|
|
|
796
795
|
durations: { min: 4, max: 30 },
|
|
797
796
|
references: { images: 30, videos: 10, audios: 10 },
|
|
798
797
|
ratioIgnoredWith: ["firstFrame"],
|
|
799
|
-
supports: ["generateAudio", "seed"]
|
|
798
|
+
supports: ["generateAudio", "seed", "lastFrame"]
|
|
800
799
|
},
|
|
801
800
|
defaults: {
|
|
802
801
|
durationSeconds: 5,
|
|
@@ -898,7 +897,7 @@ var VIDEO_MODELS = [
|
|
|
898
897
|
resolutions: ["720p", "1080p"],
|
|
899
898
|
durations: { min: 3, max: 15 },
|
|
900
899
|
references: { images: 7 },
|
|
901
|
-
supports: ["generateAudio"]
|
|
900
|
+
supports: ["generateAudio", "lastFrame"]
|
|
902
901
|
},
|
|
903
902
|
defaults: { durationSeconds: 5, aspectRatio: "16:9", generateAudio: false, mode: "pro" },
|
|
904
903
|
usage: { unit: "compute_seconds", modality: "VIDEO" },
|
|
@@ -1431,23 +1430,46 @@ async function withRetry(fn, opts = {}) {
|
|
|
1431
1430
|
}
|
|
1432
1431
|
function sleep(ms, signal) {
|
|
1433
1432
|
return new Promise((resolve, reject) => {
|
|
1434
|
-
const
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1433
|
+
const rejectAborted = () => {
|
|
1434
|
+
reject(new ModelKitError({ code: "timeout", message: "aborted", retryable: false }));
|
|
1435
|
+
};
|
|
1436
|
+
if (signal?.aborted) {
|
|
1437
|
+
rejectAborted();
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
let timer;
|
|
1441
|
+
const onAbort = () => {
|
|
1442
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
1443
|
+
rejectAborted();
|
|
1444
|
+
};
|
|
1445
|
+
timer = setTimeout(() => {
|
|
1446
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1447
|
+
resolve();
|
|
1448
|
+
}, ms);
|
|
1449
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1445
1450
|
});
|
|
1446
1451
|
}
|
|
1452
|
+
function throwAborted() {
|
|
1453
|
+
return new ModelKitError({ code: "timeout", message: "aborted", retryable: false });
|
|
1454
|
+
}
|
|
1455
|
+
function transportError(provider, cause, model) {
|
|
1456
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
1457
|
+
const aborted = cause instanceof Error && cause.name === "AbortError";
|
|
1458
|
+
const init = {
|
|
1459
|
+
code: aborted ? "timeout" : "network",
|
|
1460
|
+
message: `${provider} request failed before a response: ${message}`,
|
|
1461
|
+
provider,
|
|
1462
|
+
retryable: !aborted,
|
|
1463
|
+
cause
|
|
1464
|
+
};
|
|
1465
|
+
if (model !== void 0) init.model = model;
|
|
1466
|
+
return new ModelKitError(init);
|
|
1467
|
+
}
|
|
1447
1468
|
async function pollUntil(check, opts) {
|
|
1448
1469
|
const start = Date.now();
|
|
1449
1470
|
let interval = opts.intervalMs;
|
|
1450
1471
|
for (; ; ) {
|
|
1472
|
+
if (opts.signal?.aborted) throw throwAborted();
|
|
1451
1473
|
const value = await check();
|
|
1452
1474
|
if (value !== void 0) return value;
|
|
1453
1475
|
if (Date.now() - start > opts.timeoutMs)
|
|
@@ -1456,6 +1478,7 @@ async function pollUntil(check, opts) {
|
|
|
1456
1478
|
message: `poll timed out after ${opts.timeoutMs}ms`,
|
|
1457
1479
|
retryable: false
|
|
1458
1480
|
});
|
|
1481
|
+
if (opts.signal?.aborted) throw throwAborted();
|
|
1459
1482
|
await sleep(interval, opts.signal);
|
|
1460
1483
|
if (opts.backoff)
|
|
1461
1484
|
interval = Math.min(opts.maxIntervalMs ?? interval * 4, interval * opts.backoff);
|
|
@@ -1640,7 +1663,7 @@ var OPENAI_COMPATIBLE_BASE_URLS = {
|
|
|
1640
1663
|
var GATEWAY_SLUGS = {
|
|
1641
1664
|
openai: "openai",
|
|
1642
1665
|
anthropic: "anthropic",
|
|
1643
|
-
google: "google-ai-studio",
|
|
1666
|
+
google: "google-ai-studio/v1beta",
|
|
1644
1667
|
xai: "grok",
|
|
1645
1668
|
perplexity: "perplexity-ai",
|
|
1646
1669
|
deepseek: "deepseek"
|
|
@@ -2066,13 +2089,21 @@ function createModelKit(config, adapters) {
|
|
|
2066
2089
|
});
|
|
2067
2090
|
const job = await adapter.generateVideo(request, ctx);
|
|
2068
2091
|
const result = job.result.bind(job);
|
|
2092
|
+
let settled;
|
|
2069
2093
|
return {
|
|
2070
2094
|
...job,
|
|
2071
2095
|
warnings,
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2096
|
+
result(opts) {
|
|
2097
|
+
if (settled) return settled;
|
|
2098
|
+
const pending = result(opts).then(
|
|
2099
|
+
(out) => emit({ ...out.usage, model: model.id }).then(() => out),
|
|
2100
|
+
(cause) => {
|
|
2101
|
+
settled = void 0;
|
|
2102
|
+
throw cause;
|
|
2103
|
+
}
|
|
2104
|
+
);
|
|
2105
|
+
settled = pending;
|
|
2106
|
+
return pending;
|
|
2076
2107
|
}
|
|
2077
2108
|
};
|
|
2078
2109
|
},
|
|
@@ -2433,6 +2464,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2433
2464
|
};
|
|
2434
2465
|
if (!hasFrameAnchor && req.aspectRatio !== void 0) body.ratio = req.aspectRatio;
|
|
2435
2466
|
if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
|
|
2467
|
+
if (req.seed !== void 0) body.seed = req.seed;
|
|
2436
2468
|
const submit = await withRetry(async () => {
|
|
2437
2469
|
const res = await ctx.fetch(
|
|
2438
2470
|
`${ARK_BASE_URL}${SUBMIT_PATH}`,
|
|
@@ -2886,7 +2918,7 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
2886
2918
|
if (isKling(providerModelId)) {
|
|
2887
2919
|
const input = klingO1Input(req);
|
|
2888
2920
|
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
2889
|
-
return passthroughVideoJob(ctx, req, KLING_O1_ENDPOINT, input);
|
|
2921
|
+
return await passthroughVideoJob(ctx, req, KLING_O1_ENDPOINT, input);
|
|
2890
2922
|
}
|
|
2891
2923
|
const result2 = await runJob(ctx, deps, KLING_O1_ENDPOINT, input);
|
|
2892
2924
|
return completedVideoJob(
|
|
@@ -2921,7 +2953,7 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
2921
2953
|
base.aspect_ratio = req.aspectRatio ?? "adaptive";
|
|
2922
2954
|
}
|
|
2923
2955
|
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
2924
|
-
return passthroughVideoJob(ctx, req, endpoint, base);
|
|
2956
|
+
return await passthroughVideoJob(ctx, req, endpoint, base);
|
|
2925
2957
|
}
|
|
2926
2958
|
const result = await runJob(ctx, deps, endpoint, base);
|
|
2927
2959
|
return completedVideoJob(ctx, req, extractVideoUrl(result, endpoint, ctx.model.id), result);
|
|
@@ -2939,31 +2971,26 @@ function completedVideoJob(ctx, req, url, raw) {
|
|
|
2939
2971
|
}
|
|
2940
2972
|
};
|
|
2941
2973
|
}
|
|
2942
|
-
function passthroughVideoJob(ctx, req, endpoint, input) {
|
|
2974
|
+
async function passthroughVideoJob(ctx, req, endpoint, input) {
|
|
2943
2975
|
const cfg = gatewayConfig(ctx);
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2976
|
+
const res = await gatewayFetch(cfg, ctx.fetch, `${FAL_QUEUE_HOST}/${endpoint}`, {
|
|
2977
|
+
method: "POST",
|
|
2978
|
+
body: JSON.stringify({ ...input, sync_mode: true })
|
|
2979
|
+
});
|
|
2980
|
+
if (!res.ok) throw falError(res.status, await readBody(res), ctx.model.id);
|
|
2981
|
+
const parsed = falQueueSubmitSchema.safeParse(await res.json());
|
|
2982
|
+
if (!parsed.success) {
|
|
2983
|
+
throw new ModelKitError({
|
|
2984
|
+
code: "provider_rejected",
|
|
2985
|
+
message: `fal ${endpoint} submit returned no status URL`,
|
|
2986
|
+
provider: "fal",
|
|
2987
|
+
model: ctx.model.id,
|
|
2988
|
+
retryable: false
|
|
2949
2989
|
});
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
if (!parsed.success) {
|
|
2953
|
-
throw new ModelKitError({
|
|
2954
|
-
code: "provider_rejected",
|
|
2955
|
-
message: `fal ${endpoint} submit returned no status URL`,
|
|
2956
|
-
provider: "fal",
|
|
2957
|
-
model: ctx.model.id,
|
|
2958
|
-
retryable: false
|
|
2959
|
-
});
|
|
2960
|
-
}
|
|
2961
|
-
statusUrl = parsed.data.status_url;
|
|
2962
|
-
return parsed.data;
|
|
2963
|
-
})();
|
|
2990
|
+
}
|
|
2991
|
+
const { request_id: jobId, status_url, response_url } = parsed.data;
|
|
2964
2992
|
const checkStatus = async () => {
|
|
2965
|
-
const
|
|
2966
|
-
const statusRes = await gatewayFetch(cfg, ctx.fetch, statusUrl ?? "", { method: "GET" });
|
|
2993
|
+
const statusRes = await gatewayFetch(cfg, ctx.fetch, status_url, { method: "GET" });
|
|
2967
2994
|
if (!statusRes.ok)
|
|
2968
2995
|
throw falError(statusRes.status, await readBody(statusRes), ctx.model.id);
|
|
2969
2996
|
const statusParsed = falQueueStatusSchema.safeParse(await statusRes.json());
|
|
@@ -2977,7 +3004,7 @@ function passthroughVideoJob(ctx, req, endpoint, input) {
|
|
|
2977
3004
|
};
|
|
2978
3005
|
const duration = req.durationSeconds ?? 5;
|
|
2979
3006
|
return {
|
|
2980
|
-
jobId
|
|
3007
|
+
jobId,
|
|
2981
3008
|
async poll() {
|
|
2982
3009
|
try {
|
|
2983
3010
|
const url = await checkStatus();
|
|
@@ -3838,6 +3865,7 @@ function toProviderError(cause, ctx) {
|
|
|
3838
3865
|
});
|
|
3839
3866
|
}
|
|
3840
3867
|
const info = describeThrown(cause);
|
|
3868
|
+
if (info.status === void 0) return transportError("google-image", cause, ctx.model.id);
|
|
3841
3869
|
return classifyHttpError(info.status, info.body, "google-image", ctx.model.id);
|
|
3842
3870
|
}
|
|
3843
3871
|
function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
@@ -4545,6 +4573,7 @@ var openaiImageAdapter = {
|
|
|
4545
4573
|
const refs = req.references ?? [];
|
|
4546
4574
|
const isEdit = refs.length > 0;
|
|
4547
4575
|
const quality = req.quality ?? (isEdit ? "medium" : "auto");
|
|
4576
|
+
const sdkQuality = quality;
|
|
4548
4577
|
const count = req.count !== void 0 && req.count > 1 ? { n: req.count } : {};
|
|
4549
4578
|
const retryOptions = {};
|
|
4550
4579
|
if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
|
|
@@ -4556,14 +4585,14 @@ var openaiImageAdapter = {
|
|
|
4556
4585
|
model: ctx.model.providerModelId,
|
|
4557
4586
|
prompt: req.prompt,
|
|
4558
4587
|
size,
|
|
4559
|
-
quality,
|
|
4588
|
+
quality: sdkQuality,
|
|
4560
4589
|
...count
|
|
4561
4590
|
});
|
|
4562
4591
|
}
|
|
4563
4592
|
return await client2.images.generate({
|
|
4564
4593
|
model: ctx.model.providerModelId,
|
|
4565
4594
|
prompt: req.prompt,
|
|
4566
|
-
quality,
|
|
4595
|
+
quality: sdkQuality,
|
|
4567
4596
|
...count
|
|
4568
4597
|
});
|
|
4569
4598
|
}
|
|
@@ -4582,7 +4611,7 @@ var openaiImageAdapter = {
|
|
|
4582
4611
|
image: imageInput,
|
|
4583
4612
|
prompt: req.prompt,
|
|
4584
4613
|
size,
|
|
4585
|
-
quality,
|
|
4614
|
+
quality: sdkQuality,
|
|
4586
4615
|
...count
|
|
4587
4616
|
});
|
|
4588
4617
|
}
|
|
@@ -4590,7 +4619,7 @@ var openaiImageAdapter = {
|
|
|
4590
4619
|
model: ctx.model.providerModelId,
|
|
4591
4620
|
image: imageInput,
|
|
4592
4621
|
prompt: req.prompt,
|
|
4593
|
-
quality,
|
|
4622
|
+
quality: sdkQuality,
|
|
4594
4623
|
...count
|
|
4595
4624
|
});
|
|
4596
4625
|
} catch (cause) {
|
|
@@ -4811,7 +4840,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4811
4840
|
});
|
|
4812
4841
|
} catch (err) {
|
|
4813
4842
|
if (isModelKitError(err)) throw err;
|
|
4814
|
-
throw
|
|
4843
|
+
throw transportError("prodia", err, ctx.model.id);
|
|
4815
4844
|
}
|
|
4816
4845
|
if (!attemptRes.ok) {
|
|
4817
4846
|
const text2 = await attemptRes.text().catch(() => "");
|
|
@@ -4821,7 +4850,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4821
4850
|
}, retryOpts);
|
|
4822
4851
|
} catch (err) {
|
|
4823
4852
|
if (isModelKitError(err)) throw err;
|
|
4824
|
-
throw
|
|
4853
|
+
throw transportError("prodia", err, ctx.model.id);
|
|
4825
4854
|
}
|
|
4826
4855
|
const bytes = parseImageResponse(
|
|
4827
4856
|
new Uint8Array(await res.arrayBuffer()),
|
|
@@ -5109,6 +5138,27 @@ function klingInput(req) {
|
|
|
5109
5138
|
if (req.negativePrompt !== void 0) input.negative_prompt = req.negativePrompt;
|
|
5110
5139
|
return input;
|
|
5111
5140
|
}
|
|
5141
|
+
function klingOmniInput(req) {
|
|
5142
|
+
const images = (req.firstFrame ? [req.firstFrame] : []).map(refToUrl3);
|
|
5143
|
+
if (req.lastFrame) images.push(refToUrl3(req.lastFrame));
|
|
5144
|
+
const input = {
|
|
5145
|
+
prompt: req.prompt,
|
|
5146
|
+
duration: req.durationSeconds ?? 10,
|
|
5147
|
+
mode: req.mode ?? "standard",
|
|
5148
|
+
generate_audio: req.generateAudio ?? false
|
|
5149
|
+
};
|
|
5150
|
+
const startImage = images[0];
|
|
5151
|
+
if (startImage !== void 0) {
|
|
5152
|
+
input.start_image = startImage;
|
|
5153
|
+
const endImage = images[1];
|
|
5154
|
+
if (endImage !== void 0) input.end_image = endImage;
|
|
5155
|
+
} else {
|
|
5156
|
+
input.aspect_ratio = req.aspectRatio ?? "16:9";
|
|
5157
|
+
}
|
|
5158
|
+
const refs = (req.referenceImages ?? []).map(refToUrl3);
|
|
5159
|
+
if (refs.length > 0) input.reference_images = refs;
|
|
5160
|
+
return input;
|
|
5161
|
+
}
|
|
5112
5162
|
function hailuoInput(req) {
|
|
5113
5163
|
const input = {
|
|
5114
5164
|
prompt: req.prompt,
|
|
@@ -5131,7 +5181,7 @@ function wanInput(req) {
|
|
|
5131
5181
|
}
|
|
5132
5182
|
async function generateReplicateVideo(req, ctx, deps) {
|
|
5133
5183
|
const id = isLower(ctx.model.providerModelId);
|
|
5134
|
-
const input = id.includes("kling") ? klingInput(req) : id.includes("hailuo") ? hailuoInput(req) : wanInput(req);
|
|
5184
|
+
const input = id.includes("kling") ? id.includes("omni") ? klingOmniInput(req) : klingInput(req) : id.includes("hailuo") ? hailuoInput(req) : wanInput(req);
|
|
5135
5185
|
const api = client(ctx, deps);
|
|
5136
5186
|
const createOptions = { ...route(ctx.model.providerModelId), input };
|
|
5137
5187
|
let prediction;
|
|
@@ -5221,6 +5271,9 @@ function lyriaAudioInput(req, ctx) {
|
|
|
5221
5271
|
if (negative) input.negative_prompt = negative;
|
|
5222
5272
|
return input;
|
|
5223
5273
|
}
|
|
5274
|
+
function elevenLabsMusicDuration(seconds) {
|
|
5275
|
+
return Math.min(300, Math.max(5, seconds ?? 15));
|
|
5276
|
+
}
|
|
5224
5277
|
function elevenLabsMusicInput(req, ctx) {
|
|
5225
5278
|
const prompt = req.prompt.trim();
|
|
5226
5279
|
if (!prompt) {
|
|
@@ -5232,10 +5285,9 @@ function elevenLabsMusicInput(req, ctx) {
|
|
|
5232
5285
|
retryable: false
|
|
5233
5286
|
});
|
|
5234
5287
|
}
|
|
5235
|
-
const seconds = Math.min(300, Math.max(5, req.durationSeconds ?? 15));
|
|
5236
5288
|
return {
|
|
5237
5289
|
prompt,
|
|
5238
|
-
music_length_ms:
|
|
5290
|
+
music_length_ms: elevenLabsMusicDuration(req.durationSeconds) * 1e3,
|
|
5239
5291
|
force_instrumental: req.instrumental ?? true,
|
|
5240
5292
|
output_format: "wav_cd_quality"
|
|
5241
5293
|
};
|
|
@@ -5275,7 +5327,13 @@ async function generateReplicateAudio(req, ctx, deps) {
|
|
|
5275
5327
|
const input = id.includes("mmaudio") ? mmaudioInput(req, ctx) : id.includes("elevenlabs") ? elevenLabsMusicInput(req, ctx) : lyriaAudioInput(req, ctx);
|
|
5276
5328
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|
|
5277
5329
|
const usage2 = audioUsage(ctx, req);
|
|
5278
|
-
|
|
5330
|
+
if (ctx.model.usage.unit === "seconds") {
|
|
5331
|
+
const seconds = elevenLabsMusicDuration(req.durationSeconds);
|
|
5332
|
+
usage2.quantity = seconds;
|
|
5333
|
+
usage2.durationSeconds = seconds;
|
|
5334
|
+
} else {
|
|
5335
|
+
usage2.quantity = predictTime;
|
|
5336
|
+
}
|
|
5279
5337
|
return { audio: { url }, usage: usage2, raw: predictionRaw(raw) };
|
|
5280
5338
|
}
|
|
5281
5339
|
|