@koda-sl/baker-cli 0.306.3-dev.bb28562ac → 0.306.6
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 +8 -1
- package/dist/{chunk-A2VZOTCV.js → chunk-AEU5X443.js} +3 -3
- package/dist/{chunk-2IUN3S3E.js → chunk-FOWT5AS4.js} +2 -2
- package/dist/{chunk-4YF56EGK.js → chunk-KMQHIAYG.js} +4 -4
- package/dist/{chunk-KDTHRRAC.js → chunk-TTIGSGXE.js} +3 -3
- package/dist/{chunk-WFWU3CHS.js → chunk-UIQJZGBG.js} +9 -1
- package/dist/{chunk-WFWU3CHS.js.map → chunk-UIQJZGBG.js.map} +1 -1
- package/dist/{chunk-3TEVIAAV.js → chunk-WONWYE7B.js} +8 -9
- package/dist/chunk-WONWYE7B.js.map +1 -0
- package/dist/cli.js +95 -74
- package/dist/cli.js.map +1 -1
- package/dist/{client-6KQHCXS2.js → client-QFJHI3FX.js} +4 -4
- package/dist/engine/index.js +3 -3
- package/dist/{env-C7YXL6C6.js → env-PJSBLG56.js} +6 -2
- package/dist/{output-RBM32FKJ.js → output-PAE5S7RI.js} +5 -5
- package/dist/{shared-WJIJTWST.js → shared-J6GGQDIL.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-3TEVIAAV.js.map +0 -1
- /package/dist/{chunk-A2VZOTCV.js.map → chunk-AEU5X443.js.map} +0 -0
- /package/dist/{chunk-2IUN3S3E.js.map → chunk-FOWT5AS4.js.map} +0 -0
- /package/dist/{chunk-4YF56EGK.js.map → chunk-KMQHIAYG.js.map} +0 -0
- /package/dist/{chunk-KDTHRRAC.js.map → chunk-TTIGSGXE.js.map} +0 -0
- /package/dist/{client-6KQHCXS2.js.map → client-QFJHI3FX.js.map} +0 -0
- /package/dist/{env-C7YXL6C6.js.map → env-PJSBLG56.js.map} +0 -0
- /package/dist/{output-RBM32FKJ.js.map → output-PAE5S7RI.js.map} +0 -0
- /package/dist/{shared-WJIJTWST.js.map → shared-J6GGQDIL.js.map} +0 -0
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,
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
resolveAccountIdArg,
|
|
77
77
|
resolveEffectiveStatus,
|
|
78
78
|
todayIso
|
|
79
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-KMQHIAYG.js";
|
|
80
80
|
import {
|
|
81
81
|
buildQueryCacheKey,
|
|
82
82
|
cacheGet,
|
|
@@ -92,32 +92,32 @@ import {
|
|
|
92
92
|
writeAdsJson,
|
|
93
93
|
writeAdsOutput,
|
|
94
94
|
writeJsonEnvelope
|
|
95
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-AEU5X443.js";
|
|
96
96
|
import {
|
|
97
97
|
ApiError,
|
|
98
98
|
apiGet,
|
|
99
99
|
apiGetWithHeaders,
|
|
100
100
|
apiPost,
|
|
101
101
|
validateConvexId
|
|
102
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-TTIGSGXE.js";
|
|
103
103
|
import {
|
|
104
104
|
installStreamTaps,
|
|
105
105
|
logInvocation
|
|
106
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-FOWT5AS4.js";
|
|
107
107
|
import {
|
|
108
108
|
captureBudgetMs,
|
|
109
109
|
captureProxyCredentials,
|
|
110
110
|
captureVimeoCookie,
|
|
111
|
-
frameVisionKey,
|
|
112
111
|
getEnv,
|
|
113
|
-
|
|
112
|
+
hasOpenRouterKey,
|
|
114
113
|
isProxyFailure,
|
|
114
|
+
openRouterKey,
|
|
115
115
|
plannedRoutes,
|
|
116
116
|
refuseNonPublicUrl,
|
|
117
117
|
requireChatId,
|
|
118
118
|
resolveChatId,
|
|
119
119
|
shouldEscalate
|
|
120
|
-
} from "./chunk-
|
|
120
|
+
} from "./chunk-UIQJZGBG.js";
|
|
121
121
|
|
|
122
122
|
// src/cli.ts
|
|
123
123
|
import { defineCommand as defineCommand240, runMain } from "citty";
|
|
@@ -23377,10 +23377,10 @@ Example: baker ads meta ads retag 120252158038400247 --url-tags "utm_source={{si
|
|
|
23377
23377
|
}
|
|
23378
23378
|
},
|
|
23379
23379
|
run: async ({ args }) => {
|
|
23380
|
-
const { apiPost: apiPost2 } = await import("./client-
|
|
23381
|
-
const { requireChatId: requireChatId2 } = await import("./env-
|
|
23382
|
-
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-
|
|
23383
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
23380
|
+
const { apiPost: apiPost2 } = await import("./client-QFJHI3FX.js");
|
|
23381
|
+
const { requireChatId: requireChatId2 } = await import("./env-PJSBLG56.js");
|
|
23382
|
+
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-PAE5S7RI.js");
|
|
23383
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-J6GGQDIL.js");
|
|
23384
23384
|
try {
|
|
23385
23385
|
const accountId = bareAccountId2(args);
|
|
23386
23386
|
const urlTags = typeof args["url-tags"] === "string" ? args["url-tags"] : void 0;
|
|
@@ -23521,10 +23521,10 @@ function duplicateCommand2(entity, label) {
|
|
|
23521
23521
|
replace: { type: "boolean", description: "Pause the original once the copy publishes" }
|
|
23522
23522
|
},
|
|
23523
23523
|
run: async ({ args }) => {
|
|
23524
|
-
const { apiPost: apiPost2 } = await import("./client-
|
|
23525
|
-
const { requireChatId: requireChatId2 } = await import("./env-
|
|
23526
|
-
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-
|
|
23527
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
23524
|
+
const { apiPost: apiPost2 } = await import("./client-QFJHI3FX.js");
|
|
23525
|
+
const { requireChatId: requireChatId2 } = await import("./env-PJSBLG56.js");
|
|
23526
|
+
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-PAE5S7RI.js");
|
|
23527
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-J6GGQDIL.js");
|
|
23528
23528
|
try {
|
|
23529
23529
|
const accountId = bareAccountId2(args);
|
|
23530
23530
|
const chatId = requireChatId2();
|
|
@@ -30402,7 +30402,7 @@ function rosterHints(roster, statusFilter) {
|
|
|
30402
30402
|
`@${mine[0]} was made in this conversation${mine.length > 1 ? ` (with ${mine.slice(1).map((h) => `@${h}`).join(", ")})` : ""} \u2014 that is the avatar this chat is about, and the user chose its face. Use it. The others belong to earlier conversations: only reach for one if the user names it, and never ask which to use when the answer is the one you just cast.`
|
|
30403
30403
|
] : [];
|
|
30404
30404
|
hints2.push(
|
|
30405
|
-
"Casting one of these?
|
|
30405
|
+
"Casting one of these? Cast them with `--avatar <handle>` on `baker studio generate` / `baker studio animate` \u2014 that flag carries their face AND their accent. `baker avatars get <handle>` returns the written profile behind it; the roster leaves the description out on purpose, because it must never be read half-way."
|
|
30406
30406
|
);
|
|
30407
30407
|
const building = roster.filter((avatar) => avatar.status === "generating").map((avatar) => avatar.handle);
|
|
30408
30408
|
if (building.length > 0) {
|
|
@@ -36920,17 +36920,20 @@ import { tmpdir } from "os";
|
|
|
36920
36920
|
import path15 from "path";
|
|
36921
36921
|
import { promisify as promisify2 } from "util";
|
|
36922
36922
|
import { z as z35 } from "zod";
|
|
36923
|
-
var RENDER_REVIEW_MODEL = "gemini-pro-latest";
|
|
36923
|
+
var RENDER_REVIEW_MODEL = "~google/gemini-pro-latest";
|
|
36924
36924
|
var RENDER_REVIEW_FRAMES = 12;
|
|
36925
36925
|
var RENDER_REVIEW_WIDTH = 1024;
|
|
36926
|
-
var RENDER_WATCH_MODEL = "gemini-
|
|
36926
|
+
var RENDER_WATCH_MODEL = "~google/gemini-flash-latest";
|
|
36927
36927
|
function usageFrom(model, body) {
|
|
36928
|
-
const
|
|
36929
|
-
if (!
|
|
36930
|
-
const
|
|
36931
|
-
|
|
36932
|
-
|
|
36933
|
-
|
|
36928
|
+
const usage = body?.usage;
|
|
36929
|
+
if (!usage) return null;
|
|
36930
|
+
const positive = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : null;
|
|
36931
|
+
return {
|
|
36932
|
+
model,
|
|
36933
|
+
inputTokens: usage.prompt_tokens ?? 0,
|
|
36934
|
+
outputTokens: usage.completion_tokens ?? 0,
|
|
36935
|
+
costUsd: positive(usage.cost) ?? positive(usage.cost_details?.upstream_inference_cost) ?? 0
|
|
36936
|
+
};
|
|
36934
36937
|
}
|
|
36935
36938
|
var WATCH_MAX_BYTES = 60 * 1024 * 1024;
|
|
36936
36939
|
function sceneAt(windows, atS) {
|
|
@@ -37233,7 +37236,7 @@ function classifyAudio(volumedetect, hasAudioStream) {
|
|
|
37233
37236
|
}
|
|
37234
37237
|
return findings;
|
|
37235
37238
|
}
|
|
37236
|
-
var RENDER_REVIEW_UNAVAILABLE = "The render was NOT reviewed \u2014 no
|
|
37239
|
+
var RENDER_REVIEW_UNAVAILABLE = "The render was NOT reviewed \u2014 no model gateway key in this environment. Watch it yourself before sending it on.";
|
|
37237
37240
|
var REVIEW_CONCURRENCY = 3;
|
|
37238
37241
|
async function mapWithLimit(items, limit, fn) {
|
|
37239
37242
|
const out = new Array(items.length);
|
|
@@ -37276,64 +37279,63 @@ async function videoDuration(video) {
|
|
|
37276
37279
|
return null;
|
|
37277
37280
|
}
|
|
37278
37281
|
}
|
|
37279
|
-
async function
|
|
37280
|
-
const key =
|
|
37282
|
+
async function askGateway(model, parts, timeoutMs, spent) {
|
|
37283
|
+
const key = openRouterKey();
|
|
37281
37284
|
if (!key) return null;
|
|
37282
37285
|
try {
|
|
37283
|
-
const
|
|
37284
|
-
|
|
37285
|
-
|
|
37286
|
-
|
|
37287
|
-
|
|
37288
|
-
|
|
37289
|
-
|
|
37290
|
-
|
|
37291
|
-
|
|
37292
|
-
|
|
37293
|
-
parts: [{ text: prompt }, { inline_data: { mime_type: "video/mp4", data: bytes.toString("base64") } }]
|
|
37294
|
-
}
|
|
37295
|
-
]
|
|
37296
|
-
}),
|
|
37297
|
-
signal: AbortSignal.timeout(6e5)
|
|
37298
|
-
}
|
|
37299
|
-
);
|
|
37286
|
+
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
|
|
37287
|
+
method: "POST",
|
|
37288
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${key}` },
|
|
37289
|
+
body: JSON.stringify({
|
|
37290
|
+
model,
|
|
37291
|
+
messages: [{ role: "user", content: parts }],
|
|
37292
|
+
usage: { include: true }
|
|
37293
|
+
}),
|
|
37294
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
37295
|
+
});
|
|
37300
37296
|
if (!response.ok) return null;
|
|
37301
37297
|
const body = await response.json();
|
|
37302
|
-
const usage = usageFrom(
|
|
37298
|
+
const usage = usageFrom(model, body);
|
|
37303
37299
|
if (usage) spent(usage);
|
|
37304
|
-
const text2 = body.
|
|
37300
|
+
const text2 = body.choices?.[0]?.message?.content;
|
|
37305
37301
|
return text2 ? parseReviewJson(text2) : null;
|
|
37306
37302
|
} catch {
|
|
37307
37303
|
return null;
|
|
37308
37304
|
}
|
|
37309
37305
|
}
|
|
37310
|
-
async function
|
|
37311
|
-
|
|
37312
|
-
if (!key) return null;
|
|
37313
|
-
const parts = [{ text: prompt }];
|
|
37314
|
-
for (const b64 of images) parts.push({ inline_data: { mime_type: "image/jpeg", data: b64 } });
|
|
37306
|
+
async function askVideo(video, prompt, spent) {
|
|
37307
|
+
let bytes;
|
|
37315
37308
|
try {
|
|
37316
|
-
|
|
37317
|
-
`https://generativelanguage.googleapis.com/v1beta/models/${RENDER_REVIEW_MODEL}:generateContent`,
|
|
37318
|
-
{
|
|
37319
|
-
method: "POST",
|
|
37320
|
-
headers: { "content-type": "application/json", "x-goog-api-key": key },
|
|
37321
|
-
body: JSON.stringify({ contents: [{ parts }] }),
|
|
37322
|
-
signal: AbortSignal.timeout(18e4)
|
|
37323
|
-
}
|
|
37324
|
-
);
|
|
37325
|
-
if (!response.ok) return null;
|
|
37326
|
-
const body = await response.json();
|
|
37327
|
-
const usage = usageFrom(RENDER_REVIEW_MODEL, body);
|
|
37328
|
-
if (usage) spent(usage);
|
|
37329
|
-
const text2 = body.candidates?.[0]?.content?.parts?.map((p) => p.text ?? "").join("");
|
|
37330
|
-
return text2 ? parseReviewJson(text2) : null;
|
|
37309
|
+
bytes = await readFile11(video);
|
|
37331
37310
|
} catch {
|
|
37332
37311
|
return null;
|
|
37333
37312
|
}
|
|
37313
|
+
if (bytes.byteLength > WATCH_MAX_BYTES) return null;
|
|
37314
|
+
return await askGateway(
|
|
37315
|
+
RENDER_WATCH_MODEL,
|
|
37316
|
+
[
|
|
37317
|
+
{ type: "text", text: prompt },
|
|
37318
|
+
{ type: "video_url", video_url: { url: `data:video/mp4;base64,${bytes.toString("base64")}` } }
|
|
37319
|
+
],
|
|
37320
|
+
6e5,
|
|
37321
|
+
spent
|
|
37322
|
+
);
|
|
37323
|
+
}
|
|
37324
|
+
async function ask(images, prompt, spent) {
|
|
37325
|
+
return await askGateway(
|
|
37326
|
+
RENDER_REVIEW_MODEL,
|
|
37327
|
+
[
|
|
37328
|
+
{ type: "text", text: prompt },
|
|
37329
|
+
...images.map(
|
|
37330
|
+
(b64) => ({ type: "image_url", image_url: { url: `data:image/jpeg;base64,${b64}` } })
|
|
37331
|
+
)
|
|
37332
|
+
],
|
|
37333
|
+
18e4,
|
|
37334
|
+
spent
|
|
37335
|
+
);
|
|
37334
37336
|
}
|
|
37335
37337
|
async function reviewRenderedVideo(opts) {
|
|
37336
|
-
if (!
|
|
37338
|
+
if (!hasOpenRouterKey()) return null;
|
|
37337
37339
|
const duration = await videoDuration(opts.video);
|
|
37338
37340
|
if (duration === null) return null;
|
|
37339
37341
|
const spent = (usage) => opts.onSpend?.(usage);
|
|
@@ -37815,6 +37817,12 @@ ${describeRewrites(healed.rewrites)}
|
|
|
37815
37817
|
}
|
|
37816
37818
|
if (e instanceof RunAbortedError && e.reason === "checkpoint") {
|
|
37817
37819
|
await clearRunMarker(outputsDir, filePath);
|
|
37820
|
+
if (poster) {
|
|
37821
|
+
await poster.flush({
|
|
37822
|
+
...failedPayload(`Stopped before the clips, waiting on a decision. Resume with --run-id ${runId}.`),
|
|
37823
|
+
interrupted: true
|
|
37824
|
+
});
|
|
37825
|
+
}
|
|
37818
37826
|
const frames = frameUrls;
|
|
37819
37827
|
process.stdout.write(
|
|
37820
37828
|
`${JSON.stringify(
|
|
@@ -39335,6 +39343,13 @@ function beatToCamera(spec, beat, isClosingCard) {
|
|
|
39335
39343
|
if (beat.on_camera !== void 0) return beat.on_camera;
|
|
39336
39344
|
return Boolean(spec.cast) && beat.cast !== false;
|
|
39337
39345
|
}
|
|
39346
|
+
function beatsIntroducingSpeakerOffCamera(spec) {
|
|
39347
|
+
const closesOnCard = endCardWanted(spec);
|
|
39348
|
+
const last = spec.beats.length - 1;
|
|
39349
|
+
return spec.beats.flatMap(
|
|
39350
|
+
(beat, i) => lineIntroducesSpeaker(beat.say) && !beatToCamera(spec, beat, closesOnCard && i === last) ? [i] : []
|
|
39351
|
+
);
|
|
39352
|
+
}
|
|
39338
39353
|
function wantsNativeSpeech(spec, closesOnCard) {
|
|
39339
39354
|
if (!spec.cast || spec.voiceover === false) return false;
|
|
39340
39355
|
const last = spec.beats.length - 1;
|
|
@@ -39453,7 +39468,7 @@ function beatsTooShortToPlay(spec) {
|
|
|
39453
39468
|
}
|
|
39454
39469
|
|
|
39455
39470
|
// src/engine/scaffold/ad-brand-overlay.ts
|
|
39456
|
-
var markFallback = (name) => name.trim() ? ` onerror="this.replaceWith(Object.assign(document.createElement('span'),{className:this.className+' brand-wordmark',textContent:${JSON.stringify(name.trim())}}))"` : "";
|
|
39471
|
+
var markFallback = (name) => name.trim() ? ` onerror="this.replaceWith(Object.assign(document.createElement('span'),{className:this.className+' brand-wordmark',textContent:${escapeHtml2(JSON.stringify(name.trim()))}}))"` : "";
|
|
39457
39472
|
var escapeHtml2 = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
39458
39473
|
function firstHex(palette) {
|
|
39459
39474
|
const hex = (palette ?? []).find((h) => /^#?[0-9a-fA-F]{6}$/.test(h.trim()));
|
|
@@ -39822,7 +39837,12 @@ var scaffoldAdCommand = defineCommand111({
|
|
|
39822
39837
|
error: {
|
|
39823
39838
|
code: "VALIDATION_ERROR",
|
|
39824
39839
|
message: "This ad names a recurring place but gives no picture of it. A location sheet is fused from a real image; with nothing to fuse there is no sheet, and every shot invents the room again.",
|
|
39825
|
-
|
|
39840
|
+
// Names `studio generate`, which is the command that exists — `baker images`
|
|
39841
|
+
// finds and ingests pictures, it does not make them, so the line this used to
|
|
39842
|
+
// print could not be run. No `--model` either: the lane already defaults to the
|
|
39843
|
+
// curated image model, and the one named here was the legacy id the picker now
|
|
39844
|
+
// offers to nobody.
|
|
39845
|
+
fix: `Make the plate once, then pass it: \`baker studio generate "${spec.data.set.description}"\`, then put its url in the spec as \`"set": { "description": "\u2026", "image": "<url>" }\`. Drop \`set\` entirely if the ad does not keep returning to one place.`
|
|
39826
39846
|
}
|
|
39827
39847
|
});
|
|
39828
39848
|
process.exit(1);
|
|
@@ -39884,14 +39904,15 @@ var scaffoldAdCommand = defineCommand111({
|
|
|
39884
39904
|
...filledPalette ? { palette: filledPalette } : {}
|
|
39885
39905
|
};
|
|
39886
39906
|
}
|
|
39887
|
-
const introducesOffCamera = spec.data
|
|
39888
|
-
|
|
39889
|
-
|
|
39907
|
+
const introducesOffCamera = beatsIntroducingSpeakerOffCamera(spec.data);
|
|
39908
|
+
const firstIntro = introducesOffCamera[0];
|
|
39909
|
+
if (firstIntro !== void 0) {
|
|
39910
|
+
const line = (spec.data.beats[firstIntro]?.say ?? "").trim();
|
|
39890
39911
|
writeJson({
|
|
39891
39912
|
ok: false,
|
|
39892
39913
|
error: {
|
|
39893
39914
|
code: "VALIDATION_ERROR",
|
|
39894
|
-
message: `Beat ${
|
|
39915
|
+
message: `Beat ${firstIntro + 1} says "${line}" \u2014 the speaker introducing themselves \u2014 but nobody is on camera saying it. A voice from off screen introducing the person standing in shot reads as a mistake, the same way a moving mouth under someone else's voice does.`,
|
|
39895
39916
|
fix: 'Either set `on_camera: true` on that beat so they say it themselves \u2014 which needs the avatar to have their own accent \u2014 or rewrite the line as narration about them rather than by them: "Marta instal\xF3 placas en nueve d\xEDas", not "Hola, soy Marta".'
|
|
39896
39917
|
}
|
|
39897
39918
|
});
|