comfyui

Generate images, video, and audio via diffusion workflows.

  • comfyui
  • image-generation
  • stable-diffusion
  • flux
  • sd3
  • wan-video
  • hunyuan-video
  • creative
  • generative-ai
  • video-generation

Declared platforms: macos · linux · windows

Install
npx skills add 'https://github.com/NousResearch/hermes-agent/tree/main/optional-skills/creative/comfyui'
Download bundle ↓
main · 24fd22bScanned 2026-09-15

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗
View on GitHub
← Back to SKILL.md
"""Integration tests against the live Comfy Cloud API. These tests are auto-skipped when COMFY_CLOUD_API_KEY is not set.They never SUBMIT workflows (would need a paid subscription) — they onlyverify the read-only endpoints we rely on.""" from __future__ import annotations import pytest from _common import http_get, parse_model_list, resolve_url  pytestmark = pytest.mark.cloud  class TestCloudEndpointsLive:    def test_system_stats_reachable(self, cloud_key):        url = resolve_url("https://cloud.comfy.org", "/system_stats")        r = http_get(url, headers={"X-API-Key": cloud_key})        assert r.status == 200        data = r.json()        assert "system" in data     def test_models_endpoint_routed_to_experiment(self, cloud_key):        # We expect the skill to route /models/checkpoints → /api/experiment/models/checkpoints        url = resolve_url("https://cloud.comfy.org", "/models/checkpoints")        assert "/api/experiment/models/checkpoints" in url        r = http_get(url, headers={"X-API-Key": cloud_key})        assert r.status == 200     def test_models_endpoint_returns_dicts(self, cloud_key):        url = resolve_url("https://cloud.comfy.org", "/models/checkpoints")        r = http_get(url, headers={"X-API-Key": cloud_key})        data = r.json()        assert isinstance(data, list)        if data:            # Cloud format: list of dicts with `name`            assert isinstance(data[0], dict)            assert "name" in data[0]            # Our parser normalizes both            normalized = parse_model_list(data)            assert len(normalized) == len(data)     def test_history_renamed_to_v2(self, cloud_key):        # /history → /api/history_v2 on cloud        url = resolve_url("https://cloud.comfy.org", "/history/some-fake-id")        assert "/api/history_v2/some-fake-id" in url     def test_object_info_paid_tier(self, cloud_key):        # On free tier, /object_info returns 403 with a recognizable message        url = resolve_url("https://cloud.comfy.org", "/object_info")        r = http_get(url, headers={"X-API-Key": cloud_key})        # Should be either 200 (paid) or 403 (free) — not 404 / 500        assert r.status in {200, 403}        if r.status == 403:            # Body should mention the limitation            assert "free tier" in r.text().lower() or "subscription" in r.text().lower()  class TestCloudCheckDepsLive:    def test_check_deps_against_cloud(self, cloud_key, sd15_workflow):        from check_deps import check_deps        report = check_deps(sd15_workflow, host="https://cloud.comfy.org", api_key=cloud_key)        # Either node check passed OR was skipped (free tier)        assert "missing_models" in report        assert "is_cloud" in report and report["is_cloud"] is True     def test_flux_workflow_models_resolved_via_aliases(self, cloud_key, flux_workflow):        """Flux uses unet/clip folders; cloud has them in diffusion_models/text_encoders.        With folder aliasing, the check should still find them."""        from check_deps import check_deps        report = check_deps(flux_workflow, host="https://cloud.comfy.org", api_key=cloud_key)        # The exact required Flux files (flux1-dev.safetensors, t5xxl_fp16, clip_l, ae)        # are present on cloud; with folder aliasing, none should be missing.        # If this fails, either the cloud removed the model or the aliasing logic broke.        missing_filenames = {m["value"] for m in report["missing_models"]}        assert "ae.safetensors" not in missing_filenames, \            "ae.safetensors should be on cloud's vae folder"        # t5xxl_fp16 / clip_l should be reachable via the clip → text_encoders alias        # flux1-dev.safetensors likewise via unet → diffusion_models  class TestHealthCheckLive:    def test_health_check_passes(self, cloud_key, capsys):        from health_check import main as health_main        rc = health_main(["--host", "https://cloud.comfy.org", "--api-key", cloud_key])        captured = capsys.readouterr()        # Should produce JSON        import json        report = json.loads(captured.out)        assert report["server"]["reachable"] is True        assert report["checkpoints"]["queryable"] is True        assert report["checkpoints"]["count"] > 0