@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/README.md
CHANGED
|
@@ -101,6 +101,11 @@ fetch, logging, and the `onUsage` sink.
|
|
|
101
101
|
pass-through instances; catalog rows carry their own and the caller's are dropped
|
|
102
102
|
with an `option_ignored` warning.
|
|
103
103
|
|
|
104
|
+
Text catalog rows carry no reasoning defaults. A catalog id behaves like the
|
|
105
|
+
provider's own default, so `temperature` and friends work as they do in `ai`.
|
|
106
|
+
Opt into thinking per call, for example
|
|
107
|
+
`providerOptions: { anthropic: { thinking: { type: "enabled", budgetTokens: 4000 } } }`.
|
|
108
|
+
|
|
104
109
|
The kit keeps its `Warning` type for coercions; the SDK's warning type is `AiWarning`.
|
|
105
110
|
`languageModel()` remains the low-level handle for Mastra and custom middleware.
|
|
106
111
|
|
package/dist/index.cjs
CHANGED
|
@@ -212,6 +212,44 @@ var IMAGE_MODELS = [
|
|
|
212
212
|
usage: { ...IMAGE_USAGE },
|
|
213
213
|
pricingKind: "image_size"
|
|
214
214
|
},
|
|
215
|
+
{
|
|
216
|
+
// Same Images API surface as gpt-image-2 plus the "xhigh" and "max" quality tiers.
|
|
217
|
+
id: "gpt-image-2.5-sunburst",
|
|
218
|
+
aliases: [],
|
|
219
|
+
label: "GPT Image 2.5 Sunburst",
|
|
220
|
+
type: "image",
|
|
221
|
+
adapter: "openai-image",
|
|
222
|
+
providerModelId: "gpt-image-2.5-sunburst",
|
|
223
|
+
lifecycle: "active",
|
|
224
|
+
constraints: {
|
|
225
|
+
aspectRatios: ["1:1", "3:2", "2:3", "16:9", "9:16", "4:5", "5:4", "adaptive"],
|
|
226
|
+
sizes: ["1K", "2K", "4K"],
|
|
227
|
+
references: { images: 16 },
|
|
228
|
+
supports: ["quality", "count"]
|
|
229
|
+
},
|
|
230
|
+
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
231
|
+
usage: { ...IMAGE_USAGE },
|
|
232
|
+
pricingKind: "image_size"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
// Same Images API surface as gpt-image-2 plus the "xhigh" and "max" quality tiers.
|
|
236
|
+
id: "gpt-image-2.5-flare",
|
|
237
|
+
aliases: [],
|
|
238
|
+
label: "GPT Image 2.5 Flare",
|
|
239
|
+
type: "image",
|
|
240
|
+
adapter: "openai-image",
|
|
241
|
+
providerModelId: "gpt-image-2.5-flare",
|
|
242
|
+
lifecycle: "active",
|
|
243
|
+
constraints: {
|
|
244
|
+
aspectRatios: ["1:1", "3:2", "2:3", "16:9", "9:16", "4:5", "5:4", "adaptive"],
|
|
245
|
+
sizes: ["1K", "2K", "4K"],
|
|
246
|
+
references: { images: 16 },
|
|
247
|
+
supports: ["quality", "count"]
|
|
248
|
+
},
|
|
249
|
+
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
250
|
+
usage: { ...IMAGE_USAGE },
|
|
251
|
+
pricingKind: "image_size"
|
|
252
|
+
},
|
|
215
253
|
{
|
|
216
254
|
// Cowork allows 7 ratios; trigger-workflows allows 9 (adds 3:2, 9:21, drops 4:5/5:4).
|
|
217
255
|
id: "muse-image-1.0",
|
|
@@ -588,77 +626,42 @@ function text(id, label, providerModelId, extra) {
|
|
|
588
626
|
...extra
|
|
589
627
|
};
|
|
590
628
|
}
|
|
591
|
-
var ANTHROPIC_THINKING = {
|
|
592
|
-
anthropic: {
|
|
593
|
-
thinking: { type: "enabled", budgetTokens: 4e3 },
|
|
594
|
-
sendReasoning: true
|
|
595
|
-
}
|
|
596
|
-
};
|
|
597
|
-
var ANTHROPIC_ADAPTIVE = {
|
|
598
|
-
anthropic: {
|
|
599
|
-
thinking: { type: "adaptive", display: "summarized" },
|
|
600
|
-
sendReasoning: true
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
|
-
var OPENAI_REASONING = {
|
|
604
|
-
openai: {
|
|
605
|
-
reasoningEffort: "medium",
|
|
606
|
-
reasoningSummary: "auto"
|
|
607
|
-
}
|
|
608
|
-
};
|
|
609
|
-
var DEEPSEEK_THINKING = {
|
|
610
|
-
deepseek: {
|
|
611
|
-
thinking: { type: "enabled" }
|
|
612
|
-
}
|
|
613
|
-
};
|
|
614
629
|
var TEXT_MODELS = [
|
|
615
630
|
text("gpt-4o", "GPT-4o", "gpt-4o"),
|
|
616
631
|
text("gpt-4o-mini", "GPT-4o mini", "gpt-4o-mini"),
|
|
617
632
|
text("gpt-5.1", "GPT-5.1", "gpt-5.1"),
|
|
618
|
-
text("gpt-5.1-mini", "GPT-5.1 mini", "gpt-5.1-mini"),
|
|
619
633
|
text("gpt-5.2", "GPT-5.2", "gpt-5.2"),
|
|
620
|
-
text("gpt-5.2-mini", "GPT-5.2 mini", "gpt-5.2-mini"),
|
|
621
634
|
text("gpt-5.4", "GPT-5.4", "gpt-5.4"),
|
|
622
|
-
|
|
623
|
-
text("gpt-5.
|
|
624
|
-
|
|
625
|
-
providerOptions: { ...OPENAI_REASONING }
|
|
626
|
-
}),
|
|
627
|
-
text("gpt-5.6-terra", "GPT-5.6 Terra", "gpt-5.6-terra", {
|
|
628
|
-
providerOptions: { ...OPENAI_REASONING }
|
|
629
|
-
}),
|
|
630
|
-
text("gpt-5.6-sol", "GPT-5.6 Sol", "gpt-5.6-sol", {
|
|
631
|
-
providerOptions: { ...OPENAI_REASONING }
|
|
632
|
-
}),
|
|
633
|
-
// Dated 4.0 ids are what vibe-api, pro-admin and the TW geo agents still send.
|
|
634
|
-
text("claude-sonnet-4", "Claude Sonnet 4", "claude-sonnet-4-20250514", {
|
|
635
|
-
aliases: ["claude-sonnet-4.0", "claude-sonnet-4-20250514"]
|
|
636
|
-
}),
|
|
637
|
-
text("claude-opus-4", "Claude Opus 4", "claude-opus-4-20250514", {
|
|
638
|
-
aliases: ["claude-opus-4.0", "claude-opus-4-20250514"]
|
|
635
|
+
// OpenAI never shipped gpt-5.1-mini or gpt-5.2-mini; callers that still send them get 5.4 mini.
|
|
636
|
+
text("gpt-5.4-mini", "GPT-5.4 mini", "gpt-5.4-mini", {
|
|
637
|
+
aliases: ["gpt-5.1-mini", "gpt-5.2-mini"]
|
|
639
638
|
}),
|
|
639
|
+
text("gpt-5.5", "GPT-5.5", "gpt-5.5"),
|
|
640
|
+
text("gpt-5.6-luna", "GPT-5.6 Luna", "gpt-5.6-luna"),
|
|
641
|
+
text("gpt-5.6-terra", "GPT-5.6 Terra", "gpt-5.6-terra"),
|
|
642
|
+
text("gpt-5.6-sol", "GPT-5.6 Sol", "gpt-5.6-sol"),
|
|
640
643
|
// Library key "claude-sonnet-4.5" maps to the SDK id "claude-sonnet-4-5".
|
|
641
644
|
text("claude-sonnet-4-5", "Claude Sonnet 4.5", "claude-sonnet-4-5", {
|
|
642
645
|
aliases: ["claude-sonnet-4.5"]
|
|
643
646
|
}),
|
|
647
|
+
// Anthropic retired the dated 4.0 ids; callers that still send them get 4.6.
|
|
644
648
|
text("claude-sonnet-4-6", "Claude Sonnet 4.6", "claude-sonnet-4-6", {
|
|
645
|
-
aliases: [
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
649
|
+
aliases: [
|
|
650
|
+
"claude-sonnet-4.6",
|
|
651
|
+
"claude-sonnet-4",
|
|
652
|
+
"claude-sonnet-4.0",
|
|
653
|
+
"claude-sonnet-4-20250514"
|
|
654
|
+
]
|
|
650
655
|
}),
|
|
656
|
+
text("claude-sonnet-5", "Claude Sonnet 5", "claude-sonnet-5"),
|
|
651
657
|
text("claude-opus-4-8", "Claude Opus 4.8", "claude-opus-4-8", {
|
|
652
|
-
aliases: ["claude-opus-4.8"]
|
|
653
|
-
providerOptions: { ...ANTHROPIC_ADAPTIVE }
|
|
658
|
+
aliases: ["claude-opus-4.8", "claude-opus-4", "claude-opus-4.0", "claude-opus-4-20250514"]
|
|
654
659
|
}),
|
|
655
660
|
text("claude-haiku-4-5", "Claude Haiku 4.5", "claude-haiku-4-5", {
|
|
656
|
-
aliases: ["claude-haiku-4.5", "claude-haiku-4-5-20251001"]
|
|
657
|
-
providerOptions: { ...ANTHROPIC_THINKING }
|
|
661
|
+
aliases: ["claude-haiku-4.5", "claude-haiku-4-5-20251001"]
|
|
658
662
|
}),
|
|
659
663
|
text("claude-opus-5", "Claude Opus 5", "claude-opus-5", {
|
|
660
|
-
aliases: ["claude-opus-5.0"]
|
|
661
|
-
providerOptions: { ...ANTHROPIC_ADAPTIVE }
|
|
664
|
+
aliases: ["claude-opus-5.0"]
|
|
662
665
|
}),
|
|
663
666
|
text("claude-fable-5", "Claude Fable 5", "claude-fable-5"),
|
|
664
667
|
text("gemini-2.5-flash", "Gemini 2.5 Flash", "gemini-2.5-flash"),
|
|
@@ -677,12 +680,8 @@ var TEXT_MODELS = [
|
|
|
677
680
|
text("sonar", "Sonar", "sonar"),
|
|
678
681
|
text("sonar-pro", "Sonar Pro", "sonar-pro"),
|
|
679
682
|
text("sonar-reasoning-pro", "Sonar Reasoning Pro", "sonar-reasoning-pro"),
|
|
680
|
-
text("deepseek-v4-flash", "DeepSeek V4 Flash", "deepseek-v4-flash",
|
|
681
|
-
|
|
682
|
-
}),
|
|
683
|
-
text("deepseek-v4-pro", "DeepSeek V4 Pro", "deepseek-v4-pro", {
|
|
684
|
-
providerOptions: { ...DEEPSEEK_THINKING }
|
|
685
|
-
}),
|
|
683
|
+
text("deepseek-v4-flash", "DeepSeek V4 Flash", "deepseek-v4-flash"),
|
|
684
|
+
text("deepseek-v4-pro", "DeepSeek V4 Pro", "deepseek-v4-pro"),
|
|
686
685
|
text("grok-4.3", "Grok 4.3", "grok-4.3"),
|
|
687
686
|
text("kimi-k2.5", "Kimi K2.5", "kimi-k2.5"),
|
|
688
687
|
text("kimi-k3", "Kimi K3", "kimi-k3"),
|
|
@@ -827,7 +826,7 @@ var VIDEO_MODELS = [
|
|
|
827
826
|
durations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
828
827
|
references: { images: 9, videos: 3, audios: 3, audioOnly: false },
|
|
829
828
|
ratioIgnoredWith: ["firstFrame"],
|
|
830
|
-
supports: ["generateAudio", "seed"]
|
|
829
|
+
supports: ["generateAudio", "seed", "lastFrame"]
|
|
831
830
|
},
|
|
832
831
|
defaults: {
|
|
833
832
|
durationSeconds: 5,
|
|
@@ -852,7 +851,7 @@ var VIDEO_MODELS = [
|
|
|
852
851
|
durations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
853
852
|
references: { images: 9, videos: 3, audios: 3, audioOnly: false },
|
|
854
853
|
ratioIgnoredWith: ["firstFrame"],
|
|
855
|
-
supports: ["generateAudio", "seed"]
|
|
854
|
+
supports: ["generateAudio", "seed", "lastFrame"]
|
|
856
855
|
},
|
|
857
856
|
defaults: {
|
|
858
857
|
durationSeconds: 5,
|
|
@@ -878,7 +877,7 @@ var VIDEO_MODELS = [
|
|
|
878
877
|
durations: { min: 4, max: 30 },
|
|
879
878
|
references: { images: 30, videos: 10, audios: 10 },
|
|
880
879
|
ratioIgnoredWith: ["firstFrame"],
|
|
881
|
-
supports: ["generateAudio", "seed"]
|
|
880
|
+
supports: ["generateAudio", "seed", "lastFrame"]
|
|
882
881
|
},
|
|
883
882
|
defaults: {
|
|
884
883
|
durationSeconds: 5,
|
|
@@ -980,7 +979,7 @@ var VIDEO_MODELS = [
|
|
|
980
979
|
resolutions: ["720p", "1080p"],
|
|
981
980
|
durations: { min: 3, max: 15 },
|
|
982
981
|
references: { images: 7 },
|
|
983
|
-
supports: ["generateAudio"]
|
|
982
|
+
supports: ["generateAudio", "lastFrame"]
|
|
984
983
|
},
|
|
985
984
|
defaults: { durationSeconds: 5, aspectRatio: "16:9", generateAudio: false, mode: "pro" },
|
|
986
985
|
usage: { unit: "compute_seconds", modality: "VIDEO" },
|
|
@@ -1513,23 +1512,46 @@ async function withRetry(fn, opts = {}) {
|
|
|
1513
1512
|
}
|
|
1514
1513
|
function sleep(ms, signal) {
|
|
1515
1514
|
return new Promise((resolve, reject) => {
|
|
1516
|
-
const
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1515
|
+
const rejectAborted = () => {
|
|
1516
|
+
reject(new ModelKitError({ code: "timeout", message: "aborted", retryable: false }));
|
|
1517
|
+
};
|
|
1518
|
+
if (signal?.aborted) {
|
|
1519
|
+
rejectAborted();
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
let timer;
|
|
1523
|
+
const onAbort = () => {
|
|
1524
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
1525
|
+
rejectAborted();
|
|
1526
|
+
};
|
|
1527
|
+
timer = setTimeout(() => {
|
|
1528
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1529
|
+
resolve();
|
|
1530
|
+
}, ms);
|
|
1531
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1527
1532
|
});
|
|
1528
1533
|
}
|
|
1534
|
+
function throwAborted() {
|
|
1535
|
+
return new ModelKitError({ code: "timeout", message: "aborted", retryable: false });
|
|
1536
|
+
}
|
|
1537
|
+
function transportError(provider, cause, model) {
|
|
1538
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
1539
|
+
const aborted = cause instanceof Error && cause.name === "AbortError";
|
|
1540
|
+
const init = {
|
|
1541
|
+
code: aborted ? "timeout" : "network",
|
|
1542
|
+
message: `${provider} request failed before a response: ${message}`,
|
|
1543
|
+
provider,
|
|
1544
|
+
retryable: !aborted,
|
|
1545
|
+
cause
|
|
1546
|
+
};
|
|
1547
|
+
if (model !== void 0) init.model = model;
|
|
1548
|
+
return new ModelKitError(init);
|
|
1549
|
+
}
|
|
1529
1550
|
async function pollUntil(check, opts) {
|
|
1530
1551
|
const start = Date.now();
|
|
1531
1552
|
let interval = opts.intervalMs;
|
|
1532
1553
|
for (; ; ) {
|
|
1554
|
+
if (opts.signal?.aborted) throw throwAborted();
|
|
1533
1555
|
const value = await check();
|
|
1534
1556
|
if (value !== void 0) return value;
|
|
1535
1557
|
if (Date.now() - start > opts.timeoutMs)
|
|
@@ -1538,6 +1560,7 @@ async function pollUntil(check, opts) {
|
|
|
1538
1560
|
message: `poll timed out after ${opts.timeoutMs}ms`,
|
|
1539
1561
|
retryable: false
|
|
1540
1562
|
});
|
|
1563
|
+
if (opts.signal?.aborted) throw throwAborted();
|
|
1541
1564
|
await sleep(interval, opts.signal);
|
|
1542
1565
|
if (opts.backoff)
|
|
1543
1566
|
interval = Math.min(opts.maxIntervalMs ?? interval * 4, interval * opts.backoff);
|
|
@@ -1715,7 +1738,7 @@ var OPENAI_COMPATIBLE_BASE_URLS = {
|
|
|
1715
1738
|
var GATEWAY_SLUGS = {
|
|
1716
1739
|
openai: "openai",
|
|
1717
1740
|
anthropic: "anthropic",
|
|
1718
|
-
google: "google-ai-studio",
|
|
1741
|
+
google: "google-ai-studio/v1beta",
|
|
1719
1742
|
xai: "grok",
|
|
1720
1743
|
perplexity: "perplexity-ai",
|
|
1721
1744
|
deepseek: "deepseek"
|
|
@@ -2141,13 +2164,21 @@ function createModelKit(config, adapters) {
|
|
|
2141
2164
|
});
|
|
2142
2165
|
const job = await adapter.generateVideo(request, ctx);
|
|
2143
2166
|
const result = job.result.bind(job);
|
|
2167
|
+
let settled;
|
|
2144
2168
|
return {
|
|
2145
2169
|
...job,
|
|
2146
2170
|
warnings,
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2171
|
+
result(opts) {
|
|
2172
|
+
if (settled) return settled;
|
|
2173
|
+
const pending = result(opts).then(
|
|
2174
|
+
(out) => emit({ ...out.usage, model: model.id }).then(() => out),
|
|
2175
|
+
(cause) => {
|
|
2176
|
+
settled = void 0;
|
|
2177
|
+
throw cause;
|
|
2178
|
+
}
|
|
2179
|
+
);
|
|
2180
|
+
settled = pending;
|
|
2181
|
+
return pending;
|
|
2151
2182
|
}
|
|
2152
2183
|
};
|
|
2153
2184
|
},
|
|
@@ -2508,6 +2539,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2508
2539
|
};
|
|
2509
2540
|
if (!hasFrameAnchor && req.aspectRatio !== void 0) body.ratio = req.aspectRatio;
|
|
2510
2541
|
if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
|
|
2542
|
+
if (req.seed !== void 0) body.seed = req.seed;
|
|
2511
2543
|
const submit = await withRetry(async () => {
|
|
2512
2544
|
const res = await ctx.fetch(
|
|
2513
2545
|
`${ARK_BASE_URL}${SUBMIT_PATH}`,
|
|
@@ -2961,7 +2993,7 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
2961
2993
|
if (isKling(providerModelId)) {
|
|
2962
2994
|
const input = klingO1Input(req);
|
|
2963
2995
|
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
2964
|
-
return passthroughVideoJob(ctx, req, KLING_O1_ENDPOINT, input);
|
|
2996
|
+
return await passthroughVideoJob(ctx, req, KLING_O1_ENDPOINT, input);
|
|
2965
2997
|
}
|
|
2966
2998
|
const result2 = await runJob(ctx, deps, KLING_O1_ENDPOINT, input);
|
|
2967
2999
|
return completedVideoJob(
|
|
@@ -2996,7 +3028,7 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
2996
3028
|
base.aspect_ratio = req.aspectRatio ?? "adaptive";
|
|
2997
3029
|
}
|
|
2998
3030
|
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
2999
|
-
return passthroughVideoJob(ctx, req, endpoint, base);
|
|
3031
|
+
return await passthroughVideoJob(ctx, req, endpoint, base);
|
|
3000
3032
|
}
|
|
3001
3033
|
const result = await runJob(ctx, deps, endpoint, base);
|
|
3002
3034
|
return completedVideoJob(ctx, req, extractVideoUrl(result, endpoint, ctx.model.id), result);
|
|
@@ -3014,31 +3046,26 @@ function completedVideoJob(ctx, req, url, raw) {
|
|
|
3014
3046
|
}
|
|
3015
3047
|
};
|
|
3016
3048
|
}
|
|
3017
|
-
function passthroughVideoJob(ctx, req, endpoint, input) {
|
|
3049
|
+
async function passthroughVideoJob(ctx, req, endpoint, input) {
|
|
3018
3050
|
const cfg = gatewayConfig(ctx);
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3051
|
+
const res = await gatewayFetch(cfg, ctx.fetch, `${FAL_QUEUE_HOST}/${endpoint}`, {
|
|
3052
|
+
method: "POST",
|
|
3053
|
+
body: JSON.stringify({ ...input, sync_mode: true })
|
|
3054
|
+
});
|
|
3055
|
+
if (!res.ok) throw falError(res.status, await readBody(res), ctx.model.id);
|
|
3056
|
+
const parsed = falQueueSubmitSchema.safeParse(await res.json());
|
|
3057
|
+
if (!parsed.success) {
|
|
3058
|
+
throw new ModelKitError({
|
|
3059
|
+
code: "provider_rejected",
|
|
3060
|
+
message: `fal ${endpoint} submit returned no status URL`,
|
|
3061
|
+
provider: "fal",
|
|
3062
|
+
model: ctx.model.id,
|
|
3063
|
+
retryable: false
|
|
3024
3064
|
});
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
if (!parsed.success) {
|
|
3028
|
-
throw new ModelKitError({
|
|
3029
|
-
code: "provider_rejected",
|
|
3030
|
-
message: `fal ${endpoint} submit returned no status URL`,
|
|
3031
|
-
provider: "fal",
|
|
3032
|
-
model: ctx.model.id,
|
|
3033
|
-
retryable: false
|
|
3034
|
-
});
|
|
3035
|
-
}
|
|
3036
|
-
statusUrl = parsed.data.status_url;
|
|
3037
|
-
return parsed.data;
|
|
3038
|
-
})();
|
|
3065
|
+
}
|
|
3066
|
+
const { request_id: jobId, status_url, response_url } = parsed.data;
|
|
3039
3067
|
const checkStatus = async () => {
|
|
3040
|
-
const
|
|
3041
|
-
const statusRes = await gatewayFetch(cfg, ctx.fetch, statusUrl ?? "", { method: "GET" });
|
|
3068
|
+
const statusRes = await gatewayFetch(cfg, ctx.fetch, status_url, { method: "GET" });
|
|
3042
3069
|
if (!statusRes.ok)
|
|
3043
3070
|
throw falError(statusRes.status, await readBody(statusRes), ctx.model.id);
|
|
3044
3071
|
const statusParsed = falQueueStatusSchema.safeParse(await statusRes.json());
|
|
@@ -3052,7 +3079,7 @@ function passthroughVideoJob(ctx, req, endpoint, input) {
|
|
|
3052
3079
|
};
|
|
3053
3080
|
const duration = req.durationSeconds ?? 5;
|
|
3054
3081
|
return {
|
|
3055
|
-
jobId
|
|
3082
|
+
jobId,
|
|
3056
3083
|
async poll() {
|
|
3057
3084
|
try {
|
|
3058
3085
|
const url = await checkStatus();
|
|
@@ -3911,6 +3938,7 @@ function toProviderError(cause, ctx) {
|
|
|
3911
3938
|
});
|
|
3912
3939
|
}
|
|
3913
3940
|
const info = describeThrown(cause);
|
|
3941
|
+
if (info.status === void 0) return transportError("google-image", cause, ctx.model.id);
|
|
3914
3942
|
return classifyHttpError(info.status, info.body, "google-image", ctx.model.id);
|
|
3915
3943
|
}
|
|
3916
3944
|
function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
@@ -4618,6 +4646,7 @@ var openaiImageAdapter = {
|
|
|
4618
4646
|
const refs = req.references ?? [];
|
|
4619
4647
|
const isEdit = refs.length > 0;
|
|
4620
4648
|
const quality = req.quality ?? (isEdit ? "medium" : "auto");
|
|
4649
|
+
const sdkQuality = quality;
|
|
4621
4650
|
const count = req.count !== void 0 && req.count > 1 ? { n: req.count } : {};
|
|
4622
4651
|
const retryOptions = {};
|
|
4623
4652
|
if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
|
|
@@ -4629,14 +4658,14 @@ var openaiImageAdapter = {
|
|
|
4629
4658
|
model: ctx.model.providerModelId,
|
|
4630
4659
|
prompt: req.prompt,
|
|
4631
4660
|
size,
|
|
4632
|
-
quality,
|
|
4661
|
+
quality: sdkQuality,
|
|
4633
4662
|
...count
|
|
4634
4663
|
});
|
|
4635
4664
|
}
|
|
4636
4665
|
return await client2.images.generate({
|
|
4637
4666
|
model: ctx.model.providerModelId,
|
|
4638
4667
|
prompt: req.prompt,
|
|
4639
|
-
quality,
|
|
4668
|
+
quality: sdkQuality,
|
|
4640
4669
|
...count
|
|
4641
4670
|
});
|
|
4642
4671
|
}
|
|
@@ -4655,7 +4684,7 @@ var openaiImageAdapter = {
|
|
|
4655
4684
|
image: imageInput,
|
|
4656
4685
|
prompt: req.prompt,
|
|
4657
4686
|
size,
|
|
4658
|
-
quality,
|
|
4687
|
+
quality: sdkQuality,
|
|
4659
4688
|
...count
|
|
4660
4689
|
});
|
|
4661
4690
|
}
|
|
@@ -4663,7 +4692,7 @@ var openaiImageAdapter = {
|
|
|
4663
4692
|
model: ctx.model.providerModelId,
|
|
4664
4693
|
image: imageInput,
|
|
4665
4694
|
prompt: req.prompt,
|
|
4666
|
-
quality,
|
|
4695
|
+
quality: sdkQuality,
|
|
4667
4696
|
...count
|
|
4668
4697
|
});
|
|
4669
4698
|
} catch (cause) {
|
|
@@ -4884,7 +4913,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4884
4913
|
});
|
|
4885
4914
|
} catch (err) {
|
|
4886
4915
|
if (isModelKitError(err)) throw err;
|
|
4887
|
-
throw
|
|
4916
|
+
throw transportError("prodia", err, ctx.model.id);
|
|
4888
4917
|
}
|
|
4889
4918
|
if (!attemptRes.ok) {
|
|
4890
4919
|
const text2 = await attemptRes.text().catch(() => "");
|
|
@@ -4894,7 +4923,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4894
4923
|
}, retryOpts);
|
|
4895
4924
|
} catch (err) {
|
|
4896
4925
|
if (isModelKitError(err)) throw err;
|
|
4897
|
-
throw
|
|
4926
|
+
throw transportError("prodia", err, ctx.model.id);
|
|
4898
4927
|
}
|
|
4899
4928
|
const bytes = parseImageResponse(
|
|
4900
4929
|
new Uint8Array(await res.arrayBuffer()),
|
|
@@ -5182,6 +5211,27 @@ function klingInput(req) {
|
|
|
5182
5211
|
if (req.negativePrompt !== void 0) input.negative_prompt = req.negativePrompt;
|
|
5183
5212
|
return input;
|
|
5184
5213
|
}
|
|
5214
|
+
function klingOmniInput(req) {
|
|
5215
|
+
const images = (req.firstFrame ? [req.firstFrame] : []).map(refToUrl3);
|
|
5216
|
+
if (req.lastFrame) images.push(refToUrl3(req.lastFrame));
|
|
5217
|
+
const input = {
|
|
5218
|
+
prompt: req.prompt,
|
|
5219
|
+
duration: req.durationSeconds ?? 10,
|
|
5220
|
+
mode: req.mode ?? "standard",
|
|
5221
|
+
generate_audio: req.generateAudio ?? false
|
|
5222
|
+
};
|
|
5223
|
+
const startImage = images[0];
|
|
5224
|
+
if (startImage !== void 0) {
|
|
5225
|
+
input.start_image = startImage;
|
|
5226
|
+
const endImage = images[1];
|
|
5227
|
+
if (endImage !== void 0) input.end_image = endImage;
|
|
5228
|
+
} else {
|
|
5229
|
+
input.aspect_ratio = req.aspectRatio ?? "16:9";
|
|
5230
|
+
}
|
|
5231
|
+
const refs = (req.referenceImages ?? []).map(refToUrl3);
|
|
5232
|
+
if (refs.length > 0) input.reference_images = refs;
|
|
5233
|
+
return input;
|
|
5234
|
+
}
|
|
5185
5235
|
function hailuoInput(req) {
|
|
5186
5236
|
const input = {
|
|
5187
5237
|
prompt: req.prompt,
|
|
@@ -5204,7 +5254,7 @@ function wanInput(req) {
|
|
|
5204
5254
|
}
|
|
5205
5255
|
async function generateReplicateVideo(req, ctx, deps) {
|
|
5206
5256
|
const id = isLower(ctx.model.providerModelId);
|
|
5207
|
-
const input = id.includes("kling") ? klingInput(req) : id.includes("hailuo") ? hailuoInput(req) : wanInput(req);
|
|
5257
|
+
const input = id.includes("kling") ? id.includes("omni") ? klingOmniInput(req) : klingInput(req) : id.includes("hailuo") ? hailuoInput(req) : wanInput(req);
|
|
5208
5258
|
const api = client(ctx, deps);
|
|
5209
5259
|
const createOptions = { ...route(ctx.model.providerModelId), input };
|
|
5210
5260
|
let prediction;
|
|
@@ -5294,6 +5344,9 @@ function lyriaAudioInput(req, ctx) {
|
|
|
5294
5344
|
if (negative) input.negative_prompt = negative;
|
|
5295
5345
|
return input;
|
|
5296
5346
|
}
|
|
5347
|
+
function elevenLabsMusicDuration(seconds) {
|
|
5348
|
+
return Math.min(300, Math.max(5, seconds ?? 15));
|
|
5349
|
+
}
|
|
5297
5350
|
function elevenLabsMusicInput(req, ctx) {
|
|
5298
5351
|
const prompt = req.prompt.trim();
|
|
5299
5352
|
if (!prompt) {
|
|
@@ -5305,10 +5358,9 @@ function elevenLabsMusicInput(req, ctx) {
|
|
|
5305
5358
|
retryable: false
|
|
5306
5359
|
});
|
|
5307
5360
|
}
|
|
5308
|
-
const seconds = Math.min(300, Math.max(5, req.durationSeconds ?? 15));
|
|
5309
5361
|
return {
|
|
5310
5362
|
prompt,
|
|
5311
|
-
music_length_ms:
|
|
5363
|
+
music_length_ms: elevenLabsMusicDuration(req.durationSeconds) * 1e3,
|
|
5312
5364
|
force_instrumental: req.instrumental ?? true,
|
|
5313
5365
|
output_format: "wav_cd_quality"
|
|
5314
5366
|
};
|
|
@@ -5348,7 +5400,13 @@ async function generateReplicateAudio(req, ctx, deps) {
|
|
|
5348
5400
|
const input = id.includes("mmaudio") ? mmaudioInput(req, ctx) : id.includes("elevenlabs") ? elevenLabsMusicInput(req, ctx) : lyriaAudioInput(req, ctx);
|
|
5349
5401
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|
|
5350
5402
|
const usage2 = audioUsage(ctx, req);
|
|
5351
|
-
|
|
5403
|
+
if (ctx.model.usage.unit === "seconds") {
|
|
5404
|
+
const seconds = elevenLabsMusicDuration(req.durationSeconds);
|
|
5405
|
+
usage2.quantity = seconds;
|
|
5406
|
+
usage2.durationSeconds = seconds;
|
|
5407
|
+
} else {
|
|
5408
|
+
usage2.quantity = predictTime;
|
|
5409
|
+
}
|
|
5352
5410
|
return { audio: { url }, usage: usage2, raw: predictionRaw(raw) };
|
|
5353
5411
|
}
|
|
5354
5412
|
|