Nodes/ComfyUI-Angelo/Angelo — click to refine
ComfyUI Node

Angelo — click to refine

The click-to-edit sampler that replaces your whole fix-it chain

By shootthesound·Created 3 months ago·Updated about a month ago· 128
Angelo — click to refine
  • model
  • positive
  • negative
  • vae
  • clip
  • latent
  • overrides
  • image
  • latent
  • source_image
modeSampler Mode
sampler_denoise1.00
sampler_seed0
sampler_seed_controlrandomize
seed0
seed_controlrandomize
steps4
cfg1.0
sampler_nameeuler
schedulersimple
denoise0.50
click_radius96
feather_radius24
click_x-1
click_y-1
click_seq0
image_w0
image_h0
undo_seq0
resetfalse
auto_decodetrue
fine_upscalingfalse
min_megapixels1.0
max_upscale8.0
resize_methodlanczos
inpainting_modeRefine
guided_location(none)
fine_context_pad64
persistent_maskfalse
paint_modefalse
stroke_points
rect_points
area_promptfalse
area_text_positive
area_text_negative
loaded_image
loaded_image_seq0
loaded_resize_modekeep
loaded_target_mp1.5
seg_polygon
reroll_seq0
seg_mask_png
redo_seq0
restore_modefalse
area_prompt_slots
vary_seq0
vary_pick-1
vary_pick_seq0
outpaint_seq0
outpaint_dirright
outpaint_amount256
outpaint_overlap64
outpaint_accept_seq0
outpaint_protect
outpaint_instruction_posprepend
refine_referencefalse
quick_refine_seq0
reference_strength0.00
upscale_seq0
quick_prompt_modeIdentity + Quality
shrink_seq0
shrink_scale0.50
quick_litefalse
remove_modefalse

If you've ever generated something 95% right and then burned ten minutes fixing it - save the image, open MaskEditor, paint a mask, wire it back through a second KSampler, requeue, repeat for the next thing - AngeloRefine exists to make you stop doing that. It's a sampler with an interactive canvas bolted onto the front: generate the base image in Sampler Mode, flip to Edit Mode, then click, paint, or drag directly on the node's own preview to fix what's wrong. One node instead of a KSampler plus ADetailer plus MaskEditor plus an outpaint-pad chain, and every fix redraws immediately, in place.

The underlying idea isn't new - it's the same detect-mask-inpaint loop that made A1111's ADetailer beloved and that Impact Pack's FaceDetailer ported to ComfyUI: crop a struggling region, refine it at real resolution, composite back so everything else stays untouched. What's different is where the pieces live. ADetailer and FaceDetailer are separate detect → crop → sample → composite nodes you wire together; Angelo folds the mask, the crop-and-upscale (called Xtra-Fine here), and the composite into one sampler, driven by your mouse instead of a YOLO model. Same payoff - a 64-latent-unit face jumping to roughly 1000 units of working room - with no detector graph to assemble.

Two modes gate everything. Sampler Mode is Angelo acting like a plain KSampler off your Empty Latent - sampler_denoise, sampler_seed, and the seed-control widget live here. Flip Mode to Edit Mode and those grey out; instead you get denoise (per the node's own tooltip: 0.3 for a subtle touch-up, 0.6 for a real redo, 0.9+ to essentially regenerate the region), click_radius for how big a single click's refine area is, and feather_radius to soften the mask edge. inpainting_mode decides how a painted region gets treated: Refine partially denoises whatever's already there and works on any sampler-compatible checkpoint - SDXL, SD 1.5, FLUX 1, anything. Smart Inpaint and Smart Guided Inpaint zero the masked latent and inject reference_latents, which only an edit-trained model can use - FLUX 2 Klein 9B or Qwen-Image-Edit. That's the same reference-latent-plus-InpaintModelConditioning trick people wire by hand elsewhere to get true masked inpainting out of an edit model; Angelo just does it natively when you drag a rectangle or pick a location from a dropdown. Outpaint grows the canvas instead, with a review-before-commit step so a bad extension costs nothing.

Required wiring is unremarkable: model, positive, negative, vae. clip is optional but you'll want it connected - without it, the in-node Area Prompt box and both Smart modes are dead. latent is optional too; skip it and use Load Image instead if you're editing a real photo rather than something you generated. There's also an overrides slot that takes the paired Angelo - Overrides node, for driving steps/cfg/sampler/scheduler from elsewhere in your graph instead of the toolbar. Outputs are image, latent, and source_image - that last one is the original, pre-edit base, useful for wiring straight into a before/after compare node. Most of the remaining schema fields (click_x, stroke_points, rect_points, seg_polygon, and a pile of *_seq counters) aren't things you type - they're state the toolbar JavaScript writes when you click, paint, or drag. Ignore them and use the actual toolbar.

Installing it is a plain custom-node clone: cd ComfyUI/custom_nodes && git clone https://github.com/shootthesound/ComfyUI-Angelo, then restart. No extra Python dependencies for the core node, which is genuinely nice given how much it does. The one opt-in extra is Detect, which lets you type "the face" instead of clicking it - that needs Meta's SAM 3, which isn't on PyPI, so it ships as a separate installer (install_sam3_support.sh / .bat) you run with ComfyUI closed; the ~1GB weights pull down automatically the first time you use it. Skip it if you don't need "type a word, get a mask" - everything else in the node works without it.

Where people actually get stuck: pointing Smart Inpaint or Smart Guided Inpaint at a plain checkpoint instead of an edit model. A base Qwen-Image (not the Edit variant) has the reference-latent code path but was never trained for it, so you get color-distorted output rather than a clean error - regular Refine works on anything, the Smart modes specifically need Klein 9B or Qwen-Image-Edit. Second: ComfyUI's global latent-preview setting can render into the node mid-sample and squash the editing canvas down to nothing - a real, reported annoyance; the fix (disable_live_preview) lives on the companion Overrides node, not here. And go in knowing this is in-process state: undo history and cached refinements live in the running ComfyUI server, not the saved workflow JSON, so a restart clears the canvas back to nothing and you're loading the base image again.

Categorysampling/Angelo

Inputs (71)

NameTypeDefaultDescription
modelMODEL
positiveCONDITIONING
negativeCONDITIONING
vaeVAE
modeCOMBOSampler ModeSampler Mode: AngeloRefine acts like a KSampler — generates the base latent from the incoming (usually empty) latent. Toolbar and canvas clicks are inert. Edit Mode: click / paint / drag to refine or inpaint the cached base. Switching to Edit Mode auto-locks sampler_seed_control to 'fixed' so the base stays stable.
sampler_denoiseFLOAT1.000.05–1[Sampler Mode] Denoise level for the base generation. 1.0 = generate fully from noise (KSampler default). Lower = img2img-style from the incoming latent.
sampler_seedINT00–18446744073709550000[Sampler Mode] Seed for the base generation. Controlled by sampler_seed_control after each run.
sampler_seed_controlCOMBOrandomize[Sampler Mode] After-generation seed behaviour. Defaults to randomize so each base generation gets a fresh seed. Auto-forced to 'fixed' (locked to the seed that produced the base) when you switch to Edit Mode so refine clicks stay stable.
seedINT00–18446744073709550000[Edit Mode] Seed for the refine pass. Hidden — controlled by the Seed input on the toolbar.
seed_controlCOMBOrandomize[Edit Mode] After-click seed behaviour. Hidden — controlled by the Seed Ctrl dropdown on the toolbar. Defaults to randomize so each refine click produces a fresh variation rather than repeating the same result.
stepsINT41–100Match the model's expected step count. FLUX 2 Klein distilled = 4.
cfgFLOAT1.00–30FLUX 2 Klein distilled uses CFG=1 (no negative).
sampler_nameCOMBOeuler44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBOsimple9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
denoiseFLOAT0.500.05–1How much noise to add back for the refinement. 0.3 = subtle touch-up, 0.6 = real redo, 0.9+ = essentially regenerate that region.
click_radiusINT968–1024Pixel-space radius of the refinement region. Updated automatically by the JS click widget.
feather_radiusINT240–256Pixel-space gaussian blur applied to the mask before sampling. Smooths the seam between the refined region and the preserved surroundings. Roughly half of click_radius is a good default.
click_xINT-1-1–16384
click_yINT-1-1–16384
click_seqINT00–2147483647
image_wINT00–16384
image_hINT00–16384
undo_seqINT00–2147483647
resetBOOLEANfalseTick + re-queue to discard the cached refined latent and start over from the incoming latent.
auto_decodeBOOLEANtrue(Deprecated — preview always decodes now.)
fine_upscalingBOOLEANfalseWhen ON, the painted region is cropped, bilinear-upscaled in latent space to hit min_megapixels, refined, downscaled, and composited back. Gives the model more effective resolution on small painted regions. Upscale capped at 8× linear internally. Set via the Fine Upscale toggle above the preview.
min_megapixelsFLOAT1.00.1–4Target megapixels for the refine pass when Fine Upscaling is on. Only used in that mode. Set via the MP input above the preview.
max_upscaleFLOAT8.01–16Hard cap on the linear upscale factor in Fine Upscaling. 8.0 was the original internal default. Lower values reduce smoothing artifacts from extreme upscales at the cost of less effective resolution gain. Set via the Max input above the preview.
resize_methodCOMBOlanczosPixel-space upscale method for Fine Upscale. lanczos is the default — sharpest detail recovery for natural images. bilinear is smooth (good for skin/faces); bicubic middle ground; nearest-exact preserves exact sample values; area/bislerp niche.
inpainting_modeCOMBORefineHow the painted region is treated. Refine — the painted region is partially denoised from the existing content. Best for refining what's already there (faces, hands, textures). Paint/click as normal. Smart Inpaint — adds NEW content where you drag a rectangle. Click+hold one corner, release at the opposite corner. Locks denoise=1.0, Fine Upscale=ON, Ctx Pad=0 (the right defaults for adding new subjects with an edit model — Klein 9B etc.). Reference_latents are auto-injected so the model's edit branch activates. Smart Guided Inpaint — no painting or boxes. Pick a location from the dropdown above the Area Prompt; it's prepended to your prompt (e.g. 'In the top left of the image, ...') and the edit model places the content there across the whole image. Locks denoise=1.0, Fine Upscale=OFF, Area Prompt=ON; press 'Generate Guided Edit' to run. Outpaint — extend the canvas. Pick a direction (arrows, or click near an edge of the preview), review the result, Accept to commit. Accepting installs the new canvas as a fresh session base — history resets.
guided_locationSTRING(none)
fine_context_padINT640–512[Fine Upscale] Pixel-space padding around the painted-shape bbox before cropping. Gives the model surrounding context (skin, hair, background) so a tight face mask at high denoise still produces a coherent face that matches its surroundings. The painted shape is unchanged — only the area the model SEES grows. Outside the painted shape, the surrounding pixels are preserved (not refined). Larger pad = more context + less effective resolution on the painted area (bump MP to compensate).
persistent_maskBOOLEANfalseWhen ON, the last mask used (click point or paint stroke) is held in the node. Pressing the standard ComfyUI Queue button re-runs that same mask + a fresh seed on the LATEST result, so each press builds further on that region — use it to gradually morph an area over several presses while the rest of the image stays unchanged. (To re-roll the same edit on the ORIGINAL image instead of building on it, use the Re-roll button.) Toggled via the Persistent Mask button above the preview.
paint_modeBOOLEANfalseWhen ON, hold + drag on the preview paints a freeform brush stroke (each dragged point is the centre of a circle of click_radius; the union is the refine mask). Release to submit. Single clicks in paint mode work as one-point strokes. When OFF, clicks behave as before (single-circle refine).
stroke_pointsSTRING
rect_pointsSTRING
area_promptBOOLEANfalseWhen ON, refinements encode the Area Prompt text (typed in the box below the canvas) with the connected CLIP and use it instead of the main positive/negative — useful for reshaping a region with a different prompt (e.g. main prompt = wide shot, area prompt = "detailed face, photorealistic eyes"). The click-and-mask behaviour is unchanged; only the prompt differs. If CLIP isn't connected or the area text is empty, the main positive/negative are used. Forced ON in Smart Inpaint.
area_text_positiveSTRING
area_text_negativeSTRING
loaded_imageSTRING
loaded_image_seqINT00–4294967295
loaded_resize_modeCOMBOkeep2 options: keep, mp
loaded_target_mpFLOAT1.50.1–8
seg_polygonSTRING
reroll_seqINT00–2147483647
seg_mask_pngSTRING
redo_seqINT00–2147483647
restore_modeBOOLEANfalseWhen ON, clicks and paint strokes restore the painted region back to the session base image (a feathered latent blend — no sampling, instant). Refine mode only. Toggled via the Restore button on the toolbar.
area_prompt_slotsSTRING
vary_seqINT00–2147483647
vary_pickINT-1-1–15
vary_pick_seqINT00–2147483647
outpaint_seqINT00–2147483647
outpaint_dirSTRINGright
outpaint_amountINT25616–2048Outpaint: how many pixels to extend the canvas by (snapped to /16). Set via the Amount input on the Outpaint row.
outpaint_overlapINT640–512Outpaint: feathered band reaching this many pixels INTO the existing image, redrawn so the seam blends instead of butting. Set via the Overlap input on the Outpaint row.
outpaint_accept_seqINT00–2147483647
outpaint_protectSTRING
outpaint_instruction_posCOMBOprepend2 options: prepend, append
refine_referenceBOOLEANfalseAnchor refines to the current image (edit models). The strength box beside the toolbar button sets the blend. Toggled via the Reference button.
quick_refine_seqINT00–2147483647
reference_strengthFLOAT0.000–1How strongly the current image anchors a refine — a true blend between the anchored and free predictions. 0 = off, 1 = fully anchored. Set via the Ref box on the toolbar.
upscale_seqINT00–2147483647
quick_prompt_modeCOMBOIdentity + Quality4 options: Identity + Quality, Restore Photo, Identity + Colours, Use Area Prompt
shrink_seqINT00–2147483647
shrink_scaleFLOAT0.500.05–0.95
quick_liteBOOLEANfalse
remove_modeBOOLEANfalseWhen ON, clicks / paint / Detect masks REMOVE the painted object: the hole is filled with surrounding background, a removal pass reconstructs it, then a neutral refine cleans it up (edit models only). Refine mode only; toggled via the Remove button on the toolbar.
clipoptCLIP
latentoptLATENT
overridesoptANGELO_OVERRIDESOptional. Wire from an 'Angelo — Overrides' node to drive steps / cfg / sampler / scheduler from your workflow instead of the toolbar — and/or to supply a dedicated GENERATION model (gen bundle): Sampler Mode generates the base with it, then the main model handles all edits.

Outputs (3)

NameTypeDescription
imageIMAGE
latentLATENT
source_imageIMAGE