Kinburg-Nodes
Kinburg's ComfyUI nodes. An end-to-end music-video pipeline: write and sing a song with Siren (AceStep, per-section voices), find where every word was actually sung with Echo (karaoke .ass or burnt-in subtitles that follow the performance rather than the plan), cut the edit to its own music with Orpheus, storyboard and render it with Phantas and Morpheus, then write it out with Save Clip and Save Song. Alongside it a local-LLM toolkit: GGUF nodes with on-demand VRAM unloading and vision, a chat node for talking a task through before you generate, a vision LLM judge, and a managed OpenAI-compatible LLM server that steps aside when ComfyUI needs the card. Plus Ouroboros (self-correcting sampler), Chimera (multi-stage sampler), Audio SR, an interactive HTML image-comparison node, a model and settings preset library, and workflow utilities - loops, accumulators, switches, timers.
Nodes (102)
When ComfyUI won't let you plug a combo into a text box
Your saved characters, one dropdown away
Turn an LLM's JSON card into a reusable library entry in one step
One place to describe a character — for the prompt, the lyrics, and the music
A caption, plus the color it should render in
Pick a color once, get HEX, RGB, RGBA and alpha out
The Primitive-node trap, fixed
One block of reference material for your LLM, framed properly
Tick the boxes, get a judge's rubric
A contact sheet in one node, no layout math required
Character Card's looser sibling, for everything that isn't a person
Every setting that made this image, dumped onto the node
What actually differed between your comparison images
Collect your audio takes into one list
One caption per line, perfectly aligned to the images
Gather every branch's settings into one bundle
The read side of the pack's image accumulator
The accumulator read that leaves mixed sizes alone
Your sweep's full prompts, aligned to the images that made them
Collect branch texts into one joined string
Force your local LLM into a shape it can't talk its way out of
Slot a frame into an image batch anywhere — no resampling surprises
Drop one image from a batch by index
The A/B gallery you used to build by hand — as one node
Pick one of twenty inputs, of any type
Wring real top end out of a dead-sounding mix
Run two samplers over one image with a real step budget
Stop guessing how big your LLM's context window should be
The vision judge inside the self-correcting loop
Timestamp your filenames without the 'what day is it' math
An honest pause you can drop into any wire
Storyboard your video by chatting to an LLM
Echo already knows the words — it just finds out when they were sung
The receiving end of a map loop
Run the graph once per frame, without the copy-paste
Pull one frame out of anything, without the slicing math
A dashboard for switching whole workflow sections off
Turn an LLM's JSON blob into graph wires
The node that turns a collected list into a real ComfyUI list
Watch every LLM node in your graph think, live
The compatibility ghost that still works
Save your whole loader stack once, delete it forever
One node instead of a loader stack and a pile of settings
Morpheus turns MiniMax H3's 15-second ceiling into a whole video
One shot of the long-video chain, nothing more
Let a local LLM write the whole video, not just the prompts
Orpheus cuts your music video to the actual music
The sampler that critiques its own output until you say stop
Watch the self-correcting loop correct itself
Phantas renders the keyframes so the video looks like one world
Turn a sentence into a chain of consistent stills
The bottom half of a counted loop that really iterates
Real counted loops with state, inside an acyclic graph
One config bundle to feed every Kinburg sampler
A music clip from stills that can't drift off the beat
Get your Siren track out of ComfyUI and into your library
Drop a picture into the scrollback, mid-graph
Stop remembering, start a preset library that scores itself
Reuse a saved recipe without loading the model
Prettier than the default, and it can save the file too
Siren Cast is how you get ACE-Step to actually put the right voice on the verse
A/B two takes of the same song by ear, blind if you want
Siren is the sampler dials ACE-Step actually needs, plus a retake button
See the song, so you know which take to keep
Stop Letting the LLM Decide Your Song Structure — Siren Score Reads the Lyrics
Regenerate Just the Bad 15 Seconds of a Song — Siren Section Marks the Window
Your MP3 Won't Know Its Own Title Until You Add This Node
The Text Node That Tells You When Your Regex Is Garbage
Know Your Budget Before You Blow the Context
The Half of the Loop That Actually Decides When to Stop
A Loop That Runs Until You Say Stop — Not a Fixed Count
Slide an Item Into a ComfyUI List Without Rewiring Everything
Pull Items Out of a ComfyUI List and Get Them Back, Too
The little node that hands VRAM back before the sampler
Let a small model guess ahead
Vector storage on the same address as your chat model
Give your chat client eyes — one projector file, no second model
Chat With Your Local GGUF Inside ComfyUI — Before You Generate a Single Pixel
Get a Picture You Just Generated Into the Conversation
Run a GGUF LLM Inside ComfyUI Without Leaving It Eating Your VRAM
Read a .gguf's mind before you load it
Run llama-server under ComfyUI so one GPU hosts your chat and your images
One Config Node to Rule All Your Local Models
The Small Node That Makes Your Local LLM See
A Config Node That Remembers Your LoRA's Trigger Word
Stack 10 LoRAs and Keep Their Trigger Words in the Prompt
Five Dropdowns That Stop You Re-typing the Same Camera and Light
Sweep Every Prompt Combination Without Copy-Pasting the Canvas
Convert Your Own LLM to GGUF Without Leaving ComfyUI
Stop waiting for someone else to quantize your model
Collect audio clips by name, like you collect images
One caption per image, in the order the compare expects
Carry each branch's settings to the compare, automatically
Label your results, collect them by name, stop hand-wiring batches
Tag each branch's prompt so the judge can check it
Collect scattered text into one block, by name
Find out which node is eating your generation time
The other half of the stopwatch, and the number that comes out
Stack an unlimited pile of images into one batch
When images won't agree on a size, hand them out one at a time
Glue as many strings together as you like, no limits
Automate the 'which one is better?' argument
🎨 Kinburg-Nodes
<!-- BEGIN GENERATED badges — tools/gen_readme_index.py --> <!-- END GENERATED badges -->A personal collection of custom ComfyUI nodes, grown around one thing it does end to end: a music video, from the song to the finished file.
Siren writes and sings it (AceStep, with a voice per section). Echo finds where every word was actually sung and turns that into karaoke subtitles — soft .ass or burnt into the picture — timed to the performance rather than to the plan, and it hands back the plan corrected to match. Orpheus cuts the edit to the song's own music. Phantas and Morpheus storyboard and render the shots. Save Clip and Save Song write the result out.
Around that: local GGUF LLM nodes with on-demand VRAM unloading and vision, a chat node for talking a task through before you generate, a managed OpenAI-compatible LLM server, the Ouroboros self-correcting and Chimera multi-stage samplers, an interactive HTML image-comparison node, a model and settings preset library, and the usual workflow plumbing — loops, accumulators, switches, timers.
One folder = one package: ComfyUI reads the node mappings from the root __init__.py, and the sets are split into subpackages.
<!-- BEGIN GENERATED index — tools/gen_readme_index.py -->
📍 Node Index
All 102 nodes, grouped by the package they live in. Every package links to its full documentation under docs/.
🧠 LLM & Vision Systems
| Package | Nodes |
|---|---|
| local_llm/ — Local LLM (GGUF) & Live Logging | Context Sizer (GGUF), Kinburg Live Log 📜, LLM Live Log (old id), Local LLM (GGUF), Local LLM Chat (GGUF), Local LLM Model Info 🔍, Local LLM Settings (GGUF), Send Image to Chat, Send Image to Live Log 📜, Token Counter (GGUF), Vision Settings (GGUF) |
| llm_server/ — Local LLM Server & Control | LLM Server Control, LLM Server Draft (GGUF), LLM Server Embeddings (GGUF), LLM Server Vision (GGUF), Local LLM Server |
| context/ — Character Card, Entity Card, Context Collector | Character Card, Context Collector, Entity Card |
| vision_judge/ — Vision LLM Judge & Criteria Builder | Criteria Builder 📋, Vision LLM Judge |
| card_presets/ — Card Save & Card Presets | Card Presets, Card Save |
| grammar_presets/ — Grammar Presets | Grammar Presets |
| show_text/ — Show Text (Markdown) | Show Text (Markdown) |
| gguf_convert/ — Safetensors → GGUF Converters | Diffusion Safetensors -> GGUF (city96), Safetensors -> GGUF (llama.cpp) |
🐍 Iterative Samplers & Optimizers
📖 🐍 Iterative Samplers & Optimizers
| Package | Nodes |
|---|---|
| ouroboros/ — Ouroboros (Self-Correcting Sampler) 🐍 | Ouroboros (Self-Correcting Sampler) 🐍, Ouroboros Critic Settings 🐍, Ouroboros Live Log 🐍📜, Sampler Settings |
| chimera/ — Chimera (Multi-Sampler) 🦁 | Chimera (Multi-Sampler) 🦁 |
🎵 Audio & Music Suite
| Package | Nodes |
|---|---|
| siren/ — Siren Suite 🧜 | Siren (Music Sampler) 🧜, Siren Cast (Voice Plan) 🧜, Siren Compare (Audio) 🧜, Siren Scope (Audio → Image) 🧜, Siren Score (Lyrics → Plan) 🧜, Siren Section (Audio Window) 🧜 |
| audio_sr/ — Audio SR (48 kHz Upscale) 🔊 | Audio SR (48 kHz Upscale) 🔊 |
| save_song/ — Save Song & Song Tags | Save Song, Song Tags |
🎬 Video Generation & Storyboarding
📖 🎬 Video Generation & Storyboarding
| Package | Nodes |
|---|---|
| morpheus/ — Morpheus Suite 🌙 | Morpheus (Video Sampler) 🌙, Morpheus Dream Board 🌙, Morpheus Dream 🌙, Morpheus Storyboard 🌙 |
| phantas/ — Phantas Suite 🎞 | Phantas Storyboard 🎞, Phantas 🎞 |
| orpheus/ — Orpheus Suite 🎶 | Orpheus (Audio → Shots) 🎶 |
| echo/ — Echo Suite 💬 | Echo (Lyrics → Timing) 💬 |
| save_video/ — Save Clip | Save Clip |
🎛️ Presets & Asset Management
📖 🎛️ Presets & Asset Management
| Package | Nodes |
|---|---|
| model_presets/ — Model Capture & Settings Management | Model Capture 📥, Model Select 🎛, Settings Save 💾, Settings Select ⚙ |
| prompt_presets/ — Prompt Presets | Prompt Presets |
| prompt_variations/ — Prompt Variations | Prompt Variations |
| lora/ — Lora Trigger Loader & Accumulator | Lora Trigger Loader, Lora Unlim Accumulator |
🖼️ Image Processing & Visualizers
📖 🖼️ Image Processing & Visualizers
| Package | Nodes |
|---|---|
| image_compare/ — Image Compare (HTML) & Color Caption | Color Caption, Image Compare (HTML) |
| image_batch/ — Unlim Image Batch & List | Unlim Image Batch, Unlim Image List |
| collage/ — Collage Layout Builder | Collage |
🛠️ Workflow Control & Utilities
📖 🛠️ Workflow Control & Utilities
| Package | Nodes |
|---|---|
| util/ — General Workflow Utilities | Any Switch, Any to String, Color Picker, Combo to String, Date String, JSON Extract, Text Transform, Unlim Text Concat |
| timer/ — Execution Timer | Start Timer, Stop Timer |
| gen_info/ — Generation Info & Filter | Generation Info, Generation Info Filter |
| group_control/ — Group Control 🎚️ | Group Control 🎚️ |
| loops/ — Flexible Iteration Loops | Delay, For Each (Collect), For Each (Open), Get by Index, List Output, Repeat (Close), Repeat (Open), While (Close), While (Open) |
| accumulators/ — Name-Based Accumulators | Get Accumulator (audio), Get Accumulator (captions), Get Accumulator (gen info), Get Accumulator (images list), Get Accumulator (images), Get Accumulator (prompts), Get Accumulator (texts), Set Accumulator (audio), Set Accumulator (captions), Set Accumulator (gen info), Set Accumulator (images), Set Accumulator (prompts), Set Accumulator (texts) |
| list_ops/ — List & Batch Operations | Image Batch Insert, Image Batch Remove, List Insert, List Remove |
| report/ — Investigation Report DB | — no nodes of its own |
<details> <summary><b>🔎 All node ids (for workflow JSON / bug reports)</b></summary>
| Display name | Node id | Category |
|---|---|---|
| Any Switch | KinburgAnySwitch | Kinburg-Nodes/util |
| Any to String | AnyToString | Kinburg-Nodes/util |
| Audio SR (48 kHz Upscale) 🔊 | KinburgAudioSR | Kinburg-Nodes/audio |
| Card Presets | CardPresets | Kinburg-Nodes/LLM/presets |
| Card Save | CardSave | Kinburg-Nodes/LLM/presets |
| Character Card | CharacterCard | Kinburg-Nodes/LLM/context |
| Chimera (Multi-Sampler) 🦁 | KinburgChimeraSampler | Kinburg-Nodes/Bestiary/Chimera |
| Collage | CustomCollageNode | Kinburg-Nodes/image |
| Color Caption | ColorCaption | Kinburg-Nodes/image/compare |
| Color Picker | ColorPicker | Kinburg-Nodes/util |
| Combo to String | ComboToString | Kinburg-Nodes/util |
| Context Collector | ContextCollector | Kinburg-Nodes/LLM/context |
| Context Sizer (GGUF) | KinburgContextSizer | Kinburg-Nodes/LLM |
| Criteria Builder 📋 | CriteriaBuilder | Kinburg-Nodes/LLM/presets |
| Date String | KinburgDateString | Kinburg-Nodes/util |
| Delay | KinburgDelay | Kinburg-Nodes/flow/loops |
| Diffusion Safetensors -> GGUF (city96) | SafetensorsToGGUFDiffusion | Kinburg-Nodes/LLM/GGUF |
| Echo (Lyrics → Timing) 💬 | KinburgEchoAlign | Kinburg-Nodes/Bestiary/Echo |
| Entity Card | EntityCard | Kinburg-Nodes/LLM/context |
| For Each (Collect) | KinburgForEachCollect | Kinburg-Nodes/flow/loops |
| For Each (Open) | KinburgForEachOpen | Kinburg-Nodes/flow/loops |
| Generation Info | GenerationInfo | Kinburg-Nodes/util |
| Generation Info Filter | GenerationInfoFilter | Kinburg-Nodes/util |
| Get Accumulator (audio) | GetAccumAudio | Kinburg-Nodes/flow/accumulators |
| Get Accumulator (captions) | GetAccumCaptions | Kinburg-Nodes/flow/accumulators |
| Get Accumulator (gen info) | GetAccumGenInfo | Kinburg-Nodes/flow/accumulators |
| Get Accumulator (images list) | GetAccumImagesList | Kinburg-Nodes/flow/accumulators |
| Get Accumulator (images) | GetAccumImages | Kinburg-Nodes/flow/accumulators |
| Get Accumulator (prompts) | GetAccumPrompts | Kinburg-Nodes/flow/accumulators |
| Get Accumulator (texts) | GetAccumTexts | Kinburg-Nodes/flow/accumulators |
| Get by Index | KinburgGetByIndex | Kinburg-Nodes/flow/loops |
| Grammar Presets | GrammarPresets | Kinburg-Nodes/LLM/presets |
| Group Control 🎚️ | KinburgGroupControl | Kinburg-Nodes/util |
| Image Batch Insert | ImageBatchInsert | Kinburg-Nodes/image |
| Image Batch Remove | ImageBatchRemove | Kinburg-Nodes/image |
| Image Compare (HTML) | ImageCompareHTML | Kinburg-Nodes/image/compare |
| JSON Extract | KinburgJSONExtract | Kinburg-Nodes/util |
| Kinburg Live Log 📜 | KinburgLiveLog | Kinburg-Nodes/LLM |
| LLM Live Log (old id) | KinburgLLMLog | Kinburg-Nodes/LLM |
| LLM Server Control | LLMServerControl | Kinburg-Nodes/LLM |
| LLM Server Draft (GGUF) | LLMServerDraft | Kinburg-Nodes/LLM |
| LLM Server Embeddings (GGUF) | LLMServerEmbeddings | Kinburg-Nodes/LLM |
| LLM Server Vision (GGUF) | LLMServerVision | Kinburg-Nodes/LLM |
| List Insert | ListInsert | Kinburg-Nodes/flow/list |
| List Output | KinburgListEmit | Kinburg-Nodes/flow/loops |
| List Remove | ListRemove | Kinburg-Nodes/flow/list |
| Local LLM (GGUF) | LocalLLMGGUF | Kinburg-Nodes/LLM |
| Local LLM Chat (GGUF) | LocalLLMChatGGUF | Kinburg-Nodes/LLM |
| Local LLM Model Info 🔍 | LocalLLMModelInfo | Kinburg-Nodes/LLM |
| Local LLM Server | LocalLLMServer | Kinburg-Nodes/LLM |
| Local LLM Settings (GGUF) | LocalLLMSettingsGGUF | Kinburg-Nodes/LLM |
| Lora Trigger Loader | LoraTriggerLoader | Kinburg-Nodes/lora |
| Lora Unlim Accumulator | LoraUnlimAccumulator | Kinburg-Nodes/lora |
| Model Capture 📥 | KinburgModelCapture | Kinburg-Nodes/model |
| Model Select 🎛 | KinburgModelSelect | Kinburg-Nodes/model |
| Morpheus (Video Sampler) 🌙 | KinburgMorpheus | Kinburg-Nodes/Bestiary/Morpheus |
| Morpheus Dream Board 🌙 | KinburgDreamBoard | Kinburg-Nodes/Bestiary/Morpheus |
| Morpheus Dream 🌙 | KinburgMorpheusDream | Kinburg-Nodes/Bestiary/Morpheus |
| Morpheus Storyboard 🌙 | KinburgMorpheusStoryboard | Kinburg-Nodes/Bestiary/Morpheus |
| Orpheus (Audio → Shots) 🎶 | KinburgOrpheusScore | Kinburg-Nodes/Bestiary/Orpheus |
| Ouroboros (Self-Correcting Sampler) 🐍 | KinburgOuroboros | Kinburg-Nodes/Bestiary/Ouroboros |
| Ouroboros Critic Settings 🐍 | KinburgCriticSettings | Kinburg-Nodes/Bestiary/Ouroboros |
| Ouroboros Live Log 🐍📜 | KinburgOuroborosLog | Kinburg-Nodes/Bestiary/Ouroboros |
| Phantas Storyboard 🎞 | KinburgPhantasStoryboard | Kinburg-Nodes/Bestiary/Phantas |
| Phantas 🎞 | KinburgPhantas | Kinburg-Nodes/Bestiary/Phantas |
| Prompt Presets | PromptPresets | Kinburg-Nodes/prompt |
| Prompt Variations | PromptVariations | Kinburg-Nodes/prompt |
| Repeat (Close) | KinburgRepeatClose | Kinburg-Nodes/flow/loops |
| Repeat (Open) | KinburgRepeatOpen | Kinburg-Nodes/flow/loops |
| Safetensors -> GGUF (llama.cpp) | SafetensorsToGGUF | Kinburg-Nodes/LLM/GGUF |
| Sampler Settings | KinburgSamplerSettings | Kinburg-Nodes/Bestiary |
| Save Clip | KinburgSaveClip | Kinburg-Nodes/video |
| Save Song | KinburgSaveSong | Kinburg-Nodes/audio |
| Send Image to Chat | LocalLLMChatSendImage | Kinburg-Nodes/LLM |
| Send Image to Live Log 📜 | KinburgSendImageToLog | Kinburg-Nodes/LLM |
| Set Accumulator (audio) | SetAccumAudio | Kinburg-Nodes/flow/accumulators |
| Set Accumulator (captions) | SetAccumCaptions | Kinburg-Nodes/flow/accumulators |
| Set Accumulator (gen info) | SetAccumGenInfo | Kinburg-Nodes/flow/accumulators |
| Set Accumulator (images) | SetAccumImages | Kinburg-Nodes/flow/accumulators |
| Set Accumulator (prompts) | SetAccumPrompts | Kinburg-Nodes/flow/accumulators |
| Set Accumulator (texts) | SetAccumTexts | Kinburg-Nodes/flow/accumulators |
| Settings Save 💾 | KinburgSettingsSave | Kinburg-Nodes/model |
| Settings Select ⚙ | KinburgSettingsSelect | Kinburg-Nodes/model |
| Show Text (Markdown) | KinburgShowText | Kinburg-Nodes/util |
| Siren (Music Sampler) 🧜 | KinburgSirenSampler | Kinburg-Nodes/Bestiary/Siren |
| Siren Cast (Voice Plan) 🧜 | KinburgSirenCast | Kinburg-Nodes/Bestiary/Siren |
| Siren Compare (Audio) 🧜 | KinburgSirenCompare | Kinburg-Nodes/Bestiary/Siren |
| Siren Scope (Audio → Image) 🧜 | KinburgSirenScope | Kinburg-Nodes/Bestiary/Siren |
| Siren Score (Lyrics → Plan) 🧜 | KinburgSirenScore | Kinburg-Nodes/Bestiary/Siren |
| Siren Section (Audio Window) 🧜 | KinburgSirenSection | Kinburg-Nodes/Bestiary/Siren |
| Song Tags | KinburgSongTags | Kinburg-Nodes/audio |
| Start Timer | StartTimer | Kinburg-Nodes/util |
| Stop Timer | StopTimer | Kinburg-Nodes/util |
| Text Transform | KinburgTextTransform | Kinburg-Nodes/util |
| Token Counter (GGUF) | KinburgTokenCounter | Kinburg-Nodes/LLM |
| Unlim Image Batch | UnlimImageBatch | Kinburg-Nodes/image |
| Unlim Image List | UnlimImageList | Kinburg-Nodes/image |
| Unlim Text Concat | UnlimTextConcat | Kinburg-Nodes/util |
| Vision LLM Judge | VisionLLMJudge | Kinburg-Nodes/LLM |
| Vision Settings (GGUF) | LocalLLMVisionSettingsGGUF | Kinburg-Nodes/LLM |
| While (Close) | KinburgWhileClose | Kinburg-Nodes/flow/loops |
| While (Open) | KinburgWhileOpen | Kinburg-Nodes/flow/loops |
📦 Installation
- Clone this repository into
ComfyUI/custom_nodes(or install it through ComfyUI-Manager). - The Local LLM nodes need
llama-cpp-python(CUDA build). It is installed automatically byinstall.py(which ComfyUI-Manager runs on install). To do it by hand, run with this ComfyUI's Python:
The Image Compare and Date String nodes need nothing extra.<ComfyUI>/.venv/Scripts/python.exe <ComfyUI>/custom_nodes/Kinburg-Nodes/install.py - The GGUF converters use packages that already ship with ComfyUI (
huggingface_hub,gguf,torch,safetensors) and fetch the conversion scripts themselves (giton PATH,auto_cloneon). Only quantization needs an external binary you provide:llama-quantizefor the LLM converter, or the patchedllama-quantizefrom city96's llama.cpp fork for the diffusion converter (see ComfyUI-GGUF/tools/README.md). Leavingquantize = noneneeds nothing extra.
Each node's parameters are documented in their tooltips. The Local LLM node also exposes a
help output with a quick cheat-sheet — wire it to a "Preview as Text" node to read it.
🧪 Tests
python tests/run.py
with ComfyUI's own interpreter (.venv/Scripts/python.exe). 1395 checks in 23 suites, about two
and a half minutes — over local_llm/ (chat, worker, both send-image nodes, lazy guard),
morpheus/ (storyboard, dream board, trims), phantas/ (timing, board, render), orpheus/
(timing, detect, node), siren/ (cast, score), audio_sr/, lora/, util/diskcache.py, three of
the web/*.js extensions (chat, dream board, group control), and the docs audit below. Nothing real
is loaded (llama.cpp, H3 and the browser are all stubbed), so it is a regression net for those paths
and not a substitute for trying a change in the app. tests/README.md says exactly what is and
is not covered.
📑 Keeping the docs honest
The node index in this README is generated, so it cannot drift from the nodes the pack registers:
python tools/gen_readme_index.py
It rewrites only the regions between the <!-- BEGIN/END GENERATED --> markers — every other line
here is hand-written. --check verifies instead of writing (that is the docs test suite, so a
stale index fails the tests), and --run-tests also refreshes the tests badge from a real run.
Adding a node needs no edit there at all: it appears in the index on the next run. Adding a
package needs only its ## heading in the right docs/*.md file — the tool reads the folder
name out of the heading, and fails with undocumented: <folder> if a node's folder has no section
to live in. A group's position comes from its own <!-- index-order: N --> line.
Alongside the index it audits the prose: every node must be mentioned, every local link and anchor
must resolve, and every backticked snake_case term must be a real node input or output — anything
else has to be listed in tools/known_terms.txt (sampler names, enum values, comfy internals).
That last check is the one that catches a renamed input still being documented under its old name.
📄 License
MIT — see LICENSE.