Files
EnragedAntelope c385f389ee v2.4.1: queue-time validation, absolute pixel ceiling, CI hardening
- Reject invalid configs in validate_inputs instead of mid-execution:
  Strict-mode multiple_of above max_res, out-of-range min_res/max_res/
  multiple_of, and unknown constraint modes
- Share the resolution and multiple_of bounds between define_schema() and
  validate_inputs() so the widget and the queue-time check cannot drift
- Cap the min-res pixel budget at an absolute 64 MP, floored at max_res
  squared; the multiplier alone permitted ~12 GB outputs at max_res=8192
- Warn on large upscales in Strict mode as well as min-res mode
- Pin GitHub Actions by commit SHA on node24-native majors; drop issues:write
  from the publish workflow and set contents:read on both
- Pin Comfy-Org/publish-node-action to the commit @v1 resolves to; the 1.0.1
  tag calls `comfy tracking disable`, removed from comfy-cli
- Add requirements-ci.txt with pip caching; add ruff config and a CI lint step
- Add schema-contract, tooltip, budget, crop-guard and validation tests
- Replace typing.Tuple with tuple
- Bump version to 2.4.1
2026-08-24 14:11:51 -04:00

6.5 KiB
Raw Permalink Blame History

AGENTS.md — ComfyUI-ConstrainResolution

A ComfyUI node that resizes any image to fit your model's resolution rules: a minimum size, a maximum size, and dimensions guaranteed divisible by 2, 8, 16, 32, or 64. Keeps aspect ratio by cropping a few pixels when needed. No dependencies beyond ComfyUI itself (Python ≥3.10). Built on ComfyUI v3 node API (comfy_api.latest).

Current state

Last verified: 2026-08-24

  • Status: released v2.4.1 (pyproject.toml). Stable and feature-complete for what it sets out to do. Published to the Comfy Registry — .github/workflows/publish_action.yml fires on a pyproject.toml version change on main, so a functional change needs a version bump or it never ships.
  • Works: both constraint modes (Prioritize Min Resolution, Prioritize Max Resolution strict); divisibility by 2/8/16/32/64 enforced together with the min/max limits so reported width/height always match the output tensor; minimal smart cropping with a configurable crop position; all five resize methods; the full output set (resized image, original passthrough, width, height, final and original aspect ratios). .github/workflows/test.yml runs the pytest suite.
  • In progress: nothing — v2.4.1 polished the v2.4.0 audit: validate_inputs now rejects at queue time (Strict-mode multiple_of > max_res, out-of-range resolutions, unknown constraint modes), the min-res memory guard gained an absolute pixel ceiling, large-upscale warnings fire in both modes, CI actions are SHA-pinned with pip caching (requirements-ci.txt, CI-only), and a schema-contract test keeps define_schema() in sync with execute().
  • Known gaps / next steps: no batch-specific handling beyond what ComfyUI's own resizer provides; behaviour under extreme aspect ratios is covered by tests but has had little real-world exercise; the README screenshots track v2.3.1 and would need refreshing alongside any visible change.
  • Deep docs: none — README.md is the user-facing reference and nodes.py is the whole implementation.

Architecture in 60 seconds

  • Single node. nodes.py contains the entire feature — one node class, all logic self-contained.
  • Three rules in one step: min resolution, max resolution, and divisibility. Resize, round, and crop all land on multiples of the chosen number.
  • Two constraint modes: "Prioritize Min Resolution" (neither dimension goes below min_res) and "Prioritize Max Resolution (Strict)" (output always fits in a max_res × max_res box — hard VRAM cap).
  • Smart cropping. When an extreme aspect ratio can't satisfy both limits, crops minimally to hit exact dimensions instead of distorting. Crop position configurable (center/top/bottom/left/right).
  • Uses ComfyUI's own resizer (comfy.utils.common_upscale) — results match core resize nodes. Bicubic/lanczos output clamped to valid range to avoid overshoot artifacts.
  • Rich outputs. Returns resized_image, original_image passthrough, width/height, and both final and original aspect ratios.

Layout

File / Directory Purpose
__init__.py ComfyUI custom-node entry point (registers the node)
nodes.py The entire node: resize logic, constraint modes, cropping, validation
tests/ pytest test suite
conftest.py pytest configuration/fixtures
docs/ Images for README

Build / test / run

# Install via ComfyUI Manager (recommended)
# Search for "Constrain Resolution" in the Manager

# Manual install
cd ComfyUI/custom_nodes
git clone https://github.com/EnragedAntelope/ComfyUI-ConstrainResolution.git
# Restart ComfyUI

# No pip dependencies — Python 3.10+ and ComfyUI itself are the only requirements

# Run tests (conftest.py mocks comfy_api, so no ComfyUI install is needed)
pip install -r requirements-ci.txt
pytest
ruff check .

Conventions & gotchas

  • Single-file node — nodes.py is the entire feature. Keep it self-contained.
  • Zero pip dependencies for the pack itself. requirements-ci.txt exists only for CI (pytest/torch/numpy); never add runtime deps.
  • validate_inputs must NOT take **kwargs: ComfyUI then skips its own range and combo-option validation for every input on the node (execution.py, validate_has_kwargs). It also skips those checks for each input the function names explicitly, so anything listed in the signature must have its bounds re-asserted inside the function. MIN_RESOLUTION/MAX_RESOLUTION/MIN_MULTIPLE_OF/MAX_MULTIPLE_OF are shared by define_schema() and validate_inputs() so the widget and the queue-time check cannot drift.
  • The GitHub Actions pins are commit SHAs; the comment above each one records the version it corresponds to. Keep them on node24-native majors — GitHub warns on, and will eventually stop running, node20 actions. Comfy-Org/publish-node-action is pinned to the commit its v1 branch points at — its 1.0.1 tag is older than that branch and still calls comfy tracking disable, which current comfy-cli does not have.
  • Divisibility, min/max, and crop dimensions are enforced together — reported width/height always match the actual output tensor.
  • Unsatisfiable or memory-exhausting settings raise ValueError rather than returning a zero dimension; calculate_optimal_dimensions never returns 0 for a non-empty input. The min-res pixel budget is max(box, min(box * FACTOR, MAX_OUTPUT_PIXELS)) where box = max_res ** 2 — a size the user's own max_res permits is never refused.
  • resize_method defaults to lanczos (sharpest). Options: lanczos, bicubic, bilinear, nearest-exact (pixel art/masks), area (big downscales).
  • When crop_as_required=False and multiple_of=1, no cropping occurs — keeps every pixel.
  • The node uses ComfyUI v3 schema (comfy_api.latest).

Security

This file is public-safe by default. Never add local paths, credentials, API keys, personal data, infrastructure details, or subscription info.

Before pushing, re-read this file and confirm it contains no local paths, credentials, or personal data.

Maintenance

Update rule: When you change the architecture, build/test commands, or conventions, update this AGENTS.md in the same commit. Keep under 200 lines.

CLAUDE.md: One-line shim: @AGENTS.md.

New-repo rule: Create AGENTS.md in the first session a new repo is worked on.

No-overlap rule: Explanatory prose lives in one file. AGENTS.md = agent-facing summary; README.md = human/usage. Identical install commands may be restated verbatim. Explanatory prose must not be duplicated — link instead.