Nodes/ComfyUI-FeiFei/Prompt Enhancer (API: edit config.json)
ComfyUI Node

Prompt Enhancer (API: edit config.json)

It doesn't need to be Qwen, it needs an endpoint

By aifeifei798·Created about a month ago·Updated about 20 hours ago· 3
Prompt Enhancer (API: edit config.json)
  • image_1
  • image_2
  • image_3
  • image_4
  • rewritten_prompt
  • wh_ratio
  • width
  • height
  • ratio_follow
  • thinking
◄user_promptTokyo Japanese girl walking in the rain with umbrella►
◄modeT2I►
◄temperature0.70►
◄thinking_modeOurs (8-step)►
◄prompt_setQwen-Image-2.1►
◄timeout120►
◄bboxfalse►
◄canvas►

The class is called QwenImagePromptEnhancer and the display name is just "Prompt Enhancer," which is fair - the Qwen part refers to the system prompts, copied from Qwen-Image 2.1's own T2I and I2I prompt guides. Behind the URL, any OpenAI-compatible text LLM works. It defaults to llama.cpp on 127.0.0.1:8080.

The job is the classic one: you type a rough idea, a small local model rewrites it into a structured, detailed prompt and - this is the part most enhancers skip - also tells you what aspect ratio the composition wants, in pixels.

Inputs

Four widgets, all required: user_prompt (multiline, the rough idea), mode (T2I or I2I - this selects which system prompt is used), temperature (0.7), and thinking_mode.

thinking_mode is a real switch, not a cosmetic one. Ours (8-step), the default, sends the full shipped system prompt with enable_thinking false - in the author's own measurements that produces roughly 1600 characters of output. Model native throws your system prompt away and uses a built-in minimal instruction that just describes the JSON shape, with enable_thinking true, and yields around 550 characters. Both is for future Qwen3-class models that can do the full instruction and think. If a server rejects enable_thinking with a 400, the node retries once without it. There are no other inputs - no api_key widget, deliberately.

Outputs, and the one that surprises people

Six outputs: rewritten_prompt, wh_ratio, width, height, ratio_follow, thinking.

rewritten_prompt goes into your text encoder. width and height are real INTs ready for Empty Latent Image - the model isn't guessing pixels. The node takes the ratio the LLM returned, looks it up in a table of common 2K-ish sizes (so 2:1 is 2048×1024, 7:3 is 2352×1008, 18:39 is 1056×2288, 5:7 is 1280×1792), and for anything not in the table computes from a 1536×1536 target pixel count, clamped to ratios between 0.25 and 4.0 so a hallucinated 100:1 can't hand you a 40,000-pixel-wide latent. Everything is then rounded to a multiple of 16.

ratio_follow is the model's own notes about why it picked that ratio. Most people will ignore it, and it's genuinely useful the first few times your output keeps coming out 1:1 - because that's the tell. In T2I the code seeds wh_ratio with 3:2 before the call, so a model that says nothing gets the landscape default; in I2I it starts empty, and an unparseable or missing ratio falls back to 1:1, i.e. a 1536×1536 latent. If every run is square, the answer is in ratio_follow.

thinking is the model's reasoning, either from the API's reasoning_content field or pulled out of inline <think> tags. Wire it to a Show Text node while you're tuning; leave it unconnected after.

Configuring it

api_base, api_key and model come from config.json in the pack folder - there is no widget for them, and no environment variable is read anywhere in this pack (not OPENAI_API_KEY, not proxy vars). That's on purpose: a key typed into a panel gets written verbatim into every saved workflow and every image's metadata. Per-node overrides live under per_node:

{
  "api_base": "http://127.0.0.1:8080",
  "model": "",
  "per_node": { "QwenImagePromptEnhancer": { "model": "Qwen3-8B-Q4_K_M" } }
}

Leave api_key empty for llama.cpp, which needs none. The file is re-read on every run, so edits apply immediately without restarting ComfyUI. Host root or full /v1 URL both work - the code normalises to /v1 for the chat-completions call and strips it back off for a /completion fallback if your server doesn't speak the OpenAI route.

Install

ComfyUI Manager → ComfyUI-FeiFei, or:

cd ComfyUI/custom_nodes
git clone https://github.com/aifeifei798/ComfyUI-FeiFei.git
pip install openai   # optional; a urllib fallback handles the request without it

No model files ship with the pack. The LLM is yours to run - llama.cpp, Ollama, vLLM, or a cloud endpoint, as long as it exposes an OpenAI-compatible chat API.

What to watch for

  • API Error: as your output. Errors come back as strings instead of exceptions, so a dead endpoint doesn't kill the run - it just hands you an error message where a prompt should be. Fix config.json and re-run.
  • The enhancer adding things you didn't ask for. Every one of these nodes does this; it's the job description. Keep the prompt short and specific and check the first few outputs before you trust it in a batch.
  • A model that doesn't follow JSON. The node expects one JSON object and extracts it, but a chatty model leaks preamble into the prompt. Small and obedient beats large and clever here.
  • Bilingual output is a feature, not a bug. The Qwen-Image system prompt is happy to write Chinese, which is native territory for LLM-encoded image models and wasted tokens on a tag-based SDXL checkpoint. If you're on an old model, this is the wrong enhancer - the pack's Prompt Director has an explicit model_style switch for exactly that reason.
CategoryFeiFei

Inputs (12)

NameTypeDefaultDescription
user_promptSTRINGTokyo Japanese girl walking in the rain with umbrella—
modeCOMBOT2I2 options: T2I, I2I
temperatureFLOAT0.700.1–1.5—
thinking_modeCOMBOOurs (8-step)3 options: Ours (8-step), Model native, Both
prompt_setCOMBOQwen-Image-2.1Qwen-Image-2.1 replies with JSON and a wh_ratio; Flux-3-Klein-PUP replies with the bare caption (or instruction) the image model consumes.
timeoutoptINT12010–600Request timeout in seconds.
bboxoptBOOLEANfalseFlux set only: use the _bbox prompt (caption/instruction plus a JSON element table).
canvasoptSTRINGFlux T2I only: target canvas as W:H, sent as a TARGET CANVAS line and echoed to wh_ratio / width / height. Leave empty to let the model compose freely.
image_1optIMAGE—
image_2optIMAGE—
image_3optIMAGE—
image_4optIMAGE—

Outputs (6)

NameTypeDescription
rewritten_promptSTRING—
wh_ratioSTRING—
widthINT—
heightINT—
ratio_followSTRING—
thinkingSTRING—