Nodes/MiniMax H3 Novel Pipeline/Load Character Profiles
ComfyUI Node

Load Character Profiles

Load Character Profiles is a validator wearing a loader's coat

By yuyuki·Created 2 months ago·Updated a day ago· 5
Load Character Profiles
    • character_profiles
    • saved_file
    ◄profiles_path►

    Most "load" nodes in ComfyUI are dumb. They read a file, they hand it over, they get out of the way. This one reads the file and then argues with you about it - and in the MiniMax H3 Novel Pipeline that's exactly what you want, because the file is a character study you've been hand-editing at midnight and the next three stages will believe every word of it.

    So think of it as a schema-enforcing handoff, not a file picker. Feed it your edited character_profiles.json, get a validated typed object back, no LM Studio in the loop.

    What it loads and how it checks it

    One input, profiles_path. Per the tooltip: a saved profiles JSON - renamed copies count - or a directory containing character_profiles.json, resolved inside output/minimax_h3_novel. Relative paths start at that root. So 20261024163701/character_profiles works, and so does a file you copied to my_edits/ellis_v2.json.

    Then the validation stack, in order. Schema first. Then the digest: source_digest must still match source_document, which means you cannot quietly rewrite the embedded upstream evidence and still load the file - the error tells you to reconsolidate the edited evidence instead. Then identity integrity: local_id values must be unique, link_to_local_id must point at another principal in the same file, and self-links, chains and cycles are rejected with a field-specific message. Then evidence integrity, which is where it gets genuinely strict. Every evidence_id referenced from a profile must exist in the source records, must not be flagged low-confidence, must not be reused across profiles, and the stored observation must be byte-identical to the validated source record. Trait references have to be non-empty and unique. global_traits entries must reference explicit, persistent physical observations. Conflict choices must cover exactly the conflict's evidence set.

    Miss any of that and you get a message naming the field, not a stack trace. That's the pack's better habit showing.

    The edits that are allowed

    Selections and links. Multiple unresolved_conflicts choices can be selected - zero or several are both valid, and the loader does not rebuild model decisions, does not clamp your choices to one, and does not write the file back. If you want to resolve a hair-colour argument by flipping selected on the alternative, do it here and the document passes through intact, selections and all.

    What it won't let you do is invent evidence. You can't promote a trait into global_traits unless it traces to an explicit persistent physical observation, and you can't re-word an observation in the profiles file while leaving the source record alone. That's the guarantee downstream stages rely on, and the loader is the door it's enforced at.

    Outputs

    character_profiles, typed MINIMAX_CHARACTER_PROFILES - identical shape to the consolidation output, so it drops straight into Character Visual Profile Generator. And saved_file, a STRING with the resolved path.

    Change detection is a hash of the file's bytes, so saving edits in your text editor and re-queuing reloads them. No restart. If the path is bad, the check fails open so the node can report what's actually wrong.

    Install

    cd ComfyUI/custom_nodes
    git clone https://github.com/yuyuki/ComfyUI-Minimax_H3_Novel_Pipeline
    python -m pip install -r ComfyUI-Minimax_H3_Novel_Pipeline/requirements.txt
    

    Restart ComfyUI after installing, refresh the browser, find it under MiniMax H3 Novel. ComfyUI Manager installs the same repo if you search "MiniMax H3 Novel Pipeline". Python 3.10 or newer. The dependency that matters here is jsonschema, which is in requirements.txt even though the README's dependency paragraph only names three packages - the schema validation you just read about is plain jsonschema, so if that import fails, this node fails at load time, not at queue time.

    No LM Studio server, no model, no API key needed. The loaders are deliberately independent of the processing half of the pack, which makes them the right nodes to build a hand-curated workflow around.

    Where people get burned

    The digest error. "source_document was altered; reconsolidate the edited evidence file." You edited the embedded evidence inside the profiles document rather than the evidence file itself. Go back to character_evidence.json, edit there, run Load Character Evidence into consolidation. That's the supported order of operations, and reconsolidating is the price of the guarantee.

    Duplicated evidence ids. If you copied a profile section to make a variant, both copies now claim the same evidence_id across profiles, which is rejected. One observation belongs to exactly one identity in this document. Duplicate the profile and give it its own evidence, or link it with link_to_local_id.

    Multiple selections. Perfectly legal, and the first selected choice wins with a console notice. Not legal: expecting consolidation's defaults to survive a re-run of consolidation, which regenerates the file. Keep manual edits in a renamed copy and point this node at that.

    Silence from semantic errors. It validates structure, references and identity linkage - not whether "grey-green eyes" is true to chapter twelve. If you mistype a value in a way that still matches its source record's field names, nothing complains here. That's what the source quotations in your evidence file are for.

    CategoryMiniMax H3 Novel

    Inputs (1)

    NameTypeDefaultDescription
    profiles_pathSTRINGSaved character profiles JSON file (including renamed copies), or a directory containing character_profiles.json. Must be inside output/minimax_h3_novel; relative paths start there. Edits reload on the next execution.

    Outputs (2)

    NameTypeDescription
    character_profilesMINIMAX_CHARACTER_PROFILES—
    saved_fileSTRING—