@shop-os/modelkit 0.5.0 → 0.6.1

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
@@ -136,11 +136,11 @@ function normalizeExposure(value) {
136
136
  }
137
137
  return value;
138
138
  }
139
- function isListedOn(row, surface) {
140
- return row.lifecycle === "active" && row.exposure.includes(surface);
139
+ function isListedOn(row2, surface) {
140
+ return row2.lifecycle === "active" && row2.exposure.includes(surface);
141
141
  }
142
- function isListed(row) {
143
- return row.lifecycle === "active" && row.exposure.length > 0;
142
+ function isListed(row2) {
143
+ return row2.lifecycle === "active" && row2.exposure.length > 0;
144
144
  }
145
145
 
146
146
  // src/catalog/image-fal.ts
@@ -3542,6 +3542,197 @@ var MEDIA_NODE_MODELS = [
3542
3542
  SAM_3_IMAGE
3543
3543
  ];
3544
3544
 
3545
+ // src/catalog/model3d.ts
3546
+ var REQUEST_USAGE = { unit: "requests" };
3547
+ function row(id, label, spec, display) {
3548
+ return {
3549
+ id,
3550
+ aliases: [],
3551
+ label,
3552
+ type: "model3d",
3553
+ adapter: "fal",
3554
+ // The single-image endpoint; the adapter picks the endpoint a request needs.
3555
+ providerModelId: spec.endpoints.image ?? id,
3556
+ lifecycle: "active",
3557
+ exposure: ["space_builder"],
3558
+ constraints: { supports: [], model3d: spec },
3559
+ defaults: {},
3560
+ usage: REQUEST_USAGE,
3561
+ pricingKind: "flat",
3562
+ display
3563
+ };
3564
+ }
3565
+ var MODEL3D_MODELS = [
3566
+ row(
3567
+ "trellis-2",
3568
+ "Trellis 2",
3569
+ {
3570
+ family: "trellis",
3571
+ endpoints: { image: "fal-ai/trellis-2" },
3572
+ text: false,
3573
+ imageRequired: true,
3574
+ views: "none",
3575
+ maxImages: 1,
3576
+ texture: [],
3577
+ pbr: false,
3578
+ textureRef: false,
3579
+ seed: true,
3580
+ resolutions: { label: "Resolution", options: ["512", "1024", "1536"], default: "1024" }
3581
+ },
3582
+ {
3583
+ provider: "microsoft",
3584
+ description: "One photo to a detailed textured model. Fast and the best value.",
3585
+ sortOrder: 70
3586
+ }
3587
+ ),
3588
+ row(
3589
+ "hunyuan3d-3.1-pro",
3590
+ "Hunyuan3D 3.1 Pro",
3591
+ {
3592
+ family: "hunyuan",
3593
+ endpoints: {
3594
+ text: "fal-ai/hunyuan-3d/v3.1/pro/text-to-3d",
3595
+ image: "fal-ai/hunyuan-3d/v3.1/pro/image-to-3d"
3596
+ },
3597
+ text: true,
3598
+ imageRequired: false,
3599
+ views: "named",
3600
+ maxImages: 4,
3601
+ texture: ["none", "standard"],
3602
+ pbr: true,
3603
+ textureRef: false,
3604
+ seed: false
3605
+ },
3606
+ {
3607
+ provider: "tencent",
3608
+ description: "Photo-faithful models from a prompt, a photo, or a photo with back and side views.",
3609
+ sortOrder: 60
3610
+ }
3611
+ ),
3612
+ row(
3613
+ "tripo-h3.1",
3614
+ "Tripo H3.1",
3615
+ {
3616
+ family: "tripo",
3617
+ endpoints: {
3618
+ text: "tripo3d/h3.1/text-to-3d",
3619
+ image: "tripo3d/h3.1/image-to-3d",
3620
+ multiImage: "tripo3d/h3.1/multiview-to-3d"
3621
+ },
3622
+ text: true,
3623
+ imageRequired: false,
3624
+ views: "ordered",
3625
+ maxImages: 4,
3626
+ texture: ["none", "standard", "detailed"],
3627
+ pbr: true,
3628
+ textureRef: false,
3629
+ seed: true
3630
+ },
3631
+ {
3632
+ provider: "tripo",
3633
+ description: "Clean, game-ready models from a prompt, a photo or four views.",
3634
+ sortOrder: 50
3635
+ }
3636
+ ),
3637
+ row(
3638
+ "rodin-gen-2.5",
3639
+ "Rodin Gen-2.5",
3640
+ {
3641
+ family: "rodin",
3642
+ endpoints: {
3643
+ text: "fal-ai/hyper3d/rodin/v2.5/text-to-3d",
3644
+ image: "fal-ai/hyper3d/rodin/v2.5"
3645
+ },
3646
+ text: true,
3647
+ imageRequired: false,
3648
+ views: "unordered",
3649
+ maxImages: 5,
3650
+ texture: [],
3651
+ pbr: false,
3652
+ textureRef: false,
3653
+ seed: true,
3654
+ seedMax: 65535
3655
+ },
3656
+ {
3657
+ provider: "hyper3d",
3658
+ description: "Detailed PBR models from a prompt or up to five photos.",
3659
+ sortOrder: 40
3660
+ }
3661
+ ),
3662
+ row(
3663
+ "meshy-7.1",
3664
+ "Meshy 7.1",
3665
+ {
3666
+ family: "meshy",
3667
+ endpoints: {
3668
+ text: "meshy/v7.1/text-to-3d",
3669
+ image: "meshy/v7.1/image-to-3d",
3670
+ multiImage: "meshy/v7.1/multi-image-to-3d"
3671
+ },
3672
+ text: true,
3673
+ imageRequired: false,
3674
+ views: "unordered",
3675
+ maxImages: 4,
3676
+ texture: ["none", "standard"],
3677
+ pbr: true,
3678
+ textureRef: true,
3679
+ seed: true
3680
+ },
3681
+ {
3682
+ provider: "meshy",
3683
+ description: "Models from a prompt or photos, with a texture prompt or texture image to restyle.",
3684
+ sortOrder: 30
3685
+ }
3686
+ ),
3687
+ row(
3688
+ "hi3d-3.0",
3689
+ "Hi3D 3.0",
3690
+ {
3691
+ family: "hi3d",
3692
+ endpoints: {
3693
+ image: "hitem3d/hi3d/v3.0/image-to-3d",
3694
+ multiImage: "hitem3d/hi3d/v3.0/multi-view-to-3d"
3695
+ },
3696
+ text: false,
3697
+ imageRequired: true,
3698
+ views: "named",
3699
+ maxImages: 4,
3700
+ texture: ["none", "standard"],
3701
+ pbr: true,
3702
+ textureRef: false,
3703
+ seed: false,
3704
+ resolutions: { label: "Quality", options: ["quality", "master"], default: "quality" }
3705
+ },
3706
+ {
3707
+ provider: "hitem3d",
3708
+ description: "Highest-fidelity product models from a photo or four views. Slowest.",
3709
+ sortOrder: 20
3710
+ }
3711
+ ),
3712
+ row(
3713
+ "sam-3d-objects",
3714
+ "SAM 3D Objects",
3715
+ {
3716
+ family: "sam",
3717
+ endpoints: { image: "fal-ai/sam-3/3d-objects" },
3718
+ text: true,
3719
+ imageRequired: true,
3720
+ promptRequired: true,
3721
+ views: "none",
3722
+ maxImages: 1,
3723
+ texture: [],
3724
+ pbr: false,
3725
+ textureRef: false,
3726
+ seed: true
3727
+ },
3728
+ {
3729
+ provider: "meta",
3730
+ description: "Lifts one named object out of a real photo into a 3D model.",
3731
+ sortOrder: 10
3732
+ }
3733
+ )
3734
+ ];
3735
+
3545
3736
  // src/catalog/other.ts
3546
3737
  var GOOGLE_LOGO2 = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png";
3547
3738
  var ELEVENLABS_LOGO2 = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/elevenlabs.png";
@@ -5860,6 +6051,7 @@ var MODELS = [
5860
6051
  ...IMAGE_MODELS,
5861
6052
  ...VIDEO_MODELS,
5862
6053
  ...VIDEO_TOOL_MODELS,
6054
+ ...MODEL3D_MODELS,
5863
6055
  ...OTHER_MODELS,
5864
6056
  ...MEDIA_NODE_MODELS
5865
6057
  ];
@@ -5868,11 +6060,11 @@ var MODELS = [
5868
6060
  import { z as z3 } from "zod";
5869
6061
 
5870
6062
  // src/resolve-provider-rules.ts
5871
- function ruleRefusal(row, message, code) {
6063
+ function ruleRefusal(row2, message, code) {
5872
6064
  return new ModelKitError({
5873
6065
  code,
5874
- message: `${row.label}: ${message}`,
5875
- model: row.id,
6066
+ message: `${row2.label}: ${message}`,
6067
+ model: row2.id,
5876
6068
  retryable: false
5877
6069
  });
5878
6070
  }
@@ -6031,27 +6223,27 @@ function collisionIssues(rows) {
6031
6223
  const issues = [];
6032
6224
  const seenIds = /* @__PURE__ */ new Map();
6033
6225
  const seenAliases = /* @__PURE__ */ new Map();
6034
- rows.forEach((row, index) => {
6035
- if (seenIds.has(row.id)) {
6226
+ rows.forEach((row2, index) => {
6227
+ if (seenIds.has(row2.id)) {
6036
6228
  issues.push({
6037
6229
  index,
6038
6230
  path: ["id"],
6039
- message: `Duplicate model id "${row.id}"`
6231
+ message: `Duplicate model id "${row2.id}"`
6040
6232
  });
6041
6233
  } else {
6042
- const aliasOwner = seenAliases.get(row.id);
6234
+ const aliasOwner = seenAliases.get(row2.id);
6043
6235
  if (aliasOwner !== void 0) {
6044
6236
  issues.push({
6045
6237
  index: aliasOwner.index,
6046
6238
  path: ["aliases", aliasOwner.aliasIndex],
6047
- message: `Alias "${row.id}" collides with a model id`
6239
+ message: `Alias "${row2.id}" collides with a model id`
6048
6240
  });
6049
6241
  }
6050
- seenIds.set(row.id, index);
6242
+ seenIds.set(row2.id, index);
6051
6243
  }
6052
6244
  const local = /* @__PURE__ */ new Set();
6053
- for (const [aliasIndex, alias] of row.aliases.entries()) {
6054
- if (alias === row.id || seenIds.has(alias)) {
6245
+ for (const [aliasIndex, alias] of row2.aliases.entries()) {
6246
+ if (alias === row2.id || seenIds.has(alias)) {
6055
6247
  issues.push({
6056
6248
  index,
6057
6249
  path: ["aliases", aliasIndex],
@@ -6090,23 +6282,23 @@ var ConstraintsReadView = z.looseObject({
6090
6282
  }).optional().catch(void 0)
6091
6283
  });
6092
6284
  var DEFAULT_CONVENTIONS = { referenceSyntax: "numbered" };
6093
- function outputAudio(row) {
6094
- const view = ConstraintsReadView.safeParse(row.constraints);
6285
+ function outputAudio(row2) {
6286
+ const view = ConstraintsReadView.safeParse(row2.constraints);
6095
6287
  return view.success ? view.data.audio : void 0;
6096
6288
  }
6097
6289
  var DefaultsReadView = z.looseObject({
6098
6290
  generateAudio: z.boolean().optional().catch(void 0)
6099
6291
  });
6100
- function billedAudio(row, requested) {
6101
- const audio = outputAudio(row);
6292
+ function billedAudio(row2, requested) {
6293
+ const audio = outputAudio(row2);
6102
6294
  if (audio === "never") return false;
6103
6295
  if (audio !== "optional") return true;
6104
6296
  if (requested !== void 0) return requested;
6105
- const defaults = DefaultsReadView.safeParse(row.defaults);
6297
+ const defaults = DefaultsReadView.safeParse(row2.defaults);
6106
6298
  return (defaults.success ? defaults.data.generateAudio : void 0) ?? true;
6107
6299
  }
6108
- function promptConventions(row) {
6109
- const view = ConstraintsReadView.safeParse(row.constraints);
6300
+ function promptConventions(row2) {
6301
+ const view = ConstraintsReadView.safeParse(row2.constraints);
6110
6302
  const prompt = view.success ? view.data.prompt : void 0;
6111
6303
  if (prompt === void 0) return { ...DEFAULT_CONVENTIONS };
6112
6304
  const result = { referenceSyntax: prompt.referenceSyntax };
@@ -6117,22 +6309,111 @@ var RawConventionsView = z.looseObject({
6117
6309
  audio: z.unknown().optional(),
6118
6310
  prompt: z.unknown().optional()
6119
6311
  });
6120
- function normaliseConventions(row) {
6121
- const view = RawConventionsView.safeParse(row.constraints);
6122
- if (!view.success) return { row, invalidKeys: [] };
6312
+ function normaliseConventions(row2) {
6313
+ const view = RawConventionsView.safeParse(row2.constraints);
6314
+ if (!view.success) return { row: row2, invalidKeys: [] };
6123
6315
  const { audio, prompt } = view.data;
6124
6316
  const badAudio = audio !== void 0 && !AudioOutputSchema.safeParse(audio).success;
6125
6317
  const badPrompt = prompt !== void 0 && !PromptConventionsSchema.safeParse(prompt).success;
6126
- if (!badAudio && !badPrompt) return { row, invalidKeys: [] };
6318
+ if (!badAudio && !badPrompt) return { row: row2, invalidKeys: [] };
6127
6319
  const invalidKeys = [];
6128
6320
  if (badAudio) invalidKeys.push("constraints.audio");
6129
6321
  if (badPrompt) invalidKeys.push("constraints.prompt");
6130
- const entries = Object.entries(row.constraints).flatMap(([key, value]) => {
6322
+ const entries = Object.entries(row2.constraints).flatMap(([key, value]) => {
6131
6323
  if (key === "audio" && badAudio) return [];
6132
- if (key === "prompt" && badPrompt) return [[key, promptConventions(row)]];
6324
+ if (key === "prompt" && badPrompt) return [[key, promptConventions(row2)]];
6133
6325
  return [[key, value]];
6134
6326
  });
6135
- return { row: { ...row, constraints: Object.fromEntries(entries) }, invalidKeys };
6327
+ return { row: { ...row2, constraints: Object.fromEntries(entries) }, invalidKeys };
6328
+ }
6329
+
6330
+ // src/catalog/model3d-spec.ts
6331
+ function model3dConstraints(row2) {
6332
+ if (row2.type !== "model3d") return void 0;
6333
+ return row2.constraints.model3d;
6334
+ }
6335
+ var MODEL3D_IMAGE_SLOTS = {
6336
+ none: ["image"],
6337
+ named: ["image", "back", "left", "right"],
6338
+ ordered: ["image", "left", "back", "right"],
6339
+ unordered: ["image", "back", "left", "right", "top"]
6340
+ };
6341
+ function model3dInputRefusal(spec, wired) {
6342
+ const top = spec.views === "unordered" && wired.top === true;
6343
+ const anyView = spec.views !== "none" && (wired.back || wired.left || wired.right || top);
6344
+ if (anyView && !wired.image) return "model3d_views_need_image";
6345
+ if (spec.imageRequired && !wired.image) return "model3d_needs_image";
6346
+ if (spec.promptRequired && !wired.prompt) return "model3d_needs_prompt";
6347
+ if (!wired.image && !(spec.text && wired.prompt)) return "model3d_needs_input";
6348
+ if (spec.views === "ordered") {
6349
+ if ((wired.back || wired.right) && !wired.left) return "model3d_views_out_of_order";
6350
+ if (wired.right && !wired.back) return "model3d_views_out_of_order";
6351
+ }
6352
+ return null;
6353
+ }
6354
+ function model3dSeedFits(spec, seed) {
6355
+ return Number.isSafeInteger(seed) && seed >= 0 && seed <= (spec.seedMax ?? Number.MAX_SAFE_INTEGER);
6356
+ }
6357
+ function model3dTexture(spec, requested) {
6358
+ if (requested !== void 0 && spec.texture.includes(requested)) return requested;
6359
+ return spec.texture.includes("standard") ? "standard" : spec.texture[0] ?? "standard";
6360
+ }
6361
+ function model3dResolution(spec, requested) {
6362
+ const res = spec.resolutions;
6363
+ if (res === void 0) return void 0;
6364
+ return requested !== void 0 && res.options.includes(requested) ? requested : res.default;
6365
+ }
6366
+ function model3dPricingSku(row2, options, inputs) {
6367
+ const spec = model3dConstraints(row2);
6368
+ if (spec === void 0) throw new Error(`${row2.id} is not a 3D model`);
6369
+ const texture = model3dTexture(spec, options.texture);
6370
+ const textured = spec.texture.length > 0 && texture !== "none";
6371
+ const pbr = spec.pbr && textured && options.pbr === true;
6372
+ const resolution = model3dResolution(spec, options.resolution);
6373
+ switch (spec.family) {
6374
+ case "meshy":
6375
+ return `${row2.id}__${textured ? "textured" : "untextured"}`;
6376
+ case "tripo":
6377
+ return `${row2.id}__${inputs.image ? "image" : "text"}__${texture}`;
6378
+ case "hunyuan":
6379
+ return `${row2.id}${pbr ? "__pbr" : ""}${inputs.views ? "__views" : ""}`;
6380
+ case "trellis":
6381
+ return `${row2.id}__${resolution}`;
6382
+ case "hi3d":
6383
+ return `${row2.id}__${resolution}__${textured ? pbr ? "texture-pbr" : "texture" : "geometry"}`;
6384
+ case "rodin":
6385
+ case "sam":
6386
+ return row2.id;
6387
+ }
6388
+ }
6389
+ function model3dSkus(row2) {
6390
+ const spec = model3dConstraints(row2);
6391
+ if (spec === void 0) return [];
6392
+ const textures = spec.texture.length > 0 ? spec.texture : [void 0];
6393
+ const pbrs = spec.pbr ? [false, true] : [false];
6394
+ const resolutions = spec.resolutions?.options ?? [void 0];
6395
+ const images = spec.text && !spec.imageRequired ? [true, false] : [true];
6396
+ const views = spec.views === "none" ? [false] : [false, true];
6397
+ const skus = /* @__PURE__ */ new Set();
6398
+ for (const texture of textures)
6399
+ for (const pbr of pbrs)
6400
+ for (const resolution of resolutions)
6401
+ for (const image of images)
6402
+ for (const view of views) {
6403
+ if (view && !image) continue;
6404
+ skus.add(
6405
+ model3dPricingSku(
6406
+ row2,
6407
+ {
6408
+ ...texture !== void 0 && { texture },
6409
+ pbr,
6410
+ ...resolution !== void 0 && { resolution }
6411
+ },
6412
+ { image, views: view }
6413
+ )
6414
+ );
6415
+ }
6416
+ return [...skus].sort();
6136
6417
  }
6137
6418
 
6138
6419
  // src/catalog/input-spec.ts
@@ -6277,7 +6558,7 @@ var InputSpecSchema = z2.strictObject({
6277
6558
  }
6278
6559
  }
6279
6560
  });
6280
- function validateInputSpec(raw, row) {
6561
+ function validateInputSpec(raw, row2) {
6281
6562
  const parsed = InputSpecSchema.safeParse(raw);
6282
6563
  if (!parsed.success) {
6283
6564
  return {
@@ -6289,7 +6570,7 @@ function validateInputSpec(raw, row) {
6289
6570
  };
6290
6571
  }
6291
6572
  const spec = parsed.data;
6292
- const supportedTypes = TYPES_BY_ADAPTER.get(row.adapter);
6573
+ const supportedTypes = TYPES_BY_ADAPTER.get(row2.adapter);
6293
6574
  if (supportedTypes === void 0) {
6294
6575
  return {
6295
6576
  ok: false,
@@ -6302,18 +6583,18 @@ function validateInputSpec(raw, row) {
6302
6583
  };
6303
6584
  }
6304
6585
  const issues = [];
6305
- const allowed = ALLOWED_KEYS_BY_TYPE.get(row.type);
6306
- if (allowed === void 0 || !supportedTypes.includes(row.type)) {
6586
+ const allowed = ALLOWED_KEYS_BY_TYPE.get(row2.type);
6587
+ if (allowed === void 0 || !supportedTypes.includes(row2.type)) {
6307
6588
  issues.push({
6308
6589
  path: [],
6309
- 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`
6590
+ message: row2.adapter === "fal" ? `inputSpec on fal rows is only supported for image rows, not "${row2.type}"` : `inputSpec is not supported for "${row2.type}" rows`
6310
6591
  });
6311
6592
  } else {
6312
6593
  for (const key of Object.keys(spec.fields)) {
6313
6594
  if (!allowed.has(key)) {
6314
6595
  issues.push({
6315
6596
  path: ["fields", key],
6316
- message: `inputSpec.fields "${key}" is not supported for ${row.type} rows`
6597
+ message: `inputSpec.fields "${key}" is not supported for ${row2.type} rows`
6317
6598
  });
6318
6599
  }
6319
6600
  }
@@ -6321,13 +6602,13 @@ function validateInputSpec(raw, row) {
6321
6602
  if (!allowed.has(key)) {
6322
6603
  issues.push({
6323
6604
  path: ["values", key],
6324
- message: `inputSpec.values "${key}" is not supported for ${row.type} rows`
6605
+ message: `inputSpec.values "${key}" is not supported for ${row2.type} rows`
6325
6606
  });
6326
6607
  }
6327
6608
  }
6328
6609
  }
6329
6610
  if (spec.editEndpoint !== void 0) {
6330
- if (row.adapter !== "fal") {
6611
+ if (row2.adapter !== "fal") {
6331
6612
  issues.push({
6332
6613
  path: ["editEndpoint"],
6333
6614
  message: "inputSpec.editEndpoint is only supported on fal rows"
@@ -6371,7 +6652,7 @@ function validateInputSpec(raw, row) {
6371
6652
  if (allowed !== void 0 && !allowed.has(key)) {
6372
6653
  issues.push({
6373
6654
  path: ["arrays", name],
6374
- message: `inputSpec.arrays "${key}" is not supported for ${row.type} rows`
6655
+ message: `inputSpec.arrays "${key}" is not supported for ${row2.type} rows`
6375
6656
  });
6376
6657
  }
6377
6658
  if (key in spec.fields) {
@@ -6391,7 +6672,7 @@ function validateInputSpec(raw, row) {
6391
6672
  }
6392
6673
  }
6393
6674
  if (spec.dimensions !== void 0) {
6394
- if (row.type !== "image") {
6675
+ if (row2.type !== "image") {
6395
6676
  issues.push({
6396
6677
  path: ["dimensions"],
6397
6678
  message: "inputSpec.dimensions is only supported on image rows"
@@ -6413,7 +6694,7 @@ function validateInputSpec(raw, row) {
6413
6694
  });
6414
6695
  }
6415
6696
  }
6416
- const supports = row.constraints.supports ?? [];
6697
+ const supports = row2.constraints.supports ?? [];
6417
6698
  for (const key of INPUT_SPEC_SUPPORTS_KEYS) {
6418
6699
  if (supports.includes(key)) continue;
6419
6700
  if (key in spec.fields) {
@@ -6458,8 +6739,8 @@ function listIssues(name, values, fallback, defaultKey) {
6458
6739
  }
6459
6740
  return issues;
6460
6741
  }
6461
- function optionListIssues(row) {
6462
- const { constraints, defaults } = row;
6742
+ function optionListIssues(row2) {
6743
+ const { constraints, defaults } = row2;
6463
6744
  const issues = [
6464
6745
  ...listIssues(
6465
6746
  "voices",
@@ -6517,7 +6798,8 @@ var ModelTypeSchema = z3.enum([
6517
6798
  "voice-change",
6518
6799
  "dubbing",
6519
6800
  "lipsync",
6520
- "transcription"
6801
+ "transcription",
6802
+ "model3d"
6521
6803
  ]);
6522
6804
  var LifecycleSchema = z3.enum(["active", "deprecated", "retired"]);
6523
6805
  var SurfaceSchema = z3.enum(["cowork", "space_builder"]);
@@ -6581,7 +6863,8 @@ var UsageUnitSchema = z3.enum([
6581
6863
  "images",
6582
6864
  "seconds",
6583
6865
  "reported_cost_usd",
6584
- "compute_seconds"
6866
+ "compute_seconds",
6867
+ "requests"
6585
6868
  ]);
6586
6869
  var PricingKindSchema = z3.enum(["token", "image_size", "video_per_second", "flat"]);
6587
6870
  var ProviderOptionValueSchema = z3.lazy(
@@ -6635,6 +6918,156 @@ var LanguageOptionSchema = z3.looseObject({
6635
6918
  code: z3.string().min(1),
6636
6919
  name: z3.string().min(1)
6637
6920
  });
6921
+ var MODEL3D_FAMILY_RULES = {
6922
+ trellis: {
6923
+ textPath: false,
6924
+ views: ["none"],
6925
+ multiImage: false,
6926
+ texture: null,
6927
+ pbr: false,
6928
+ seed: true,
6929
+ textureRef: false,
6930
+ resolutions: "integer"
6931
+ },
6932
+ hunyuan: {
6933
+ textPath: true,
6934
+ views: ["none", "named"],
6935
+ multiImage: false,
6936
+ texture: ["none", "standard"],
6937
+ pbr: true,
6938
+ seed: false,
6939
+ textureRef: false,
6940
+ resolutions: null
6941
+ },
6942
+ tripo: {
6943
+ textPath: true,
6944
+ views: ["none", "ordered"],
6945
+ multiImage: true,
6946
+ texture: ["none", "standard", "detailed"],
6947
+ pbr: true,
6948
+ seed: true,
6949
+ textureRef: false,
6950
+ resolutions: null
6951
+ },
6952
+ rodin: {
6953
+ textPath: true,
6954
+ views: ["none", "unordered"],
6955
+ multiImage: false,
6956
+ texture: null,
6957
+ pbr: false,
6958
+ seed: true,
6959
+ textureRef: false,
6960
+ resolutions: null
6961
+ },
6962
+ meshy: {
6963
+ textPath: true,
6964
+ views: ["none", "unordered"],
6965
+ multiImage: true,
6966
+ texture: ["none", "standard"],
6967
+ pbr: true,
6968
+ seed: true,
6969
+ textureRef: true,
6970
+ resolutions: null
6971
+ },
6972
+ hi3d: {
6973
+ textPath: false,
6974
+ views: ["none", "named"],
6975
+ multiImage: true,
6976
+ texture: ["none", "standard"],
6977
+ pbr: true,
6978
+ seed: false,
6979
+ textureRef: false,
6980
+ resolutions: ["quality", "master"]
6981
+ },
6982
+ sam: {
6983
+ textPath: false,
6984
+ views: ["none"],
6985
+ multiImage: false,
6986
+ texture: null,
6987
+ pbr: false,
6988
+ seed: true,
6989
+ textureRef: false,
6990
+ resolutions: null
6991
+ }
6992
+ };
6993
+ function model3dSpecIssues(spec) {
6994
+ const issues = [];
6995
+ const add = (path, message) => issues.push({ path, message });
6996
+ const rules = MODEL3D_FAMILY_RULES[spec.family];
6997
+ const promptOnly = spec.text && !spec.imageRequired;
6998
+ if (spec.endpoints.image === void 0)
6999
+ add(["endpoints", "image"], "every row needs an image endpoint");
7000
+ if (promptOnly && !rules.textPath) {
7001
+ add(
7002
+ ["imageRequired"],
7003
+ `${spec.family} has no text-to-3D endpoint; a text row needs an image`
7004
+ );
7005
+ }
7006
+ if (promptOnly && spec.endpoints.text === void 0) {
7007
+ add(["endpoints", "text"], "a text row needs a text endpoint");
7008
+ }
7009
+ if (!rules.views.includes(spec.views)) {
7010
+ add(["views"], `${spec.family} takes views ${rules.views.join(" or ")}`);
7011
+ }
7012
+ if (spec.views === "none" && spec.maxImages !== 1) {
7013
+ add(["maxImages"], "a row without views takes 1 image");
7014
+ }
7015
+ if (spec.views === "unordered" && spec.maxImages < 2) {
7016
+ add(["maxImages"], "a row with views takes at least 2 images");
7017
+ }
7018
+ const slots = MODEL3D_IMAGE_SLOTS[spec.views].length;
7019
+ if (spec.views !== "none" && spec.maxImages > slots) {
7020
+ add(["maxImages"], `a row with ${spec.views} views sends at most ${slots} images`);
7021
+ }
7022
+ if ((spec.views === "named" || spec.views === "ordered") && spec.maxImages < slots) {
7023
+ add(
7024
+ ["maxImages"],
7025
+ `a row with ${spec.views} views takes ${slots} images (front and three sides)`
7026
+ );
7027
+ }
7028
+ if (spec.views !== "none" && rules.multiImage && spec.endpoints.multiImage === void 0) {
7029
+ add(["endpoints", "multiImage"], `${spec.family} sends views to a multi-image endpoint`);
7030
+ }
7031
+ if (rules.texture === null) {
7032
+ if (spec.texture.length > 0) add(["texture"], `${spec.family} has no texture switch`);
7033
+ } else {
7034
+ const allowed = rules.texture;
7035
+ if (spec.texture.length === 0) add(["texture"], `${spec.family} needs its texture options`);
7036
+ if (new Set(spec.texture).size !== spec.texture.length)
7037
+ add(["texture"], "texture options repeat");
7038
+ for (const t of spec.texture) {
7039
+ if (!allowed.includes(t)) add(["texture"], `${spec.family} has no "${t}" texture`);
7040
+ }
7041
+ }
7042
+ if (spec.pbr && !rules.pbr) add(["pbr"], `${spec.family} has no PBR switch`);
7043
+ if (spec.pbr && !spec.texture.some((t) => t !== "none")) {
7044
+ add(["pbr"], "PBR needs a textured option");
7045
+ }
7046
+ if (spec.seed && !rules.seed) add(["seed"], `${spec.family} takes no seed`);
7047
+ if (spec.seedMax !== void 0 && !spec.seed) add(["seedMax"], "seedMax needs seed");
7048
+ if (spec.textureRef && !rules.textureRef)
7049
+ add(["textureRef"], `${spec.family} takes no texture reference`);
7050
+ const res = spec.resolutions;
7051
+ if (rules.resolutions === null) {
7052
+ if (res !== void 0) add(["resolutions"], `${spec.family} has no resolution option`);
7053
+ } else if (res === void 0) {
7054
+ add(["resolutions"], `${spec.family} needs its resolution options`);
7055
+ } else {
7056
+ if (!res.options.includes(res.default)) {
7057
+ add(["resolutions", "default"], "default must be an option");
7058
+ }
7059
+ if (new Set(res.options).size !== res.options.length) {
7060
+ add(["resolutions", "options"], "resolution options repeat");
7061
+ }
7062
+ const allowed = rules.resolutions;
7063
+ for (const option of res.options) {
7064
+ const ok = allowed === "integer" ? /^[1-9][0-9]*$/.test(option) : allowed.includes(option);
7065
+ if (!ok)
7066
+ add(["resolutions", "options"], `${spec.family} has no "${option}" resolution`);
7067
+ }
7068
+ }
7069
+ return issues;
7070
+ }
6638
7071
  var VideoToolConstraintsSchema = z3.looseObject({
6639
7072
  kind: z3.enum(["upscale", "interpolate", "hdr", "bg-remove", "subtitles"]),
6640
7073
  upscaleFactor: RangeSchema.optional(),
@@ -6651,6 +7084,30 @@ var VideoToolConstraintsSchema = z3.looseObject({
6651
7084
  translationLanguages: z3.array(z3.string().min(1)).min(1).optional(),
6652
7085
  maxSecondsAbove1080p: z3.number().positive().optional()
6653
7086
  });
7087
+ var Model3dTextureSchema = z3.enum(["none", "standard", "detailed"]);
7088
+ var Model3dConstraintsSchema = z3.looseObject({
7089
+ family: z3.enum(["trellis", "hunyuan", "tripo", "rodin", "meshy", "hi3d", "sam"]),
7090
+ endpoints: z3.looseObject({
7091
+ text: z3.string().min(1).optional(),
7092
+ image: z3.string().min(1).optional(),
7093
+ multiImage: z3.string().min(1).optional()
7094
+ }),
7095
+ text: z3.boolean(),
7096
+ imageRequired: z3.boolean(),
7097
+ promptRequired: z3.boolean().optional(),
7098
+ views: z3.enum(["none", "unordered", "ordered", "named"]),
7099
+ maxImages: z3.number().int().positive(),
7100
+ texture: z3.array(Model3dTextureSchema),
7101
+ pbr: z3.boolean(),
7102
+ textureRef: z3.boolean(),
7103
+ seed: z3.boolean(),
7104
+ seedMax: z3.number().int().positive().optional(),
7105
+ resolutions: z3.looseObject({
7106
+ label: z3.string().min(1),
7107
+ options: z3.array(z3.string().min(1)).min(1),
7108
+ default: z3.string().min(1)
7109
+ }).optional()
7110
+ });
6654
7111
  var ModelConstraintsSchema = z3.looseObject({
6655
7112
  aspectRatios: z3.array(AspectRatioSchema).optional(),
6656
7113
  sizes: z3.array(ImageSizeSchema).optional(),
@@ -6678,6 +7135,7 @@ var ModelConstraintsSchema = z3.looseObject({
6678
7135
  returns: z3.enum(["new", "joined"]).optional()
6679
7136
  }).optional(),
6680
7137
  tool: VideoToolConstraintsSchema.optional(),
7138
+ model3d: Model3dConstraintsSchema.optional(),
6681
7139
  // Loose on purpose: the read path keeps a row whose value is invalid (the accessors in
6682
7140
  // conventions.ts read it as "not set"); CatalogModelSchema below rejects it on write.
6683
7141
  audio: z3.unknown().optional(),
@@ -6793,29 +7251,47 @@ var CatalogModelSchemaBase = z3.looseObject({
6793
7251
  pricingKind: PricingKindSchema,
6794
7252
  display: CatalogDisplaySchema.optional(),
6795
7253
  capabilities: CatalogCapabilitiesSchema.optional()
6796
- }).superRefine((row, ctx) => {
6797
- if (row.lifecycle === "active" && !row.display) {
7254
+ }).superRefine((row2, ctx) => {
7255
+ if (row2.lifecycle === "active" && !row2.display) {
6798
7256
  ctx.addIssue({
6799
7257
  code: "custom",
6800
7258
  path: ["display"],
6801
7259
  message: "active rows need display"
6802
7260
  });
6803
7261
  }
6804
- if (row.lifecycle === "active" && row.type === "text" && !row.capabilities?.contextWindow) {
7262
+ if (row2.lifecycle === "active" && row2.type === "text" && !row2.capabilities?.contextWindow) {
6805
7263
  ctx.addIssue({
6806
7264
  code: "custom",
6807
7265
  path: ["capabilities", "contextWindow"],
6808
7266
  message: "active text rows need contextWindow"
6809
7267
  });
6810
7268
  }
6811
- if (row.type === "video-tool" && row.constraints.tool === void 0) {
7269
+ if (row2.type === "video-tool" && row2.constraints.tool === void 0) {
6812
7270
  ctx.addIssue({
6813
7271
  code: "custom",
6814
7272
  path: ["constraints", "tool"],
6815
7273
  message: "video-tool rows need constraints.tool"
6816
7274
  });
6817
7275
  }
6818
- if (row.replacedBy !== void 0 && row.replacedBy === row.id) {
7276
+ if (row2.type === "model3d") {
7277
+ const spec = row2.constraints.model3d;
7278
+ if (spec === void 0) {
7279
+ ctx.addIssue({
7280
+ code: "custom",
7281
+ path: ["constraints", "model3d"],
7282
+ message: "model3d rows need constraints.model3d"
7283
+ });
7284
+ } else {
7285
+ for (const issue of model3dSpecIssues(spec)) {
7286
+ ctx.addIssue({
7287
+ code: "custom",
7288
+ path: ["constraints", "model3d", ...issue.path],
7289
+ message: issue.message
7290
+ });
7291
+ }
7292
+ }
7293
+ }
7294
+ if (row2.replacedBy !== void 0 && row2.replacedBy === row2.id) {
6819
7295
  ctx.addIssue({
6820
7296
  code: "custom",
6821
7297
  path: ["replacedBy"],
@@ -6824,8 +7300,8 @@ var CatalogModelSchemaBase = z3.looseObject({
6824
7300
  }
6825
7301
  });
6826
7302
  var CatalogModelSchema = CatalogModelSchemaBase.superRefine(
6827
- (row, ctx) => {
6828
- const transport = row.providerOptions?.["modelkit"]?.["transport"];
7303
+ (row2, ctx) => {
7304
+ const transport = row2.providerOptions?.["modelkit"]?.["transport"];
6829
7305
  if (transport !== void 0 && transport !== "direct" && transport !== "bedrock") {
6830
7306
  ctx.addIssue({
6831
7307
  code: "custom",
@@ -6833,9 +7309,9 @@ var CatalogModelSchema = CatalogModelSchemaBase.superRefine(
6833
7309
  message: 'transport must be "direct" or "bedrock"'
6834
7310
  });
6835
7311
  }
6836
- const inputSpecRaw = row.providerOptions?.["modelkit"]?.["inputSpec"];
7312
+ const inputSpecRaw = row2.providerOptions?.["modelkit"]?.["inputSpec"];
6837
7313
  if (inputSpecRaw !== void 0) {
6838
- const result = validateInputSpec(inputSpecRaw, row);
7314
+ const result = validateInputSpec(inputSpecRaw, row2);
6839
7315
  if (!result.ok) {
6840
7316
  for (const issue of result.issues) {
6841
7317
  ctx.addIssue({
@@ -6846,7 +7322,7 @@ var CatalogModelSchema = CatalogModelSchemaBase.superRefine(
6846
7322
  }
6847
7323
  }
6848
7324
  }
6849
- const audio = row.constraints.audio;
7325
+ const audio = row2.constraints.audio;
6850
7326
  if (audio !== void 0 && !AudioOutputSchema.safeParse(audio).success) {
6851
7327
  ctx.addIssue({
6852
7328
  code: "custom",
@@ -6854,7 +7330,7 @@ var CatalogModelSchema = CatalogModelSchemaBase.superRefine(
6854
7330
  message: 'audio must be "always", "optional" or "never"'
6855
7331
  });
6856
7332
  }
6857
- const refs = row.constraints.references;
7333
+ const refs = row2.constraints.references;
6858
7334
  for (const kind of ["images", "videos", "audios"]) {
6859
7335
  const least = refs?.min?.[kind];
6860
7336
  const most = refs?.[kind];
@@ -6866,10 +7342,10 @@ var CatalogModelSchema = CatalogModelSchemaBase.superRefine(
6866
7342
  });
6867
7343
  }
6868
7344
  }
6869
- for (const issue of optionListIssues(row)) {
7345
+ for (const issue of optionListIssues(row2)) {
6870
7346
  ctx.addIssue({ code: "custom", path: issue.path, message: issue.message });
6871
7347
  }
6872
- const prompt = row.constraints.prompt;
7348
+ const prompt = row2.constraints.prompt;
6873
7349
  if (prompt !== void 0) {
6874
7350
  const parsed = PromptConventionsSchema.safeParse(prompt);
6875
7351
  if (!parsed.success) {
@@ -6884,7 +7360,7 @@ var CatalogModelSchema = CatalogModelSchemaBase.superRefine(
6884
7360
  }
6885
7361
  }
6886
7362
  );
6887
- var CatalogSchema = z3.array(CatalogModelSchemaBase.transform((row) => normaliseConventions(row).row)).superRefine((rows, ctx) => {
7363
+ var CatalogSchema = z3.array(CatalogModelSchemaBase.transform((row2) => normaliseConventions(row2).row)).superRefine((rows, ctx) => {
6888
7364
  for (const issue of collisionIssues(rows)) {
6889
7365
  ctx.addIssue({
6890
7366
  code: "custom",
@@ -6958,22 +7434,22 @@ function quarantine(rawRows, logger) {
6958
7434
  dropped += 1;
6959
7435
  continue;
6960
7436
  }
6961
- const row = parsed.data;
6962
- const inputSpecRaw = row.providerOptions?.["modelkit"]?.["inputSpec"];
7437
+ const row2 = parsed.data;
7438
+ const inputSpecRaw = row2.providerOptions?.["modelkit"]?.["inputSpec"];
6963
7439
  if (inputSpecRaw !== void 0) {
6964
- const result = validateInputSpec(inputSpecRaw, row);
7440
+ const result = validateInputSpec(inputSpecRaw, row2);
6965
7441
  if (!result.ok) {
6966
7442
  const first = result.issues[0];
6967
7443
  const detail = first ? dropReason(first.path, first.message) : "invalid inputSpec";
6968
7444
  logger.warn(
6969
- `[modelkit] catalog row ${row.id} has an invalid providerOptions.modelkit.inputSpec: ${detail}; calls fail until it is fixed`
7445
+ `[modelkit] catalog row ${row2.id} has an invalid providerOptions.modelkit.inputSpec: ${detail}; calls fail until it is fixed`
6970
7446
  );
6971
7447
  }
6972
7448
  }
6973
- const normalised = normaliseConventions(row);
7449
+ const normalised = normaliseConventions(row2);
6974
7450
  if (normalised.invalidKeys.length > 0) {
6975
7451
  logger.warn(
6976
- `[modelkit] catalog row ${row.id} has an invalid ${normalised.invalidKeys.join(", ")}; read as not set`
7452
+ `[modelkit] catalog row ${row2.id} has an invalid ${normalised.invalidKeys.join(", ")}; read as not set`
6977
7453
  );
6978
7454
  }
6979
7455
  valid.push(normalised.row);
@@ -6987,10 +7463,10 @@ function quarantine(rawRows, logger) {
6987
7463
  if (!firstByIndex.has(issue.index)) firstByIndex.set(issue.index, issue);
6988
7464
  }
6989
7465
  for (const [index, issue] of [...firstByIndex.entries()].sort((a, b) => a[0] - b[0])) {
6990
- const row = kept[index];
6991
- if (!row) continue;
7466
+ const row2 = kept[index];
7467
+ if (!row2) continue;
6992
7468
  logger.warn(
6993
- `[modelkit] catalog row dropped id=${row.id} reason=${String(issue.path[0] ?? "")} ${issue.message}`
7469
+ `[modelkit] catalog row dropped id=${row2.id} reason=${String(issue.path[0] ?? "")} ${issue.message}`
6994
7470
  );
6995
7471
  }
6996
7472
  const dropSet = new Set(firstByIndex.keys());
@@ -7209,9 +7685,9 @@ var ToolSchema = z6.object({
7209
7685
  translationLanguages: z6.array(z6.string().min(1)).min(1).optional(),
7210
7686
  maxSecondsAbove1080p: z6.number().positive().optional()
7211
7687
  });
7212
- function videoToolConstraints(row) {
7213
- if (row.type !== "video-tool") return void 0;
7214
- const parsed = ToolSchema.safeParse(row.constraints.tool);
7688
+ function videoToolConstraints(row2) {
7689
+ if (row2.type !== "video-tool") return void 0;
7690
+ const parsed = ToolSchema.safeParse(row2.constraints.tool);
7215
7691
  if (!parsed.success) return void 0;
7216
7692
  const {
7217
7693
  kind,
@@ -7258,16 +7734,16 @@ function resolutionTier(width, height) {
7258
7734
  function fail(error) {
7259
7735
  return { ok: false, error };
7260
7736
  }
7261
- function planVideoTool(row, req) {
7262
- const tool = videoToolConstraints(row);
7263
- if (!tool) return fail(`${row.id} is not a video tool`);
7737
+ function planVideoTool(row2, req) {
7738
+ const tool = videoToolConstraints(row2);
7739
+ if (!tool) return fail(`${row2.id} is not a video tool`);
7264
7740
  const { width, height, durationSeconds, fps } = req.source;
7265
7741
  if (!(width > 0 && height > 0 && durationSeconds > 0)) {
7266
7742
  return fail("The source video's width, height and duration are required");
7267
7743
  }
7268
- const maxSeconds = row.constraints.sourceVideoSeconds?.max;
7744
+ const maxSeconds = row2.constraints.sourceVideoSeconds?.max;
7269
7745
  if (maxSeconds !== void 0 && overMax(durationSeconds, maxSeconds)) {
7270
- return fail(`${row.label} takes source videos up to ${maxSeconds} seconds.`);
7746
+ return fail(`${row2.label} takes source videos up to ${maxSeconds} seconds.`);
7271
7747
  }
7272
7748
  const base = {
7273
7749
  durationSeconds,
@@ -7278,7 +7754,7 @@ function planVideoTool(row, req) {
7278
7754
  if (factor === void 0) return fail("An upscale factor is required");
7279
7755
  const range2 = tool.upscaleFactor;
7280
7756
  if (range2 && (factor < range2.min || factor > range2.max)) {
7281
- return fail(`${row.label} upscales by ${range2.min}x to ${range2.max}x.`);
7757
+ return fail(`${row2.label} upscales by ${range2.min}x to ${range2.max}x.`);
7282
7758
  }
7283
7759
  const outWidth = Math.round(width * factor);
7284
7760
  const outHeight = Math.round(height * factor);
@@ -7306,7 +7782,7 @@ function planVideoTool(row, req) {
7306
7782
  }
7307
7783
  const range2 = tool.fps;
7308
7784
  if (range2 && (target < range2.min || target > range2.max)) {
7309
- return fail(`${row.label} outputs ${range2.min} to ${range2.max} fps.`);
7785
+ return fail(`${row2.label} outputs ${range2.min} to ${range2.max} fps.`);
7310
7786
  }
7311
7787
  return {
7312
7788
  ok: true,
@@ -7335,7 +7811,7 @@ function planVideoTool(row, req) {
7335
7811
  if (tool.kind === "subtitles") {
7336
7812
  const resolution = resolutionTier(width, height);
7337
7813
  const problem = subtitleProblem(
7338
- row.label,
7814
+ row2.label,
7339
7815
  tool,
7340
7816
  req.subtitles,
7341
7817
  resolution,
@@ -7347,9 +7823,9 @@ function planVideoTool(row, req) {
7347
7823
  const formats = tool.outputFormats ?? ["h265"];
7348
7824
  const format = req.outputFormat ?? formats[0] ?? "h265";
7349
7825
  if (!formats.includes(format)) {
7350
- return fail(`${row.label} writes ${formats.join(" or ")}.`);
7826
+ return fail(`${row2.label} writes ${formats.join(" or ")}.`);
7351
7827
  }
7352
- const timing = renderedTiming(row, tool, durationSeconds, fps);
7828
+ const timing = renderedTiming(row2, tool, durationSeconds, fps);
7353
7829
  if (!timing.ok) return fail(timing.error);
7354
7830
  const out = shrinkToShortEdge(width, height, tool.maxOutputShortEdge);
7355
7831
  return {
@@ -7365,7 +7841,7 @@ function planVideoTool(row, req) {
7365
7841
  };
7366
7842
  }
7367
7843
  var DEFAULT_FPS = 24;
7368
- function renderedTiming(row, tool, durationSeconds, fps) {
7844
+ function renderedTiming(row2, tool, durationSeconds, fps) {
7369
7845
  const { maxOutputFps, minOutputFrames, maxOutputFrames } = tool;
7370
7846
  if (maxOutputFps === void 0 && minOutputFrames === void 0 && maxOutputFrames === void 0) {
7371
7847
  return fps !== void 0 ? { ok: true, fps } : { ok: true };
@@ -7374,7 +7850,7 @@ function renderedTiming(row, tool, durationSeconds, fps) {
7374
7850
  const frames = Math.max(minOutputFrames ?? 1, Math.round(durationSeconds * rate));
7375
7851
  if (maxOutputFrames !== void 0 && frames > maxOutputFrames) {
7376
7852
  const limit = `${maxOutputFrames} frames (${seconds(maxOutputFrames, rate)})`;
7377
- return { ok: false, error: `${row.label} renders up to ${limit}.` };
7853
+ return { ok: false, error: `${row2.label} renders up to ${limit}.` };
7378
7854
  }
7379
7855
  return { ok: true, fps: rate, frames, durationSeconds: frames / rate };
7380
7856
  }
@@ -7718,6 +8194,30 @@ function applyFalImageRules(model, req, callerSize, warnings) {
7718
8194
  req.size = exact.tier;
7719
8195
  }
7720
8196
 
8197
+ // src/replicate-video-kinds.ts
8198
+ function replicateBaseModelId(providerModelId) {
8199
+ const colon = providerModelId.indexOf(":");
8200
+ return colon === -1 ? providerModelId : providerModelId.slice(0, colon);
8201
+ }
8202
+ var REPLICATE_VIDEO_KINDS = /* @__PURE__ */ new Map([
8203
+ ["kling-video/v2.5-turbo/pro/image-to-video", "kling"],
8204
+ ["kling-video/v3.0/pro/image-to-video", "kling"],
8205
+ ["kwaivgi/kling-v3-video", "kling"],
8206
+ ["kwaivgi/kling-v3-omni-video", "kling-omni"],
8207
+ ["minimax/hailuo-02", "hailuo"]
8208
+ ]);
8209
+ function videoKind(providerModelId) {
8210
+ return REPLICATE_VIDEO_KINDS.get(replicateBaseModelId(providerModelId));
8211
+ }
8212
+ var KLING_TIERS = [
8213
+ { mode: "standard", resolution: "720p" },
8214
+ { mode: "pro", resolution: "1080p" },
8215
+ { mode: "4k", resolution: "4k" }
8216
+ ];
8217
+ function klingTier(req) {
8218
+ return KLING_TIERS.find((tier) => tier.resolution === req.resolution) ?? KLING_TIERS.find((tier) => tier.mode === req.mode) ?? KLING_TIERS[0];
8219
+ }
8220
+
7721
8221
  // src/resolve-video-rules.ts
7722
8222
  var MOTION_PRO = "fal-ai/kling-video/v3/pro/motion-control";
7723
8223
  var MOTION_STANDARD = "fal-ai/kling-video/v3/standard/motion-control";
@@ -7891,6 +8391,16 @@ function h3EndFrameRatioWarning(model, ratio) {
7891
8391
  message: `${model.id} follows the end frame's aspect ratio`
7892
8392
  };
7893
8393
  }
8394
+ function isReplicateKling(model) {
8395
+ if (model.adapter !== "replicate") return false;
8396
+ const kind = videoKind(model.providerModelId);
8397
+ return kind === "kling" || kind === "kling-omni";
8398
+ }
8399
+ function fillReplicateKlingResolution(model, req) {
8400
+ if (isReplicateKling(model) && req.resolution === void 0) {
8401
+ req.resolution = klingTier(req).resolution;
8402
+ }
8403
+ }
7894
8404
  function applyFalVideoRules(model, req, callerRatio, warnings) {
7895
8405
  if (model.adapter !== "fal") return;
7896
8406
  const problem = falVideoProblem(model.providerModelId, withPromptForResolve(req));
@@ -8280,8 +8790,10 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
8280
8790
  warnings
8281
8791
  );
8282
8792
  if (aspectRatio !== void 0) merged.aspectRatio = aspectRatio;
8793
+ fillReplicateKlingResolution(model, merged);
8283
8794
  const resolution = resolveVideoResolution(merged.resolution, model, onUnsupported, warnings);
8284
8795
  if (resolution !== void 0) merged.resolution = resolution;
8796
+ if (isReplicateKling(model)) delete merged.mode;
8285
8797
  const duration = resolveDuration(
8286
8798
  merged.durationSeconds,
8287
8799
  c.durations,
@@ -8687,7 +9199,10 @@ var MEDIA_METHODS = {
8687
9199
  lipsync: ["lipsync"],
8688
9200
  dubbing: ["dub"],
8689
9201
  transcription: ["transcribe"],
8690
- "video-tool": ["submitVideoTool"]
9202
+ "video-tool": ["submitVideoTool"],
9203
+ // 3D jobs run through submitModel3d, which checks the row type itself; their preflight
9204
+ // is model3dInputRefusal, not resolveOptions.
9205
+ model3d: []
8691
9206
  };
8692
9207
  var METHOD_NOUN = {
8693
9208
  generateImage: "an image model",
@@ -8801,6 +9316,8 @@ export {
8801
9316
  IMAGE_MODELS,
8802
9317
  MEDIA_METHODS,
8803
9318
  MEDIA_NODE_MODELS,
9319
+ MODEL3D_IMAGE_SLOTS,
9320
+ MODEL3D_MODELS,
8804
9321
  MODELS,
8805
9322
  ModelKitError,
8806
9323
  OTHER_MODELS,
@@ -8818,6 +9335,13 @@ export {
8818
9335
  isModelKitError,
8819
9336
  liveCatalog,
8820
9337
  liveState,
9338
+ model3dConstraints,
9339
+ model3dInputRefusal,
9340
+ model3dPricingSku,
9341
+ model3dResolution,
9342
+ model3dSeedFits,
9343
+ model3dSkus,
9344
+ model3dTexture,
8821
9345
  nearestAspectRatio,
8822
9346
  normalizeExposure,
8823
9347
  outputAudio,