Skip to content

Commit 05a614d

Browse files
committed
Fix API V2 runtime invariants in cloud mode
1 parent a8acc30 commit 05a614d

3 files changed

Lines changed: 38 additions & 20 deletions

File tree

comfy_api/latest/_sdk.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@
5353
if TYPE_CHECKING: # keep this module import-safe / torch-free at import time
5454
import torch
5555

56-
from ._io import NodeOutput
57-
5856
logger = logging.getLogger(__name__)
5957

6058
# Env var an operator points at a directory/module implementing ``register``.
@@ -16088,13 +16086,13 @@ async def _model_ground_image(
1608816086
if not isinstance(raw_box, dict):
1608916087
raise RuntimeError("SAM3 grounding returned an invalid box")
1609016088
box: dict[str, float] = {}
16091-
for field in ("x", "y", "width", "height", "score"):
16092-
value = raw_box.get(field)
16089+
for box_field in ("x", "y", "width", "height", "score"):
16090+
value = raw_box.get(box_field)
1609316091
if (type(value) not in (int, float)
1609416092
or not math.isfinite(float(value))):
1609516093
raise RuntimeError(
16096-
f"SAM3 grounding box has invalid {field}")
16097-
box[field] = float(value)
16094+
f"SAM3 grounding box has invalid {box_field}")
16095+
box[box_field] = float(value)
1609816096
if (box["width"] < 0.0 or box["height"] < 0.0
1609916097
or not 0.0 <= box["score"] <= 1.0
1610016098
or abs(box["x"]) > width * 4
@@ -16579,6 +16577,7 @@ def __init__(self) -> None:
1657916577
self.ops_provider: OpsProvider = InProcessOps()
1658016578
self.ref_resolver_factory: Callable[[], RefResolver] = InProcessRefResolver
1658116579
self._overlay_name: Optional[str] = None
16580+
self._extension_host_module_url: Optional[str] = None
1658216581

1658316582
# Overlay entry points -------------------------------------------------- #
1658416583
def register_execution_backend(self, impl: ExecutionBackend) -> None:
@@ -16597,6 +16596,21 @@ def register_ref_resolver_factory(self, factory: Callable[[], RefResolver]) -> N
1659716596
logger.info("SDK: ref resolver -> %s", getattr(factory, "__name__", factory))
1659816597
self.ref_resolver_factory = factory
1659916598

16599+
def register_extension_host(self, module_url: str) -> None:
16600+
if not module_url:
16601+
raise ValueError("extension host module URL must not be empty")
16602+
self._extension_host_module_url = module_url
16603+
16604+
@property
16605+
def frontend_runtime_config(self) -> dict[str, Any]:
16606+
if self._extension_host_module_url is None:
16607+
return {}
16608+
return {
16609+
"extension_host": {
16610+
"module_url": self._extension_host_module_url,
16611+
}
16612+
}
16613+
1660016614
@property
1660116615
def overlay_active(self) -> bool:
1660216616
return self._overlay_name is not None
@@ -16643,15 +16657,21 @@ def load_overlay(spec: Optional[str] = None) -> bool:
1664316657
module = importlib.import_module(spec) # importable module name
1664416658

1664516659
if module is None:
16646-
logger.error("SDK overlay %r could not be loaded", spec)
16647-
return False
16660+
raise RuntimeError(f"SDK overlay {spec!r} could not be loaded")
1664816661

1664916662
register = getattr(module, "register", None)
1665016663
if not callable(register):
16651-
logger.error("SDK overlay %r has no register(providers) entrypoint", spec)
16652-
return False
16664+
raise RuntimeError(
16665+
f"SDK overlay {spec!r} has no register(providers) entrypoint"
16666+
)
1665316667

1665416668
register(providers)
1665516669
providers._overlay_name = getattr(module, "__name__", spec)
1665616670
logger.info("SDK overlay loaded: %s", providers._overlay_name)
1665716671
return True
16672+
16673+
16674+
def should_load_legacy_custom_nodes(
16675+
*, secure_mode: bool, disabled: bool, has_whitelist: bool
16676+
) -> bool:
16677+
return not secure_mode and (not disabled or has_whitelist)

execution.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ def __init__(self, server, cache_type=False, cache_args=None):
821821
self.cache_args = cache_args
822822
self.cache_type = cache_type
823823
self.server = server
824+
self.prompt_model_tracker = comfy.model_patcher.PromptModelTracker()
824825
self._runner = asyncio.Runner()
825826
self._active_loop = None
826827
self._active_task = None

main.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -558,16 +558,13 @@ def start_comfyui(asyncio_loop=None):
558558
if args.enable_manager and not args.disable_manager_ui:
559559
comfyui_manager.start()
560560

561-
# Custom-node SDK overlay: if COMFY_OVERLAY_MODULE points at a module, it
562-
# registers isolated execution/ctx/ref providers before nodes load. Unset =
563-
# pure in-process open-source behavior.
564-
try:
565-
from comfy_api.latest import sdk
566-
sdk.providers # ensure module imported
567-
from comfy_api.latest._sdk import load_overlay
568-
load_overlay()
569-
except Exception as e:
570-
logging.error(f"Custom-node SDK overlay failed to load: {e}")
561+
from comfy_api.latest import sdk
562+
sdk.providers
563+
from comfy_api.latest._sdk import (
564+
load_overlay,
565+
should_load_legacy_custom_nodes,
566+
)
567+
secure_custom_nodes = load_overlay()
571568

572569
hook_breaker_ac10a0.save_functions()
573570
asyncio_loop.run_until_complete(nodes.init_extra_nodes(

0 commit comments

Comments
 (0)