JB · Ideogram Assembler
Fill KJNodes Ideogram-4 caption boxes from your structured JSON — the layout-to-prompt bridge
- context_from_prompt_generator
- prompt
- raw_json
- report
Ideogram-4's ComfyUI story goes through KJNodes' Ideogram 4 Prompt Builder, which is a visual canvas: you draw boxes on a layout and type a description into each one. The FVMtools JB suite speaks structured JSON. These two don't naturally talk - so FVM_Ideogram_Assembler is the translator. It takes the KJ caption JSON (the prompt output of the builder) plus a keyed JSON document from JB · Builder, and fills each box's description with the matching slot's content. The layout - every bbox - stays exactly where KJNodes drew it.
The mechanism is the slot-key. Each KJ box gets a short key typed into its desc field (like hair or logo). The assembler reads the key, looks up that slot in your JSON, and writes the value in. This is the bridge that turns "I drew a layout" + "I built structured character data" into "I have a full Ideogram caption with my content in exactly the right boxes."
What a slot value can be
- A string - goes straight into the box's
desc. Simplest case. - A field-map dict - a sub-dict with
desc,text,color_palette, and/ortypekeys, mapping directly onto the Ideogram element's fields. Settingtextforcestype: "text", which is how you get text-rendering boxes in the right place. - A nested structure - anything else gets serialized and folded into
desc, so a placeholder box can be replaced by an entire subtree (e.g.{age_desc, gender, hair: {...}, body: {...}}becomes a prose description of all of it). This is how a single "character" box becomes a whole character block.
Two behaviors to know: scene_overrides (default off) decides whether every top-level key in your JSON is a box placeholder, or whether the three reserved keys - background, high_level_description, style_description - set the scene instead of filling boxes. And on_unmatched_box (default "keep typed desc") controls what happens to boxes with no matching slot: keep the prose you typed in KJ, or clear it. If you're doing seed-run variations, keeping the typed desc means untouched boxes stay identical between runs.
Every text field then goes through a wildcard pass, so __wildcards__, {a|b} alternation, and __^var__ variable recall all work inside the caption.
Inputs and outputs
Required: caption_json (from KJNodes' Ideogram 4 Prompt Builder), box_prompts (your keyed JSON - wire an FVM_JB_Builder's raw_json here), seed, output_format (ideogram is the default and what the model expects), nested_desc_format, and the two enum behaviors above. Optional: context_from_prompt_generator for variable recall. Outputs: prompt (the finished Ideogram caption), raw_json (what the caption parsed to), and report (what got filled where - check this when a box comes out empty).
Installing
cd ComfyUI/custom_nodes
git clone https://github.com/ping1979ping/comfyui-FVMtools
No extra deps. You will need KJNodes for the Ideogram 4 Prompt Builder itself. Restart ComfyUI after installing either.
The ordering gotcha
Run order matters and it's counterintuitive: the assembler matches boxes by the slot-key in their desc, so anything that overwrites desc with prose before this node breaks the matching. That's why BoxJitter (which rewrites boxes with prose) must run before the assembler, not after - the pack's pipeline is KJ → BoxJitter → Assembler → Ideogram. Wire it in that order and the whole thing composes; wire it backwards and the assembler finds no keys and your boxes stay empty.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| caption_json | STRING | Ideogram-4 caption JSON, e.g. the `prompt` output of KJNodes' Ideogram 4 Prompt Builder (or our BoxJitter). | |
| box_prompts | STRING | {} | Keyed JSON: {slot: <string | field-map | nested structure>, ..., background:"..."}. Wire an FVM_JB_Builder raw_json here. |
| seed | INT | 00–18446744073709550000 | Seed for the wildcard/variable pass. |
| output_format | COMBO | ideogram | 3 options: ideogram, pretty_json, compact_json |
| nested_desc_format | COMBO | loose_keys | How a nested slot structure is serialised into the box's desc. |
| scene_overrides | COMBO | off (all top-level keys are box slots) | off: every top-level key in box_prompts is a box placeholder; the scene comes from the KJ node. on: the three reserved keys set the scene and are not used to fill boxes. |
| on_unmatched_box | COMBO | keep typed desc | 2 options: keep typed desc, clear desc |
| context_from_prompt_generatoropt | DICT | Optional adaptiveprompts context for `__^var__` recall. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| prompt | STRING | — |
| raw_json | STRING | — |
| report | STRING | — |