@koda-sl/baker-cli 0.306.6-dev.368ebfa99 → 0.306.7
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 +2 -0
- package/dist/{chunk-PY7R67NE.js → chunk-WONWYE7B.js} +4 -4
- package/dist/chunk-WONWYE7B.js.map +1 -0
- package/dist/cli.js +62 -25
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-PY7R67NE.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
validateCanvasDeep,
|
|
68
68
|
withoutCastName,
|
|
69
69
|
ytDlpBlockSignal
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-WONWYE7B.js";
|
|
71
71
|
import {
|
|
72
72
|
csvOrJson,
|
|
73
73
|
daysAgoIso,
|
|
@@ -58456,6 +58456,43 @@ import { defineCommand as defineCommand209 } from "citty";
|
|
|
58456
58456
|
// src/commands/studio/animate.ts
|
|
58457
58457
|
import { defineCommand as defineCommand201 } from "citty";
|
|
58458
58458
|
|
|
58459
|
+
// src/commands/studio/spokenPace.ts
|
|
58460
|
+
var WORDS_PER_SECOND3 = SPOKEN_WORDS_PER_SECOND;
|
|
58461
|
+
var spokenWords = spokenWordsIn;
|
|
58462
|
+
function wordsThatFit(seconds) {
|
|
58463
|
+
return Math.floor(seconds * WORDS_PER_SECOND3);
|
|
58464
|
+
}
|
|
58465
|
+
function spokenPaceHint(prompt, seconds, model) {
|
|
58466
|
+
const words2 = spokenWords(prompt);
|
|
58467
|
+
if (words2 === 0) return null;
|
|
58468
|
+
const split = model ? splitScriptFor(words2, model) : null;
|
|
58469
|
+
if (split) {
|
|
58470
|
+
return `The line is ${words2} words \u2014 about ${Math.ceil(words2 / WORDS_PER_SECOND3)}s of speech \u2014 and ${model} renders at most ${split.maxSeconds}s (~${Math.floor(split.maxSeconds * WORDS_PER_SECOND3)} words). It will not refuse and it will not cut: it will RUSH, swallowing syllables. Split the script into ${split.clips} takes of roughly ${split.wordsPerClip} words each, rendered separately and cut together \u2014 break it where the thought breaks, not mid-sentence. Or move to a model that renders longer (bytedance/seedance-2.5 goes to 30s).`;
|
|
58471
|
+
}
|
|
58472
|
+
if (!seconds) return null;
|
|
58473
|
+
const fits = wordsThatFit(seconds);
|
|
58474
|
+
if (words2 <= fits) return null;
|
|
58475
|
+
const rate = (words2 / seconds).toFixed(1);
|
|
58476
|
+
return `The line is ${words2} words and this clip is ${seconds}s \u2014 that is ${rate} words a second against a natural ${WORDS_PER_SECOND3}. The model will not run over, it will RUSH: syllables swallowed, endings clipped, and the take unusable however good the picture. Cut the line to about ${fits} words, or give it the length it needs (${Math.ceil(words2 / WORDS_PER_SECOND3)}s). Do not re-render the same line at the same length and hope.`;
|
|
58477
|
+
}
|
|
58478
|
+
|
|
58479
|
+
// src/commands/studio/adByHand.ts
|
|
58480
|
+
function priorScriptedTakes(batches) {
|
|
58481
|
+
return batches.filter(
|
|
58482
|
+
(batch) => batch.kind === "video" && spokenWords(batch.prompt) > 0 && batch.variants.some((variant) => variant.status !== "failed")
|
|
58483
|
+
).length;
|
|
58484
|
+
}
|
|
58485
|
+
function ordinal(n) {
|
|
58486
|
+
const suffix = n % 100 >= 11 && n % 100 <= 13 ? "th" : ["th", "st", "nd", "rd"][n % 10] ?? "th";
|
|
58487
|
+
return `${n}${suffix}`;
|
|
58488
|
+
}
|
|
58489
|
+
function adByHandHint(input) {
|
|
58490
|
+
if (!input.thisTakeIsScripted || input.buildsOnAClip) return null;
|
|
58491
|
+
if (input.priorScriptedTakes < 1) return null;
|
|
58492
|
+
const which = ordinal(input.priorScriptedTakes + 1);
|
|
58493
|
+
return `This is the ${which} clip with a scripted line in this conversation. Separate takes stay separate \u2014 nothing cuts them together, the audio stops and restarts at every join, and there are no captions and no closing card \u2014 so ${input.priorScriptedTakes + 1} takes of a presenter are ${input.priorScriptedTakes + 1} clips and never one ad. If these are the beats of one ad, stop rendering them one at a time: write them as beats (one line the voice says plus one shot on screen while it is said) and \`baker canvas scaffold-ad\` emits the whole ad \u2014 one canvas, one render, continuous read, synced captions and a brand end card. If they really are consecutive parts of ONE long read you will cut together yourself, carry on.`;
|
|
58494
|
+
}
|
|
58495
|
+
|
|
58459
58496
|
// src/commands/studio/batch.ts
|
|
58460
58497
|
function projectBatch(generation, full) {
|
|
58461
58498
|
const compact3 = {
|
|
@@ -58670,26 +58707,6 @@ function uploadFailure(path48) {
|
|
|
58670
58707
|
};
|
|
58671
58708
|
}
|
|
58672
58709
|
|
|
58673
|
-
// src/commands/studio/spokenPace.ts
|
|
58674
|
-
var WORDS_PER_SECOND3 = SPOKEN_WORDS_PER_SECOND;
|
|
58675
|
-
var spokenWords = spokenWordsIn;
|
|
58676
|
-
function wordsThatFit(seconds) {
|
|
58677
|
-
return Math.floor(seconds * WORDS_PER_SECOND3);
|
|
58678
|
-
}
|
|
58679
|
-
function spokenPaceHint(prompt, seconds, model) {
|
|
58680
|
-
const words2 = spokenWords(prompt);
|
|
58681
|
-
if (words2 === 0) return null;
|
|
58682
|
-
const split = model ? splitScriptFor(words2, model) : null;
|
|
58683
|
-
if (split) {
|
|
58684
|
-
return `The line is ${words2} words \u2014 about ${Math.ceil(words2 / WORDS_PER_SECOND3)}s of speech \u2014 and ${model} renders at most ${split.maxSeconds}s (~${Math.floor(split.maxSeconds * WORDS_PER_SECOND3)} words). It will not refuse and it will not cut: it will RUSH, swallowing syllables. Split the script into ${split.clips} takes of roughly ${split.wordsPerClip} words each, rendered separately and cut together \u2014 break it where the thought breaks, not mid-sentence. Or move to a model that renders longer (bytedance/seedance-2.5 goes to 30s).`;
|
|
58685
|
-
}
|
|
58686
|
-
if (!seconds) return null;
|
|
58687
|
-
const fits = wordsThatFit(seconds);
|
|
58688
|
-
if (words2 <= fits) return null;
|
|
58689
|
-
const rate = (words2 / seconds).toFixed(1);
|
|
58690
|
-
return `The line is ${words2} words and this clip is ${seconds}s \u2014 that is ${rate} words a second against a natural ${WORDS_PER_SECOND3}. The model will not run over, it will RUSH: syllables swallowed, endings clipped, and the take unusable however good the picture. Cut the line to about ${fits} words, or give it the length it needs (${Math.ceil(words2 / WORDS_PER_SECOND3)}s). Do not re-render the same line at the same length and hope.`;
|
|
58691
|
-
}
|
|
58692
|
-
|
|
58693
58710
|
// src/commands/studio/animate.ts
|
|
58694
58711
|
var MODEL_LIST = VIDEO_MODEL_IDS;
|
|
58695
58712
|
var DEFAULT_MAX_WAIT_MS = 6e5;
|
|
@@ -58931,6 +58948,25 @@ function costHintsFor(body) {
|
|
|
58931
58948
|
}
|
|
58932
58949
|
return hints2;
|
|
58933
58950
|
}
|
|
58951
|
+
var PRIOR_TAKE_WINDOW = 20;
|
|
58952
|
+
async function adByHandHintFor(body) {
|
|
58953
|
+
const thisTakeIsScripted = spokenWords(body.prompt) > 0;
|
|
58954
|
+
const buildsOnAClip = (body.clipRefs?.length ?? 0) + (body.videoIds?.length ?? 0) > 0;
|
|
58955
|
+
if (!thisTakeIsScripted || buildsOnAClip) return null;
|
|
58956
|
+
try {
|
|
58957
|
+
const { generations } = await apiGet("/api/studio/generations", {
|
|
58958
|
+
kind: "video",
|
|
58959
|
+
limit: String(PRIOR_TAKE_WINDOW)
|
|
58960
|
+
});
|
|
58961
|
+
return adByHandHint({
|
|
58962
|
+
priorScriptedTakes: priorScriptedTakes(generations),
|
|
58963
|
+
thisTakeIsScripted,
|
|
58964
|
+
buildsOnAClip
|
|
58965
|
+
});
|
|
58966
|
+
} catch {
|
|
58967
|
+
return null;
|
|
58968
|
+
}
|
|
58969
|
+
}
|
|
58934
58970
|
var animateCommand = defineCommand201({
|
|
58935
58971
|
meta: {
|
|
58936
58972
|
name: "animate",
|
|
@@ -59020,7 +59056,8 @@ var animateCommand = defineCommand201({
|
|
|
59020
59056
|
}
|
|
59021
59057
|
const { imageIds } = args.image ? await resolveLibraryImageIds(args.image, clipImageLimitFor(args)) : { imageIds: [] };
|
|
59022
59058
|
const body = buildAnimateBody(args, prompt, imageIds);
|
|
59023
|
-
const
|
|
59059
|
+
const assembling = await adByHandHintFor(body);
|
|
59060
|
+
const preflightHints = [...assembling ? [assembling] : [], ...costHintsFor(body)];
|
|
59024
59061
|
const start = await apiPost("/api/studio/animate", body);
|
|
59025
59062
|
const maxWaitMs = resolveMaxWaitMs(args.wait, args["max-wait"], DEFAULT_MAX_WAIT_MS);
|
|
59026
59063
|
if (maxWaitMs === 0) {
|
|
@@ -59029,7 +59066,7 @@ var animateCommand = defineCommand201({
|
|
|
59029
59066
|
data: start,
|
|
59030
59067
|
hints: [
|
|
59031
59068
|
`Rendering ${start.count} take(s). Read them with \`baker studio get ${start.generationId}\`, then keep the one you want.`,
|
|
59032
|
-
...
|
|
59069
|
+
...preflightHints
|
|
59033
59070
|
]
|
|
59034
59071
|
});
|
|
59035
59072
|
return;
|
|
@@ -59039,14 +59076,14 @@ var animateCommand = defineCommand201({
|
|
|
59039
59076
|
writeJson({
|
|
59040
59077
|
ok: true,
|
|
59041
59078
|
data: { ...start, status: "running" },
|
|
59042
|
-
hints: [waitingHint(outcome, start.generationId, maxWaitMs), ...
|
|
59079
|
+
hints: [waitingHint(outcome, start.generationId, maxWaitMs), ...preflightHints]
|
|
59043
59080
|
});
|
|
59044
59081
|
return;
|
|
59045
59082
|
}
|
|
59046
59083
|
writeJson({
|
|
59047
59084
|
ok: true,
|
|
59048
59085
|
data: projectBatch(outcome.generation, args.full === true),
|
|
59049
|
-
hints: [...batchHints(outcome.generation), ...
|
|
59086
|
+
hints: [...batchHints(outcome.generation), ...preflightHints]
|
|
59050
59087
|
});
|
|
59051
59088
|
} catch (error) {
|
|
59052
59089
|
failStudioCommand(error, { withFix: true });
|