@koda-sl/baker-cli 0.120.0-dev.3bcc79f9c → 0.121.0-dev.045b11c52
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 +83 -43
- package/dist/chunk-5WRI5ZAA.js +31 -0
- package/dist/chunk-5WRI5ZAA.js.map +1 -0
- package/dist/chunk-AVJ3B6LC.js +97 -0
- package/dist/chunk-AVJ3B6LC.js.map +1 -0
- package/dist/chunk-ISFSUDEQ.js +264 -0
- package/dist/chunk-ISFSUDEQ.js.map +1 -0
- package/dist/chunk-K47Q73CK.js +156 -0
- package/dist/chunk-K47Q73CK.js.map +1 -0
- package/dist/{chunk-OCMOQOIJ.js → chunk-MWFJ5NOP.js} +132 -273
- package/dist/chunk-MWFJ5NOP.js.map +1 -0
- package/dist/chunk-YTEAWSEM.js +39 -0
- package/dist/chunk-YTEAWSEM.js.map +1 -0
- package/dist/cli.js +4233 -2658
- package/dist/cli.js.map +1 -1
- package/dist/client-PGOTU24X.js +15 -0
- package/dist/client-PGOTU24X.js.map +1 -0
- package/dist/engine/index.d.ts +1 -30
- package/dist/engine/index.js +2 -1
- package/dist/env-TD4VXCQ7.js +10 -0
- package/dist/env-TD4VXCQ7.js.map +1 -0
- package/dist/output-2LGBISBQ.js +18 -0
- package/dist/output-2LGBISBQ.js.map +1 -0
- package/dist/shared-CQC3YRBA.js +23 -0
- package/dist/shared-CQC3YRBA.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-OCMOQOIJ.js.map +0 -1
|
@@ -1,28 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
-
mod
|
|
25
|
-
));
|
|
1
|
+
import {
|
|
2
|
+
__commonJS,
|
|
3
|
+
__toESM
|
|
4
|
+
} from "./chunk-5WRI5ZAA.js";
|
|
26
5
|
|
|
27
6
|
// ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/index.js
|
|
28
7
|
var require_safe_stable_stringify = __commonJS({
|
|
@@ -159,9 +138,9 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
159
138
|
}
|
|
160
139
|
if (value) {
|
|
161
140
|
return (value2) => {
|
|
162
|
-
let
|
|
163
|
-
if (typeof value2 !== "function")
|
|
164
|
-
throw new Error(
|
|
141
|
+
let message = `Object can not safely be stringified. Received type ${typeof value2}`;
|
|
142
|
+
if (typeof value2 !== "function") message += ` (${value2.toString()})`;
|
|
143
|
+
throw new Error(message);
|
|
165
144
|
};
|
|
166
145
|
}
|
|
167
146
|
}
|
|
@@ -673,9 +652,6 @@ var HttpClient = class {
|
|
|
673
652
|
async postJson(path16, body, signal) {
|
|
674
653
|
return await this.requestJson("POST", path16, body, signal);
|
|
675
654
|
}
|
|
676
|
-
async putJson(path16, body, signal) {
|
|
677
|
-
return await this.requestJson("PUT", path16, body, signal);
|
|
678
|
-
}
|
|
679
655
|
async getJson(path16, signal) {
|
|
680
656
|
return await this.requestJson("GET", path16, void 0, signal);
|
|
681
657
|
}
|
|
@@ -703,8 +679,8 @@ var HttpClient = class {
|
|
|
703
679
|
try {
|
|
704
680
|
const res = await this.fetchFn(url, {
|
|
705
681
|
method,
|
|
706
|
-
headers: method === "
|
|
707
|
-
body: method === "
|
|
682
|
+
headers: method === "POST" ? { "Content-Type": "application/json", Authorization: `Bearer ${this.apiKey}` } : { Authorization: `Bearer ${this.apiKey}` },
|
|
683
|
+
body: method === "POST" ? JSON.stringify(body) : void 0,
|
|
708
684
|
signal: controller.signal
|
|
709
685
|
});
|
|
710
686
|
if (res.ok) return { kind: "value", value: await res.json() };
|
|
@@ -741,33 +717,33 @@ async function parseErrorBody(res) {
|
|
|
741
717
|
const errObj = body.error ?? {};
|
|
742
718
|
return classifyHttpError(res.status, errObj, errObj.message ?? `HTTP ${res.status}`);
|
|
743
719
|
}
|
|
744
|
-
function classifyHttpError(status, errObj,
|
|
720
|
+
function classifyHttpError(status, errObj, message) {
|
|
745
721
|
if (errObj.code === CONTENT_POLICY_CODE) {
|
|
746
|
-
return { kind: "content_policy", status, provider: errObj.provider, message
|
|
722
|
+
return { kind: "content_policy", status, provider: errObj.provider, message };
|
|
747
723
|
}
|
|
748
724
|
if (status === 401 || status === 403) {
|
|
749
|
-
return { kind: "unauthorized", status, message
|
|
725
|
+
return { kind: "unauthorized", status, message };
|
|
750
726
|
}
|
|
751
727
|
if (status === 400 || status === 422) {
|
|
752
|
-
return { kind: "validation", status, message
|
|
728
|
+
return { kind: "validation", status, message, details: errObj.details };
|
|
753
729
|
}
|
|
754
730
|
if (status === 502 || status === 504) {
|
|
755
731
|
if (errObj.code === "provider_timeout" || status === 504) {
|
|
756
|
-
return { kind: "timeout", provider: errObj.provider, message
|
|
732
|
+
return { kind: "timeout", provider: errObj.provider, message };
|
|
757
733
|
}
|
|
758
734
|
return {
|
|
759
735
|
kind: "provider",
|
|
760
736
|
status,
|
|
761
737
|
provider: errObj.provider,
|
|
762
738
|
code: errObj.code ?? "provider_error",
|
|
763
|
-
message
|
|
739
|
+
message,
|
|
764
740
|
retryable: errObj.retryable ?? true
|
|
765
741
|
};
|
|
766
742
|
}
|
|
767
743
|
if (status >= 500 || status === 429) {
|
|
768
|
-
return { kind: "server", status, message
|
|
744
|
+
return { kind: "server", status, message };
|
|
769
745
|
}
|
|
770
|
-
return { kind: "validation", status, message
|
|
746
|
+
return { kind: "validation", status, message, details: errObj.details };
|
|
771
747
|
}
|
|
772
748
|
function backoffMs(attempt) {
|
|
773
749
|
return 1e3 * 2 ** attempt;
|
|
@@ -838,27 +814,6 @@ var BackendClient = class {
|
|
|
838
814
|
signal
|
|
839
815
|
);
|
|
840
816
|
}
|
|
841
|
-
/** Remote cache lookup. A miss (404) — or an old backend without the route — returns null. */
|
|
842
|
-
async getCacheEntry(cacheKey, signal) {
|
|
843
|
-
try {
|
|
844
|
-
const res = await this.http.getJson(`/api/canvas/cache/${encodeURIComponent(cacheKey)}`, signal);
|
|
845
|
-
return res.entry;
|
|
846
|
-
} catch (e) {
|
|
847
|
-
if (e instanceof BackendHttpError && "status" in e.detail && e.detail.status === 404) return null;
|
|
848
|
-
throw e;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
async putCacheEntry(entry, signal) {
|
|
852
|
-
await this.http.putJson(
|
|
853
|
-
`/api/canvas/cache/${encodeURIComponent(entry.cacheKey)}`,
|
|
854
|
-
entry,
|
|
855
|
-
signal
|
|
856
|
-
);
|
|
857
|
-
}
|
|
858
|
-
/** Durable run-history record — POST /api/canvas/runs (idempotent server-side on runId). */
|
|
859
|
-
async recordRun(payload, signal) {
|
|
860
|
-
await this.http.postJson("/api/canvas/runs", payload, signal);
|
|
861
|
-
}
|
|
862
817
|
getArtifact(kind, name, version, signal) {
|
|
863
818
|
const path16 = version ? `/api/canvas/artifacts/${encodeURIComponent(kind)}/${encodeURIComponent(name)}/${encodeURIComponent(version)}` : `/api/canvas/artifacts/${encodeURIComponent(kind)}/${encodeURIComponent(name)}`;
|
|
864
819
|
return this.http.getJson(path16, signal);
|
|
@@ -882,17 +837,14 @@ function requireCredentialsFromEnv(env = process.env) {
|
|
|
882
837
|
}
|
|
883
838
|
return c;
|
|
884
839
|
}
|
|
885
|
-
function remoteCacheEnabledFromEnv(env = process.env) {
|
|
886
|
-
return env.BAKER_CANVAS_REMOTE_CACHE !== "off";
|
|
887
|
-
}
|
|
888
840
|
|
|
889
841
|
// src/engine/engine/errors.ts
|
|
890
842
|
function isBlocking(issue) {
|
|
891
843
|
return issue.severity !== "warning";
|
|
892
844
|
}
|
|
893
845
|
var CanvasError = class extends Error {
|
|
894
|
-
constructor(
|
|
895
|
-
super(
|
|
846
|
+
constructor(message) {
|
|
847
|
+
super(message);
|
|
896
848
|
this.name = "CanvasError";
|
|
897
849
|
}
|
|
898
850
|
};
|
|
@@ -1610,158 +1562,6 @@ function encodeRandom() {
|
|
|
1610
1562
|
return out;
|
|
1611
1563
|
}
|
|
1612
1564
|
|
|
1613
|
-
// src/engine/storage/remote-cache-store.ts
|
|
1614
|
-
var CANVAS_ASSETS_URL_SEGMENT = "/canvas-assets/";
|
|
1615
|
-
function isPersistedAssetRef(ref) {
|
|
1616
|
-
return typeof ref.url === "string" && ref.url.includes(`${CANVAS_ASSETS_URL_SEGMENT}${ref.sha256}`);
|
|
1617
|
-
}
|
|
1618
|
-
function isAssetRefLike(value) {
|
|
1619
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && typeof value.sha256 === "string" && typeof value.mime === "string";
|
|
1620
|
-
}
|
|
1621
|
-
function collectAssetRefLikes(value, out = []) {
|
|
1622
|
-
if (Array.isArray(value)) {
|
|
1623
|
-
for (const item of value) collectAssetRefLikes(item, out);
|
|
1624
|
-
return out;
|
|
1625
|
-
}
|
|
1626
|
-
if (typeof value !== "object" || value === null) return out;
|
|
1627
|
-
if (isAssetRefLike(value)) {
|
|
1628
|
-
out.push(value);
|
|
1629
|
-
}
|
|
1630
|
-
for (const item of Object.values(value)) collectAssetRefLikes(item, out);
|
|
1631
|
-
return out;
|
|
1632
|
-
}
|
|
1633
|
-
function entryFullyPersisted(entry) {
|
|
1634
|
-
return collectAssetRefLikes(entry.outputs).every((ref) => isPersistedAssetRef(ref));
|
|
1635
|
-
}
|
|
1636
|
-
function stripLocalFields(entry) {
|
|
1637
|
-
const clone = JSON.parse(JSON.stringify(entry));
|
|
1638
|
-
for (const ref of collectAssetRefLikes(clone.outputs)) {
|
|
1639
|
-
delete ref.path;
|
|
1640
|
-
delete ref.bytes;
|
|
1641
|
-
}
|
|
1642
|
-
return clone;
|
|
1643
|
-
}
|
|
1644
|
-
var RemoteCacheStore = class {
|
|
1645
|
-
client;
|
|
1646
|
-
log;
|
|
1647
|
-
constructor(client, log) {
|
|
1648
|
-
this.client = client;
|
|
1649
|
-
this.log = log ?? (() => void 0);
|
|
1650
|
-
}
|
|
1651
|
-
async get(cacheKey) {
|
|
1652
|
-
return await this.client.getCacheEntry(cacheKey);
|
|
1653
|
-
}
|
|
1654
|
-
async put(entry) {
|
|
1655
|
-
if (!entryFullyPersisted(entry)) {
|
|
1656
|
-
this.log(`[cache ] ${entry.cacheKey.slice(0, 12)}\u2026 has local-only assets, kept local`);
|
|
1657
|
-
return;
|
|
1658
|
-
}
|
|
1659
|
-
const stripped = stripLocalFields(entry);
|
|
1660
|
-
if (stripped.refs.length > MAX_REMOTE_REFS) {
|
|
1661
|
-
stripped.refs = stripped.refs.slice(0, MAX_REMOTE_REFS);
|
|
1662
|
-
}
|
|
1663
|
-
await this.client.putCacheEntry(stripped);
|
|
1664
|
-
}
|
|
1665
|
-
};
|
|
1666
|
-
var MAX_REMOTE_REFS = 512;
|
|
1667
|
-
var LayeredCacheStore = class {
|
|
1668
|
-
rootDir;
|
|
1669
|
-
local;
|
|
1670
|
-
remote;
|
|
1671
|
-
assets;
|
|
1672
|
-
log;
|
|
1673
|
-
constructor(opts) {
|
|
1674
|
-
this.local = opts.local;
|
|
1675
|
-
this.remote = opts.remote;
|
|
1676
|
-
this.assets = opts.assets;
|
|
1677
|
-
this.rootDir = opts.local.rootDir;
|
|
1678
|
-
this.log = opts.log ?? (() => void 0);
|
|
1679
|
-
}
|
|
1680
|
-
async get(cacheKey) {
|
|
1681
|
-
const localHit = await this.local.get(cacheKey);
|
|
1682
|
-
if (localHit) return localHit;
|
|
1683
|
-
let remoteEntry;
|
|
1684
|
-
try {
|
|
1685
|
-
remoteEntry = await this.remote.get(cacheKey);
|
|
1686
|
-
} catch (e) {
|
|
1687
|
-
this.log(`[cache ] remote lookup failed (${message(e)}) \u2014 treating as miss`);
|
|
1688
|
-
return null;
|
|
1689
|
-
}
|
|
1690
|
-
if (!remoteEntry) return null;
|
|
1691
|
-
let rehydrated;
|
|
1692
|
-
try {
|
|
1693
|
-
rehydrated = await this.rehydrate(remoteEntry);
|
|
1694
|
-
} catch (e) {
|
|
1695
|
-
this.log(`[cache ] ${cacheKey.slice(0, 12)}\u2026 rehydration failed (${message(e)}) \u2014 treating as miss`);
|
|
1696
|
-
return null;
|
|
1697
|
-
}
|
|
1698
|
-
await this.local.put(rehydrated);
|
|
1699
|
-
return rehydrated;
|
|
1700
|
-
}
|
|
1701
|
-
async put(entry) {
|
|
1702
|
-
await this.local.put(entry);
|
|
1703
|
-
try {
|
|
1704
|
-
await this.remote.put(entry);
|
|
1705
|
-
} catch (e) {
|
|
1706
|
-
this.log(`[cache ] remote write failed (${message(e)}) \u2014 entry kept local`);
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
/**
|
|
1710
|
-
* Download every referenced asset into the local content-addressed store
|
|
1711
|
-
* (sha-verified) and stamp fresh local paths. Any ref that cannot be
|
|
1712
|
-
* rehydrated fails the WHOLE entry — a partially-hydrated cache hit would
|
|
1713
|
-
* crash materialization later with a far less actionable error.
|
|
1714
|
-
*/
|
|
1715
|
-
async rehydrate(entry) {
|
|
1716
|
-
const clone = JSON.parse(JSON.stringify(entry));
|
|
1717
|
-
for (const ref of collectAssetRefLikes(clone.outputs)) {
|
|
1718
|
-
if (!isPersistedAssetRef(ref)) {
|
|
1719
|
-
throw new Error(`ref ${ref.sha256.slice(0, 12)}\u2026 has no persisted url`);
|
|
1720
|
-
}
|
|
1721
|
-
const ingested = await this.assets.ingestRemote({
|
|
1722
|
-
kind: typeof ref.kind === "string" ? ref.kind : "json",
|
|
1723
|
-
url: ref.url,
|
|
1724
|
-
sha256: ref.sha256,
|
|
1725
|
-
mime: ref.mime,
|
|
1726
|
-
metadata: ref.metadata ?? void 0
|
|
1727
|
-
});
|
|
1728
|
-
ref.path = ingested.path;
|
|
1729
|
-
}
|
|
1730
|
-
return clone;
|
|
1731
|
-
}
|
|
1732
|
-
};
|
|
1733
|
-
function message(e) {
|
|
1734
|
-
return e instanceof Error ? e.message : String(e);
|
|
1735
|
-
}
|
|
1736
|
-
|
|
1737
|
-
// src/engine/nodes/remote/upload.ts
|
|
1738
|
-
async function presignAndPut(args) {
|
|
1739
|
-
const { putUrl, publicUrl } = await args.ctx.client.presignAssetUpload(args.sha256, args.mime, args.ctx.signal);
|
|
1740
|
-
const putRes = await fetch(putUrl, {
|
|
1741
|
-
method: "PUT",
|
|
1742
|
-
body: new Uint8Array(args.bytes),
|
|
1743
|
-
headers: { "Content-Type": args.mime },
|
|
1744
|
-
signal: args.ctx.signal
|
|
1745
|
-
});
|
|
1746
|
-
if (!putRes.ok) {
|
|
1747
|
-
throw new Error(`upload: presigned PUT failed ${putRes.status} ${putRes.statusText}`);
|
|
1748
|
-
}
|
|
1749
|
-
return publicUrl;
|
|
1750
|
-
}
|
|
1751
|
-
async function ensureUploaded(ref, ctx) {
|
|
1752
|
-
if (ref.url) return ref;
|
|
1753
|
-
const bytes = await ctx.assets.readBytes(ref.sha256, ref.mime);
|
|
1754
|
-
const url = await presignAndPut({ bytes, sha256: ref.sha256, mime: ref.mime, ctx });
|
|
1755
|
-
return { ...ref, url };
|
|
1756
|
-
}
|
|
1757
|
-
async function persistOutputAssetUrls(outputs, ctx) {
|
|
1758
|
-
for (const ref of collectAssetRefLikes(outputs)) {
|
|
1759
|
-
if (isPersistedAssetRef(ref)) continue;
|
|
1760
|
-
const bytes = await ctx.assets.readBytes(ref.sha256, ref.mime);
|
|
1761
|
-
ref.url = await presignAndPut({ bytes, sha256: ref.sha256, mime: ref.mime, ctx });
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
|
|
1765
1565
|
// src/engine/schema/canvas.ts
|
|
1766
1566
|
import { z } from "zod";
|
|
1767
1567
|
var REF_PREFIX = "$ref:";
|
|
@@ -1823,7 +1623,11 @@ var VideoMeta = z.object({
|
|
|
1823
1623
|
// Advisory: the scene's visual length vs the estimated spoken length, so
|
|
1824
1624
|
// a reviewer can see a native line that may run past its cut. Not gated.
|
|
1825
1625
|
scene_s: z.number().optional(),
|
|
1826
|
-
est_speech_s: z.number().optional()
|
|
1626
|
+
est_speech_s: z.number().optional(),
|
|
1627
|
+
// Word count of the line est_speech_s was measured for. Together they carry
|
|
1628
|
+
// the speaker's OBSERVED pace (from the deconstruct's word timings), so the
|
|
1629
|
+
// overrun check budgets re-authored lines at the real rate, not a wps guess.
|
|
1630
|
+
speech_words: z.number().optional()
|
|
1827
1631
|
}),
|
|
1828
1632
|
z.object({ scene: z.number(), lipsync_node: z.string() })
|
|
1829
1633
|
])
|
|
@@ -2353,7 +2157,9 @@ var STAGE_CODES = {
|
|
|
2353
2157
|
SPEECH_OVERRUN: "VIDEO_SPEECH_OVERRUN",
|
|
2354
2158
|
ASPECT_MISMATCH: "VIDEO_ASPECT_MISMATCH",
|
|
2355
2159
|
REFERENCE_MISSING: "VIDEO_REFERENCE_MISSING",
|
|
2356
|
-
SPAN_EXCEEDS_MODEL: "VIDEO_SPAN_EXCEEDS_MODEL"
|
|
2160
|
+
SPAN_EXCEEDS_MODEL: "VIDEO_SPAN_EXCEEDS_MODEL",
|
|
2161
|
+
UI_IN_PROMPT: "VIDEO_UI_IN_PROMPT",
|
|
2162
|
+
BRANDMARK_IN_PROMPT: "VIDEO_BRANDMARK_IN_PROMPT"
|
|
2357
2163
|
};
|
|
2358
2164
|
var SPAN_MODEL_SLACK_S = 0.25;
|
|
2359
2165
|
var VIDEO_TIME_SLACK_S = 0.75;
|
|
@@ -2732,6 +2538,8 @@ function checkVideoInvariants(ctx) {
|
|
|
2732
2538
|
}
|
|
2733
2539
|
checkSpeechOverrun(ctx, meta.talking_scenes);
|
|
2734
2540
|
checkAspectConsistency(ctx);
|
|
2541
|
+
checkUiInPrompt(ctx);
|
|
2542
|
+
checkBrandmarkInPrompt(ctx);
|
|
2735
2543
|
checkReferenceCompleteness(ctx, meta);
|
|
2736
2544
|
checkClipSpanFitsModel(ctx, meta);
|
|
2737
2545
|
}
|
|
@@ -2761,18 +2569,30 @@ function keywordTokens(text) {
|
|
|
2761
2569
|
if (!text) return [];
|
|
2762
2570
|
return text.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 3 && !KEYWORD_STOPWORDS.has(t));
|
|
2763
2571
|
}
|
|
2764
|
-
function
|
|
2765
|
-
const
|
|
2766
|
-
const typeWords = ELEMENT_TYPE_KEYWORDS[type] ?? [];
|
|
2572
|
+
function elementMentionKeywords(el) {
|
|
2573
|
+
const typeWords = ELEMENT_TYPE_KEYWORDS[el.type.toLowerCase()] ?? [];
|
|
2767
2574
|
return [.../* @__PURE__ */ new Set([...typeWords, ...keywordTokens(el.label), ...keywordTokens(el.description)])];
|
|
2768
2575
|
}
|
|
2576
|
+
function keywordsForElement(el) {
|
|
2577
|
+
return elementMentionKeywords(el);
|
|
2578
|
+
}
|
|
2769
2579
|
function containsWord(text, word) {
|
|
2770
2580
|
const esc = word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2771
2581
|
return new RegExp(`\\b${esc}\\b`, "i").test(text);
|
|
2772
2582
|
}
|
|
2583
|
+
var FRAME_DESCRIPTION_START = "FRAME DESCRIPTION (this frame's editable prompt):";
|
|
2584
|
+
var FRAME_DESCRIPTION_END = "Render exactly what the FRAME DESCRIPTION";
|
|
2585
|
+
function frameDescriptionOf(prompt) {
|
|
2586
|
+
const i = prompt.indexOf(FRAME_DESCRIPTION_START);
|
|
2587
|
+
if (i < 0) return prompt;
|
|
2588
|
+
const rest = prompt.slice(i + FRAME_DESCRIPTION_START.length);
|
|
2589
|
+
const j = rest.indexOf(FRAME_DESCRIPTION_END);
|
|
2590
|
+
return j < 0 ? rest : rest.slice(0, j);
|
|
2591
|
+
}
|
|
2773
2592
|
function checkFrameReferences(ctx, node, index, keyworded) {
|
|
2774
|
-
const
|
|
2775
|
-
if (typeof
|
|
2593
|
+
const rawPrompt = node.params?.prompt;
|
|
2594
|
+
if (typeof rawPrompt !== "string" || rawPrompt.length === 0) return;
|
|
2595
|
+
const prompt = frameDescriptionOf(rawPrompt);
|
|
2776
2596
|
const inputsBlob = JSON.stringify(node.inputs ?? {});
|
|
2777
2597
|
for (const { el, keywords } of keyworded) {
|
|
2778
2598
|
if (inputsBlob.includes(el.ref)) continue;
|
|
@@ -2822,13 +2642,24 @@ function checkClipSpanFitsModel(ctx, meta) {
|
|
|
2822
2642
|
});
|
|
2823
2643
|
}
|
|
2824
2644
|
}
|
|
2825
|
-
|
|
2645
|
+
var OBSERVED_WPS_MIN = 1;
|
|
2646
|
+
var OBSERVED_WPS_MAX = 6;
|
|
2647
|
+
function secondsPerWord(stamped) {
|
|
2648
|
+
const est = stamped?.est_speech_s;
|
|
2649
|
+
const words = stamped?.speech_words;
|
|
2650
|
+
if (est && words && est > 0 && words > 0) {
|
|
2651
|
+
const wps = words / est;
|
|
2652
|
+
if (wps >= OBSERVED_WPS_MIN && wps <= OBSERVED_WPS_MAX) return est / words;
|
|
2653
|
+
}
|
|
2654
|
+
return 1 / SPEECH_WORDS_PER_SECOND;
|
|
2655
|
+
}
|
|
2656
|
+
function speechOverrunOf(node, secPerWord) {
|
|
2826
2657
|
const params = node.params;
|
|
2827
2658
|
if (params?.generate_audio !== true) return null;
|
|
2828
2659
|
const line = nativeDialogueOf(params.prompt);
|
|
2829
2660
|
const duration = typeof params.duration === "number" ? params.duration : void 0;
|
|
2830
2661
|
if (!line || !duration) return null;
|
|
2831
|
-
const estSpeechS = line.split(/\s+/).filter(Boolean).length
|
|
2662
|
+
const estSpeechS = line.split(/\s+/).filter(Boolean).length * secPerWord;
|
|
2832
2663
|
return estSpeechS > duration * SPEECH_OVERRUN_RATIO ? { estSpeechS, duration } : null;
|
|
2833
2664
|
}
|
|
2834
2665
|
function checkSpeechOverrun(ctx, talkingScenes) {
|
|
@@ -2837,7 +2668,7 @@ function checkSpeechOverrun(ctx, talkingScenes) {
|
|
|
2837
2668
|
const nativeClipRe = new RegExp(`^s${entry.scene}(_r\\d+)?_clip$`);
|
|
2838
2669
|
for (const n of ctx.canvas.nodes) {
|
|
2839
2670
|
if (!nativeClipRe.test(n.id) || n.type !== "video_generate") continue;
|
|
2840
|
-
const overrun = speechOverrunOf(n);
|
|
2671
|
+
const overrun = speechOverrunOf(n, secondsPerWord(entry));
|
|
2841
2672
|
if (!overrun) continue;
|
|
2842
2673
|
ctx.issues.push({
|
|
2843
2674
|
path: `nodes[${ctx.idToIndex.get(n.id) ?? -1}].params.prompt`,
|
|
@@ -2847,6 +2678,38 @@ function checkSpeechOverrun(ctx, talkingScenes) {
|
|
|
2847
2678
|
}
|
|
2848
2679
|
}
|
|
2849
2680
|
}
|
|
2681
|
+
var UI_IN_PROMPT_RE = /\bscreen[- ]?(?:recording|capture|grab|share)\b|\bapp (?:interface|screen)\b|\bphone screen overlay\b/i;
|
|
2682
|
+
function checkUiInPrompt(ctx) {
|
|
2683
|
+
for (const n of ctx.canvas.nodes) {
|
|
2684
|
+
if (n.type !== "video_generate") continue;
|
|
2685
|
+
const prompt = n.params?.prompt;
|
|
2686
|
+
if (typeof prompt !== "string" || !UI_IN_PROMPT_RE.test(prompt)) continue;
|
|
2687
|
+
ctx.issues.push({
|
|
2688
|
+
path: `nodes[${ctx.idToIndex.get(n.id) ?? -1}].params.prompt`,
|
|
2689
|
+
code: STAGE_CODES.UI_IN_PROMPT,
|
|
2690
|
+
severity: "warning",
|
|
2691
|
+
message: `"${n.id}" asks the video model to render a screen/UI surface \u2014 generative video garbles UI text and chrome. Composite the real screen on the overlay layer (screenshot / brand HTML) and keep this prompt to the background plate`,
|
|
2692
|
+
node_id: n.id,
|
|
2693
|
+
node_type: "video_generate"
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
var BRANDMARK_IN_PROMPT_RE = /\b(?:logo|wordmark) (?:overlay|animation|sting|card|reveal)\b|\b(?:google|facebook|instagram|tiktok|youtube|amazon|apple|microsoft|whatsapp|netflix|spotify|excel|trustpilot) (?:logo|wordmark|branding)\b/i;
|
|
2698
|
+
function checkBrandmarkInPrompt(ctx) {
|
|
2699
|
+
for (const n of ctx.canvas.nodes) {
|
|
2700
|
+
if (n.type !== "video_generate" && n.type !== "image_generate") continue;
|
|
2701
|
+
const prompt = n.params?.prompt;
|
|
2702
|
+
if (typeof prompt !== "string" || !BRANDMARK_IN_PROMPT_RE.test(prompt)) continue;
|
|
2703
|
+
ctx.issues.push({
|
|
2704
|
+
path: `nodes[${ctx.idToIndex.get(n.id) ?? -1}].params.prompt`,
|
|
2705
|
+
code: STAGE_CODES.BRANDMARK_IN_PROMPT,
|
|
2706
|
+
severity: "warning",
|
|
2707
|
+
message: `"${n.id}" asks the model to render a brand logo/wordmark \u2014 generation garbles marks and third-party logos carry IP exposure. Source the real mark (baker images logo <domain>) and composite it on the overlay layer`,
|
|
2708
|
+
node_id: n.id,
|
|
2709
|
+
node_type: n.type
|
|
2710
|
+
});
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2850
2713
|
function checkAspectConsistency(ctx) {
|
|
2851
2714
|
const clips = ctx.canvas.nodes.filter((n) => n.type === "video_generate");
|
|
2852
2715
|
if (clips.length < 2) return;
|
|
@@ -2978,7 +2841,6 @@ var Engine = class {
|
|
|
2978
2841
|
cache;
|
|
2979
2842
|
outputsDir;
|
|
2980
2843
|
log;
|
|
2981
|
-
persistAssets;
|
|
2982
2844
|
constructor(opts) {
|
|
2983
2845
|
this.registry = opts.registry;
|
|
2984
2846
|
this.client = opts.client;
|
|
@@ -2986,7 +2848,6 @@ var Engine = class {
|
|
|
2986
2848
|
this.cache = opts.cache;
|
|
2987
2849
|
this.outputsDir = opts.outputsDir;
|
|
2988
2850
|
this.log = opts.log ?? (() => void 0);
|
|
2989
|
-
this.persistAssets = opts.persistAssets ?? false;
|
|
2990
2851
|
}
|
|
2991
2852
|
validate(canvas) {
|
|
2992
2853
|
return validateCanvas(canvas, this.registry);
|
|
@@ -3033,7 +2894,7 @@ var Engine = class {
|
|
|
3033
2894
|
`[done ] ${stats.cached_nodes}/${stats.total_nodes} cached, ${stats.total_credits} credits, ${stats.duration_ms}ms`
|
|
3034
2895
|
);
|
|
3035
2896
|
this.log(`outputs in: ${writer.runDir}`);
|
|
3036
|
-
return { run_id: runId, output, outputs_by_node: outputs, stats, outputs_dir: writer.runDir
|
|
2897
|
+
return { run_id: runId, output, outputs_by_node: outputs, stats, outputs_dir: writer.runDir };
|
|
3037
2898
|
}
|
|
3038
2899
|
async runLayers(canvas, outputs, runId, writer, opts, counters, nodeRuns) {
|
|
3039
2900
|
const layers = topologicalLayers(this.pruneToOutput(canvas, buildGraph(canvas)));
|
|
@@ -3130,14 +2991,6 @@ var Engine = class {
|
|
|
3130
2991
|
const credits = def.cost ? def.cost({ params: parsedParams }).credits : 0;
|
|
3131
2992
|
const outputsObj = result;
|
|
3132
2993
|
outputs[node.id] = outputsObj;
|
|
3133
|
-
if (this.persistAssets) {
|
|
3134
|
-
try {
|
|
3135
|
-
await persistOutputAssetUrls(outputsObj, ctx);
|
|
3136
|
-
} catch (e) {
|
|
3137
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
3138
|
-
this.log(`[warn ] ${node.id}: asset persistence failed (${msg}) \u2014 outputs stay local-only`);
|
|
3139
|
-
}
|
|
3140
|
-
}
|
|
3141
2994
|
if (policy === "read_write") {
|
|
3142
2995
|
await this.cache.put({
|
|
3143
2996
|
cacheKey: prepared.cacheKey,
|
|
@@ -3456,6 +3309,27 @@ var FontRef = BaseAssetRef.extend({
|
|
|
3456
3309
|
});
|
|
3457
3310
|
var AssetRef = z4.discriminatedUnion("kind", [ImageRef, VideoRef, AudioRef, JsonRef, TextRef, FontRef]);
|
|
3458
3311
|
|
|
3312
|
+
// src/engine/nodes/remote/upload.ts
|
|
3313
|
+
async function presignAndPut(args) {
|
|
3314
|
+
const { putUrl, publicUrl } = await args.ctx.client.presignAssetUpload(args.sha256, args.mime, args.ctx.signal);
|
|
3315
|
+
const putRes = await fetch(putUrl, {
|
|
3316
|
+
method: "PUT",
|
|
3317
|
+
body: new Uint8Array(args.bytes),
|
|
3318
|
+
headers: { "Content-Type": args.mime },
|
|
3319
|
+
signal: args.ctx.signal
|
|
3320
|
+
});
|
|
3321
|
+
if (!putRes.ok) {
|
|
3322
|
+
throw new Error(`upload: presigned PUT failed ${putRes.status} ${putRes.statusText}`);
|
|
3323
|
+
}
|
|
3324
|
+
return publicUrl;
|
|
3325
|
+
}
|
|
3326
|
+
async function ensureUploaded(ref, ctx) {
|
|
3327
|
+
if (ref.url) return ref;
|
|
3328
|
+
const bytes = await ctx.assets.readBytes(ref.sha256, ref.mime);
|
|
3329
|
+
const url = await presignAndPut({ bytes, sha256: ref.sha256, mime: ref.mime, ctx });
|
|
3330
|
+
return { ...ref, url };
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3459
3333
|
// src/engine/nodes/remote/delegate.ts
|
|
3460
3334
|
function delegated(spec) {
|
|
3461
3335
|
return {
|
|
@@ -3850,10 +3724,10 @@ function inferKindFromMime(mime) {
|
|
|
3850
3724
|
if (mime.startsWith("font/")) return "font";
|
|
3851
3725
|
return null;
|
|
3852
3726
|
}
|
|
3853
|
-
function localExecError(ctx,
|
|
3727
|
+
function localExecError(ctx, message) {
|
|
3854
3728
|
return new NodeExecutionError(ctx.nodeId, ctx.nodeType, {
|
|
3855
3729
|
kind: "local",
|
|
3856
|
-
cause: new Error(`ingest: ${
|
|
3730
|
+
cause: new Error(`ingest: ${message}`)
|
|
3857
3731
|
});
|
|
3858
3732
|
}
|
|
3859
3733
|
async function execLocalFile(params, ctx) {
|
|
@@ -4520,7 +4394,7 @@ async function refToUrl(ref) {
|
|
|
4520
4394
|
return `data:${ref.mime};base64,${bytes.toString("base64")}`;
|
|
4521
4395
|
}
|
|
4522
4396
|
var ASSET_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
|
|
4523
|
-
function
|
|
4397
|
+
function isAssetRefLike(value) {
|
|
4524
4398
|
if (!value || typeof value !== "object") return false;
|
|
4525
4399
|
const v = value;
|
|
4526
4400
|
return typeof v.kind === "string" && ASSET_KINDS.has(v.kind) && typeof v.mime === "string" && typeof v.sha256 === "string" && (typeof v.url === "string" || typeof v.path === "string");
|
|
@@ -4892,8 +4766,8 @@ var NEVER_BLOCK = [
|
|
|
4892
4766
|
/text[_-]?occluded/i
|
|
4893
4767
|
];
|
|
4894
4768
|
var UNAVAILABLE = /unknown command|command not found|not found|Did you mean|Unknown argument|ENOENT/i;
|
|
4895
|
-
function isAdvisory(code,
|
|
4896
|
-
const hay = `${code} ${
|
|
4769
|
+
function isAdvisory(code, message) {
|
|
4770
|
+
const hay = `${code} ${message}`;
|
|
4897
4771
|
return NEVER_BLOCK.some((re) => re.test(hay));
|
|
4898
4772
|
}
|
|
4899
4773
|
function parseCheckJson(raw) {
|
|
@@ -4921,10 +4795,10 @@ function classifyLint(json) {
|
|
|
4921
4795
|
for (const f of findings) {
|
|
4922
4796
|
const rec = f;
|
|
4923
4797
|
const code = String(rec?.code ?? "");
|
|
4924
|
-
const
|
|
4798
|
+
const message = String(rec?.message ?? "");
|
|
4925
4799
|
const severity = String(rec?.severity ?? "info");
|
|
4926
|
-
const blocking = severity === "error" && !isAdvisory(code,
|
|
4927
|
-
out.push({ source: "lint", code, message
|
|
4800
|
+
const blocking = severity === "error" && !isAdvisory(code, message);
|
|
4801
|
+
out.push({ source: "lint", code, message, severity: blocking ? "blocking" : "warning" });
|
|
4928
4802
|
}
|
|
4929
4803
|
return out;
|
|
4930
4804
|
}
|
|
@@ -4936,9 +4810,9 @@ function classifyInspect(json) {
|
|
|
4936
4810
|
for (const iss of issues) {
|
|
4937
4811
|
const rec = iss;
|
|
4938
4812
|
const code = String(rec?.code ?? rec?.type ?? "overflow");
|
|
4939
|
-
const
|
|
4813
|
+
const message = String(rec?.message ?? rec?.detail ?? JSON.stringify(iss));
|
|
4940
4814
|
const severity = rec?.severity ? String(rec.severity) : obj?.ok === false ? "error" : "warning";
|
|
4941
|
-
out.push({ source: "inspect", code, message
|
|
4815
|
+
out.push({ source: "inspect", code, message, severity: severity === "error" ? "blocking" : "warning" });
|
|
4942
4816
|
}
|
|
4943
4817
|
return out;
|
|
4944
4818
|
}
|
|
@@ -5383,7 +5257,7 @@ async function buildSubstitutionValues(compositionParams, meta, duration) {
|
|
|
5383
5257
|
}
|
|
5384
5258
|
function coerceImageParam(value) {
|
|
5385
5259
|
if (typeof value === "string") return Promise.resolve(value);
|
|
5386
|
-
if (
|
|
5260
|
+
if (isAssetRefLike(value)) return refToUrl(value);
|
|
5387
5261
|
throw new Error("hyperframe_render: image param must be a URL string or AssetRef");
|
|
5388
5262
|
}
|
|
5389
5263
|
async function substituteCompositionFiles(tmp, values) {
|
|
@@ -5613,7 +5487,7 @@ async function buildSubstitutionValues2(compositionParams, meta) {
|
|
|
5613
5487
|
}
|
|
5614
5488
|
function coerceImageParam2(value) {
|
|
5615
5489
|
if (typeof value === "string") return Promise.resolve(value);
|
|
5616
|
-
if (
|
|
5490
|
+
if (isAssetRefLike(value)) return refToUrl(value);
|
|
5617
5491
|
throw new Error("hyperframe_snapshot: image param must be a URL string or AssetRef");
|
|
5618
5492
|
}
|
|
5619
5493
|
async function substituteCompositionFiles2(tmp, values) {
|
|
@@ -6639,29 +6513,17 @@ function createEngineFromEnv(opts = {}) {
|
|
|
6639
6513
|
const cacheDir = opts.cacheDir ?? path15.join(cwd, "canvas", ".cache");
|
|
6640
6514
|
const outputsDir = opts.outputsDir ?? path15.join(cwd, "canvas");
|
|
6641
6515
|
const creds = requireCredentialsFromEnv();
|
|
6642
|
-
const client = new BackendClient({ baseUrl: creds.url, apiKey: creds.apiKey });
|
|
6643
|
-
const assets = new LocalAssetStore(path15.join(cacheDir, "assets"));
|
|
6644
|
-
const localCache = new LocalCacheStore(path15.join(cacheDir, "index"));
|
|
6645
|
-
const remoteCacheEnabled = opts.remoteCache ?? remoteCacheEnabledFromEnv();
|
|
6646
|
-
const cache = remoteCacheEnabled ? new LayeredCacheStore({
|
|
6647
|
-
local: localCache,
|
|
6648
|
-
remote: new RemoteCacheStore(client, opts.log),
|
|
6649
|
-
assets,
|
|
6650
|
-
log: opts.log
|
|
6651
|
-
}) : localCache;
|
|
6652
6516
|
return new Engine({
|
|
6653
6517
|
registry: defaultRegistry(),
|
|
6654
|
-
client,
|
|
6655
|
-
assets,
|
|
6656
|
-
cache,
|
|
6518
|
+
client: new BackendClient({ baseUrl: creds.url, apiKey: creds.apiKey }),
|
|
6519
|
+
assets: new LocalAssetStore(path15.join(cacheDir, "assets")),
|
|
6520
|
+
cache: new LocalCacheStore(path15.join(cacheDir, "index")),
|
|
6657
6521
|
outputsDir,
|
|
6658
|
-
log: opts.log
|
|
6659
|
-
persistAssets: remoteCacheEnabled
|
|
6522
|
+
log: opts.log
|
|
6660
6523
|
});
|
|
6661
6524
|
}
|
|
6662
6525
|
|
|
6663
6526
|
export {
|
|
6664
|
-
requireCredentialsFromEnv,
|
|
6665
6527
|
LayerExecutionError,
|
|
6666
6528
|
describeFailureReason,
|
|
6667
6529
|
SEEDANCE_DURATIONS,
|
|
@@ -6669,10 +6531,7 @@ export {
|
|
|
6669
6531
|
IMAGE_GENERATE_MODELS,
|
|
6670
6532
|
MODEL_REGISTRY,
|
|
6671
6533
|
resolveConcurrency,
|
|
6672
|
-
|
|
6673
|
-
isPersistedAssetRef,
|
|
6674
|
-
collectAssetRefLikes,
|
|
6675
|
-
sha256Hex,
|
|
6534
|
+
elementMentionKeywords,
|
|
6676
6535
|
BackendClient2 as BackendClient,
|
|
6677
6536
|
Engine2 as Engine,
|
|
6678
6537
|
LocalAssetStore2 as LocalAssetStore,
|
|
@@ -6683,4 +6542,4 @@ export {
|
|
|
6683
6542
|
defaultRegistry,
|
|
6684
6543
|
createEngineFromEnv
|
|
6685
6544
|
};
|
|
6686
|
-
//# sourceMappingURL=chunk-
|
|
6545
|
+
//# sourceMappingURL=chunk-MWFJ5NOP.js.map
|