@shop-os/modelkit 0.7.10 → 0.8.0

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/CHANGELOG.md CHANGED
@@ -9,6 +9,24 @@ header in the release PR.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.8.0] - Unreleased
13
+
14
+ The BytePlus ModelArk key has one env name.
15
+
16
+ ### Removed
17
+ - `keysFromEnv` reads the `ark` key from `BYTEDANCE_API_KEY` only (with the `ENTERPRISE_` / `SLOOSH_` prefixes); the two older alias names are no longer read. An env that sets only an alias gets no `ark` key, so an Ark call fails with a `ModelKitError` code `auth`. Set `BYTEDANCE_API_KEY` before a consumer upgrades.
18
+
19
+ ## [0.7.11] - Unreleased
20
+
21
+ Kling 4.0 on fal.
22
+
23
+ ### Added
24
+ - `kling-4.0` (fal `kling/v4`): one row for text-, image- and reference-to-video. Reference images or videos go to `kling/v4/reference-to-video` (`image_urls`, `video_urls`, and a start frame as `start_image_url`), else a start frame to `image-to-video` (with an optional end frame), else `text-to-video`. 720p / 1080p, 3-30 s (whole seconds), aspect ratios `adaptive` (fal's `auto` on reference-to-video), 16:9, 9:16, 1:1, 21:9. References: 10 images (the start frame counts toward them) and 5 videos, each 3-30.05 s and 30 s combined. An end frame with references, more than 10 images with the start frame, and a blank prompt are refused before the call.
25
+ - `kling-4.0-edit` (fal `kling/v4/video-to-video/edit`): a 3-30.05 s source plus up to 10 reference images, 720p / 1080p. `durationSeconds` 3-30 sets the output length; left out, the output (and its usage) is the source's length.
26
+ - Prompts name inputs `@Image1`, `@Video1` (no space); on an edit the source is `@Video1`. Kit requests send no Kling elements.
27
+ - Neither endpoint has a sound field, so both rows declare `audio: "always"` and drop `generateAudio` with an `option_ignored` warning.
28
+ - Usage reports the output seconds and resolution. fal bills a request with reference videos, and every edit, on input plus output seconds (at least twice the output) at a lower rate; pricing that is the consumer's job (pro-backend's video-input rate).
29
+
12
30
  ## [0.7.10] - Unreleased
13
31
 
14
32
  Kling V3 Omni moves from Replicate to fal at half the provider cost.
package/README.md CHANGED
@@ -108,7 +108,7 @@ before submit), and `model3dPricingSku(row, options, inputs)` names the flat pri
108
108
  bills under; `model3dSkus(row)` lists them all, and pro-backend keeps a `credit_pricing_flat`
109
109
  row for each. All three are in the browser-safe catalog entry.
110
110
 
111
- Keys come from `process.env` by default: bare names for pro (`OPENAI_API_KEY`, `FAL_KEY`, `ARK_API_KEY`, `LUMA_API_KEY` ...), the `ENTERPRISE_` prefix for enterprise and the `SLOOSH_` prefix for sloosh (sloosh reads `SLOOSH_LUMA_API_KEY` for Luma). Pass `keys: { pro, enterprise, sloosh }` to override. `tier: "sloosh"` uses the sloosh keys only: a missing key is a `ModelKitError` with code `auth`, never a fallback to pro.
111
+ Keys come from `process.env` by default: bare names for pro (`OPENAI_API_KEY`, `FAL_KEY`, `BYTEDANCE_API_KEY`, `LUMA_API_KEY` ...), the `ENTERPRISE_` prefix for enterprise and the `SLOOSH_` prefix for sloosh (sloosh reads `SLOOSH_LUMA_API_KEY` for Luma). Pass `keys: { pro, enterprise, sloosh }` to override. `tier: "sloosh"` uses the sloosh keys only: a missing key is a `ModelKitError` with code `auth`, never a fallback to pro.
112
112
 
113
113
  ## Browser-safe catalog
114
114
 
package/dist/catalog.cjs CHANGED
@@ -4778,6 +4778,8 @@ function range(min, max) {
4778
4778
  }
4779
4779
  var KLING_PROMPT = { referenceSyntax: "numbered", maxChars: 2500 };
4780
4780
  var H3_PROMPT = { referenceSyntax: "numbered", maxChars: 5e4 };
4781
+ var KLING_V4_PROMPT = { referenceSyntax: "numbered", maxChars: 2500 };
4782
+ var KLING_V4_AUDIO = "always";
4781
4783
  var NO_REFERENCES = { images: 0, videos: 0, audios: 0 };
4782
4784
  function klingMotionControl(tier) {
4783
4785
  const label = tier === "pro" ? "Pro" : "Standard";
@@ -4878,6 +4880,79 @@ var VIDEO_FAMILY_MODELS = [
4878
4880
  },
4879
4881
  capabilities: { acceptsSourceVideo: true, videoEdit: true }
4880
4882
  },
4883
+ {
4884
+ // https://fal.ai/models/kling/v4/reference-to-video/api (+ /text-to-video,
4885
+ // /image-to-video): one row; references (images or videos) go to reference-to-video,
4886
+ // else a start frame to image-to-video, else text-to-video. Reference images: 10, the
4887
+ // start frame included (fal: "counts toward the image reference limit"), 300 px min.
4888
+ // Reference videos: 5, 3-30.05 s each and 30 s combined, 700 px min, 23.9-60.05 fps.
4889
+ // The prompt names references as @Image1, @Video1 (no space; @Element1 for elements,
4890
+ // which the kit does not send). No sound switch on any endpoint.
4891
+ id: "kling-4.0",
4892
+ aliases: ["kling-4", "kling-v4"],
4893
+ label: "Kling 4.0",
4894
+ type: "video",
4895
+ adapter: "fal",
4896
+ providerModelId: "kling/v4",
4897
+ lifecycle: "active",
4898
+ exposure: ["cowork", "space_builder"],
4899
+ constraints: {
4900
+ aspectRatios: ["adaptive", "16:9", "9:16", "1:1", "21:9"],
4901
+ resolutions: ["720p", "1080p"],
4902
+ durations: { min: 3, max: 30 },
4903
+ durationPresets: [5, 10, 15, 30],
4904
+ references: {
4905
+ ...NO_REFERENCES,
4906
+ images: 10,
4907
+ videos: 5,
4908
+ videoSeconds: { min: 3, max: 30.05, total: 30 }
4909
+ },
4910
+ supports: ["lastFrame"],
4911
+ prompt: KLING_V4_PROMPT,
4912
+ audio: KLING_V4_AUDIO
4913
+ },
4914
+ defaults: { durationSeconds: 5, resolution: "1080p", aspectRatio: "16:9" },
4915
+ usage: { ...VIDEO_USAGE },
4916
+ pricingKind: "video_per_second",
4917
+ display: {
4918
+ provider: "kuaishou",
4919
+ logo: KLING_LOGO,
4920
+ description: "Kuaishou Kling 4.0: text-to-video, start/end frames, or reference-to-video from up to 10 images and 5 videos (30 seconds combined), 3-30 seconds at 720p or 1080p. Prompts name references @Image1, @Video1."
4921
+ },
4922
+ capabilities: { lastFrameRequiresFirstFrame: true }
4923
+ },
4924
+ {
4925
+ // https://fal.ai/models/kling/v4/video-to-video/edit/api: source 3-30.05 s (700 px
4926
+ // min, 23.9-60.05 fps), up to 10 reference images. duration 3-30, or left out for the
4927
+ // source's length. The prompt names the source @Video1 and images @Image1, @Image2.
4928
+ id: "kling-4.0-edit",
4929
+ aliases: ["kling-4-edit", "kling-v4-edit"],
4930
+ label: "Kling 4.0 Edit",
4931
+ type: "video",
4932
+ adapter: "fal",
4933
+ providerModelId: "kling/v4/video-to-video/edit",
4934
+ lifecycle: "active",
4935
+ exposure: ["cowork", "space_builder"],
4936
+ constraints: {
4937
+ resolutions: ["720p", "1080p"],
4938
+ durations: { min: 3, max: 30 },
4939
+ references: { ...NO_REFERENCES, images: 10 },
4940
+ requires: ["sourceVideo"],
4941
+ sourceVideoSeconds: { min: 3, max: 30.05 },
4942
+ supports: [],
4943
+ prompt: KLING_V4_PROMPT,
4944
+ audio: KLING_V4_AUDIO
4945
+ },
4946
+ defaults: { resolution: "1080p" },
4947
+ usage: { ...VIDEO_USAGE },
4948
+ pricingKind: "video_per_second",
4949
+ display: {
4950
+ provider: "kuaishou",
4951
+ logo: KLING_LOGO,
4952
+ description: "Kuaishou Kling 4.0 video edit: change a 3-30 second clip with a prompt and up to 10 reference images, at 720p or 1080p, as long as the source or a set 3-30 seconds. Prompts name the source @Video1 and images @Image1."
4953
+ },
4954
+ capabilities: { acceptsSourceVideo: true, videoEdit: true }
4955
+ },
4881
4956
  {
4882
4957
  // https://fal.ai/models/minimax/h3-max-turbo/text-to-video/api (+ /image-to-video).
4883
4958
  // image-to-video takes a start frame, an end frame, or both, and no aspect_ratio.
@@ -8532,6 +8607,8 @@ var MOTION_PRO = "fal-ai/kling-video/v3/pro/motion-control";
8532
8607
  var MOTION_STANDARD = "fal-ai/kling-video/v3/standard/motion-control";
8533
8608
  var O3_REFERENCE = "fal-ai/kling-video/o3/pro/reference-to-video";
8534
8609
  var O3_EDIT = "fal-ai/kling-video/o3/pro/video-to-video/edit";
8610
+ var KLING_V4 = "kling/v4";
8611
+ var KLING_V4_EDIT = "kling/v4/video-to-video/edit";
8535
8612
  var H3_TURBO = "minimax/h3-max-turbo";
8536
8613
  var H3_RECAST = "minimax/h3-max/recast";
8537
8614
  var H3_RELIGHT = "minimax/h3-max/relight";
@@ -8540,6 +8617,7 @@ var HAPPY_HORSE_EDIT = "alibaba/happy-horse/video-edit";
8540
8617
  var VIDU_Q4 = "fal-ai/vidu/q4";
8541
8618
  var OMNIHUMAN_V2 = "bytedance/omnihuman/v2";
8542
8619
  var KLING_O3_IMAGE_CAP = 7;
8620
+ var KLING_V4_IMAGE_CAP = 10;
8543
8621
  var TURBO_AUDIO_MIN_SECONDS = 2;
8544
8622
  var OMNIHUMAN_AUDIO_SECONDS = { min: 4, max: 300 };
8545
8623
  function missing(message) {
@@ -8595,6 +8673,23 @@ function o3Reference(req) {
8595
8673
  }
8596
8674
  return needsPrompt(req);
8597
8675
  }
8676
+ function hasReferences(req) {
8677
+ return count(req.referenceImages) + count(req.referenceVideos) > 0;
8678
+ }
8679
+ function klingV4(req) {
8680
+ if (hasReferences(req)) {
8681
+ if (req.lastFrame !== void 0) {
8682
+ return unsupported2("takes an end frame only without reference images or videos");
8683
+ }
8684
+ const images = count(req.referenceImages) + (req.firstFrame === void 0 ? 0 : 1);
8685
+ if (images > KLING_V4_IMAGE_CAP) {
8686
+ return unsupported2(
8687
+ `takes up to ${KLING_V4_IMAGE_CAP} images in all, the start frame included; this request has ${images}`
8688
+ );
8689
+ }
8690
+ }
8691
+ return needsPrompt(req);
8692
+ }
8598
8693
  function h3Turbo(req) {
8599
8694
  if (count(req.referenceImages) + count(req.referenceVideos) > 0) {
8600
8695
  return unsupported2("takes no reference images or videos");
@@ -8673,6 +8768,8 @@ var RULES = /* @__PURE__ */ new Map([
8673
8768
  [O3_REFERENCE, o3Reference],
8674
8769
  [KLING_O3_OMNI, o3Reference],
8675
8770
  [O3_EDIT, (req) => needsSource(req) ?? needsPrompt(req)],
8771
+ [KLING_V4, klingV4],
8772
+ [KLING_V4_EDIT, (req) => needsSource(req) ?? needsPrompt(req)],
8676
8773
  [H3_TURBO, h3Turbo],
8677
8774
  [MINIMAX_H3_INSERT, h3Insert],
8678
8775
  [H3_RECAST, h3Recast],
@@ -8722,6 +8819,19 @@ function applyFalVideoRules(model, req, callerRatio, warnings) {
8722
8819
  warnings.push(viduSilentWarning(model));
8723
8820
  req.generateAudio = false;
8724
8821
  }
8822
+ if (id === KLING_V4 && req.firstFrame !== void 0 && !hasReferences(req)) {
8823
+ if (req.aspectRatio !== void 0) {
8824
+ if (callerRatio !== void 0) {
8825
+ warnings.push({
8826
+ code: "ratio_dropped",
8827
+ field: "aspectRatio",
8828
+ from: req.aspectRatio,
8829
+ message: `${model.id} follows the start frame's aspect ratio`
8830
+ });
8831
+ }
8832
+ delete req.aspectRatio;
8833
+ }
8834
+ }
8725
8835
  const endFrameOnly = req.lastFrame !== void 0 && req.firstFrame === void 0;
8726
8836
  if (id === H3_TURBO && endFrameOnly && req.aspectRatio !== void 0) {
8727
8837
  if (callerRatio !== void 0 && callerRatio !== "adaptive") {