Skip to content

feat(isolation): wheel support for isolated custom nodes#12959

Merged
pollockjj merged 1 commit intoComfy-Org:pyisolate-supportfrom
pollockjj:wheel-support-pr
Mar 15, 2026
Merged

feat(isolation): wheel support for isolated custom nodes#12959
pollockjj merged 1 commit intoComfy-Org:pyisolate-supportfrom
pollockjj:wheel-support-pr

Conversation

@pollockjj
Copy link
Copy Markdown

@pollockjj pollockjj commented Mar 15, 2026

Summary

  • Extends pyisolate process isolation with wheel-based dependency management and sandbox mode policy
  • Adds sandbox_mode (required/disabled) host policy with COMFY_HOST_POLICY_PATH env override
  • Plumbs cuda_wheels config and standardizes child environment detection
  • Fixes five isolation compatibility gaps found during DA3 validation:
    • ACCEPT_ALL_INPUTS capture preventing @classproperty trigger on proxy
    • NodeOutput serialization preserving ui/expand/block_execution through JSON-RPC
    • Web directory registration for isolated extension frontend widgets
    • V3 python_module metadata fix (cherry-pick of e459219)

Validated against

  • ComfyUI-DepthAnythingV3: all 7 shipped workflows pass both non-isolated and isolated (sandbox_mode=disabled)
  • bas_relief with da3_large (~781MB) completes without OOM on RTX 3090

Test plan

  • All existing isolation unit tests pass
  • DA3 workflows pass non-isolated (upstream parity)
  • DA3 workflows pass isolated with --use-process-isolation --disable-cuda-malloc

Extends pyisolate process isolation with wheel-based dependency
management, sandbox mode policy, and compatibility fixes validated
against DA3 as the first complex isolated custom node.

- Add sandbox_mode policy (required/disabled) with COMFY_HOST_POLICY_PATH
  env override for host security configuration
- Plumb cuda_wheels config and standardize child environment detection
- Add PLY, NPZ, File3D, VIDEO serializers for core save nodes
- Register isolated extension web directories on host side
  (sandbox_mode=disabled) for frontend JS widget serving
- Capture ACCEPT_ALL_INPUTS from child node class to prevent
  @classproperty trigger on proxy class
- Serialize NodeOutput with ui/expand/block_execution through JSON-RPC
- Cherry-pick V3 python_module metadata fix (e459219)
- Remove improperly committed cache artifacts
Copilot AI review requested due to automatic review settings March 15, 2026 06:25
@pollockjj pollockjj requested a review from guill as a code owner March 15, 2026 06:25
@pollockjj pollockjj merged commit c023729 into Comfy-Org:pyisolate-support Mar 15, 2026
10 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the process-isolation subsystem to support a host-controlled sandbox policy (sandbox_mode) and improves isolated node compatibility by preserving richer execution results and registering extension web assets when sandboxing is disabled.

Changes:

  • Add sandbox_mode to host policy with TOML + COMFY_HOST_POLICY_PATH override and propagate it into isolated extension configs.
  • Preserve V3 NodeOutput metadata across isolation boundaries (including ui/expand/block_execution) and capture accept_all_inputs for stub class generation.
  • Register isolated extension web directories on the host when sandboxing is disabled; remove accidentally committed cache artifacts.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
comfy/isolation/host_policy.py Introduces sandbox_mode, env override for policy path, and enhanced logging.
comfy/isolation/extension_loader.py Plumbs sandbox_mode into extension config and adds host-side web dir registration (sandbox-disabled only).
comfy/isolation/extension_wrapper.py Wraps execution with inference mode and introduces NodeOutput envelope serialization.
comfy/isolation/runtime_helpers.py Reconstructs NodeOutput on host and normalizes V3 python_module metadata; captures ACCEPT_ALL_INPUTS.
pyproject.toml Sets default host sandbox_mode = "required".
tests/isolation/test_host_policy.py Adds coverage for sandbox_mode parsing, invalid values, and env override path.
tests/isolation/test_cuda_wheels_and_env_flags.py Updates isolation manifest plumbing tests to assert sandbox_mode propagation.
.pyisolate_venvs/ComfyUI-IsolationToolkit/cache/cache_key Removes committed cache artifact.
.pyisolate_venvs/ComfyUI-DepthAnythingV2/cache/node_info.json Removes committed cache artifact.
.pyisolate_venvs/ComfyUI-DepthAnythingV2/cache/cache_key Removes committed cache artifact.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 399 to +410
if type(result).__name__ == "NodeOutput":
result = result.args
node_output_dict = {
"__node_output__": True,
"args": self._wrap_unpicklable_objects(result.args),
}
if result.ui is not None:
node_output_dict["ui"] = result.ui
if getattr(result, "expand", None) is not None:
node_output_dict["expand"] = result.expand
if getattr(result, "block_execution", None) is not None:
node_output_dict["block_execution"] = result.block_execution
return node_output_dict
node_info = copy.deepcopy(info.get("schema_v1", {}))
relative_python_module = node_info.get("python_module")
if not isinstance(relative_python_module, str) or not relative_python_module:
relative_python_module = f"custom_nodes.{extension.name}"
Comment on lines +55 to +60
for line in source.splitlines():
stripped = line.strip()
if stripped.startswith("WEB_DIRECTORY"):
# Parse: WEB_DIRECTORY = "./web" or WEB_DIRECTORY = "web"
_, _, value = stripped.partition("=")
value = value.strip().strip("\"'")
Comment on lines 399 to +410
if type(result).__name__ == "NodeOutput":
result = result.args
node_output_dict = {
"__node_output__": True,
"args": self._wrap_unpicklable_objects(result.args),
}
if result.ui is not None:
node_output_dict["ui"] = result.ui
if getattr(result, "expand", None) is not None:
node_output_dict["expand"] = result.expand
if getattr(result, "block_execution", None) is not None:
node_output_dict["block_execution"] = result.block_execution
return node_output_dict
Comment on lines +224 to +228
scan_shm_forensics("RUNTIME:post_execute", refresh_model_context=True)
return latest_io.NodeOutput(
*deserialized_args,
ui=result.get("ui"),
expand=result.get("expand"),
Comment on lines +377 to +378
with torch.inference_mode():
result = await handler(**resolved_inputs)
Comment on lines +404 to +407
if result.ui is not None:
node_output_dict["ui"] = result.ui
if getattr(result, "expand", None) is not None:
node_output_dict["expand"] = result.expand
@pollockjj pollockjj deleted the wheel-support-pr branch March 15, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants