[PR #14] [MERGED] feat(model_3d): add client-side MODEL_3D decoder + capability advertisement #14

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

📋 Pull Request Information

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

Base: main ← Head: feat/client-model-3d-decoder


📝 Commits (1)

  • 58d93da feat(model_3d): add client-side MODEL_3D decoder + capability advertisement

📊 Changes

5 files changed (+391 additions, -15 deletions)

View changed files

📝 client.py (+9 -0)
➕ notes/run_model3d_decoder.py (+316 -0)
📝 protocol.py (+14 -3)
📝 proxy_node.py (+19 -8)
📝 serialization.py (+33 -4)

📄 Description

Closes the loop on the just-merged comfy-rnp-server PR #37 which added the four Tripo / Rodin 3D providers and the Capability.MODEL_3D_GLB_INLINE token. Without this client-side half the providers were unreachable from any RNP client — descriptors would fail negotiation because the proxy_node didn't advertise the token.

Client changes (all inside ComfyUI/custom_nodes/comfy_remote_nodes)

  • protocol.py — mirror the new Capability.MODEL_3D_GLB_INLINE constant and add "model_3d" to HEAVY_TYPES so is_envelope recognises inbound 3D-model envelopes. The vendored protocol module is the single source of truth for the proxy_node and serialization layers; both already consume is_envelope / decode_envelope_data from here.
  • serialization.py — add decode_model3d_envelope that hands raw GLB bytes to comfy_api.latest._util.File3D via BytesIO, mirroring the existing decode_video_envelope shape. Only glb_inline is accepted today; any other encoding surfaces RnpProtocolError(code=INTERNAL) as defence-in-depth so a future encoding never silently downgrades to garbage bytes. Registered in the _DECODERS dispatch table and re-exported via __all__.
  • proxy_node.py — add "MODEL_3D" -> IO.File3DGLB.Output to _OUTPUT_CLASSES so descriptors with output=["MODEL_3D"] parse to a real socket. The descriptor io_type string is the logical name "MODEL_3D" (consistent across vendors) — the resulting V3 Output carries the upstream "FILE_3D_GLB" comfytype tag from IO.File3DGLB so frontend-side socket matching works against any GLB-aware downstream node (preview3d / SaveGLB / Load3D).
  • client.py — advertise Capability.MODEL_3D_GLB_INLINE in CLIENT_CAPABILITIES so servers gate provider descriptors on the presence of the token. Legacy clients that don't advertise it still see NEGOTIATION_FAILED at descriptor-load time (safe degradation), not a parse error at execute.

Smoke test (notes/run_model3d_decoder.py)

Covers:

  1. HEAVY_TYPES includes "model_3d".
  2. is_envelope recognises a MODEL_3D envelope.
  3. decode_model3d_envelope round-trips a minimal valid GLB (binary glTF 2.0, magic b"glTF").
  4. decode_envelope dispatches type=model_3d to the new decoder.
  5. Unsupported encoding raises RnpProtocolError.
  6. End-to-end against the server's make_model3d_envelope helper — server packs, client decodes, bytes match.
  7. proxy_node._OUTPUT_CLASSES contract: "MODEL_3D" -> IO.File3DGLB.Output.
  8. client.CLIENT_CAPABILITIES advertises Capability.MODEL_3D_GLB_INLINE.

No server-side changes. The 4 just-shipped Tripo / Rodin providers (TripoTextToModelApi_RNP, TripoImageToModelApi_RNP, TripoMultiviewToModelApi_RNP, Rodin3DRegularApi_RNP) are now reachable end-to-end from ComfyUI.

First of four cross-cutting RNP/1 protocol PRs in leverage order:

  1. CLIENT-SIDE MODEL_3D DECODER (this PR — smallest; closes loop on server PR #37)
  2. IO.DynamicCombo parser extension (highest leverage — unblocks Meshy / Kling OmniPro / Kling multi-shot)
  3. Multi-file 3D envelope (unblocks Hunyuan3D / Tencent* ObjZipResult)
  4. Cross-node graph-state envelope (unblocks Tripo chained nodes + Kling VideoExtend)

Amp-Thread-ID: T-019e3314-4336-71d2-a333-6d1e33a9986e


🔄 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/14 **Author:** [@Kosinkadink](https://github.com/Kosinkadink) **Created:** 5/16/2026 **Status:** ✅ Merged **Merged:** 5/16/2026 **Merged by:** [@Kosinkadink](https://github.com/Kosinkadink) **Base:** `main` ← **Head:** `feat/client-model-3d-decoder` --- ### 📝 Commits (1) - [`58d93da`](https://github.com/Comfy-Org/comfy-remote-nodes/commit/58d93daf2aab3878125d6e313eca8586a1d6a3e0) feat(model_3d): add client-side MODEL_3D decoder + capability advertisement ### 📊 Changes **5 files changed** (+391 additions, -15 deletions) <details> <summary>View changed files</summary> 📝 `client.py` (+9 -0) ➕ `notes/run_model3d_decoder.py` (+316 -0) 📝 `protocol.py` (+14 -3) 📝 `proxy_node.py` (+19 -8) 📝 `serialization.py` (+33 -4) </details> ### 📄 Description Closes the loop on the just-merged comfy-rnp-server PR #37 which added the four Tripo / Rodin 3D providers and the `Capability.MODEL_3D_GLB_INLINE` token. Without this client-side half the providers were unreachable from any RNP client — descriptors would fail negotiation because the proxy_node didn't advertise the token. ## Client changes (all inside `ComfyUI/custom_nodes/comfy_remote_nodes`) - **`protocol.py`** — mirror the new `Capability.MODEL_3D_GLB_INLINE` constant and add `"model_3d"` to `HEAVY_TYPES` so `is_envelope` recognises inbound 3D-model envelopes. The vendored `protocol` module is the single source of truth for the proxy_node and serialization layers; both already consume `is_envelope` / `decode_envelope_data` from here. - **`serialization.py`** — add `decode_model3d_envelope` that hands raw GLB bytes to `comfy_api.latest._util.File3D` via `BytesIO`, mirroring the existing `decode_video_envelope` shape. Only `glb_inline` is accepted today; any other encoding surfaces `RnpProtocolError(code=INTERNAL)` as defence-in-depth so a future encoding never silently downgrades to garbage bytes. Registered in the `_DECODERS` dispatch table and re-exported via `__all__`. - **`proxy_node.py`** — add `"MODEL_3D" -> IO.File3DGLB.Output` to `_OUTPUT_CLASSES` so descriptors with `output=["MODEL_3D"]` parse to a real socket. The descriptor io_type string is the logical name `"MODEL_3D"` (consistent across vendors) — the resulting V3 Output carries the upstream `"FILE_3D_GLB"` comfytype tag from `IO.File3DGLB` so frontend-side socket matching works against any GLB-aware downstream node (preview3d / SaveGLB / Load3D). - **`client.py`** — advertise `Capability.MODEL_3D_GLB_INLINE` in `CLIENT_CAPABILITIES` so servers gate provider descriptors on the presence of the token. Legacy clients that don't advertise it still see NEGOTIATION_FAILED at descriptor-load time (safe degradation), not a parse error at execute. ## Smoke test (`notes/run_model3d_decoder.py`) Covers: 1. `HEAVY_TYPES` includes `"model_3d"`. 2. `is_envelope` recognises a MODEL_3D envelope. 3. `decode_model3d_envelope` round-trips a minimal valid GLB (binary glTF 2.0, magic `b"glTF"`). 4. `decode_envelope` dispatches `type=model_3d` to the new decoder. 5. Unsupported encoding raises `RnpProtocolError`. 6. End-to-end against the server's `make_model3d_envelope` helper — server packs, client decodes, bytes match. 7. `proxy_node._OUTPUT_CLASSES` contract: `"MODEL_3D" -> IO.File3DGLB.Output`. 8. `client.CLIENT_CAPABILITIES` advertises `Capability.MODEL_3D_GLB_INLINE`. No server-side changes. The 4 just-shipped Tripo / Rodin providers (`TripoTextToModelApi_RNP`, `TripoImageToModelApi_RNP`, `TripoMultiviewToModelApi_RNP`, `Rodin3DRegularApi_RNP`) are now reachable end-to-end from ComfyUI. First of four cross-cutting RNP/1 protocol PRs in leverage order: 1. **CLIENT-SIDE MODEL_3D DECODER** (this PR — smallest; closes loop on server PR #37) 2. IO.DynamicCombo parser extension (highest leverage — unblocks Meshy / Kling OmniPro / Kling multi-shot) 3. Multi-file 3D envelope (unblocks Hunyuan3D / Tencent* ObjZipResult) 4. Cross-node graph-state envelope (unblocks Tripo chained nodes + Kling VideoExtend) Amp-Thread-ID: T-019e3314-4336-71d2-a333-6d1e33a9986e --- <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:55 +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#14
No description provided.