@koda-sl/baker-cli 0.294.0 → 0.295.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -12
- package/dist/{chunk-NNQDWCFG.js → chunk-YFQWCJX4.js} +22 -9
- package/dist/chunk-YFQWCJX4.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-NNQDWCFG.js.map +0 -1
package/README.md
CHANGED
|
@@ -4018,7 +4018,7 @@ Pick a `source` discriminator and declare the kind you expect. See [Ingestion](#
|
|
|
4018
4018
|
|
|
4019
4019
|
**Params** — discriminated on `source`:
|
|
4020
4020
|
|
|
4021
|
-
`source: "url"` (yt-dlp / direct fetch /
|
|
4021
|
+
`source: "url"` (yt-dlp / direct fetch / Firecrawl):
|
|
4022
4022
|
|
|
4023
4023
|
| Name | Type | Required | Constraint |
|
|
4024
4024
|
|---|---|---|---|
|
|
@@ -4038,7 +4038,7 @@ Pick a `source` discriminator and declare the kind you expect. See [Ingestion](#
|
|
|
4038
4038
|
|
|
4039
4039
|
**Path-source notes:** the canvas is **not portable** to another machine without the file. Cache key folds the file's `mtime:size`, so editing the file invalidates the cache automatically. Supported extensions: `png`, `jpg`/`jpeg`, `webp`, `gif`, `avif`, `svg`, `mp4`, `webm`, `mov`, `m4v`, `mp3`, `wav`, `m4a`, `ogg`, `flac`, `json`, `txt`, `md`, `markdown`, `html`/`htm`, `csv`, `ttf`, `otf`, `woff`, `woff2`. Unknown extensions fall back to magic-byte sniffing for common image formats (and an SVG content sniff), else `kind_mismatch`. **Any `expect: "image"` in a format image-generation models can't read (SVG, AVIF, HEIC, TIFF, BMP) is normalized to PNG on ingest** — model-safe rasters (`jpeg`/`png`/`gif`/`webp`) pass through untouched, everything else is transcoded so a reference can never 400 a generation. This applies to **both `source: "path"` and `source: "url"`** (URL images are fetched and normalized locally, since the backend can't run the rasterizer). SVG gets density-aware upscaling (longest edge near 2048px, transparency preserved). The normalized asset carries `metadata.rasterized_from` set to the source format (e.g. `"svg"`, `"avif"`). **Video (`expect: "video"`) duration is probed from the file's ISO-BMFF (`mp4`/`mov`/`m4v`) header** and stamped as the canonical `duration_ms` (and `metadata.duration_ms`); other containers (e.g. `webm`) leave it unset. Downstream `video_deconstruct` uses this declared duration to size its ingest-poll timeout and preflight — without it those fall back to worst-case budgets and a single deconstruct step can hit the action time limit.
|
|
4040
4040
|
|
|
4041
|
-
**Cost:** 0 engine credits for direct fetch + yt-dlp + local file.
|
|
4041
|
+
**Cost:** 0 engine credits for direct fetch + yt-dlp + local file. Firecrawl charges per scrape.
|
|
4042
4042
|
|
|
4043
4043
|
---
|
|
4044
4044
|
|
|
@@ -5352,10 +5352,10 @@ baker canvas catalog | jq '.compositions[].id'
|
|
|
5352
5352
|
// URL source — YouTube audio-only (yt-dlp -x)
|
|
5353
5353
|
{ "id": "src", "type": "ingest", "params": { "source": "url", "url": "https://youtu.be/dQw4w9WgXcQ", "expect": "audio" } }
|
|
5354
5354
|
|
|
5355
|
-
// URL source — blog post → clean markdown (
|
|
5355
|
+
// URL source — blog post → clean markdown (Firecrawl)
|
|
5356
5356
|
{ "id": "src", "type": "ingest", "params": { "source": "url", "url": "https://example.com/blog/post", "expect": "text" } }
|
|
5357
5357
|
|
|
5358
|
-
// URL source — PDF → markdown (
|
|
5358
|
+
// URL source — PDF → markdown (Firecrawl handles PDFs)
|
|
5359
5359
|
{ "id": "src", "type": "ingest", "params": { "source": "url", "url": "https://example.com/whitepaper.pdf", "expect": "text" } }
|
|
5360
5360
|
|
|
5361
5361
|
// URL source — raw markdown file (direct fetch)
|
|
@@ -5383,7 +5383,7 @@ baker canvas catalog | jq '.compositions[].id'
|
|
|
5383
5383
|
| url | video / audio | any | `yt_dlp` (works on platform URLs *and* direct file URLs via the generic extractor) |
|
|
5384
5384
|
| url | image / json / font | any | `direct_fetch` (HTTP GET) |
|
|
5385
5385
|
| url | text | ends in `.txt` or `.md` | `direct_fetch` |
|
|
5386
|
-
| url | text | anything else (HTML, PDF, …) | `
|
|
5386
|
+
| url | text | anything else (HTML, PDF, …) | `firecrawl` `/v2/scrape` (extracted markdown — HTML/PDF made readable) |
|
|
5387
5387
|
|
|
5388
5388
|
If the bytes' mime contradicts `expect` (e.g. `expect: "image"` but the URL serves `text/html`, or a `.pdf` file is passed as `expect: "image"`), the node fails with a clear `kind_mismatch` error instead of forwarding bad bytes downstream.
|
|
5389
5389
|
|
|
@@ -5426,7 +5426,7 @@ If the bytes' mime contradicts `expect` (e.g. `expect: "image"` but the URL serv
|
|
|
5426
5426
|
file_size?: number, // bytes
|
|
5427
5427
|
original_filename?: string, // basename of the source path
|
|
5428
5428
|
|
|
5429
|
-
strategy: "direct_fetch" | "
|
|
5429
|
+
strategy: "direct_fetch" | "firecrawl" | "yt_dlp" | "local_file",
|
|
5430
5430
|
ingested_at: string, // ISO 8601 timestamp
|
|
5431
5431
|
|
|
5432
5432
|
// yt-dlp adds (when available from --dump-json):
|
|
@@ -5437,7 +5437,7 @@ If the bytes' mime contradicts `expect` (e.g. `expect: "image"` but the URL serv
|
|
|
5437
5437
|
width?: number,
|
|
5438
5438
|
height?: number,
|
|
5439
5439
|
|
|
5440
|
-
//
|
|
5440
|
+
// Firecrawl adds:
|
|
5441
5441
|
word_count?: number,
|
|
5442
5442
|
},
|
|
5443
5443
|
|
|
@@ -5456,8 +5456,8 @@ The `url` is a stable R2 URL — remote downstream nodes (e.g. `video_lipsync`)
|
|
|
5456
5456
|
|-----------------------|----------------|------------------------------------------------------------------------------|
|
|
5457
5457
|
| `INVALID_PARAMS` | engine validator | Missing/malformed fields, mixing `url` + `path`, unknown `source`, unknown `expect`. |
|
|
5458
5458
|
| `kind_mismatch` | url + direct_fetch | URL returned bytes whose mime doesn't match `expect`. Message: `ingest expect=<X> but <url> returned <mime> (kind=<Y>)`. |
|
|
5459
|
-
| `kind_mismatch` | path + local_file | File mime (from extension or magic-byte sniff) doesn't match `expect`, *or* mime doesn't map to any of our kinds (e.g. local PDFs aren't supported as `text` — host them via URL for
|
|
5460
|
-
| `provider_error` | url +
|
|
5459
|
+
| `kind_mismatch` | path + local_file | File mime (from extension or magic-byte sniff) doesn't match `expect`, *or* mime doesn't map to any of our kinds (e.g. local PDFs aren't supported as `text` — host them via URL for Firecrawl to extract). |
|
|
5460
|
+
| `provider_error` | url + firecrawl / direct_fetch | Firecrawl `/v2/scrape` non-2xx or no markdown in the response, **or the target site answering 4xx/5xx** (Firecrawl reports that inside a 200 carrying the error page, so it is refused rather than stored as the page), or upstream `fetch` non-ok. Terminal: a bad host, a 404 and a block page fail identically on a retry and each retry is billed. Retried: a 429 from either side, a Firecrawl-side 5xx, a dropped connection. |
|
|
5461
5461
|
| `file_not_found` | path + local_file | `stat()` returned `ENOENT`. Error names the absolute resolved path. |
|
|
5462
5462
|
| `not_a_file` | path + local_file | Path exists but is a directory / block device / socket. |
|
|
5463
5463
|
| `permission_denied` | path + local_file | `stat()` or `readFile()` returned `EACCES`. |
|
|
@@ -5474,7 +5474,7 @@ All execution-time failures flow through `NodeExecutionError` so they appear in
|
|
|
5474
5474
|
- **Engine-level cache** (`canvas/.cache/index/`) keys by node params + node version + node-supplied cache extras. Re-running the same canvas with the same params is a cache hit and skips the network/yt-dlp/local-read entirely.
|
|
5475
5475
|
- **yt-dlp version is folded into the cache key** for `source: "url"` with `expect: video | audio`. Upgrading yt-dlp busts the cache automatically, since new versions can produce different bitstreams.
|
|
5476
5476
|
- **Local file `mtime + size` is folded into the cache key** for `source: "path"`. Editing the file (any save bumps mtime) invalidates the cache so you get fresh ingestion. mtime+size is cheap to read at validate time; for cases where mtime is unreliable (`cp -p`, content-only changes), force-bypass with `--cache-policy bypass` or change the canvas's `cache_salt`.
|
|
5477
|
-
- **No TTL.**
|
|
5477
|
+
- **No TTL.** Firecrawl and direct fetch don't cache-bust on page changes — if the source page updates, use `--cache-policy bypass` or change `cache_salt`.
|
|
5478
5478
|
|
|
5479
5479
|
**Local files (`source: "path"`):**
|
|
5480
5480
|
|
|
@@ -5497,10 +5497,10 @@ ingest { source: "path", expect: "video" } → video_transcribe # Local
|
|
|
5497
5497
|
**Requirements:**
|
|
5498
5498
|
|
|
5499
5499
|
- `yt-dlp` and `ffmpeg` on PATH for `source: "url"` with `expect: "video" | "audio"` (already in the E2B sandbox image; install locally with `pip install yt-dlp` and `brew install ffmpeg` / equivalent).
|
|
5500
|
-
- `
|
|
5500
|
+
- `FIRECRAWL_API_KEY` on the Convex backend for `source: "url"` with `expect: "text"` on non-`.md`/`.txt` URLs.
|
|
5501
5501
|
- No additional dependencies for `source: "path"` — just filesystem access.
|
|
5502
5502
|
|
|
5503
|
-
**Cost:** zero engine credits for direct_fetch + yt_dlp.
|
|
5503
|
+
**Cost:** zero engine credits for direct_fetch + yt_dlp. Firecrawl charges per scrape on your Firecrawl account (configured outside Baker).
|
|
5504
5504
|
|
|
5505
5505
|
---
|
|
5506
5506
|
|
|
@@ -757,6 +757,19 @@ async function parseErrorBody(res) {
|
|
|
757
757
|
}
|
|
758
758
|
return classifyHttpError(res.status, errObj, message2);
|
|
759
759
|
}
|
|
760
|
+
function providerVerdict(status, errObj, message2) {
|
|
761
|
+
if (errObj.provider === void 0 && errObj.code !== "provider_error") return null;
|
|
762
|
+
return {
|
|
763
|
+
kind: "provider",
|
|
764
|
+
status,
|
|
765
|
+
provider: errObj.provider,
|
|
766
|
+
code: errObj.code ?? "provider_error",
|
|
767
|
+
message: message2,
|
|
768
|
+
// A 4xx is terminal unless the backend says otherwise — the opposite
|
|
769
|
+
// default from the 502 branch, where the status itself means "try again".
|
|
770
|
+
retryable: errObj.retryable ?? false
|
|
771
|
+
};
|
|
772
|
+
}
|
|
760
773
|
function classifyHttpError(status, errObj, message2) {
|
|
761
774
|
if (errObj.code === CONTENT_POLICY_CODE) {
|
|
762
775
|
return { kind: "content_policy", status, provider: errObj.provider, message: message2 };
|
|
@@ -765,7 +778,7 @@ function classifyHttpError(status, errObj, message2) {
|
|
|
765
778
|
return { kind: "unauthorized", status, message: message2 };
|
|
766
779
|
}
|
|
767
780
|
if (status === 400 || status === 422) {
|
|
768
|
-
return { kind: "validation", status, message: message2, details: errObj.details };
|
|
781
|
+
return providerVerdict(status, errObj, message2) ?? { kind: "validation", status, message: message2, details: errObj.details };
|
|
769
782
|
}
|
|
770
783
|
if (status === 502 || status === 504) {
|
|
771
784
|
if (errObj.code === "provider_timeout" || status === 504) {
|
|
@@ -5936,7 +5949,7 @@ function resolveStrategy(params) {
|
|
|
5936
5949
|
case "text": {
|
|
5937
5950
|
const p = safePathname(params.url);
|
|
5938
5951
|
const isRawText = RAW_TEXT_EXTENSIONS.some((ext) => p.endsWith(ext));
|
|
5939
|
-
return isRawText ? "direct_fetch" : "
|
|
5952
|
+
return isRawText ? "direct_fetch" : "firecrawl";
|
|
5940
5953
|
}
|
|
5941
5954
|
default: {
|
|
5942
5955
|
params.expect;
|
|
@@ -5953,10 +5966,10 @@ function safePathname(rawUrl) {
|
|
|
5953
5966
|
}
|
|
5954
5967
|
var ingestNode = defineNode({
|
|
5955
5968
|
id: "ingest",
|
|
5956
|
-
version: "1.
|
|
5969
|
+
version: "1.3.0",
|
|
5957
5970
|
category: "io",
|
|
5958
5971
|
location: "local",
|
|
5959
|
-
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),
|
|
5972
|
+
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), Firecrawl 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.",
|
|
5960
5973
|
when_to_use: 'Use as the on-ramp for any external asset a canvas needs. `expect` makes the output port statically typed so downstream wiring is checked before any byte is fetched. Pick `source: "url"` for portable canvas; pick `source: "path"` for local files (canvas is not portable across machines without the file). Compose with other nodes for richer pipelines (e.g. `ingest expect=video` \u2192 `video_transcribe`).',
|
|
5961
5974
|
inputs: IngestInputs,
|
|
5962
5975
|
params: IngestParams,
|
|
@@ -5983,8 +5996,8 @@ function runStrategy(strategy, params, ctx) {
|
|
|
5983
5996
|
switch (strategy) {
|
|
5984
5997
|
case "direct_fetch":
|
|
5985
5998
|
return execDirectFetch(params, ctx);
|
|
5986
|
-
case "
|
|
5987
|
-
return
|
|
5999
|
+
case "firecrawl":
|
|
6000
|
+
return execFirecrawl(params, ctx);
|
|
5988
6001
|
case "yt_dlp":
|
|
5989
6002
|
return execYtDlp(params, ctx);
|
|
5990
6003
|
case "local_file":
|
|
@@ -6037,11 +6050,11 @@ async function ingestImageUrl(url, ctx) {
|
|
|
6037
6050
|
ctx
|
|
6038
6051
|
});
|
|
6039
6052
|
}
|
|
6040
|
-
async function
|
|
6053
|
+
async function execFirecrawl(params, ctx) {
|
|
6041
6054
|
const result = await callBackendExec({
|
|
6042
6055
|
nodeType: "ingest",
|
|
6043
6056
|
nodeVersion: ingestNode.version,
|
|
6044
|
-
params: { strategy: "
|
|
6057
|
+
params: { strategy: "firecrawl", url: params.url },
|
|
6045
6058
|
inputs: {},
|
|
6046
6059
|
outputKinds: { asset: "text" },
|
|
6047
6060
|
ctx
|
|
@@ -9199,4 +9212,4 @@ export {
|
|
|
9199
9212
|
defaultRegistry,
|
|
9200
9213
|
createEngineFromEnv
|
|
9201
9214
|
};
|
|
9202
|
-
//# sourceMappingURL=chunk-
|
|
9215
|
+
//# sourceMappingURL=chunk-YFQWCJX4.js.map
|