@shop-os/modelkit 0.3.0 → 0.3.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/CHANGELOG.md +21 -0
- package/README.md +3 -3
- package/dist/catalog.cjs +55 -7
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +9 -1
- package/dist/catalog.d.ts +9 -1
- package/dist/catalog.js +55 -7
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +165 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +165 -125
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -11,7 +11,7 @@ import { LanguageModelV3, LanguageModelV2 } from '@ai-sdk/provider';
|
|
|
11
11
|
|
|
12
12
|
/** The AI SDK video model spelling: a catalog id or a provider video model instance. */
|
|
13
13
|
type VideoModel = Parameters<typeof experimental_generateVideo>[0]["model"];
|
|
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";
|
|
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" | "1:4" | "4:1" | "1:8" | "8:1" | "adaptive";
|
|
15
15
|
type ImageSize = "512" | "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. */
|
|
@@ -716,6 +716,10 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
716
716
|
"21:9": "21:9";
|
|
717
717
|
"9:21": "9:21";
|
|
718
718
|
"97:30": "97:30";
|
|
719
|
+
"1:4": "1:4";
|
|
720
|
+
"4:1": "4:1";
|
|
721
|
+
"1:8": "1:8";
|
|
722
|
+
"8:1": "8:1";
|
|
719
723
|
adaptive: "adaptive";
|
|
720
724
|
}>>>;
|
|
721
725
|
sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
@@ -851,6 +855,10 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
851
855
|
"21:9": "21:9";
|
|
852
856
|
"9:21": "9:21";
|
|
853
857
|
"97:30": "97:30";
|
|
858
|
+
"1:4": "1:4";
|
|
859
|
+
"4:1": "4:1";
|
|
860
|
+
"1:8": "1:8";
|
|
861
|
+
"8:1": "8:1";
|
|
854
862
|
adaptive: "adaptive";
|
|
855
863
|
}>>;
|
|
856
864
|
size: z.ZodOptional<z.ZodEnum<{
|
|
@@ -1031,6 +1039,7 @@ declare const InputSpecSchema: z.ZodObject<{
|
|
|
1031
1039
|
fields: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1032
1040
|
values: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>>;
|
|
1033
1041
|
static: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
1042
|
+
editEndpoint: z.ZodOptional<z.ZodString>;
|
|
1034
1043
|
}, z.core.$strict>;
|
|
1035
1044
|
type InputSpec = z.infer<typeof InputSpecSchema>;
|
|
1036
1045
|
interface InputSpecIssue {
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { LanguageModelV3, LanguageModelV2 } from '@ai-sdk/provider';
|
|
|
11
11
|
|
|
12
12
|
/** The AI SDK video model spelling: a catalog id or a provider video model instance. */
|
|
13
13
|
type VideoModel = Parameters<typeof experimental_generateVideo>[0]["model"];
|
|
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";
|
|
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" | "1:4" | "4:1" | "1:8" | "8:1" | "adaptive";
|
|
15
15
|
type ImageSize = "512" | "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. */
|
|
@@ -716,6 +716,10 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
716
716
|
"21:9": "21:9";
|
|
717
717
|
"9:21": "9:21";
|
|
718
718
|
"97:30": "97:30";
|
|
719
|
+
"1:4": "1:4";
|
|
720
|
+
"4:1": "4:1";
|
|
721
|
+
"1:8": "1:8";
|
|
722
|
+
"8:1": "8:1";
|
|
719
723
|
adaptive: "adaptive";
|
|
720
724
|
}>>>;
|
|
721
725
|
sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
@@ -851,6 +855,10 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
851
855
|
"21:9": "21:9";
|
|
852
856
|
"9:21": "9:21";
|
|
853
857
|
"97:30": "97:30";
|
|
858
|
+
"1:4": "1:4";
|
|
859
|
+
"4:1": "4:1";
|
|
860
|
+
"1:8": "1:8";
|
|
861
|
+
"8:1": "8:1";
|
|
854
862
|
adaptive: "adaptive";
|
|
855
863
|
}>>;
|
|
856
864
|
size: z.ZodOptional<z.ZodEnum<{
|
|
@@ -1031,6 +1039,7 @@ declare const InputSpecSchema: z.ZodObject<{
|
|
|
1031
1039
|
fields: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1032
1040
|
values: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>>;
|
|
1033
1041
|
static: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
1042
|
+
editEndpoint: z.ZodOptional<z.ZodString>;
|
|
1034
1043
|
}, z.core.$strict>;
|
|
1035
1044
|
type InputSpec = z.infer<typeof InputSpecSchema>;
|
|
1036
1045
|
interface InputSpecIssue {
|
package/dist/index.js
CHANGED
|
@@ -169,13 +169,21 @@ var GEMINI_RATIOS = [
|
|
|
169
169
|
"5:4",
|
|
170
170
|
"adaptive"
|
|
171
171
|
];
|
|
172
|
+
var NANO_BANANA_2_1_RATIOS = [
|
|
173
|
+
...GEMINI_RATIOS.filter((r) => r !== "adaptive"),
|
|
174
|
+
"1:4",
|
|
175
|
+
"4:1",
|
|
176
|
+
"1:8",
|
|
177
|
+
"8:1",
|
|
178
|
+
"adaptive"
|
|
179
|
+
];
|
|
172
180
|
var GEMINI_PROMPT_MAX_CHARS = 5e4;
|
|
173
181
|
var GPT_IMAGE_PROMPT = { referenceSyntax: "numbered", maxChars: 32e3 };
|
|
174
|
-
function geminiImage(id, label, aliases, sizes, display, exposure, references, promptMaxChars) {
|
|
182
|
+
function geminiImage(id, label, aliases, sizes, display, exposure, references, promptMaxChars, aspectRatios = GEMINI_RATIOS) {
|
|
175
183
|
const prompt = { referenceSyntax: "caption" };
|
|
176
184
|
if (promptMaxChars !== void 0) prompt.maxChars = promptMaxChars;
|
|
177
185
|
const constraints = {
|
|
178
|
-
aspectRatios: [...
|
|
186
|
+
aspectRatios: [...aspectRatios],
|
|
179
187
|
sizes,
|
|
180
188
|
supports: ["safetySettings", "temperature"],
|
|
181
189
|
prompt
|
|
@@ -199,6 +207,21 @@ function geminiImage(id, label, aliases, sizes, display, exposure, references, p
|
|
|
199
207
|
return model;
|
|
200
208
|
}
|
|
201
209
|
var IMAGE_MODELS = [
|
|
210
|
+
geminiImage(
|
|
211
|
+
"gemini-nano-banana-2.1",
|
|
212
|
+
"Nano Banana 2.1",
|
|
213
|
+
["nb-2.1"],
|
|
214
|
+
["1K", "2K", "4K"],
|
|
215
|
+
{
|
|
216
|
+
provider: "google",
|
|
217
|
+
description: "Latest high-efficiency Nano Banana. Better realism, prompt adherence, text rendering and character consistency at Flash speed. Great for campaigns, infographics, and iterative edits.",
|
|
218
|
+
logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png"
|
|
219
|
+
},
|
|
220
|
+
["cowork", "space_builder"],
|
|
221
|
+
{ images: 14 },
|
|
222
|
+
GEMINI_PROMPT_MAX_CHARS,
|
|
223
|
+
NANO_BANANA_2_1_RATIOS
|
|
224
|
+
),
|
|
202
225
|
geminiImage(
|
|
203
226
|
"gemini-3-pro-image-preview",
|
|
204
227
|
"Nano Banana Pro",
|
|
@@ -2252,6 +2275,10 @@ var ALL_KEY_SET = /* @__PURE__ */ new Set([
|
|
|
2252
2275
|
...IMAGE_INPUT_SPEC_KEYS,
|
|
2253
2276
|
...AUDIO_INPUT_SPEC_KEYS
|
|
2254
2277
|
]);
|
|
2278
|
+
var TYPES_BY_ADAPTER = /* @__PURE__ */ new Map([
|
|
2279
|
+
["replicate", ["video", "image", "audio"]],
|
|
2280
|
+
["fal", ["image"]]
|
|
2281
|
+
]);
|
|
2255
2282
|
var ALLOWED_KEYS_BY_TYPE = /* @__PURE__ */ new Map([
|
|
2256
2283
|
["video", VIDEO_KEY_SET],
|
|
2257
2284
|
["image", IMAGE_KEY_SET],
|
|
@@ -2290,7 +2317,8 @@ var StaticSchema = z2.record(z2.string(), ProviderScalarSchema);
|
|
|
2290
2317
|
var InputSpecSchema = z2.strictObject({
|
|
2291
2318
|
fields: FieldsSchema,
|
|
2292
2319
|
values: ValuesSchema.optional(),
|
|
2293
|
-
static: StaticSchema.optional()
|
|
2320
|
+
static: StaticSchema.optional(),
|
|
2321
|
+
editEndpoint: z2.string().min(1).optional()
|
|
2294
2322
|
}).superRefine((spec, ctx) => {
|
|
2295
2323
|
const mappedNames = new Set(Object.values(spec.fields));
|
|
2296
2324
|
for (const key of Object.keys(spec.static ?? {})) {
|
|
@@ -2318,18 +2346,21 @@ function validateInputSpec(raw, row) {
|
|
|
2318
2346
|
};
|
|
2319
2347
|
}
|
|
2320
2348
|
const spec = parsed.data;
|
|
2321
|
-
|
|
2349
|
+
const supportedTypes = TYPES_BY_ADAPTER.get(row.adapter);
|
|
2350
|
+
if (supportedTypes === void 0) {
|
|
2322
2351
|
return {
|
|
2323
2352
|
ok: false,
|
|
2324
|
-
issues: [
|
|
2353
|
+
issues: [
|
|
2354
|
+
{ path: [], message: "inputSpec is only supported on replicate and fal rows" }
|
|
2355
|
+
]
|
|
2325
2356
|
};
|
|
2326
2357
|
}
|
|
2327
2358
|
const issues = [];
|
|
2328
2359
|
const allowed = ALLOWED_KEYS_BY_TYPE.get(row.type);
|
|
2329
|
-
if (allowed === void 0) {
|
|
2360
|
+
if (allowed === void 0 || !supportedTypes.includes(row.type)) {
|
|
2330
2361
|
issues.push({
|
|
2331
2362
|
path: [],
|
|
2332
|
-
message: `inputSpec is not supported for "${row.type}" rows`
|
|
2363
|
+
message: row.adapter === "fal" ? `inputSpec on fal rows is only supported for image rows, not "${row.type}"` : `inputSpec is not supported for "${row.type}" rows`
|
|
2333
2364
|
});
|
|
2334
2365
|
} else {
|
|
2335
2366
|
for (const key of Object.keys(spec.fields)) {
|
|
@@ -2349,6 +2380,19 @@ function validateInputSpec(raw, row) {
|
|
|
2349
2380
|
}
|
|
2350
2381
|
}
|
|
2351
2382
|
}
|
|
2383
|
+
if (spec.editEndpoint !== void 0) {
|
|
2384
|
+
if (row.adapter !== "fal") {
|
|
2385
|
+
issues.push({
|
|
2386
|
+
path: ["editEndpoint"],
|
|
2387
|
+
message: "inputSpec.editEndpoint is only supported on fal rows"
|
|
2388
|
+
});
|
|
2389
|
+
} else if (!("references" in spec.fields)) {
|
|
2390
|
+
issues.push({
|
|
2391
|
+
path: ["editEndpoint"],
|
|
2392
|
+
message: 'inputSpec.editEndpoint needs a "references" entry in inputSpec.fields'
|
|
2393
|
+
});
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2352
2396
|
const seenNames = /* @__PURE__ */ new Map();
|
|
2353
2397
|
for (const [key, name] of Object.entries(spec.fields)) {
|
|
2354
2398
|
const first = seenNames.get(name);
|
|
@@ -2424,6 +2468,10 @@ var AspectRatioSchema = z3.enum([
|
|
|
2424
2468
|
"21:9",
|
|
2425
2469
|
"9:21",
|
|
2426
2470
|
"97:30",
|
|
2471
|
+
"1:4",
|
|
2472
|
+
"4:1",
|
|
2473
|
+
"1:8",
|
|
2474
|
+
"8:1",
|
|
2427
2475
|
"adaptive"
|
|
2428
2476
|
]);
|
|
2429
2477
|
var ImageSizeSchema = z3.enum(["512", "1K", "2K", "4K"]);
|
|
@@ -4093,6 +4141,70 @@ async function cancelFalVideoTool(sub, ctx) {
|
|
|
4093
4141
|
throw falError(res.status, await readBody(res), ctx.model.id);
|
|
4094
4142
|
}
|
|
4095
4143
|
|
|
4144
|
+
// src/adapters/input-spec-mapper.ts
|
|
4145
|
+
function canonicalValue(req, key) {
|
|
4146
|
+
return req[key];
|
|
4147
|
+
}
|
|
4148
|
+
function isMediaRef(value) {
|
|
4149
|
+
return value instanceof Object && ("url" in value || "bytes" in value);
|
|
4150
|
+
}
|
|
4151
|
+
function toProviderValue(value, refToUrl2) {
|
|
4152
|
+
if (Array.isArray(value)) {
|
|
4153
|
+
return value.map(refToUrl2);
|
|
4154
|
+
}
|
|
4155
|
+
if (isMediaRef(value)) {
|
|
4156
|
+
return refToUrl2(value);
|
|
4157
|
+
}
|
|
4158
|
+
return value;
|
|
4159
|
+
}
|
|
4160
|
+
function applyInputSpec(spec, req, refToUrl2, opts) {
|
|
4161
|
+
const out = {};
|
|
4162
|
+
for (const [canonical, providerField] of Object.entries(spec.fields)) {
|
|
4163
|
+
if (!isInputSpecKey(canonical)) continue;
|
|
4164
|
+
const value = canonicalValue(req, canonical);
|
|
4165
|
+
if (value === void 0) continue;
|
|
4166
|
+
if (opts?.omit?.(canonical, value)) continue;
|
|
4167
|
+
const serialised = toProviderValue(value, refToUrl2);
|
|
4168
|
+
const mapped = spec.values?.[canonical]?.[String(value)];
|
|
4169
|
+
out[providerField] = mapped ?? serialised;
|
|
4170
|
+
}
|
|
4171
|
+
for (const [key, value] of Object.entries(spec.static ?? {})) {
|
|
4172
|
+
out[key] = value;
|
|
4173
|
+
}
|
|
4174
|
+
return out;
|
|
4175
|
+
}
|
|
4176
|
+
function resolveRowInputSpec(req, ctx) {
|
|
4177
|
+
const raw = ctx.model.providerOptions?.["modelkit"]?.["inputSpec"];
|
|
4178
|
+
if (raw === void 0) return { kind: "absent" };
|
|
4179
|
+
const result = validateInputSpec(raw, ctx.model);
|
|
4180
|
+
if (!result.ok) {
|
|
4181
|
+
ctx.logger.warn(
|
|
4182
|
+
`[modelkit] ${ctx.model.id} has an invalid providerOptions.modelkit.inputSpec; the call fails`
|
|
4183
|
+
);
|
|
4184
|
+
return { kind: "invalid", issues: result.issues };
|
|
4185
|
+
}
|
|
4186
|
+
return {
|
|
4187
|
+
kind: "ok",
|
|
4188
|
+
spec: result.spec,
|
|
4189
|
+
input: applyInputSpec(result.spec, req, refToUrl, {
|
|
4190
|
+
omit: (key, value) => key === "aspectRatio" && value === "adaptive"
|
|
4191
|
+
})
|
|
4192
|
+
};
|
|
4193
|
+
}
|
|
4194
|
+
function describeInputSpecIssue(issue) {
|
|
4195
|
+
if (!issue) return "invalid inputSpec";
|
|
4196
|
+
return issue.path.length === 0 ? issue.message : `${issue.path.map((part) => String(part)).join(".")} ${issue.message}`;
|
|
4197
|
+
}
|
|
4198
|
+
function invalidInputSpecError(provider, ctx, issues) {
|
|
4199
|
+
return new ModelKitError({
|
|
4200
|
+
code: "unsupported_option",
|
|
4201
|
+
message: `${provider} row "${ctx.model.id}" has an invalid providerOptions.modelkit.inputSpec: ${describeInputSpecIssue(issues[0])}`,
|
|
4202
|
+
provider,
|
|
4203
|
+
model: ctx.model.id,
|
|
4204
|
+
retryable: false
|
|
4205
|
+
});
|
|
4206
|
+
}
|
|
4207
|
+
|
|
4096
4208
|
// src/adapters/fal.ts
|
|
4097
4209
|
var MUSE_T2I_ENDPOINT = "meta/muse-image/text-to-image";
|
|
4098
4210
|
var MUSE_EDIT_ENDPOINT = "meta/muse-image/edit";
|
|
@@ -4147,6 +4259,11 @@ function createFalAdapter(deps = defaultDeps) {
|
|
|
4147
4259
|
id: "fal",
|
|
4148
4260
|
generateImage: (req, ctx) => {
|
|
4149
4261
|
throwIfAborted(ctx.signal);
|
|
4262
|
+
const spec = resolveRowInputSpec(req, ctx);
|
|
4263
|
+
if (spec.kind === "invalid") {
|
|
4264
|
+
return Promise.reject(invalidInputSpecError("fal", ctx, spec.issues));
|
|
4265
|
+
}
|
|
4266
|
+
if (spec.kind === "ok") return generateSpecImage(req, ctx, deps, spec);
|
|
4150
4267
|
if (isIdeogram(ctx.model.providerModelId)) return generateIdeogramImage(req, ctx, deps);
|
|
4151
4268
|
return generateMuseImage(req, ctx, deps);
|
|
4152
4269
|
},
|
|
@@ -4326,6 +4443,36 @@ var museImageResultSchema = z12.object({
|
|
|
4326
4443
|
})
|
|
4327
4444
|
).optional()
|
|
4328
4445
|
});
|
|
4446
|
+
async function collectFalImages(payload, ctx, req, label) {
|
|
4447
|
+
const parsed = museImageResultSchema.safeParse(payload);
|
|
4448
|
+
const images = parsed.success ? parsed.data.images ?? [] : [];
|
|
4449
|
+
const files = await Promise.all(
|
|
4450
|
+
images.flatMap((img) => {
|
|
4451
|
+
if (img.url === void 0) return [];
|
|
4452
|
+
return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
|
|
4453
|
+
})
|
|
4454
|
+
);
|
|
4455
|
+
if (files.length === 0) {
|
|
4456
|
+
throw new ModelKitError({
|
|
4457
|
+
code: "provider_rejected",
|
|
4458
|
+
message: `${label} returned no image`,
|
|
4459
|
+
provider: "fal",
|
|
4460
|
+
model: ctx.model.id,
|
|
4461
|
+
retryable: false
|
|
4462
|
+
});
|
|
4463
|
+
}
|
|
4464
|
+
return {
|
|
4465
|
+
images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
|
|
4466
|
+
usage: imageUsage(ctx, req, files.length),
|
|
4467
|
+
raw: payload
|
|
4468
|
+
};
|
|
4469
|
+
}
|
|
4470
|
+
async function generateSpecImage(req, ctx, deps, spec) {
|
|
4471
|
+
const hasReferences = (req.references ?? []).length > 0;
|
|
4472
|
+
const endpoint = hasReferences && spec.spec.editEndpoint !== void 0 ? spec.spec.editEndpoint : ctx.model.providerModelId;
|
|
4473
|
+
const payload = await runJob(ctx, deps, endpoint, spec.input);
|
|
4474
|
+
return collectFalImages(payload, ctx, req, `fal ${endpoint}`);
|
|
4475
|
+
}
|
|
4329
4476
|
async function generateMuseImage(req, ctx, deps) {
|
|
4330
4477
|
const refs = (req.references ?? []).map(refToUrl);
|
|
4331
4478
|
const isEdit = refs.length > 0;
|
|
@@ -4342,29 +4489,7 @@ async function generateMuseImage(req, ctx, deps) {
|
|
|
4342
4489
|
const custom = id.includes("/") && !id.startsWith("meta/muse-image") ? id : void 0;
|
|
4343
4490
|
const endpoint = custom ?? (isEdit ? MUSE_EDIT_ENDPOINT : MUSE_T2I_ENDPOINT);
|
|
4344
4491
|
const payload = await runJob(ctx, deps, endpoint, input);
|
|
4345
|
-
|
|
4346
|
-
const images = parsed.success ? parsed.data.images ?? [] : [];
|
|
4347
|
-
const firstUrl = images[0]?.url;
|
|
4348
|
-
if (images.length === 0 || firstUrl === void 0) {
|
|
4349
|
-
throw new ModelKitError({
|
|
4350
|
-
code: "provider_rejected",
|
|
4351
|
-
message: "fal Meta Muse returned no image",
|
|
4352
|
-
provider: "fal",
|
|
4353
|
-
model: ctx.model.id,
|
|
4354
|
-
retryable: false
|
|
4355
|
-
});
|
|
4356
|
-
}
|
|
4357
|
-
const files = await Promise.all(
|
|
4358
|
-
images.flatMap((img) => {
|
|
4359
|
-
if (img.url === void 0) return [];
|
|
4360
|
-
return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
|
|
4361
|
-
})
|
|
4362
|
-
);
|
|
4363
|
-
return {
|
|
4364
|
-
images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
|
|
4365
|
-
usage: imageUsage(ctx, req, files.length),
|
|
4366
|
-
raw: payload
|
|
4367
|
-
};
|
|
4492
|
+
return collectFalImages(payload, ctx, req, "fal Meta Muse");
|
|
4368
4493
|
}
|
|
4369
4494
|
var IDEOGRAM_MODEL_IDS = /* @__PURE__ */ new Set(["ideogram/v4.5"]);
|
|
4370
4495
|
function isIdeogram(providerModelId) {
|
|
@@ -4409,28 +4534,7 @@ async function generateIdeogramImage(req, ctx, deps) {
|
|
|
4409
4534
|
if (references.length > 0) input.reference_image_urls = references;
|
|
4410
4535
|
}
|
|
4411
4536
|
const payload = await runJob(ctx, deps, endpoint, input);
|
|
4412
|
-
|
|
4413
|
-
const images = parsed.success ? parsed.data.images ?? [] : [];
|
|
4414
|
-
const files = await Promise.all(
|
|
4415
|
-
images.flatMap((img) => {
|
|
4416
|
-
if (img.url === void 0) return [];
|
|
4417
|
-
return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
|
|
4418
|
-
})
|
|
4419
|
-
);
|
|
4420
|
-
if (files.length === 0) {
|
|
4421
|
-
throw new ModelKitError({
|
|
4422
|
-
code: "provider_rejected",
|
|
4423
|
-
message: "fal Ideogram returned no image",
|
|
4424
|
-
provider: "fal",
|
|
4425
|
-
model: ctx.model.id,
|
|
4426
|
-
retryable: false
|
|
4427
|
-
});
|
|
4428
|
-
}
|
|
4429
|
-
return {
|
|
4430
|
-
images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
|
|
4431
|
-
usage: imageUsage(ctx, req, files.length),
|
|
4432
|
-
raw: payload
|
|
4433
|
-
};
|
|
4537
|
+
return collectFalImages(payload, ctx, req, "fal Ideogram");
|
|
4434
4538
|
}
|
|
4435
4539
|
var H3_MAX_MODEL_IDS = /* @__PURE__ */ new Set([
|
|
4436
4540
|
"minimax/h3-max",
|
|
@@ -6781,41 +6885,6 @@ function createReplicateHttpClient(opts) {
|
|
|
6781
6885
|
|
|
6782
6886
|
// src/adapters/replicate.ts
|
|
6783
6887
|
import { z as z19 } from "zod";
|
|
6784
|
-
|
|
6785
|
-
// src/adapters/input-spec-mapper.ts
|
|
6786
|
-
function canonicalValue(req, key) {
|
|
6787
|
-
return req[key];
|
|
6788
|
-
}
|
|
6789
|
-
function isMediaRef(value) {
|
|
6790
|
-
return value instanceof Object && ("url" in value || "bytes" in value);
|
|
6791
|
-
}
|
|
6792
|
-
function toProviderValue(value, refToUrl2) {
|
|
6793
|
-
if (Array.isArray(value)) {
|
|
6794
|
-
return value.map(refToUrl2);
|
|
6795
|
-
}
|
|
6796
|
-
if (isMediaRef(value)) {
|
|
6797
|
-
return refToUrl2(value);
|
|
6798
|
-
}
|
|
6799
|
-
return value;
|
|
6800
|
-
}
|
|
6801
|
-
function applyInputSpec(spec, req, refToUrl2, opts) {
|
|
6802
|
-
const out = {};
|
|
6803
|
-
for (const [canonical, providerField] of Object.entries(spec.fields)) {
|
|
6804
|
-
if (!isInputSpecKey(canonical)) continue;
|
|
6805
|
-
const value = canonicalValue(req, canonical);
|
|
6806
|
-
if (value === void 0) continue;
|
|
6807
|
-
if (opts?.omit?.(canonical, value)) continue;
|
|
6808
|
-
const serialised = toProviderValue(value, refToUrl2);
|
|
6809
|
-
const mapped = spec.values?.[canonical]?.[String(value)];
|
|
6810
|
-
out[providerField] = mapped ?? serialised;
|
|
6811
|
-
}
|
|
6812
|
-
for (const [key, value] of Object.entries(spec.static ?? {})) {
|
|
6813
|
-
out[key] = value;
|
|
6814
|
-
}
|
|
6815
|
-
return out;
|
|
6816
|
-
}
|
|
6817
|
-
|
|
6818
|
-
// src/adapters/replicate.ts
|
|
6819
6888
|
var POLL_INTERVAL_MS = 1e3;
|
|
6820
6889
|
var POLL_TIMEOUT_MS = 15 * 6e4;
|
|
6821
6890
|
var defaultReplicateDeps = {
|
|
@@ -7058,38 +7127,6 @@ function replicateNoMapper(ctx, section) {
|
|
|
7058
7127
|
retryable: false
|
|
7059
7128
|
});
|
|
7060
7129
|
}
|
|
7061
|
-
function describeInputSpecIssue(issue) {
|
|
7062
|
-
if (!issue) return "invalid inputSpec";
|
|
7063
|
-
return issue.path.length === 0 ? issue.message : `${issue.path.map((part) => String(part)).join(".")} ${issue.message}`;
|
|
7064
|
-
}
|
|
7065
|
-
function replicateInvalidSpec(ctx, issues) {
|
|
7066
|
-
const detail = describeInputSpecIssue(issues[0]);
|
|
7067
|
-
return new ModelKitError({
|
|
7068
|
-
code: "unsupported_option",
|
|
7069
|
-
message: `replicate row "${ctx.model.id}" has an invalid providerOptions.modelkit.inputSpec: ${detail}`,
|
|
7070
|
-
provider: "replicate",
|
|
7071
|
-
model: ctx.model.id,
|
|
7072
|
-
retryable: false
|
|
7073
|
-
});
|
|
7074
|
-
}
|
|
7075
|
-
function omitAdaptive(key, value) {
|
|
7076
|
-
return key === "aspectRatio" && value === "adaptive";
|
|
7077
|
-
}
|
|
7078
|
-
function replicateInputSpec(req, ctx) {
|
|
7079
|
-
const raw = ctx.model.providerOptions?.["modelkit"]?.["inputSpec"];
|
|
7080
|
-
if (raw === void 0) return { kind: "absent" };
|
|
7081
|
-
const result = validateInputSpec(raw, ctx.model);
|
|
7082
|
-
if (!result.ok) {
|
|
7083
|
-
ctx.logger.warn(
|
|
7084
|
-
`[modelkit] ${ctx.model.id} has an invalid providerOptions.modelkit.inputSpec; the call fails`
|
|
7085
|
-
);
|
|
7086
|
-
return { kind: "invalid", issues: result.issues };
|
|
7087
|
-
}
|
|
7088
|
-
return {
|
|
7089
|
-
kind: "ok",
|
|
7090
|
-
input: applyInputSpec(result.spec, req, refToUrl, { omit: omitAdaptive })
|
|
7091
|
-
};
|
|
7092
|
-
}
|
|
7093
7130
|
var QWEN_IMAGE_RATIOS = /* @__PURE__ */ new Set([
|
|
7094
7131
|
"1:1",
|
|
7095
7132
|
"16:9",
|
|
@@ -7233,8 +7270,9 @@ async function generateReplicateImage(req, ctx, deps) {
|
|
|
7233
7270
|
break;
|
|
7234
7271
|
}
|
|
7235
7272
|
default: {
|
|
7236
|
-
const specResult =
|
|
7237
|
-
if (specResult.kind === "invalid")
|
|
7273
|
+
const specResult = resolveRowInputSpec(req, ctx);
|
|
7274
|
+
if (specResult.kind === "invalid")
|
|
7275
|
+
throw invalidInputSpecError("replicate", ctx, specResult.issues);
|
|
7238
7276
|
if (specResult.kind === "ok") {
|
|
7239
7277
|
input = specResult.input;
|
|
7240
7278
|
break;
|
|
@@ -7314,9 +7352,10 @@ async function generateReplicateVideo(req, ctx, deps) {
|
|
|
7314
7352
|
else if (kind === "kling-omni") input = klingOmniInput(req);
|
|
7315
7353
|
else if (kind === "hailuo") input = hailuoInput(req);
|
|
7316
7354
|
else {
|
|
7317
|
-
const specResult =
|
|
7355
|
+
const specResult = resolveRowInputSpec(req, ctx);
|
|
7318
7356
|
if (specResult.kind === "absent") throw replicateNoMapper(ctx, "video");
|
|
7319
|
-
if (specResult.kind === "invalid")
|
|
7357
|
+
if (specResult.kind === "invalid")
|
|
7358
|
+
throw invalidInputSpecError("replicate", ctx, specResult.issues);
|
|
7320
7359
|
input = specResult.input;
|
|
7321
7360
|
}
|
|
7322
7361
|
const api = client(ctx, deps);
|
|
@@ -7471,9 +7510,10 @@ async function generateReplicateAudio(req, ctx, deps) {
|
|
|
7471
7510
|
else if (kind === "elevenlabs") input = elevenLabsMusicInput(req, ctx);
|
|
7472
7511
|
else if (kind === "lyria") input = lyriaAudioInput(req, ctx);
|
|
7473
7512
|
else {
|
|
7474
|
-
const specResult =
|
|
7513
|
+
const specResult = resolveRowInputSpec(req, ctx);
|
|
7475
7514
|
if (specResult.kind === "absent") throw replicateNoMapper(ctx, "audio");
|
|
7476
|
-
if (specResult.kind === "invalid")
|
|
7515
|
+
if (specResult.kind === "invalid")
|
|
7516
|
+
throw invalidInputSpecError("replicate", ctx, specResult.issues);
|
|
7477
7517
|
input = specResult.input;
|
|
7478
7518
|
}
|
|
7479
7519
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|