@shop-os/modelkit 0.3.1 → 0.3.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/CHANGELOG.md +19 -0
- package/README.md +2 -1
- package/dist/catalog.cjs +118 -5
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +12 -1
- package/dist/catalog.d.ts +12 -1
- package/dist/catalog.js +118 -5
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +136 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -3
- package/dist/index.d.ts +19 -3
- package/dist/index.js +134 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/catalog.d.cts
CHANGED
|
@@ -8,7 +8,7 @@ import { z } from 'zod';
|
|
|
8
8
|
|
|
9
9
|
/** The AI SDK video model spelling: a catalog id or a provider video model instance. */
|
|
10
10
|
type VideoModel = Parameters<typeof experimental_generateVideo>[0]["model"];
|
|
11
|
-
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";
|
|
11
|
+
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";
|
|
12
12
|
type ImageSize = "512" | "1K" | "2K" | "4K";
|
|
13
13
|
type VideoResolution = "360p" | "480p" | "720p" | "768p" | "1080p" | "2k" | "4k";
|
|
14
14
|
/** "xhigh" and "max" exist only on gpt-image-2.5; gpt-image-2 rejects them at the provider. */
|
|
@@ -393,6 +393,8 @@ interface CatalogCapabilities {
|
|
|
393
393
|
videoEdit?: boolean;
|
|
394
394
|
/** Video rows: first/last frames and reference images are mutually exclusive inputs. */
|
|
395
395
|
framesExcludeReferences?: boolean;
|
|
396
|
+
/** Video rows: a source video is never sent with first/last frames or reference images. */
|
|
397
|
+
sourceVideoExcludesFrames?: boolean;
|
|
396
398
|
/** Video rows: a last frame is accepted only together with a first frame. */
|
|
397
399
|
lastFrameRequiresFirstFrame?: boolean;
|
|
398
400
|
/** Text rows. `reasoning`: the model streams reasoning the UI should surface. */
|
|
@@ -689,6 +691,10 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
689
691
|
"21:9": "21:9";
|
|
690
692
|
"9:21": "9:21";
|
|
691
693
|
"97:30": "97:30";
|
|
694
|
+
"1:4": "1:4";
|
|
695
|
+
"4:1": "4:1";
|
|
696
|
+
"1:8": "1:8";
|
|
697
|
+
"8:1": "8:1";
|
|
692
698
|
adaptive: "adaptive";
|
|
693
699
|
}>>>;
|
|
694
700
|
sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
@@ -824,6 +830,10 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
824
830
|
"21:9": "21:9";
|
|
825
831
|
"9:21": "9:21";
|
|
826
832
|
"97:30": "97:30";
|
|
833
|
+
"1:4": "1:4";
|
|
834
|
+
"4:1": "4:1";
|
|
835
|
+
"1:8": "1:8";
|
|
836
|
+
"8:1": "8:1";
|
|
827
837
|
adaptive: "adaptive";
|
|
828
838
|
}>>;
|
|
829
839
|
size: z.ZodOptional<z.ZodEnum<{
|
|
@@ -986,6 +996,7 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
986
996
|
acceptsSourceVideo: z.ZodOptional<z.ZodBoolean>;
|
|
987
997
|
videoEdit: z.ZodOptional<z.ZodBoolean>;
|
|
988
998
|
framesExcludeReferences: z.ZodOptional<z.ZodBoolean>;
|
|
999
|
+
sourceVideoExcludesFrames: z.ZodOptional<z.ZodBoolean>;
|
|
989
1000
|
lastFrameRequiresFirstFrame: z.ZodOptional<z.ZodBoolean>;
|
|
990
1001
|
reasoning: z.ZodOptional<z.ZodBoolean>;
|
|
991
1002
|
vision: z.ZodOptional<z.ZodBoolean>;
|
package/dist/catalog.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { z } from 'zod';
|
|
|
8
8
|
|
|
9
9
|
/** The AI SDK video model spelling: a catalog id or a provider video model instance. */
|
|
10
10
|
type VideoModel = Parameters<typeof experimental_generateVideo>[0]["model"];
|
|
11
|
-
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";
|
|
11
|
+
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";
|
|
12
12
|
type ImageSize = "512" | "1K" | "2K" | "4K";
|
|
13
13
|
type VideoResolution = "360p" | "480p" | "720p" | "768p" | "1080p" | "2k" | "4k";
|
|
14
14
|
/** "xhigh" and "max" exist only on gpt-image-2.5; gpt-image-2 rejects them at the provider. */
|
|
@@ -393,6 +393,8 @@ interface CatalogCapabilities {
|
|
|
393
393
|
videoEdit?: boolean;
|
|
394
394
|
/** Video rows: first/last frames and reference images are mutually exclusive inputs. */
|
|
395
395
|
framesExcludeReferences?: boolean;
|
|
396
|
+
/** Video rows: a source video is never sent with first/last frames or reference images. */
|
|
397
|
+
sourceVideoExcludesFrames?: boolean;
|
|
396
398
|
/** Video rows: a last frame is accepted only together with a first frame. */
|
|
397
399
|
lastFrameRequiresFirstFrame?: boolean;
|
|
398
400
|
/** Text rows. `reasoning`: the model streams reasoning the UI should surface. */
|
|
@@ -689,6 +691,10 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
689
691
|
"21:9": "21:9";
|
|
690
692
|
"9:21": "9:21";
|
|
691
693
|
"97:30": "97:30";
|
|
694
|
+
"1:4": "1:4";
|
|
695
|
+
"4:1": "4:1";
|
|
696
|
+
"1:8": "1:8";
|
|
697
|
+
"8:1": "8:1";
|
|
692
698
|
adaptive: "adaptive";
|
|
693
699
|
}>>>;
|
|
694
700
|
sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
@@ -824,6 +830,10 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
824
830
|
"21:9": "21:9";
|
|
825
831
|
"9:21": "9:21";
|
|
826
832
|
"97:30": "97:30";
|
|
833
|
+
"1:4": "1:4";
|
|
834
|
+
"4:1": "4:1";
|
|
835
|
+
"1:8": "1:8";
|
|
836
|
+
"8:1": "8:1";
|
|
827
837
|
adaptive: "adaptive";
|
|
828
838
|
}>>;
|
|
829
839
|
size: z.ZodOptional<z.ZodEnum<{
|
|
@@ -986,6 +996,7 @@ declare const CatalogModelSchemaBase: z.ZodObject<{
|
|
|
986
996
|
acceptsSourceVideo: z.ZodOptional<z.ZodBoolean>;
|
|
987
997
|
videoEdit: z.ZodOptional<z.ZodBoolean>;
|
|
988
998
|
framesExcludeReferences: z.ZodOptional<z.ZodBoolean>;
|
|
999
|
+
sourceVideoExcludesFrames: z.ZodOptional<z.ZodBoolean>;
|
|
989
1000
|
lastFrameRequiresFirstFrame: z.ZodOptional<z.ZodBoolean>;
|
|
990
1001
|
reasoning: z.ZodOptional<z.ZodBoolean>;
|
|
991
1002
|
vision: z.ZodOptional<z.ZodBoolean>;
|
package/dist/catalog.js
CHANGED
|
@@ -158,13 +158,21 @@ var GEMINI_RATIOS = [
|
|
|
158
158
|
"5:4",
|
|
159
159
|
"adaptive"
|
|
160
160
|
];
|
|
161
|
+
var NANO_BANANA_2_1_RATIOS = [
|
|
162
|
+
...GEMINI_RATIOS.filter((r) => r !== "adaptive"),
|
|
163
|
+
"1:4",
|
|
164
|
+
"4:1",
|
|
165
|
+
"1:8",
|
|
166
|
+
"8:1",
|
|
167
|
+
"adaptive"
|
|
168
|
+
];
|
|
161
169
|
var GEMINI_PROMPT_MAX_CHARS = 5e4;
|
|
162
170
|
var GPT_IMAGE_PROMPT = { referenceSyntax: "numbered", maxChars: 32e3 };
|
|
163
|
-
function geminiImage(id, label, aliases, sizes, display, exposure, references, promptMaxChars) {
|
|
171
|
+
function geminiImage(id, label, aliases, sizes, display, exposure, references, promptMaxChars, aspectRatios = GEMINI_RATIOS) {
|
|
164
172
|
const prompt = { referenceSyntax: "caption" };
|
|
165
173
|
if (promptMaxChars !== void 0) prompt.maxChars = promptMaxChars;
|
|
166
174
|
const constraints = {
|
|
167
|
-
aspectRatios: [...
|
|
175
|
+
aspectRatios: [...aspectRatios],
|
|
168
176
|
sizes,
|
|
169
177
|
supports: ["safetySettings", "temperature"],
|
|
170
178
|
prompt
|
|
@@ -188,6 +196,21 @@ function geminiImage(id, label, aliases, sizes, display, exposure, references, p
|
|
|
188
196
|
return model;
|
|
189
197
|
}
|
|
190
198
|
var IMAGE_MODELS = [
|
|
199
|
+
geminiImage(
|
|
200
|
+
"gemini-nano-banana-2.1",
|
|
201
|
+
"Nano Banana 2.1",
|
|
202
|
+
["nb-2.1"],
|
|
203
|
+
["1K", "2K", "4K"],
|
|
204
|
+
{
|
|
205
|
+
provider: "google",
|
|
206
|
+
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.",
|
|
207
|
+
logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png"
|
|
208
|
+
},
|
|
209
|
+
["cowork", "space_builder"],
|
|
210
|
+
{ images: 14 },
|
|
211
|
+
GEMINI_PROMPT_MAX_CHARS,
|
|
212
|
+
NANO_BANANA_2_1_RATIOS
|
|
213
|
+
),
|
|
191
214
|
geminiImage(
|
|
192
215
|
"gemini-3-pro-image-preview",
|
|
193
216
|
"Nano Banana Pro",
|
|
@@ -2216,7 +2239,8 @@ var VIDEO_INPUT_SPEC_KEYS = [
|
|
|
2216
2239
|
"generateAudio",
|
|
2217
2240
|
"cfgScale",
|
|
2218
2241
|
"promptExpansion",
|
|
2219
|
-
"referenceImages"
|
|
2242
|
+
"referenceImages",
|
|
2243
|
+
"sourceVideo"
|
|
2220
2244
|
];
|
|
2221
2245
|
var IMAGE_INPUT_SPEC_KEYS = [
|
|
2222
2246
|
"prompt",
|
|
@@ -2235,6 +2259,12 @@ var AUDIO_INPUT_SPEC_KEYS = [
|
|
|
2235
2259
|
"sourceVideo",
|
|
2236
2260
|
"instrumental"
|
|
2237
2261
|
];
|
|
2262
|
+
var ARRAY_INPUT_SPEC_KEYS = [
|
|
2263
|
+
"firstFrame",
|
|
2264
|
+
"referenceImages",
|
|
2265
|
+
"lastFrame",
|
|
2266
|
+
"references"
|
|
2267
|
+
];
|
|
2238
2268
|
var INPUT_SPEC_SUPPORTS_KEYS = [
|
|
2239
2269
|
"lastFrame",
|
|
2240
2270
|
"seed",
|
|
@@ -2248,6 +2278,7 @@ var INPUT_SPEC_SUPPORTS_KEYS = [
|
|
|
2248
2278
|
var VIDEO_KEY_SET = new Set(VIDEO_INPUT_SPEC_KEYS);
|
|
2249
2279
|
var IMAGE_KEY_SET = new Set(IMAGE_INPUT_SPEC_KEYS);
|
|
2250
2280
|
var AUDIO_KEY_SET = new Set(AUDIO_INPUT_SPEC_KEYS);
|
|
2281
|
+
var ARRAY_KEY_SET = new Set(ARRAY_INPUT_SPEC_KEYS);
|
|
2251
2282
|
var ALL_KEY_SET = /* @__PURE__ */ new Set([
|
|
2252
2283
|
...VIDEO_INPUT_SPEC_KEYS,
|
|
2253
2284
|
...IMAGE_INPUT_SPEC_KEYS,
|
|
@@ -2292,13 +2323,30 @@ var ValuesSchema = z2.record(z2.string(), z2.record(z2.string(), ProviderScalarS
|
|
|
2292
2323
|
}
|
|
2293
2324
|
});
|
|
2294
2325
|
var StaticSchema = z2.record(z2.string(), ProviderScalarSchema);
|
|
2326
|
+
var ArraysSchema = z2.record(z2.string().min(1), z2.array(z2.string()).min(1)).superRefine((arrays, ctx) => {
|
|
2327
|
+
for (const [name, keys] of Object.entries(arrays)) {
|
|
2328
|
+
for (const key of keys) {
|
|
2329
|
+
if (!ARRAY_KEY_SET.has(key)) {
|
|
2330
|
+
ctx.addIssue({
|
|
2331
|
+
code: "custom",
|
|
2332
|
+
path: [name],
|
|
2333
|
+
message: `inputSpec.arrays "${name}" has unknown image key "${key}"`
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
});
|
|
2295
2339
|
var InputSpecSchema = z2.strictObject({
|
|
2296
2340
|
fields: FieldsSchema,
|
|
2297
2341
|
values: ValuesSchema.optional(),
|
|
2298
2342
|
static: StaticSchema.optional(),
|
|
2343
|
+
arrays: ArraysSchema.optional(),
|
|
2299
2344
|
editEndpoint: z2.string().min(1).optional()
|
|
2300
2345
|
}).superRefine((spec, ctx) => {
|
|
2301
|
-
const mappedNames = new Set(
|
|
2346
|
+
const mappedNames = /* @__PURE__ */ new Set([
|
|
2347
|
+
...Object.values(spec.fields),
|
|
2348
|
+
...Object.keys(spec.arrays ?? {})
|
|
2349
|
+
]);
|
|
2302
2350
|
for (const key of Object.keys(spec.static ?? {})) {
|
|
2303
2351
|
if (mappedNames.has(key)) {
|
|
2304
2352
|
ctx.addIssue({
|
|
@@ -2387,14 +2435,54 @@ function validateInputSpec(raw, row) {
|
|
|
2387
2435
|
});
|
|
2388
2436
|
}
|
|
2389
2437
|
}
|
|
2438
|
+
const arrayOwner = /* @__PURE__ */ new Map();
|
|
2439
|
+
for (const [name, keys] of Object.entries(spec.arrays ?? {})) {
|
|
2440
|
+
const fieldKey = seenNames.get(name);
|
|
2441
|
+
if (fieldKey !== void 0) {
|
|
2442
|
+
issues.push({
|
|
2443
|
+
path: ["arrays", name],
|
|
2444
|
+
message: `inputSpec.arrays "${name}" is also the provider field of inputSpec.fields "${fieldKey}"`
|
|
2445
|
+
});
|
|
2446
|
+
}
|
|
2447
|
+
for (const key of keys) {
|
|
2448
|
+
if (allowed !== void 0 && !allowed.has(key)) {
|
|
2449
|
+
issues.push({
|
|
2450
|
+
path: ["arrays", name],
|
|
2451
|
+
message: `inputSpec.arrays "${key}" is not supported for ${row.type} rows`
|
|
2452
|
+
});
|
|
2453
|
+
}
|
|
2454
|
+
if (key in spec.fields) {
|
|
2455
|
+
issues.push({
|
|
2456
|
+
path: ["arrays", name],
|
|
2457
|
+
message: `inputSpec.arrays "${key}" is already mapped in inputSpec.fields`
|
|
2458
|
+
});
|
|
2459
|
+
}
|
|
2460
|
+
const owner = arrayOwner.get(key);
|
|
2461
|
+
if (owner === void 0) arrayOwner.set(key, name);
|
|
2462
|
+
else {
|
|
2463
|
+
issues.push({
|
|
2464
|
+
path: ["arrays", name],
|
|
2465
|
+
message: owner === name ? `inputSpec.arrays "${name}" lists "${key}" twice` : `inputSpec.arrays "${owner}" and "${name}" both take "${key}"`
|
|
2466
|
+
});
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2390
2470
|
const supports = row.constraints.supports ?? [];
|
|
2391
2471
|
for (const key of INPUT_SPEC_SUPPORTS_KEYS) {
|
|
2392
|
-
if (
|
|
2472
|
+
if (supports.includes(key)) continue;
|
|
2473
|
+
if (key in spec.fields) {
|
|
2393
2474
|
issues.push({
|
|
2394
2475
|
path: ["fields", key],
|
|
2395
2476
|
message: `inputSpec.fields "${key}" needs "${key}" in constraints.supports`
|
|
2396
2477
|
});
|
|
2397
2478
|
}
|
|
2479
|
+
const arrayName = arrayOwner.get(key);
|
|
2480
|
+
if (arrayName !== void 0) {
|
|
2481
|
+
issues.push({
|
|
2482
|
+
path: ["arrays", arrayName],
|
|
2483
|
+
message: `inputSpec.arrays "${key}" needs "${key}" in constraints.supports`
|
|
2484
|
+
});
|
|
2485
|
+
}
|
|
2398
2486
|
}
|
|
2399
2487
|
if (issues.length > 0) return { ok: false, issues };
|
|
2400
2488
|
return { ok: true, spec };
|
|
@@ -2443,6 +2531,10 @@ var AspectRatioSchema = z3.enum([
|
|
|
2443
2531
|
"21:9",
|
|
2444
2532
|
"9:21",
|
|
2445
2533
|
"97:30",
|
|
2534
|
+
"1:4",
|
|
2535
|
+
"4:1",
|
|
2536
|
+
"1:8",
|
|
2537
|
+
"8:1",
|
|
2446
2538
|
"adaptive"
|
|
2447
2539
|
]);
|
|
2448
2540
|
var ImageSizeSchema = z3.enum(["512", "1K", "2K", "4K"]);
|
|
@@ -2612,6 +2704,7 @@ var CatalogCapabilitiesSchema = z3.looseObject({
|
|
|
2612
2704
|
acceptsSourceVideo: z3.boolean().optional(),
|
|
2613
2705
|
videoEdit: z3.boolean().optional(),
|
|
2614
2706
|
framesExcludeReferences: z3.boolean().optional(),
|
|
2707
|
+
sourceVideoExcludesFrames: z3.boolean().optional(),
|
|
2615
2708
|
lastFrameRequiresFirstFrame: z3.boolean().optional(),
|
|
2616
2709
|
reasoning: z3.boolean().optional(),
|
|
2617
2710
|
vision: z3.boolean().optional(),
|
|
@@ -3309,6 +3402,26 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
3309
3402
|
});
|
|
3310
3403
|
delete merged.sourceVideo;
|
|
3311
3404
|
}
|
|
3405
|
+
const imageInputs = ["firstFrame", "lastFrame", "referenceImages"].filter(
|
|
3406
|
+
(field) => field === "referenceImages" ? compact(merged.referenceImages).length > 0 : merged[field] !== void 0
|
|
3407
|
+
);
|
|
3408
|
+
if (merged.sourceVideo !== void 0 && imageInputs.length > 0 && model.capabilities?.sourceVideoExcludesFrames) {
|
|
3409
|
+
if (onUnsupported === "error") {
|
|
3410
|
+
throw new ModelKitError({
|
|
3411
|
+
code: "unsupported_option",
|
|
3412
|
+
message: `${model.id} takes a source video or images, not both`,
|
|
3413
|
+
model: model.id
|
|
3414
|
+
});
|
|
3415
|
+
}
|
|
3416
|
+
for (const field of imageInputs) {
|
|
3417
|
+
warnings.push({
|
|
3418
|
+
code: "option_ignored",
|
|
3419
|
+
field,
|
|
3420
|
+
message: `${model.id} takes a source video or images, not both; ${field} dropped`
|
|
3421
|
+
});
|
|
3422
|
+
delete merged[field];
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3312
3425
|
if (merged.lastFrame !== void 0 && merged.firstFrame === void 0 && model.capabilities?.lastFrameRequiresFirstFrame) {
|
|
3313
3426
|
if (onUnsupported === "error") {
|
|
3314
3427
|
throw new ModelKitError({
|