@shop-os/modelkit 0.4.2 → 0.4.4

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/index.cjs CHANGED
@@ -2617,16 +2617,26 @@ var ArraysSchema = import_zod2.z.record(import_zod2.z.string().min(1), import_zo
2617
2617
  }
2618
2618
  }
2619
2619
  });
2620
+ var DimensionsSchema = import_zod2.z.strictObject({
2621
+ field: import_zod2.z.string().min(1),
2622
+ areas: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.number().int().positive()).refine((a) => Object.keys(a).length > 0, {
2623
+ message: "inputSpec.dimensions.areas must name at least one size"
2624
+ }),
2625
+ maxSide: import_zod2.z.number().int().positive().optional(),
2626
+ multipleOf: import_zod2.z.number().int().positive().optional()
2627
+ });
2620
2628
  var InputSpecSchema = import_zod2.z.strictObject({
2621
2629
  fields: FieldsSchema,
2622
2630
  values: ValuesSchema.optional(),
2623
2631
  static: StaticSchema.optional(),
2624
2632
  arrays: ArraysSchema.optional(),
2625
- editEndpoint: import_zod2.z.string().min(1).optional()
2633
+ editEndpoint: import_zod2.z.string().min(1).optional(),
2634
+ dimensions: DimensionsSchema.optional()
2626
2635
  }).superRefine((spec, ctx) => {
2627
2636
  const mappedNames = /* @__PURE__ */ new Set([
2628
2637
  ...Object.values(spec.fields),
2629
- ...Object.keys(spec.arrays ?? {})
2638
+ ...Object.keys(spec.arrays ?? {}),
2639
+ ...spec.dimensions ? [spec.dimensions.field] : []
2630
2640
  ]);
2631
2641
  for (const key of Object.keys(spec.static ?? {})) {
2632
2642
  if (mappedNames.has(key)) {
@@ -2661,7 +2671,10 @@ function validateInputSpec(raw, row) {
2661
2671
  return {
2662
2672
  ok: false,
2663
2673
  issues: [
2664
- { path: [], message: "inputSpec is only supported on replicate and fal rows" }
2674
+ {
2675
+ path: [],
2676
+ message: "inputSpec is only supported on replicate and fal rows"
2677
+ }
2665
2678
  ]
2666
2679
  };
2667
2680
  }
@@ -2754,6 +2767,29 @@ function validateInputSpec(raw, row) {
2754
2767
  }
2755
2768
  }
2756
2769
  }
2770
+ if (spec.dimensions !== void 0) {
2771
+ if (row.type !== "image") {
2772
+ issues.push({
2773
+ path: ["dimensions"],
2774
+ message: "inputSpec.dimensions is only supported on image rows"
2775
+ });
2776
+ }
2777
+ for (const key of ["aspectRatio", "size"]) {
2778
+ if (key in spec.fields) {
2779
+ issues.push({
2780
+ path: ["fields", key],
2781
+ message: `inputSpec.fields "${key}" cannot be set with inputSpec.dimensions, which sends it`
2782
+ });
2783
+ }
2784
+ }
2785
+ const owner = seenNames.get(spec.dimensions.field);
2786
+ if (owner !== void 0 || spec.dimensions.field in (spec.arrays ?? {})) {
2787
+ issues.push({
2788
+ path: ["dimensions", "field"],
2789
+ message: `inputSpec.dimensions.field "${spec.dimensions.field}" is already a mapped provider field`
2790
+ });
2791
+ }
2792
+ }
2757
2793
  const supports = row.constraints.supports ?? [];
2758
2794
  for (const key of INPUT_SPEC_SUPPORTS_KEYS) {
2759
2795
  if (supports.includes(key)) continue;
@@ -4570,11 +4606,37 @@ function applyInputSpec(spec, req, refToUrl2, opts) {
4570
4606
  }
4571
4607
  if (urls.length > 0) out[providerField] = urls;
4572
4608
  }
4609
+ if (spec.dimensions !== void 0) {
4610
+ const dims = dimensionsFor(spec.dimensions, req);
4611
+ if (dims !== void 0) out[spec.dimensions.field] = dims;
4612
+ }
4573
4613
  for (const [key, value] of Object.entries(spec.static ?? {})) {
4574
4614
  out[key] = value;
4575
4615
  }
4576
4616
  return out;
4577
4617
  }
4618
+ function dimensionsFor(dims, req) {
4619
+ const ratio = req.aspectRatio;
4620
+ const size = req.size;
4621
+ if (ratio === void 0 || ratio === "adaptive" || size === void 0) return void 0;
4622
+ const area = dims.areas[size];
4623
+ const match = /^(\d+):(\d+)$/.exec(ratio);
4624
+ if (area === void 0 || match === null) return void 0;
4625
+ const r = Number(match[1]) / Number(match[2]);
4626
+ let width = Math.sqrt(area * r);
4627
+ let height = width / r;
4628
+ const longest = Math.max(width, height);
4629
+ if (dims.maxSide !== void 0 && longest > dims.maxSide) {
4630
+ const scale = dims.maxSide / longest;
4631
+ width *= scale;
4632
+ height *= scale;
4633
+ }
4634
+ const step = dims.multipleOf ?? 1;
4635
+ return {
4636
+ width: Math.max(step, Math.floor(width / step) * step),
4637
+ height: Math.max(step, Math.floor(height / step) * step)
4638
+ };
4639
+ }
4578
4640
  function resolveRowInputSpec(req, ctx) {
4579
4641
  const raw = ctx.model.providerOptions?.["modelkit"]?.["inputSpec"];
4580
4642
  if (raw === void 0) return { kind: "absent" };
@@ -5757,8 +5819,10 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
5757
5819
  const apiKey = googleKey(ctx);
5758
5820
  const modelId = ctx.model.id;
5759
5821
  const providerModelId = ctx.model.providerModelId;
5760
- const duration = req.durationSeconds ?? 10;
5761
5822
  const extend = req.taskType === "extend";
5823
+ const sourceSeconds = extend ? void 0 : req.sourceVideo?.durationSeconds;
5824
+ const editSeconds = sourceSeconds !== void 0 && Number.isFinite(sourceSeconds) && sourceSeconds > 0 ? sourceSeconds : void 0;
5825
+ const duration = req.durationSeconds ?? editSeconds ?? 10;
5762
5826
  const previousId = extend ? req.previousInteractionId : void 0;
5763
5827
  const chained = previousId !== void 0;
5764
5828
  for (const field of [