@shop-os/modelkit 0.4.3 → 0.4.5

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/dist/catalog.js CHANGED
@@ -2499,16 +2499,26 @@ var ArraysSchema = z2.record(z2.string().min(1), z2.array(z2.string()).min(1)).s
2499
2499
  }
2500
2500
  }
2501
2501
  });
2502
+ var DimensionsSchema = z2.strictObject({
2503
+ field: z2.string().min(1),
2504
+ areas: z2.record(z2.string(), z2.number().int().positive()).refine((a) => Object.keys(a).length > 0, {
2505
+ message: "inputSpec.dimensions.areas must name at least one size"
2506
+ }),
2507
+ maxSide: z2.number().int().positive().optional(),
2508
+ multipleOf: z2.number().int().positive().optional()
2509
+ });
2502
2510
  var InputSpecSchema = z2.strictObject({
2503
2511
  fields: FieldsSchema,
2504
2512
  values: ValuesSchema.optional(),
2505
2513
  static: StaticSchema.optional(),
2506
2514
  arrays: ArraysSchema.optional(),
2507
- editEndpoint: z2.string().min(1).optional()
2515
+ editEndpoint: z2.string().min(1).optional(),
2516
+ dimensions: DimensionsSchema.optional()
2508
2517
  }).superRefine((spec, ctx) => {
2509
2518
  const mappedNames = /* @__PURE__ */ new Set([
2510
2519
  ...Object.values(spec.fields),
2511
- ...Object.keys(spec.arrays ?? {})
2520
+ ...Object.keys(spec.arrays ?? {}),
2521
+ ...spec.dimensions ? [spec.dimensions.field] : []
2512
2522
  ]);
2513
2523
  for (const key of Object.keys(spec.static ?? {})) {
2514
2524
  if (mappedNames.has(key)) {
@@ -2537,7 +2547,10 @@ function validateInputSpec(raw, row) {
2537
2547
  return {
2538
2548
  ok: false,
2539
2549
  issues: [
2540
- { path: [], message: "inputSpec is only supported on replicate and fal rows" }
2550
+ {
2551
+ path: [],
2552
+ message: "inputSpec is only supported on replicate and fal rows"
2553
+ }
2541
2554
  ]
2542
2555
  };
2543
2556
  }
@@ -2630,6 +2643,29 @@ function validateInputSpec(raw, row) {
2630
2643
  }
2631
2644
  }
2632
2645
  }
2646
+ if (spec.dimensions !== void 0) {
2647
+ if (row.type !== "image") {
2648
+ issues.push({
2649
+ path: ["dimensions"],
2650
+ message: "inputSpec.dimensions is only supported on image rows"
2651
+ });
2652
+ }
2653
+ for (const key of ["aspectRatio", "size"]) {
2654
+ if (key in spec.fields) {
2655
+ issues.push({
2656
+ path: ["fields", key],
2657
+ message: `inputSpec.fields "${key}" cannot be set with inputSpec.dimensions, which sends it`
2658
+ });
2659
+ }
2660
+ }
2661
+ const owner = seenNames.get(spec.dimensions.field);
2662
+ if (owner !== void 0 || spec.dimensions.field in (spec.arrays ?? {})) {
2663
+ issues.push({
2664
+ path: ["dimensions", "field"],
2665
+ message: `inputSpec.dimensions.field "${spec.dimensions.field}" is already a mapped provider field`
2666
+ });
2667
+ }
2668
+ }
2633
2669
  const supports = row.constraints.supports ?? [];
2634
2670
  for (const key of INPUT_SPEC_SUPPORTS_KEYS) {
2635
2671
  if (supports.includes(key)) continue;
@@ -3224,6 +3260,20 @@ function resetLiveCatalog() {
3224
3260
 
3225
3261
  // src/catalog/video-tools-spec.ts
3226
3262
  import { z as z6 } from "zod";
3263
+
3264
+ // src/video-length.ts
3265
+ function tenths(seconds2) {
3266
+ return Math.round(seconds2 * 10) / 10;
3267
+ }
3268
+ function overMax(seconds2, max) {
3269
+ return seconds2 > max && tenths(seconds2) > max;
3270
+ }
3271
+ function overTotal(lengths, total) {
3272
+ const sum = (values) => values.reduce((acc, len) => acc + len, 0);
3273
+ return sum(lengths) > total && tenths(sum(lengths.map(tenths))) > total;
3274
+ }
3275
+
3276
+ // src/catalog/video-tools-spec.ts
3227
3277
  var RangeSchema2 = z6.object({ min: z6.number(), max: z6.number() });
3228
3278
  var ToolSchema = z6.object({
3229
3279
  kind: z6.enum(["upscale", "interpolate", "hdr"]),
@@ -3267,7 +3317,7 @@ function planVideoTool(row, req) {
3267
3317
  return fail("The source video's width, height and duration are required");
3268
3318
  }
3269
3319
  const maxSeconds = row.constraints.sourceVideoSeconds?.max;
3270
- if (maxSeconds !== void 0 && durationSeconds > maxSeconds) {
3320
+ if (maxSeconds !== void 0 && overMax(durationSeconds, maxSeconds)) {
3271
3321
  return fail(`${row.label} takes source videos up to ${maxSeconds} seconds.`);
3272
3322
  }
3273
3323
  const base = {
@@ -3464,7 +3514,7 @@ function videoLengthViolation(model, input) {
3464
3514
  const lengths = (input.referenceVideos ?? []).map(knownLength);
3465
3515
  if (limits?.max !== void 0) {
3466
3516
  const max = limits.max;
3467
- const i = lengths.findIndex((len) => len !== void 0 && len > max);
3517
+ const i = lengths.findIndex((len) => len !== void 0 && overMax(len, max));
3468
3518
  if (i >= 0)
3469
3519
  return `${model.label} takes reference videos up to ${String(max)} s each; video ${i + 1} is ${seconds(lengths[i], max)} s.`;
3470
3520
  }
@@ -3476,14 +3526,17 @@ function videoLengthViolation(model, input) {
3476
3526
  const source = knownLength(input.sourceVideo);
3477
3527
  const sourceLimits = model.constraints.sourceVideoSeconds;
3478
3528
  if (limits?.total !== void 0) {
3479
- const refSum = lengths.reduce((acc, len) => acc + (len ?? 0), 0);
3480
- const sum = refSum + (sourceLimits?.inReferenceTotal ? source ?? 0 : 0);
3481
- if (sum > limits.total)
3529
+ const counted = [
3530
+ ...lengths.filter((len) => len !== void 0),
3531
+ ...sourceLimits?.inReferenceTotal && source !== void 0 ? [source] : []
3532
+ ];
3533
+ const sum = counted.reduce((acc, len) => acc + len, 0);
3534
+ if (overTotal(counted, limits.total))
3482
3535
  return `${model.label} takes reference videos up to ${String(limits.total)} s combined; these add up to ${seconds(sum, limits.total)} s.`;
3483
3536
  }
3484
3537
  if (source === void 0) return void 0;
3485
3538
  const sourceMin = effectiveMin(sourceLimits, input.taskType);
3486
- if (sourceLimits?.max !== void 0 && source > sourceLimits.max)
3539
+ if (sourceLimits?.max !== void 0 && overMax(source, sourceLimits.max))
3487
3540
  return `${model.label} takes a source video up to ${String(sourceLimits.max)} s; this one is ${seconds(source, sourceLimits.max)} s.`;
3488
3541
  if (sourceMin !== void 0 && source < sourceMin)
3489
3542
  return `${model.label} takes a source video of at least ${String(sourceMin)} s; this one is ${seconds(source, sourceMin)} s.`;