@koda-sl/baker-cli 0.282.0-dev.37d65c47b → 0.282.0-dev.555a170a5
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/cli.js
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
VIDEO_GENERATE_MODELS,
|
|
20
20
|
ValidationError,
|
|
21
21
|
YtDlpError,
|
|
22
|
+
bestSupportedQuality,
|
|
22
23
|
canonicalUrl,
|
|
23
24
|
clipParamRecipe,
|
|
24
25
|
clipProfileFor,
|
|
@@ -59,7 +60,7 @@ import {
|
|
|
59
60
|
ulid,
|
|
60
61
|
validateCanvasDeep,
|
|
61
62
|
ytDlpBlockSignal
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-LOUE7GTU.js";
|
|
63
64
|
import {
|
|
64
65
|
csvOrJson,
|
|
65
66
|
daysAgoIso,
|
|
@@ -6195,8 +6196,9 @@ var imagesPinterestRequestSchema = z18.object({
|
|
|
6195
6196
|
});
|
|
6196
6197
|
var imagesPinterestResponseSchema = providerHitsResponseSchema();
|
|
6197
6198
|
var imageGenerateModelSchema = z18.enum([
|
|
6199
|
+
"openai/gpt-image-2.5-sunburst",
|
|
6200
|
+
// Legacy — see the registry entries; kept so pre-switch canvases still run.
|
|
6198
6201
|
"openai/gpt-image-2",
|
|
6199
|
-
// Legacy — see the registry entry; kept so pre-switch canvases still run.
|
|
6200
6202
|
"openai/gpt-5.4-image-2",
|
|
6201
6203
|
"google/gemini-3.1-flash-image-preview",
|
|
6202
6204
|
"google/gemini-3.1-flash-lite-image",
|
|
@@ -6555,7 +6557,7 @@ var studioGenerateRequestSchema = z21.object({
|
|
|
6555
6557
|
useBrand: z21.boolean().optional(),
|
|
6556
6558
|
// Per-model knobs; the backend refuses one the chosen model does not advertise.
|
|
6557
6559
|
imageSize: z21.string().optional(),
|
|
6558
|
-
quality: z21.enum(["auto", "low", "medium", "high"]).optional(),
|
|
6560
|
+
quality: z21.enum(["auto", "low", "medium", "high", "xhigh", "max"]).optional(),
|
|
6559
6561
|
strength: z21.coerce.number().min(0).max(1).optional(),
|
|
6560
6562
|
rgbColors: z21.array(rgbTriple).optional(),
|
|
6561
6563
|
backgroundRgbColor: rgbTriple.optional()
|
|
@@ -29842,9 +29844,17 @@ function thinProfileHint(profile, handle) {
|
|
|
29842
29844
|
if (missing.length === 0) return null;
|
|
29843
29845
|
return `MISSING ${missing.map((field) => `--${field}`).join(" ")}. A bare subject description holds the face still and nothing else, so clips of @${handle} come out stiff and generic \u2014 measured, filling these in nearly doubled the movement in the same brief. --accent is the one nobody guesses and the only one that fails silently: it decides the accent the avatar SPEAKS with in every clip, so name the region the user is writing to you from ("Spanish from Spain, Madrid accent") \u2014 "Spanish" on its own renders as no accent at all. The user almost certainly told you how this person talks and carries themselves; put it in: \`baker avatars update ${handle} ${missing.map((field) => `--${field} "\u2026"`).join(" ")}\`.`;
|
|
29844
29846
|
}
|
|
29847
|
+
function parseFaceChoice(raw) {
|
|
29848
|
+
if (raw === void 0) return "ask";
|
|
29849
|
+
const value = raw.trim().toLowerCase();
|
|
29850
|
+
if (value === "ask" || value === "auto") return value;
|
|
29851
|
+
return null;
|
|
29852
|
+
}
|
|
29845
29853
|
function creationHints(created, profile) {
|
|
29846
29854
|
const thin = thinProfileHint(profile, created.handle);
|
|
29847
|
-
const casting = created.likeness === "synthetic" ? [
|
|
29855
|
+
const casting = created.likeness === "synthetic" && created.faceChoice === "auto" ? [
|
|
29856
|
+
`No one was asked about this face \u2014 \`--face auto\` cast it and it is kept. Do not tell the user they chose it, and do not offer them a pick you are not going to run. If this should have been theirs, say so and create it again with \`--face ask\`.`
|
|
29857
|
+
] : created.likeness === "synthetic" ? [
|
|
29848
29858
|
`The user chooses this face, and it only happens if you ask: call \`request_avatar_casting { avatarHandle: "${created.handle}" }\` now. It shows them real portraits and blocks until they pick \u2014 never stand in a question of your own, which can only offer them words. The sheet building right now is fused from a face nobody has chosen.`
|
|
29849
29859
|
] : [];
|
|
29850
29860
|
const hints2 = [
|
|
@@ -30051,7 +30061,12 @@ registerSchema({
|
|
|
30051
30061
|
required: false
|
|
30052
30062
|
},
|
|
30053
30063
|
"voice-id": { type: "string", description: "Voice id to speak with in video", required: false },
|
|
30054
|
-
"voice-description": { type: "string", description: "How the voice should sound", required: false }
|
|
30064
|
+
"voice-description": { type: "string", description: "How the voice should sound", required: false },
|
|
30065
|
+
face: {
|
|
30066
|
+
type: "string",
|
|
30067
|
+
description: "Who picks the face, for an invented avatar: 'ask' (default) blocks on the user through `request_avatar_casting`, 'auto' keeps the one this build casts and asks nobody. Use 'auto' only when there is no one to answer \u2014 a Schedule, a batch, an explicit \"do it yourself\" \u2014 because a person who is there almost always wants this choice.",
|
|
30068
|
+
required: false
|
|
30069
|
+
}
|
|
30055
30070
|
}
|
|
30056
30071
|
});
|
|
30057
30072
|
var createCommand2 = defineCommand96({
|
|
@@ -30086,7 +30101,12 @@ var createCommand2 = defineCommand96({
|
|
|
30086
30101
|
default: false
|
|
30087
30102
|
},
|
|
30088
30103
|
"voice-id": { type: "string", description: "Voice id", required: false },
|
|
30089
|
-
"voice-description": { type: "string", description: "How the voice should sound", required: false }
|
|
30104
|
+
"voice-description": { type: "string", description: "How the voice should sound", required: false },
|
|
30105
|
+
face: {
|
|
30106
|
+
type: "string",
|
|
30107
|
+
description: "Who picks the face of an invented avatar: 'ask' (default, blocks on the user) or 'auto' (asks nobody)",
|
|
30108
|
+
required: false
|
|
30109
|
+
}
|
|
30090
30110
|
},
|
|
30091
30111
|
run: async ({ args }) => {
|
|
30092
30112
|
const name = args.name?.trim();
|
|
@@ -30110,6 +30130,16 @@ var createCommand2 = defineCommand96({
|
|
|
30110
30130
|
`--handle "${handle}" is not usable. Use lowercase letters, numbers and dashes, starting with a letter \u2014 "maria-founder", not "Maria Founder". Leave it off to have one derived from the name.`
|
|
30111
30131
|
);
|
|
30112
30132
|
}
|
|
30133
|
+
const faceChoice = parseFaceChoice(args.face);
|
|
30134
|
+
if (faceChoice === null) {
|
|
30135
|
+
failValidation2(
|
|
30136
|
+
`--face "${String(args.face)}" is not a mode. Use --face ask to let the user pick the face, or --face auto to keep the one this build casts.`,
|
|
30137
|
+
{
|
|
30138
|
+
action: "pick_a_mode",
|
|
30139
|
+
explanation: "Drop the flag entirely if a person is in the conversation \u2014 that is --face ask, and it is what they almost always want. Pass --face auto only when nobody is there to answer: a Schedule, a batch run, or the user telling you to do it without them."
|
|
30140
|
+
}
|
|
30141
|
+
);
|
|
30142
|
+
}
|
|
30113
30143
|
const sourceImageIds = parseImageIds(args["source-image"]);
|
|
30114
30144
|
const likenessConfirmed = Boolean(args["likeness-confirmed"]);
|
|
30115
30145
|
if (sourceImageIds && !likenessConfirmed) {
|
|
@@ -30132,7 +30162,7 @@ var createCommand2 = defineCommand96({
|
|
|
30132
30162
|
...chatIdFromEnv() ? { chatId: chatIdFromEnv() } : {}
|
|
30133
30163
|
};
|
|
30134
30164
|
const data = await writeAvatars("/api/avatars", body);
|
|
30135
|
-
writeJson({ ok: true, data, hints: creationHints(data, body.profile) });
|
|
30165
|
+
writeJson({ ok: true, data, hints: creationHints({ ...data, faceChoice }, body.profile) });
|
|
30136
30166
|
} catch (err) {
|
|
30137
30167
|
failAvatarApi(err, handle);
|
|
30138
30168
|
}
|
|
@@ -32867,6 +32897,7 @@ function extendPresenceByPromptMentions(slots, blueprint) {
|
|
|
32867
32897
|
}
|
|
32868
32898
|
var ACTOR_SHEET_MODEL = "google/gemini-3-pro-image-preview";
|
|
32869
32899
|
var KEYFRAME_IMAGE_SIZE = "2K";
|
|
32900
|
+
var FRAME_QUALITY = "xhigh";
|
|
32870
32901
|
var SHEET_SUBJECT_TYPE = {
|
|
32871
32902
|
person: "person",
|
|
32872
32903
|
animal: "character",
|
|
@@ -33057,6 +33088,7 @@ function buildFrameRef(edge, url, framePrompt, present2, ctx, nodes) {
|
|
|
33057
33088
|
const presentOrdered = orderSlotsByIdentity(present2);
|
|
33058
33089
|
const reference = [...presentOrdered.map((s) => s.ref), ...originalRef ? [originalRef] : []];
|
|
33059
33090
|
const imageProfile = imageProfileFor(ctx.imageModel);
|
|
33091
|
+
const quality = bestSupportedQuality("image_generate", ctx.imageModel, FRAME_QUALITY);
|
|
33060
33092
|
const genParams = {
|
|
33061
33093
|
model: ctx.imageModel,
|
|
33062
33094
|
// gpt-image-2 derives pixel dimensions from the ratio and has no size knob,
|
|
@@ -33065,9 +33097,14 @@ function buildFrameRef(edge, url, framePrompt, present2, ctx, nodes) {
|
|
|
33065
33097
|
// so snap to the best tier the chosen model actually offers rather than pinning
|
|
33066
33098
|
// a literal that a cheaper model would reject outright.
|
|
33067
33099
|
...supportsParam("image_generate", ctx.imageModel, "image_size") ? { image_size: nearestSupportedImageSize("image_generate", ctx.imageModel, KEYFRAME_IMAGE_SIZE) } : {},
|
|
33068
|
-
// Per-model image defaults (
|
|
33069
|
-
//
|
|
33100
|
+
// Per-model image defaults (we do NOT send input_fidelity, which gpt-image forces
|
|
33101
|
+
// high automatically).
|
|
33070
33102
|
...imageProfile?.paramDefaults ?? {},
|
|
33103
|
+
// The frame IS the clip's first moment, and the video model animates whatever it is
|
|
33104
|
+
// handed — a soft frame is a soft clip for its whole length, and no amount of motion
|
|
33105
|
+
// direction recovers it. Worth the step the older models cannot reach; they fall back
|
|
33106
|
+
// to `high` on their own rather than failing validate.
|
|
33107
|
+
...quality ? { quality } : {},
|
|
33071
33108
|
prompt: buildFramePrompt(
|
|
33072
33109
|
edge,
|
|
33073
33110
|
ctx.sceneIndex,
|
|
@@ -37432,6 +37469,12 @@ function scaffoldStaticAd(input, elementsInput, opts) {
|
|
|
37432
37469
|
...supportsParam("image_generate", opts.genModel, "image_size") ? { image_size: "2K" } : {},
|
|
37433
37470
|
// Per-model image defaults (gpt-image: quality=high).
|
|
37434
37471
|
...imageProfileFor(opts.genModel)?.paramDefaults ?? {},
|
|
37472
|
+
// This one render IS the ad — it gets published at full size and read by a person,
|
|
37473
|
+
// not consumed by another model. One image, so the best step the model has.
|
|
37474
|
+
...(() => {
|
|
37475
|
+
const quality = bestSupportedQuality("image_generate", opts.genModel, "xhigh");
|
|
37476
|
+
return quality ? { quality } : {};
|
|
37477
|
+
})(),
|
|
37435
37478
|
prompt
|
|
37436
37479
|
}
|
|
37437
37480
|
});
|
|
@@ -38808,7 +38851,7 @@ function resolveShippedCanvasDir(name, startDir, exists = existsSync5, maxDepth
|
|
|
38808
38851
|
}
|
|
38809
38852
|
|
|
38810
38853
|
// src/commands/canvas/scaffold-ad.ts
|
|
38811
|
-
var AD_IMAGE_MODEL = "openai/gpt-image-2";
|
|
38854
|
+
var AD_IMAGE_MODEL = "openai/gpt-image-2.5-sunburst";
|
|
38812
38855
|
var SHIPPED_COMPOSITION_DIR = resolveShippedCanvasDir("video-overlay-composition", import.meta.dirname);
|
|
38813
38856
|
var SHIPPED_CAPTIONS_DIR = resolveShippedCanvasDir("tiktok-captions-composition", import.meta.dirname);
|
|
38814
38857
|
registerSchema({
|
|
@@ -39534,7 +39577,7 @@ function resolveModels2(args) {
|
|
|
39534
39577
|
// Default to the strongest image model (matches the static-ad scaffold); the
|
|
39535
39578
|
// frame generators need the most faithful text/identity reproduction. Override
|
|
39536
39579
|
// with --image-model for a cheaper/faster pass.
|
|
39537
|
-
imageModel: pick("image-model", "image_generate", "openai/gpt-image-2")
|
|
39580
|
+
imageModel: pick("image-model", "image_generate", "openai/gpt-image-2.5-sunburst")
|
|
39538
39581
|
};
|
|
39539
39582
|
}
|
|
39540
39583
|
function hasPhotorealCast(elements) {
|