Nodes/comfyui-fvmtools/JB · Extractor
ComfyUI Node

JB · Extractor

Pull one subtree out of a JSON prompt — for regional detailer passes and reuse

By ping1979ping·Created 7 months ago·Updated a day ago· 2
JB · Extractor
    • raw_json
    • string
    • found
    ◄json_input—►
    ◄category►
    ◄output_formatloose_keys►
    ◄collect_allfalse►
    ◄with_keysfalse►

    The JB suite builds one big structured document, and then most of the time you want part of it. JB · Extractor is the knife: it pulls one or more named subtrees out of a JSON string and hands them back as their own mini-document. The canonical use is regional detailing - you've stitched a whole character document, but the face-detailing pass only needs character_1.outfit.garments.upper_body, so you extract that one branch and feed it to a regional prompt rather than re-prompting by hand.

    It's a small node with a four-mode personality, and the mode is auto-selected by what you type into category.

    The four modes

    • Single key - type hair and it recursively searches every nesting level for the first hair key, returning {hair: value}. Great when you don't know exactly which level the key lives at.
    • Dot-path - type character_1.outfit.garments.upper_body and it does a strict descent down that exact path, returning {upper_body: value}. Precise, and fails cleanly if the path doesn't exist.
    • Multi - separate categories with commas/newlines/semicolons, e.g. hair, eyes, shoes. Each is resolved independently and the results merge into one {key: value} dict. Missing categories are skipped silently.
    • Empty - leave category blank and you get the whole input back unwrapped. Handy as a passthrough/debug switch.

    The output_format choice (pretty_json, compact_json, loose_keys) applies to whatever comes out. And there's a found boolean output - true if at least one category matched - which you can wire into a condition to branch your workflow instead of relying on string inspection.

    What it's actually for

    Think of it as the re-use and plumbing node of the JB suite. The Stitcher produces one giant document per character; the Extractor lets you slice that document into focused prompts for different stages - a full-body prompt for the base pass, a hair+face subset for a face detailer, the shoes alone for a footwear ControlNet pass. Because it takes a plain STRING input, it doesn't care whether the JSON came from a Stitcher, a Builder, an Ideogram Assembler, or a text file you typed yourself.

    Installing

    cd ComfyUI/custom_nodes
    git clone https://github.com/ping1979ping/comfyui-FVMtools
    

    No dependencies, pure string parsing, instant. Restart ComfyUI and it's under FVM Tools/JB.

    The gotchas

    Two, both about silent behavior. Single-key search returns the first match in document order - if hair appears for both character_1 and character_2 and you search single-key, you get whichever comes first, with no warning. Use the dot-path mode when key names repeat. And multi-mode skips missing categories silently: if you ask for eyes, nonexistent_field, you get {eyes: ...} with no error telling you the second one wasn't found - check the found output or the returned document before assuming you got everything.

    CategoryFVM Tools/JB

    Inputs (5)

    NameTypeDefaultDescription
    json_inputSTRINGJSON to search. Wire a raw_json output here — the loose_keys `string` output is one-way and cannot be parsed back.
    categorySTRINGWhat to pull out. Four syntaxes, auto-detected: face → single key, recursive search through every nesting level. Wraps as {face: ...}. face, hair → several keys at once. Separators: comma, semicolon, or one per line. Keys that aren't found are skipped silently. character_1.face → dot-path, strict descent from the root. Wraps under the LAST segment: {face: ...}. (empty) → the whole document, unwrapped. Dots are path separators, never list separators — 'a.b, c.d' is two paths. With collect_all ON the meaning of a dot-path changes: all but the last segment is a strict descent that SCOPES the search, and the last segment is then collected recursively below it. So 'input_4.prompt_fragment' sweeps every prompt_fragment inside input_4 only. Careful: two dot-paths ending in the same segment share one wrap key. Their values merge (collect_all: appended; otherwise: last one wins). Prefix a line with [NOT] to EXCLUDE instead of pull: [NOT]key → drop that key + subtree everywhere [NOT]a.b.c → drop just that path Exclusions are pruned from the source first. [NOT] lines alone → the whole document minus those keys. If they empty the result → found=False.
    output_formatCOMBOloose_keyspretty_json / compact_json → strict JSON. loose_keys → unquoted keys for SD/CLIP encoders; with collect_all it collapses to one flat comma-joined line.
    collect_allBOOLEANfalseOFF: return the FIRST match of a key. ON: collect EVERY match at any depth into a list — the classic 'give me all prompt_fragments' case. A dot-path then SCOPES the sweep instead of pinpointing one value: all but the last segment is a strict descent, the last segment is searched recursively below it. With output_format=loose_keys the string output becomes one flat comma-joined line.
    with_keysBOOLEANfalseOnly applies when collect_all is ON. OFF: bare values — 'wallpapered feature wall, shag area rug'. ON: each value keeps the key of the element it came from — 'background: wallpapered feature wall, midground: shag area rug'. raw_json becomes {key: {background: ..., midground: ...}} instead of a flat list. Repeated element names collect into a list rather than overwriting.

    Outputs (3)

    NameTypeDescription
    raw_jsonSTRING—
    stringSTRING—
    foundBOOLEAN—