@shop-os/modelkit 0.7.3 → 0.7.6

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
@@ -6467,14 +6467,14 @@ function xaiReferenceMode(model, req) {
6467
6467
  const takesLastFrame = (model.constraints.supports ?? []).includes("lastFrame");
6468
6468
  return (req.referenceImages ?? []).length > 0 || takesLastFrame && req.lastFrame !== void 0;
6469
6469
  }
6470
- function applyXaiVideoRules(model, req, onUnsupported, warnings) {
6471
- if (model.adapter !== "xai-video" || req.resolution !== "1080p") return;
6472
- if (!xaiReferenceMode(model, req)) return;
6470
+ function xaiReferenceResolution(model, req, onUnsupported, warnings, provider) {
6471
+ if (req.resolution !== "1080p" || !xaiReferenceMode(model, req)) return void 0;
6473
6472
  const message = xaiReferenceResolutionMessage(model.id);
6474
6473
  if (onUnsupported === "error") {
6475
6474
  throw new ModelKitError({
6476
6475
  code: "unsupported_option",
6477
6476
  message,
6477
+ ...provider === void 0 ? {} : { provider },
6478
6478
  model: model.id,
6479
6479
  retryable: false
6480
6480
  });
@@ -6486,7 +6486,12 @@ function applyXaiVideoRules(model, req, onUnsupported, warnings) {
6486
6486
  to: XAI_REFERENCE_MAX_RESOLUTION,
6487
6487
  message
6488
6488
  });
6489
- req.resolution = XAI_REFERENCE_MAX_RESOLUTION;
6489
+ return XAI_REFERENCE_MAX_RESOLUTION;
6490
+ }
6491
+ function applyXaiVideoRules(model, req, onUnsupported, warnings) {
6492
+ if (model.adapter !== "xai-video") return;
6493
+ const lowered = xaiReferenceResolution(model, req, onUnsupported, warnings);
6494
+ if (lowered !== void 0) req.resolution = lowered;
6490
6495
  }
6491
6496
  function takesTargetAspectRatio(model) {
6492
6497
  const ratios = model.constraints.aspectRatios ?? [];
@@ -6687,6 +6692,161 @@ var MODEL3D_IMAGE_SLOTS = {
6687
6692
  ordered: ["image", "left", "back", "right"],
6688
6693
  unordered: ["image", "back", "left", "right", "top"]
6689
6694
  };
6695
+ var MODEL3D_FAMILY_RULES = {
6696
+ trellis: {
6697
+ textPath: false,
6698
+ views: ["none"],
6699
+ multiImage: false,
6700
+ texture: null,
6701
+ pbr: false,
6702
+ seed: true,
6703
+ textureRef: false,
6704
+ resolutions: "integer"
6705
+ },
6706
+ hunyuan: {
6707
+ textPath: true,
6708
+ views: ["none", "named"],
6709
+ multiImage: false,
6710
+ // generate_type
6711
+ texture: { none: "Geometry", standard: "Normal" },
6712
+ pbr: true,
6713
+ seed: false,
6714
+ textureRef: false,
6715
+ resolutions: null
6716
+ },
6717
+ tripo: {
6718
+ textPath: true,
6719
+ views: ["none", "ordered"],
6720
+ multiImage: true,
6721
+ // texture_quality; null sends an untextured model.
6722
+ texture: { none: null, standard: "standard", detailed: "detailed" },
6723
+ pbr: true,
6724
+ seed: true,
6725
+ textureRef: false,
6726
+ resolutions: null
6727
+ },
6728
+ rodin: {
6729
+ textPath: true,
6730
+ views: ["none", "unordered"],
6731
+ multiImage: false,
6732
+ texture: null,
6733
+ pbr: false,
6734
+ seed: true,
6735
+ textureRef: false,
6736
+ resolutions: null
6737
+ },
6738
+ meshy: {
6739
+ textPath: true,
6740
+ views: ["none", "unordered"],
6741
+ multiImage: true,
6742
+ // The text endpoint's mode; the image endpoints take should_texture.
6743
+ texture: { none: "preview", standard: "full" },
6744
+ pbr: true,
6745
+ seed: true,
6746
+ textureRef: true,
6747
+ resolutions: null
6748
+ },
6749
+ hi3d: {
6750
+ textPath: false,
6751
+ views: ["none", "named"],
6752
+ multiImage: true,
6753
+ // enable_texture
6754
+ texture: { none: false, standard: true },
6755
+ pbr: true,
6756
+ seed: false,
6757
+ textureRef: false,
6758
+ resolutions: { quality: "2048quality", master: "2048master" }
6759
+ },
6760
+ sam: {
6761
+ textPath: false,
6762
+ views: ["none"],
6763
+ multiImage: false,
6764
+ texture: null,
6765
+ pbr: false,
6766
+ seed: true,
6767
+ textureRef: false,
6768
+ resolutions: null
6769
+ }
6770
+ };
6771
+ function model3dSpecIssues(spec) {
6772
+ const issues = [];
6773
+ const add = (path, message) => issues.push({ path, message });
6774
+ const rules = MODEL3D_FAMILY_RULES[spec.family];
6775
+ const promptOnly = spec.text && !spec.imageRequired;
6776
+ if (spec.endpoints.image === void 0)
6777
+ add(["endpoints", "image"], "every row needs an image endpoint");
6778
+ if (promptOnly && !rules.textPath) {
6779
+ add(
6780
+ ["imageRequired"],
6781
+ `${spec.family} has no text-to-3D endpoint; a text row needs an image`
6782
+ );
6783
+ }
6784
+ if (promptOnly && spec.endpoints.text === void 0) {
6785
+ add(["endpoints", "text"], "a text row needs a text endpoint");
6786
+ }
6787
+ if (!rules.views.includes(spec.views)) {
6788
+ add(["views"], `${spec.family} takes views ${rules.views.join(" or ")}`);
6789
+ }
6790
+ if (spec.views === "none" && spec.maxImages !== 1) {
6791
+ add(["maxImages"], "a row without views takes 1 image");
6792
+ }
6793
+ if (spec.views === "unordered" && spec.maxImages < 2) {
6794
+ add(["maxImages"], "a row with views takes at least 2 images");
6795
+ }
6796
+ const slots = MODEL3D_IMAGE_SLOTS[spec.views].length;
6797
+ if (spec.views !== "none" && spec.maxImages > slots) {
6798
+ add(["maxImages"], `a row with ${spec.views} views sends at most ${slots} images`);
6799
+ }
6800
+ if ((spec.views === "named" || spec.views === "ordered") && spec.maxImages < slots) {
6801
+ add(
6802
+ ["maxImages"],
6803
+ `a row with ${spec.views} views takes ${slots} images (front and three sides)`
6804
+ );
6805
+ }
6806
+ if (spec.views !== "none" && rules.multiImage && spec.endpoints.multiImage === void 0) {
6807
+ add(["endpoints", "multiImage"], `${spec.family} sends views to a multi-image endpoint`);
6808
+ }
6809
+ if (rules.texture === null) {
6810
+ if (spec.texture.length > 0) add(["texture"], `${spec.family} has no texture switch`);
6811
+ } else {
6812
+ const allowed = rules.texture;
6813
+ if (spec.texture.length === 0) add(["texture"], `${spec.family} needs its texture options`);
6814
+ if (new Set(spec.texture).size !== spec.texture.length)
6815
+ add(["texture"], "texture options repeat");
6816
+ for (const t of spec.texture) {
6817
+ if (!Object.hasOwn(allowed, t))
6818
+ add(["texture"], `${spec.family} has no "${t}" texture`);
6819
+ }
6820
+ }
6821
+ if (spec.pbr && !rules.pbr) add(["pbr"], `${spec.family} has no PBR switch`);
6822
+ if (spec.pbr && !spec.texture.some((t) => t !== "none")) {
6823
+ add(["pbr"], "PBR needs a textured option");
6824
+ }
6825
+ if (spec.seed && !rules.seed) add(["seed"], `${spec.family} takes no seed`);
6826
+ if (spec.seedMax !== void 0 && !spec.seed) add(["seedMax"], "seedMax needs seed");
6827
+ if (spec.textureRef && !rules.textureRef)
6828
+ add(["textureRef"], `${spec.family} takes no texture reference`);
6829
+ const res = spec.resolutions;
6830
+ if (rules.resolutions === null) {
6831
+ if (res !== void 0) add(["resolutions"], `${spec.family} has no resolution option`);
6832
+ } else if (res === void 0) {
6833
+ add(["resolutions"], `${spec.family} needs its resolution options`);
6834
+ } else {
6835
+ if (!res.options.includes(res.default)) {
6836
+ add(["resolutions", "default"], "default must be an option");
6837
+ }
6838
+ if (new Set(res.options).size !== res.options.length) {
6839
+ add(["resolutions", "options"], "resolution options repeat");
6840
+ }
6841
+ const allowed = rules.resolutions;
6842
+ for (const option of res.options) {
6843
+ const ok = allowed === "integer" ? /^[1-9][0-9]*$/.test(option) : Object.hasOwn(allowed, option);
6844
+ if (!ok)
6845
+ add(["resolutions", "options"], `${spec.family} has no "${option}" resolution`);
6846
+ }
6847
+ }
6848
+ return issues;
6849
+ }
6690
6850
  function model3dInputRefusal(spec, wired) {
6691
6851
  const top = spec.views === "unordered" && wired.top === true;
6692
6852
  const anyView = spec.views !== "none" && (wired.back || wired.left || wired.right || top);
@@ -7274,156 +7434,6 @@ var LanguageOptionSchema = import_zod3.z.looseObject({
7274
7434
  code: import_zod3.z.string().min(1),
7275
7435
  name: import_zod3.z.string().min(1)
7276
7436
  });
7277
- var MODEL3D_FAMILY_RULES = {
7278
- trellis: {
7279
- textPath: false,
7280
- views: ["none"],
7281
- multiImage: false,
7282
- texture: null,
7283
- pbr: false,
7284
- seed: true,
7285
- textureRef: false,
7286
- resolutions: "integer"
7287
- },
7288
- hunyuan: {
7289
- textPath: true,
7290
- views: ["none", "named"],
7291
- multiImage: false,
7292
- texture: ["none", "standard"],
7293
- pbr: true,
7294
- seed: false,
7295
- textureRef: false,
7296
- resolutions: null
7297
- },
7298
- tripo: {
7299
- textPath: true,
7300
- views: ["none", "ordered"],
7301
- multiImage: true,
7302
- texture: ["none", "standard", "detailed"],
7303
- pbr: true,
7304
- seed: true,
7305
- textureRef: false,
7306
- resolutions: null
7307
- },
7308
- rodin: {
7309
- textPath: true,
7310
- views: ["none", "unordered"],
7311
- multiImage: false,
7312
- texture: null,
7313
- pbr: false,
7314
- seed: true,
7315
- textureRef: false,
7316
- resolutions: null
7317
- },
7318
- meshy: {
7319
- textPath: true,
7320
- views: ["none", "unordered"],
7321
- multiImage: true,
7322
- texture: ["none", "standard"],
7323
- pbr: true,
7324
- seed: true,
7325
- textureRef: true,
7326
- resolutions: null
7327
- },
7328
- hi3d: {
7329
- textPath: false,
7330
- views: ["none", "named"],
7331
- multiImage: true,
7332
- texture: ["none", "standard"],
7333
- pbr: true,
7334
- seed: false,
7335
- textureRef: false,
7336
- resolutions: ["quality", "master"]
7337
- },
7338
- sam: {
7339
- textPath: false,
7340
- views: ["none"],
7341
- multiImage: false,
7342
- texture: null,
7343
- pbr: false,
7344
- seed: true,
7345
- textureRef: false,
7346
- resolutions: null
7347
- }
7348
- };
7349
- function model3dSpecIssues(spec) {
7350
- const issues = [];
7351
- const add = (path, message) => issues.push({ path, message });
7352
- const rules = MODEL3D_FAMILY_RULES[spec.family];
7353
- const promptOnly = spec.text && !spec.imageRequired;
7354
- if (spec.endpoints.image === void 0)
7355
- add(["endpoints", "image"], "every row needs an image endpoint");
7356
- if (promptOnly && !rules.textPath) {
7357
- add(
7358
- ["imageRequired"],
7359
- `${spec.family} has no text-to-3D endpoint; a text row needs an image`
7360
- );
7361
- }
7362
- if (promptOnly && spec.endpoints.text === void 0) {
7363
- add(["endpoints", "text"], "a text row needs a text endpoint");
7364
- }
7365
- if (!rules.views.includes(spec.views)) {
7366
- add(["views"], `${spec.family} takes views ${rules.views.join(" or ")}`);
7367
- }
7368
- if (spec.views === "none" && spec.maxImages !== 1) {
7369
- add(["maxImages"], "a row without views takes 1 image");
7370
- }
7371
- if (spec.views === "unordered" && spec.maxImages < 2) {
7372
- add(["maxImages"], "a row with views takes at least 2 images");
7373
- }
7374
- const slots = MODEL3D_IMAGE_SLOTS[spec.views].length;
7375
- if (spec.views !== "none" && spec.maxImages > slots) {
7376
- add(["maxImages"], `a row with ${spec.views} views sends at most ${slots} images`);
7377
- }
7378
- if ((spec.views === "named" || spec.views === "ordered") && spec.maxImages < slots) {
7379
- add(
7380
- ["maxImages"],
7381
- `a row with ${spec.views} views takes ${slots} images (front and three sides)`
7382
- );
7383
- }
7384
- if (spec.views !== "none" && rules.multiImage && spec.endpoints.multiImage === void 0) {
7385
- add(["endpoints", "multiImage"], `${spec.family} sends views to a multi-image endpoint`);
7386
- }
7387
- if (rules.texture === null) {
7388
- if (spec.texture.length > 0) add(["texture"], `${spec.family} has no texture switch`);
7389
- } else {
7390
- const allowed = rules.texture;
7391
- if (spec.texture.length === 0) add(["texture"], `${spec.family} needs its texture options`);
7392
- if (new Set(spec.texture).size !== spec.texture.length)
7393
- add(["texture"], "texture options repeat");
7394
- for (const t of spec.texture) {
7395
- if (!allowed.includes(t)) add(["texture"], `${spec.family} has no "${t}" texture`);
7396
- }
7397
- }
7398
- if (spec.pbr && !rules.pbr) add(["pbr"], `${spec.family} has no PBR switch`);
7399
- if (spec.pbr && !spec.texture.some((t) => t !== "none")) {
7400
- add(["pbr"], "PBR needs a textured option");
7401
- }
7402
- if (spec.seed && !rules.seed) add(["seed"], `${spec.family} takes no seed`);
7403
- if (spec.seedMax !== void 0 && !spec.seed) add(["seedMax"], "seedMax needs seed");
7404
- if (spec.textureRef && !rules.textureRef)
7405
- add(["textureRef"], `${spec.family} takes no texture reference`);
7406
- const res = spec.resolutions;
7407
- if (rules.resolutions === null) {
7408
- if (res !== void 0) add(["resolutions"], `${spec.family} has no resolution option`);
7409
- } else if (res === void 0) {
7410
- add(["resolutions"], `${spec.family} needs its resolution options`);
7411
- } else {
7412
- if (!res.options.includes(res.default)) {
7413
- add(["resolutions", "default"], "default must be an option");
7414
- }
7415
- if (new Set(res.options).size !== res.options.length) {
7416
- add(["resolutions", "options"], "resolution options repeat");
7417
- }
7418
- const allowed = rules.resolutions;
7419
- for (const option of res.options) {
7420
- const ok = allowed === "integer" ? /^[1-9][0-9]*$/.test(option) : allowed.includes(option);
7421
- if (!ok)
7422
- add(["resolutions", "options"], `${spec.family} has no "${option}" resolution`);
7423
- }
7424
- }
7425
- return issues;
7426
- }
7427
7437
  var VideoToolConstraintsSchema = import_zod3.z.looseObject({
7428
7438
  kind: import_zod3.z.enum(["upscale", "interpolate", "hdr", "bg-remove", "subtitles"]),
7429
7439
  upscaleFactor: RangeSchema.optional(),
@@ -10825,6 +10835,19 @@ function specOf(ctx) {
10825
10835
  return spec;
10826
10836
  }
10827
10837
  var present = (v) => v !== void 0 && v.length > 0;
10838
+ function wireValue(row2, values, option, what) {
10839
+ const value = option !== void 0 && Object.hasOwn(values, option) ? values[option] : void 0;
10840
+ if (value === void 0) {
10841
+ throw new ModelKitError({
10842
+ code: "unsupported_option",
10843
+ message: `${row2.id} has no ${what} "${option ?? ""}" to send`,
10844
+ provider: "fal",
10845
+ model: row2.id,
10846
+ retryable: false
10847
+ });
10848
+ }
10849
+ return value;
10850
+ }
10828
10851
  function model3dCall(row2, spec, req) {
10829
10852
  const prompt = req.prompt?.trim() || void 0;
10830
10853
  const texture = model3dTexture(spec, req.texture);
@@ -10868,7 +10891,15 @@ function model3dCall(row2, spec, req) {
10868
10891
  }
10869
10892
  };
10870
10893
  case "hunyuan": {
10871
- const opts = { generate_type: textured ? "Normal" : "Geometry", enable_pbr: pbr };
10894
+ const opts = {
10895
+ generate_type: wireValue(
10896
+ row2,
10897
+ MODEL3D_FAMILY_RULES.hunyuan.texture,
10898
+ texture,
10899
+ "texture"
10900
+ ),
10901
+ enable_pbr: pbr
10902
+ };
10872
10903
  if (!present(req.image)) {
10873
10904
  return {
10874
10905
  endpoint: endpoint(spec.endpoints.text),
@@ -10887,12 +10918,11 @@ function model3dCall(row2, spec, req) {
10887
10918
  };
10888
10919
  }
10889
10920
  case "tripo": {
10921
+ const quality = wireValue(row2, MODEL3D_FAMILY_RULES.tripo.texture, texture, "texture");
10890
10922
  const opts = {
10891
10923
  texture: textured,
10892
10924
  pbr,
10893
- ...textured && {
10894
- texture_quality: texture === "detailed" ? "detailed" : "standard"
10895
- },
10925
+ ...quality !== null && { texture_quality: quality },
10896
10926
  ...seed !== void 0 && { model_seed: seed }
10897
10927
  };
10898
10928
  if (!present(req.image)) {
@@ -10928,6 +10958,7 @@ function model3dCall(row2, spec, req) {
10928
10958
  };
10929
10959
  }
10930
10960
  case "meshy": {
10961
+ const mode = wireValue(row2, MODEL3D_FAMILY_RULES.meshy.texture, texture, "texture");
10931
10962
  const texturePrompt = req.texturePrompt?.trim() || void 0;
10932
10963
  const opts = {
10933
10964
  enable_pbr: pbr,
@@ -10939,7 +10970,7 @@ function model3dCall(row2, spec, req) {
10939
10970
  endpoint: endpoint(spec.endpoints.text),
10940
10971
  input: {
10941
10972
  prompt: prompt ?? "",
10942
- mode: textured ? "full" : "preview",
10973
+ mode,
10943
10974
  ...opts,
10944
10975
  ...seed !== void 0 && { seed }
10945
10976
  }
@@ -10955,8 +10986,18 @@ function model3dCall(row2, spec, req) {
10955
10986
  }
10956
10987
  case "hi3d": {
10957
10988
  const opts = {
10958
- resolution: resolution === "master" ? "2048master" : "2048quality",
10959
- enable_texture: textured,
10989
+ resolution: wireValue(
10990
+ row2,
10991
+ MODEL3D_FAMILY_RULES.hi3d.resolutions,
10992
+ resolution,
10993
+ "resolution"
10994
+ ),
10995
+ enable_texture: wireValue(
10996
+ row2,
10997
+ MODEL3D_FAMILY_RULES.hi3d.texture,
10998
+ texture,
10999
+ "texture"
11000
+ ),
10960
11001
  enable_pbr: pbr,
10961
11002
  export_format: "glb"
10962
11003
  };
@@ -15682,14 +15723,15 @@ async function generateXaiVideo(req, ctx, deps) {
15682
15723
  });
15683
15724
  }
15684
15725
  const refLimit = ctx.model.constraints.references?.images ?? SDK_REFERENCE_CAP;
15685
- const refUrls = (req.referenceImages ?? []).map(refToUrl).slice(0, refLimit);
15726
+ const refs = (req.referenceImages ?? []).slice(0, refLimit);
15727
+ const refUrls = refs.map(refToUrl);
15686
15728
  const takesLastFrame = (ctx.model.constraints.supports ?? []).includes("lastFrame");
15687
15729
  const lastFrame = takesLastFrame && req.lastFrame ? refToUrl(req.lastFrame) : void 0;
15688
15730
  const xaiOptions = {
15689
15731
  pollIntervalMs: POLL_INTERVAL_MS2,
15690
15732
  pollTimeoutMs: POLL_TIMEOUT_MS2
15691
15733
  };
15692
- const resolution = xaiResolution(req, ctx, refUrls.length > 0 || lastFrame !== void 0);
15734
+ const resolution = xaiResolution(req, ctx, refs);
15693
15735
  if (resolution !== void 0) xaiOptions.resolution = resolution;
15694
15736
  const sent = resolution === void 0 ? req : { ...req, resolution };
15695
15737
  if (refUrls.length > SDK_REFERENCE_CAP) {
@@ -15816,27 +15858,17 @@ function usage2(ctx, req, meta) {
15816
15858
  if (req.resolution !== void 0) event.resolution = req.resolution;
15817
15859
  return event;
15818
15860
  }
15819
- function xaiResolution(req, ctx, referenceMode) {
15861
+ function xaiResolution(req, ctx, sentRefs) {
15820
15862
  const requested = req.resolution;
15821
15863
  if (requested !== "480p" && requested !== "720p" && requested !== "1080p") return void 0;
15822
- if (!referenceMode || requested !== "1080p") return requested;
15823
- if ((ctx.call.onUnsupported ?? "error") === "error") {
15824
- throw new ModelKitError({
15825
- code: "unsupported_option",
15826
- message: xaiReferenceResolutionMessage(ctx.model.id),
15827
- provider: "xai-video",
15828
- model: ctx.model.id,
15829
- retryable: false
15830
- });
15831
- }
15832
- ctx.warnings.push({
15833
- code: "resolution_coerced",
15834
- field: "resolution",
15835
- from: requested,
15836
- to: XAI_REFERENCE_MAX_RESOLUTION,
15837
- message: xaiReferenceResolutionMessage(ctx.model.id)
15838
- });
15839
- return XAI_REFERENCE_MAX_RESOLUTION;
15864
+ const lowered = xaiReferenceResolution(
15865
+ ctx.model,
15866
+ { ...req, referenceImages: sentRefs },
15867
+ ctx.call.onUnsupported ?? "error",
15868
+ ctx.warnings,
15869
+ "xai-video"
15870
+ );
15871
+ return lowered ?? requested;
15840
15872
  }
15841
15873
 
15842
15874
  // src/adapters/index.ts