@clipwright/core 0.20.0 → 0.21.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/CHANGELOG.md +41 -0
- package/dist/endpoints.js +2 -0
- package/dist/endpoints.js.map +1 -1
- package/dist/faceless-price.d.ts +21 -0
- package/dist/faceless-price.js +25 -0
- package/dist/faceless-price.js.map +1 -0
- package/dist/faceless-public-plan.d.ts +71 -0
- package/dist/faceless-public-plan.js +166 -0
- package/dist/faceless-public-plan.js.map +1 -0
- package/dist/faceless-public.d.ts +107 -0
- package/dist/faceless-public.js +74 -0
- package/dist/faceless-public.js.map +1 -0
- package/dist/faceless-storyboard-v2-timing.d.ts +11 -0
- package/dist/faceless-storyboard-v2-timing.js +9 -2
- package/dist/faceless-storyboard-v2-timing.js.map +1 -1
- package/dist/idempotency.d.ts +2 -0
- package/dist/idempotency.js +8 -0
- package/dist/idempotency.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/run-static-warnings.js +2 -0
- package/dist/run-static-warnings.js.map +1 -1
- package/dist/runs.d.ts +17 -1
- package/dist/runs.js +3 -1
- package/dist/runs.js.map +1 -1
- package/dist/skills.d.ts +4 -1
- package/dist/skills.js +8 -1
- package/dist/skills.js.map +1 -1
- package/dist/voice-catalog.generated.json +56 -54
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,47 @@ a customer reading it should not miss what appeared in the product. Like *Server
|
|
|
16
16
|
they are live from the day the web app was deployed, not from the package release they are
|
|
17
17
|
listed under.
|
|
18
18
|
|
|
19
|
+
## [0.21.0] - 2026-09-27
|
|
20
|
+
|
|
21
|
+
Faceless videos: an agent can now make a video of up to 90 seconds without an on-camera presenter, from a script or
|
|
22
|
+
from a short brief, and see the price before anything is made.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- `quote_faceless` and `make_faceless` MCP tools, `quoteFaceless` and `startFaceless` in the SDK, and the
|
|
27
|
+
`quote-faceless` and `make-faceless` CLI commands. The video is narration over an opening animated clip and image
|
|
28
|
+
scenes, with captions on by default. `duration_seconds` (30 to 90) is a target: the video ends with its narration
|
|
29
|
+
and runs from 25 seconds to 5 seconds past `duration_seconds`, never past 90. `quote_faceless` is free;
|
|
30
|
+
`make_faceless` returns a `run_id`, and `get_run` reports progress. The MCP server now lists fourteen tools.
|
|
31
|
+
|
|
32
|
+
### Server-side
|
|
33
|
+
|
|
34
|
+
- A faceless run is charged for the video it delivers, by its actual length, and never more than its quote: seconds
|
|
35
|
+
past `duration_seconds` are free. A failed
|
|
36
|
+
run is charged nothing, including one we stop ourselves because a step did not meet our checks. A run held for
|
|
37
|
+
review keeps its credit hold until it is resolved.
|
|
38
|
+
- Captions drop surrounding punctuation, keep accents and other diacritics, and show numbers as written (`$3.50`,
|
|
39
|
+
`10:30`, `1,000`, `50%`, `-20`).
|
|
40
|
+
- With captions on, the script is checked against the caption font before speech is generated; a character the font
|
|
41
|
+
cannot draw fails the run without a customer charge.
|
|
42
|
+
- Narration uses automatic language detection.
|
|
43
|
+
- Pictures change about every three seconds, between spoken words.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- *Server-side* Voice catalog: `cs_female_jana` is now listed with use case `advertisement` (was `narrative_story`);
|
|
48
|
+
the notice period is 4015 days for `en_female_cassidy` (was 730) and 730 days for `fi_male_jaakko` (was 365).
|
|
49
|
+
`es_male_benjamin` is unchanged and remains available.
|
|
50
|
+
|
|
51
|
+
### Known limits
|
|
52
|
+
|
|
53
|
+
- The voice reads some abbreviations literally: write "1.5 million" rather than "1.5M".
|
|
54
|
+
- A generated picture can come out as a collage of two or three panels, and small character details (glasses,
|
|
55
|
+
for instance) can change between pictures.
|
|
56
|
+
- Narration is not loudness-normalized yet, so a video can play quieter than other clips in the same feed.
|
|
57
|
+
- *Server-side* A faceless run can fail when the opening clip shows a pattern our text check mistakes for lettering
|
|
58
|
+
(a chain, for instance). The run is charged nothing; running it again produces a new video.
|
|
59
|
+
|
|
19
60
|
## [0.20.0] - 2026-09-25
|
|
20
61
|
|
|
21
62
|
The MCP server is ready for directories: it has a name in the official MCP
|
package/dist/endpoints.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
/** prints the "what costs money" list from here. */
|
|
3
3
|
import { ACTOR_DEFAULTS_PATH } from "./broll-policy.js";
|
|
4
4
|
export const API_ENDPOINTS = [
|
|
5
|
+
{ method: "POST", path: "/v1/skills/make_faceless/quote", billed: false, onQuickstart: false, jsonBody: true },
|
|
6
|
+
{ method: "POST", path: "/v1/skills/make_faceless/run", billed: true, onQuickstart: false, jsonBody: true },
|
|
5
7
|
{ method: "GET", path: "/health", billed: false, onQuickstart: true, jsonBody: false },
|
|
6
8
|
{ method: "GET", path: "/v1/voices", billed: false, onQuickstart: true, jsonBody: false },
|
|
7
9
|
{ method: "GET", path: "/v1/account", billed: false, onQuickstart: true, jsonBody: false },
|
package/dist/endpoints.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const FACELESS_TARIFF_ID: "faceless-image-i2v-v1";
|
|
3
|
+
/** A faceless video ends with its speech and runs at least 25 s (owner, 2026-09-27). */
|
|
4
|
+
export declare const FACELESS_MIN_OUTPUT_FRAMES = 625;
|
|
5
|
+
/** The pre-speech estimate floor keeps the 4 s offset the 26 s floor had from the former 30 s minimum. */
|
|
6
|
+
export declare const FACELESS_MIN_ESTIMATE_SEC = 21;
|
|
7
|
+
/** A video may run up to 5 s past its selection, never past 90 s; the charge stays within the selection's quote (owner, 2026-09-27). */
|
|
8
|
+
export declare const facelessMaxOutputFrames: (selectedFrames: number) => number;
|
|
9
|
+
export declare const facelessQuote: z.ZodObject<{
|
|
10
|
+
outputFrames: z.ZodNumber;
|
|
11
|
+
baseCredits: z.ZodNumber;
|
|
12
|
+
openerCredits: z.ZodNumber;
|
|
13
|
+
totalCredits: z.ZodNumber;
|
|
14
|
+
tariffId: z.ZodLiteral<"faceless-image-i2v-v1">;
|
|
15
|
+
captions: z.ZodBoolean;
|
|
16
|
+
}, z.core.$strict>;
|
|
17
|
+
export type FacelessQuote = z.infer<typeof facelessQuote>;
|
|
18
|
+
export declare function quoteFaceless(input: {
|
|
19
|
+
outputFrames: number;
|
|
20
|
+
captions: boolean;
|
|
21
|
+
}): FacelessQuote;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const FACELESS_TARIFF_ID = "faceless-image-i2v-v1";
|
|
3
|
+
/** A faceless video ends with its speech and runs at least 25 s (owner, 2026-09-27). */
|
|
4
|
+
export const FACELESS_MIN_OUTPUT_FRAMES = 625;
|
|
5
|
+
/** The pre-speech estimate floor keeps the 4 s offset the 26 s floor had from the former 30 s minimum. */
|
|
6
|
+
export const FACELESS_MIN_ESTIMATE_SEC = 21;
|
|
7
|
+
/** A video may run up to 5 s past its selection, never past 90 s; the charge stays within the selection's quote (owner, 2026-09-27). */
|
|
8
|
+
export const facelessMaxOutputFrames = (selectedFrames) => Math.min(selectedFrames + 125, 2250);
|
|
9
|
+
export const facelessQuote = z.object({
|
|
10
|
+
outputFrames: z.number().int().min(FACELESS_MIN_OUTPUT_FRAMES).max(2250),
|
|
11
|
+
baseCredits: z.number().int().nonnegative(),
|
|
12
|
+
openerCredits: z.number().int().nonnegative(),
|
|
13
|
+
totalCredits: z.number().int().nonnegative(),
|
|
14
|
+
tariffId: z.literal(FACELESS_TARIFF_ID),
|
|
15
|
+
captions: z.boolean(),
|
|
16
|
+
}).strict();
|
|
17
|
+
export function quoteFaceless(input) {
|
|
18
|
+
const outputFrames = z.number().int().min(FACELESS_MIN_OUTPUT_FRAMES).max(2250).parse(input.outputFrames);
|
|
19
|
+
const captions = z.boolean().parse(input.captions);
|
|
20
|
+
const baseCredits = Math.max(200, Math.ceil(180 * outputFrames / 1500));
|
|
21
|
+
const openerCredits = 150;
|
|
22
|
+
return { outputFrames, baseCredits, openerCredits,
|
|
23
|
+
totalCredits: baseCredits + openerCredits, tariffId: FACELESS_TARIFF_ID, captions };
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=faceless-price.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faceless-price.js","sourceRoot":"","sources":["../src/faceless-price.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,kBAAkB,GAAG,uBAAgC,CAAC;AACnE,wFAAwF;AACxF,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAC9C,0GAA0G;AAC1G,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAC5C,wIAAwI;AACxI,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,cAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;AAExG,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IACxE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC3C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC7C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC5C,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC;IACvC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;CACtB,CAAC,CAAC,MAAM,EAAE,CAAC;AAGZ,MAAM,UAAU,aAAa,CAAC,KAAkD;IAC9E,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC1G,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC;IACxE,MAAM,aAAa,GAAG,GAAG,CAAC;IAC1B,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa;QAC/C,YAAY,EAAE,WAAW,GAAG,aAAa,EAAE,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC;AACxF,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type CutStyleProfile } from "./faceless-cut-style.js";
|
|
3
|
+
import { facelessCutScore } from "./faceless-storyboard-v2-timing.js";
|
|
4
|
+
import type { WordTiming } from "./tts-backend.js";
|
|
5
|
+
declare const phrase: z.ZodObject<{
|
|
6
|
+
wordStart: z.ZodNumber;
|
|
7
|
+
wordEnd: z.ZodNumber;
|
|
8
|
+
accentWord: z.ZodNumber;
|
|
9
|
+
}, z.core.$strict>;
|
|
10
|
+
declare const storySchema: z.ZodObject<{
|
|
11
|
+
script: z.ZodString;
|
|
12
|
+
narrationStartFrame: z.ZodNumber;
|
|
13
|
+
beats: z.ZodArray<z.ZodObject<{
|
|
14
|
+
id: z.ZodString;
|
|
15
|
+
wordStart: z.ZodNumber;
|
|
16
|
+
wordEnd: z.ZodNumber;
|
|
17
|
+
mediaType: z.ZodEnum<{
|
|
18
|
+
image: "image";
|
|
19
|
+
video: "video";
|
|
20
|
+
}>;
|
|
21
|
+
reason: z.ZodEnum<{
|
|
22
|
+
action: "action";
|
|
23
|
+
emphasis: "emphasis";
|
|
24
|
+
place: "place";
|
|
25
|
+
reveal: "reveal";
|
|
26
|
+
}>;
|
|
27
|
+
phase: z.ZodEnum<{
|
|
28
|
+
climax: "climax";
|
|
29
|
+
development: "development";
|
|
30
|
+
resolution: "resolution";
|
|
31
|
+
setup: "setup";
|
|
32
|
+
}>;
|
|
33
|
+
visualPrompt: z.ZodString;
|
|
34
|
+
}, z.core.$strict>>;
|
|
35
|
+
captionPhrases: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
36
|
+
wordStart: z.ZodNumber;
|
|
37
|
+
wordEnd: z.ZodNumber;
|
|
38
|
+
accentWord: z.ZodNumber;
|
|
39
|
+
}, z.core.$strict>>>;
|
|
40
|
+
}, z.core.$strict>;
|
|
41
|
+
export type FacelessPublicStory = z.infer<typeof storySchema>;
|
|
42
|
+
export declare function facelessSpeechWordSpans(script: string): Array<{
|
|
43
|
+
word: string;
|
|
44
|
+
start: number;
|
|
45
|
+
end: number;
|
|
46
|
+
}>;
|
|
47
|
+
export declare function facelessSpeechLexicalWords(script: string): string[];
|
|
48
|
+
export declare function parseFacelessPublicStory(input: unknown, expectedScript?: string): FacelessPublicStory;
|
|
49
|
+
type Score = ReturnType<typeof facelessCutScore>;
|
|
50
|
+
export type FacelessPublicPlan = {
|
|
51
|
+
version: "faceless_public_v1";
|
|
52
|
+
outputFrames: number;
|
|
53
|
+
script: string;
|
|
54
|
+
words: WordTiming[];
|
|
55
|
+
narrationStartFrame: number;
|
|
56
|
+
captionPhrases: z.infer<typeof phrase>[];
|
|
57
|
+
shots: Array<{
|
|
58
|
+
id: string;
|
|
59
|
+
mediaType: "video" | "image";
|
|
60
|
+
startFrame: number;
|
|
61
|
+
endFrame: number;
|
|
62
|
+
beatIds: string[];
|
|
63
|
+
visualPrompts: string[];
|
|
64
|
+
phase: FacelessPublicStory["beats"][number]["phase"];
|
|
65
|
+
motion?: "PAN_UP" | "PAN_DOWN";
|
|
66
|
+
cutAfterWord?: number;
|
|
67
|
+
score: Score;
|
|
68
|
+
}>;
|
|
69
|
+
};
|
|
70
|
+
export declare function planPublicFacelessStory(input: FacelessPublicStory, words: readonly WordTiming[], inputStyle: CutStyleProfile, outputFrames: number): FacelessPublicPlan;
|
|
71
|
+
export {};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { FACELESS_MIN_OUTPUT_FRAMES } from "./faceless-price.js";
|
|
3
|
+
import { parseCutStyle } from "./faceless-cut-style.js";
|
|
4
|
+
import { assertStoryboardWords } from "./faceless-storyboard.js";
|
|
5
|
+
import { facelessCutScore } from "./faceless-storyboard-v2-timing.js";
|
|
6
|
+
const index = z.number().int().nonnegative().safe();
|
|
7
|
+
const phrase = z.strictObject({ wordStart: index, wordEnd: index, accentWord: index });
|
|
8
|
+
const storySchema = z.strictObject({
|
|
9
|
+
script: z.string().trim().min(1),
|
|
10
|
+
narrationStartFrame: index.max(125),
|
|
11
|
+
beats: z.array(z.strictObject({
|
|
12
|
+
id: z.string().trim().min(1), wordStart: index, wordEnd: index,
|
|
13
|
+
mediaType: z.enum(["video", "image"]),
|
|
14
|
+
reason: z.enum(["place", "reveal", "action", "emphasis"]),
|
|
15
|
+
phase: z.enum(["setup", "development", "climax", "resolution"]),
|
|
16
|
+
visualPrompt: z.string().trim().min(1),
|
|
17
|
+
})).min(2),
|
|
18
|
+
captionPhrases: z.array(phrase).min(1).optional(),
|
|
19
|
+
});
|
|
20
|
+
const lexicalWordPattern = /[\p{L}\p{N}\p{M}]+(?:['’][\p{L}\p{N}\p{M}]+)*/gu;
|
|
21
|
+
export function facelessSpeechWordSpans(script) {
|
|
22
|
+
const matches = [...script.matchAll(lexicalWordPattern)];
|
|
23
|
+
const normalizedCount = script.normalize("NFKC").match(lexicalWordPattern)?.length ?? 0;
|
|
24
|
+
if (!matches.length || matches.length !== normalizedCount)
|
|
25
|
+
throw new Error("unsupported faceless script word boundaries");
|
|
26
|
+
const compactOffset = Array(script.length + 1).fill(0);
|
|
27
|
+
for (let i = 0; i < script.length; i++)
|
|
28
|
+
compactOffset[i + 1] = compactOffset[i] + (/\s/u.test(script[i]) ? 0 : 1);
|
|
29
|
+
return matches.map((match, index) => {
|
|
30
|
+
const first = index === 0 ? 0 : match.index;
|
|
31
|
+
const last = matches[index + 1]?.index ?? script.length;
|
|
32
|
+
return { word: script.slice(first, last).replace(/\s/gu, ""), start: compactOffset[first], end: compactOffset[last] };
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function facelessSpeechLexicalWords(script) {
|
|
36
|
+
return facelessSpeechWordSpans(script).map(({ word }) => {
|
|
37
|
+
const normalized = word.normalize("NFKC").match(lexicalWordPattern);
|
|
38
|
+
if (normalized?.length !== 1)
|
|
39
|
+
throw new Error("unsupported faceless lexical word");
|
|
40
|
+
return normalized[0].replace(/[’]/gu, "'").normalize("NFD")
|
|
41
|
+
.replace(/\p{M}/gu, "").toLocaleLowerCase("und");
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function parseFacelessPublicStory(input, expectedScript) {
|
|
45
|
+
if (expectedScript !== undefined && (typeof input !== "object" || input === null ||
|
|
46
|
+
input.script !== expectedScript))
|
|
47
|
+
throw new Error("faceless story changed supplied script");
|
|
48
|
+
const story = storySchema.parse(input);
|
|
49
|
+
const wordCount = facelessSpeechWordSpans(story.script).length;
|
|
50
|
+
const phases = ["setup", "development", "climax", "resolution"];
|
|
51
|
+
let nextWord = 0, lastPhase = 0;
|
|
52
|
+
const ids = new Set();
|
|
53
|
+
for (const [index, beat] of story.beats.entries()) {
|
|
54
|
+
const phase = phases.indexOf(beat.phase);
|
|
55
|
+
if (ids.has(beat.id) || beat.wordStart !== nextWord || beat.wordEnd <= beat.wordStart || beat.wordEnd > wordCount ||
|
|
56
|
+
beat.mediaType !== (index === 0 ? "video" : "image") || phase < lastPhase) {
|
|
57
|
+
throw new Error("faceless story beats must cover all words in phase order with one opening video");
|
|
58
|
+
}
|
|
59
|
+
ids.add(beat.id);
|
|
60
|
+
nextWord = beat.wordEnd;
|
|
61
|
+
lastPhase = phase;
|
|
62
|
+
}
|
|
63
|
+
if (nextWord !== wordCount)
|
|
64
|
+
throw new Error("faceless story beats do not cover all words");
|
|
65
|
+
if (story.captionPhrases) {
|
|
66
|
+
let end = 0;
|
|
67
|
+
for (const phrase of story.captionPhrases) {
|
|
68
|
+
if (phrase.wordStart !== end || phrase.wordEnd <= end || phrase.wordEnd > wordCount ||
|
|
69
|
+
phrase.accentWord < end || phrase.accentWord >= phrase.wordEnd)
|
|
70
|
+
throw new Error("invalid faceless caption phrase");
|
|
71
|
+
end = phrase.wordEnd;
|
|
72
|
+
}
|
|
73
|
+
if (end !== wordCount)
|
|
74
|
+
throw new Error("faceless caption phrases do not cover all words");
|
|
75
|
+
}
|
|
76
|
+
return story;
|
|
77
|
+
}
|
|
78
|
+
export function planPublicFacelessStory(input, words, inputStyle, outputFrames) {
|
|
79
|
+
if (!Number.isSafeInteger(outputFrames) || outputFrames < FACELESS_MIN_OUTPUT_FRAMES || outputFrames > 2250) {
|
|
80
|
+
throw new Error("public faceless output must be 625–2250 frames");
|
|
81
|
+
}
|
|
82
|
+
const story = parseFacelessPublicStory(input);
|
|
83
|
+
const style = parseCutStyle(inputStyle);
|
|
84
|
+
assertStoryboardWords(story.script, words);
|
|
85
|
+
const speechEnd = story.narrationStartFrame + words.at(-1).endSec * 25;
|
|
86
|
+
if (speechEnd > outputFrames + 1e-9 || outputFrames - speechEnd > 12.5 + 1e-9 ||
|
|
87
|
+
story.narrationStartFrame + words[0].startSec * 25 > 125)
|
|
88
|
+
throw new Error("speech duration outside public output bounds");
|
|
89
|
+
const phases = { setup: 0, development: 1, climax: 2, resolution: 3 };
|
|
90
|
+
const ids = new Set();
|
|
91
|
+
let nextWord = 0;
|
|
92
|
+
for (const [i, beat] of story.beats.entries()) {
|
|
93
|
+
if (ids.has(beat.id) || beat.wordStart !== nextWord || beat.wordEnd <= beat.wordStart || beat.wordEnd > words.length ||
|
|
94
|
+
beat.mediaType !== (i === 0 ? "video" : "image") ||
|
|
95
|
+
(i > 0 && phases[beat.phase] < phases[story.beats[i - 1].phase])) {
|
|
96
|
+
throw new Error("story beats require unique IDs, ordered phases, complete word coverage and one opening VIDEO");
|
|
97
|
+
}
|
|
98
|
+
nextWord = beat.wordEnd;
|
|
99
|
+
ids.add(beat.id);
|
|
100
|
+
}
|
|
101
|
+
if (nextWord !== words.length)
|
|
102
|
+
throw new Error("story beats must cover every word");
|
|
103
|
+
const captionPhrases = story.captionPhrases ?? story.beats.map(b => ({ wordStart: b.wordStart, wordEnd: b.wordEnd, accentWord: b.wordStart }));
|
|
104
|
+
nextWord = 0;
|
|
105
|
+
for (const p of captionPhrases) {
|
|
106
|
+
if (p.wordStart !== nextWord || p.wordEnd <= p.wordStart || p.wordEnd > words.length ||
|
|
107
|
+
p.accentWord < p.wordStart || p.accentWord >= p.wordEnd)
|
|
108
|
+
throw new Error("caption phrases must partition all words");
|
|
109
|
+
nextWord = p.wordEnd;
|
|
110
|
+
}
|
|
111
|
+
if (nextWord !== words.length)
|
|
112
|
+
throw new Error("caption phrases must cover all words");
|
|
113
|
+
const nodes = story.beats.slice(1).map((beat, i) => {
|
|
114
|
+
const afterWord = beat.wordStart - 1;
|
|
115
|
+
const frame = story.narrationStartFrame + Math.round((words[afterWord].endSec + words[afterWord + 1].startSec) / 2 * 25);
|
|
116
|
+
return { beatIndex: i + 1, afterWord, frame };
|
|
117
|
+
});
|
|
118
|
+
if (nodes[0].frame < 50 || nodes[0].frame > 125)
|
|
119
|
+
throw new Error("mandatory opening VIDEO requires 50–125 frames");
|
|
120
|
+
nodes.push({ beatIndex: story.beats.length, afterWord: words.length - 1, frame: outputFrames });
|
|
121
|
+
const final = nodes.length - 1;
|
|
122
|
+
const states = Array(nodes.length);
|
|
123
|
+
const openerScore = facelessCutScore(story.beats[1].reason, 0, { p25: 0, p75: 0 });
|
|
124
|
+
states[0] = { total: openerScore.net, path: [0], scores: [openerScore] };
|
|
125
|
+
for (let end = 1; end <= final; end++) {
|
|
126
|
+
for (let start = 0; start < end; start++) {
|
|
127
|
+
const prior = states[start];
|
|
128
|
+
const duration = nodes[end].frame - nodes[start].frame;
|
|
129
|
+
if (!prior || duration < 25 || duration > 150)
|
|
130
|
+
continue;
|
|
131
|
+
const phase = story.beats[nodes[start].beatIndex].phase;
|
|
132
|
+
const phaseRange = style.pacing.by_phase[phase];
|
|
133
|
+
const range = phaseRange && phaseRange.n > 0 ? phaseRange : style.pacing.global_image_frames;
|
|
134
|
+
const score = facelessCutScore(end === final ? null : story.beats[nodes[end].beatIndex].reason, duration, range);
|
|
135
|
+
const candidate = { total: prior.total + score.net, path: [...prior.path, end], scores: [...prior.scores, score] };
|
|
136
|
+
const best = states[end];
|
|
137
|
+
const firstDifference = best ? candidate.path.findIndex((v, i) => v !== best.path[i]) : -1;
|
|
138
|
+
if (!best || candidate.total > best.total + 1e-9 || (Math.abs(candidate.total - best.total) <= 1e-9 &&
|
|
139
|
+
(candidate.path.length < best.path.length || (candidate.path.length === best.path.length && firstDifference >= 0 &&
|
|
140
|
+
candidate.path[firstDifference] < best.path[firstDifference]))))
|
|
141
|
+
states[end] = candidate;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const selected = states[final];
|
|
145
|
+
if (!selected)
|
|
146
|
+
throw new Error("no feasible public storyboard within IMAGE duration bounds");
|
|
147
|
+
let startFrame = 0;
|
|
148
|
+
let beatStart = 0;
|
|
149
|
+
const shots = selected.path.map((nodeIndex, i) => {
|
|
150
|
+
const node = nodes[nodeIndex];
|
|
151
|
+
const included = story.beats.slice(beatStart, node.beatIndex);
|
|
152
|
+
const hold = style.motion.pan_transition_n > 0 && style.motion.pan_flip_probability !== null && style.motion.pan_flip_probability < .5;
|
|
153
|
+
const shot = {
|
|
154
|
+
id: included[0].id, mediaType: i ? "image" : "video", startFrame, endFrame: node.frame,
|
|
155
|
+
beatIds: included.map(b => b.id), visualPrompts: included.map(b => b.visualPrompt), phase: included[0].phase,
|
|
156
|
+
...(i ? { motion: hold || i % 2 === 1 ? "PAN_UP" : "PAN_DOWN" } : {}),
|
|
157
|
+
...(nodeIndex < final ? { cutAfterWord: node.afterWord } : {}), score: selected.scores[i],
|
|
158
|
+
};
|
|
159
|
+
startFrame = node.frame;
|
|
160
|
+
beatStart = node.beatIndex;
|
|
161
|
+
return shot;
|
|
162
|
+
});
|
|
163
|
+
return { version: "faceless_public_v1", outputFrames, script: story.script, words: words.map(w => ({ ...w })),
|
|
164
|
+
narrationStartFrame: story.narrationStartFrame, captionPhrases, shots };
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=faceless-public-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faceless-public-plan.js","sourceRoot":"","sources":["../src/faceless-public-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const facelessSceneAnchor: z.ZodUnion<readonly [z.ZodObject<{
|
|
3
|
+
startWord: z.ZodNumber;
|
|
4
|
+
endWord: z.ZodNumber;
|
|
5
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
6
|
+
quote: z.ZodString;
|
|
7
|
+
occurrence: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
}, z.core.$strict>]>;
|
|
9
|
+
export type FacelessSceneAnchor = z.infer<typeof facelessSceneAnchor>;
|
|
10
|
+
export declare const facelessCustomerSceneImage: z.ZodObject<{
|
|
11
|
+
image_url: z.ZodString;
|
|
12
|
+
anchor: z.ZodUnion<readonly [z.ZodObject<{
|
|
13
|
+
startWord: z.ZodNumber;
|
|
14
|
+
endWord: z.ZodNumber;
|
|
15
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
16
|
+
quote: z.ZodString;
|
|
17
|
+
occurrence: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
}, z.core.$strict>]>;
|
|
19
|
+
}, z.core.$strict>;
|
|
20
|
+
export type FacelessCustomerSceneImage = z.infer<typeof facelessCustomerSceneImage>;
|
|
21
|
+
export declare const makeFacelessInput: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
22
|
+
duration_seconds: z.ZodNumber;
|
|
23
|
+
style_reference: z.ZodOptional<z.ZodString>;
|
|
24
|
+
character_reference: z.ZodOptional<z.ZodString>;
|
|
25
|
+
scene_images: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
26
|
+
image_url: z.ZodString;
|
|
27
|
+
anchor: z.ZodUnion<readonly [z.ZodObject<{
|
|
28
|
+
startWord: z.ZodNumber;
|
|
29
|
+
endWord: z.ZodNumber;
|
|
30
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
31
|
+
quote: z.ZodString;
|
|
32
|
+
occurrence: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
}, z.core.$strict>]>;
|
|
34
|
+
}, z.core.$strict>>>;
|
|
35
|
+
captions: z.ZodDefault<z.ZodBoolean>;
|
|
36
|
+
input_mode: z.ZodLiteral<"script">;
|
|
37
|
+
script: z.ZodString;
|
|
38
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
39
|
+
duration_seconds: z.ZodNumber;
|
|
40
|
+
style_reference: z.ZodOptional<z.ZodString>;
|
|
41
|
+
character_reference: z.ZodOptional<z.ZodString>;
|
|
42
|
+
scene_images: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
43
|
+
image_url: z.ZodString;
|
|
44
|
+
anchor: z.ZodUnion<readonly [z.ZodObject<{
|
|
45
|
+
startWord: z.ZodNumber;
|
|
46
|
+
endWord: z.ZodNumber;
|
|
47
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
48
|
+
quote: z.ZodString;
|
|
49
|
+
occurrence: z.ZodOptional<z.ZodNumber>;
|
|
50
|
+
}, z.core.$strict>]>;
|
|
51
|
+
}, z.core.$strict>>>;
|
|
52
|
+
captions: z.ZodDefault<z.ZodBoolean>;
|
|
53
|
+
input_mode: z.ZodLiteral<"brief">;
|
|
54
|
+
brief: z.ZodString;
|
|
55
|
+
}, z.core.$strict>], "input_mode">;
|
|
56
|
+
export type MakeFacelessInput = z.infer<typeof makeFacelessInput>;
|
|
57
|
+
export type MakeFacelessInputArgs = z.input<typeof makeFacelessInput>;
|
|
58
|
+
/** The API routes repeat these paths as literals, and a test keeps them equal. */
|
|
59
|
+
export declare const FACELESS_QUOTE_PATH = "/v1/skills/make_faceless/quote";
|
|
60
|
+
export declare const FACELESS_RUN_PATH = "/v1/skills/make_faceless/run";
|
|
61
|
+
/** Flat form of `makeFacelessInput` for MCP, which needs an object shape, not a union. */
|
|
62
|
+
/** Clients still parse with `makeFacelessInput` before sending, so the union stays the contract. */
|
|
63
|
+
export declare const offeredFacelessInputShape: {
|
|
64
|
+
input_mode: z.ZodEnum<{
|
|
65
|
+
brief: "brief";
|
|
66
|
+
script: "script";
|
|
67
|
+
}>;
|
|
68
|
+
script: z.ZodOptional<z.ZodString>;
|
|
69
|
+
brief: z.ZodOptional<z.ZodString>;
|
|
70
|
+
duration_seconds: z.ZodNumber;
|
|
71
|
+
style_reference: z.ZodOptional<z.ZodString>;
|
|
72
|
+
character_reference: z.ZodOptional<z.ZodString>;
|
|
73
|
+
scene_images: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
74
|
+
image_url: z.ZodString;
|
|
75
|
+
anchor: z.ZodUnion<readonly [z.ZodObject<{
|
|
76
|
+
startWord: z.ZodNumber;
|
|
77
|
+
endWord: z.ZodNumber;
|
|
78
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
79
|
+
quote: z.ZodString;
|
|
80
|
+
occurrence: z.ZodOptional<z.ZodNumber>;
|
|
81
|
+
}, z.core.$strict>]>;
|
|
82
|
+
}, z.core.$strict>>>;
|
|
83
|
+
captions: z.ZodDefault<z.ZodBoolean>;
|
|
84
|
+
};
|
|
85
|
+
export declare const facelessPlannerInput: z.ZodObject<{
|
|
86
|
+
script: z.ZodString;
|
|
87
|
+
outputFrames: z.ZodNumber;
|
|
88
|
+
captions: z.ZodBoolean;
|
|
89
|
+
words: z.ZodArray<z.ZodObject<{
|
|
90
|
+
word: z.ZodString;
|
|
91
|
+
startSec: z.ZodNumber;
|
|
92
|
+
endSec: z.ZodNumber;
|
|
93
|
+
}, z.core.$strict>>;
|
|
94
|
+
}, z.core.$strict>;
|
|
95
|
+
export type FacelessPlannerInput = z.infer<typeof facelessPlannerInput>;
|
|
96
|
+
export declare const facelessQuoteResponse: z.ZodObject<{
|
|
97
|
+
outputFrames: z.ZodNumber;
|
|
98
|
+
baseCredits: z.ZodNumber;
|
|
99
|
+
openerCredits: z.ZodNumber;
|
|
100
|
+
totalCredits: z.ZodNumber;
|
|
101
|
+
tariffId: z.ZodLiteral<"faceless-image-i2v-v1">;
|
|
102
|
+
captions: z.ZodBoolean;
|
|
103
|
+
skill: z.ZodLiteral<"make_faceless">;
|
|
104
|
+
warnings: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
105
|
+
contract_version: z.ZodString;
|
|
106
|
+
}, z.core.$strict>;
|
|
107
|
+
export type FacelessQuoteResponse = z.infer<typeof facelessQuoteResponse>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { uploadResponse } from "./uploads.js";
|
|
3
|
+
import { MAX_URL_LENGTH } from "./skills.js";
|
|
4
|
+
import { FACELESS_MIN_OUTPUT_FRAMES, facelessQuote } from "./faceless-price.js";
|
|
5
|
+
const qualifiedImageUrl = uploadResponse.shape.url.max(MAX_URL_LENGTH).refine((value) => {
|
|
6
|
+
const host = new URL(value).hostname.toLowerCase();
|
|
7
|
+
return host !== "localhost" && !host.endsWith(".localhost") &&
|
|
8
|
+
host !== "127.0.0.1" && host !== "[::1]" &&
|
|
9
|
+
!/^10\.|^192\.168\.|^169\.254\.|^172\.(1[6-9]|2\d|3[01])\./.test(host);
|
|
10
|
+
}, "image must use a qualified public https source");
|
|
11
|
+
export const facelessSceneAnchor = z.union([
|
|
12
|
+
z.object({ startWord: z.number().int().nonnegative(), endWord: z.number().int().positive() })
|
|
13
|
+
.strict().refine((range) => range.endWord > range.startWord),
|
|
14
|
+
z.object({ quote: z.string().trim().min(1).max(500), occurrence: z.number().int().nonnegative().optional() }).strict(),
|
|
15
|
+
]);
|
|
16
|
+
export const facelessCustomerSceneImage = z.object({
|
|
17
|
+
image_url: qualifiedImageUrl,
|
|
18
|
+
anchor: facelessSceneAnchor,
|
|
19
|
+
}).strict();
|
|
20
|
+
const common = {
|
|
21
|
+
duration_seconds: z.number().min(30).max(90).refine((seconds) => Number.isInteger(seconds * 25), "duration_seconds must align to a 25 fps frame boundary"),
|
|
22
|
+
style_reference: qualifiedImageUrl.optional(),
|
|
23
|
+
character_reference: qualifiedImageUrl.optional(),
|
|
24
|
+
scene_images: z.array(facelessCustomerSceneImage).max(30).optional(),
|
|
25
|
+
captions: z.boolean().default(true),
|
|
26
|
+
};
|
|
27
|
+
const scriptInput = z.object({ ...common,
|
|
28
|
+
input_mode: z.literal("script"),
|
|
29
|
+
script: z.string().trim().min(1).max(10_000),
|
|
30
|
+
}).strict();
|
|
31
|
+
const briefInput = z.object({ ...common,
|
|
32
|
+
input_mode: z.literal("brief"),
|
|
33
|
+
brief: z.string().trim().min(1).max(5_000),
|
|
34
|
+
}).strict();
|
|
35
|
+
export const makeFacelessInput = z.discriminatedUnion("input_mode", [scriptInput, briefInput]);
|
|
36
|
+
/** The API routes repeat these paths as literals, and a test keeps them equal. */
|
|
37
|
+
export const FACELESS_QUOTE_PATH = "/v1/skills/make_faceless/quote";
|
|
38
|
+
export const FACELESS_RUN_PATH = "/v1/skills/make_faceless/run";
|
|
39
|
+
/** Flat form of `makeFacelessInput` for MCP, which needs an object shape, not a union. */
|
|
40
|
+
/** Clients still parse with `makeFacelessInput` before sending, so the union stays the contract. */
|
|
41
|
+
export const offeredFacelessInputShape = {
|
|
42
|
+
input_mode: z.enum(["script", "brief"])
|
|
43
|
+
.describe("'script' narrates your exact text; 'brief' writes the narration from a short description. Send exactly one of script or brief, matching this mode."),
|
|
44
|
+
script: scriptInput.shape.script.optional()
|
|
45
|
+
.describe("The narration, read as written. Required when input_mode is 'script'; must be absent when it is 'brief'."),
|
|
46
|
+
brief: briefInput.shape.brief.optional()
|
|
47
|
+
.describe("What the video is about; the narration is written from it. Required when input_mode is 'brief'; must be absent when it is 'script'."),
|
|
48
|
+
duration_seconds: common.duration_seconds
|
|
49
|
+
.describe("Selected length, 30 to 90 seconds, on a 1/25 s frame boundary. The video ends with its narration, runs at least 25 seconds and may exceed the selection by up to 5 seconds, never beyond 90 seconds. The charge never exceeds the quote. A script must fit this output range."),
|
|
50
|
+
style_reference: common.style_reference
|
|
51
|
+
.describe("Optional public https image whose visual style the scenes follow."),
|
|
52
|
+
character_reference: common.character_reference
|
|
53
|
+
.describe("Optional public https image of a person or figure to keep consistent across scenes."),
|
|
54
|
+
scene_images: common.scene_images
|
|
55
|
+
.describe("Optional images of your own, each placed at a word range or quote of the narration."),
|
|
56
|
+
captions: common.captions.describe("Burned-in captions; on by default."),
|
|
57
|
+
};
|
|
58
|
+
const wordTiming = z.object({
|
|
59
|
+
word: z.string().trim().min(1),
|
|
60
|
+
startSec: z.number().nonnegative(),
|
|
61
|
+
endSec: z.number().positive(),
|
|
62
|
+
}).strict().refine((word) => word.endSec > word.startSec);
|
|
63
|
+
export const facelessPlannerInput = z.object({
|
|
64
|
+
script: z.string().trim().min(1),
|
|
65
|
+
outputFrames: z.number().int().min(FACELESS_MIN_OUTPUT_FRAMES).max(2250),
|
|
66
|
+
captions: z.boolean(),
|
|
67
|
+
words: z.array(wordTiming).min(1),
|
|
68
|
+
}).strict();
|
|
69
|
+
export const facelessQuoteResponse = facelessQuote.extend({
|
|
70
|
+
skill: z.literal("make_faceless"),
|
|
71
|
+
warnings: z.array(z.string()).default([]),
|
|
72
|
+
contract_version: z.string().min(1),
|
|
73
|
+
}).strict();
|
|
74
|
+
//# sourceMappingURL=faceless-public.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faceless-public.js","sourceRoot":"","sources":["../src/faceless-public.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,5 +48,16 @@ export type StoryboardV2FramePlan = {
|
|
|
48
48
|
cuts: number;
|
|
49
49
|
};
|
|
50
50
|
};
|
|
51
|
+
declare const semantic: {
|
|
52
|
+
readonly place: 4;
|
|
53
|
+
readonly reveal: 4;
|
|
54
|
+
readonly action: 3;
|
|
55
|
+
readonly emphasis: 1;
|
|
56
|
+
};
|
|
57
|
+
/** Shared semantic objective; duration feasibility belongs to each profile. */
|
|
58
|
+
export declare function facelessCutScore(reason: keyof typeof semantic | null, duration: number, range: {
|
|
59
|
+
p25: number | null;
|
|
60
|
+
p75: number | null;
|
|
61
|
+
}): Score;
|
|
51
62
|
export declare function planStoryboardV2(input: StoryboardV2Proposal, words: readonly WordTiming[], narrationStartFrame: number, style: CutStyleProfile): StoryboardV2FramePlan;
|
|
52
63
|
export {};
|
|
@@ -4,6 +4,14 @@ const semantic = { place: 4, reveal: 4, action: 3, emphasis: 1 };
|
|
|
4
4
|
const CUT_COST = 2;
|
|
5
5
|
const OUTPUT_FRAMES = 1522;
|
|
6
6
|
const FPS = 25;
|
|
7
|
+
/** Shared semantic objective; duration feasibility belongs to each profile. */
|
|
8
|
+
export function facelessCutScore(reason, duration, range) {
|
|
9
|
+
const value = reason === null ? 0 : semantic[reason];
|
|
10
|
+
const cost = reason === null ? 0 : CUT_COST;
|
|
11
|
+
const distance = duration < range.p25 ? range.p25 - duration : duration > range.p75 ? duration - range.p75 : 0;
|
|
12
|
+
const penalty = 0.25 * distance / FPS;
|
|
13
|
+
return { semanticValue: value, cutCost: cost, pacePenalty: penalty, net: value - cost - penalty };
|
|
14
|
+
}
|
|
7
15
|
function better(a, b) {
|
|
8
16
|
if (!b)
|
|
9
17
|
return true;
|
|
@@ -55,8 +63,7 @@ export function planStoryboardV2(input, words, narrationStartFrame, style) {
|
|
|
55
63
|
const phaseRange = style.pacing.by_phase[phase];
|
|
56
64
|
const range = phaseRange && phaseRange.n > 0 ? phaseRange : style.pacing.global_image_frames;
|
|
57
65
|
const duration = nodes[end].frame - nodes[start].frame;
|
|
58
|
-
|
|
59
|
-
return 0.25 * distance / 25;
|
|
66
|
+
return facelessCutScore(null, duration, range).pacePenalty;
|
|
60
67
|
}
|
|
61
68
|
for (let end = 1; end <= final; end++) {
|
|
62
69
|
const destination = nodes[end];
|