← back to Wallco Ai
comfy: optional SDXL base+refiner workflow (COMFY_REFINER_MODEL) — matches Replicate's expert-ensemble pipeline
25f96e92aab6ec4998c42da35999895ffbbf39c0 · 2026-05-19 11:10:18 -0700 · SteveStudio2
Files touched
M scripts/generate_designs.js
Diff
commit 25f96e92aab6ec4998c42da35999895ffbbf39c0
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date: Tue May 19 11:10:18 2026 -0700
comfy: optional SDXL base+refiner workflow (COMFY_REFINER_MODEL) — matches Replicate's expert-ensemble pipeline
---
scripts/generate_designs.js | 42 +++++++++++++++++++++++++++++++++---------
1 file changed, 33 insertions(+), 9 deletions(-)
diff --git a/scripts/generate_designs.js b/scripts/generate_designs.js
index 71b9ab4..eb3c696 100644
--- a/scripts/generate_designs.js
+++ b/scripts/generate_designs.js
@@ -219,15 +219,39 @@ function genComfy(prompt, seed, outPath) {
const positivePrompt = `${prompt}, seamless tile, repeating pattern, no edges, fabric pattern, wallpaper design, high detail, archival quality, screen-printed wallpaper, solid opaque flat ink, flat color blocks, every shape fully filled with solid color, even saturated pigment coverage, crisp screen-print layers`;
const negativePrompt = 'low quality, blurry, edges, seam, border, frame, signature, watermark, text, hands, fingers, transparent, see-through, translucent, unfilled shapes, hollow outlines, outline-only motifs, ghosted layers, washed out, faded, low opacity, gaps in the ink, missing fill, gradient bleed';
- const workflow = {
- '3': { class_type: 'KSampler', inputs: { seed, steps: 28, cfg: 7.5, sampler_name: 'euler', scheduler: 'normal', denoise: 1.0, model: ['4', 0], positive: ['6', 0], negative: ['7', 0], latent_image: ['5', 0] } },
- '4': { class_type: 'CheckpointLoaderSimple', inputs: { ckpt_name: MODEL } },
- '5': { class_type: 'EmptyLatentImage', inputs: { width: WIDTH, height: HEIGHT, batch_size: 1 } },
- '6': { class_type: 'CLIPTextEncode', inputs: { text: positivePrompt, clip: ['4', 1] } },
- '7': { class_type: 'CLIPTextEncode', inputs: { text: negativePrompt, clip: ['4', 1] } },
- '8': { class_type: 'VAEDecode', inputs: { samples: ['3', 0], vae: ['4', 2] } },
- '9': { class_type: 'SaveImage', inputs: { filename_prefix: `wallco_${seed}`, images: ['8', 0] } }
- };
+ // Optional SDXL refiner — set COMFY_REFINER_MODEL=sd_xl_refiner_1.0.safetensors
+ // to run base+refiner (expert-ensemble), matching what Replicate's SDXL does.
+ // Unset => base-only (the default; SaveImage stays node '9' either way).
+ const REFINER = process.env.COMFY_REFINER_MODEL || '';
+ const STEPS = parseInt(process.env.COMFY_STEPS || '30', 10);
+ const SWITCH = Math.round(STEPS * 0.8); // base → refiner handoff at 80%
+
+ let workflow;
+ if (REFINER) {
+ workflow = {
+ '4': { class_type: 'CheckpointLoaderSimple', inputs: { ckpt_name: MODEL } },
+ '15': { class_type: 'CheckpointLoaderSimple', inputs: { ckpt_name: REFINER } },
+ '5': { class_type: 'EmptyLatentImage', inputs: { width: WIDTH, height: HEIGHT, batch_size: 1 } },
+ '6': { class_type: 'CLIPTextEncode', inputs: { text: positivePrompt, clip: ['4', 1] } },
+ '7': { class_type: 'CLIPTextEncode', inputs: { text: negativePrompt, clip: ['4', 1] } },
+ '16': { class_type: 'CLIPTextEncode', inputs: { text: positivePrompt, clip: ['15', 1] } },
+ '17': { class_type: 'CLIPTextEncode', inputs: { text: negativePrompt, clip: ['15', 1] } },
+ '10': { class_type: 'KSamplerAdvanced', inputs: { add_noise: 'enable', noise_seed: seed, steps: STEPS, cfg: 7.5, sampler_name: 'euler', scheduler: 'normal', start_at_step: 0, end_at_step: SWITCH, return_with_leftover_noise: 'enable', model: ['4', 0], positive: ['6', 0], negative: ['7', 0], latent_image: ['5', 0] } },
+ '11': { class_type: 'KSamplerAdvanced', inputs: { add_noise: 'disable', noise_seed: seed, steps: STEPS, cfg: 7.5, sampler_name: 'euler', scheduler: 'normal', start_at_step: SWITCH, end_at_step: 10000, return_with_leftover_noise: 'disable', model: ['15', 0], positive: ['16', 0], negative: ['17', 0], latent_image: ['10', 0] } },
+ '8': { class_type: 'VAEDecode', inputs: { samples: ['11', 0], vae: ['15', 2] } },
+ '9': { class_type: 'SaveImage', inputs: { filename_prefix: `wallco_${seed}`, images: ['8', 0] } }
+ };
+ } else {
+ workflow = {
+ '3': { class_type: 'KSampler', inputs: { seed, steps: 28, cfg: 7.5, sampler_name: 'euler', scheduler: 'normal', denoise: 1.0, model: ['4', 0], positive: ['6', 0], negative: ['7', 0], latent_image: ['5', 0] } },
+ '4': { class_type: 'CheckpointLoaderSimple', inputs: { ckpt_name: MODEL } },
+ '5': { class_type: 'EmptyLatentImage', inputs: { width: WIDTH, height: HEIGHT, batch_size: 1 } },
+ '6': { class_type: 'CLIPTextEncode', inputs: { text: positivePrompt, clip: ['4', 1] } },
+ '7': { class_type: 'CLIPTextEncode', inputs: { text: negativePrompt, clip: ['4', 1] } },
+ '8': { class_type: 'VAEDecode', inputs: { samples: ['3', 0], vae: ['4', 2] } },
+ '9': { class_type: 'SaveImage', inputs: { filename_prefix: `wallco_${seed}`, images: ['8', 0] } }
+ };
+ }
// Submit
const submit = execSync(`curl -sf -m 30 -H 'Content-Type: application/json' -X POST '${COMFY}/prompt' -d @-`, {
← a787241 generator: steer SDXL to screen-print look — solid opaque fl
·
back to Wallco Ai
·
add refiner_compare.js — 25-prompt base vs base+refiner side 9bda674 →