@koda-sl/baker-cli 0.121.0-dev.775026ddd → 0.121.0-dev.a2cdb40bc
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 +108 -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-GQIOFHVI.js → chunk-MWFJ5NOP.js} +132 -275
- 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 +4389 -2321
- 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-GQIOFHVI.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,160 +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
|
-
const { url, sha256 } = ref;
|
|
1617
|
-
if (typeof url !== "string" || typeof sha256 !== "string") return false;
|
|
1618
|
-
return url.includes(`${CANVAS_ASSETS_URL_SEGMENT}${sha256.slice(0, 2)}/${sha256}`) || url.includes(`${CANVAS_ASSETS_URL_SEGMENT}${sha256}`);
|
|
1619
|
-
}
|
|
1620
|
-
function isAssetRefLike(value) {
|
|
1621
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && typeof value.sha256 === "string" && typeof value.mime === "string";
|
|
1622
|
-
}
|
|
1623
|
-
function collectAssetRefLikes(value, out = []) {
|
|
1624
|
-
if (Array.isArray(value)) {
|
|
1625
|
-
for (const item of value) collectAssetRefLikes(item, out);
|
|
1626
|
-
return out;
|
|
1627
|
-
}
|
|
1628
|
-
if (typeof value !== "object" || value === null) return out;
|
|
1629
|
-
if (isAssetRefLike(value)) {
|
|
1630
|
-
out.push(value);
|
|
1631
|
-
}
|
|
1632
|
-
for (const item of Object.values(value)) collectAssetRefLikes(item, out);
|
|
1633
|
-
return out;
|
|
1634
|
-
}
|
|
1635
|
-
function entryFullyPersisted(entry) {
|
|
1636
|
-
return collectAssetRefLikes(entry.outputs).every((ref) => isPersistedAssetRef(ref));
|
|
1637
|
-
}
|
|
1638
|
-
function stripLocalFields(entry) {
|
|
1639
|
-
const clone = JSON.parse(JSON.stringify(entry));
|
|
1640
|
-
for (const ref of collectAssetRefLikes(clone.outputs)) {
|
|
1641
|
-
delete ref.path;
|
|
1642
|
-
delete ref.bytes;
|
|
1643
|
-
}
|
|
1644
|
-
return clone;
|
|
1645
|
-
}
|
|
1646
|
-
var RemoteCacheStore = class {
|
|
1647
|
-
client;
|
|
1648
|
-
log;
|
|
1649
|
-
constructor(client, log) {
|
|
1650
|
-
this.client = client;
|
|
1651
|
-
this.log = log ?? (() => void 0);
|
|
1652
|
-
}
|
|
1653
|
-
async get(cacheKey) {
|
|
1654
|
-
return await this.client.getCacheEntry(cacheKey);
|
|
1655
|
-
}
|
|
1656
|
-
async put(entry) {
|
|
1657
|
-
if (!entryFullyPersisted(entry)) {
|
|
1658
|
-
this.log(`[cache ] ${entry.cacheKey.slice(0, 12)}\u2026 has local-only assets, kept local`);
|
|
1659
|
-
return;
|
|
1660
|
-
}
|
|
1661
|
-
const stripped = stripLocalFields(entry);
|
|
1662
|
-
if (stripped.refs.length > MAX_REMOTE_REFS) {
|
|
1663
|
-
stripped.refs = stripped.refs.slice(0, MAX_REMOTE_REFS);
|
|
1664
|
-
}
|
|
1665
|
-
await this.client.putCacheEntry(stripped);
|
|
1666
|
-
}
|
|
1667
|
-
};
|
|
1668
|
-
var MAX_REMOTE_REFS = 512;
|
|
1669
|
-
var LayeredCacheStore = class {
|
|
1670
|
-
rootDir;
|
|
1671
|
-
local;
|
|
1672
|
-
remote;
|
|
1673
|
-
assets;
|
|
1674
|
-
log;
|
|
1675
|
-
constructor(opts) {
|
|
1676
|
-
this.local = opts.local;
|
|
1677
|
-
this.remote = opts.remote;
|
|
1678
|
-
this.assets = opts.assets;
|
|
1679
|
-
this.rootDir = opts.local.rootDir;
|
|
1680
|
-
this.log = opts.log ?? (() => void 0);
|
|
1681
|
-
}
|
|
1682
|
-
async get(cacheKey) {
|
|
1683
|
-
const localHit = await this.local.get(cacheKey);
|
|
1684
|
-
if (localHit) return localHit;
|
|
1685
|
-
let remoteEntry;
|
|
1686
|
-
try {
|
|
1687
|
-
remoteEntry = await this.remote.get(cacheKey);
|
|
1688
|
-
} catch (e) {
|
|
1689
|
-
this.log(`[cache ] remote lookup failed (${message(e)}) \u2014 treating as miss`);
|
|
1690
|
-
return null;
|
|
1691
|
-
}
|
|
1692
|
-
if (!remoteEntry) return null;
|
|
1693
|
-
let rehydrated;
|
|
1694
|
-
try {
|
|
1695
|
-
rehydrated = await this.rehydrate(remoteEntry);
|
|
1696
|
-
} catch (e) {
|
|
1697
|
-
this.log(`[cache ] ${cacheKey.slice(0, 12)}\u2026 rehydration failed (${message(e)}) \u2014 treating as miss`);
|
|
1698
|
-
return null;
|
|
1699
|
-
}
|
|
1700
|
-
await this.local.put(rehydrated);
|
|
1701
|
-
return rehydrated;
|
|
1702
|
-
}
|
|
1703
|
-
async put(entry) {
|
|
1704
|
-
await this.local.put(entry);
|
|
1705
|
-
try {
|
|
1706
|
-
await this.remote.put(entry);
|
|
1707
|
-
} catch (e) {
|
|
1708
|
-
this.log(`[cache ] remote write failed (${message(e)}) \u2014 entry kept local`);
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
/**
|
|
1712
|
-
* Download every referenced asset into the local content-addressed store
|
|
1713
|
-
* (sha-verified) and stamp fresh local paths. Any ref that cannot be
|
|
1714
|
-
* rehydrated fails the WHOLE entry — a partially-hydrated cache hit would
|
|
1715
|
-
* crash materialization later with a far less actionable error.
|
|
1716
|
-
*/
|
|
1717
|
-
async rehydrate(entry) {
|
|
1718
|
-
const clone = JSON.parse(JSON.stringify(entry));
|
|
1719
|
-
for (const ref of collectAssetRefLikes(clone.outputs)) {
|
|
1720
|
-
if (!isPersistedAssetRef(ref)) {
|
|
1721
|
-
throw new Error(`ref ${ref.sha256.slice(0, 12)}\u2026 has no persisted url`);
|
|
1722
|
-
}
|
|
1723
|
-
const ingested = await this.assets.ingestRemote({
|
|
1724
|
-
kind: typeof ref.kind === "string" ? ref.kind : "json",
|
|
1725
|
-
url: ref.url,
|
|
1726
|
-
sha256: ref.sha256,
|
|
1727
|
-
mime: ref.mime,
|
|
1728
|
-
metadata: ref.metadata ?? void 0
|
|
1729
|
-
});
|
|
1730
|
-
ref.path = ingested.path;
|
|
1731
|
-
}
|
|
1732
|
-
return clone;
|
|
1733
|
-
}
|
|
1734
|
-
};
|
|
1735
|
-
function message(e) {
|
|
1736
|
-
return e instanceof Error ? e.message : String(e);
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
|
-
// src/engine/nodes/remote/upload.ts
|
|
1740
|
-
async function presignAndPut(args) {
|
|
1741
|
-
const { putUrl, publicUrl } = await args.ctx.client.presignAssetUpload(args.sha256, args.mime, args.ctx.signal);
|
|
1742
|
-
const putRes = await fetch(putUrl, {
|
|
1743
|
-
method: "PUT",
|
|
1744
|
-
body: new Uint8Array(args.bytes),
|
|
1745
|
-
headers: { "Content-Type": args.mime },
|
|
1746
|
-
signal: args.ctx.signal
|
|
1747
|
-
});
|
|
1748
|
-
if (!putRes.ok) {
|
|
1749
|
-
throw new Error(`upload: presigned PUT failed ${putRes.status} ${putRes.statusText}`);
|
|
1750
|
-
}
|
|
1751
|
-
return publicUrl;
|
|
1752
|
-
}
|
|
1753
|
-
async function ensureUploaded(ref, ctx) {
|
|
1754
|
-
if (ref.url) return ref;
|
|
1755
|
-
const bytes = await ctx.assets.readBytes(ref.sha256, ref.mime);
|
|
1756
|
-
const url = await presignAndPut({ bytes, sha256: ref.sha256, mime: ref.mime, ctx });
|
|
1757
|
-
return { ...ref, url };
|
|
1758
|
-
}
|
|
1759
|
-
async function persistOutputAssetUrls(outputs, ctx) {
|
|
1760
|
-
for (const ref of collectAssetRefLikes(outputs)) {
|
|
1761
|
-
if (isPersistedAssetRef(ref)) continue;
|
|
1762
|
-
const bytes = await ctx.assets.readBytes(ref.sha256, ref.mime);
|
|
1763
|
-
ref.url = await presignAndPut({ bytes, sha256: ref.sha256, mime: ref.mime, ctx });
|
|
1764
|
-
}
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
1565
|
// src/engine/schema/canvas.ts
|
|
1768
1566
|
import { z } from "zod";
|
|
1769
1567
|
var REF_PREFIX = "$ref:";
|
|
@@ -1825,7 +1623,11 @@ var VideoMeta = z.object({
|
|
|
1825
1623
|
// Advisory: the scene's visual length vs the estimated spoken length, so
|
|
1826
1624
|
// a reviewer can see a native line that may run past its cut. Not gated.
|
|
1827
1625
|
scene_s: z.number().optional(),
|
|
1828
|
-
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()
|
|
1829
1631
|
}),
|
|
1830
1632
|
z.object({ scene: z.number(), lipsync_node: z.string() })
|
|
1831
1633
|
])
|
|
@@ -2355,7 +2157,9 @@ var STAGE_CODES = {
|
|
|
2355
2157
|
SPEECH_OVERRUN: "VIDEO_SPEECH_OVERRUN",
|
|
2356
2158
|
ASPECT_MISMATCH: "VIDEO_ASPECT_MISMATCH",
|
|
2357
2159
|
REFERENCE_MISSING: "VIDEO_REFERENCE_MISSING",
|
|
2358
|
-
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"
|
|
2359
2163
|
};
|
|
2360
2164
|
var SPAN_MODEL_SLACK_S = 0.25;
|
|
2361
2165
|
var VIDEO_TIME_SLACK_S = 0.75;
|
|
@@ -2734,6 +2538,8 @@ function checkVideoInvariants(ctx) {
|
|
|
2734
2538
|
}
|
|
2735
2539
|
checkSpeechOverrun(ctx, meta.talking_scenes);
|
|
2736
2540
|
checkAspectConsistency(ctx);
|
|
2541
|
+
checkUiInPrompt(ctx);
|
|
2542
|
+
checkBrandmarkInPrompt(ctx);
|
|
2737
2543
|
checkReferenceCompleteness(ctx, meta);
|
|
2738
2544
|
checkClipSpanFitsModel(ctx, meta);
|
|
2739
2545
|
}
|
|
@@ -2763,18 +2569,30 @@ function keywordTokens(text) {
|
|
|
2763
2569
|
if (!text) return [];
|
|
2764
2570
|
return text.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 3 && !KEYWORD_STOPWORDS.has(t));
|
|
2765
2571
|
}
|
|
2766
|
-
function
|
|
2767
|
-
const
|
|
2768
|
-
const typeWords = ELEMENT_TYPE_KEYWORDS[type] ?? [];
|
|
2572
|
+
function elementMentionKeywords(el) {
|
|
2573
|
+
const typeWords = ELEMENT_TYPE_KEYWORDS[el.type.toLowerCase()] ?? [];
|
|
2769
2574
|
return [.../* @__PURE__ */ new Set([...typeWords, ...keywordTokens(el.label), ...keywordTokens(el.description)])];
|
|
2770
2575
|
}
|
|
2576
|
+
function keywordsForElement(el) {
|
|
2577
|
+
return elementMentionKeywords(el);
|
|
2578
|
+
}
|
|
2771
2579
|
function containsWord(text, word) {
|
|
2772
2580
|
const esc = word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2773
2581
|
return new RegExp(`\\b${esc}\\b`, "i").test(text);
|
|
2774
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
|
+
}
|
|
2775
2592
|
function checkFrameReferences(ctx, node, index, keyworded) {
|
|
2776
|
-
const
|
|
2777
|
-
if (typeof
|
|
2593
|
+
const rawPrompt = node.params?.prompt;
|
|
2594
|
+
if (typeof rawPrompt !== "string" || rawPrompt.length === 0) return;
|
|
2595
|
+
const prompt = frameDescriptionOf(rawPrompt);
|
|
2778
2596
|
const inputsBlob = JSON.stringify(node.inputs ?? {});
|
|
2779
2597
|
for (const { el, keywords } of keyworded) {
|
|
2780
2598
|
if (inputsBlob.includes(el.ref)) continue;
|
|
@@ -2824,13 +2642,24 @@ function checkClipSpanFitsModel(ctx, meta) {
|
|
|
2824
2642
|
});
|
|
2825
2643
|
}
|
|
2826
2644
|
}
|
|
2827
|
-
|
|
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) {
|
|
2828
2657
|
const params = node.params;
|
|
2829
2658
|
if (params?.generate_audio !== true) return null;
|
|
2830
2659
|
const line = nativeDialogueOf(params.prompt);
|
|
2831
2660
|
const duration = typeof params.duration === "number" ? params.duration : void 0;
|
|
2832
2661
|
if (!line || !duration) return null;
|
|
2833
|
-
const estSpeechS = line.split(/\s+/).filter(Boolean).length
|
|
2662
|
+
const estSpeechS = line.split(/\s+/).filter(Boolean).length * secPerWord;
|
|
2834
2663
|
return estSpeechS > duration * SPEECH_OVERRUN_RATIO ? { estSpeechS, duration } : null;
|
|
2835
2664
|
}
|
|
2836
2665
|
function checkSpeechOverrun(ctx, talkingScenes) {
|
|
@@ -2839,7 +2668,7 @@ function checkSpeechOverrun(ctx, talkingScenes) {
|
|
|
2839
2668
|
const nativeClipRe = new RegExp(`^s${entry.scene}(_r\\d+)?_clip$`);
|
|
2840
2669
|
for (const n of ctx.canvas.nodes) {
|
|
2841
2670
|
if (!nativeClipRe.test(n.id) || n.type !== "video_generate") continue;
|
|
2842
|
-
const overrun = speechOverrunOf(n);
|
|
2671
|
+
const overrun = speechOverrunOf(n, secondsPerWord(entry));
|
|
2843
2672
|
if (!overrun) continue;
|
|
2844
2673
|
ctx.issues.push({
|
|
2845
2674
|
path: `nodes[${ctx.idToIndex.get(n.id) ?? -1}].params.prompt`,
|
|
@@ -2849,6 +2678,38 @@ function checkSpeechOverrun(ctx, talkingScenes) {
|
|
|
2849
2678
|
}
|
|
2850
2679
|
}
|
|
2851
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
|
+
}
|
|
2852
2713
|
function checkAspectConsistency(ctx) {
|
|
2853
2714
|
const clips = ctx.canvas.nodes.filter((n) => n.type === "video_generate");
|
|
2854
2715
|
if (clips.length < 2) return;
|
|
@@ -2980,7 +2841,6 @@ var Engine = class {
|
|
|
2980
2841
|
cache;
|
|
2981
2842
|
outputsDir;
|
|
2982
2843
|
log;
|
|
2983
|
-
persistAssets;
|
|
2984
2844
|
constructor(opts) {
|
|
2985
2845
|
this.registry = opts.registry;
|
|
2986
2846
|
this.client = opts.client;
|
|
@@ -2988,7 +2848,6 @@ var Engine = class {
|
|
|
2988
2848
|
this.cache = opts.cache;
|
|
2989
2849
|
this.outputsDir = opts.outputsDir;
|
|
2990
2850
|
this.log = opts.log ?? (() => void 0);
|
|
2991
|
-
this.persistAssets = opts.persistAssets ?? false;
|
|
2992
2851
|
}
|
|
2993
2852
|
validate(canvas) {
|
|
2994
2853
|
return validateCanvas(canvas, this.registry);
|
|
@@ -3035,7 +2894,7 @@ var Engine = class {
|
|
|
3035
2894
|
`[done ] ${stats.cached_nodes}/${stats.total_nodes} cached, ${stats.total_credits} credits, ${stats.duration_ms}ms`
|
|
3036
2895
|
);
|
|
3037
2896
|
this.log(`outputs in: ${writer.runDir}`);
|
|
3038
|
-
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 };
|
|
3039
2898
|
}
|
|
3040
2899
|
async runLayers(canvas, outputs, runId, writer, opts, counters, nodeRuns) {
|
|
3041
2900
|
const layers = topologicalLayers(this.pruneToOutput(canvas, buildGraph(canvas)));
|
|
@@ -3132,14 +2991,6 @@ var Engine = class {
|
|
|
3132
2991
|
const credits = def.cost ? def.cost({ params: parsedParams }).credits : 0;
|
|
3133
2992
|
const outputsObj = result;
|
|
3134
2993
|
outputs[node.id] = outputsObj;
|
|
3135
|
-
if (this.persistAssets) {
|
|
3136
|
-
try {
|
|
3137
|
-
await persistOutputAssetUrls(outputsObj, ctx);
|
|
3138
|
-
} catch (e) {
|
|
3139
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
3140
|
-
this.log(`[warn ] ${node.id}: asset persistence failed (${msg}) \u2014 outputs stay local-only`);
|
|
3141
|
-
}
|
|
3142
|
-
}
|
|
3143
2994
|
if (policy === "read_write") {
|
|
3144
2995
|
await this.cache.put({
|
|
3145
2996
|
cacheKey: prepared.cacheKey,
|
|
@@ -3458,6 +3309,27 @@ var FontRef = BaseAssetRef.extend({
|
|
|
3458
3309
|
});
|
|
3459
3310
|
var AssetRef = z4.discriminatedUnion("kind", [ImageRef, VideoRef, AudioRef, JsonRef, TextRef, FontRef]);
|
|
3460
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
|
+
|
|
3461
3333
|
// src/engine/nodes/remote/delegate.ts
|
|
3462
3334
|
function delegated(spec) {
|
|
3463
3335
|
return {
|
|
@@ -3852,10 +3724,10 @@ function inferKindFromMime(mime) {
|
|
|
3852
3724
|
if (mime.startsWith("font/")) return "font";
|
|
3853
3725
|
return null;
|
|
3854
3726
|
}
|
|
3855
|
-
function localExecError(ctx,
|
|
3727
|
+
function localExecError(ctx, message) {
|
|
3856
3728
|
return new NodeExecutionError(ctx.nodeId, ctx.nodeType, {
|
|
3857
3729
|
kind: "local",
|
|
3858
|
-
cause: new Error(`ingest: ${
|
|
3730
|
+
cause: new Error(`ingest: ${message}`)
|
|
3859
3731
|
});
|
|
3860
3732
|
}
|
|
3861
3733
|
async function execLocalFile(params, ctx) {
|
|
@@ -4522,7 +4394,7 @@ async function refToUrl(ref) {
|
|
|
4522
4394
|
return `data:${ref.mime};base64,${bytes.toString("base64")}`;
|
|
4523
4395
|
}
|
|
4524
4396
|
var ASSET_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
|
|
4525
|
-
function
|
|
4397
|
+
function isAssetRefLike(value) {
|
|
4526
4398
|
if (!value || typeof value !== "object") return false;
|
|
4527
4399
|
const v = value;
|
|
4528
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");
|
|
@@ -4894,8 +4766,8 @@ var NEVER_BLOCK = [
|
|
|
4894
4766
|
/text[_-]?occluded/i
|
|
4895
4767
|
];
|
|
4896
4768
|
var UNAVAILABLE = /unknown command|command not found|not found|Did you mean|Unknown argument|ENOENT/i;
|
|
4897
|
-
function isAdvisory(code,
|
|
4898
|
-
const hay = `${code} ${
|
|
4769
|
+
function isAdvisory(code, message) {
|
|
4770
|
+
const hay = `${code} ${message}`;
|
|
4899
4771
|
return NEVER_BLOCK.some((re) => re.test(hay));
|
|
4900
4772
|
}
|
|
4901
4773
|
function parseCheckJson(raw) {
|
|
@@ -4923,10 +4795,10 @@ function classifyLint(json) {
|
|
|
4923
4795
|
for (const f of findings) {
|
|
4924
4796
|
const rec = f;
|
|
4925
4797
|
const code = String(rec?.code ?? "");
|
|
4926
|
-
const
|
|
4798
|
+
const message = String(rec?.message ?? "");
|
|
4927
4799
|
const severity = String(rec?.severity ?? "info");
|
|
4928
|
-
const blocking = severity === "error" && !isAdvisory(code,
|
|
4929
|
-
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" });
|
|
4930
4802
|
}
|
|
4931
4803
|
return out;
|
|
4932
4804
|
}
|
|
@@ -4938,9 +4810,9 @@ function classifyInspect(json) {
|
|
|
4938
4810
|
for (const iss of issues) {
|
|
4939
4811
|
const rec = iss;
|
|
4940
4812
|
const code = String(rec?.code ?? rec?.type ?? "overflow");
|
|
4941
|
-
const
|
|
4813
|
+
const message = String(rec?.message ?? rec?.detail ?? JSON.stringify(iss));
|
|
4942
4814
|
const severity = rec?.severity ? String(rec.severity) : obj?.ok === false ? "error" : "warning";
|
|
4943
|
-
out.push({ source: "inspect", code, message
|
|
4815
|
+
out.push({ source: "inspect", code, message, severity: severity === "error" ? "blocking" : "warning" });
|
|
4944
4816
|
}
|
|
4945
4817
|
return out;
|
|
4946
4818
|
}
|
|
@@ -5385,7 +5257,7 @@ async function buildSubstitutionValues(compositionParams, meta, duration) {
|
|
|
5385
5257
|
}
|
|
5386
5258
|
function coerceImageParam(value) {
|
|
5387
5259
|
if (typeof value === "string") return Promise.resolve(value);
|
|
5388
|
-
if (
|
|
5260
|
+
if (isAssetRefLike(value)) return refToUrl(value);
|
|
5389
5261
|
throw new Error("hyperframe_render: image param must be a URL string or AssetRef");
|
|
5390
5262
|
}
|
|
5391
5263
|
async function substituteCompositionFiles(tmp, values) {
|
|
@@ -5615,7 +5487,7 @@ async function buildSubstitutionValues2(compositionParams, meta) {
|
|
|
5615
5487
|
}
|
|
5616
5488
|
function coerceImageParam2(value) {
|
|
5617
5489
|
if (typeof value === "string") return Promise.resolve(value);
|
|
5618
|
-
if (
|
|
5490
|
+
if (isAssetRefLike(value)) return refToUrl(value);
|
|
5619
5491
|
throw new Error("hyperframe_snapshot: image param must be a URL string or AssetRef");
|
|
5620
5492
|
}
|
|
5621
5493
|
async function substituteCompositionFiles2(tmp, values) {
|
|
@@ -6641,29 +6513,17 @@ function createEngineFromEnv(opts = {}) {
|
|
|
6641
6513
|
const cacheDir = opts.cacheDir ?? path15.join(cwd, "canvas", ".cache");
|
|
6642
6514
|
const outputsDir = opts.outputsDir ?? path15.join(cwd, "canvas");
|
|
6643
6515
|
const creds = requireCredentialsFromEnv();
|
|
6644
|
-
const client = new BackendClient({ baseUrl: creds.url, apiKey: creds.apiKey });
|
|
6645
|
-
const assets = new LocalAssetStore(path15.join(cacheDir, "assets"));
|
|
6646
|
-
const localCache = new LocalCacheStore(path15.join(cacheDir, "index"));
|
|
6647
|
-
const remoteCacheEnabled = opts.remoteCache ?? remoteCacheEnabledFromEnv();
|
|
6648
|
-
const cache = remoteCacheEnabled ? new LayeredCacheStore({
|
|
6649
|
-
local: localCache,
|
|
6650
|
-
remote: new RemoteCacheStore(client, opts.log),
|
|
6651
|
-
assets,
|
|
6652
|
-
log: opts.log
|
|
6653
|
-
}) : localCache;
|
|
6654
6516
|
return new Engine({
|
|
6655
6517
|
registry: defaultRegistry(),
|
|
6656
|
-
client,
|
|
6657
|
-
assets,
|
|
6658
|
-
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")),
|
|
6659
6521
|
outputsDir,
|
|
6660
|
-
log: opts.log
|
|
6661
|
-
persistAssets: remoteCacheEnabled
|
|
6522
|
+
log: opts.log
|
|
6662
6523
|
});
|
|
6663
6524
|
}
|
|
6664
6525
|
|
|
6665
6526
|
export {
|
|
6666
|
-
requireCredentialsFromEnv,
|
|
6667
6527
|
LayerExecutionError,
|
|
6668
6528
|
describeFailureReason,
|
|
6669
6529
|
SEEDANCE_DURATIONS,
|
|
@@ -6671,10 +6531,7 @@ export {
|
|
|
6671
6531
|
IMAGE_GENERATE_MODELS,
|
|
6672
6532
|
MODEL_REGISTRY,
|
|
6673
6533
|
resolveConcurrency,
|
|
6674
|
-
|
|
6675
|
-
isPersistedAssetRef,
|
|
6676
|
-
collectAssetRefLikes,
|
|
6677
|
-
sha256Hex,
|
|
6534
|
+
elementMentionKeywords,
|
|
6678
6535
|
BackendClient2 as BackendClient,
|
|
6679
6536
|
Engine2 as Engine,
|
|
6680
6537
|
LocalAssetStore2 as LocalAssetStore,
|
|
@@ -6685,4 +6542,4 @@ export {
|
|
|
6685
6542
|
defaultRegistry,
|
|
6686
6543
|
createEngineFromEnv
|
|
6687
6544
|
};
|
|
6688
|
-
//# sourceMappingURL=chunk-
|
|
6545
|
+
//# sourceMappingURL=chunk-MWFJ5NOP.js.map
|