@shop-os/modelkit 0.7.8 → 0.7.10

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
@@ -5802,38 +5802,38 @@ var VIDEO_MODELS = [
5802
5802
  capabilities: { ...FRAMES_EXCLUDE_REFERENCES }
5803
5803
  },
5804
5804
  {
5805
- // mode standard/pro/4k selects 720p/1080p/4K; the endpoint takes no separate resolution.
5806
- // Replicate: "Max 7 [images] without video, 4 with video"; 4K does not support
5807
- // reference_video. No `videos` limit yet: the adapter sends no reference video,
5808
- // so `imagesWithVideo` stays dormant until one is wired through.
5805
+ // fal Kling O3 (adapters/fal-kling-omni.ts): mode standard/pro/4k selects 720p/1080p/4K
5806
+ // in the endpoint path. Moved off Replicate kwaivgi/kling-v3-omni-video, which fal sells
5807
+ // at half the price; the id and inputs stay. The Replicate mapper stays for deployed
5808
+ // model_catalog rows not yet switched. Frames and reference images share fal's cap of 7.
5809
+ // Reference video, multi-shot and keep-sound were never wired, so stay off.
5809
5810
  id: "kling-v3-omni-video",
5810
5811
  aliases: ["kwaivgi/kling-v3-omni-video", "kling-v3-omni"],
5811
5812
  label: "Kling V3 Omni",
5812
5813
  type: "video",
5813
- adapter: "replicate",
5814
- providerModelId: "kwaivgi/kling-v3-omni-video",
5814
+ adapter: "fal",
5815
+ providerModelId: "fal-ai/kling-video/o3",
5815
5816
  lifecycle: "active",
5816
5817
  exposure: ["cowork", "space_builder"],
5817
5818
  constraints: {
5818
5819
  aspectRatios: [...KLING_OMNI_RATIOS],
5819
5820
  resolutions: ["720p", "1080p", "4k"],
5820
5821
  durations: { min: 3, max: 15 },
5821
- references: { images: 7, imagesWithVideo: 4 },
5822
+ references: { images: 7, videos: 0, audios: 0 },
5822
5823
  supports: ["generateAudio", "lastFrame"],
5823
5824
  prompt: KLING_PROMPT2,
5824
5825
  audio: "optional"
5825
5826
  },
5826
5827
  defaults: { durationSeconds: 5, aspectRatio: "16:9", generateAudio: true, mode: "pro" },
5827
- usage: { unit: "compute_seconds" },
5828
+ usage: { ...VIDEO_USAGE3 },
5828
5829
  pricingKind: "video_per_second",
5829
5830
  display: {
5830
5831
  provider: "kuaishou",
5831
5832
  logo: "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/kling-color.png",
5832
- description: "Kuaishou Kling Video 3.0 Omni unified generation and editing from text, start/end images, up to 7 reference images, and reference video; up to 15 seconds at up to 4K."
5833
+ description: "Kuaishou Kling Video 3.0 Omni generation from text, start/end images and up to 7 reference images, with optional native audio; up to 15 seconds at up to 4K."
5833
5834
  }
5834
- // end_image "Requires start_image", but no lastFrameRequiresFirstFrame: SpaceLab resolves
5835
- // replicate rows in error mode, so the flag would refuse its end-frame-only nodes, which
5836
- // the adapter sends as start_image.
5835
+ // No lastFrameRequiresFirstFrame: fal image-to-video needs a start frame, so the adapter
5836
+ // sends a lone end frame as the start frame, as the Replicate model took it.
5837
5837
  },
5838
5838
  {
5839
5839
  id: "minimax-h3",
@@ -9448,11 +9448,11 @@ function toolInput(ctx, req, output) {
9448
9448
  }
9449
9449
  var EXR_DEFAULT_PROMPT = "The same video in high dynamic range, with unchanged content, motion, framing and timing.";
9450
9450
  async function submitFalVideoTool(req, ctx, opts) {
9451
- const plan3 = planVideoTool(ctx.model, req);
9452
- if (!plan3.ok) {
9451
+ const plan4 = planVideoTool(ctx.model, req);
9452
+ if (!plan4.ok) {
9453
9453
  throw new ModelKitError({
9454
9454
  code: "unsupported_option",
9455
- message: plan3.error,
9455
+ message: plan4.error,
9456
9456
  provider: "fal",
9457
9457
  model: ctx.model.id,
9458
9458
  retryable: false
@@ -9460,7 +9460,7 @@ async function submitFalVideoTool(req, ctx, opts) {
9460
9460
  }
9461
9461
  const target = new URL(`${FAL_QUEUE_ORIGIN}/${ctx.model.providerModelId}`);
9462
9462
  if (opts.webhookUrl !== void 0) target.searchParams.set("fal_webhook", opts.webhookUrl);
9463
- const res = await queueFetch(ctx, target.toString(), "POST", toolInput(ctx, req, plan3.output));
9463
+ const res = await queueFetch(ctx, target.toString(), "POST", toolInput(ctx, req, plan4.output));
9464
9464
  const parsed = submitResponseSchema.safeParse(await readJson(ctx, res));
9465
9465
  if (!parsed.success) {
9466
9466
  throw new ModelKitError({
@@ -9478,7 +9478,7 @@ async function submitFalVideoTool(req, ctx, opts) {
9478
9478
  statusUrl: parsed.data.status_url,
9479
9479
  responseUrl: parsed.data.response_url,
9480
9480
  cancelUrl: parsed.data.cancel_url,
9481
- output: plan3.output
9481
+ output: plan4.output
9482
9482
  };
9483
9483
  }
9484
9484
  async function falVideoToolStatus(sub, ctx) {
@@ -10167,14 +10167,14 @@ function planFalImage(req, providerModelId, model) {
10167
10167
  const exact = falExactSize(spec, req);
10168
10168
  const call = { label: spec.label, req, refs, edit: edit2, ...exact !== void 0 && { exact } };
10169
10169
  const built = family.build(call, model);
10170
- const plan3 = {
10170
+ const plan4 = {
10171
10171
  endpoint: edit2 && family.editEndpoint !== void 0 ? family.editEndpoint : id,
10172
10172
  input: built.input,
10173
10173
  output: family.output ?? "images"
10174
10174
  };
10175
- if (built.imageQuality !== void 0) plan3.imageQuality = built.imageQuality;
10176
- if (built.imageSize !== void 0) plan3.imageSize = built.imageSize;
10177
- return plan3;
10175
+ if (built.imageQuality !== void 0) plan4.imageQuality = built.imageQuality;
10176
+ if (built.imageSize !== void 0) plan4.imageSize = built.imageSize;
10177
+ return plan4;
10178
10178
  }
10179
10179
  var FalFileSchema = import_zod14.z.object({ url: import_zod14.z.string(), content_type: import_zod14.z.string().nullish() });
10180
10180
  var ImagesPayloadSchema = import_zod14.z.object({ images: import_zod14.z.array(FalFileSchema) });
@@ -10196,18 +10196,18 @@ async function downloadFalFile(ctx, file) {
10196
10196
  const mime = res.headers.get("content-type") ?? file.content_type ?? "";
10197
10197
  return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
10198
10198
  }
10199
- function filesOf(payload, plan3) {
10200
- if (plan3.output === "image") {
10199
+ function filesOf(payload, plan4) {
10200
+ if (plan4.output === "image") {
10201
10201
  const parsed2 = ImagePayloadSchema.safeParse(payload);
10202
10202
  return parsed2.success ? [parsed2.data.image] : [];
10203
10203
  }
10204
10204
  const parsed = ImagesPayloadSchema.safeParse(payload);
10205
10205
  return parsed.success ? parsed.data.images : [];
10206
10206
  }
10207
- async function collectFalPlanImages(payload, plan3, ctx, req) {
10208
- const files = filesOf(payload, plan3);
10207
+ async function collectFalPlanImages(payload, plan4, ctx, req) {
10208
+ const files = filesOf(payload, plan4);
10209
10209
  if (files.length === 0) {
10210
- throw fail2(ctx.model.id, `fal ${plan3.endpoint} returned no image`, "provider_rejected");
10210
+ throw fail2(ctx.model.id, `fal ${plan4.endpoint} returned no image`, "provider_rejected");
10211
10211
  }
10212
10212
  const images = await Promise.all(
10213
10213
  files.map(async (file) => {
@@ -10222,18 +10222,18 @@ async function collectFalPlanImages(payload, plan3, ctx, req) {
10222
10222
  unit: "images",
10223
10223
  quantity: images.length
10224
10224
  };
10225
- const billedSize = plan3.imageSize ?? req.size;
10225
+ const billedSize = plan4.imageSize ?? req.size;
10226
10226
  if (billedSize !== void 0 && ctx.model.type === "image") usage3.imageSize = billedSize;
10227
- if (plan3.imageQuality !== void 0) usage3.imageQuality = plan3.imageQuality;
10227
+ if (plan4.imageQuality !== void 0) usage3.imageQuality = plan4.imageQuality;
10228
10228
  const result = { images, usage: usage3, raw: payload };
10229
10229
  const remote = files.find((f) => !f.url.startsWith("data:"));
10230
10230
  if (remote !== void 0) result.outputUrl = remote.url;
10231
10231
  return result;
10232
10232
  }
10233
10233
  async function generateFalFamilyImage(req, ctx, run) {
10234
- const plan3 = planFalImage(req, ctx.model.providerModelId, ctx.model.id);
10235
- const payload = await run(plan3.endpoint, plan3.input);
10236
- return collectFalPlanImages(payload, plan3, ctx, req);
10234
+ const plan4 = planFalImage(req, ctx.model.providerModelId, ctx.model.id);
10235
+ const payload = await run(plan4.endpoint, plan4.input);
10236
+ return collectFalPlanImages(payload, plan4, ctx, req);
10237
10237
  }
10238
10238
 
10239
10239
  // src/adapters/fal-mask.ts
@@ -11331,10 +11331,50 @@ var KLING_TIERS = [
11331
11331
  { mode: "pro", resolution: "1080p" },
11332
11332
  { mode: "4k", resolution: "4k" }
11333
11333
  ];
11334
+ var KLING_O3_OMNI = "fal-ai/kling-video/o3";
11334
11335
  function klingTier(req) {
11335
11336
  return KLING_TIERS.find((tier) => tier.resolution === req.resolution) ?? KLING_TIERS.find((tier) => tier.mode === req.mode) ?? KLING_TIERS[0];
11336
11337
  }
11337
11338
 
11339
+ // src/adapters/fal-kling-omni.ts
11340
+ function plan(req, ctx) {
11341
+ const tier = klingTier(req);
11342
+ const duration = wholeSeconds(req, ctx);
11343
+ const input = {
11344
+ prompt: req.prompt.trim(),
11345
+ duration: String(duration),
11346
+ generate_audio: req.generateAudio ?? true
11347
+ };
11348
+ const start = req.firstFrame ?? req.lastFrame;
11349
+ const end = req.firstFrame ? req.lastFrame : void 0;
11350
+ const images = urls(req.referenceImages);
11351
+ let task;
11352
+ if (images.length > 0) {
11353
+ task = "reference-to-video";
11354
+ input["image_urls"] = images;
11355
+ if (start) input["start_image_url"] = refToUrl(start);
11356
+ if (end) input["end_image_url"] = refToUrl(end);
11357
+ } else if (start) {
11358
+ task = "image-to-video";
11359
+ input["image_url"] = refToUrl(start);
11360
+ if (end) input["end_image_url"] = refToUrl(end);
11361
+ } else {
11362
+ task = "text-to-video";
11363
+ }
11364
+ const ratio = concreteRatio(req);
11365
+ if (ratio !== void 0 && start === void 0) input["aspect_ratio"] = ratio;
11366
+ return {
11367
+ endpoint: `${KLING_O3_OMNI}/${tier.mode}/${task}`,
11368
+ input,
11369
+ resolution: tier.resolution,
11370
+ seconds: requestedSeconds(duration)
11371
+ };
11372
+ }
11373
+ var klingOmniFamily = {
11374
+ ids: /* @__PURE__ */ new Set([KLING_O3_OMNI]),
11375
+ plan
11376
+ };
11377
+
11338
11378
  // src/resolve-video-rules.ts
11339
11379
  var MOTION_PRO2 = "fal-ai/kling-video/v3/pro/motion-control";
11340
11380
  var MOTION_STANDARD2 = "fal-ai/kling-video/v3/standard/motion-control";
@@ -11479,6 +11519,7 @@ var RULES = /* @__PURE__ */ new Map([
11479
11519
  [MOTION_PRO2, motionControl2],
11480
11520
  [MOTION_STANDARD2, motionControl2],
11481
11521
  [O3_REFERENCE2, o3Reference2],
11522
+ [KLING_O3_OMNI, o3Reference2],
11482
11523
  [O3_EDIT2, (req) => needsSource(req) ?? needsPrompt(req)],
11483
11524
  [H3_TURBO, h3Turbo],
11484
11525
  [MINIMAX_H3_INSERT, h3Insert],
@@ -11508,13 +11549,14 @@ function h3EndFrameRatioWarning(model, ratio) {
11508
11549
  message: `${model.id} follows the end frame's aspect ratio`
11509
11550
  };
11510
11551
  }
11511
- function isReplicateKling(model) {
11552
+ function takesKlingMode(model) {
11553
+ if (model.adapter === "fal") return model.providerModelId.toLowerCase() === KLING_O3_OMNI;
11512
11554
  if (model.adapter !== "replicate") return false;
11513
11555
  const kind = videoKind(model.providerModelId);
11514
11556
  return kind === "kling" || kind === "kling-omni";
11515
11557
  }
11516
- function fillReplicateKlingResolution(model, req) {
11517
- if (isReplicateKling(model) && req.resolution === void 0) {
11558
+ function fillKlingModeResolution(model, req) {
11559
+ if (takesKlingMode(model) && req.resolution === void 0) {
11518
11560
  req.resolution = klingTier(req).resolution;
11519
11561
  }
11520
11562
  }
@@ -11653,7 +11695,7 @@ var minimaxH3MaxFamily = {
11653
11695
 
11654
11696
  // src/adapters/fal-omnihuman.ts
11655
11697
  var OMNIHUMAN_V22 = "bytedance/omnihuman/v2";
11656
- function plan(req, ctx) {
11698
+ function plan2(req, ctx) {
11657
11699
  const [image] = req.referenceImages ?? [];
11658
11700
  const [audio] = req.referenceAudios ?? [];
11659
11701
  if (image === void 0 || audio === void 0) {
@@ -11664,14 +11706,14 @@ function plan(req, ctx) {
11664
11706
  return { endpoint: OMNIHUMAN_V22, input, seconds: inputLengthSeconds(req, audio) };
11665
11707
  }
11666
11708
  var OMNIHUMAN_MODEL_IDS = /* @__PURE__ */ new Set([OMNIHUMAN_V22]);
11667
- var omnihumanFamily = { ids: OMNIHUMAN_MODEL_IDS, plan };
11709
+ var omnihumanFamily = { ids: OMNIHUMAN_MODEL_IDS, plan: plan2 };
11668
11710
 
11669
11711
  // src/adapters/fal-vidu.ts
11670
11712
  var FAMILY2 = "fal-ai/vidu/q4";
11671
11713
  function viduTier(resolution) {
11672
11714
  return resolution === "2k" || resolution === "4k" ? upperTier(resolution) : resolution;
11673
11715
  }
11674
- function plan2(req, ctx) {
11716
+ function plan3(req, ctx) {
11675
11717
  const images = urls(req.referenceImages);
11676
11718
  const audios = urls(req.referenceAudios);
11677
11719
  const duration = wholeSeconds(req, ctx);
@@ -11698,11 +11740,12 @@ function plan2(req, ctx) {
11698
11740
  return { endpoint, input, resolution, seconds: requestedSeconds(duration) };
11699
11741
  }
11700
11742
  var VIDU_MODEL_IDS = /* @__PURE__ */ new Set([FAMILY2]);
11701
- var viduFamily = { ids: VIDU_MODEL_IDS, plan: plan2 };
11743
+ var viduFamily = { ids: VIDU_MODEL_IDS, plan: plan3 };
11702
11744
 
11703
11745
  // src/adapters/fal-video-families.ts
11704
11746
  var FAMILIES2 = [
11705
11747
  klingV3Family,
11748
+ klingOmniFamily,
11706
11749
  minimaxH3MaxFamily,
11707
11750
  happyHorseFamily,
11708
11751
  viduFamily,
@@ -12179,7 +12222,7 @@ function extractVideoUrl(result, endpoint, model) {
12179
12222
  }
12180
12223
  async function generateFalVideo(req, ctx, deps) {
12181
12224
  const providerModelId = ctx.model.providerModelId;
12182
- const plan3 = planFalFamilyVideo(req, ctx);
12225
+ const plan4 = planFalFamilyVideo(req, ctx);
12183
12226
  const start = (endpoint2, input, usageOf2) => startFalVideoJob(
12184
12227
  ctx,
12185
12228
  () => falClientOf(ctx, deps),
@@ -12187,7 +12230,7 @@ async function generateFalVideo(req, ctx, deps) {
12187
12230
  input,
12188
12231
  videoFileDecoder(ctx, req, endpoint2, usageOf2)
12189
12232
  );
12190
- if (plan3 !== void 0) return start(plan3.endpoint, plan3.input, planUsage(ctx, plan3));
12233
+ if (plan4 !== void 0) return start(plan4.endpoint, plan4.input, planUsage(ctx, plan4));
12191
12234
  if (isKling(providerModelId)) return start(KLING_O1_ENDPOINT, klingO1Input(req));
12192
12235
  if (isWan(providerModelId)) {
12193
12236
  const { endpoint: endpoint2, input } = wanVideo(req, providerModelId.toLowerCase());
@@ -12237,9 +12280,9 @@ function videoFileDecoder(ctx, req, endpoint, usageOf2) {
12237
12280
  raw: payload
12238
12281
  });
12239
12282
  }
12240
- function planUsage(ctx, plan3) {
12283
+ function planUsage(ctx, plan4) {
12241
12284
  return (payload) => {
12242
- const seconds3 = plan3.seconds(payload);
12285
+ const seconds3 = plan4.seconds(payload);
12243
12286
  return {
12244
12287
  model: ctx.model.id,
12245
12288
  provider: "fal",
@@ -12247,7 +12290,7 @@ function planUsage(ctx, plan3) {
12247
12290
  unit: "seconds",
12248
12291
  quantity: seconds3,
12249
12292
  durationSeconds: seconds3,
12250
- ...plan3.resolution !== void 0 && { resolution: plan3.resolution }
12293
+ ...plan4.resolution !== void 0 && { resolution: plan4.resolution }
12251
12294
  };
12252
12295
  };
12253
12296
  }
@@ -16699,10 +16742,10 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
16699
16742
  warnings
16700
16743
  );
16701
16744
  if (aspectRatio !== void 0) merged.aspectRatio = aspectRatio;
16702
- fillReplicateKlingResolution(model, merged);
16745
+ fillKlingModeResolution(model, merged);
16703
16746
  const resolution = resolveVideoResolution(merged.resolution, model, onUnsupported, warnings);
16704
16747
  if (resolution !== void 0) merged.resolution = resolution;
16705
- if (isReplicateKling(model)) delete merged.mode;
16748
+ if (takesKlingMode(model)) delete merged.mode;
16706
16749
  const duration = resolveDuration(
16707
16750
  merged.durationSeconds,
16708
16751
  c.durations,