[PR #10] [MERGED] feat(local-validate): fail-fast on over-cap image batches #10

Closed
opened 2026-10-26 22:28:52 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Comfy-Org/comfy-remote-nodes/pull/10
Author: @Kosinkadink
Created: 5/15/2026
Status: ✅ Merged
Merged: 5/15/2026
Merged by: @Kosinkadink

Base: main ← Head: feat/image-max-batch-rule


📝 Commits (1)

  • 37a4961 feat(local-validate): fail-fast on over-cap image batches

📊 Changes

2 files changed (+384 additions, -0 deletions)

View changed files

➕ notes/run_image_max_batch.py (+268 -0)
📝 proxy_node.py (+116 -0)

📄 Description

Summary

First slice of Track D (RNP/1 immediate follow-ups), client side. Wires proxy_node._encode_inputs to consult each input's descriptor.input.<section>.<name>[1].local_validate.image_max_batch rule. When set, the encoder asserts tensor.shape[0] <= cap for IMAGE inputs and raises RnpProtocolError(code=INPUT_INVALID, user_facing=True) before any HTTP round trip — so a workflow with N>cap reference frames surfaces the per-provider error in the standard friendly-message dialog instead of paying for a doomed upstream call.

Changes

proxy_node.py

  • New _collect_local_validate(descriptor) walks descriptor.input.{required,optional} and returns {name: rules} for every input that carries a non-empty local_validate block. Inputs nested inside AUTOGROW / DYNAMIC_COMBO aren't surfaced — the parser doesn't yet flatten them into top-level inputs, so the cap declared on those templates documents the future contract rather than firing today.
  • New _enforce_local_validate(name, value, rules, *, node_id) applies each supported rule to value. Today only image_max_batch is implemented: rank-4 / rank-3-channels-last tensors with shape[0] > cap raise RnpProtocolError with code INPUT_INVALID and user_facing=True. Friendly per-provider message echoes the upstream wording — Flux2's "The current maximum number of supported images is N" for cap≥2; a "expects a single image frame" copy for cap=1 (LTXV i2v).
  • _encode_inputs runs the validator before the encoder so the raise happens before any tensor → PNG conversion or maybe_externalize upload — the cheapest possible fail point.
  • Lookup is defensive at every layer: missing local_validate → no-op, missing image_max_batch sub-key → no-op, non-tensor input → no-op, non-image rank → no-op. Older descriptors emit no rule and the encoder behaves identically to before.

notes/run_image_max_batch.py (new)

Standalone smoke test that loads the helper functions via AST extraction (so the test runs in a bare venv with just torch installed; doesn't drag in the ComfyUI package). Asserts:

  1. _collect_local_validate extracts the rule from a Flux2-shaped descriptor.
  2. A 3-frame tensor against cap=2 raises RnpProtocolError with code=INPUT_INVALID, user_facing=True, and the node_id + counts mentioned in the message.
  3. A 2-frame tensor against cap=2 encodes cleanly.
  4. cap=1 surfaces the single-frame copy (LTXV i2v shape).
  5. Descriptor without local_validate is a no-op.
  6. local_validate block missing the image_max_batch key is a no-op.

Verification

python notes/run_image_max_batch.py
# -> PASS: image_max_batch local_validate smoke test

Lockstep

Paired with server PR https://github.com/Comfy-Org/comfy-rnp-server/pull/15 (feat(descriptor): declare image_max_batch local_validate caps), which adds the matching local_validate.image_max_batch rule to each provider's IMAGE input options dict. The server-side per-call caps inside each provider's execute() stay in place as defense-in-depth; non-compliant clients still fail.

Both branches were cut off origin/main before PR-2 lands; the orchestrator will rebase PR-3 onto PR-2 before merging.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Comfy-Org/comfy-remote-nodes/pull/10 **Author:** [@Kosinkadink](https://github.com/Kosinkadink) **Created:** 5/15/2026 **Status:** ✅ Merged **Merged:** 5/15/2026 **Merged by:** [@Kosinkadink](https://github.com/Kosinkadink) **Base:** `main` ← **Head:** `feat/image-max-batch-rule` --- ### 📝 Commits (1) - [`37a4961`](https://github.com/Comfy-Org/comfy-remote-nodes/commit/37a4961d6d61e8a1d08fcb2356fc858086d878c3) feat(local-validate): fail-fast on over-cap image batches ### 📊 Changes **2 files changed** (+384 additions, -0 deletions) <details> <summary>View changed files</summary> ➕ `notes/run_image_max_batch.py` (+268 -0) 📝 `proxy_node.py` (+116 -0) </details> ### 📄 Description ## Summary First slice of Track D (RNP/1 immediate follow-ups), client side. Wires `proxy_node._encode_inputs` to consult each input's `descriptor.input.<section>.<name>[1].local_validate.image_max_batch` rule. When set, the encoder asserts `tensor.shape[0] <= cap` for IMAGE inputs and raises `RnpProtocolError(code=INPUT_INVALID, user_facing=True)` **before** any HTTP round trip — so a workflow with N>cap reference frames surfaces the per-provider error in the standard friendly-message dialog instead of paying for a doomed upstream call. ## Changes **`proxy_node.py`** - New `_collect_local_validate(descriptor)` walks `descriptor.input.{required,optional}` and returns `{name: rules}` for every input that carries a non-empty `local_validate` block. Inputs nested inside `AUTOGROW` / `DYNAMIC_COMBO` aren't surfaced — the parser doesn't yet flatten them into top-level inputs, so the cap declared on those templates documents the future contract rather than firing today. - New `_enforce_local_validate(name, value, rules, *, node_id)` applies each supported rule to `value`. Today only `image_max_batch` is implemented: rank-4 / rank-3-channels-last tensors with `shape[0] > cap` raise `RnpProtocolError` with code `INPUT_INVALID` and `user_facing=True`. Friendly per-provider message echoes the upstream wording — Flux2's "The current maximum number of supported images is N" for cap≥2; a "expects a single image frame" copy for cap=1 (LTXV i2v). - `_encode_inputs` runs the validator before the encoder so the raise happens *before* any tensor → PNG conversion or `maybe_externalize` upload — the cheapest possible fail point. - Lookup is defensive at every layer: missing `local_validate` → no-op, missing `image_max_batch` sub-key → no-op, non-tensor input → no-op, non-image rank → no-op. Older descriptors emit no rule and the encoder behaves identically to before. **`notes/run_image_max_batch.py`** (new) Standalone smoke test that loads the helper functions via AST extraction (so the test runs in a bare venv with just `torch` installed; doesn't drag in the ComfyUI package). Asserts: 1. `_collect_local_validate` extracts the rule from a Flux2-shaped descriptor. 2. A 3-frame tensor against `cap=2` raises `RnpProtocolError` with `code=INPUT_INVALID`, `user_facing=True`, and the `node_id` + counts mentioned in the message. 3. A 2-frame tensor against `cap=2` encodes cleanly. 4. `cap=1` surfaces the single-frame copy (LTXV i2v shape). 5. Descriptor without `local_validate` is a no-op. 6. `local_validate` block missing the `image_max_batch` key is a no-op. ## Verification ``` python notes/run_image_max_batch.py # -> PASS: image_max_batch local_validate smoke test ``` ## Lockstep Paired with server PR https://github.com/Comfy-Org/comfy-rnp-server/pull/15 (`feat(descriptor): declare image_max_batch local_validate caps`), which adds the matching `local_validate.image_max_batch` rule to each provider's IMAGE input options dict. The server-side per-call caps inside each provider's `execute()` stay in place as defense-in-depth; non-compliant clients still fail. Both branches were cut off `origin/main` before PR-2 lands; the orchestrator will rebase PR-3 onto PR-2 before merging. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-26 22:28:52 +00:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Comfy-Org/comfy-remote-nodes#10
No description provided.