A batch whose reply ran past the model's length limit came back as truncated
JSON and aborted the whole run — hit in practice on batch 7 of 7, after the
first 90 of 101 assets had already been catalogued successfully.
Parse failures now raise BatchParseError, which the batch runner handles by
splitting the file list in half and retrying each side, recursively. Normal
batches are unaffected; only a batch that actually fails to parse pays for a
retry, and each half that succeeds is merged and checkpointed immediately.
A single asset that still cannot be parsed stops the run with a message naming
that file, so the recursion always terminates.
Verified with a stubbed CLI: a reply truncating above 4 files descends
12 -> 6 -> 3+3 per side and catalogues all 12, and the worst case where every
reply truncates stops after 3 calls with the checkpoint intact.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A single session asking Claude to open an entire large library, compose one
manifest, and write it via the Write tool could spiral to 200-400+ turns and
tens of dollars of subscription usage with nothing produced (is_error: true,
reported on a 101-asset library). Rewritten so each Claude call handles only
batch_size assets (default 15) and replies with JSON only — the node itself
assembles and writes the final manifest, so Claude is never given a
file-writing tool for this.
Progress is tracked in a hidden, atomically-written checkpoint
(.sf_library_builder_checkpoint.json, cleared on success). A failed or
interrupted run resumes from the same settings instead of re-paying for
finished batches.
Verified on 45 synthetic assets: 16 turns and ~$0.08 per batch of 15 (vs.
198-401 turns and $25-130 for 101 assets before), and confirmed resume by
pre-seeding a checkpoint and watching it skip the already-done batches while
preserving their entries and reusing the established art_style.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Library Builder opens every asset in a folder once and writes a manifest
describing each — category, subcategory, archetype, tags, a one-line
description, and a project-level art_style. Asset Director then searches that
manifest on every run without opening an image, which is what keeps a large
library cheap to work with.
Modes: manifest only (read-only, the default), organise into a copy, or
organise in place. write_manifest is off by default so a first run shows the
JSON without touching anything.
Also aligns Asset Director's manifest default to manifest.json and teaches it
to honour the manifest's art_style when writing prompts, so a library
generates in one consistent style.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude reads an asset library's manifest, picks the references that suit the
brief, and writes the image prompt for them. Emits an IMAGE batch plus the
prompt, which wire directly into a generation node's image and prompt inputs.
Choosing from a manifest rather than the images themselves keeps a large
library cheap; look_at_images opts into opening the files and is off by
default. pad_to_fit controls how mixed-size assets are reconciled into a
single batch tensor: letterbox onto a shared canvas (default) or stretch.
Runs on the existing Claude Code login, no API key.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Inherited from the original repo. It fires on every pyproject.toml change
and immediately fails, because the Stillfront org blocks third-party GitHub
Actions and `Comfy-Org/publish-node-action` is not on the allowlist. Each
version bump therefore produced a failure email for no benefit.
Publishing is done manually with `comfy node publish`. Recoverable from
history if the action is ever allowlisted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Runs prompts through the locally installed Claude Code CLI, so it uses the
user's existing Claude login rather than an Anthropic API key. Accepts a
system prompt and up to 16 images, which are written to a temp working
directory and read back by the agent's Read tool.
Image inputs grow on demand: connecting one reveals the next empty slot, and
unused trailing slots are trimmed.
Closes stdin on the subprocess, which otherwise costs 3s per call while the
CLI waits for input that never arrives.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Removing the route did not clear the Pending status: 1.0.9 shipped without
it and sits Pending alongside 1.0.8, so the endpoint was never the cause.
Pending appears to be the normal post-upload state before a scan promotes a
version to Active.
Restores the Refresh button and its preview endpoint.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1.0.8 registered a ComfyUI server route to power a Refresh button, which
put that version into NodeVersionStatusPending and blocked installs. The
route only ever supplied a pre-run preview of the pending count; IS_CHANGED
already forces a fresh read of the sheet on every run, so removing it costs
no functionality.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Dispatches unfinished prompts from a Google Sheet column as a batch, one
downstream graph run per prompt, capped by max_rows. Rows carrying any text
in the status column are skipped, so reruns continue where the last one
stopped and clearing a cell requeues that row. Scanning stops at the first
empty prompt cell.
Adds a Refresh button that re-reads the sheet and reports pending counts.
Also stops tracking node.zip, which is a `comfy node publish` build artifact.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>