ComfyUI Workflow Builder Translates natural language requests into executable ComfyUI workflow JSON. Always validates against inventory before generating. Workflow Generation Process Step 1: Understand the Request Parse the user's intent into: - Output type : Image, video, or audio - Source material : Text-only, reference image(s), existing video - Identity method : None, zero-shot (InstantID/PuLID), LoRA, Kontext - Quality level : Draft (fast iteration) vs production (maximum quality) - Special requirements : ControlNet, inpainting, upscaling, lip-sync Step 2: Check Inventory Read to determi…

\\n'\n fi\n fi\n done \u003c \"$yaml_file\"\n\n if [[ -n \"$current_id\" ]]; then\n ids+=(\"$current_id\")\n printf '%s' \"$current_prompt\" > \"$RESULTS_DIR/prompts/${current_id}.txt\"\n fi\n\n echo \"${ids[@]}\"\n}\n\nCASE_IDS=($(extract_cases))\necho \"Found ${#CASE_IDS[@]} test cases: ${CASE_IDS[*]}\"\n\nif [[ -n \"$SINGLE_CASE\" ]]; then\n CASE_IDS=(\"$SINGLE_CASE\")\n echo \"Filtering to: $SINGLE_CASE\"\nfi\necho \"\"\n\n# ─── Run test cases ────────────────────────────────────────────────\n\nrun_case() {\n local case_id=\"$1\"\n local mode=\"$2\"\n local prompt_file=\"$RESULTS_DIR/prompts/${case_id}.txt\"\n local output_file=\"$RESULTS_DIR/$mode/${case_id}.md\"\n local prompt_text\n prompt_text=$(cat \"$prompt_file\")\n\n echo \" [$mode] Running $case_id...\"\n\n if [[ \"$mode\" == \"with-skill\" ]]; then\n local full_prompt=\"Use the $SKILL_NAME skill to answer this: $prompt_text\"\n claude -p \"$full_prompt\" \\\n --allowedTools \"Read,Glob,Grep\" \\\n --max-turns 3 \\\n --output-format text \\\n > \"$output_file\" 2>/dev/null || {\n echo \"EVAL_ERROR: claude command failed for $case_id ($mode)\" > \"$output_file\"\n }\n else\n claude -p \"$prompt_text\" \\\n --allowedTools \"Read,Glob,Grep\" \\\n --max-turns 3 \\\n --output-format text \\\n > \"$output_file\" 2>/dev/null || {\n echo \"EVAL_ERROR: claude command failed for $case_id ($mode)\" > \"$output_file\"\n }\n fi\n\n local wc_out\n wc_out=$(wc -w \u003c \"$output_file\" | tr -d ' ')\n echo \" [$mode] $case_id complete ($wc_out words)\"\n}\n\nif ! $SCORE_ONLY; then\n if $RUN_SKILL; then\n echo \"── With Skill ──\"\n for case_id in \"${CASE_IDS[@]}\"; do\n run_case \"$case_id\" \"with-skill\"\n done\n echo \"\"\n fi\n\n if $RUN_BASELINE; then\n echo \"── Baseline (no skill) ──\"\n for case_id in \"${CASE_IDS[@]}\"; do\n run_case \"$case_id\" \"baseline\"\n done\n echo \"\"\n fi\nfi\n\n# ─── Assertion evaluation helpers ──────────────────────────────────\n\n# Extract first JSON block from response\nextract_json() {\n local text=\"$1\"\n # Try ```json fenced block first\n local block\n block=$(echo \"$text\" | sed -n '/```json/,/```/p' | sed '1d;$d')\n if [[ -z \"$block\" ]]; then\n # Try bare { ... } block\n block=$(echo \"$text\" | grep -Pzo '\\{[^{}]*(\\{[^{}]*\\}[^{}]*)*\\}' 2>/dev/null | head -1 || true)\n fi\n echo \"$block\"\n}\n\n# Get a field value from JSON (uses python if available, else node)\njson_field() {\n local json=\"$1\"\n local field=\"$2\"\n if command -v python3 &>/dev/null; then\n echo \"$json\" | python3 -c \"\nimport sys, json\ntry:\n d = json.load(sys.stdin)\n v = d.get('$field', '')\n if isinstance(v, list): print(len(v))\n elif isinstance(v, (int, float)): print(v)\n else: print(v)\nexcept: print('')\n\" 2>/dev/null\n elif command -v node &>/dev/null; then\n echo \"$json\" | node -e \"\nlet d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{\n try{const o=JSON.parse(d);const v=o['$field'];\n if(Array.isArray(v))console.log(v.length);\n else console.log(v??'');}catch(e){console.log('');}\n})\" 2>/dev/null\n else\n echo \"\"\n fi\n}\n\n# Word count of a string\nword_count() {\n echo \"$1\" | wc -w | tr -d ' '\n}\n\n# ─── Score a single assertion ──────────────────────────────────────\n\neval_assertion() {\n local response=\"$1\"\n local atype=\"$2\"\n local target=\"$3\"\n local json_block=\"$4\"\n\n case \"$atype\" in\n contains)\n echo \"$response\" | grep -qi \"$target\" && echo \"PASS\" || echo \"FAIL\"\n ;;\n\n not_contains)\n # Handle descriptive targets: if target contains spaces and \"should not contain\",\n # try to extract the quoted literal(s)\n if [[ \"$target\" =~ \\'([^\\']+)\\' ]]; then\n local found=false\n while [[ \"$target\" =~ \\'([^\\']+)\\' ]]; do\n local literal=\"${BASH_REMATCH[1]}\"\n if echo \"$response\" | grep -qi \"$literal\"; then\n found=true\n break\n fi\n target=\"${target#*\"'${literal}'\"}\"\n done\n $found && echo \"FAIL\" || echo \"PASS\"\n else\n echo \"$response\" | grep -qi \"$target\" && echo \"FAIL\" || echo \"PASS\"\n fi\n ;;\n\n regex)\n echo \"$response\" | grep -qiE \"$target\" && echo \"PASS\" || echo \"FAIL\"\n ;;\n\n question_before_code)\n local q_line code_line\n q_line=$(echo \"$response\" | grep -n '?' | head -1 | cut -d: -f1)\n code_line=$(echo \"$response\" | grep -n '```' | head -1 | cut -d: -f1)\n if [[ -z \"$code_line\" ]] || [[ -n \"$q_line\" && \"$q_line\" -lt \"$code_line\" ]]; then\n echo \"PASS\"\n else\n echo \"FAIL\"\n fi\n ;;\n\n json_valid)\n if [[ -n \"$json_block\" ]]; then\n if command -v python3 &>/dev/null; then\n echo \"$json_block\" | python3 -c \"import sys,json;json.load(sys.stdin)\" 2>/dev/null && echo \"PASS\" || echo \"FAIL\"\n elif command -v node &>/dev/null; then\n echo \"$json_block\" | node -e \"let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{JSON.parse(d);console.log('PASS')}catch(e){console.log('FAIL')}})\" 2>/dev/null\n else\n echo \"SKIP\"\n fi\n else\n echo \"FAIL\"\n fi\n ;;\n\n json_schema|json_fields)\n # Target is comma-separated field names\n if [[ -z \"$json_block\" ]]; then\n echo \"FAIL\"\n return\n fi\n local all_found=true\n IFS=',' read -ra FIELDS \u003c\u003c\u003c \"$target\"\n for field in \"${FIELDS[@]}\"; do\n field=$(echo \"$field\" | xargs) # trim whitespace\n if ! echo \"$json_block\" | grep -q \"\\\"$field\\\"\"; then\n all_found=false\n break\n fi\n done\n $all_found && echo \"PASS\" || echo \"FAIL\"\n ;;\n\n token_limit)\n local wc\n wc=$(word_count \"$response\")\n local est_tokens=$(( wc * 13 / 10 ))\n [[ \"$est_tokens\" -le \"${target:-99999}\" ]] && echo \"PASS\" || echo \"FAIL\"\n ;;\n\n range_check)\n # Parse common patterns from the target expression\n if [[ -z \"$json_block\" ]]; then\n echo \"FAIL\"\n return\n fi\n\n # Handle: bias_score >= X AND bias_score \u003c= Y\n if [[ \"$target\" =~ ([a-z_]+)\\ *\\>=\\ *(-?[0-9.]+)\\ +AND\\ +\\1\\ *\\\u003c=\\ *(-?[0-9.]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local max=\"${BASH_REMATCH[3]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n if [[ -n \"$val\" ]] && command -v python3 &>/dev/null; then\n python3 -c \"v=$val; print('PASS' if $min \u003c= v \u003c= $max else 'FAIL')\" 2>/dev/null || echo \"FAIL\"\n else\n echo \"SKIP\"\n fi\n return\n fi\n\n # Handle: abs(field) \u003c= X\n if [[ \"$target\" =~ abs\\(([a-z_]+)\\)\\ *\\\u003c=\\ *(-?[0-9.]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local limit=\"${BASH_REMATCH[2]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n if [[ -n \"$val\" ]] && command -v python3 &>/dev/null; then\n python3 -c \"v=$val; print('PASS' if abs(v) \u003c= $limit else 'FAIL')\" 2>/dev/null || echo \"FAIL\"\n else\n echo \"SKIP\"\n fi\n return\n fi\n\n # Handle: quality_score >= X\n if [[ \"$target\" =~ ([a-z_]+)\\ *\\>=\\ *(-?[0-9.]+)$ ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n if [[ -n \"$val\" ]] && command -v python3 &>/dev/null; then\n python3 -c \"v=$val; print('PASS' if v >= $min else 'FAIL')\" 2>/dev/null || echo \"FAIL\"\n else\n echo \"SKIP\"\n fi\n return\n fi\n\n # Handle: len(field) >= X AND len(field) \u003c= Y (character length)\n if [[ \"$target\" =~ len\\(([a-z_]+)\\)\\ *\\>=\\ *([0-9]+)\\ +AND\\ +len\\(\\1\\)\\ *\\\u003c=\\ *([0-9]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local max=\"${BASH_REMATCH[3]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n local len=${#val}\n [[ \"$len\" -ge \"$min\" && \"$len\" -le \"$max\" ]] && echo \"PASS\" || echo \"FAIL\"\n return\n fi\n\n # Handle: len(field) \u003c= X\n if [[ \"$target\" =~ len\\(([a-z_]+)\\)\\ *\\\u003c=\\ *([0-9]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local max=\"${BASH_REMATCH[2]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n local len=${#val}\n [[ \"$len\" -le \"$max\" ]] && echo \"PASS\" || echo \"FAIL\"\n return\n fi\n\n # Handle: len(field) >= X (list length)\n if [[ \"$target\" =~ len\\(([a-z_]+)\\)\\ *\\>=\\ *([0-9]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n [[ \"$val\" -ge \"$min\" ]] 2>/dev/null && echo \"PASS\" || echo \"FAIL\"\n return\n fi\n\n # Handle: word_count(field) >= X AND word_count(field) \u003c= Y\n if [[ \"$target\" =~ word_count\\(([a-z_]+)\\)\\ *\\>=\\ *([0-9]+)\\ +AND\\ +word_count\\(\\1\\)\\ *\\\u003c=\\ *([0-9]+) ]]; then\n local field=\"${BASH_REMATCH[1]}\"\n local min=\"${BASH_REMATCH[2]}\"\n local max=\"${BASH_REMATCH[3]}\"\n local val\n val=$(json_field \"$json_block\" \"$field\")\n local wc\n wc=$(word_count \"$val\")\n [[ \"$wc\" -ge \"$min\" && \"$wc\" -le \"$max\" ]] && echo \"PASS\" || echo \"FAIL\"\n return\n fi\n\n echo \"SKIP\" # Unrecognized expression\n ;;\n\n # Soft assertion types — logged but always PASS (require LLM judge)\n structure_check|sequence_check)\n echo \"SOFT\"\n ;;\n\n *)\n echo \"SKIP\"\n ;;\n esac\n}\n\n# ─── Score all assertions for a case ───────────────────────────────\n\nscore_case() {\n local case_id=\"$1\"\n local mode=\"$2\"\n local output_file=\"$RESULTS_DIR/$mode/${case_id}.md\"\n local score_file=\"$RESULTS_DIR/$mode/${case_id}.score.txt\"\n local response\n response=$(cat \"$output_file\" 2>/dev/null || echo \"\")\n\n if [[ \"$response\" == EVAL_ERROR* ]]; then\n echo \"ERROR\" > \"$score_file\"\n echo \"ERROR\"\n return\n fi\n\n local json_block\n json_block=$(extract_json \"$response\")\n\n local pass=0 fail=0 soft=0 skip=0 total=0\n local critical_fail=false\n local details=\"\"\n\n # Parse assertions from YAML\n local in_case=false\n local in_assertions=false\n local assert_type=\"\" assert_target=\"\" assert_critical=\"false\" assert_desc=\"\"\n\n process_assertion() {\n if [[ -z \"$assert_type\" ]]; then return; fi\n total=$((total + 1))\n local result\n result=$(eval_assertion \"$response\" \"$assert_type\" \"$assert_target\" \"$json_block\")\n\n case \"$result\" in\n PASS) pass=$((pass + 1)) ;;\n FAIL)\n fail=$((fail + 1))\n [[ \"$assert_critical\" == \"true\" ]] && critical_fail=true\n ;;\n SOFT) soft=$((soft + 1)) ;;\n SKIP) skip=$((skip + 1)) ;;\n esac\n\n local label=\"${assert_desc:-$assert_type($assert_target)}\"\n local crit_marker=\"\"\n [[ \"$assert_critical\" == \"true\" ]] && crit_marker=\" [CRITICAL]\"\n details+=\" $result$crit_marker — $label\"

ComfyUI Workflow Builder Translates natural language requests into executable ComfyUI workflow JSON. Always validates against inventory before generating. Workflow Generation Process Step 1: Understand the Request Parse the user's intent into: - Output type : Image, video, or audio - Source material : Text-only, reference image(s), existing video - Identity method : None, zero-shot (InstantID/PuLID), LoRA, Kontext - Quality level : Draft (fast iteration) vs production (maximum quality) - Special requirements : ControlNet, inpainting, upscaling, lip-sync Step 2: Check Inventory Read to determi…

\\n'\n }\n\n while IFS= read -r line; do\n if [[ \"$line\" =~ ^-\\ id:\\ $case_id$ ]]; then\n in_case=true\n continue\n fi\n if $in_case && [[ \"$line\" =~ ^-\\ id: ]]; then\n break\n fi\n\n if $in_case && [[ \"$line\" =~ ^\\ \\ \\ \\ -\\ type:\\ (.+) ]]; then\n process_assertion\n assert_type=\"${BASH_REMATCH[1]}\"\n assert_target=\"\"\n assert_critical=\"false\"\n assert_desc=\"\"\n fi\n if $in_case && [[ \"$line\" =~ ^\\ \\ \\ \\ \\ \\ target:\\ (.+) ]]; then\n assert_target=\"${BASH_REMATCH[1]}\"\n assert_target=\"${assert_target#\\\"}\"\n assert_target=\"${assert_target%\\\"}\"\n fi\n if $in_case && [[ \"$line\" =~ ^\\ \\ \\ \\ \\ \\ critical:\\ (.+) ]]; then\n assert_critical=\"${BASH_REMATCH[1]}\"\n fi\n if $in_case && [[ \"$line\" =~ ^\\ \\ \\ \\ \\ \\ description:\\ (.+) ]]; then\n assert_desc=\"${BASH_REMATCH[1]}\"\n assert_desc=\"${assert_desc#\\\"}\"\n assert_desc=\"${assert_desc%\\\"}\"\n fi\n done \u003c \"$SCRIPT_DIR/test-cases.yaml\"\n process_assertion # last assertion\n\n local anchored=$((pass + fail))\n local score_line=\"$pass/$total (${anchored} anchored, ${soft} soft, ${skip} skipped)\"\n if $critical_fail; then\n score_line+=\" [CRITICAL FAIL]\"\n fi\n\n {\n echo \"$score_line\"\n echo \"$details\"\n } > \"$score_file\"\n\n echo \"$score_line\"\n}\n\n# ─── Generate scorecard ───────────────────────────────────────────\n\ngenerate_scorecard() {\n local scorecard=\"$RESULTS_DIR/scorecard.md\"\n\n cat > \"$scorecard\" \u003c\u003cHEADER\n# Eval Scorecard — $SKILL_NAME\n**Timestamp:** $TIMESTAMP\n\n| Test Case | With Skill | Baseline |\n|-----------|-----------|----------|\nHEADER\n\n for case_id in \"${CASE_IDS[@]}\"; do\n local skill_score=\"—\"\n local base_score=\"—\"\n\n if $RUN_SKILL && [[ -f \"$RESULTS_DIR/with-skill/${case_id}.md\" ]]; then\n skill_score=$(score_case \"$case_id\" \"with-skill\")\n fi\n if $RUN_BASELINE && [[ -f \"$RESULTS_DIR/baseline/${case_id}.md\" ]]; then\n base_score=$(score_case \"$case_id\" \"baseline\")\n fi\n\n echo \"| $case_id | $skill_score | $base_score |\" >> \"$scorecard\"\n done\n\n echo \"\" >> \"$scorecard\"\n echo \"## Assertion Details\" >> \"$scorecard\"\n\n for case_id in \"${CASE_IDS[@]}\"; do\n echo \"\" >> \"$scorecard\"\n echo \"### $case_id\" >> \"$scorecard\"\n for mode in \"with-skill\" \"baseline\"; do\n if [[ -f \"$RESULTS_DIR/$mode/${case_id}.score.txt\" ]]; then\n echo \"**${mode}:**\" >> \"$scorecard\"\n echo '```' >> \"$scorecard\"\n cat \"$RESULTS_DIR/$mode/${case_id}.score.txt\" >> \"$scorecard\"\n echo '```' >> \"$scorecard\"\n fi\n done\n done\n\n echo \"\"\n echo \"=== Scorecard ===\"\n cat \"$scorecard\"\n}\n\ngenerate_scorecard\n\necho \"\"\necho \"=== Eval complete — $RESULTS_DIR/ ===\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":18242,"content_sha256":"4a5f64f9347e91d8bedb149ea5fd16263f0db37875164a5c584401f915567585"},{"filename":"eval/test-cases.yaml","content":"- id: TC-001\n name: simple-sdxl-txt2img\n prompt: \"Generate a ComfyUI workflow for a simple SDXL text-to-image of a sunset over mountains\"\n assertions:\n - type: json_valid\n description: \"Output is valid JSON with nodes\"\n critical: true\n - type: contains\n target: \"CheckpointLoaderSimple\"\n critical: true\n - type: contains\n target: \"KSampler\"\n critical: true\n - type: regex\n target: \"1024\"\n description: \"Resolution is 1024 (SDXL-native)\"\n critical: true\n - type: not_contains\n target: \"512x512\"\n description: \"Does not use SD1.5 resolution for SDXL\"\n critical: true\n expected_behavior: \"Produces a valid SDXL txt2img workflow with correct resolution, valid node types, and proper connections from checkpoint loader through sampler to image output\"\n edge_case: false\n\n- id: TC-002\n name: checkpoint-loader-output-indices\n prompt: \"Build a ComfyUI workflow using SDXL with separate CLIP text encode for positive and negative prompts\"\n assertions:\n - type: structure_check\n target: \"CheckpointLoaderSimple output index 0 connects to MODEL input, index 1 connects to CLIP inputs, index 2 connects to VAE input\"\n description: \"Semantic check — requires JSON graph analysis to verify output index wiring\"\n critical: true\n - type: not_contains\n target: \"CLIP output from index 0 of CheckpointLoader\"\n critical: true\n - type: structure_check\n target: \"All node connections reference valid output indices for their source node type\"\n description: \"Semantic check — requires JSON graph analysis to verify connection validity\"\n critical: true\n expected_behavior: \"Output indices are correct: CheckpointLoaderSimple outputs MODEL at 0, CLIP at 1, VAE at 2. Both CLIPTextEncode nodes receive CLIP from index 1, not index 0\"\n edge_case: true\n\n- id: TC-003\n name: lora-stacked-workflow\n prompt: \"Create a workflow that loads an SDXL checkpoint, applies two LoRAs (one for style, one for character), and generates a portrait\"\n assertions:\n - type: contains\n target: \"LoraLoader\"\n critical: true\n - type: structure_check\n target: \"LoRA loaders are chained: first LoRA output MODEL/CLIP feeds into second LoRA input\"\n description: \"Semantic check — requires JSON graph analysis to verify LoRA chaining\"\n critical: true\n - type: structure_check\n target: \"Second LoRA output MODEL connects to KSampler, second LoRA output CLIP connects to CLIPTextEncode\"\n description: \"Semantic check — requires JSON graph analysis to verify final LoRA connections\"\n critical: true\n - type: structure_check\n target: \"No dangling inputs — every required input on every node has a connection or value\"\n description: \"Semantic check — requires full graph traversal to verify completeness\"\n critical: true\n expected_behavior: \"LoRA loaders are chained correctly with MODEL and CLIP passing through each loader sequentially before reaching the sampler and text encoders\"\n edge_case: false\n\n- id: TC-004\n name: controlnet-depth-workflow\n prompt: \"Make a ComfyUI workflow that uses a depth ControlNet with SDXL to generate an interior design scene from a depth map\"\n assertions:\n - type: contains\n target: \"ControlNetLoader\"\n critical: true\n - type: contains\n target: \"ControlNetApplyAdvanced\"\n critical: false\n - type: regex\n target: \"(conditioning|positive).*ControlNet|ControlNet.*(conditioning|positive)\"\n description: \"ControlNet conditioning applied to positive prompt conditioning\"\n critical: true\n - type: structure_check\n target: \"Image loader node feeds into ControlNet apply node, not into the sampler latent input\"\n description: \"Semantic check — requires JSON graph analysis to verify image routing\"\n critical: true\n expected_behavior: \"ControlNet is loaded and applied to conditioning before reaching the sampler. Depth map image is loaded and connected to the ControlNet apply node correctly\"\n edge_case: false\n\n- id: TC-005\n name: sd15-not-sdxl-resolution\n prompt: \"Build a workflow using Deliberate v2 (SD 1.5 model) to generate anime character art\"\n assertions:\n - type: contains\n target: \"512\"\n description: \"Resolution is 512-based (SD1.5 native)\"\n critical: true\n - type: not_contains\n target: \"width: 1024\"\n critical: true\n - type: not_contains\n target: \"SDXLClipTextEncode\"\n description: \"No SDXL-specific nodes used with SD1.5 model\"\n critical: true\n - type: contains\n target: \"CLIPTextEncode\"\n critical: true\n expected_behavior: \"Recognizes Deliberate v2 as an SD1.5 model and uses 512-native resolution, standard CLIPTextEncode (not SDXL variant), and SD1.5-appropriate settings\"\n edge_case: false\n\n- id: TC-006\n name: flux-specific-workflow\n prompt: \"Create a ComfyUI workflow for FLUX.1 Dev text-to-image of a portrait photo\"\n assertions:\n - type: json_valid\n critical: true\n - type: not_contains\n target: \"CheckpointLoaderSimple\"\n critical: true\n description: \"FLUX uses LoadDiffusionModel, not CheckpointLoaderSimple\"\n - type: regex\n target: \"(LoadDiffusionModel|UNETLoader|DiffusionModelLoader)\"\n critical: true\n description: \"Must use FLUX-appropriate model loader\"\n - type: regex\n target: \"(DualCLIP|CLIPLoader.*flux|t5xxl)\"\n critical: false\n description: \"FLUX requires dual CLIP (CLIP-L + T5XXL)\"\n - type: regex\n target: \"(3\\\\.5|4\\\\.0|cfg.*[3-5])\"\n critical: false\n description: \"FLUX uses lower CFG values (3-5)\"\n - type: contains\n target: \"1024\"\n critical: true\n description: \"FLUX generates at 1024x1024 minimum\"\n expected_behavior: >\n FLUX has a completely different architecture from SD/SDXL. It uses\n LoadDiffusionModel (not CheckpointLoaderSimple), requires separate\n VAE loading, uses dual CLIP (CLIP-L + T5XXL), and operates at lower\n CFG values. The workflow must reflect FLUX-specific node types.\n edge_case: true\n\n- id: TC-007\n name: wan-i2v-video-workflow\n prompt: \"Build a ComfyUI workflow for Wan 2.1 image-to-video — I have a landscape photo and want a 4-second clip with gentle camera pan\"\n assertions:\n - type: json_valid\n critical: true\n - type: regex\n target: \"(Wan|wan|WAN)\"\n critical: true\n description: \"Must reference Wan model\"\n - type: regex\n target: \"(I2V|img2vid|image.to.video|ImageEncode)\"\n critical: true\n description: \"Must be an I2V pipeline, not txt2vid\"\n - type: regex\n target: \"(frame|frames|[0-9]+f|duration|length)\"\n critical: true\n description: \"Must specify frame count for video output\"\n - type: regex\n target: \"(camera|pan|motion|movement)\"\n critical: false\n description: \"Should address the camera pan request\"\n expected_behavior: >\n Wan I2V workflows require specific nodes: image encoder, latent\n preparation with frame count, and video-specific sampling. The workflow\n must load the input image, encode it, set up the correct number of frames\n for 4 seconds, and configure camera motion parameters.\n edge_case: false\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":7222,"content_sha256":"e2e0117b8b64582f6070ea569d5b1a0df3f16f13a91312f88d63f43747735185"},{"filename":"eval/trigger-tests.yaml","content":"should_trigger:\n - \"Build me a ComfyUI workflow for generating anime portraits\"\n - \"Create a workflow JSON that uses SDXL with ControlNet depth\"\n - \"Make me an image generation pipeline in ComfyUI\"\n - \"I need a txt2img workflow with two LoRAs stacked\"\n - \"Generate a ComfyUI workflow for inpainting with SDXL\"\n - \"Set up a workflow that goes from text prompt to final image using Juggernaut XL\"\n - \"Can you make a ComfyUI pipeline for img2img with SD 1.5?\"\n - \"I want to create a workflow with upscaling after generation\"\n - \"Build a node graph for generating product photos with ControlNet\"\n - \"Help me wire up a ComfyUI workflow for face detailing with ADetailer\"\n\nshould_not_trigger:\n - \"Explain how latent diffusion models work mathematically\"\n - \"Review this Python script for bugs\"\n - \"What's the difference between SDXL and SD 1.5 architecturally?\"\n - \"Help me install ComfyUI on my server\"\n - \"Write a custom ComfyUI node in Python\"\n - \"Debug why my ComfyUI server won't start\"\n - \"Compare Midjourney vs Stable Diffusion quality\"\n - \"Help me fine-tune a LoRA model\"\n - \"What GPU should I buy for AI image generation?\"\n - \"Convert this Automatic1111 workflow to a Python script\"\n\noptimized_description: >\n Generate, build, create, or design ComfyUI workflow JSON from natural language descriptions.\n Produces valid node graphs with correct class_types, connections, output indices, and\n model-appropriate settings. Handles txt2img, img2img, inpainting, ControlNet, LoRA stacking,\n upscaling, and face detailing pipelines. Does NOT cover ComfyUI installation, custom node\n development, Python scripting, model training, hardware advice, or architectural explanations.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":1699,"content_sha256":"b16b0ccf836e6f60e56bea7c739286c17e331f64164afdb7b32b6586adad0908"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"ComfyUI Workflow Builder","type":"text"}]},{"type":"paragraph","content":[{"text":"Translates natural language requests into executable ComfyUI workflow JSON. Always validates against inventory before generating.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow Generation Process","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Understand the Request","type":"text"}]},{"type":"paragraph","content":[{"text":"Parse the user's intent into:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Output type","type":"text","marks":[{"type":"strong"}]},{"text":": Image, video, or audio","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Source material","type":"text","marks":[{"type":"strong"}]},{"text":": Text-only, reference image(s), existing video","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identity method","type":"text","marks":[{"type":"strong"}]},{"text":": None, zero-shot (InstantID/PuLID), LoRA, Kontext","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Quality level","type":"text","marks":[{"type":"strong"}]},{"text":": Draft (fast iteration) vs production (maximum quality)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Special requirements","type":"text","marks":[{"type":"strong"}]},{"text":": ControlNet, inpainting, upscaling, lip-sync","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Check Inventory","type":"text"}]},{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"state/inventory.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" to determine:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Available checkpoints → select best match for task","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Available identity models → determine which methods are possible","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Available ControlNet models → enable pose/depth control if available","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Custom nodes installed → verify all required nodes exist","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"VRAM available → optimize settings accordingly","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Select Pipeline Pattern","type":"text"}]},{"type":"paragraph","content":[{"text":"Based on request + inventory, choose from:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pattern","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"When","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Key Nodes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Text-to-Image","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Simple generation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Checkpoint → CLIP → KSampler → VAE","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Identity-Preserved Image","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Character consistency","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+ InstantID/PuLID/IP-Adapter","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"LoRA Character","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Trained character","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+ LoRA Loader","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Image-to-Video (Wan)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"High-quality video","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Diffusion Model → Wan I2V → Video Combine","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Image-to-Video (AnimateDiff)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fast video, motion control","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+ AnimateDiff Loader + Motion LoRAs","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Talking Head","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Character speaks","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Image → Video → Voice → Lip-Sync","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Upscale","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Enhance resolution","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Image → UltimateSDUpscale → Save","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Inpainting","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Edit regions","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Image + Mask → Inpaint Model → KSampler","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Generate Workflow JSON","type":"text"}]},{"type":"paragraph","content":[{"text":"ComfyUI workflow format:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"{node_id}\": {\n \"class_type\": \"{NodeClassName}\",\n \"inputs\": {\n \"{param_name}\": \"{value}\",\n \"{connected_param}\": [\"{source_node_id}\", {output_index}]\n }\n }\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"Rules:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Node IDs are strings (typically \"1\", \"2\", \"3\"...)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Connected inputs use array format: ","type":"text"},{"text":"[\"source_node_id\", output_index]","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Output index is 0-based integer","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Filenames must match exactly what's in inventory","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Seed values: use random large integer or fixed for reproducibility","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: Validate","type":"text"}]},{"type":"paragraph","content":[{"text":"Before presenting to user:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Every ","type":"text"},{"text":"class_type","type":"text","marks":[{"type":"code_inline"}]},{"text":" exists in inventory's node list","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Every model filename exists in inventory's model list","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"All required connections are present (no dangling inputs)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"VRAM estimate doesn't exceed available VRAM","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Resolution is compatible with chosen model (512 for SD1.5, 1024 for SDXL/FLUX)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 6: Output","type":"text"}]},{"type":"paragraph","content":[{"text":"If online mode","type":"text","marks":[{"type":"strong"}]},{"text":": Queue via ","type":"text"},{"text":"comfyui-api","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill ","type":"text"},{"text":"If offline mode","type":"text","marks":[{"type":"strong"}]},{"text":": Save JSON to ","type":"text"},{"text":"projects/{project}/workflows/","type":"text","marks":[{"type":"code_inline"}]},{"text":" with descriptive name","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow Templates","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Basic Text-to-Image (FLUX)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"1\": {\n \"class_type\": \"LoadCheckpoint\",\n \"inputs\": {\"ckpt_name\": \"flux1-dev.safetensors\"}\n },\n \"2\": {\n \"class_type\": \"CLIPTextEncode\",\n \"inputs\": {\"text\": \"{positive_prompt}\", \"clip\": [\"1\", 1]}\n },\n \"3\": {\n \"class_type\": \"CLIPTextEncode\",\n \"inputs\": {\"text\": \"{negative_prompt}\", \"clip\": [\"1\", 1]}\n },\n \"4\": {\n \"class_type\": \"EmptyLatentImage\",\n \"inputs\": {\"width\": 1024, \"height\": 1024, \"batch_size\": 1}\n },\n \"5\": {\n \"class_type\": \"KSampler\",\n \"inputs\": {\n \"seed\": 42,\n \"steps\": 25,\n \"cfg\": 3.5,\n \"sampler_name\": \"euler\",\n \"scheduler\": \"normal\",\n \"denoise\": 1.0,\n \"model\": [\"1\", 0],\n \"positive\": [\"2\", 0],\n \"negative\": [\"3\", 0],\n \"latent_image\": [\"4\", 0]\n }\n },\n \"6\": {\n \"class_type\": \"VAEDecode\",\n \"inputs\": {\"samples\": [\"5\", 0], \"vae\": [\"1\", 2]}\n },\n \"7\": {\n \"class_type\": \"SaveImage\",\n \"inputs\": {\"filename_prefix\": \"output\", \"images\": [\"6\", 0]}\n }\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"With Identity Preservation (InstantID + IP-Adapter)","type":"text"}]},{"type":"paragraph","content":[{"text":"Extends basic template by adding:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Load reference image node","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"InstantID Model Loader + Apply InstantID","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"IPAdapter Unified Loader + Apply IPAdapter","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"FaceDetailer post-processing","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/workflows.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for complete node settings.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Video Generation (Wan I2V)","type":"text"}]},{"type":"paragraph","content":[{"text":"Uses different loader chain:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Load Diffusion Model (not LoadCheckpoint)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wan I2V Conditioning","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"EmptySD3LatentImage (with frame count)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Video Combine (VHS)","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/workflows.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" Workflow 4 for complete settings.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"VRAM Estimation","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Component","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Approximate VRAM","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FLUX FP16","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"16GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FLUX FP8","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SDXL","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"6GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SD1.5","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"4GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"InstantID","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+4GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"IP-Adapter","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+2GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ControlNet (each)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+1.5GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Wan 14B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"20GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Wan 1.3B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"5GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AnimateDiff","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+3GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FaceDetailer","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+2GB","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Mistakes to Avoid","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wrong output index","type":"text","marks":[{"type":"strong"}]},{"text":": CheckpointLoader outputs ","type":"text"},{"text":"[model, clip, vae]","type":"text","marks":[{"type":"code_inline"}]},{"text":" at indices ","type":"text"},{"text":"[0, 1, 2]","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CFG too high for InstantID","type":"text","marks":[{"type":"strong"}]},{"text":": Use 4-5, not default 7-8","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wrong resolution for model","type":"text","marks":[{"type":"strong"}]},{"text":": FLUX/SDXL=1024, SD1.5=512","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Missing VAE","type":"text","marks":[{"type":"strong"}]},{"text":": FLUX needs explicit VAE (","type":"text"},{"text":"ae.safetensors","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wrong model in wrong loader","type":"text","marks":[{"type":"strong"}]},{"text":": Diffusion models need ","type":"text"},{"text":"LoadDiffusionModel","type":"text","marks":[{"type":"code_inline"}]},{"text":", not ","type":"text"},{"text":"LoadCheckpoint","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Files","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/workflows.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Detailed node-by-node templates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/models.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Model files and paths","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/prompt-templates.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Model-specific prompts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"state/inventory.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Current inventory cache","type":"text"}]}]}]}]},"metadata":{"date":"2026-11-02","name":"comfyui-workflow-builder","author":"@skillopedia","source":{"stars":93,"repo_name":"ComfyUI-Expert","origin_url":"https://github.com/MCKRUZ/ComfyUI-Expert/blob/HEAD/skills/comfyui-workflow-builder/SKILL.md","repo_owner":"MCKRUZ","body_sha256":"4d0aa17fb3f107e13e63aaf259b555318be258ad1ed5d683ae188aff6d390a3f","cluster_key":"7ba8f6be93796b27795dcc1b97b63467a7a886cc9c415c6ea328df29ff43aa34","clean_bundle":{"format":"clean-skill-bundle-v1","source":"MCKRUZ/ComfyUI-Expert/skills/comfyui-workflow-builder/SKILL.md","text_bytes":30983,"source_commit":"dee27dc3d69b609c0006a8a12e71aadfc475ae95","skills_sh_rank":8088,"attachment_count":5,"text_attachments":5,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/comfyui-workflow-builder/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"ai-agent-development","category_label":"AI"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"ai-agent-development","metadata":{"openclaw":{"os":["darwin","linux","win32"],"emoji":"🔧","requires":{"anyBins":["curl","wget"]},"primaryEnv":"COMFYUI_URL"}},"import_tag":"skills-sh-top20k-2026-11","description":"Generate, build, create, or design ComfyUI workflow JSON from natural language descriptions. Produces valid node graphs with correct class_types, connections, output indices, and model-appropriate settings. Handles txt2img, img2img, inpainting, ControlNet, LoRA stacking, upscaling, and face detailing pipelines. Does NOT cover ComfyUI installation, custom node development, Python scripting, model training, hardware advice, or architectural explanations.","user-invocable":true}},"renderedAt":1793671411896}

ComfyUI Workflow Builder Translates natural language requests into executable ComfyUI workflow JSON. Always validates against inventory before generating. Workflow Generation Process Step 1: Understand the Request Parse the user's intent into: - Output type : Image, video, or audio - Source material : Text-only, reference image(s), existing video - Identity method : None, zero-shot (InstantID/PuLID), LoRA, Kontext - Quality level : Draft (fast iteration) vs production (maximum quality) - Special requirements : ControlNet, inpainting, upscaling, lip-sync Step 2: Check Inventory Read to determi…