@koda-sl/baker-cli 0.121.0-dev.3b02f951b → 0.121.0-dev.4a71225ab
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 +24 -35
- package/dist/{chunk-7WLX7E7H.js → chunk-MWFJ5NOP.js} +61 -303
- package/dist/chunk-MWFJ5NOP.js.map +1 -0
- package/dist/cli.js +1113 -1225
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.d.ts +0 -30
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-7WLX7E7H.js.map +0 -1
|
@@ -138,9 +138,9 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
138
138
|
}
|
|
139
139
|
if (value) {
|
|
140
140
|
return (value2) => {
|
|
141
|
-
let
|
|
142
|
-
if (typeof value2 !== "function")
|
|
143
|
-
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);
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
146
|
}
|
|
@@ -652,9 +652,6 @@ var HttpClient = class {
|
|
|
652
652
|
async postJson(path16, body, signal) {
|
|
653
653
|
return await this.requestJson("POST", path16, body, signal);
|
|
654
654
|
}
|
|
655
|
-
async putJson(path16, body, signal) {
|
|
656
|
-
return await this.requestJson("PUT", path16, body, signal);
|
|
657
|
-
}
|
|
658
655
|
async getJson(path16, signal) {
|
|
659
656
|
return await this.requestJson("GET", path16, void 0, signal);
|
|
660
657
|
}
|
|
@@ -682,8 +679,8 @@ var HttpClient = class {
|
|
|
682
679
|
try {
|
|
683
680
|
const res = await this.fetchFn(url, {
|
|
684
681
|
method,
|
|
685
|
-
headers: method === "
|
|
686
|
-
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,
|
|
687
684
|
signal: controller.signal
|
|
688
685
|
});
|
|
689
686
|
if (res.ok) return { kind: "value", value: await res.json() };
|
|
@@ -720,33 +717,33 @@ async function parseErrorBody(res) {
|
|
|
720
717
|
const errObj = body.error ?? {};
|
|
721
718
|
return classifyHttpError(res.status, errObj, errObj.message ?? `HTTP ${res.status}`);
|
|
722
719
|
}
|
|
723
|
-
function classifyHttpError(status, errObj,
|
|
720
|
+
function classifyHttpError(status, errObj, message) {
|
|
724
721
|
if (errObj.code === CONTENT_POLICY_CODE) {
|
|
725
|
-
return { kind: "content_policy", status, provider: errObj.provider, message
|
|
722
|
+
return { kind: "content_policy", status, provider: errObj.provider, message };
|
|
726
723
|
}
|
|
727
724
|
if (status === 401 || status === 403) {
|
|
728
|
-
return { kind: "unauthorized", status, message
|
|
725
|
+
return { kind: "unauthorized", status, message };
|
|
729
726
|
}
|
|
730
727
|
if (status === 400 || status === 422) {
|
|
731
|
-
return { kind: "validation", status, message
|
|
728
|
+
return { kind: "validation", status, message, details: errObj.details };
|
|
732
729
|
}
|
|
733
730
|
if (status === 502 || status === 504) {
|
|
734
731
|
if (errObj.code === "provider_timeout" || status === 504) {
|
|
735
|
-
return { kind: "timeout", provider: errObj.provider, message
|
|
732
|
+
return { kind: "timeout", provider: errObj.provider, message };
|
|
736
733
|
}
|
|
737
734
|
return {
|
|
738
735
|
kind: "provider",
|
|
739
736
|
status,
|
|
740
737
|
provider: errObj.provider,
|
|
741
738
|
code: errObj.code ?? "provider_error",
|
|
742
|
-
message
|
|
739
|
+
message,
|
|
743
740
|
retryable: errObj.retryable ?? true
|
|
744
741
|
};
|
|
745
742
|
}
|
|
746
743
|
if (status >= 500 || status === 429) {
|
|
747
|
-
return { kind: "server", status, message
|
|
744
|
+
return { kind: "server", status, message };
|
|
748
745
|
}
|
|
749
|
-
return { kind: "validation", status, message
|
|
746
|
+
return { kind: "validation", status, message, details: errObj.details };
|
|
750
747
|
}
|
|
751
748
|
function backoffMs(attempt) {
|
|
752
749
|
return 1e3 * 2 ** attempt;
|
|
@@ -817,27 +814,6 @@ var BackendClient = class {
|
|
|
817
814
|
signal
|
|
818
815
|
);
|
|
819
816
|
}
|
|
820
|
-
/** Remote cache lookup. A miss (404) — or an old backend without the route — returns null. */
|
|
821
|
-
async getCacheEntry(cacheKey, signal) {
|
|
822
|
-
try {
|
|
823
|
-
const res = await this.http.getJson(`/api/canvas/cache/${encodeURIComponent(cacheKey)}`, signal);
|
|
824
|
-
return res.entry;
|
|
825
|
-
} catch (e) {
|
|
826
|
-
if (e instanceof BackendHttpError && "status" in e.detail && e.detail.status === 404) return null;
|
|
827
|
-
throw e;
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
async putCacheEntry(entry, signal) {
|
|
831
|
-
await this.http.putJson(
|
|
832
|
-
`/api/canvas/cache/${encodeURIComponent(entry.cacheKey)}`,
|
|
833
|
-
entry,
|
|
834
|
-
signal
|
|
835
|
-
);
|
|
836
|
-
}
|
|
837
|
-
/** Durable run-history record — POST /api/canvas/runs (idempotent server-side on runId). */
|
|
838
|
-
async recordRun(payload, signal) {
|
|
839
|
-
await this.http.postJson("/api/canvas/runs", payload, signal);
|
|
840
|
-
}
|
|
841
817
|
getArtifact(kind, name, version, signal) {
|
|
842
818
|
const path16 = version ? `/api/canvas/artifacts/${encodeURIComponent(kind)}/${encodeURIComponent(name)}/${encodeURIComponent(version)}` : `/api/canvas/artifacts/${encodeURIComponent(kind)}/${encodeURIComponent(name)}`;
|
|
843
819
|
return this.http.getJson(path16, signal);
|
|
@@ -861,17 +837,14 @@ function requireCredentialsFromEnv(env = process.env) {
|
|
|
861
837
|
}
|
|
862
838
|
return c;
|
|
863
839
|
}
|
|
864
|
-
function remoteCacheEnabledFromEnv(env = process.env) {
|
|
865
|
-
return env.BAKER_CANVAS_REMOTE_CACHE !== "off";
|
|
866
|
-
}
|
|
867
840
|
|
|
868
841
|
// src/engine/engine/errors.ts
|
|
869
842
|
function isBlocking(issue) {
|
|
870
843
|
return issue.severity !== "warning";
|
|
871
844
|
}
|
|
872
845
|
var CanvasError = class extends Error {
|
|
873
|
-
constructor(
|
|
874
|
-
super(
|
|
846
|
+
constructor(message) {
|
|
847
|
+
super(message);
|
|
875
848
|
this.name = "CanvasError";
|
|
876
849
|
}
|
|
877
850
|
};
|
|
@@ -1589,160 +1562,6 @@ function encodeRandom() {
|
|
|
1589
1562
|
return out;
|
|
1590
1563
|
}
|
|
1591
1564
|
|
|
1592
|
-
// src/engine/storage/remote-cache-store.ts
|
|
1593
|
-
var CANVAS_ASSETS_URL_SEGMENT = "/canvas-assets/";
|
|
1594
|
-
function isPersistedAssetRef(ref) {
|
|
1595
|
-
const { url, sha256 } = ref;
|
|
1596
|
-
if (typeof url !== "string" || typeof sha256 !== "string") return false;
|
|
1597
|
-
return url.includes(`${CANVAS_ASSETS_URL_SEGMENT}${sha256.slice(0, 2)}/${sha256}`) || url.includes(`${CANVAS_ASSETS_URL_SEGMENT}${sha256}`);
|
|
1598
|
-
}
|
|
1599
|
-
function isAssetRefLike(value) {
|
|
1600
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && typeof value.sha256 === "string" && typeof value.mime === "string";
|
|
1601
|
-
}
|
|
1602
|
-
function collectAssetRefLikes(value, out = []) {
|
|
1603
|
-
if (Array.isArray(value)) {
|
|
1604
|
-
for (const item of value) collectAssetRefLikes(item, out);
|
|
1605
|
-
return out;
|
|
1606
|
-
}
|
|
1607
|
-
if (typeof value !== "object" || value === null) return out;
|
|
1608
|
-
if (isAssetRefLike(value)) {
|
|
1609
|
-
out.push(value);
|
|
1610
|
-
}
|
|
1611
|
-
for (const item of Object.values(value)) collectAssetRefLikes(item, out);
|
|
1612
|
-
return out;
|
|
1613
|
-
}
|
|
1614
|
-
function entryFullyPersisted(entry) {
|
|
1615
|
-
return collectAssetRefLikes(entry.outputs).every((ref) => isPersistedAssetRef(ref));
|
|
1616
|
-
}
|
|
1617
|
-
function stripLocalFields(entry) {
|
|
1618
|
-
const clone = JSON.parse(JSON.stringify(entry));
|
|
1619
|
-
for (const ref of collectAssetRefLikes(clone.outputs)) {
|
|
1620
|
-
delete ref.path;
|
|
1621
|
-
delete ref.bytes;
|
|
1622
|
-
}
|
|
1623
|
-
return clone;
|
|
1624
|
-
}
|
|
1625
|
-
var RemoteCacheStore = class {
|
|
1626
|
-
client;
|
|
1627
|
-
log;
|
|
1628
|
-
constructor(client, log) {
|
|
1629
|
-
this.client = client;
|
|
1630
|
-
this.log = log ?? (() => void 0);
|
|
1631
|
-
}
|
|
1632
|
-
async get(cacheKey) {
|
|
1633
|
-
return await this.client.getCacheEntry(cacheKey);
|
|
1634
|
-
}
|
|
1635
|
-
async put(entry) {
|
|
1636
|
-
if (!entryFullyPersisted(entry)) {
|
|
1637
|
-
this.log(`[cache ] ${entry.cacheKey.slice(0, 12)}\u2026 has local-only assets, kept local`);
|
|
1638
|
-
return;
|
|
1639
|
-
}
|
|
1640
|
-
const stripped = stripLocalFields(entry);
|
|
1641
|
-
if (stripped.refs.length > MAX_REMOTE_REFS) {
|
|
1642
|
-
stripped.refs = stripped.refs.slice(0, MAX_REMOTE_REFS);
|
|
1643
|
-
}
|
|
1644
|
-
await this.client.putCacheEntry(stripped);
|
|
1645
|
-
}
|
|
1646
|
-
};
|
|
1647
|
-
var MAX_REMOTE_REFS = 512;
|
|
1648
|
-
var LayeredCacheStore = class {
|
|
1649
|
-
rootDir;
|
|
1650
|
-
local;
|
|
1651
|
-
remote;
|
|
1652
|
-
assets;
|
|
1653
|
-
log;
|
|
1654
|
-
constructor(opts) {
|
|
1655
|
-
this.local = opts.local;
|
|
1656
|
-
this.remote = opts.remote;
|
|
1657
|
-
this.assets = opts.assets;
|
|
1658
|
-
this.rootDir = opts.local.rootDir;
|
|
1659
|
-
this.log = opts.log ?? (() => void 0);
|
|
1660
|
-
}
|
|
1661
|
-
async get(cacheKey) {
|
|
1662
|
-
const localHit = await this.local.get(cacheKey);
|
|
1663
|
-
if (localHit) return localHit;
|
|
1664
|
-
let remoteEntry;
|
|
1665
|
-
try {
|
|
1666
|
-
remoteEntry = await this.remote.get(cacheKey);
|
|
1667
|
-
} catch (e) {
|
|
1668
|
-
this.log(`[cache ] remote lookup failed (${message(e)}) \u2014 treating as miss`);
|
|
1669
|
-
return null;
|
|
1670
|
-
}
|
|
1671
|
-
if (!remoteEntry) return null;
|
|
1672
|
-
let rehydrated;
|
|
1673
|
-
try {
|
|
1674
|
-
rehydrated = await this.rehydrate(remoteEntry);
|
|
1675
|
-
} catch (e) {
|
|
1676
|
-
this.log(`[cache ] ${cacheKey.slice(0, 12)}\u2026 rehydration failed (${message(e)}) \u2014 treating as miss`);
|
|
1677
|
-
return null;
|
|
1678
|
-
}
|
|
1679
|
-
await this.local.put(rehydrated);
|
|
1680
|
-
return rehydrated;
|
|
1681
|
-
}
|
|
1682
|
-
async put(entry) {
|
|
1683
|
-
await this.local.put(entry);
|
|
1684
|
-
try {
|
|
1685
|
-
await this.remote.put(entry);
|
|
1686
|
-
} catch (e) {
|
|
1687
|
-
this.log(`[cache ] remote write failed (${message(e)}) \u2014 entry kept local`);
|
|
1688
|
-
}
|
|
1689
|
-
}
|
|
1690
|
-
/**
|
|
1691
|
-
* Download every referenced asset into the local content-addressed store
|
|
1692
|
-
* (sha-verified) and stamp fresh local paths. Any ref that cannot be
|
|
1693
|
-
* rehydrated fails the WHOLE entry — a partially-hydrated cache hit would
|
|
1694
|
-
* crash materialization later with a far less actionable error.
|
|
1695
|
-
*/
|
|
1696
|
-
async rehydrate(entry) {
|
|
1697
|
-
const clone = JSON.parse(JSON.stringify(entry));
|
|
1698
|
-
for (const ref of collectAssetRefLikes(clone.outputs)) {
|
|
1699
|
-
if (!isPersistedAssetRef(ref)) {
|
|
1700
|
-
throw new Error(`ref ${ref.sha256.slice(0, 12)}\u2026 has no persisted url`);
|
|
1701
|
-
}
|
|
1702
|
-
const ingested = await this.assets.ingestRemote({
|
|
1703
|
-
kind: typeof ref.kind === "string" ? ref.kind : "json",
|
|
1704
|
-
url: ref.url,
|
|
1705
|
-
sha256: ref.sha256,
|
|
1706
|
-
mime: ref.mime,
|
|
1707
|
-
metadata: ref.metadata ?? void 0
|
|
1708
|
-
});
|
|
1709
|
-
ref.path = ingested.path;
|
|
1710
|
-
}
|
|
1711
|
-
return clone;
|
|
1712
|
-
}
|
|
1713
|
-
};
|
|
1714
|
-
function message(e) {
|
|
1715
|
-
return e instanceof Error ? e.message : String(e);
|
|
1716
|
-
}
|
|
1717
|
-
|
|
1718
|
-
// src/engine/nodes/remote/upload.ts
|
|
1719
|
-
async function presignAndPut(args) {
|
|
1720
|
-
const { putUrl, publicUrl } = await args.ctx.client.presignAssetUpload(args.sha256, args.mime, args.ctx.signal);
|
|
1721
|
-
const putRes = await fetch(putUrl, {
|
|
1722
|
-
method: "PUT",
|
|
1723
|
-
body: new Uint8Array(args.bytes),
|
|
1724
|
-
headers: { "Content-Type": args.mime },
|
|
1725
|
-
signal: args.ctx.signal
|
|
1726
|
-
});
|
|
1727
|
-
if (!putRes.ok) {
|
|
1728
|
-
throw new Error(`upload: presigned PUT failed ${putRes.status} ${putRes.statusText}`);
|
|
1729
|
-
}
|
|
1730
|
-
return publicUrl;
|
|
1731
|
-
}
|
|
1732
|
-
async function ensureUploaded(ref, ctx) {
|
|
1733
|
-
if (ref.url) return ref;
|
|
1734
|
-
const bytes = await ctx.assets.readBytes(ref.sha256, ref.mime);
|
|
1735
|
-
const url = await presignAndPut({ bytes, sha256: ref.sha256, mime: ref.mime, ctx });
|
|
1736
|
-
return { ...ref, url };
|
|
1737
|
-
}
|
|
1738
|
-
async function persistOutputAssetUrls(outputs, ctx) {
|
|
1739
|
-
for (const ref of collectAssetRefLikes(outputs)) {
|
|
1740
|
-
if (isPersistedAssetRef(ref)) continue;
|
|
1741
|
-
const bytes = await ctx.assets.readBytes(ref.sha256, ref.mime);
|
|
1742
|
-
ref.url = await presignAndPut({ bytes, sha256: ref.sha256, mime: ref.mime, ctx });
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
1565
|
// src/engine/schema/canvas.ts
|
|
1747
1566
|
import { z } from "zod";
|
|
1748
1567
|
var REF_PREFIX = "$ref:";
|
|
@@ -3022,7 +2841,6 @@ var Engine = class {
|
|
|
3022
2841
|
cache;
|
|
3023
2842
|
outputsDir;
|
|
3024
2843
|
log;
|
|
3025
|
-
persistAssets;
|
|
3026
2844
|
constructor(opts) {
|
|
3027
2845
|
this.registry = opts.registry;
|
|
3028
2846
|
this.client = opts.client;
|
|
@@ -3030,7 +2848,6 @@ var Engine = class {
|
|
|
3030
2848
|
this.cache = opts.cache;
|
|
3031
2849
|
this.outputsDir = opts.outputsDir;
|
|
3032
2850
|
this.log = opts.log ?? (() => void 0);
|
|
3033
|
-
this.persistAssets = opts.persistAssets ?? false;
|
|
3034
2851
|
}
|
|
3035
2852
|
validate(canvas) {
|
|
3036
2853
|
return validateCanvas(canvas, this.registry);
|
|
@@ -3077,7 +2894,7 @@ var Engine = class {
|
|
|
3077
2894
|
`[done ] ${stats.cached_nodes}/${stats.total_nodes} cached, ${stats.total_credits} credits, ${stats.duration_ms}ms`
|
|
3078
2895
|
);
|
|
3079
2896
|
this.log(`outputs in: ${writer.runDir}`);
|
|
3080
|
-
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 };
|
|
3081
2898
|
}
|
|
3082
2899
|
async runLayers(canvas, outputs, runId, writer, opts, counters, nodeRuns) {
|
|
3083
2900
|
const layers = topologicalLayers(this.pruneToOutput(canvas, buildGraph(canvas)));
|
|
@@ -3174,14 +2991,6 @@ var Engine = class {
|
|
|
3174
2991
|
const credits = def.cost ? def.cost({ params: parsedParams }).credits : 0;
|
|
3175
2992
|
const outputsObj = result;
|
|
3176
2993
|
outputs[node.id] = outputsObj;
|
|
3177
|
-
if (this.persistAssets) {
|
|
3178
|
-
try {
|
|
3179
|
-
await persistOutputAssetUrls(outputsObj, ctx);
|
|
3180
|
-
} catch (e) {
|
|
3181
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
3182
|
-
this.log(`[warn ] ${node.id}: asset persistence failed (${msg}) \u2014 outputs stay local-only`);
|
|
3183
|
-
}
|
|
3184
|
-
}
|
|
3185
2994
|
if (policy === "read_write") {
|
|
3186
2995
|
await this.cache.put({
|
|
3187
2996
|
cacheKey: prepared.cacheKey,
|
|
@@ -3500,6 +3309,27 @@ var FontRef = BaseAssetRef.extend({
|
|
|
3500
3309
|
});
|
|
3501
3310
|
var AssetRef = z4.discriminatedUnion("kind", [ImageRef, VideoRef, AudioRef, JsonRef, TextRef, FontRef]);
|
|
3502
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
|
+
|
|
3503
3333
|
// src/engine/nodes/remote/delegate.ts
|
|
3504
3334
|
function delegated(spec) {
|
|
3505
3335
|
return {
|
|
@@ -3693,7 +3523,7 @@ function safePathname(rawUrl) {
|
|
|
3693
3523
|
}
|
|
3694
3524
|
var ingestNode = defineNode({
|
|
3695
3525
|
id: "ingest",
|
|
3696
|
-
version: "1.
|
|
3526
|
+
version: "1.1.0",
|
|
3697
3527
|
category: "io",
|
|
3698
3528
|
location: "local",
|
|
3699
3529
|
summary: "Ingest an external URL or a local file into the asset store. Declare the kind you expect (image/video/audio/text/json/font); the node picks the strategy. For source=url: yt-dlp for video/audio (YouTube/TikTok/Vimeo/etc. and direct file URLs), Handinger for HTML/PDF pages \u2192 markdown, direct HTTP fetch for binary URLs (images, fonts) and raw .txt/.md. For source=path: read from the local filesystem and upload to R2.",
|
|
@@ -3736,9 +3566,6 @@ function runStrategy(strategy, params, ctx) {
|
|
|
3736
3566
|
}
|
|
3737
3567
|
}
|
|
3738
3568
|
async function execDirectFetch(params, ctx) {
|
|
3739
|
-
if (params.expect === "image") {
|
|
3740
|
-
return ingestImageUrl(params.url, ctx);
|
|
3741
|
-
}
|
|
3742
3569
|
const result = await callBackendExec({
|
|
3743
3570
|
nodeType: "ingest",
|
|
3744
3571
|
nodeVersion: ingestNode.version,
|
|
@@ -3749,37 +3576,6 @@ async function execDirectFetch(params, ctx) {
|
|
|
3749
3576
|
});
|
|
3750
3577
|
return assertAssetOutput(result, params.expect);
|
|
3751
3578
|
}
|
|
3752
|
-
async function ingestImageUrl(url, ctx) {
|
|
3753
|
-
const res = await fetch(url);
|
|
3754
|
-
if (!res.ok) {
|
|
3755
|
-
throw localExecError(ctx, `fetch ${url} \u2192 ${res.status}`);
|
|
3756
|
-
}
|
|
3757
|
-
const ab = await res.arrayBuffer();
|
|
3758
|
-
if (ab.byteLength > MAX_ASSET_BYTES) {
|
|
3759
|
-
throw localExecError(ctx, `file_too_large: ${url} is ${ab.byteLength} bytes (limit ${MAX_ASSET_BYTES})`);
|
|
3760
|
-
}
|
|
3761
|
-
let normalized;
|
|
3762
|
-
try {
|
|
3763
|
-
normalized = await toModelSafeImage(Buffer.from(ab));
|
|
3764
|
-
} catch (e) {
|
|
3765
|
-
throw localExecError(ctx, `${url}: ${e.message}`);
|
|
3766
|
-
}
|
|
3767
|
-
if (normalized.rasterizedFrom) {
|
|
3768
|
-
ctx.log(`ingest: normalized ${normalized.rasterizedFrom} URL -> PNG (${normalized.bytes.length}B)`);
|
|
3769
|
-
}
|
|
3770
|
-
return uploadAndIngest({
|
|
3771
|
-
bytes: normalized.bytes,
|
|
3772
|
-
kind: "image",
|
|
3773
|
-
mime: normalized.mime,
|
|
3774
|
-
metadata: {
|
|
3775
|
-
source_url: url,
|
|
3776
|
-
strategy: "direct_fetch",
|
|
3777
|
-
ingested_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3778
|
-
...normalized.rasterizedFrom ? { rasterized_from: normalized.rasterizedFrom } : {}
|
|
3779
|
-
},
|
|
3780
|
-
ctx
|
|
3781
|
-
});
|
|
3782
|
-
}
|
|
3783
3579
|
async function execHandinger(params, ctx) {
|
|
3784
3580
|
const result = await callBackendExec({
|
|
3785
3581
|
nodeType: "ingest",
|
|
@@ -3867,25 +3663,6 @@ async function rasterizeSvgToPng(bytes) {
|
|
|
3867
3663
|
}
|
|
3868
3664
|
return await sharp(bytes, { density }).png({ force: true, palette: false }).toBuffer();
|
|
3869
3665
|
}
|
|
3870
|
-
var MODEL_SAFE_IMAGE_MIMES = /* @__PURE__ */ new Set(["image/jpeg", "image/png", "image/gif", "image/webp"]);
|
|
3871
|
-
async function toModelSafeImage(bytes) {
|
|
3872
|
-
const safe = sniffImageMime(bytes);
|
|
3873
|
-
if (safe && MODEL_SAFE_IMAGE_MIMES.has(safe)) {
|
|
3874
|
-
return { bytes, mime: safe };
|
|
3875
|
-
}
|
|
3876
|
-
if (sniffSvg(bytes)) {
|
|
3877
|
-
return { bytes: await rasterizeSvgToPng(bytes), mime: "image/png", rasterizedFrom: "svg" };
|
|
3878
|
-
}
|
|
3879
|
-
const { default: sharp } = await import("sharp");
|
|
3880
|
-
try {
|
|
3881
|
-
const img = sharp(bytes);
|
|
3882
|
-
const format = (await img.metadata()).format;
|
|
3883
|
-
const png = await img.png({ force: true }).toBuffer();
|
|
3884
|
-
return { bytes: png, mime: "image/png", rasterizedFrom: format ?? "unknown" };
|
|
3885
|
-
} catch (e) {
|
|
3886
|
-
throw new Error(`bytes are not a decodable image (${e.message})`);
|
|
3887
|
-
}
|
|
3888
|
-
}
|
|
3889
3666
|
function sniffImageMime(buf) {
|
|
3890
3667
|
if (buf.length < 4) return null;
|
|
3891
3668
|
if (buf[0] === 137 && buf[1] === 80 && buf[2] === 78 && buf[3] === 71) return "image/png";
|
|
@@ -3947,10 +3724,10 @@ function inferKindFromMime(mime) {
|
|
|
3947
3724
|
if (mime.startsWith("font/")) return "font";
|
|
3948
3725
|
return null;
|
|
3949
3726
|
}
|
|
3950
|
-
function localExecError(ctx,
|
|
3727
|
+
function localExecError(ctx, message) {
|
|
3951
3728
|
return new NodeExecutionError(ctx.nodeId, ctx.nodeType, {
|
|
3952
3729
|
kind: "local",
|
|
3953
|
-
cause: new Error(`ingest: ${
|
|
3730
|
+
cause: new Error(`ingest: ${message}`)
|
|
3954
3731
|
});
|
|
3955
3732
|
}
|
|
3956
3733
|
async function execLocalFile(params, ctx) {
|
|
@@ -3997,20 +3774,17 @@ async function execLocalFile(params, ctx) {
|
|
|
3997
3774
|
ctx.log(`ingest: local file ${stats.size}B mime=${mime}`);
|
|
3998
3775
|
let outBytes = bytes;
|
|
3999
3776
|
let outMime = mime;
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
outMime = normalized.mime;
|
|
4005
|
-
rasterizedFrom = normalized.rasterizedFrom;
|
|
4006
|
-
if (rasterizedFrom) ctx.log(`ingest: normalized ${rasterizedFrom} -> PNG (${outBytes.length}B)`);
|
|
3777
|
+
if (mime === SVG_MIME) {
|
|
3778
|
+
outBytes = await rasterizeSvgToPng(bytes);
|
|
3779
|
+
outMime = "image/png";
|
|
3780
|
+
ctx.log(`ingest: rasterized SVG -> PNG (${outBytes.length}B)`);
|
|
4007
3781
|
}
|
|
4008
3782
|
const durationMs = probeVideoDurationMs(params.expect, outBytes, ctx);
|
|
4009
3783
|
const ref = await uploadAndIngest({
|
|
4010
3784
|
bytes: outBytes,
|
|
4011
3785
|
kind: params.expect,
|
|
4012
3786
|
mime: outMime,
|
|
4013
|
-
metadata: localFileMetadata({ absPath, fileSize: stats.size, mime, durationMs
|
|
3787
|
+
metadata: localFileMetadata({ absPath, fileSize: stats.size, mime, durationMs }),
|
|
4014
3788
|
ctx
|
|
4015
3789
|
});
|
|
4016
3790
|
return withProbedDuration(ref, durationMs);
|
|
@@ -4028,7 +3802,7 @@ function localFileMetadata(args) {
|
|
|
4028
3802
|
ingested_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4029
3803
|
file_size: args.fileSize,
|
|
4030
3804
|
original_filename: path3.basename(args.absPath),
|
|
4031
|
-
...args.
|
|
3805
|
+
...args.mime === SVG_MIME ? { rasterized_from: "svg" } : {},
|
|
4032
3806
|
...args.durationMs !== void 0 ? { duration_ms: args.durationMs } : {}
|
|
4033
3807
|
};
|
|
4034
3808
|
}
|
|
@@ -4620,7 +4394,7 @@ async function refToUrl(ref) {
|
|
|
4620
4394
|
return `data:${ref.mime};base64,${bytes.toString("base64")}`;
|
|
4621
4395
|
}
|
|
4622
4396
|
var ASSET_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
|
|
4623
|
-
function
|
|
4397
|
+
function isAssetRefLike(value) {
|
|
4624
4398
|
if (!value || typeof value !== "object") return false;
|
|
4625
4399
|
const v = value;
|
|
4626
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");
|
|
@@ -4992,8 +4766,8 @@ var NEVER_BLOCK = [
|
|
|
4992
4766
|
/text[_-]?occluded/i
|
|
4993
4767
|
];
|
|
4994
4768
|
var UNAVAILABLE = /unknown command|command not found|not found|Did you mean|Unknown argument|ENOENT/i;
|
|
4995
|
-
function isAdvisory(code,
|
|
4996
|
-
const hay = `${code} ${
|
|
4769
|
+
function isAdvisory(code, message) {
|
|
4770
|
+
const hay = `${code} ${message}`;
|
|
4997
4771
|
return NEVER_BLOCK.some((re) => re.test(hay));
|
|
4998
4772
|
}
|
|
4999
4773
|
function parseCheckJson(raw) {
|
|
@@ -5021,10 +4795,10 @@ function classifyLint(json) {
|
|
|
5021
4795
|
for (const f of findings) {
|
|
5022
4796
|
const rec = f;
|
|
5023
4797
|
const code = String(rec?.code ?? "");
|
|
5024
|
-
const
|
|
4798
|
+
const message = String(rec?.message ?? "");
|
|
5025
4799
|
const severity = String(rec?.severity ?? "info");
|
|
5026
|
-
const blocking = severity === "error" && !isAdvisory(code,
|
|
5027
|
-
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" });
|
|
5028
4802
|
}
|
|
5029
4803
|
return out;
|
|
5030
4804
|
}
|
|
@@ -5036,9 +4810,9 @@ function classifyInspect(json) {
|
|
|
5036
4810
|
for (const iss of issues) {
|
|
5037
4811
|
const rec = iss;
|
|
5038
4812
|
const code = String(rec?.code ?? rec?.type ?? "overflow");
|
|
5039
|
-
const
|
|
4813
|
+
const message = String(rec?.message ?? rec?.detail ?? JSON.stringify(iss));
|
|
5040
4814
|
const severity = rec?.severity ? String(rec.severity) : obj?.ok === false ? "error" : "warning";
|
|
5041
|
-
out.push({ source: "inspect", code, message
|
|
4815
|
+
out.push({ source: "inspect", code, message, severity: severity === "error" ? "blocking" : "warning" });
|
|
5042
4816
|
}
|
|
5043
4817
|
return out;
|
|
5044
4818
|
}
|
|
@@ -5483,7 +5257,7 @@ async function buildSubstitutionValues(compositionParams, meta, duration) {
|
|
|
5483
5257
|
}
|
|
5484
5258
|
function coerceImageParam(value) {
|
|
5485
5259
|
if (typeof value === "string") return Promise.resolve(value);
|
|
5486
|
-
if (
|
|
5260
|
+
if (isAssetRefLike(value)) return refToUrl(value);
|
|
5487
5261
|
throw new Error("hyperframe_render: image param must be a URL string or AssetRef");
|
|
5488
5262
|
}
|
|
5489
5263
|
async function substituteCompositionFiles(tmp, values) {
|
|
@@ -5713,7 +5487,7 @@ async function buildSubstitutionValues2(compositionParams, meta) {
|
|
|
5713
5487
|
}
|
|
5714
5488
|
function coerceImageParam2(value) {
|
|
5715
5489
|
if (typeof value === "string") return Promise.resolve(value);
|
|
5716
|
-
if (
|
|
5490
|
+
if (isAssetRefLike(value)) return refToUrl(value);
|
|
5717
5491
|
throw new Error("hyperframe_snapshot: image param must be a URL string or AssetRef");
|
|
5718
5492
|
}
|
|
5719
5493
|
async function substituteCompositionFiles2(tmp, values) {
|
|
@@ -6739,29 +6513,17 @@ function createEngineFromEnv(opts = {}) {
|
|
|
6739
6513
|
const cacheDir = opts.cacheDir ?? path15.join(cwd, "canvas", ".cache");
|
|
6740
6514
|
const outputsDir = opts.outputsDir ?? path15.join(cwd, "canvas");
|
|
6741
6515
|
const creds = requireCredentialsFromEnv();
|
|
6742
|
-
const client = new BackendClient({ baseUrl: creds.url, apiKey: creds.apiKey });
|
|
6743
|
-
const assets = new LocalAssetStore(path15.join(cacheDir, "assets"));
|
|
6744
|
-
const localCache = new LocalCacheStore(path15.join(cacheDir, "index"));
|
|
6745
|
-
const remoteCacheEnabled = opts.remoteCache ?? remoteCacheEnabledFromEnv();
|
|
6746
|
-
const cache = remoteCacheEnabled ? new LayeredCacheStore({
|
|
6747
|
-
local: localCache,
|
|
6748
|
-
remote: new RemoteCacheStore(client, opts.log),
|
|
6749
|
-
assets,
|
|
6750
|
-
log: opts.log
|
|
6751
|
-
}) : localCache;
|
|
6752
6516
|
return new Engine({
|
|
6753
6517
|
registry: defaultRegistry(),
|
|
6754
|
-
client,
|
|
6755
|
-
assets,
|
|
6756
|
-
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")),
|
|
6757
6521
|
outputsDir,
|
|
6758
|
-
log: opts.log
|
|
6759
|
-
persistAssets: remoteCacheEnabled
|
|
6522
|
+
log: opts.log
|
|
6760
6523
|
});
|
|
6761
6524
|
}
|
|
6762
6525
|
|
|
6763
6526
|
export {
|
|
6764
|
-
requireCredentialsFromEnv,
|
|
6765
6527
|
LayerExecutionError,
|
|
6766
6528
|
describeFailureReason,
|
|
6767
6529
|
SEEDANCE_DURATIONS,
|
|
@@ -6769,10 +6531,6 @@ export {
|
|
|
6769
6531
|
IMAGE_GENERATE_MODELS,
|
|
6770
6532
|
MODEL_REGISTRY,
|
|
6771
6533
|
resolveConcurrency,
|
|
6772
|
-
ulid,
|
|
6773
|
-
isPersistedAssetRef,
|
|
6774
|
-
collectAssetRefLikes,
|
|
6775
|
-
sha256Hex,
|
|
6776
6534
|
elementMentionKeywords,
|
|
6777
6535
|
BackendClient2 as BackendClient,
|
|
6778
6536
|
Engine2 as Engine,
|
|
@@ -6784,4 +6542,4 @@ export {
|
|
|
6784
6542
|
defaultRegistry,
|
|
6785
6543
|
createEngineFromEnv
|
|
6786
6544
|
};
|
|
6787
|
-
//# sourceMappingURL=chunk-
|
|
6545
|
+
//# sourceMappingURL=chunk-MWFJ5NOP.js.map
|