mirror of
https://github.com/Comfy-Org/comfy-remote-nodes.git
synced 2026-11-04 23:37:22 +00:00
[PR #22] [MERGED] fix(encoder): recurse into nested AUTOGROW / DYNAMIC_COMBO runtime dicts #21
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/comfy-remote-nodes#21
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/comfy-remote-nodes/pull/22
Author: @Kosinkadink
Created: 5/17/2026
Status: ✅ Merged
Merged: 5/17/2026
Merged by: @Kosinkadink
Base:
main← Head:feat/encode-nested-autogrow-dicts📝 Commits (1)
866b7e3fix(encoder): recurse into nested AUTOGROW / DYNAMIC_COMBO runtime dicts📊 Changes
2 files changed (+431 additions, -7 deletions)
View changed files
➕
notes/run_encode_nested_dicts.py(+360 -0)📝
proxy_node.py(+71 -7)📄 Description
ComfyUI's V3
build_nested_inputs(comfy_api/latest/_io.pyL1722) rebuilds AUTOGROW / DYNAMIC_COMBO runtime kwargs into nested dicts before they reach the proxy_node'sexecute(). For an AUTOGROW input namedreference_images, the value arrives as{"image1": <tensor>, "image2": <tensor>, ...}; for a DYNAMIC_COMBO branch with a nested AUTOGROW (e.g. the new Wan2ReferenceVideoApimodelDC with nestedvideo1..video3+image1..image5), the value arrives as{"<dc-name>": branch_key, "video_refs": {"video1": <VideoInput>}, "reference_images": {"image1": <tensor>}, ...}.Before this change
_encode_oneonly encoded values where the top-level value was itself atorch.Tensor/VideoInput/ audio dict / model3d input. A non-audio dict (the AG / DC runtime shape) failed all four duck-type checks and was returned unchanged, so per-slot tensors / VideoInputs survived past encoding and either crashed atjson.dumpstime (no custom JSONEncoder fortorch.Tensor) or violated the server's contract (comfy-rnp-server's_ordered_wan_videoedit_image_envelopesand the WAN2 / HappyHorse / Grok / Bria / Luma AG providers shipped over the last 5 PRs all require each slot value to already be an RNP envelope before they reach the upload step).The same gap also defeated the externalization cap:
_encode_inputsonly ranmaybe_externalizewhen the top-level encoded value was itself an envelope, so per-slot envelopes inside an AG dict would ship inline regardless ofmax_inline_bytes.Fix
Structural — match the runtime data model:
_encode_onerecurses into plain (non-envelope, non-audio) dict values, calling itself for each entry. Envelope dicts pass through so we don't double-encode; audio dicts still route toencode_audio_inputbecause their dict shape (waveform+sample_rate) is a heavy leaf, not a container. The recursion passes the parent'saccepted_encodingsdownward — single-image AG slots and VIDEO / AUDIO / MODEL_3D leaves don't depend on it, and gating per-child policy on descriptor metadata adds plumbing for no concrete provider need today.New
_externalize_nestedhelper walks the encoded tree the same way: envelope leaves go throughserialization.maybe_externalize; plain dicts recurse; everything else passes through._encode_inputsreplaces the old "ifis_envelope: externalize" guard with one call to the recursive walker, so per-slot envelopes inside AG / DC dicts get the same presigned-PUT treatment top-level envelopes get.Lists are intentionally NOT traversed — AG / DC runtime values always materialize as dicts, never lists, and recursing into arbitrary lists would touch opaque payloads. Recursion depth is bounded by the upstream Autogrow max-slot cap (100) and the maximum DC branch nesting depth observed in any provider today (1).
Tests
New
notes/run_encode_nested_dicts.pystandalone smoke test exercises 9 scenarios:image<N>tensor becomes an image envelope; wrapping dict preserved.video<N>VideoInputbecomes a video envelope.encode_audio_input(not swallowed by dict-recursion branch)._externalize_nestedwalks per-slot envelopes (cap=3 forces every slot to externalize via the stubbedmaybe_externalize).json.dumps(...)round-trips the full payload (regression guard for the exact bug fixed).Loads
_encode_one/_encode_inputs/_externalize_nestedout ofproxy_node.pyvia AST extraction so it runs without importing the fullcomfy_api/comfy_api_nodespackages, same pattern asrun_image_max_batch.py.Runs clean against the ComfyUI venv:
Unblocks the next batch of
comfy-rnp-serverproviders that need AG-of-VIDEO or DC-wrapping-AG-of-VIDEO support (WanReferenceVideoApi_RNPcharacter1..character3andWan2ReferenceVideoApi_RNPvideo1..video3+image1..image5).🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.