@koda-sl/baker-cli 0.185.2 → 0.186.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/README.md CHANGED
@@ -2890,7 +2890,7 @@ The generation lane. `baker images` **sources** what already exists; `baker stud
2890
2890
  | `baker studio skills` | Craft directions accepted by `generate --skill <id>` |
2891
2891
  | `baker studio improve <prompt>` | Sharpen a rough brief — the same rewrite the client's prompt-bar wand performs. Returns the rewrite and the original; generates nothing |
2892
2892
 
2893
- **Every per-model limit is enforced before anything is billed.** Prompt character caps (Kling 2,500 · Seedance 4,000 · Recraft 10,000 · gpt-image 32,000), reference-image counts (Recraft 1 · Gemini 14 · gpt-image 16 · Seedance 9 in reference mode), the uint32 seed range, RGB channel bounds, and `width:height` shapes are all checked against the chosen model up front — the request is refused with the number to fix rather than opening a batch that fails a take at a time. A knob the model does not have is refused too; only the *shape* snaps to the nearest it renders. `baker studio models` reads all of this from the same contract table the backend validates against, so it cannot drift.
2893
+ **Every per-model limit is enforced before anything is billed.** Prompt character caps (Kling 2,500 · Seedance 2.0 4,000 · Recraft 10,000 · gpt-image 32,000 · Seedance 2.5 uncapped), reference counts (Recraft 1 · Gemini 14 · gpt-image 16 · Seedance 2.0 9 · Seedance 2.5 30 images plus 10 source clips), the uint32 seed range, RGB channel bounds, and `width:height` shapes are all checked against the chosen model up front — the request is refused with the number to fix rather than opening a batch that fails a take at a time. A knob the model does not have is refused too; only the *shape* snaps to the nearest it renders. `baker studio models` reads all of this from the same contract table the backend validates against, so it cannot drift.
2894
2894
 
2895
2895
  Two of those checks run in the CLI itself, before the request is even sent. The **reference-image count** is one: `--reference` / `--image` accept file paths and URLs, which are uploaded to the media library first, so checking the count only at the backend means paying to ingest and describe every image in a set that was always going to be refused. The **first-frame rule** is the other — a clip started from one exact frame takes exactly one image whatever the model's reference slot allows, and reference mode is refused outright on Veo and Kling, which cannot read references at all.
2896
2896
 
@@ -2980,19 +2980,40 @@ baker studio animate "handheld drift right, steam rising from the cup" \
2980
2980
  baker studio animate "product rotates once on a turntable" --image j57abc…,j57def… --from references
2981
2981
  ```
2982
2982
 
2983
- The image fixes the look, so the prompt describes **movement**. Models: `bytedance/seedance-2.0` (default), `google/veo-3.1`, `google/veo-3.1-fast`, `kwaivgi/kling-v3.0-pro`.
2983
+ The image fixes the look, so the prompt describes **movement**. Models: `google/gemini-omni-flash` (default), `bytedance/seedance-2.0`, `bytedance/seedance-2.5`, `google/veo-3.1`, `google/veo-3.1-fast`, `kwaivgi/kling-v3.0-pro`.
2984
+
2985
+ **`bytedance/seedance-2.5` is the long-form, multimodal tier**, and the only model that does either of the two things below. Reach for it when the beat cannot be five seconds, or when the source is footage rather than a still.
2986
+
2987
+ ```bash
2988
+ baker studio animate "she keeps walking, camera stays with her, then she stops and looks up" \
2989
+ --image j57abc… --from references --from-clip j57batch…:0 \
2990
+ --model bytedance/seedance-2.5 --duration 20
2991
+ ```
2992
+
2993
+ - **4–30 seconds** in one render; everything else in the roster stops at 15, and Veo at 8.
2994
+ - **`--from-clip batchId:slot`** builds on takes already rendered, and **`--from-video <videoId>`** on anything in the video library (client footage, synced ads). Together up to 10 — this is how a clip is extended, edited, or has its motion carried into a new shot. Both need `--from references`. A library video's first use spends ~1 minute encoding a reusable copy and is refused with "try again shortly"; every use after is instant.
2995
+ - **No soundtrack input.** The model reads MP3/WAV reference audio; the only audio Baker stores is Mux's M4A, which it refuses. Nothing to pass it today.
2996
+ - **The output shape follows the source clip** — `--aspect-ratio` does not apply when building on one, and building on one **costs about double** the per-second rate (measured; the estimate accounts for it).
2997
+ - **`--from text`** renders with no image at all. Every model does text-to-video; this is the only mode where `--image` may be omitted.
2998
+ - **Up to 30 reference images**, against 9 on Seedance 2.0.
2999
+ - **480p / 720p only** — 1080p and 4K are real Seedance tiers but not on this route.
3000
+ - **Sound costs nothing extra** here, unlike every other model that offers it.
3001
+ - **No watermark** unless `--watermark` asks for one; it cannot be removed after the render.
3002
+ - **No people from an uploaded picture.** A privacy pre-check refuses any recognisable face in the input image — invented characters included, and images from ByteDance's own image model included. Clips that hit it are re-rendered automatically on Gemini Omni (reference mode) or Veo (frame mode).
2984
3003
 
2985
3004
  | Flag | Description |
2986
3005
  |---|---|
2987
- | `--image` | **Required.** Comma-separated library image ids / local paths / image URLs; the first is the opening frame |
2988
- | `--from` | `frame` (default — animate the first image) \| `references` (use the images as visual reference). Mutually exclusive at every provider |
2989
- | `--model` | Video model id (default `bytedance/seedance-2.0`) |
3006
+ | `--image` | Comma-separated library image ids / local paths / image URLs; the first is the opening frame. **Required unless `--from text`** |
3007
+ | `--from` | `frame` (default — animate the first image) \| `references` (use the assets as visual guidance) \| `text` (no image; render the prompt). The first two are mutually exclusive at every provider |
3008
+ | `--from-clip` | Studio takes to build on, `batchId:slot` comma-separated (Seedance 2.5, needs `--from references`) |
3009
+ | `--from-video` | Library video ids to build on — same 10-clip budget as `--from-clip` |
3010
+ | `--model` | Video model id (default `google/gemini-omni-flash`) |
2990
3011
  | `--aspect-ratio` | Default `9:16` |
2991
3012
  | `--duration` | Seconds; per-model set (default 5, snapped onto what the model renders) |
2992
3013
  | `--quality` | Resolution, e.g. `720p` (default) \| `1080p` |
2993
3014
  | `--count` | Takes, 1–3 (default 1). A clip costs ~45x an image |
2994
3015
  | `--sound` | Let the model generate audio. Off by default (billed on top) |
2995
- | `--negative` / `--seed` / `--people` / `--enhance-prompt` / `--conditioning-scale` / `--cfg-scale` | Per-model knobs; refused when the chosen model doesn't advertise them |
3016
+ | `--negative` / `--seed` / `--people` / `--enhance-prompt` / `--conditioning-scale` / `--cfg-scale` / `--watermark` | Per-model knobs; refused when the chosen model doesn't advertise them |
2996
3017
  | `--wait` / `--max-wait` | Wait for the takes (default on, 600000 ms) |
2997
3018
  | `--full` | Include settings, references, chat attribution, `createdAt` |
2998
3019
 
@@ -1124,7 +1124,8 @@ var GPT_IMAGE_PROMPT_MAX = 32e3;
1124
1124
  var RECRAFT_PROMPT_MAX = 1e4;
1125
1125
  var SEEDANCE_PROMPT_MAX = 4e3;
1126
1126
  var KLING_PROMPT_MAX = 2500;
1127
- var VEO_SEED_MAX = 4294967295;
1127
+ var UINT32_MAX = 4294967295;
1128
+ var VEO_SEED_MAX = UINT32_MAX;
1128
1129
  var GPT_IMAGE_MAX_REFERENCES = 16;
1129
1130
  var GEMINI_IMAGE_MAX_REFERENCES = 14;
1130
1131
  var RECRAFT_MAX_REFERENCES = 1;
@@ -1136,9 +1137,42 @@ var GEMINI_LITE_IMAGE_SIZE = ["1K"];
1136
1137
  var OPENROUTER_IMAGE_QUALITY = ["auto", "low", "medium", "high"];
1137
1138
  var RECRAFT_IMAGE_AR = ["1:1", "4:3", "3:4", "16:9", "9:16"];
1138
1139
  var SEEDANCE_DURATIONS = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1140
+ var SEEDANCE_25_DURATIONS = [
1141
+ 4,
1142
+ 5,
1143
+ 6,
1144
+ 7,
1145
+ 8,
1146
+ 9,
1147
+ 10,
1148
+ 11,
1149
+ 12,
1150
+ 13,
1151
+ 14,
1152
+ 15,
1153
+ 16,
1154
+ 17,
1155
+ 18,
1156
+ 19,
1157
+ 20,
1158
+ 21,
1159
+ 22,
1160
+ 23,
1161
+ 24,
1162
+ 25,
1163
+ 26,
1164
+ 27,
1165
+ 28,
1166
+ 29,
1167
+ 30
1168
+ ];
1169
+ var SEEDANCE_25_ASPECT_RATIOS = ["1:1", "3:4", "9:16", "4:3", "16:9", "21:9"];
1170
+ var SEEDANCE_25_RESOLUTIONS = ["480p", "720p"];
1171
+ var SEEDANCE_25_MAX_IMAGE_REFERENCES = 30;
1172
+ var SEEDANCE_25_MAX_VIDEO_REFERENCES = 10;
1173
+ var SEEDANCE_25_MAX_AUDIO_REFERENCES = 10;
1139
1174
  var KLING_DURATIONS = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1140
1175
  var GEMINI_OMNI_DURATIONS = [3, 4, 5, 6, 7, 8, 9, 10];
1141
- var GEMINI_OMNI_DEFAULT_SECONDS = 10;
1142
1176
  var GEMINI_OMNI_ASPECT_RATIOS = ["16:9", "9:16"];
1143
1177
  var GEMINI_OMNI_IMAGE_MIMES = ["image/png", "image/jpeg", "image/webp"];
1144
1178
  var ELEVENLABS_OUTPUT_FORMATS = [
@@ -1152,6 +1186,8 @@ var ELEVENLABS_OUTPUT_FORMATS = [
1152
1186
  var ELEVENLABS_MAX_TEXT_CHARS = 45454;
1153
1187
  var ELEVENLABS_MAX_MUSIC_LENGTH_MS = 454545;
1154
1188
  var OPENROUTER_IMAGE_MIMES = ["image/png", "image/jpeg", "image/webp", "image/gif"];
1189
+ var OPENROUTER_VIDEO_REFERENCE_MIMES = ["video/mp4", "video/quicktime", "video/webm"];
1190
+ var OPENROUTER_AUDIO_REFERENCE_MIMES = ["audio/mpeg", "audio/mp3", "audio/wav"];
1155
1191
  var REPLICATE_IMAGE_MIMES = ["image/png", "image/jpeg", "image/webp"];
1156
1192
  var REPLICATE_VIDEO_MIMES = ["video/mp4", "video/webm", "video/quicktime"];
1157
1193
  var DECONSTRUCT_VIDEO_MIMES = ["video/mp4", "video/webm", "video/quicktime"];
@@ -1167,21 +1203,30 @@ var IMAGE_GENERATE_MODELS = [
1167
1203
  var DEFAULT_IMAGE_GENERATE_MODEL = "google/gemini-3.1-flash-image-preview";
1168
1204
  var VIDEO_GENERATE_MODELS = [
1169
1205
  "bytedance/seedance-2.0",
1206
+ "bytedance/seedance-2.5",
1170
1207
  "google/gemini-omni-flash",
1171
1208
  "google/veo-3.1",
1172
1209
  "google/veo-3.1-fast",
1173
1210
  "kwaivgi/kling-v3.0-pro"
1174
1211
  ];
1175
1212
  var DEFAULT_VIDEO_GENERATE_MODEL = "google/gemini-omni-flash";
1176
- var REFERENCE_TO_VIDEO_MODELS = ["bytedance/seedance-2.0", "google/gemini-omni-flash"];
1213
+ var REFERENCE_TO_VIDEO_MODELS = [
1214
+ "bytedance/seedance-2.0",
1215
+ "bytedance/seedance-2.5",
1216
+ "google/gemini-omni-flash"
1217
+ ];
1177
1218
  function supportsReferenceToVideo(model) {
1178
1219
  return REFERENCE_TO_VIDEO_MODELS.includes(model);
1179
1220
  }
1180
1221
  function isGeminiOmniModel(model) {
1181
1222
  return model.startsWith("google/gemini-omni");
1182
1223
  }
1224
+ function isSeedance25Model(model) {
1225
+ return model === "bytedance/seedance-2.5";
1226
+ }
1183
1227
  var LAST_FRAME_TO_VIDEO_MODELS = [
1184
1228
  "bytedance/seedance-2.0",
1229
+ "bytedance/seedance-2.5",
1185
1230
  "google/veo-3.1",
1186
1231
  "google/veo-3.1-fast",
1187
1232
  "kwaivgi/kling-v3.0-pro"
@@ -1488,6 +1533,49 @@ var MODEL_REGISTRY = {
1488
1533
  generate_audio: { kind: "boolean" }
1489
1534
  }
1490
1535
  },
1536
+ "bytedance/seedance-2.5": {
1537
+ // Seedance 2.5 — the LONG-FORM, MULTIMODAL tier, and the only curated video
1538
+ // model reached through OpenRouter that is not frame-only.
1539
+ //
1540
+ // Routed through OpenRouter's video gateway (provider `seed`), NOT through
1541
+ // Replicate like 2.0 — the gateway carries the multimodal reference surface
1542
+ // 2.5 exists for, and Replicate's 2.0 wrapper only has `reference_images`.
1543
+ // The backend branches on the exact 2.0 id for the Replicate path, so this
1544
+ // model must never be folded into a `startsWith("bytedance/seedance")`
1545
+ // routing test: that is one character away from sending 2.5 to a wrapper
1546
+ // that cannot express half of what it is being asked to do.
1547
+ //
1548
+ // Same upstream likeness filter as 2.0 — ByteDance classifies PIXELS, so an
1549
+ // AI-generated face that reads photographic is refused exactly like a
1550
+ // photograph (content_policy_blocked). The workflow's automatic Veo recovery
1551
+ // therefore covers this model too.
1552
+ //
1553
+ // No published prompt cap on this route, so none is invented: OpenRouter's
1554
+ // request schema declares no `maxLength` and the model is sold on long,
1555
+ // multi-shot briefs. A ceiling we made up would refuse the exact prompts
1556
+ // this tier exists to render.
1557
+ label: "ByteDance Seedance 2.5",
1558
+ inputs: [],
1559
+ optional_inputs: [
1560
+ { kind: "image", mimes: OPENROUTER_IMAGE_MIMES, max: SEEDANCE_25_MAX_IMAGE_REFERENCES },
1561
+ { kind: "video", mimes: OPENROUTER_VIDEO_REFERENCE_MIMES, max: SEEDANCE_25_MAX_VIDEO_REFERENCES },
1562
+ { kind: "audio", mimes: OPENROUTER_AUDIO_REFERENCE_MIMES, max: SEEDANCE_25_MAX_AUDIO_REFERENCES }
1563
+ ],
1564
+ required: ["prompt"],
1565
+ params: {
1566
+ prompt: { kind: "string" },
1567
+ aspect_ratio: { kind: "string", enum: SEEDANCE_25_ASPECT_RATIOS },
1568
+ resolution: { kind: "string", enum: SEEDANCE_25_RESOLUTIONS },
1569
+ duration: { kind: "number", enum: SEEDANCE_25_DURATIONS },
1570
+ seed: { kind: "number", integer: true, min: 0, max: UINT32_MAX },
1571
+ generate_audio: { kind: "boolean" },
1572
+ // A visible AI watermark on an ad creative is a defect, and this is the
1573
+ // only curated model that lets us turn one off: `watermark` is named in
1574
+ // the model's own `allowed_passthrough_parameters`, so it rides as a
1575
+ // top-level body field exactly like Kling's `cfg_scale` does.
1576
+ watermark: { kind: "boolean" }
1577
+ }
1578
+ },
1491
1579
  "google/gemini-omni-flash": {
1492
1580
  // Google Gemini Omni Flash — the DEFAULT video model. Natively multimodal:
1493
1581
  // it reasons over text + images and renders video WITH synchronized audio in
@@ -1763,10 +1851,15 @@ function promptMaxLength(kind, model) {
1763
1851
  const schema = MODEL_REGISTRY[kind]?.[model]?.params.prompt;
1764
1852
  return schema?.kind === "string" ? schema.maxLength : void 0;
1765
1853
  }
1766
- function maxInputReferences(kind, model) {
1854
+ function inputSlot(kind, model, inputKind) {
1767
1855
  const spec = MODEL_REGISTRY[kind]?.[model];
1768
- const slot = spec?.optional_inputs?.find((input) => input.kind === "image") ?? spec?.inputs.find((input) => input.kind === "image");
1769
- return slot?.max;
1856
+ return spec?.optional_inputs?.find((input) => input.kind === inputKind) ?? spec?.inputs.find((input) => input.kind === inputKind);
1857
+ }
1858
+ function maxInputSlot(kind, model, inputKind) {
1859
+ return inputSlot(kind, model, inputKind)?.max;
1860
+ }
1861
+ function maxInputReferences(kind, model) {
1862
+ return maxInputSlot(kind, model, "image");
1770
1863
  }
1771
1864
  function supportedAspectRatios(kind, model) {
1772
1865
  const schema = MODEL_REGISTRY[kind]?.[model]?.params.aspect_ratio;
@@ -1956,6 +2049,14 @@ var DEFAULT_VIDEO_DURATION_S = 5;
1956
2049
  function isSeedanceModel(model) {
1957
2050
  return model.startsWith("bytedance/seedance");
1958
2051
  }
2052
+ var SEEDANCE_25_USD_PER_SECOND = {
2053
+ "480p": 0.1075,
2054
+ "720p": 0.2326
2055
+ };
2056
+ var SEEDANCE_25_FALLBACK_USD_PER_SECOND = 0.2326;
2057
+ function seedance25UsdPerSecond(resolution) {
2058
+ return SEEDANCE_25_USD_PER_SECOND[resolution ?? DEFAULT_VIDEO_RESOLUTION] ?? SEEDANCE_25_FALLBACK_USD_PER_SECOND;
2059
+ }
1959
2060
  var FALLBACK_USD_PER_SECOND = 0.5;
1960
2061
  function seedanceUsdPerSecond(resolution) {
1961
2062
  return SEEDANCE_USD_PER_SECOND[resolution ?? DEFAULT_VIDEO_RESOLUTION] ?? FALLBACK_USD_PER_SECOND;
@@ -1981,11 +2082,33 @@ var USD_PER_SECOND = {
1981
2082
  };
1982
2083
  var GEMINI_OMNI_USD_PER_1M_VIDEO_TOKENS = 17.5;
1983
2084
  var GEMINI_OMNI_VIDEO_TOKENS_PER_SECOND = 5792;
2085
+ var GEMINI_OMNI_WINDOW_SECONDS = 10;
2086
+ var GEMINI_OMNI_WINDOW_MARGIN = 1.05;
1984
2087
  var GEMINI_OMNI_USD_PER_SECOND = GEMINI_OMNI_VIDEO_TOKENS_PER_SECOND * GEMINI_OMNI_USD_PER_1M_VIDEO_TOKENS / 1e6;
1985
- function estimateVideoCostUsd({ model, duration, resolution, generateAudio }) {
2088
+ var VIDEO_SOURCE_COST_MULTIPLIER = 2.5;
2089
+ var FAL_SEEDANCE_USD_PER_1K_TOKENS = 0.0214;
2090
+ var SEEDANCE_SOURCE_CLIP_DISCOUNT = 0.6;
2091
+ var SEEDANCE_DEAREST_FRAME = {
2092
+ "480p": { width: 992, height: 432 },
2093
+ "720p": { width: 1112, height: 834 }
2094
+ };
2095
+ function falSeedanceUsdPerSecond(resolution, buildsOnSourceClip = false) {
2096
+ const frame = SEEDANCE_DEAREST_FRAME[resolution ?? DEFAULT_VIDEO_RESOLUTION] ?? SEEDANCE_DEAREST_FRAME["720p"];
2097
+ const tokensPerSecond = (frame?.width ?? 1112) * (frame?.height ?? 834) * 24 / 1024;
2098
+ const rate = tokensPerSecond * FAL_SEEDANCE_USD_PER_1K_TOKENS / 1e3;
2099
+ return buildsOnSourceClip ? rate * SEEDANCE_SOURCE_CLIP_DISCOUNT : rate;
2100
+ }
2101
+ function estimateVideoCostUsd(input) {
2102
+ const { model, duration, resolution, generateAudio, buildsOnSourceClip } = input;
1986
2103
  const seconds = duration ?? DEFAULT_VIDEO_DURATION_S;
2104
+ const sourceClipPremium = buildsOnSourceClip ? VIDEO_SOURCE_COST_MULTIPLIER : 1;
1987
2105
  if (isGeminiOmniModel(model)) {
1988
- return (duration ?? GEMINI_OMNI_DEFAULT_SECONDS) * GEMINI_OMNI_USD_PER_SECOND;
2106
+ return GEMINI_OMNI_WINDOW_SECONDS * GEMINI_OMNI_USD_PER_SECOND * GEMINI_OMNI_WINDOW_MARGIN;
2107
+ }
2108
+ if (isSeedance25Model(model)) {
2109
+ const viaOpenRouter = seedance25UsdPerSecond(resolution) * seconds * sourceClipPremium;
2110
+ if (!input.mayRouteToFal) return viaOpenRouter;
2111
+ return Math.max(viaOpenRouter, falSeedanceUsdPerSecond(resolution, buildsOnSourceClip) * seconds);
1989
2112
  }
1990
2113
  if (isSeedanceModel(model)) return seedanceUsdPerSecond(resolution) * seconds;
1991
2114
  const published = USD_PER_SECOND[model];
@@ -8214,6 +8337,7 @@ export {
8214
8337
  DEFAULT_CLIP_DURATION_S,
8215
8338
  nearestClipDuration,
8216
8339
  promptMaxLength,
8340
+ maxInputSlot,
8217
8341
  maxInputReferences,
8218
8342
  nearestSupportedAspectRatio,
8219
8343
  nearestSupportedImageSize,
@@ -8244,4 +8368,4 @@ export {
8244
8368
  defaultRegistry,
8245
8369
  createEngineFromEnv
8246
8370
  };
8247
- //# sourceMappingURL=chunk-3TXZKSAR.js.map
8371
+ //# sourceMappingURL=chunk-OWDTSPY4.js.map