NInfer - Extra Body
The escape hatch for every setting with no node
- other_options
- Options
Every option family hits the same wall: someone ships a temperature node, a Top P node, a system prompt node - and then you want frequency_penalty and there's no node for it. That's this one. A text box that takes raw JSON, gets merged into the request body, and reaches the server as if a dedicated node had set it.
It's the least glamorous node in the pack and the one that keeps you unstuck, because it turns "I can't set that from ComfyUI" into "I'll write four lines of JSON".
Inputs and output
- Extra Body (JSON) - multiline string, default
{}. - Options - merged in and out, same as every other node in the chain.
The node validates before it executes: malformed JSON is rejected with the parser's own message (extra_body is not valid JSON: ...), and valid JSON that isn't an object is rejected too (extra_body must be a JSON object). So a JSON array or a bare number won't slip through - you need curly braces with key/value pairs. The multiline widget means you can format it for your own sanity:
{
"frequency_penalty": 0.3,
"presence_penalty": 0.1
}
That example is deliberately boring, because it's real: both of those are parameters the pack's code accepts but has no node for, so this is genuinely how you set them.
What happens to your JSON
Two routes, and you don't have to choose. The pack's Chat node splits the merged settings into parameters the openai Python SDK accepts natively - frequency_penalty, presence_penalty, stop, logit_bias, response_format, seed, temperature and friends - and everything else, which is forwarded through the SDK's extra_body field and merged into the top-level JSON request body. So {"response_format": {"type": "json_object"}} goes one way, and a server-specific key that no SDK has ever heard of goes the other, and both arrive.
That's how asking for structured output works in this pack: this node plus one line of JSON, instead of prayer and regex on the way out the other side. If your prompt enhancer is supposed to return a bare prompt or a JSON object, constrain it here rather than hoping the model behaves.
Where people get burned
Order in the chain matters here, unlike the other nodes. The other option nodes only ever write their own single key, so chaining order is irrelevant. This one merges a whole dictionary: it overwrites any key set by a node upstream of it, and any node after it in the chain will overwrite the keys it set. Practically: put Extra Body last, next to the Chat node, so it's the final word on the request.
A key that collides with an explicit argument. The Chat node pins n=1 when it calls the model, and n is on the SDK's accepted list - so {"n": 3} here doesn't quietly do nothing, it makes the call fail with a duplicate-argument error. Asking for three completions isn't supported by this node; run it three times with different seeds.
Whitespace and quotes. It's JSON, not Python - double quotes only, no trailing commas, no comments. The validation error you get is the raw parser complaint, which is usually enough to find the line.
Silence when a key is wrong. A typo'd or unsupported key doesn't error; it goes to the server and the server ignores it. If a setting here appears to do nothing, check the spelling against the server's own documentation before you go hunting for a bug in the pack.
Which is the honest summary of the whole node: it's a pass-through, not a validator of meaning. It gets your JSON to the server intact. Whether the server does anything sensible with it is between you and the server's docs.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| extra_body | STRING | {} | — |
| other_optionsopt | NINFER_OPTIONS | Options from the previous settings node |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| Options | NINFER_OPTIONS | Merged settings |