feat: add cross-platform hardware block to comfy env --json (BE-3399)#562
feat: add cross-platform hardware block to comfy env --json (BE-3399)#562mattmillerai wants to merge 2 commits into
Conversation
Add comfy_cli/hardware.py with a single detect_hardware() entry point that reports OS, CPU, RAM, and a GPU sub-block (vendor/model/VRAM/unified-memory) so agent surfaces can route weak machines away from local diffusion. - macOS: cpu via sysctl machdep.cpu.brand_string; Apple Silicon -> apple unified-memory GPU; Intel Mac -> unknown non-unified GPU (no system_profiler). - NVIDIA (any OS): nvidia-smi CSV, then ctypes libcuda fallback (reuses cuda_detect._load_libcuda). - AMD (Linux): best-effort rocm-smi --json. - Never raises, never blocks long: every probe wrapped, subprocesses timeout=5. Wire hardware into EnvChecker.fill_data() (JSON) and a Hardware row in fill_print_table() (pretty). Extend schemas/env.json with an OPTIONAL, fully nullable hardware property (not in required) so older/failed-probe payloads stay valid. Envelope schema unchanged (envelope/1).
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 54 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
🔍 Cursor Review — Consolidated panel
Triggered by @mattmillerai.
Found 9 finding(s).
| Severity | Count |
|---|---|
| 🟡 Medium | 4 |
| 🟢 Low | 4 |
| ⚪ Nit | 1 |
Panel: 6/8 reviewers contributed findings.
Reviewers that did not contribute: kimi-k2.5:adversarial (empty), kimi-k2.5:edge-case (empty)
…(BE-3399) - env_checker: escape untrusted cpu/gpu-model strings in the Rich-rendered hardware summary so markup-like content (e.g. "[/]") can't raise MarkupError and crash `comfy env` in pretty mode. - hardware(_detect_gpu_amd): return None (no phantom all-None AMD block) when nothing parses, matching the NVIDIA probes; gate the card loop on the "card" key prefix so a non-card metadata block isn't parsed as the GPU; exclude the "VRAM Total Used Memory" usage key so total capacity isn't understated. - hardware(_detect_gpu_nvidia_ctypes): pop/restore CUDA_VISIBLE_DEVICES around the ctypes probe (mirrors cuda_detect) so an exported ""/"-1" doesn't hide a present GPU. - tests: cover AMD total-vs-used key, metadata-block skip, all-None->None, and markup escaping. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review resolution (5e5b4f4)Addressed the Cursor consolidated-panel findings: Fixed:
New tests cover each. Deferred to follow-ups (out of scope for this PR): 🟡 unbounded in-process ctypes CUDA hang (also affects CI note: the failing |
|
🤖 The reviews loop filed Linear follow-up ticket(s) for review thread(s) deferred as out of scope for this PR:
|
ELI-5
comfy env --jsonnow tells you what machine you're on: your OS, chip, how muchRAM you have, and what GPU (and how much video memory) is available. Agents that
call the CLI can read this and avoid asking a weak laptop to run heavy local
image generation. It's purely additive — nothing that already reads the env
payload breaks.
What changed
comfy_cli/hardware.pywith one entry pointdetect_hardware() -> dictreturning
os / os_version / arch / cpu / ram_bytes / gpu. Thegpusub-block is{vendor, model, vram_bytes, unified_memory}ornull.cpufromsysctl -n machdep.cpu.brand_string(~0.012s). AppleSilicon (
arm64) →appleunified-memory GPU (RAM is the GPU budget). IntelMac →
unknownnon-unified GPU (we deliberately do not shell out tosystem_profilerper the ticket).nvidia-smi --query-gpu=name,memory.totalfirst, then actypes fallback via the existing
cuda_detect._load_libcuda(
cuInit/cuDeviceGet/cuDeviceGetName/cuDeviceTotalMem_v2).rocm-smi --showmeminfo vram --json; nulls acceptable.None), and every subprocess usestimeout=5.EnvChecker.fill_data()gains"hardware", andfill_print_table()gains aHardwarerow (cpu / RAM GB / GPU (VRAM GB or 'unified')).schemas/env.jsongains an optional, fully nullablehardwareproperty (
gpuis["object","null"]). Not added torequired, so older andfailed-probe payloads stay valid. Envelope schema unchanged (
envelope/1).Testing
tests/comfy_cli/test_hardware.py(new): macOS-arm64 apple/unified block;Intel-Mac unknown block; nvidia-smi happy path (
24564 MiB→ bytes); nvidia-smiabsent + libcuda ctypes fallback; every probe raising/timing out →
gpu: null,cpu: null, RAM still populated, no exception escapes;fill_data()includesthe key and the full payload validates against
schemas/env.json; nulled andhardware-absent payloads both still validate.
tests/comfy_cli/output/test_envelope_schemas.py::test_env_json_validates(real
comfy --json envsubprocess) passes → live payload validates and exits 0.ruff check+ruff format --checkclean.comfy env --jsonreportsDarwin / arm64 / Apple M4 Max / 64 GB+ apple unified GPU block, well under 1sadded latency.
Judgment calls
unified_memory false" and "gpu null if no GPU detected". I read these as: an
Intel Mac always has a GPU (integrated/AMD), just unidentifiable without the
forbidden
system_profiler, so it reports{vendor: "unknown", ..., unified_memory: false}rather than
null.nullis reserved for machines where no GPU is detected at all(e.g. a headless Linux CI runner). Flagging in case the reviewer prefers
null.cuda_detect: productioncuda_detectonlycalls
cuInit+cuDriverGetVersion; thecuDeviceGetName/cuDeviceTotalMem_v2calls here are new. Fully wrapped (worst case →
None), no subprocess, so a quirkydriver yields at most an odd model string, never a crash. I could not exercise it
against real NVIDIA hardware from this Mac; it's covered by a faithful ctypes mock.
gpu: nullmeans "not detected," not a user-facing dead-end — no "not supported"strings, no throw/deny path, no tests flipped to assert a dead-end. The falsification
trigger does not fire.