@docyrus/animaguru 0.35.1 → 0.38.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 +89 -9
- package/dist/animaguru.js +451 -152
- package/package.json +1 -1
- package/skills/animaguru/SKILL.md +25 -4
- package/skills/animaguru/references/avatars.md +15 -2
- package/skills/animaguru/references/sharing.md +2 -2
- package/skills/animaguru-video/SKILL.md +19 -1
- package/templates/video/src/kit/gif.ts +40 -0
package/dist/animaguru.js
CHANGED
|
@@ -19761,7 +19761,7 @@ var require_ignore2 = __commonJS({
|
|
|
19761
19761
|
// cli/package.json
|
|
19762
19762
|
var package_default = {
|
|
19763
19763
|
name: "@docyrus/animaguru",
|
|
19764
|
-
version: "0.
|
|
19764
|
+
version: "0.38.0",
|
|
19765
19765
|
description: "Agent-friendly AnimaGuru CLI built with CrustJS",
|
|
19766
19766
|
type: "module",
|
|
19767
19767
|
bin: {
|
|
@@ -45002,9 +45002,11 @@ var ALL_TOP_ACTIONS = [...new Set(Object.values(SPRITE_TOP_ACTIONS).flat())];
|
|
|
45002
45002
|
var CUSTOM_FRAMES = { min: 2, max: 12 };
|
|
45003
45003
|
|
|
45004
45004
|
// shared/sprites/models.ts
|
|
45005
|
-
var DEFAULT_SPRITE_IMAGE_MODEL = "fal/gpt-image-2.
|
|
45005
|
+
var DEFAULT_SPRITE_IMAGE_MODEL = "fal/gpt-image-2.6-medium";
|
|
45006
45006
|
var SPRITE_IMAGE_MODELS = [
|
|
45007
|
-
{ id: DEFAULT_SPRITE_IMAGE_MODEL, label: "GPT Image 2.
|
|
45007
|
+
{ id: DEFAULT_SPRITE_IMAGE_MODEL, label: "GPT Image 2.6 Flare \xB7 medium (fal)", provider: "fal", edit: true, nativeAlpha: true, maxImages: 16, relCost: 0.3, quality: "medium", endpoints: { generate: "openai/gpt-image-2.6/flare/text-to-image", edit: "openai/gpt-image-2.6/flare/edit" } },
|
|
45008
|
+
{ id: "fal/gpt-image-2.6-sunburst-high", label: "GPT Image 2.6 Sunburst \xB7 high (fal)", provider: "fal", edit: true, nativeAlpha: true, maxImages: 16, relCost: 1, quality: "high", endpoints: { generate: "openai/gpt-image-2.6/sunburst/text-to-image", edit: "openai/gpt-image-2.6/sunburst/edit" } },
|
|
45009
|
+
{ id: "fal/gpt-image-2.5-medium", label: "GPT Image 2.5 \xB7 medium (fal)", provider: "fal", edit: true, nativeAlpha: true, maxImages: 16, relCost: 0.3, quality: "medium", endpoints: { generate: "openai/gpt-image-2.5/flare/text-to-image", edit: "openai/gpt-image-2.5/flare/edit" } },
|
|
45008
45010
|
{ id: "fal/gpt-image-2-low", label: "GPT Image 2 \xB7 low (fal)", provider: "fal", edit: true, spriteBackupCutout: true, maxImages: 16, relCost: 0.2, quality: "low", endpoints: { generate: "openai/gpt-image-2", edit: "openai/gpt-image-2/edit" } },
|
|
45009
45011
|
{ id: "fal/muse-image", label: "Muse Image (fal)", provider: "fal", edit: true, maxImages: 10, relCost: 0.2, endpoints: { generate: "meta/muse-image/text-to-image", edit: "meta/muse-image/edit" } },
|
|
45010
45012
|
{ id: "fal/krea-2-turbo", label: "Krea 2 Turbo (fal)", provider: "fal", edit: false, maxImages: 0, relCost: 0.16, endpoints: { generate: "fal-ai/krea-2/turbo" } },
|
|
@@ -45013,7 +45015,11 @@ var SPRITE_IMAGE_MODELS = [
|
|
|
45013
45015
|
{ id: "bytedance/seedream-5-pro", label: "Seedream 5 Pro", provider: "workers-ai", edit: true, maxImages: 10, relCost: 1.5 },
|
|
45014
45016
|
{ id: "xai/grok-imagine-image-2.0", label: "Grok Imagine Image 2.0", provider: "workers-ai", edit: true, maxImages: 5, relCost: 1 },
|
|
45015
45017
|
{ id: "alibaba/qwen-image-3.0-pro", label: "Qwen Image 3.0 Pro", provider: "workers-ai", edit: false, maxImages: 0, relCost: 0.5 },
|
|
45016
|
-
{ id: "krea/krea-2-medium-turbo", label: "Krea 2 Medium Turbo", provider: "workers-ai", edit: false, maxImages: 0, relCost: 0.25 }
|
|
45018
|
+
{ id: "krea/krea-2-medium-turbo", label: "Krea 2 Medium Turbo", provider: "workers-ai", edit: false, maxImages: 0, relCost: 0.25 },
|
|
45019
|
+
// Seedream on AnimaGuru's own BytePlus account: $0.045 an image (Pro, up to 2.61 MP), $0.018 (Flash), $0.035 (Lite).
|
|
45020
|
+
{ id: "byteplus/seedream-5.0-pro", label: "Seedream 5.0 Pro (BytePlus)", provider: "byteplus", providerModel: "dola-seedream-5-0-pro-260628", edit: true, spriteBackupCutout: true, maxImages: 10, relCost: 0.35 },
|
|
45021
|
+
{ id: "byteplus/seedream-5.0-flash", label: "Seedream 5.0 Flash (BytePlus)", provider: "byteplus", providerModel: "dola-seedream-5-0-flash-260915", edit: true, spriteBackupCutout: true, maxImages: 10, relCost: 0.15 },
|
|
45022
|
+
{ id: "byteplus/seedream-5.0-lite", label: "Seedream 5.0 Lite (BytePlus)", provider: "byteplus", providerModel: "seedream-5-0-260128", edit: true, spriteBackupCutout: true, maxImages: 14, relCost: 0.3 }
|
|
45017
45023
|
];
|
|
45018
45024
|
var SPRITE_IMAGE_MODEL_IDS = SPRITE_IMAGE_MODELS.map((m) => m.id);
|
|
45019
45025
|
function spriteImageModel(id2) {
|
|
@@ -45048,6 +45054,8 @@ var HEYGEN_LONG = { max: 30, creditsPerSecond: { "480p": 4.5, "768p": 7.5, "1080
|
|
|
45048
45054
|
var H3_MAX = "minimax/h3-max";
|
|
45049
45055
|
var FLUX_3_MAX = "blackforestlabs/flux-3-max";
|
|
45050
45056
|
var h3Endpoints = (route) => ({ "image-to-video": `${route}/image-to-video`, "text-to-video": `${route}/text-to-video`, "extend-video": `${route}/extend-video` });
|
|
45057
|
+
var SEEDANCE_WORKFLOWS = ["image-to-video", "text-to-video", "reference-to-video"];
|
|
45058
|
+
var SEEDANCE_REFERENCES = { referencesOnly: true, mediaReferences: ["images", "audio"] };
|
|
45051
45059
|
var SPRITE_VIDEO_MODELS = [
|
|
45052
45060
|
{
|
|
45053
45061
|
id: "pruna/p-video-2-pro",
|
|
@@ -45145,6 +45153,59 @@ var SPRITE_VIDEO_MODELS = [
|
|
|
45145
45153
|
promptExpansion: ["balanced", "quality"],
|
|
45146
45154
|
estimatedCreditsPerSecond: { "720p": { quality: 17 }, "1080p": { quality: 29 } },
|
|
45147
45155
|
seconds: { min: 5, max: 20 }
|
|
45156
|
+
},
|
|
45157
|
+
// BytePlus bills a clip's tokens (width × height × frames / 1024, at 24 fps plus a frame); credits take each resolution's largest shape.
|
|
45158
|
+
{
|
|
45159
|
+
id: "byteplus/seedance-2.5",
|
|
45160
|
+
label: "Seedance 2.5 (BytePlus)",
|
|
45161
|
+
provider: "byteplus",
|
|
45162
|
+
providerModel: "dreamina-seedance-2-5-260628",
|
|
45163
|
+
workflows: SEEDANCE_WORKFLOWS,
|
|
45164
|
+
resolutions: ["480p", "720p"],
|
|
45165
|
+
workflowOptions: { "reference-to-video": { ...SEEDANCE_REFERENCES, mediaSeconds: 30 } },
|
|
45166
|
+
modes: ["quality"],
|
|
45167
|
+
lastFrame: true,
|
|
45168
|
+
estimatedCreditsPerSecond: { "480p": { quality: 10.86 }, "720p": { quality: 23.51 } },
|
|
45169
|
+
seconds: { min: 4, max: 30 }
|
|
45170
|
+
},
|
|
45171
|
+
{
|
|
45172
|
+
id: "byteplus/seedance-2.0",
|
|
45173
|
+
label: "Seedance 2.0 (BytePlus)",
|
|
45174
|
+
provider: "byteplus",
|
|
45175
|
+
providerModel: "dreamina-seedance-2-0-260128",
|
|
45176
|
+
workflows: SEEDANCE_WORKFLOWS,
|
|
45177
|
+
resolutions: ["480p", "720p", "1080p"],
|
|
45178
|
+
workflowOptions: { "reference-to-video": { ...SEEDANCE_REFERENCES, audioNeedsImages: true } },
|
|
45179
|
+
modes: ["quality"],
|
|
45180
|
+
lastFrame: true,
|
|
45181
|
+
estimatedCreditsPerSecond: { "480p": { quality: 7.11 }, "720p": { quality: 15.38 }, "1080p": { quality: 38.06 } },
|
|
45182
|
+
seconds: { min: 4, max: 15 }
|
|
45183
|
+
},
|
|
45184
|
+
{
|
|
45185
|
+
id: "byteplus/seedance-2.0-fast",
|
|
45186
|
+
label: "Seedance 2.0 Fast (BytePlus)",
|
|
45187
|
+
provider: "byteplus",
|
|
45188
|
+
providerModel: "dreamina-seedance-2-0-fast-260128",
|
|
45189
|
+
workflows: SEEDANCE_WORKFLOWS,
|
|
45190
|
+
resolutions: ["480p", "720p"],
|
|
45191
|
+
workflowOptions: { "reference-to-video": { ...SEEDANCE_REFERENCES, audioNeedsImages: true } },
|
|
45192
|
+
modes: ["speed"],
|
|
45193
|
+
lastFrame: true,
|
|
45194
|
+
estimatedCreditsPerSecond: { "480p": { speed: 5.69 }, "720p": { speed: 12.3 } },
|
|
45195
|
+
seconds: { min: 4, max: 15 }
|
|
45196
|
+
},
|
|
45197
|
+
{
|
|
45198
|
+
id: "byteplus/seedance-2.0-mini",
|
|
45199
|
+
label: "Seedance 2.0 Mini (BytePlus)",
|
|
45200
|
+
provider: "byteplus",
|
|
45201
|
+
providerModel: "dreamina-seedance-2-0-mini-260615",
|
|
45202
|
+
workflows: SEEDANCE_WORKFLOWS,
|
|
45203
|
+
resolutions: ["480p", "720p"],
|
|
45204
|
+
workflowOptions: { "reference-to-video": { ...SEEDANCE_REFERENCES, audioNeedsImages: true } },
|
|
45205
|
+
modes: ["cost"],
|
|
45206
|
+
lastFrame: true,
|
|
45207
|
+
estimatedCreditsPerSecond: { "480p": { cost: 3.56 }, "720p": { cost: 7.69 } },
|
|
45208
|
+
seconds: { min: 4, max: 15 }
|
|
45148
45209
|
}
|
|
45149
45210
|
];
|
|
45150
45211
|
var SPRITE_VIDEO_MODEL_IDS = SPRITE_VIDEO_MODELS.map((m) => m.id);
|
|
@@ -45273,7 +45334,7 @@ var Client = class {
|
|
|
45273
45334
|
origin;
|
|
45274
45335
|
async request(path, options = {}) {
|
|
45275
45336
|
const token3 = options.authenticated !== false ? await sessionToken(this.origin) : void 0;
|
|
45276
|
-
const generation = options.method === "POST" && /^\/api\/v1\/sprites\/[^/]+\/(jobs|assets|avatars|avatars\/looks|avatars\/[^/]+\/consent)$/.test(path);
|
|
45337
|
+
const generation = options.method === "POST" && /^\/api\/v1\/sprites\/[^/]+\/(jobs|assets|avatars|avatars\/looks|avatars\/videos|avatars\/[^/]+\/consent)$/.test(path);
|
|
45277
45338
|
const idempotency = generation ? { "Idempotency-Key": generationRequestId(path, options.body) } : {};
|
|
45278
45339
|
const response = await fetch(`${this.origin}${path}`, {
|
|
45279
45340
|
method: options.method ?? "GET",
|
|
@@ -46914,6 +46975,130 @@ async function createAnimation(options) {
|
|
|
46914
46975
|
};
|
|
46915
46976
|
}
|
|
46916
46977
|
|
|
46978
|
+
// shared/avatars.ts
|
|
46979
|
+
var AVATAR_OWNERSHIPS = ["public", "private"];
|
|
46980
|
+
var AVATAR_LOOK_TYPES = ["studio_avatar", "digital_twin", "photo_avatar"];
|
|
46981
|
+
var AVATAR_CREATE_TYPES = ["prompt", "photo", "digital_twin"];
|
|
46982
|
+
var AVATAR_ASPECT_RATIOS = ["auto", "16:9", "9:16", "1:1", "4:5", "5:4"];
|
|
46983
|
+
var LOOK_PACK_ASPECT_RATIOS = ["16:9", "9:16"];
|
|
46984
|
+
var AVATAR_LOOK_METHODS = ["look_pack", "template"];
|
|
46985
|
+
var AVATAR_CREDIT_UNITS = { digital_twin: 2130, photo: 1320, prompt: 1320 };
|
|
46986
|
+
var AVATAR_LOOK_CREDIT_UNITS = 1320;
|
|
46987
|
+
var LOOKS_PER_METHOD = { look_pack: 5, template: 2 };
|
|
46988
|
+
var AVATAR_LOOK_TEMPLATES = [
|
|
46989
|
+
{ id: "5a8e6be843ee4321a014946bf62aa322", method: "look_pack", name: "Modern Corporate", variant: "female" },
|
|
46990
|
+
{ id: "5e659e76755d47fd9160a2d7dedce124", method: "look_pack", name: "Modern Corporate", variant: "male" },
|
|
46991
|
+
{ id: "e1650a9029d04ea1a350421c163295fd", method: "look_pack", name: "Stylish Business-Casual", variant: "female" },
|
|
46992
|
+
{ id: "a5f8e0c0cb654c1a83c695629b173af5", method: "look_pack", name: "Stylish Business-Casual", variant: "male" },
|
|
46993
|
+
{ id: "e7b000e2cb0d44f1a2d2f291a38b395a", method: "look_pack", name: "Scandinavian Minimal", variant: "female" },
|
|
46994
|
+
{ id: "9600f78f27bb49d792e1c56ce624b929", method: "look_pack", name: "Scandinavian Minimal", variant: "male" },
|
|
46995
|
+
{ id: "d7ad40ec97d4459a92b33398b57caf4e", method: "look_pack", name: "Cool Tech / Slate", variant: "female" },
|
|
46996
|
+
{ id: "fbd03fc3603a4e3caff594f5743a1733", method: "look_pack", name: "Cool Tech / Slate", variant: "male" },
|
|
46997
|
+
{ id: "14f4070bd5a04eb6b1f82ae087cd0f30", method: "look_pack", name: "Healthcare", variant: "female" },
|
|
46998
|
+
{ id: "ce706bfa8556401e8c4401765102a455", method: "look_pack", name: "Healthcare", variant: "male" },
|
|
46999
|
+
{ id: "b0cae4fbae384ab9ab9a8e73ba504be8", method: "look_pack", name: "Keynote Power Presenter", variant: "female" },
|
|
47000
|
+
{ id: "71e84769162d4f4186563ad9e0fc45b8", method: "look_pack", name: "Keynote Power Presenter", variant: "male" },
|
|
47001
|
+
{ id: "935ea0b7cdde4e6eb5a198a3d666f677", method: "look_pack", name: "Fitness", variant: "female" },
|
|
47002
|
+
{ id: "daeb8b15c92a4acf9ffb437ba5534458", method: "look_pack", name: "Fitness", variant: "male" },
|
|
47003
|
+
{ id: "6f183d726933457c9035fc0aa4e9c0c3", method: "look_pack", name: "Automotive Dealership", variant: "female" },
|
|
47004
|
+
{ id: "8595c78b466c4e51802731229c59b6e7", method: "look_pack", name: "Automotive Dealership", variant: "male" },
|
|
47005
|
+
{ id: "b30c83d99cec48e09c8f5b07ed8aa38c", method: "template", name: "Business Casual", variant: "female" },
|
|
47006
|
+
{ id: "2dc326030e2e4471babcc9eda56131b6", method: "template", name: "Business Casual", variant: "male" },
|
|
47007
|
+
{ id: "00c49daa4eb94386a0c12508043bab17", method: "template", name: "Podcast", variant: "female" },
|
|
47008
|
+
{ id: "0e52ceafe4d5456fb83c1e39899ff76a", method: "template", name: "Podcast", variant: "male" }
|
|
47009
|
+
];
|
|
47010
|
+
var avatarTemplate = (id2) => AVATAR_LOOK_TEMPLATES.find((t) => t.id === id2);
|
|
47011
|
+
var heygenId = external_exports.string().trim().regex(/^(?!\.{1,2}$)[A-Za-z0-9_.-]{1,128}$/, "Use an avatar id returned by AnimaGuru.");
|
|
47012
|
+
var sha = external_exports.string().regex(/^[a-f0-9]{64}$/);
|
|
47013
|
+
var name = external_exports.string().trim().min(1).max(80);
|
|
47014
|
+
var https = external_exports.string().trim().max(2048).url().refine((url3) => url3.startsWith("https://"), "Use an HTTPS URL.");
|
|
47015
|
+
var AVATAR_INLINE_MAX_BYTES = 8 * 1024 * 1024;
|
|
47016
|
+
var AVATAR_PHOTO_TYPES = ["image/png", "image/jpeg", "image/webp"];
|
|
47017
|
+
var AVATAR_FOOTAGE_TYPES = ["video/mp4", "video/quicktime", "video/webm"];
|
|
47018
|
+
var avatarFile = external_exports.discriminatedUnion("type", [
|
|
47019
|
+
external_exports.object({ type: external_exports.literal("file"), sha }),
|
|
47020
|
+
external_exports.object({ type: external_exports.literal("url"), url: https }),
|
|
47021
|
+
external_exports.object({
|
|
47022
|
+
type: external_exports.literal("base64"),
|
|
47023
|
+
mediaType: external_exports.enum([...AVATAR_PHOTO_TYPES, ...AVATAR_FOOTAGE_TYPES]),
|
|
47024
|
+
data: external_exports.string().max(Math.ceil(AVATAR_INLINE_MAX_BYTES / 3) * 4, "Inline files must be at most 8 MB; use a URL or a project file.").regex(/^[A-Za-z0-9+/]+={0,2}$/, "Send the file as standard base64.")
|
|
47025
|
+
})
|
|
47026
|
+
]);
|
|
47027
|
+
var subjectConsent = external_exports.literal(true, { error: "Confirm that the person shown agreed to become an avatar (subjectConsent: true)." });
|
|
47028
|
+
var avatarCreateRequest = external_exports.discriminatedUnion("type", [
|
|
47029
|
+
external_exports.object({
|
|
47030
|
+
type: external_exports.literal("prompt"),
|
|
47031
|
+
name,
|
|
47032
|
+
prompt: external_exports.string().trim().min(3).max(1e3),
|
|
47033
|
+
aspectRatio: external_exports.enum(AVATAR_ASPECT_RATIOS).default("auto"),
|
|
47034
|
+
lookId: heygenId.optional(),
|
|
47035
|
+
groupId: heygenId.optional(),
|
|
47036
|
+
referenceImages: external_exports.array(avatarFile).max(3).default([])
|
|
47037
|
+
}),
|
|
47038
|
+
external_exports.object({ type: external_exports.literal("photo"), name, file: avatarFile, groupId: heygenId.optional(), subjectConsent }),
|
|
47039
|
+
external_exports.object({ type: external_exports.literal("digital_twin"), name, file: avatarFile, groupId: heygenId.optional(), subjectConsent })
|
|
47040
|
+
]).superRefine((p, ctx) => {
|
|
47041
|
+
const files = p.type === "prompt" ? p.referenceImages : [p.file];
|
|
47042
|
+
const footage = p.type === "digital_twin";
|
|
47043
|
+
for (const [index2, file2] of files.entries()) {
|
|
47044
|
+
if (file2.type !== "base64") continue;
|
|
47045
|
+
const allowed = footage ? AVATAR_FOOTAGE_TYPES : AVATAR_PHOTO_TYPES;
|
|
47046
|
+
if (!allowed.includes(file2.mediaType)) ctx.addIssue({ code: "custom", message: footage ? "Send footage as MP4, MOV or WebM." : "Send a PNG, JPEG or WebP image.", path: p.type === "prompt" ? ["referenceImages", index2, "mediaType"] : ["file", "mediaType"] });
|
|
47047
|
+
}
|
|
47048
|
+
});
|
|
47049
|
+
var avatarLooksRequest = external_exports.discriminatedUnion("method", [
|
|
47050
|
+
external_exports.object({ method: external_exports.literal("look_pack"), lookId: heygenId, templateId: heygenId, aspectRatio: external_exports.enum(LOOK_PACK_ASPECT_RATIOS).default("16:9") }),
|
|
47051
|
+
external_exports.object({ method: external_exports.literal("template"), lookId: heygenId, templateId: heygenId })
|
|
47052
|
+
]).superRefine((p, ctx) => {
|
|
47053
|
+
const known = avatarTemplate(p.templateId);
|
|
47054
|
+
if (known && known.method !== p.method) ctx.addIssue({ code: "custom", message: `This template is applied with method ${known.method}.`, path: ["method"] });
|
|
47055
|
+
});
|
|
47056
|
+
var heygenVoiceId = external_exports.string().trim().regex(/^[A-Za-z0-9_.-]{1,128}$/, "Use a HeyGen voice ID.");
|
|
47057
|
+
var avatarGroupUpdate = external_exports.object({ defaultVoiceId: heygenVoiceId });
|
|
47058
|
+
var avatarLookUpdate = external_exports.object({ name: external_exports.string().trim().min(1).max(255) });
|
|
47059
|
+
var avatarConsentRequest = external_exports.object({ rerouteUrl: https.optional() });
|
|
47060
|
+
var limit = external_exports.coerce.number().int().min(1).max(50).default(20);
|
|
47061
|
+
var token = external_exports.string().max(2048).optional();
|
|
47062
|
+
var avatarListQuery = external_exports.object({ ownership: external_exports.enum(AVATAR_OWNERSHIPS).default("public"), limit, token });
|
|
47063
|
+
var avatarLookListQuery = external_exports.object({ groupId: heygenId.optional(), avatarType: external_exports.enum(AVATAR_LOOK_TYPES).optional(), limit, token });
|
|
47064
|
+
var avatarVoiceListQuery = external_exports.object({ ownership: external_exports.enum(AVATAR_OWNERSHIPS).default("public"), language: external_exports.string().trim().min(1).max(40).optional(), gender: external_exports.enum(["male", "female"]).optional(), limit, token });
|
|
47065
|
+
var avatarCreateEstimate = (p) => AVATAR_CREDIT_UNITS[p.type];
|
|
47066
|
+
var avatarLooksEstimate = (p) => LOOKS_PER_METHOD[p.method] * AVATAR_LOOK_CREDIT_UNITS;
|
|
47067
|
+
var AVATAR_VIDEO_MODEL_IDS = ["heygen/avatar-iv", "heygen/avatar-v", "heygen/avatar-iii"];
|
|
47068
|
+
var DEFAULT_AVATAR_VIDEO_MODEL = "heygen/avatar-iv";
|
|
47069
|
+
var AVATAR_VIDEO_RESOLUTIONS = ["720p", "1080p"];
|
|
47070
|
+
var AVATAR_EXPRESSIVENESS = ["low", "medium", "high"];
|
|
47071
|
+
var AVATAR_SCRIPT_MAX = 1500;
|
|
47072
|
+
var AVATAR_VIDEO_MAX_SECONDS = 120;
|
|
47073
|
+
var avatarVideoRequest = external_exports.object({
|
|
47074
|
+
type: external_exports.literal("video"),
|
|
47075
|
+
name,
|
|
47076
|
+
model: external_exports.enum(AVATAR_VIDEO_MODEL_IDS).default(DEFAULT_AVATAR_VIDEO_MODEL),
|
|
47077
|
+
/** A look of this workspace's avatars or of HeyGen's catalog. */
|
|
47078
|
+
lookId: heygenId,
|
|
47079
|
+
/** What the avatar says. */
|
|
47080
|
+
script: external_exports.string().trim().min(1).max(AVATAR_SCRIPT_MAX).optional(),
|
|
47081
|
+
/** Saved speech or music in this project that the avatar lip-syncs instead of a script. */
|
|
47082
|
+
soundtrack: sha.optional(),
|
|
47083
|
+
/** The voice that speaks the script; without it, the look's own voice. */
|
|
47084
|
+
voiceId: heygenVoiceId.optional(),
|
|
47085
|
+
aspectRatio: external_exports.enum(AVATAR_ASPECT_RATIOS).default("auto"),
|
|
47086
|
+
resolution: external_exports.enum(AVATAR_VIDEO_RESOLUTIONS).default("1080p"),
|
|
47087
|
+
/** How the body and hands move: photo avatars on Avatar IV, any look on Avatar V. */
|
|
47088
|
+
motionPrompt: external_exports.string().trim().min(3).max(1e3).optional(),
|
|
47089
|
+
/** How much a photo avatar moves on Avatar IV (low unless set). */
|
|
47090
|
+
expressiveness: external_exports.enum(AVATAR_EXPRESSIVENESS).optional(),
|
|
47091
|
+
/** The clip's length, which the server sets: the audio's, or the script's estimate until the clip is made. */
|
|
47092
|
+
seconds: external_exports.number().positive().max(600).optional()
|
|
47093
|
+
}).superRefine((p, ctx) => {
|
|
47094
|
+
const issue2 = (path, message) => ctx.addIssue({ code: "custom", message, path: [path] });
|
|
47095
|
+
if (p.script && p.soundtrack) issue2("soundtrack", "Give the avatar a script or a saved audio track, not both.");
|
|
47096
|
+
if (!p.script && !p.soundtrack) issue2("script", "Write what the avatar says, or choose saved speech or music for it to lip-sync.");
|
|
47097
|
+
if (p.soundtrack && p.voiceId) issue2("voiceId", "A saved audio track speaks in its own voice; leave out voiceId.");
|
|
47098
|
+
if (p.model === "heygen/avatar-iii" && p.motionPrompt) issue2("motionPrompt", "Avatar III doesn't take a motion prompt; use Avatar IV or Avatar V.");
|
|
47099
|
+
if (p.model !== "heygen/avatar-iv" && p.expressiveness) issue2("expressiveness", "Only Avatar IV takes expressiveness.");
|
|
47100
|
+
});
|
|
47101
|
+
|
|
46917
47102
|
// shared/model-assets.ts
|
|
46918
47103
|
var MODEL_GENERATORS = [
|
|
46919
47104
|
{
|
|
@@ -46983,20 +47168,50 @@ var rigCostUsd = (clips2) => 0.2 + 0.12 * clips2;
|
|
|
46983
47168
|
var modelCostUsd = (p) => generationCostUsd(p) + (p.rig ? rigCostUsd(p.animations.length) : 0);
|
|
46984
47169
|
|
|
46985
47170
|
// shared/assets.ts
|
|
46986
|
-
var ASSET_TYPES = ["image", "vector", "video", "music", "speech", "sfx", "model"];
|
|
47171
|
+
var ASSET_TYPES = ["image", "vector", "gif", "video", "music", "speech", "sfx", "model"];
|
|
46987
47172
|
var SPEECH_MODELS = [
|
|
46988
|
-
{ id: "gemini-3.8-flash-tts", label: "Gemini 3.8 Flash TTS" },
|
|
46989
|
-
{ id: "gemini-3.8-flash-lite-tts", label: "Gemini 3.8 Flash-Lite TTS" },
|
|
46990
|
-
{ id: "eleven_v4", label: "ElevenLabs v4" },
|
|
46991
|
-
{ id: "eleven_v4_turbo", label: "ElevenLabs v4 Turbo" }
|
|
47173
|
+
{ id: "gemini-3.8-flash-tts", label: "Gemini 3.8 Flash TTS", provider: "google" },
|
|
47174
|
+
{ id: "gemini-3.8-flash-lite-tts", label: "Gemini 3.8 Flash-Lite TTS", provider: "google" },
|
|
47175
|
+
{ id: "eleven_v4", label: "ElevenLabs v4", provider: "elevenlabs" },
|
|
47176
|
+
{ id: "eleven_v4_turbo", label: "ElevenLabs v4 Turbo", provider: "elevenlabs" },
|
|
47177
|
+
{ id: "heygen-voice-1", label: "HeyGen Voice 1", provider: "heygen" },
|
|
47178
|
+
{ id: "heygen-voice-1-turbo", label: "HeyGen Voice 1 Turbo", provider: "heygen" }
|
|
46992
47179
|
];
|
|
46993
47180
|
var ELEVENLABS_SPEECH_MODEL_IDS = ["eleven_v4", "eleven_v4_turbo"];
|
|
47181
|
+
var HEYGEN_SPEECH_MODEL_IDS = ["heygen-voice-1", "heygen-voice-1-turbo"];
|
|
46994
47182
|
var SFX_MODELS = [{ id: "eleven_text_to_sound_v2", label: "ElevenLabs Sound Effects v2" }];
|
|
46995
47183
|
var DEFAULT_ELEVENLABS_VOICE = "JBFqnCBsd6RMkjVDRZzb";
|
|
46996
47184
|
var ELEVENLABS_VOICES = [{ id: DEFAULT_ELEVENLABS_VOICE, label: "George" }];
|
|
46997
47185
|
var isElevenLabsSpeech = (model) => ELEVENLABS_SPEECH_MODEL_IDS.includes(model);
|
|
46998
|
-
var
|
|
47186
|
+
var isHeyGenSpeech = (model) => HEYGEN_SPEECH_MODEL_IDS.includes(model);
|
|
47187
|
+
var DEFAULT_HEYGEN_VOICE = "83548de556df48ba8c09c42a57c51d85";
|
|
47188
|
+
var HEYGEN_VOICES = [
|
|
47189
|
+
{ id: DEFAULT_HEYGEN_VOICE, label: "Nadine \xB7 Calm & Gentle" },
|
|
47190
|
+
{ id: "75300849b571414c8d62693289cb6509", label: "Sabrina \xB7 Upbeat & Lively" },
|
|
47191
|
+
{ id: "aa9746e325ff46d482a54fe5bc87890f", label: "Meredith \xB7 Serious & Composed" },
|
|
47192
|
+
{ id: "fe333747c7d04a7188d20a8ea2a222d9", label: "Claire \xB7 Rich & Expressive" },
|
|
47193
|
+
{ id: "7e48c8d406b04a8089c5eb3cd057cb2e", label: "Jonah \xB7 Clear & Professional" },
|
|
47194
|
+
{ id: "826be797681d4b1a92042b54b3c75c64", label: "Gareth \xB7 Conversational & Easygoing" },
|
|
47195
|
+
{ id: "9b71011176ac49ee8d0936c36566d665", label: "Hugh \xB7 Firm & Measured" },
|
|
47196
|
+
{ id: "7bb4df56d7714d33bb88ed1dde8128f6", label: "Rory \xB7 Upbeat & Lively" }
|
|
47197
|
+
];
|
|
46999
47198
|
var SPEECH_VOICES = ["Kore", "Puck", "Charon", "Fenrir", "Aoede", "Leda", "Orus", "Zephyr"];
|
|
47199
|
+
var defaultSpeechVoice = (model) => isElevenLabsSpeech(model) ? DEFAULT_ELEVENLABS_VOICE : isHeyGenSpeech(model) ? DEFAULT_HEYGEN_VOICE : "Kore";
|
|
47200
|
+
var speechVoiceValid = (model, voice) => isElevenLabsSpeech(model) ? /^[a-zA-Z0-9]{20}$/.test(voice) : isHeyGenSpeech(model) ? /^[A-Za-z0-9_]{8,64}$/.test(voice) : SPEECH_VOICES.includes(voice);
|
|
47201
|
+
var MUSIC_MODELS = [
|
|
47202
|
+
{ id: "lyria-3.5", label: "Lyria 3.5", provider: "google" },
|
|
47203
|
+
{ id: "fal/mureka-9.5-song", label: "Mureka 9.5 Song", provider: "fal" },
|
|
47204
|
+
{ id: "fal/mureka-9.5-instrumental", label: "Mureka 9.5 Instrumental", provider: "fal" },
|
|
47205
|
+
{ id: "fal/mureka-9.5-soundtrack", label: "Mureka 9.5 Soundtrack", provider: "fal" }
|
|
47206
|
+
];
|
|
47207
|
+
var MUSIC_MODEL_IDS = ["lyria-3.5", "fal/mureka-9.5-song", "fal/mureka-9.5-instrumental", "fal/mureka-9.5-soundtrack"];
|
|
47208
|
+
var MUREKA_STYLES = ["pop", "rock", "jazz", "r&b", "edm", "ambient", "folk", "latin", "k-pop", "j-pop", "house", "gospel", "lo-fi"];
|
|
47209
|
+
var MUREKA_VOCALS = ["female", "male"];
|
|
47210
|
+
var MAX_SONG_LYRICS = 5e3;
|
|
47211
|
+
var SONG_SECONDS = { min: 120, max: 300 };
|
|
47212
|
+
var SONG_LENGTH = `Choose a length of ${SONG_SECONDS.min}\u2013${SONG_SECONDS.max} whole seconds.`;
|
|
47213
|
+
var SOUNDTRACK_IMAGE_MAX_BYTES = 50 * 1024 * 1024;
|
|
47214
|
+
var SOUNDTRACK_VIDEO_MAX_BYTES = 100 * 1024 * 1024;
|
|
47000
47215
|
var base = { name: external_exports.string().trim().min(1).max(80), prompt: external_exports.string().trim().min(3).max(4e3) };
|
|
47001
47216
|
var blob = external_exports.string().regex(/^[a-f0-9]{64}$/);
|
|
47002
47217
|
var cameraKeyframe = external_exports.object({
|
|
@@ -47197,6 +47412,12 @@ function videoChecks(p, ctx) {
|
|
|
47197
47412
|
if (options?.referencesOnly) {
|
|
47198
47413
|
for (const field of ["reference", "endReference", "middleReference"]) if (p[field]) issue2(field, "This video model's reference-to-video takes references only, without a first, last or middle frame.");
|
|
47199
47414
|
}
|
|
47415
|
+
const kinds = options?.mediaReferences;
|
|
47416
|
+
const files = [["images", "references", references.length], ["videos", "referenceVideos", p.referenceVideos?.length ?? 0], ["audio", "audioReferences", p.audioReferences.length]];
|
|
47417
|
+
if (kinds) {
|
|
47418
|
+
for (const [kind, field, count] of files) if (count && !kinds.includes(kind)) issue2(field, `This video model's reference-to-video takes reference ${kinds.join(" and ")}, not ${kind}.`);
|
|
47419
|
+
}
|
|
47420
|
+
if (options?.audioNeedsImages && p.audioReferences.length && !references.length && !p.referenceVideos?.length) issue2("audioReferences", "This video model needs a reference image beside reference audio.");
|
|
47200
47421
|
if (references.length + (p.referenceVideos?.length ?? 0) + p.audioReferences.length > MAX_REFERENCE_FILES) issue2("references", `reference-to-video takes at most ${MAX_REFERENCE_FILES} reference files in all.`);
|
|
47201
47422
|
const frames = !options?.referencesOnly && (p.reference || p.endReference);
|
|
47202
47423
|
if (!references.length && !p.referenceVideos?.length && !p.audioReferences.length && !frames) issue2("references", `reference-to-video needs reference images, videos or audio${options?.referencesOnly ? "" : ", or a first or last frame"}.`);
|
|
@@ -47230,6 +47451,7 @@ var videoDefaults = (p) => {
|
|
|
47230
47451
|
return { ...p, seconds: p.seconds ?? defaultSeconds(model, p.workflow), resolution: p.resolution ?? videoResolutions(model, p.workflow)[0], mode: p.mode ?? model.modes[0] };
|
|
47231
47452
|
};
|
|
47232
47453
|
var IMAGE_ASPECT_RATIOS = ["1:1", "3:2", "2:3", "16:9", "9:16"];
|
|
47454
|
+
var IMAGE_SIZES = { "1:1": [1024, 1024], "3:2": [1536, 1024], "2:3": [1024, 1536], "16:9": [1536, 864], "9:16": [864, 1536] };
|
|
47233
47455
|
var MAX_IMAGE_REFERENCES = 4;
|
|
47234
47456
|
var MAX_MASK_REGIONS = 8;
|
|
47235
47457
|
var imageReferences = external_exports.array(blob).max(MAX_IMAGE_REFERENCES).refine((shas2) => new Set(shas2).size === shas2.length, "Choose each reference image once.").default([]);
|
|
@@ -47247,10 +47469,13 @@ var imageAsset = external_exports.object({
|
|
|
47247
47469
|
var imageChecks = (p, ctx) => {
|
|
47248
47470
|
if (p.mask && !p.references.length) ctx.addIssue({ code: "custom", message: "A mask edits Image 1; add the image to edit as the first reference.", path: ["mask"] });
|
|
47249
47471
|
};
|
|
47250
|
-
var VECTOR_MODELS = [{ id: "fal/ideogram-vector", label: "Ideogram Vector (fal)" }];
|
|
47472
|
+
var VECTOR_MODELS = [{ id: "fal/ideogram-vector", label: "Ideogram Vector (fal)" }, { id: "fal/gpt-image-2.6-vector", label: "GPT Image 2.6 Vector (fal)" }];
|
|
47473
|
+
var VECTOR_MODEL_IDS = ["fal/ideogram-vector", "fal/gpt-image-2.6-vector"];
|
|
47474
|
+
var GPT_VECTOR_MODEL = "fal/gpt-image-2.6-vector";
|
|
47251
47475
|
var VECTOR_WORKFLOWS = ["text-to-vector", "image-to-vector"];
|
|
47252
47476
|
var VECTOR_QUALITIES = ["low", "medium", "high"];
|
|
47253
47477
|
var VECTOR_ASPECT_RATIOS = ["auto", "1:1", "1:4", "1:3", "1:2", "9:16", "10:16", "2:3", "3:4", "4:5", "5:4", "4:3", "3:2", "16:10", "16:9", "2:1", "3:1", "4:1"];
|
|
47478
|
+
var GPT_VECTOR_ASPECT_RATIOS = VECTOR_ASPECT_RATIOS.filter((ratio) => ratio !== "1:4" && ratio !== "4:1");
|
|
47254
47479
|
var VECTOR_SHAPES = ["detailed", "simple"];
|
|
47255
47480
|
var MAX_VECTOR_REFERENCES = 5;
|
|
47256
47481
|
var VECTOR_REFERENCE_MAX_BYTES = 10 * 1024 * 1024;
|
|
@@ -47260,7 +47485,7 @@ var vectorAsset = external_exports.object({
|
|
|
47260
47485
|
/** Image-to-vector takes no prompt. */
|
|
47261
47486
|
prompt: external_exports.string().trim().max(4e3).default(""),
|
|
47262
47487
|
type: external_exports.literal("vector"),
|
|
47263
|
-
model: external_exports.
|
|
47488
|
+
model: external_exports.enum(VECTOR_MODEL_IDS).default("fal/ideogram-vector"),
|
|
47264
47489
|
workflow: external_exports.enum(VECTOR_WORKFLOWS).default("text-to-vector"),
|
|
47265
47490
|
/** Text-to-vector; defaults to medium. */
|
|
47266
47491
|
quality: external_exports.enum(VECTOR_QUALITIES).optional(),
|
|
@@ -47273,11 +47498,24 @@ var vectorAsset = external_exports.object({
|
|
|
47273
47498
|
/** Image-to-vector; defaults to detailed. */
|
|
47274
47499
|
shapes: external_exports.enum(VECTOR_SHAPES).optional(),
|
|
47275
47500
|
/** Text-to-vector. */
|
|
47276
|
-
seed: external_exports.number().int().min(0).max(2 ** 32 - 1).optional()
|
|
47501
|
+
seed: external_exports.number().int().min(0).max(2 ** 32 - 1).optional(),
|
|
47502
|
+
/** GPT Image 2.6: draw the art alone, without a background (default false). */
|
|
47503
|
+
transparent: external_exports.boolean().optional()
|
|
47277
47504
|
});
|
|
47278
47505
|
function vectorChecks(p, ctx) {
|
|
47279
47506
|
const issue2 = (path, message) => ctx.addIssue({ code: "custom", message, path: [path] });
|
|
47280
47507
|
if (new Set(p.references).size !== p.references.length) issue2("references", "Choose each reference image once.");
|
|
47508
|
+
if (p.model === GPT_VECTOR_MODEL) {
|
|
47509
|
+
if (p.workflow !== "text-to-vector") return issue2("workflow", "GPT Image 2.6 Vector draws from text; trace a saved image with Ideogram Vector (fal/ideogram-vector).");
|
|
47510
|
+
if (p.prompt.length < 3) issue2("prompt", "Describe the vector in at least 3 characters.");
|
|
47511
|
+
if (p.references.length) issue2("references", "GPT Image 2.6 Vector draws from the prompt alone; follow reference images with Ideogram Vector (fal/ideogram-vector).");
|
|
47512
|
+
if (p.source) issue2("source", "Only image-to-vector traces a saved image.");
|
|
47513
|
+
if (p.shapes) issue2("shapes", "Only image-to-vector takes shapes.");
|
|
47514
|
+
if (p.seed !== void 0) issue2("seed", "GPT Image 2.6 Vector doesn't take a seed.");
|
|
47515
|
+
if (p.aspectRatio && !GPT_VECTOR_ASPECT_RATIOS.includes(p.aspectRatio)) issue2("aspectRatio", "GPT Image 2.6 Vector draws between 1:3 and 3:1; choose another aspect ratio.");
|
|
47516
|
+
return;
|
|
47517
|
+
}
|
|
47518
|
+
if (p.transparent !== void 0) issue2("transparent", "Only GPT Image 2.6 Vector (fal/gpt-image-2.6-vector) leaves out the background.");
|
|
47281
47519
|
if (p.workflow === "text-to-vector") {
|
|
47282
47520
|
if (p.prompt.length < 3) issue2("prompt", "Describe the vector in at least 3 characters.");
|
|
47283
47521
|
if (p.source) issue2("source", "Only image-to-vector traces a saved image; use references to guide text-to-vector.");
|
|
@@ -47289,7 +47527,93 @@ function vectorChecks(p, ctx) {
|
|
|
47289
47527
|
for (const field of ["quality", "aspectRatio", "seed"]) if (p[field] !== void 0) issue2(field, `image-to-vector doesn't take ${field === "aspectRatio" ? "an aspect ratio" : field === "seed" ? "a seed" : "a quality"}; the SVG follows the image.`);
|
|
47290
47528
|
if (p.references.length) issue2("references", "image-to-vector traces its source alone and takes no references.");
|
|
47291
47529
|
}
|
|
47292
|
-
var vectorDefaults = (p) => p.workflow === "text-to-vector" ? { ...p, quality: p.quality ?? "medium", aspectRatio: p.aspectRatio ?? "auto" } : { ...p, shapes: p.shapes ?? "detailed" };
|
|
47530
|
+
var vectorDefaults = (p) => p.workflow === "text-to-vector" ? { ...p, quality: p.quality ?? "medium", aspectRatio: p.aspectRatio ?? "auto", ...p.model === GPT_VECTOR_MODEL ? { transparent: p.transparent ?? false } : {} } : { ...p, shapes: p.shapes ?? "detailed" };
|
|
47531
|
+
var GIF_MODELS = [
|
|
47532
|
+
{ id: "fal/gpt-image-2.6-gif", label: "GPT Image 2.6 Flare GIF (fal)" },
|
|
47533
|
+
{ id: "fal/gpt-image-2.6-sunburst-gif", label: "GPT Image 2.6 Sunburst GIF (fal)" }
|
|
47534
|
+
];
|
|
47535
|
+
var GIF_MODEL_IDS = ["fal/gpt-image-2.6-gif", "fal/gpt-image-2.6-sunburst-gif"];
|
|
47536
|
+
var DEFAULT_GIF_MODEL = "fal/gpt-image-2.6-gif";
|
|
47537
|
+
var GIF_QUALITIES = ["low", "medium", "high"];
|
|
47538
|
+
var GIF_FRAMES = { min: 2, max: 16, default: 9 };
|
|
47539
|
+
var GIF_FRAME_MS = { min: 20, max: 2e3, default: 200 };
|
|
47540
|
+
var MAX_GIF_REFERENCES = 4;
|
|
47541
|
+
var GIF_PIXEL_BUDGET = 3840 * 2160;
|
|
47542
|
+
function gifFrameSize(aspectRatio, frames) {
|
|
47543
|
+
const [w, h] = IMAGE_SIZES[aspectRatio];
|
|
47544
|
+
const scale = Math.min(1, Math.sqrt(GIF_PIXEL_BUDGET / Math.max(1, frames) / (w * h)));
|
|
47545
|
+
const width = Math.max(16, Math.floor(w * scale / 16) * 16);
|
|
47546
|
+
return [width, Math.max(16, Math.floor(width * h / w / 16) * 16)];
|
|
47547
|
+
}
|
|
47548
|
+
var gifAsset = external_exports.object({
|
|
47549
|
+
...base,
|
|
47550
|
+
type: external_exports.literal("gif"),
|
|
47551
|
+
model: external_exports.enum(GIF_MODEL_IDS).default(DEFAULT_GIF_MODEL),
|
|
47552
|
+
aspectRatio: external_exports.enum(IMAGE_ASPECT_RATIOS).default("1:1"),
|
|
47553
|
+
frames: external_exports.number().int().min(GIF_FRAMES.min).max(GIF_FRAMES.max).default(GIF_FRAMES.default),
|
|
47554
|
+
/** How long each frame shows, in milliseconds; rounded to 10. */
|
|
47555
|
+
frameMs: external_exports.number().min(GIF_FRAME_MS.min).max(GIF_FRAME_MS.max).default(GIF_FRAME_MS.default),
|
|
47556
|
+
quality: external_exports.enum(GIF_QUALITIES).default("medium"),
|
|
47557
|
+
/** Frames without a background, for a sprite over a scene. */
|
|
47558
|
+
transparent: external_exports.boolean().default(false),
|
|
47559
|
+
/** Saved images or sprite art to animate or follow, named Image 1, Image 2… in the prompt. */
|
|
47560
|
+
references: external_exports.array(blob).max(MAX_GIF_REFERENCES).refine((shas2) => new Set(shas2).size === shas2.length, "Choose each reference image once.").default([])
|
|
47561
|
+
});
|
|
47562
|
+
var gifDefaults = (p) => ({ ...p, frameMs: Math.round(p.frameMs / 10) * 10 });
|
|
47563
|
+
var musicAsset = external_exports.object({
|
|
47564
|
+
name: base.name,
|
|
47565
|
+
/** A soundtrack may leave it out, and so may a song sung from lyrics, where it sets the style. */
|
|
47566
|
+
prompt: external_exports.string().trim().max(4e3).default(""),
|
|
47567
|
+
type: external_exports.literal("music"),
|
|
47568
|
+
model: external_exports.enum(MUSIC_MODEL_IDS).default("lyria-3.5"),
|
|
47569
|
+
/** Mureka Song: the words to sing. */
|
|
47570
|
+
lyrics: external_exports.string().trim().min(1).max(MAX_SONG_LYRICS).optional(),
|
|
47571
|
+
/** Mureka Song written from the prompt: its genres. */
|
|
47572
|
+
styles: external_exports.array(external_exports.enum(MUREKA_STYLES)).min(1).max(MUREKA_STYLES.length).optional(),
|
|
47573
|
+
/** Mureka Song sung from lyrics: who sings. */
|
|
47574
|
+
vocals: external_exports.enum(MUREKA_VOCALS).optional(),
|
|
47575
|
+
/** Mureka Song: about how long, in whole seconds; the model chooses when it's left out. */
|
|
47576
|
+
seconds: external_exports.number().int(SONG_LENGTH).min(SONG_SECONDS.min, SONG_LENGTH).max(SONG_SECONDS.max, SONG_LENGTH).optional(),
|
|
47577
|
+
/** Mureka Soundtrack: the saved image or video to score. */
|
|
47578
|
+
source: blob.optional()
|
|
47579
|
+
});
|
|
47580
|
+
var MUSIC_ONLY = {
|
|
47581
|
+
lyrics: ["fal/mureka-9.5-song", "Only Mureka 9.5 Song sings lyrics."],
|
|
47582
|
+
styles: ["fal/mureka-9.5-song", "Only Mureka 9.5 Song takes styles; describe the genre in the prompt."],
|
|
47583
|
+
vocals: ["fal/mureka-9.5-song", "Only Mureka 9.5 Song takes vocals."],
|
|
47584
|
+
seconds: ["fal/mureka-9.5-song", "Only Mureka 9.5 Song takes a length; the other music models choose their own."],
|
|
47585
|
+
source: ["fal/mureka-9.5-soundtrack", "Only Mureka 9.5 Soundtrack scores a saved image or video."]
|
|
47586
|
+
};
|
|
47587
|
+
function musicChecks(p, ctx) {
|
|
47588
|
+
const issue2 = (path, message) => ctx.addIssue({ code: "custom", message, path: [path] });
|
|
47589
|
+
for (const [field, [model, message]] of Object.entries(MUSIC_ONLY)) if (p[field] !== void 0 && p.model !== model) issue2(field, message);
|
|
47590
|
+
const most = (max2) => {
|
|
47591
|
+
if (p.prompt.length > max2) issue2("prompt", `Describe the music in at most ${max2.toLocaleString("en-US")} characters.`);
|
|
47592
|
+
};
|
|
47593
|
+
if (p.model === "fal/mureka-9.5-song") {
|
|
47594
|
+
if (p.lyrics) {
|
|
47595
|
+
most(1024);
|
|
47596
|
+
if (p.styles) issue2("styles", "A song sung from lyrics takes its style from the prompt; leave out styles.");
|
|
47597
|
+
} else {
|
|
47598
|
+
if (p.prompt.length < 3) issue2("prompt", "Describe the song in at least 3 characters, or give lyrics to sing.");
|
|
47599
|
+
most(2e3);
|
|
47600
|
+
if (p.vocals) issue2("vocals", "Vocals choose who sings lyrics; describe the singer in the prompt instead.");
|
|
47601
|
+
}
|
|
47602
|
+
if (p.styles && new Set(p.styles).size !== p.styles.length) issue2("styles", "Choose each style once.");
|
|
47603
|
+
return;
|
|
47604
|
+
}
|
|
47605
|
+
if (p.model === "fal/mureka-9.5-soundtrack") {
|
|
47606
|
+
if (!p.source) issue2("source", "Choose a saved image or video to score.");
|
|
47607
|
+
return most(1024);
|
|
47608
|
+
}
|
|
47609
|
+
if (p.prompt.length < 3) issue2("prompt", "Describe the music in at least 3 characters.");
|
|
47610
|
+
if (p.model === "fal/mureka-9.5-instrumental") most(1024);
|
|
47611
|
+
}
|
|
47612
|
+
function musicCostUsd(p) {
|
|
47613
|
+
if (p.model === "lyria-3.5") return 0.08;
|
|
47614
|
+
if (p.model === "fal/mureka-9.5-song") return p.lyrics ? 0.15 : 0.5;
|
|
47615
|
+
return p.model === "fal/mureka-9.5-instrumental" ? 0.15 : 0.11;
|
|
47616
|
+
}
|
|
47293
47617
|
var animationClip = external_exports.union([external_exports.enum(MODEL_ANIMATION_IDS), external_exports.number().int().min(0).max(MAX_MESHY_ACTION)]);
|
|
47294
47618
|
var modelAsset = external_exports.object({
|
|
47295
47619
|
name: base.name,
|
|
@@ -47346,24 +47670,31 @@ var modelDefaults = (p) => ({ ...p, animations: p.rig && !p.animations.length ?
|
|
|
47346
47670
|
var assetRequest = external_exports.discriminatedUnion("type", [
|
|
47347
47671
|
imageAsset.superRefine(imageChecks),
|
|
47348
47672
|
videoAsset.superRefine(videoChecks).transform(videoDefaults),
|
|
47349
|
-
|
|
47350
|
-
external_exports.object({ ...base, type: external_exports.literal("speech"), model: external_exports.enum(["gemini-3.8-flash-tts", "gemini-3.8-flash-lite-tts", ...ELEVENLABS_SPEECH_MODEL_IDS]).default("gemini-3.8-flash-lite-tts"), voice: external_exports.string().trim().max(80).default(""), delivery: external_exports.string().trim().max(600).default("") }).superRefine((p, ctx) => {
|
|
47351
|
-
if (p.voice && (
|
|
47673
|
+
musicAsset.superRefine(musicChecks),
|
|
47674
|
+
external_exports.object({ ...base, type: external_exports.literal("speech"), model: external_exports.enum(["gemini-3.8-flash-tts", "gemini-3.8-flash-lite-tts", ...ELEVENLABS_SPEECH_MODEL_IDS, ...HEYGEN_SPEECH_MODEL_IDS]).default("gemini-3.8-flash-lite-tts"), voice: external_exports.string().trim().max(80).default(""), delivery: external_exports.string().trim().max(600).default("") }).superRefine((p, ctx) => {
|
|
47675
|
+
if (p.voice && !speechVoiceValid(p.model, p.voice)) ctx.addIssue({ code: "custom", message: "Choose a voice supported by the speech provider.", path: ["voice"] });
|
|
47352
47676
|
if (isElevenLabsSpeech(p.model) && p.delivery) ctx.addIssue({ code: "custom", message: "ElevenLabs uses audio tags in the transcript; separate delivery instructions are only supported by Gemini.", path: ["delivery"] });
|
|
47353
|
-
|
|
47677
|
+
if (isHeyGenSpeech(p.model) && p.delivery) ctx.addIssue({ code: "custom", message: "HeyGen Voice speaks the transcript as written; separate delivery instructions are only supported by Gemini.", path: ["delivery"] });
|
|
47678
|
+
}).transform((p) => ({ ...p, voice: p.voice || defaultSpeechVoice(p.model) })),
|
|
47354
47679
|
external_exports.object({ ...base, type: external_exports.literal("sfx"), model: external_exports.literal("eleven_text_to_sound_v2").default("eleven_text_to_sound_v2"), seconds: external_exports.number().min(0.5).max(30).default(5), loop: external_exports.boolean().default(false), promptInfluence: external_exports.number().min(0).max(1).default(0.3) }),
|
|
47355
47680
|
vectorAsset.superRefine(vectorChecks).transform(vectorDefaults),
|
|
47356
|
-
modelAsset.superRefine(modelChecks).transform(modelDefaults)
|
|
47681
|
+
modelAsset.superRefine(modelChecks).transform(modelDefaults),
|
|
47682
|
+
gifAsset.transform(gifDefaults)
|
|
47357
47683
|
]);
|
|
47358
47684
|
var assetGenerationRequest = external_exports.discriminatedUnion("type", [imageAsset.omit({ model: true }).superRefine(imageChecks), ...assetRequest.options.slice(1)]);
|
|
47359
47685
|
var LIBRARY_AUDIO_MODEL = "library-audio";
|
|
47360
47686
|
var libraryAudio = external_exports.object({ name: base.name, prompt: external_exports.string().trim().max(4e3).default(""), type: external_exports.enum(["music", "sfx"]), model: external_exports.literal(LIBRARY_AUDIO_MODEL), loop: external_exports.boolean().default(false) });
|
|
47361
47687
|
var UPLOADED_MODEL = "uploaded";
|
|
47362
47688
|
var uploadedMedia = external_exports.object({ name: base.name, prompt: external_exports.string().trim().max(4e3).default(""), type: external_exports.enum(["image", "video"]), model: external_exports.literal(UPLOADED_MODEL) });
|
|
47363
|
-
var savedAssetOptions = external_exports.union([assetRequest, libraryAudio, uploadedMedia]);
|
|
47689
|
+
var savedAssetOptions = external_exports.union([assetRequest, avatarVideoRequest, libraryAudio, uploadedMedia]);
|
|
47364
47690
|
var speechCharacters = (text2) => Array.from(text2).length;
|
|
47365
47691
|
var imageEstimate = (p) => Math.ceil((130 + 40 * p.references.length) * spriteImageModel(p.model).relCost);
|
|
47366
|
-
var vectorEstimate = (p) => p.workflow === "image-to-vector" ? 100 : p.quality === "low" ? 130 : p.quality === "high" ? p.references.length ? 320 : 200 : 160;
|
|
47692
|
+
var vectorEstimate = (p) => p.model === GPT_VECTOR_MODEL ? p.quality === "low" ? 80 : p.quality === "high" ? 220 : 120 : p.workflow === "image-to-vector" ? 100 : p.quality === "low" ? 130 : p.quality === "high" ? p.references.length ? 320 : 200 : 160;
|
|
47693
|
+
var GIF_UNITS_PER_MEGAPIXEL = { low: 13, medium: 39, high: 130 };
|
|
47694
|
+
function gifEstimate(p) {
|
|
47695
|
+
const [w, h] = gifFrameSize(p.aspectRatio, p.frames);
|
|
47696
|
+
return Math.ceil(p.frames * (w * h) / (1024 * 1024) * GIF_UNITS_PER_MEGAPIXEL[p.quality] + 12 * p.references.length);
|
|
47697
|
+
}
|
|
47367
47698
|
function videoExtras(p, facts = {}) {
|
|
47368
47699
|
const w = p.workflow;
|
|
47369
47700
|
if (spriteVideoModel(p.model).provider === "heygen") {
|
|
@@ -47383,11 +47714,13 @@ var modelEstimate = (p) => Math.max(1, Math.ceil(modelCostUsd(p) / 1e-3));
|
|
|
47383
47714
|
function assetEstimate(p, now = Date.now()) {
|
|
47384
47715
|
if (p.type === "image") return imageEstimate(p);
|
|
47385
47716
|
if (p.type === "vector") return vectorEstimate(p);
|
|
47717
|
+
if (p.type === "gif") return gifEstimate(p);
|
|
47386
47718
|
if (p.type === "model") return modelEstimate(p);
|
|
47387
47719
|
if (p.type === "video") return spriteVideoEstimate(spriteVideoModel(p.model), p, videoExtras(p));
|
|
47388
|
-
if (p.type === "music") return
|
|
47720
|
+
if (p.type === "music") return Math.ceil(musicCostUsd(p) / 1e-3);
|
|
47389
47721
|
const units = (credits) => Math.max(1, Math.ceil(credits * UNITS_PER_CREDIT));
|
|
47390
47722
|
if (p.type === "sfx") return units(Math.max(0, p.seconds) * 0.2);
|
|
47723
|
+
if (isHeyGenSpeech(p.model)) return units(speechCharacters(p.prompt) * (p.model === "heygen-voice-1-turbo" ? 0.4 : 1.5) / 1e3);
|
|
47391
47724
|
if (isElevenLabsSpeech(p.model)) {
|
|
47392
47725
|
const promotion2 = now < Date.UTC(2026, 9, 13);
|
|
47393
47726
|
const perThousandCharacters = p.model === "eleven_v4_turbo" ? promotion2 ? 1.1 : 4 : promotion2 ? 2.2 : 8;
|
|
@@ -47411,7 +47744,7 @@ var VIDEO_PART_BYTES = 8 * 1024 * 1024;
|
|
|
47411
47744
|
var VIDEO_MAX_BYTES = { html5: 64 * 1024 * 1024, mp4: 512 * 1024 * 1024 };
|
|
47412
47745
|
var VIDEO_LIBRARY_BYTES = { user: 2 * 1024 ** 3, team: 10 * 1024 ** 3 };
|
|
47413
47746
|
var VIDEO_VISIBILITIES = ["private", "public"];
|
|
47414
|
-
var VIDEO_SHARING_AGREEMENT_VERSION = "2026-
|
|
47747
|
+
var VIDEO_SHARING_AGREEMENT_VERSION = "2026-11-02";
|
|
47415
47748
|
var videoAgreementAcceptance = external_exports.object({
|
|
47416
47749
|
version: external_exports.literal(VIDEO_SHARING_AGREEMENT_VERSION),
|
|
47417
47750
|
language: external_exports.enum(["en", "tr"])
|
|
@@ -48067,7 +48400,7 @@ ${entries.join(",\n")}
|
|
|
48067
48400
|
}}
|
|
48068
48401
|
`;
|
|
48069
48402
|
}
|
|
48070
|
-
async function
|
|
48403
|
+
async function token2(context, access4) {
|
|
48071
48404
|
const result = await context.client.request(`/api/v1/cloud/${context.link.projectId}/token`, { method: "POST", body: { access: access4 } });
|
|
48072
48405
|
const remote = new URL(result.remote);
|
|
48073
48406
|
if (remote.protocol !== "https:" && !(remote.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(remote.hostname))) throw new Error("The server returned an unsafe cloud remote.");
|
|
@@ -48234,7 +48567,7 @@ async function cloudStatus(options) {
|
|
|
48234
48567
|
await saveState(context);
|
|
48235
48568
|
let cloud = null;
|
|
48236
48569
|
if (!options.offline) {
|
|
48237
|
-
const latest = await fetchLatest(context, await
|
|
48570
|
+
const latest = await fetchLatest(context, await token2(context, "read"));
|
|
48238
48571
|
cloud = { latest, newer: Boolean(latest && latest !== context.state.base) };
|
|
48239
48572
|
}
|
|
48240
48573
|
return {
|
|
@@ -48252,7 +48585,7 @@ async function cloudStatus(options) {
|
|
|
48252
48585
|
async function pushCloud(options) {
|
|
48253
48586
|
const context = await openContext(options.dir, options);
|
|
48254
48587
|
return withLock(context.root, async () => {
|
|
48255
|
-
const remote = await
|
|
48588
|
+
const remote = await token2(context, "write");
|
|
48256
48589
|
const latest = await fetchLatest(context, remote);
|
|
48257
48590
|
if (latest && latest !== context.state.base) throw new Error(`The project's animations have a newer version (${short(latest)}). Run animaguru cloud pull, then push again.`);
|
|
48258
48591
|
const { files: scanned, skipped, tooLarge } = await scanFiles(context.root);
|
|
@@ -48310,7 +48643,7 @@ function defaultMessage(diff) {
|
|
|
48310
48643
|
async function pullCloud(options) {
|
|
48311
48644
|
const context = await openContext(options.dir, options);
|
|
48312
48645
|
return withLock(context.root, async () => {
|
|
48313
|
-
const latest = await fetchLatest(context, await
|
|
48646
|
+
const latest = await fetchLatest(context, await token2(context, "read"));
|
|
48314
48647
|
if (!latest || latest === context.state.base) return { updated: false, version: context.state.base, message: "Already up to date." };
|
|
48315
48648
|
const { files: scanned, tooLarge } = await scanFiles(context.root);
|
|
48316
48649
|
const local = await describeFiles(context, scanned);
|
|
@@ -48361,7 +48694,7 @@ async function restoreCloud(options) {
|
|
|
48361
48694
|
const context = await openContext(options.dir, options);
|
|
48362
48695
|
return withLock(context.root, async () => {
|
|
48363
48696
|
if (!/^[a-f0-9]{4,40}$/.test(options.version)) throw new Error("Pass a version ID from animaguru cloud versions.");
|
|
48364
|
-
await fetchLatest(context, await
|
|
48697
|
+
await fetchLatest(context, await token2(context, "read"));
|
|
48365
48698
|
let version4;
|
|
48366
48699
|
try {
|
|
48367
48700
|
version4 = await import_isomorphic_git.default.expandOid({ fs, gitdir: context.gitdir, oid: options.version });
|
|
@@ -48652,18 +48985,20 @@ var extras = {
|
|
|
48652
48985
|
"style",
|
|
48653
48986
|
"damage"
|
|
48654
48987
|
],
|
|
48655
|
-
music: [],
|
|
48988
|
+
music: ["lyrics", "styles", "vocals", "seconds", "source"],
|
|
48656
48989
|
speech: ["voice", "delivery"],
|
|
48657
48990
|
sfx: ["seconds", "loop", "prompt-influence"],
|
|
48658
48991
|
model: ["reference", "texture", "pbr", "faces", "rig", "animations", "height", "splats", "photo", "seed"],
|
|
48659
|
-
vector: ["workflow", "references", "source", "aspect-ratio", "quality", "shapes", "seed"]
|
|
48992
|
+
vector: ["workflow", "references", "source", "aspect-ratio", "quality", "shapes", "seed", "transparent"],
|
|
48993
|
+
gif: ["aspect-ratio", "frames", "frame-ms", "quality", "transparent", "references"]
|
|
48660
48994
|
};
|
|
48995
|
+
var typeName = (type) => type === "gif" ? "GIF" : type;
|
|
48661
48996
|
var list2 = (items) => items.length < 2 ? items.join("") : `${items.slice(0, -1).join(", ")} and ${items.at(-1)}`;
|
|
48662
48997
|
function accepted(type) {
|
|
48663
|
-
if (type === "music") return "Music accepts only --name, --prompt and --model; the model chooses the length, so fit it during the edit.";
|
|
48664
48998
|
const options = extras[type];
|
|
48665
48999
|
if (!options) return "";
|
|
48666
|
-
|
|
49000
|
+
const name2 = typeName(type);
|
|
49001
|
+
return `${name2[0].toUpperCase()}${name2.slice(1)} assets accept ${list2(["--name", "--prompt", "--model", ...options.map((option) => `--${option}`)])}.`;
|
|
48667
49002
|
}
|
|
48668
49003
|
function parseAsset(input2) {
|
|
48669
49004
|
const value = input2 && typeof input2 === "object" && "type" in input2 && input2.type === "image" ? { ...input2, model: void 0 } : input2;
|
|
@@ -48693,9 +49028,10 @@ function assetFromFlags(flags) {
|
|
|
48693
49028
|
for (const name2 of Object.values(extras).flat()) {
|
|
48694
49029
|
const value = flags[name2];
|
|
48695
49030
|
const given2 = value !== void 0 && (value !== false || (name2 === "texture" || name2 === "pbr") && flags.type !== "model");
|
|
48696
|
-
if (given2 && !extras[flags.type]?.includes(name2)) throw new Error(`--${name2} is not an option for ${flags.type} assets. ${accepted(flags.type)}`.trim());
|
|
49031
|
+
if (given2 && !extras[flags.type]?.includes(name2)) throw new Error(`--${name2} is not an option for ${typeName(flags.type)} assets. ${accepted(flags.type)}`.trim());
|
|
48697
49032
|
}
|
|
48698
|
-
|
|
49033
|
+
const promptOptional = flags.type === "video" || flags.type === "vector" || flags.type === "model" && (flags.reference || isSplatGenerator(flags.model ?? "")) || flags.type === "music" && (flags.model === "fal/mureka-9.5-soundtrack" || flags.lyrics !== void 0);
|
|
49034
|
+
if (!promptOptional && flags.prompt === void 0) throw new Error(`--prompt is required for ${typeName(flags.type)} assets${flags.type === "model" ? " unless --reference names an image to build from" : flags.type === "music" ? " unless Mureka 9.5 Song sings --lyrics or Mureka 9.5 Soundtrack scores --source" : ""}.`);
|
|
48699
49035
|
const base2 = { type: flags.type, name: flags.name, prompt: flags.prompt, model: flags.model };
|
|
48700
49036
|
if (flags.type === "image") return parseAsset({ ...base2, aspectRatio: flags["aspect-ratio"], transparent: flags.transparent, references: shas(flags.references), mask: regions(flags.mask) });
|
|
48701
49037
|
if (flags.type === "video") {
|
|
@@ -48733,8 +49069,10 @@ function assetFromFlags(flags) {
|
|
|
48733
49069
|
});
|
|
48734
49070
|
}
|
|
48735
49071
|
if (flags.type === "sfx") return parseAsset({ ...base2, seconds: flags.seconds, loop: flags.loop, promptInfluence: flags["prompt-influence"] });
|
|
49072
|
+
if (flags.type === "music") return parseAsset({ ...base2, lyrics: flags.lyrics, styles: shas(flags.styles), vocals: flags.vocals, seconds: flags.seconds, source: flags.source });
|
|
48736
49073
|
if (flags.type === "model") return parseAsset({ ...base2, reference: flags.reference, texture: flags.texture, pbr: flags.pbr, faces: flags.faces, rig: flags.rig, animations: clips(flags.animations), height: flags.height, splats: flags.splats, photo: flags.photo || void 0, seed: flags.seed });
|
|
48737
|
-
if (flags.type === "vector") return parseAsset({ ...base2, workflow: flags.workflow, quality: flags.quality, aspectRatio: flags["aspect-ratio"], references: shas(flags.references), source: flags.source, shapes: flags.shapes, seed: flags.seed });
|
|
49074
|
+
if (flags.type === "vector") return parseAsset({ ...base2, workflow: flags.workflow, quality: flags.quality, aspectRatio: flags["aspect-ratio"], references: shas(flags.references), source: flags.source, shapes: flags.shapes, seed: flags.seed, transparent: flags.transparent || void 0 });
|
|
49075
|
+
if (flags.type === "gif") return parseAsset({ ...base2, aspectRatio: flags["aspect-ratio"], frames: flags.frames, frameMs: flags["frame-ms"], quality: flags.quality, transparent: flags.transparent, references: shas(flags.references) });
|
|
48738
49076
|
return parseAsset({ ...base2, ...flags.type === "speech" ? { voice: flags.voice, delivery: flags.delivery } : {} });
|
|
48739
49077
|
}
|
|
48740
49078
|
async function assetFromFile(file2, model) {
|
|
@@ -48830,6 +49168,7 @@ var MIME_EXTENSIONS = {
|
|
|
48830
49168
|
"image/png": "png",
|
|
48831
49169
|
"image/jpeg": "jpg",
|
|
48832
49170
|
"image/webp": "webp",
|
|
49171
|
+
"image/gif": "gif",
|
|
48833
49172
|
"image/svg+xml": "svg",
|
|
48834
49173
|
"video/mp4": "mp4",
|
|
48835
49174
|
"video/webm": "webm",
|
|
@@ -48949,96 +49288,6 @@ async function submitAssetBatch(client, project, requests, options, signal) {
|
|
|
48949
49288
|
import { readFile as readFile11, stat as stat6 } from "node:fs/promises";
|
|
48950
49289
|
import { extname } from "node:path";
|
|
48951
49290
|
import { setTimeout as delay4 } from "node:timers/promises";
|
|
48952
|
-
|
|
48953
|
-
// shared/avatars.ts
|
|
48954
|
-
var AVATAR_OWNERSHIPS = ["public", "private"];
|
|
48955
|
-
var AVATAR_LOOK_TYPES = ["studio_avatar", "digital_twin", "photo_avatar"];
|
|
48956
|
-
var AVATAR_CREATE_TYPES = ["prompt", "photo", "digital_twin"];
|
|
48957
|
-
var AVATAR_ASPECT_RATIOS = ["auto", "16:9", "9:16", "1:1", "4:5", "5:4"];
|
|
48958
|
-
var LOOK_PACK_ASPECT_RATIOS = ["16:9", "9:16"];
|
|
48959
|
-
var AVATAR_LOOK_METHODS = ["look_pack", "template"];
|
|
48960
|
-
var AVATAR_CREDIT_UNITS = { digital_twin: 2130, photo: 1320, prompt: 1320 };
|
|
48961
|
-
var AVATAR_LOOK_CREDIT_UNITS = 1320;
|
|
48962
|
-
var LOOKS_PER_METHOD = { look_pack: 5, template: 2 };
|
|
48963
|
-
var AVATAR_LOOK_TEMPLATES = [
|
|
48964
|
-
{ id: "5a8e6be843ee4321a014946bf62aa322", method: "look_pack", name: "Modern Corporate", variant: "female" },
|
|
48965
|
-
{ id: "5e659e76755d47fd9160a2d7dedce124", method: "look_pack", name: "Modern Corporate", variant: "male" },
|
|
48966
|
-
{ id: "e1650a9029d04ea1a350421c163295fd", method: "look_pack", name: "Stylish Business-Casual", variant: "female" },
|
|
48967
|
-
{ id: "a5f8e0c0cb654c1a83c695629b173af5", method: "look_pack", name: "Stylish Business-Casual", variant: "male" },
|
|
48968
|
-
{ id: "e7b000e2cb0d44f1a2d2f291a38b395a", method: "look_pack", name: "Scandinavian Minimal", variant: "female" },
|
|
48969
|
-
{ id: "9600f78f27bb49d792e1c56ce624b929", method: "look_pack", name: "Scandinavian Minimal", variant: "male" },
|
|
48970
|
-
{ id: "d7ad40ec97d4459a92b33398b57caf4e", method: "look_pack", name: "Cool Tech / Slate", variant: "female" },
|
|
48971
|
-
{ id: "fbd03fc3603a4e3caff594f5743a1733", method: "look_pack", name: "Cool Tech / Slate", variant: "male" },
|
|
48972
|
-
{ id: "14f4070bd5a04eb6b1f82ae087cd0f30", method: "look_pack", name: "Healthcare", variant: "female" },
|
|
48973
|
-
{ id: "ce706bfa8556401e8c4401765102a455", method: "look_pack", name: "Healthcare", variant: "male" },
|
|
48974
|
-
{ id: "b0cae4fbae384ab9ab9a8e73ba504be8", method: "look_pack", name: "Keynote Power Presenter", variant: "female" },
|
|
48975
|
-
{ id: "71e84769162d4f4186563ad9e0fc45b8", method: "look_pack", name: "Keynote Power Presenter", variant: "male" },
|
|
48976
|
-
{ id: "935ea0b7cdde4e6eb5a198a3d666f677", method: "look_pack", name: "Fitness", variant: "female" },
|
|
48977
|
-
{ id: "daeb8b15c92a4acf9ffb437ba5534458", method: "look_pack", name: "Fitness", variant: "male" },
|
|
48978
|
-
{ id: "6f183d726933457c9035fc0aa4e9c0c3", method: "look_pack", name: "Automotive Dealership", variant: "female" },
|
|
48979
|
-
{ id: "8595c78b466c4e51802731229c59b6e7", method: "look_pack", name: "Automotive Dealership", variant: "male" },
|
|
48980
|
-
{ id: "b30c83d99cec48e09c8f5b07ed8aa38c", method: "template", name: "Business Casual", variant: "female" },
|
|
48981
|
-
{ id: "2dc326030e2e4471babcc9eda56131b6", method: "template", name: "Business Casual", variant: "male" },
|
|
48982
|
-
{ id: "00c49daa4eb94386a0c12508043bab17", method: "template", name: "Podcast", variant: "female" },
|
|
48983
|
-
{ id: "0e52ceafe4d5456fb83c1e39899ff76a", method: "template", name: "Podcast", variant: "male" }
|
|
48984
|
-
];
|
|
48985
|
-
var avatarTemplate = (id2) => AVATAR_LOOK_TEMPLATES.find((t) => t.id === id2);
|
|
48986
|
-
var heygenId = external_exports.string().trim().regex(/^(?!\.{1,2}$)[A-Za-z0-9_.-]{1,128}$/, "Use an avatar id returned by AnimaGuru.");
|
|
48987
|
-
var sha = external_exports.string().regex(/^[a-f0-9]{64}$/);
|
|
48988
|
-
var name = external_exports.string().trim().min(1).max(80);
|
|
48989
|
-
var https = external_exports.string().trim().max(2048).url().refine((url3) => url3.startsWith("https://"), "Use an HTTPS URL.");
|
|
48990
|
-
var AVATAR_INLINE_MAX_BYTES = 8 * 1024 * 1024;
|
|
48991
|
-
var AVATAR_PHOTO_TYPES = ["image/png", "image/jpeg", "image/webp"];
|
|
48992
|
-
var AVATAR_FOOTAGE_TYPES = ["video/mp4", "video/quicktime", "video/webm"];
|
|
48993
|
-
var avatarFile = external_exports.discriminatedUnion("type", [
|
|
48994
|
-
external_exports.object({ type: external_exports.literal("file"), sha }),
|
|
48995
|
-
external_exports.object({ type: external_exports.literal("url"), url: https }),
|
|
48996
|
-
external_exports.object({
|
|
48997
|
-
type: external_exports.literal("base64"),
|
|
48998
|
-
mediaType: external_exports.enum([...AVATAR_PHOTO_TYPES, ...AVATAR_FOOTAGE_TYPES]),
|
|
48999
|
-
data: external_exports.string().max(Math.ceil(AVATAR_INLINE_MAX_BYTES / 3) * 4, "Inline files must be at most 8 MB; use a URL or a project file.").regex(/^[A-Za-z0-9+/]+={0,2}$/, "Send the file as standard base64.")
|
|
49000
|
-
})
|
|
49001
|
-
]);
|
|
49002
|
-
var subjectConsent = external_exports.literal(true, { error: "Confirm that the person shown agreed to become an avatar (subjectConsent: true)." });
|
|
49003
|
-
var avatarCreateRequest = external_exports.discriminatedUnion("type", [
|
|
49004
|
-
external_exports.object({
|
|
49005
|
-
type: external_exports.literal("prompt"),
|
|
49006
|
-
name,
|
|
49007
|
-
prompt: external_exports.string().trim().min(3).max(1e3),
|
|
49008
|
-
aspectRatio: external_exports.enum(AVATAR_ASPECT_RATIOS).default("auto"),
|
|
49009
|
-
lookId: heygenId.optional(),
|
|
49010
|
-
groupId: heygenId.optional(),
|
|
49011
|
-
referenceImages: external_exports.array(avatarFile).max(3).default([])
|
|
49012
|
-
}),
|
|
49013
|
-
external_exports.object({ type: external_exports.literal("photo"), name, file: avatarFile, groupId: heygenId.optional(), subjectConsent }),
|
|
49014
|
-
external_exports.object({ type: external_exports.literal("digital_twin"), name, file: avatarFile, groupId: heygenId.optional(), subjectConsent })
|
|
49015
|
-
]).superRefine((p, ctx) => {
|
|
49016
|
-
const files = p.type === "prompt" ? p.referenceImages : [p.file];
|
|
49017
|
-
const footage = p.type === "digital_twin";
|
|
49018
|
-
for (const [index2, file2] of files.entries()) {
|
|
49019
|
-
if (file2.type !== "base64") continue;
|
|
49020
|
-
const allowed = footage ? AVATAR_FOOTAGE_TYPES : AVATAR_PHOTO_TYPES;
|
|
49021
|
-
if (!allowed.includes(file2.mediaType)) ctx.addIssue({ code: "custom", message: footage ? "Send footage as MP4, MOV or WebM." : "Send a PNG, JPEG or WebP image.", path: p.type === "prompt" ? ["referenceImages", index2, "mediaType"] : ["file", "mediaType"] });
|
|
49022
|
-
}
|
|
49023
|
-
});
|
|
49024
|
-
var avatarLooksRequest = external_exports.discriminatedUnion("method", [
|
|
49025
|
-
external_exports.object({ method: external_exports.literal("look_pack"), lookId: heygenId, templateId: heygenId, aspectRatio: external_exports.enum(LOOK_PACK_ASPECT_RATIOS).default("16:9") }),
|
|
49026
|
-
external_exports.object({ method: external_exports.literal("template"), lookId: heygenId, templateId: heygenId })
|
|
49027
|
-
]).superRefine((p, ctx) => {
|
|
49028
|
-
const known = avatarTemplate(p.templateId);
|
|
49029
|
-
if (known && known.method !== p.method) ctx.addIssue({ code: "custom", message: `This template is applied with method ${known.method}.`, path: ["method"] });
|
|
49030
|
-
});
|
|
49031
|
-
var avatarGroupUpdate = external_exports.object({ defaultVoiceId: external_exports.string().trim().min(1).max(255) });
|
|
49032
|
-
var avatarLookUpdate = external_exports.object({ name: external_exports.string().trim().min(1).max(255) });
|
|
49033
|
-
var avatarConsentRequest = external_exports.object({ rerouteUrl: https.optional() });
|
|
49034
|
-
var limit = external_exports.coerce.number().int().min(1).max(50).default(20);
|
|
49035
|
-
var token2 = external_exports.string().max(2048).optional();
|
|
49036
|
-
var avatarListQuery = external_exports.object({ ownership: external_exports.enum(AVATAR_OWNERSHIPS).default("public"), limit, token: token2 });
|
|
49037
|
-
var avatarLookListQuery = external_exports.object({ groupId: heygenId.optional(), avatarType: external_exports.enum(AVATAR_LOOK_TYPES).optional(), limit, token: token2 });
|
|
49038
|
-
var avatarCreateEstimate = (p) => AVATAR_CREDIT_UNITS[p.type];
|
|
49039
|
-
var avatarLooksEstimate = (p) => LOOKS_PER_METHOD[p.method] * AVATAR_LOOK_CREDIT_UNITS;
|
|
49040
|
-
|
|
49041
|
-
// cli/src/avatars.ts
|
|
49042
49291
|
var MEDIA_TYPES = { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".webp": "image/webp", ".mp4": "video/mp4", ".mov": "video/quicktime", ".webm": "video/webm" };
|
|
49043
49292
|
var avatarsPath = (project) => `/api/v1/sprites/${encodeURIComponent(project)}/avatars`;
|
|
49044
49293
|
function parse3(schema, input2) {
|
|
@@ -49073,6 +49322,24 @@ function looksFromFlags(flags) {
|
|
|
49073
49322
|
if (flags["aspect-ratio"] && method !== "look_pack") throw new Error("--aspect-ratio applies only to Look Packs.");
|
|
49074
49323
|
return parse3(avatarLooksRequest, { method, lookId: flags.look, templateId: flags.template, aspectRatio: flags["aspect-ratio"] });
|
|
49075
49324
|
}
|
|
49325
|
+
async function avatarVideoFromFlags(flags) {
|
|
49326
|
+
if (flags.script && flags["script-file"]) throw new Error("Pass --script or --script-file, not both.");
|
|
49327
|
+
const script = flags["script-file"] ? (await readFile11(flags["script-file"], "utf8")).trim() : flags.script;
|
|
49328
|
+
if (flags.audio && !/^[a-f0-9]{64}$/.test(flags.audio)) throw new Error("--audio takes the file SHA of saved speech or music from assets list.");
|
|
49329
|
+
return parse3(avatarVideoRequest, {
|
|
49330
|
+
type: "video",
|
|
49331
|
+
name: flags.name,
|
|
49332
|
+
lookId: flags.look,
|
|
49333
|
+
model: flags.model,
|
|
49334
|
+
script,
|
|
49335
|
+
soundtrack: flags.audio,
|
|
49336
|
+
voiceId: flags.voice,
|
|
49337
|
+
aspectRatio: flags["aspect-ratio"],
|
|
49338
|
+
resolution: flags.resolution,
|
|
49339
|
+
motionPrompt: flags["motion-prompt"],
|
|
49340
|
+
expressiveness: flags.expressiveness
|
|
49341
|
+
});
|
|
49342
|
+
}
|
|
49076
49343
|
function authorize(options) {
|
|
49077
49344
|
if (!options.yes) throw new Error("Pass --yes to authorize spending credits, or --dry-run to validate and estimate without creating anything.");
|
|
49078
49345
|
}
|
|
@@ -49086,6 +49353,11 @@ async function submitLooks(client, project, body, options) {
|
|
|
49086
49353
|
authorize(options);
|
|
49087
49354
|
return client.request(`${avatarsPath(project)}/looks`, { method: "POST", body, timeout: 18e4 });
|
|
49088
49355
|
}
|
|
49356
|
+
async function submitAvatarVideo(client, project, body, options) {
|
|
49357
|
+
if (options["dry-run"]) return client.request(`${avatarsPath(project)}/videos/estimate`, { method: "POST", body });
|
|
49358
|
+
authorize(options);
|
|
49359
|
+
return client.request(`${avatarsPath(project)}/videos`, { method: "POST", body });
|
|
49360
|
+
}
|
|
49089
49361
|
async function waitForLook(client, project, lookId, timeout, signal, interval = 1e4) {
|
|
49090
49362
|
if (!Number.isFinite(timeout) || timeout <= 0) throw new Error("Timeout must be positive.");
|
|
49091
49363
|
const deadline = Date.now() + timeout * 1e3;
|
|
@@ -50829,7 +51101,7 @@ async function curl(options, io) {
|
|
|
50829
51101
|
}
|
|
50830
51102
|
|
|
50831
51103
|
// cli/src/commands.ts
|
|
50832
|
-
var assetModelIds = [...SPRITE_VIDEO_MODEL_IDS, ...MUSIC_MODELS.map((m) => m.id), ...SPEECH_MODELS.map((m) => m.id), ...SFX_MODELS.map((m) => m.id), ...VECTOR_MODELS.map((m) => m.id), ...MODEL_GENERATOR_IDS];
|
|
51104
|
+
var assetModelIds = [...SPRITE_VIDEO_MODEL_IDS, ...MUSIC_MODELS.map((m) => m.id), ...SPEECH_MODELS.map((m) => m.id), ...SFX_MODELS.map((m) => m.id), ...VECTOR_MODELS.map((m) => m.id), ...GIF_MODELS.map((m) => m.id), ...MODEL_GENERATOR_IDS];
|
|
50833
51105
|
var assetAuthorizationFlags = [
|
|
50834
51106
|
{ name: "yes", type: "boolean", description: "Authorize spending credits" },
|
|
50835
51107
|
{ name: "dry-run", type: "boolean", description: "Validate and estimate locally without submitting a paid job" }
|
|
@@ -50842,14 +51114,23 @@ var catalogSections = {
|
|
|
50842
51114
|
sprites: ["styles", "kinds", "actions", "videoModels"],
|
|
50843
51115
|
image: ["assetTypes"],
|
|
50844
51116
|
vector: ["assetTypes", "vectorModels", "vectorOptions"],
|
|
51117
|
+
gif: ["assetTypes", "gifModels", "gifOptions"],
|
|
50845
51118
|
video: ["assetTypes", "videoModels", "videoProfiles"],
|
|
50846
|
-
music: ["assetTypes", "musicModels"],
|
|
50847
|
-
speech: ["assetTypes", "speechModels", "voices", "elevenLabsVoices"],
|
|
51119
|
+
music: ["assetTypes", "musicModels", "musicOptions"],
|
|
51120
|
+
speech: ["assetTypes", "speechModels", "voices", "elevenLabsVoices", "heygenVoices"],
|
|
50848
51121
|
sfx: ["assetTypes", "sfxModels"],
|
|
50849
51122
|
model: ["assetTypes", "modelGenerators", "modelAnimations"],
|
|
50850
|
-
avatars: ["avatarTypes", "avatarLookTypes"]
|
|
51123
|
+
avatars: ["avatarTypes", "avatarLookTypes", "avatarVideoModels"]
|
|
51124
|
+
};
|
|
51125
|
+
var gifOptions = {
|
|
51126
|
+
frames: GIF_FRAMES,
|
|
51127
|
+
frameMs: GIF_FRAME_MS,
|
|
51128
|
+
qualities: GIF_QUALITIES,
|
|
51129
|
+
aspectRatios: IMAGE_ASPECT_RATIOS,
|
|
51130
|
+
maxReferences: MAX_GIF_REFERENCES,
|
|
51131
|
+
frameSizes: Object.fromEntries(IMAGE_ASPECT_RATIOS.map((ratio) => [ratio, Object.fromEntries(Array.from({ length: GIF_FRAMES.max - GIF_FRAMES.min + 1 }, (_, i2) => GIF_FRAMES.min + i2).map((frames) => [frames, gifFrameSize(ratio, frames)]))]))
|
|
50851
51132
|
};
|
|
50852
|
-
var catalog = () => ({ styles: SPRITE_STYLES, kinds: SPRITE_KINDS, actions: ALL_SPRITE_ACTIONS, videoModels: SPRITE_VIDEO_MODEL_IDS, assetTypes: ASSET_TYPES, musicModels: MUSIC_MODELS.map((m) => m.id), speechModels: SPEECH_MODELS.map((m) => m.id), sfxModels: SFX_MODELS.map((m) => m.id), modelGenerators: MODEL_GENERATORS.map((g) => ({ id: g.id, label: g.label, output: g.output, ...g.output === "spz" ? { splats: g.splats } : { faces: g.faces } })), modelAnimations: MODEL_ANIMATIONS, vectorModels: VECTOR_MODELS.map((m) => m.id), vectorOptions: { workflows: VECTOR_WORKFLOWS, qualities: VECTOR_QUALITIES, aspectRatios: VECTOR_ASPECT_RATIOS, shapes: VECTOR_SHAPES, maxReferences: MAX_VECTOR_REFERENCES }, elevenLabsVoices: ELEVENLABS_VOICES, voices: SPEECH_VOICES, videoProfiles: SPRITE_VIDEO_MODELS, avatarTypes: AVATAR_CREATE_TYPES, avatarLookTypes: AVATAR_LOOK_TYPES });
|
|
51133
|
+
var catalog = () => ({ styles: SPRITE_STYLES, kinds: SPRITE_KINDS, actions: ALL_SPRITE_ACTIONS, videoModels: SPRITE_VIDEO_MODEL_IDS, assetTypes: ASSET_TYPES, musicModels: MUSIC_MODELS.map((m) => m.id), musicOptions: { styles: MUREKA_STYLES, vocals: MUREKA_VOCALS, songSeconds: SONG_SECONDS, maxLyrics: MAX_SONG_LYRICS }, speechModels: SPEECH_MODELS.map((m) => m.id), sfxModels: SFX_MODELS.map((m) => m.id), modelGenerators: MODEL_GENERATORS.map((g) => ({ id: g.id, label: g.label, output: g.output, ...g.output === "spz" ? { splats: g.splats } : { faces: g.faces } })), modelAnimations: MODEL_ANIMATIONS, vectorModels: VECTOR_MODELS.map((m) => m.id), vectorOptions: { workflows: VECTOR_WORKFLOWS, qualities: VECTOR_QUALITIES, aspectRatios: VECTOR_ASPECT_RATIOS, gptAspectRatios: GPT_VECTOR_ASPECT_RATIOS, shapes: VECTOR_SHAPES, maxReferences: MAX_VECTOR_REFERENCES }, gifModels: GIF_MODELS.map((m) => m.id), gifOptions, elevenLabsVoices: ELEVENLABS_VOICES, heygenVoices: HEYGEN_VOICES, voices: SPEECH_VOICES, videoProfiles: SPRITE_VIDEO_MODELS, avatarTypes: AVATAR_CREATE_TYPES, avatarLookTypes: AVATAR_LOOK_TYPES, avatarVideoModels: AVATAR_VIDEO_MODEL_IDS });
|
|
50853
51134
|
var modelFlags = [
|
|
50854
51135
|
{ name: "video-model", type: "string", choices: SPRITE_VIDEO_MODEL_IDS, description: "Video model override for this operation" }
|
|
50855
51136
|
];
|
|
@@ -51096,7 +51377,7 @@ Confirm code: ${device.user_code}`);
|
|
|
51096
51377
|
})))).add(defineCommand("credits", { description: "Show the selected workspace's remaining credit balance" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" }, description: "Server origin" }).action(async ({ flags, stdout, signal }) => {
|
|
51097
51378
|
const client = new Client(flags.url, signal);
|
|
51098
51379
|
out(stdout, await client.request(`/api/v1/credits${await workspaceQuery(client)}`));
|
|
51099
|
-
}))).add(defineCommand("catalog", { description: "List styles, kinds, actions, asset types, models, video settings, speech voices and avatar types" }, (command) => command.flags({ name: "type", type: "string", choices: Object.keys(catalogSections), description: "Only one part: sprites, image, vector, video, music, speech, sfx, model or avatars" }).action(({ flags, stdout }) => {
|
|
51380
|
+
}))).add(defineCommand("catalog", { description: "List styles, kinds, actions, asset types, models, video settings, speech voices and avatar types" }, (command) => command.flags({ name: "type", type: "string", choices: Object.keys(catalogSections), description: "Only one part: sprites, image, vector, gif, video, music, speech, sfx, model or avatars" }).action(({ flags, stdout }) => {
|
|
51100
51381
|
const full = catalog();
|
|
51101
51382
|
const section = flags.type;
|
|
51102
51383
|
out(stdout, section ? Object.fromEntries(catalogSections[section].map((key) => [key, full[key]])) : full);
|
|
@@ -51167,23 +51448,23 @@ Confirm code: ${device.user_code}`);
|
|
|
51167
51448
|
).action(async ({ args, flags, stdout, signal }) => out(stdout, await moveWork(new Client(flags.url, signal), args.id, flags))))).add(defineCommand("delete", { description: "Delete a project; requires --yes" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" }, description: "Server origin" }).args(id).flags({ name: "yes", type: "boolean", required: true }).action(async ({ args, flags, stdout, signal }) => {
|
|
51168
51449
|
if (!flags.yes) throw new Error("Pass --yes to delete this project.");
|
|
51169
51450
|
out(stdout, await new Client(flags.url, signal).request(`/api/v1/projects/${encodeURIComponent(args.id)}`, { method: "DELETE" }));
|
|
51170
|
-
})))).command("assets", (assets) => assets.add(defineCommand("list", { description: "List saved assets, their blob hashes, and configured generation models" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).action(async ({ args, flags, stdout, signal }) => out(stdout, await new Client(flags.url, signal).request(`${projectPath(args.id)}/assets`))))).add(defineCommand("generate", { description: "Generate an image, vector (SVG), video, music, speech, sound-effect or 3D model asset; --yes authorizes credits" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags(
|
|
51451
|
+
})))).command("assets", (assets) => assets.add(defineCommand("list", { description: "List saved assets, their blob hashes, and configured generation models" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).action(async ({ args, flags, stdout, signal }) => out(stdout, await new Client(flags.url, signal).request(`${projectPath(args.id)}/assets`))))).add(defineCommand("generate", { description: "Generate an image, vector (SVG), animated GIF, video, music, speech, sound-effect or 3D model asset; --yes authorizes credits" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags(
|
|
51171
51452
|
{ name: "type", type: "string", required: true, choices: ASSET_TYPES },
|
|
51172
51453
|
{ name: "name", type: "string", required: true },
|
|
51173
|
-
{ name: "prompt", type: "string", description: "Description to generate, or verbatim transcript for speech; video lip-sync and relight and vector image-to-vector take none, and camera-controls, insert-video, recast
|
|
51174
|
-
{ name: "model", type: "string", choices: assetModelIds, description: "Model for the chosen asset type" },
|
|
51175
|
-
{ name: "aspect-ratio", type: "string", choices: [.../* @__PURE__ */ new Set([...IMAGE_ASPECT_RATIOS, "auto", ...VIDEO_ASPECT_RATIOS, ...VECTOR_ASPECT_RATIOS])], description: "Image: 1:1 (default), 3:2, 2:3, 16:9 or 9:16; a masked edit keeps Image 1's shape. Video from text or a style without --reference: 21:9\u20139:16 (default 16:9). Extension, reference-to-video, relight and keyframes-to-video: auto (default, the inputs' shape) or a ratio to crop to. Vector from text: auto (default, the model's choice) or 1:4\u20134:1" },
|
|
51176
|
-
{ name: "transparent", type: "boolean", description: "Image: transparent background" },
|
|
51177
|
-
{ name: "references", type: "string", description: "Comma-separated blob SHAs of this project's images or sprite art, named Image 1, Image 2\u2026 in the prompt. Image: up to 4 to follow, such as a character sheet. Vector from text: up to 5, the first leading. Video: subjects or looks to keep (reference-to-video and insert-video up to 9, 3d-to-video up to 8), or recast's new people, one photo each (up to 4)" },
|
|
51454
|
+
{ name: "prompt", type: "string", description: "Description to generate, or verbatim transcript for speech; video lip-sync and relight and vector image-to-vector take none, and camera-controls, insert-video, recast, 3d-to-video, a Mureka soundtrack and a song with --lyrics (where it sets the style) may leave it out" },
|
|
51455
|
+
{ name: "model", type: "string", choices: assetModelIds, description: "Model for the chosen asset type. Vector: fal/ideogram-vector (default) or fal/gpt-image-2.6-vector. GIF: fal/gpt-image-2.6-gif (default, Flare, faster) or fal/gpt-image-2.6-sunburst-gif (finer, slower)" },
|
|
51456
|
+
{ name: "aspect-ratio", type: "string", choices: [.../* @__PURE__ */ new Set([...IMAGE_ASPECT_RATIOS, "auto", ...VIDEO_ASPECT_RATIOS, ...VECTOR_ASPECT_RATIOS])], description: "Image: 1:1 (default), 3:2, 2:3, 16:9 or 9:16; a masked edit keeps Image 1's shape. Video from text or a style without --reference: 21:9\u20139:16 (default 16:9). Extension, reference-to-video, relight and keyframes-to-video: auto (default, the inputs' shape) or a ratio to crop to. Vector from text: auto (default, the model's choice) or 1:4\u20134:1 (GPT Image 2.6 1:3\u20133:1). GIF: 1:1 (default), 3:2, 2:3, 16:9 or 9:16" },
|
|
51457
|
+
{ name: "transparent", type: "boolean", description: "Image or GIF: transparent background. Vector with --model fal/gpt-image-2.6-vector: leave out the background" },
|
|
51458
|
+
{ name: "references", type: "string", description: "Comma-separated blob SHAs of this project's images, GIFs (their first frame) or sprite art, named Image 1, Image 2\u2026 in the prompt. Image: up to 4 to follow, such as a character sheet. Vector from text (Ideogram): up to 5, the first leading. GIF: up to 4 to animate or follow. Video: subjects or looks to keep (reference-to-video and insert-video up to 9, 3d-to-video up to 8), or recast's new people, one photo each (up to 4)" },
|
|
51178
51459
|
{ name: "mask", type: "string", description: "Image: edit only these rectangles of Image 1 (the first --references image), as x,y,width,height fractions of its size from the top left, up to 8 separated by semicolons; the rest is kept" },
|
|
51179
|
-
{ name: "workflow", type: "string", choices: [...VIDEO_WORKFLOWS, ...VECTOR_WORKFLOWS], description: "Video: image-to-video (default), text-to-video or extend-video; H3 Max also reference-to-video, lip-sync, camera-controls, insert-video, recast, relight, 3d-to-video and style, FLUX 3 Max keyframes-to-video, HeyGen Video 1 reference-to-video, as the model's videoProfiles allow. Vector: text-to-vector (default) or image-to-vector, which traces --source" },
|
|
51180
|
-
{ name: "reference", type: "string", description: "Video: starting image blob SHA from this project's assets or sprites; the speaking face for lip-sync, the image the camera moves around for camera-controls. Model: the image or sprite art to build it from (image-to-3D); without one the prompt describes it" },
|
|
51460
|
+
{ name: "workflow", type: "string", choices: [...VIDEO_WORKFLOWS, ...VECTOR_WORKFLOWS], description: "Video: image-to-video (default), text-to-video or extend-video; H3 Max also reference-to-video, lip-sync, camera-controls, insert-video, recast, relight, 3d-to-video and style, FLUX 3 Max keyframes-to-video, HeyGen Video 1 and Seedance reference-to-video, as the model's videoProfiles allow. Vector: text-to-vector (default) or image-to-vector, which traces --source" },
|
|
51461
|
+
{ name: "reference", type: "string", description: "Video: starting image blob SHA from this project's assets (a GIF's SHA gives its first frame) or sprites; the speaking face for lip-sync, the image the camera moves around for camera-controls. Model: the image or sprite art to build it from (image-to-3D); without one the prompt describes it" },
|
|
51181
51462
|
{ name: "end-reference", type: "string", description: "Video: ending image blob SHA; models with endFrameOnly accept it without --reference" },
|
|
51182
51463
|
{ name: "middle-reference", type: "string", description: "Reference-to-video: image blob SHA reached at --middle-seconds; needs --reference and --end-reference, 480p or 768p" },
|
|
51183
51464
|
{ name: "middle-seconds", type: "number", description: "Reference-to-video: when the middle image is reached, in seconds" },
|
|
51184
|
-
{ name: "source", type: "string", description: "Blob SHA of a video asset in this project: the clip to extend, insert a scene into, recast or relight, or the 3D render 3d-to-video turns into footage. Vector image-to-vector: the image or sprite art to trace" },
|
|
51465
|
+
{ name: "source", type: "string", description: "Blob SHA of a video asset in this project: the clip to extend, insert a scene into, recast or relight, or the 3D render 3d-to-video turns into footage. Vector image-to-vector: the image, GIF (its first frame) or sprite art to trace. Music with --model fal/mureka-9.5-soundtrack: the video (up to 100 MB), image, GIF still or sprite art to score; a video's soundtrack runs as long as the video" },
|
|
51185
51466
|
{ name: "soundtrack", type: "string", description: "Video from an image or text: blob SHA of a music, speech or SFX asset pinned as the soundtrack (2 s or longer). Lip-sync: the speech to say (5 s\u201315 min), which sets the length" },
|
|
51186
|
-
{ name: "audio-references", type: "string", description: "Extension or reference-to-video: up to 3 comma-separated audio asset blob SHAs (on fal 2\u201315 s each, 15 s total) guiding the sound; refer to them as Audio 1, Audio 2\u2026 in the prompt" },
|
|
51467
|
+
{ name: "audio-references", type: "string", description: "Extension or reference-to-video: up to 3 comma-separated audio asset blob SHAs (on fal and Seedance 2\u201315 s each, 15 s total; Seedance 2.5 30 s) guiding the sound; refer to them as Audio 1, Audio 2\u2026 in the prompt" },
|
|
51187
51468
|
{ name: "reference-videos", type: "string", description: "Reference-to-video or insert-video: up to 3 comma-separated video asset blob SHAs (on fal 2\u201315 s each, 15 s total; HeyGen reads the first 5 s of each) guiding motion, named Video 1, Video 2\u2026 in the prompt" },
|
|
51188
51469
|
{ name: "camera", type: "string", description: 'Camera-controls: 2\u201312 keyframes time,azimuth,elevation,distance (time 0\u20131, angles in degrees, elevation \u221290\u201390) separated by semicolons, e.g. "0,0,0,1;1,90,15,1.2"' },
|
|
51189
51470
|
{ name: "keyframes", type: "string", description: 'Keyframes-to-video (FLUX 3 Max): 1\u201310 seconds,image-SHA pairs separated by semicolons, e.g. "0,SHA;2.5,SHA;5,SHA"; each image is reached at its second, on a frame of its own of the 24 fps clip, within --seconds' },
|
|
@@ -51197,14 +51478,17 @@ Confirm code: ${device.user_code}`);
|
|
|
51197
51478
|
{ name: "generated-references", type: "number", description: "3d-to-video without --references: how many reference images it may draw, 1\u20138 (default 2)" },
|
|
51198
51479
|
{ name: "style", type: "string", choices: VIDEO_STYLES, description: "Style workflow: the preset look, at 768p for 5\u201315 whole seconds" },
|
|
51199
51480
|
{ name: "damage", type: "string", choices: VHS_DAMAGE_LEVELS, description: "VHS style: tape damage (fal's default medium)" },
|
|
51200
|
-
{ name: "seconds", type: "number", description: "Video or
|
|
51481
|
+
{ name: "seconds", type: "number", description: "Video, SFX or song duration in seconds (default 5; a Mureka song picks its own); H3 takes fractions (6.5), FLUX 3 Max 5\u201320 whole seconds, HeyGen Video 1 5\u201315 (up to 30 from an image or text with --prompt-expansion balanced or quality), Seedance 4\u201315 whole seconds (2.5 up to 30); extensions add this many seconds, insert-video's scene is 5\u201313; lip-sync, recast, relight and 3d-to-video take their input's length; SFX supports 0.5\u201330; Mureka 9.5 Song 120\u2013300 whole seconds" },
|
|
51201
51482
|
{ name: "resolution", type: "string", choices: VIDEO_RESOLUTIONS, description: "Video resolution supported by the selected model and workflow (default its first)" },
|
|
51202
51483
|
{ name: "mode", type: "string", choices: ["cost", "speed", "quality"], description: "Video generation mode supported by the selected model (default its first)" },
|
|
51203
51484
|
{ name: "prompt-expansion", type: "string", choices: PROMPT_EXPANSION_MODES, description: "Video: how much the model may rewrite the prompt (default disabled); extensions treat any other value as on. FLUX 3 Max always reasons about the prompt: quality thoroughly, any other value lightly. HeyGen Video 1 needs balanced or quality for clips over 15 s" },
|
|
51204
51485
|
{ name: "seed", type: "number", description: "Video, vector from text, or model with --model idol: seed for repeatable results, where the model takes one" },
|
|
51205
51486
|
{ name: "extend-output", type: "string", choices: EXTEND_OUTPUTS, description: "Extension: extended (default, source plus new footage) or continuation (a 1.625 s overlap, then the new footage)" },
|
|
51206
|
-
{ name: "voice", type: "string", description: "Gemini voice name or ElevenLabs voice ID (defaults: Kore / George)" },
|
|
51207
|
-
{ name: "delivery", type: "string", description: "Gemini speech delivery instructions; ElevenLabs uses audio tags in the transcript" },
|
|
51487
|
+
{ name: "voice", type: "string", description: "Gemini voice name, or an ElevenLabs or HeyGen public voice ID (defaults: Kore / George / Nadine; catalog --type speech suggests more)" },
|
|
51488
|
+
{ name: "delivery", type: "string", description: "Gemini speech delivery instructions; ElevenLabs uses audio tags in the transcript, and HeyGen Voice reads it as written" },
|
|
51489
|
+
{ name: "lyrics", type: "string", description: `Music with --model fal/mureka-9.5-song: the words to sing, up to ${MAX_SONG_LYRICS.toLocaleString("en-US")} characters, sections tagged [Verse], [Chorus]\u2026; --prompt then sets the style. A sung song costs 15 credits, one written from the prompt 50` },
|
|
51490
|
+
{ name: "styles", type: "string", description: `Music with --model fal/mureka-9.5-song and no --lyrics: comma-separated genres from ${MUREKA_STYLES.join(", ")}` },
|
|
51491
|
+
{ name: "vocals", type: "string", choices: MUREKA_VOCALS, description: "Music with --model fal/mureka-9.5-song and --lyrics: who sings" },
|
|
51208
51492
|
{ name: "loop", type: "boolean", description: "SFX: create a seamless loop" },
|
|
51209
51493
|
{ name: "texture", type: "boolean", description: "Model: textured (default on); --no-texture makes a plain white model" },
|
|
51210
51494
|
{ name: "pbr", type: "boolean", description: "Model: metallic, roughness and normal maps with the texture (default on); --no-pbr leaves them out" },
|
|
@@ -51215,7 +51499,9 @@ Confirm code: ${device.user_code}`);
|
|
|
51215
51499
|
{ name: "splats", type: "number", description: "Model with --model idol: how many Gaussian splats, 32,768\u20131,048,576 (default 262,144)" },
|
|
51216
51500
|
{ name: "photo", type: "boolean", description: "Model with --model idol: --reference is a camera photo, cropped more loosely than a render or generated image" },
|
|
51217
51501
|
{ name: "prompt-influence", type: "number", description: "SFX: prompt adherence, 0\u20131 (default 0.3)" },
|
|
51218
|
-
{ name: "quality", type: "string", choices: VECTOR_QUALITIES, description: "Vector from text: low (fastest
|
|
51502
|
+
{ name: "quality", type: "string", choices: [.../* @__PURE__ */ new Set([...VECTOR_QUALITIES, ...GIF_QUALITIES])], description: "Vector from text: low (fastest), medium (default) or high; Ideogram 13, 16 or 20 credits (32 at high with --references), GPT Image 2.6 holds 8, 12 or 22 and is charged fal's metered tokens. GIF: low, medium (default) or high detail in every frame" },
|
|
51503
|
+
{ name: "frames", type: "number", description: `GIF: how many frames, ${GIF_FRAMES.min}\u2013${GIF_FRAMES.max} (default ${GIF_FRAMES.default}); all frames share one picture's pixels, so more frames make each smaller (catalog --type gif lists the sizes)` },
|
|
51504
|
+
{ name: "frame-ms", type: "number", description: `GIF: how long each frame shows, ${GIF_FRAME_MS.min}\u2013${GIF_FRAME_MS.max} ms (default ${GIF_FRAME_MS.default}), rounded to 10 ms` },
|
|
51219
51505
|
{ name: "shapes", type: "string", choices: VECTOR_SHAPES, description: "Vector image-to-vector (10 credits): detailed (default) keeps fine detail, simple uses fewer, simpler shapes" },
|
|
51220
51506
|
...assetAuthorizationFlags,
|
|
51221
51507
|
...assetWaitFlags,
|
|
@@ -51236,7 +51522,7 @@ Confirm code: ${device.user_code}`);
|
|
|
51236
51522
|
const result = await submitAssetBatch(new Client(flags.url, signal), args.id, await assetsFromBatchFile(flags.file, flags.model), flags, signal);
|
|
51237
51523
|
out(stdout, result);
|
|
51238
51524
|
if (result.error) throw new Error(result.error);
|
|
51239
|
-
}))).add(defineCommand("download", { description: "Download a saved asset by id; refuses to overwrite" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id, { name: "asset", type: "string", required: true, description: "Asset id from assets list" }).flags({ name: "output", type: "string", required: true }).action(async ({ args, flags, stdout, signal }) => out(stdout, await downloadAsset(new Client(flags.url, signal), args.id, args.asset, flags.output)))))).command("avatars", (avatars) => avatars.add(defineCommand("list", { description: "List HeyGen avatar characters: the public catalog, or --ownership private for this
|
|
51525
|
+
}))).add(defineCommand("download", { description: "Download a saved asset by id; refuses to overwrite" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id, { name: "asset", type: "string", required: true, description: "Asset id from assets list" }).flags({ name: "output", type: "string", required: true }).action(async ({ args, flags, stdout, signal }) => out(stdout, await downloadAsset(new Client(flags.url, signal), args.id, args.asset, flags.output)))))).command("avatars", (avatars) => avatars.add(defineCommand("list", { description: "List HeyGen avatar characters: the public catalog, or --ownership private for this workspace's own, which all its projects share" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags({ name: "ownership", type: "string", choices: AVATAR_OWNERSHIPS, default: "public" }, { name: "limit", type: "number", default: 20, description: "Avatars per page, 1\u201350" }, { name: "token", type: "string", description: "nextToken from the previous page" }).action(async ({ args, flags, stdout, signal }) => out(stdout, await new Client(flags.url, signal).request(`${avatarsPath(args.id)}?${new URLSearchParams({ ownership: flags.ownership, limit: String(flags.limit), ...flags.token ? { token: flags.token } : {} })}`))))).add(defineCommand("looks", { description: "List an avatar's looks with --group, or HeyGen's public looks; a look ID is what HeyGen renders with" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags({ name: "group", type: "string", description: "Avatar group ID: one of this workspace's or a public one" }, { name: "avatar-type", type: "string", choices: AVATAR_LOOK_TYPES }, { name: "limit", type: "number", default: 20, description: "Looks per page, 1\u201350" }, { name: "token", type: "string", description: "nextToken from the previous page" }).action(async ({ args, flags, stdout, signal }) => out(stdout, await new Client(flags.url, signal).request(`${avatarsPath(args.id)}/looks?${new URLSearchParams({ limit: String(flags.limit), ...flags.group ? { groupId: flags.group } : {}, ...flags["avatar-type"] ? { avatarType: flags["avatar-type"] } : {}, ...flags.token ? { token: flags.token } : {} })}`))))).add(defineCommand("get", { description: "Show one avatar group (--group) or look (--look), with status and consent" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags({ name: "group", type: "string" }, { name: "look", type: "string" }).action(async ({ args, flags, stdout, signal }) => {
|
|
51240
51526
|
if (Boolean(flags.group) === Boolean(flags.look)) throw new Error("Pass --group or --look.");
|
|
51241
51527
|
out(stdout, await new Client(flags.url, signal).request(flags.look ? `${avatarsPath(args.id)}/looks/${encodeURIComponent(flags.look)}` : `${avatarsPath(args.id)}/${encodeURIComponent(flags.group)}`));
|
|
51242
51528
|
}))).add(defineCommand("templates", { description: "List HeyGen Look Packs and look templates with their female and male IDs" }, (command) => command.action(({ stdout }) => out(stdout, { templates: AVATAR_LOOK_TEMPLATES })))).add(defineCommand("create", { description: "Create a HeyGen avatar from a prompt, a photo or footage (digital_twin); --yes authorizes credits" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags(
|
|
@@ -51244,19 +51530,32 @@ Confirm code: ${device.user_code}`);
|
|
|
51244
51530
|
{ name: "name", type: "string", required: true },
|
|
51245
51531
|
{ name: "prompt", type: "string", description: "Prompt: the character, wardrobe, setting and light, up to 1000 characters" },
|
|
51246
51532
|
{ name: "aspect-ratio", type: "string", choices: AVATAR_ASPECT_RATIOS, description: "Prompt: image shape (default auto)" },
|
|
51247
|
-
{ name: "look", type: "string", description: "Prompt: one of this
|
|
51533
|
+
{ name: "look", type: "string", description: "Prompt: one of this workspace's looks to put in a new outfit or setting" },
|
|
51248
51534
|
{ name: "reference-images", type: "string", description: "Prompt: up to 3 comma-separated wardrobe or style references (project image SHA, HTTPS URL or local file)" },
|
|
51249
51535
|
{ name: "file", type: "string", description: "Photo or digital_twin: project image/video SHA, HTTPS URL (up to 32 MB) or local file (up to 8 MB)" },
|
|
51250
|
-
{ name: "group", type: "string", description: "Add the result to one of this
|
|
51536
|
+
{ name: "group", type: "string", description: "Add the result to one of this workspace's avatar groups" },
|
|
51251
51537
|
{ name: "subject-consent", type: "boolean", description: "Photo or digital_twin: confirm the person shown agreed to become an avatar" },
|
|
51252
51538
|
...assetAuthorizationFlags
|
|
51253
|
-
).action(async ({ args, flags, stdout, signal }) => out(stdout, await submitAvatar(new Client(flags.url, signal), args.id, await avatarFromFlags(flags), flags))))).add(defineCommand("add-looks", { description: "Apply a Look Pack (five looks) or look template (two) to one of this
|
|
51254
|
-
{ name: "look", type: "string", required: true, description: "Reference look ID from this
|
|
51539
|
+
).action(async ({ args, flags, stdout, signal }) => out(stdout, await submitAvatar(new Client(flags.url, signal), args.id, await avatarFromFlags(flags), flags))))).add(defineCommand("add-looks", { description: "Apply a Look Pack (five looks) or look template (two) to one of this workspace's looks; --yes authorizes credits" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags(
|
|
51540
|
+
{ name: "look", type: "string", required: true, description: "Reference look ID from this workspace's avatars" },
|
|
51255
51541
|
{ name: "template", type: "string", required: true, description: "Template ID from avatars templates" },
|
|
51256
51542
|
{ name: "method", type: "string", choices: AVATAR_LOOK_METHODS, description: "Needed only for templates outside the gallery" },
|
|
51257
51543
|
{ name: "aspect-ratio", type: "string", choices: LOOK_PACK_ASPECT_RATIOS, description: "Look Pack: 16:9 (default) or 9:16, cropped to portrait" },
|
|
51258
51544
|
...assetAuthorizationFlags
|
|
51259
|
-
).action(async ({ args, flags, stdout, signal }) => out(stdout, await submitLooks(new Client(flags.url, signal), args.id, looksFromFlags(flags), flags))))).add(defineCommand("wait", { description: "Wait until HeyGen finishes a new look; fail if it fails or times out" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id, { name: "look", type: "string", required: true, description: "Look ID from avatars create or add-looks" }).flags({ name: "timeout", type: "number", default: 900, description: "Maximum seconds to wait" }).action(async ({ args, flags, stdout, signal }) => out(stdout, await waitForLook(new Client(flags.url, signal), args.id, args.look, flags.timeout, signal))))).add(defineCommand("rename", { description: "Rename one of this
|
|
51545
|
+
).action(async ({ args, flags, stdout, signal }) => out(stdout, await submitLooks(new Client(flags.url, signal), args.id, looksFromFlags(flags), flags))))).add(defineCommand("wait", { description: "Wait until HeyGen finishes a new look; fail if it fails or times out" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id, { name: "look", type: "string", required: true, description: "Look ID from avatars create or add-looks" }).flags({ name: "timeout", type: "number", default: 900, description: "Maximum seconds to wait" }).action(async ({ args, flags, stdout, signal }) => out(stdout, await waitForLook(new Client(flags.url, signal), args.id, args.look, flags.timeout, signal))))).add(defineCommand("rename", { description: "Rename one of this workspace's photo avatar or digital twin looks" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id, { name: "look", type: "string", required: true }).flags({ name: "name", type: "string", required: true }).action(async ({ args, flags, stdout, signal }) => out(stdout, await new Client(flags.url, signal).request(`${avatarsPath(args.id)}/looks/${encodeURIComponent(args.look)}`, { method: "PATCH", body: { name: flags.name } }))))).add(defineCommand("voice", { description: "Set the default voice of one of this workspace's avatars: a public voice or one of its own cloned voices" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id, { name: "group", type: "string", required: true }).flags({ name: "voice", type: "string", required: true, description: "Voice ID from avatars voices" }).action(async ({ args, flags, stdout, signal }) => out(stdout, await new Client(flags.url, signal).request(`${avatarsPath(args.id)}/${encodeURIComponent(args.group)}`, { method: "PATCH", body: { defaultVoiceId: flags.voice } }))))).add(defineCommand("voices", { description: "List voices an avatar can speak with: HeyGen's public library, or --ownership private for those cloned from this workspace's digital twins" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags({ name: "ownership", type: "string", choices: AVATAR_OWNERSHIPS, default: "public" }, { name: "language", type: "string", description: "Public voices in one language, such as English or Turkish" }, { name: "gender", type: "string", choices: ["male", "female"] }, { name: "limit", type: "number", default: 20, description: "Voices per page, 1\u201350" }, { name: "token", type: "string", description: "nextToken from the previous page" }).action(async ({ args, flags, stdout, signal }) => out(stdout, await new Client(flags.url, signal).request(`${avatarsPath(args.id)}/voices?${new URLSearchParams({ ownership: flags.ownership, limit: String(flags.limit), ...flags.language ? { language: flags.language } : {}, ...flags.gender ? { gender: flags.gender } : {}, ...flags.token ? { token: flags.token } : {} })}`))))).add(defineCommand("video", { description: "Make a video of an avatar look speaking a script or lip-syncing saved audio, saved to the project; --yes authorizes credits" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags(
|
|
51546
|
+
{ name: "look", type: "string", required: true, description: "A completed look ID: one of this workspace's avatars or a public one" },
|
|
51547
|
+
{ name: "name", type: "string", required: true, description: "Name of the saved video" },
|
|
51548
|
+
{ name: "script", type: "string", description: `What the avatar says, up to ${AVATAR_SCRIPT_MAX} characters` },
|
|
51549
|
+
{ name: "script-file", type: "string", description: "Read the script from a UTF-8 text file" },
|
|
51550
|
+
{ name: "audio", type: "string", description: `Instead of a script: the file SHA of saved speech or music to lip-sync, up to ${AVATAR_VIDEO_MAX_SECONDS} seconds` },
|
|
51551
|
+
{ name: "voice", type: "string", description: "Voice for the script (avatars voices); the look's own voice by default" },
|
|
51552
|
+
{ name: "model", type: "string", choices: AVATAR_VIDEO_MODEL_IDS, description: "Rendering engine the look supports (default heygen/avatar-iv)" },
|
|
51553
|
+
{ name: "aspect-ratio", type: "string", choices: AVATAR_ASPECT_RATIOS, description: "auto (the look's shape, default), 16:9, 9:16, 1:1, 4:5 or 5:4" },
|
|
51554
|
+
{ name: "resolution", type: "string", choices: AVATAR_VIDEO_RESOLUTIONS, description: "720p or 1080p (default)" },
|
|
51555
|
+
{ name: "motion-prompt", type: "string", description: "Body and hand movement: photo avatars on Avatar IV, any look on Avatar V" },
|
|
51556
|
+
{ name: "expressiveness", type: "string", choices: AVATAR_EXPRESSIVENESS, description: "Photo avatars on Avatar IV: how much they move" },
|
|
51557
|
+
...assetAuthorizationFlags
|
|
51558
|
+
).action(async ({ args, flags, stdout, signal }) => out(stdout, await submitAvatarVideo(new Client(flags.url, signal), args.id, await avatarVideoFromFlags(flags), flags))))).add(defineCommand("consent", { description: "Get a 24-hour link where the person in a digital twin records consent" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id, { name: "group", type: "string", required: true }).flags({ name: "reroute-url", type: "string", description: "HTTPS page to send the person to afterwards" }).action(async ({ args, flags, stdout, signal }) => out(stdout, await new Client(flags.url, signal).request(`${avatarsPath(args.id)}/${encodeURIComponent(args.group)}/consent`, { method: "POST", body: flags["reroute-url"] ? { rerouteUrl: flags["reroute-url"] } : {} }))))).add(defineCommand("delete", { description: "Permanently delete one of this workspace's avatars (--group, with every look and its cloned voice) or one look (--look); requires --yes" }, (command) => command.flags({ name: "url", type: "string", default: "https://animaguru.com", env: { name: "ANIMAGURU_URL" } }).args(id).flags({ name: "group", type: "string" }, { name: "look", type: "string" }, { name: "yes", type: "boolean", required: true }).action(async ({ args, flags, stdout, signal }) => {
|
|
51260
51559
|
if (Boolean(flags.group) === Boolean(flags.look)) throw new Error("Pass --group or --look.");
|
|
51261
51560
|
if (!flags.yes) throw new Error("Pass --yes to delete the avatar for good.");
|
|
51262
51561
|
out(stdout, await new Client(flags.url, signal).request(flags.look ? `${avatarsPath(args.id)}/looks/${encodeURIComponent(flags.look)}` : `${avatarsPath(args.id)}/${encodeURIComponent(flags.group)}`, { method: "DELETE" }));
|