- Python 100%
- If .git exists: git fetch + git pull --ff-only (normal flow) - If no .git: downloads tarball from Forgejo API, extracts, replaces changed files - Preserves local-only files (__pycache__, .db, etc.) - Reports which files were updated |
||
|---|---|---|
| __init__.py | ||
| db.py | ||
| downloader.py | ||
| jobs.py | ||
| README.md | ||
| routes.py | ||
comfy-claw-helper
ComfyUI custom node that bridges OpenClaw ↔ ComfyUI. No visible nodes — just REST API endpoints.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /claw/status |
VRAM usage, loaded models, queue depth |
| GET | /claw/models |
List available models on disk (filterable by ?type=) |
| GET | /claw/config |
Current runtime configuration |
| POST | /claw/config |
Apply runtime config (DB path, Civitai API key) |
| POST | /claw/warmup |
Preload models into VRAM (async job) |
| GET | /claw/warmup/{job_id} |
Poll warmup job status |
| POST | /claw/download |
Download models from Civitai/HuggingFace/URL (async job) |
| GET | /claw/download/{job_id} |
Poll download job status |
| POST | /claw/download/{job_id}/cancel |
Cancel a running download |
| GET | /claw/downloads |
List all download jobs |
| GET | /claw/jobs |
List all jobs (warmup + download) |
| GET | /claw/jobs/{job_id} |
Poll any job by ID |
| POST | /claw/resolve |
Resolve a single model by hash, AIR, or civitaiVersionId |
| POST | /claw/resolve/batch |
Batch resolve multiple models |
| POST | /claw/export |
Convert workflow JSON → OpenClaw plugin config |
Job System
Warmup and download operations run asynchronously. All return a job_id you can poll:
# Start a warmup
curl -X POST http://comfy:8188/claw/warmup \
-H "Content-Type: application/json" \
-d '{"checkpoint": "illustrious/model.safetensors", "type": "checkpoint"}'
# → {"job_id": "warmup-abc123", "status": "queued"}
# Poll any job
curl http://comfy:8188/claw/jobs/warmup-abc123
# → {"job_id": "warmup-abc123", "status": "done", ...}
Jobs auto-prune after completion.
Warmup
Loads models directly into VRAM using ComfyUI's internal Python API — no workflow needed.
# Standard checkpoint → loaded + moved to GPU
curl -X POST http://comfy:8188/claw/warmup \
-d '{"checkpoint": "Illustrious/model.safetensors", "type": "checkpoint"}'
# UNET model (Chroma, Lumina, etc.)
curl -X POST http://comfy:8188/claw/warmup \
-d '{"checkpoint": "chroma/model.safetensors", "type": "unet"}'
# LoRA → loaded into OS page cache (applied on use)
curl -X POST http://comfy:8188/claw/warmup \
-d '{"checkpoint": "pony/my_lora.safetensors", "type": "lora"}'
Supported types: checkpoint, unet, lora, vae, clip.
Append ?sync=true to block until loaded. Default is async — returns a job ID immediately.
Set "gpu": false to skip moving to VRAM (just read into RAM/page cache).
Model Resolution
Resolve models by AIR URN, SHA256 hash, or Civitai version ID. Returns local path if found, or Civitai download info if not.
# By AIR
curl -X POST http://comfy:8188/claw/resolve \
-d '{"air": "urn:air:illustrious:checkpoint:civitai:827184@2514310"}'
# By hash
curl -X POST http://comfy:8188/claw/resolve \
-d '{"hash": "a5f58eb1c336..."}'
# By Civitai version ID
curl -X POST http://comfy:8188/claw/resolve \
-d '{"civitaiVersionId": 2514310}'
# Batch resolve
curl -X POST http://comfy:8188/claw/resolve/batch \
-d '{"items": [{"air": "..."}, {"hash": "..."}, ...]}'
Resolution chain: AIR lookup (DB) → Hash lookup (DB) → Version ID lookup (DB) → Civitai API → download info.
Download
# From Civitai
curl -X POST http://comfy:8188/claw/download \
-d '{"civitai_model_version_id": 12345, "type": "checkpoints", "save_path": "illustrious"}'
# From HuggingFace
curl -X POST http://comfy:8188/claw/download \
-d '{"huggingface": "stabilityai/sdxl-base-1.0/model.safetensors", "type": "checkpoints"}'
# Direct URL
curl -X POST http://comfy:8188/claw/download \
-d '{"url": "https://example.com/model.safetensors", "type": "loras", "filename": "my_lora.safetensors"}'
Features: threaded downloads, SHA256 hashing, progress tracking, cancellation, duplicate detection, concurrency limits.
Configuration
Runtime config is sent by the OpenClaw plugin (lazy sync on first image gen):
curl -X POST http://comfy:8188/claw/config \
-d '{"db_path": "/path/to/models.db", "enable_db": true, "civitai_api_key": "..."}'
DB is opt-in. When enabled, shares the SQLite database with comfyui-comfychair-helper (schema v6, AIR support).
Export
Convert a ComfyUI API-format workflow into OpenClaw plugin config:
curl -X POST http://comfy:8188/claw/export \
-d '{"workflow": {...}, "name": "my-workflow"}'
Returns workflow_def, model_aliases, lora_aliases, and analysis.
Installation
Symlink or copy into ComfyUI's custom_nodes/ directory:
ln -s /path/to/comfy-claw-helper /path/to/ComfyUI/custom_nodes/comfy-claw-helper
Restart ComfyUI. Routes register automatically via PromptServer.instance.routes.
Architecture
- Routes register via aiohttp on ComfyUI's
PromptServer - Warmup loads models directly via
comfy.sd(no workflow/prompt queue needed) - Downloads run as background threads with asyncio bridges
- Job system provides unified tracking for all async operations
- No actual ComfyUI nodes registered (
NODE_CLASS_MAPPINGSis empty) - Shared SQLite DB with comfychair-helper for model metadata + AIR