5353if TYPE_CHECKING: # keep this module import-safe / torch-free at import time
5454 import torch
5555
56- from ._io import NodeOutput
57-
5856logger = 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)
0 commit comments