Archival cover in the house style: an accounting hall of adding
machines, our clerk's tape by far the longest and spilling across the
floor, hands off the keys while everyone else works on. A circuit
breaker for your wallet.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Wires Prompt Studio Settings (new in Gemini-Direct v1.2.0) → Prompt Studio
+ Hash Vault any_input_2 → Hash Vault Check Cache, with the
brief STRING driving both Prompt Studio.brief and Hash Vault.payload_string.
Cache key = (brief + style), so changing either invalidates correctly.
Label Builder auto-formats the sidecar label as 'brief / style'.
Lazy API Switch bypasses the entire Prompt Studio + Gemini + Save chain on
cache hit. Demonstrates the canonical from-scratch generation pattern with
full caching.
New node: HashVaultLabelBuilder (🏷️ Hash Vault Label Builder).
Concatenates up to 4 any-type inputs with a configurable separator into
one STRING for Hash Vault Save's label input. Wire once per workflow
(e.g. style + variant + intensity from Gemini Style Transfer Settings)
and never type a label manually again.
Empty strings, None, and whitespace-only inputs are skipped so partial
wiring produces clean output. Non-string inputs are stringified at join
time.
Solves the repeated-typing pain exposed by running the 77-entry
photographer QA pass. Labels follow the canonical
"Photographer / Variant / intensity" convention automatically.
Three ways to open the browser now:
- Ctrl+Shift+H keybinding from anywhere in ComfyUI
- Left-sidebar "Hash Vault" tab with entry count + Open Browser button
- Top menu (Extensions → AKURATE: Hash Vault Browser) — unchanged from v1.4.0
Sidebar registration guarded on app.extensionManager.registerSidebarTab so
older frontends fall back cleanly to menu + keybinding only.
No backend changes — pure JS polish.
New feature: modal gallery UI over the vault, accessible from the top menu
bar under Extensions → AKURATE: Hash Vault Browser. Reads all sidecar
metadata + thumbnails shipped in v1.3.0 and presents them as a filterable
grid. No graph node required.
Backend: new GET /akurate/hash_vault/list route walks output/hash_vault/,
reads every {hash}.json sidecar, returns JSON sorted by last_accessed_at
desc with pt_size enrichment. Thumbnails reuse ComfyUI's built-in /view
route (type=output&subfolder=hash_vault) — zero new thumbnail endpoint.
Frontend: single web/hash_vault_browser.js (vanilla JS, no framework).
Modal with CSS grid, live substring filter on label+hash, click-to-copy
hash with toast, lazy-loaded thumbnails, relative-age display, ESC and
backdrop-click dismiss.
__init__.py now declares WEB_DIRECTORY and imports the route module.
Deferred to v1.5+: load-into-workflow action, delete, bulk ops, sort
controls, pagination. Current vault (57 entries, 2.33 GB .pt, 3.7 MB
thumbs) loads instantly so none of those are urgent.
HashVaultSave now writes {hash_key}.json (label, timestamps, payload summary) and {hash_key}.thumb.png (256px preview) alongside the .pt, inside the existing FileLock. New optional label input on Save node, does not factor into the hash. DeterministicHashVault bumps last_accessed_at on cache hit (silent no-op for pre-v1.3.0 entries). folder_paths import is tolerant of being outside ComfyUI so the sidecar helpers are reusable from tooling.
tools/migrate_hash_vault.py backfills sidecars for pre-v1.3.0 entries, using file mtime as created_at and "(legacy)" as label.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the two StringConstantMultiline nodes in hash_vault_image_only.json
with the new GeminiStyleTransferSettings node from Gemini-Direct v1.1.0.
The Settings node keeps the real ComfyUI dropdown UX (typeahead, validation)
while still fanning style + intensity into both the Style Transfer input
and the Hash Vault any_input slot. Avoids the typo-silent cache-break mode
of free-text StringConstantMultiline.
README's image-only section rewritten to explain the UX rationale.
workflows/hash_vault_image_only.json demonstrates the v1.2.0 image+
widgets pattern: Gemini Style Transfer (image, style, intensity, no
prompt). The style and intensity widgets are converted to inputs and
driven by two StringConstantMultiline nodes that ALSO feed Hash
Vault's any_input_2 / any_input_3. The image fans out to both Style
Transfer and Hash Vault's any_input.
README split into two examples (prompt-driven vs image-only) so new
users can pick the pattern that matches their API node.
Patch bump to retrigger the Comfy Registry publish so installed
copies pick up the new workflow file.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dropped the forceInput=True on payload_string so the socket is truly
optional. Added any_input_2, any_input_3, any_input_4 alongside the
existing any_input. Users can now hash purely on image + converted-
widget values without manufacturing a synthetic payload string.
Primary use case: image-only APIs with meaningful widgets. For a
Gemini Style Transfer node with (image, style dropdown, strength
float) and no prompt, convert the style and strength widgets to
inputs, then wire image -> any_input, style -> any_input_2,
strength -> any_input_3. All three factor into the hash.
Back-compat: workflows that only use payload_string + any_input
produce bit-identical hash keys to v1.0/v1.1. The "__slotN:" prefix
only appears when slots 2-4 are actually wired, so existing
hash_vault/ entries keep hitting. Verified with a direct comparison
against the pre-v1.2 hashing path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
workflows/hash_vault_basic.json wires the canonical cache-skip pattern:
one StringConstantMultiline feeds both DeterministicHashVault (for hashing)
and GeminiImageGenerate (for the actual API call). On cache hit the Lazy
API Switch short-circuits the Gemini branch entirely — no API call, no
charge. On miss, Gemini runs, HashVaultSave writes the result to disk,
and the next run with the same prompt is a hit.
README updated with a walkthrough and the pack dependencies
(ComfyUI-API-Optimizer, ComfyUI-Gemini-Direct, ComfyUI-KJNodes for the
StringConstantMultiline primitive — any STRING-output node works in
its place).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>