diff --git a/invokeai/app/invocations/baseinvocation.py b/invokeai/app/invocations/baseinvocation.py index 65a8734690..f5ad61e4f8 100644 --- a/invokeai/app/invocations/baseinvocation.py +++ b/invokeai/app/invocations/baseinvocation.py @@ -28,6 +28,8 @@ from pydantic.fields import Undefined, ModelField from pydantic.typing import NoArgAnyCallable import semver +from invokeai.app.services.config.invokeai_config import InvokeAIAppConfig + if TYPE_CHECKING: from ..services.invocation_services import InvocationServices @@ -470,6 +472,8 @@ class BaseInvocation(ABC, BaseModel): @classmethod def get_all_subclasses(cls): + app_config = InvokeAIAppConfig.get_config() + app_config.parse_args() subclasses = [] toprocess = [cls] while len(toprocess) > 0: @@ -477,7 +481,23 @@ class BaseInvocation(ABC, BaseModel): next_subclasses = next.__subclasses__() subclasses.extend(next_subclasses) toprocess.extend(next_subclasses) - return subclasses + allowed_invocations = [] + for sc in subclasses: + is_in_allowlist = ( + sc.__fields__.get("type").default in app_config.allow_nodes + if isinstance(app_config.allow_nodes, list) + else True + ) + + is_in_denylist = ( + sc.__fields__.get("type").default in app_config.deny_nodes + if isinstance(app_config.deny_nodes, list) + else False + ) + + if is_in_allowlist and not is_in_denylist: + allowed_invocations.append(sc) + return allowed_invocations @classmethod def get_invocations(cls): diff --git a/invokeai/app/services/config/invokeai_config.py b/invokeai/app/services/config/invokeai_config.py index 1a2c22c89a..7b687a28a1 100644 --- a/invokeai/app/services/config/invokeai_config.py +++ b/invokeai/app/services/config/invokeai_config.py @@ -254,6 +254,10 @@ class InvokeAIAppConfig(InvokeAISettings): attention_slice_size: Literal[tuple(["auto", "balanced", "max", 1, 2, 3, 4, 5, 6, 7, 8])] = Field(default="auto", description='Slice size, valid when attention_type=="sliced"', category="Generation", ) force_tiled_decode: bool = Field(default=False, description="Whether to enable tiled VAE decode (reduces memory consumption with some performance penalty)", category="Generation",) + # NODES + allow_nodes : Optional[List[str]] = Field(default=None, description="List of nodes to allow. Omit to allow all.", category="Nodes") + deny_nodes : Optional[List[str]] = Field(default=None, description="List of nodes to deny. Omit to deny none.", category="Nodes") + # DEPRECATED FIELDS - STILL HERE IN ORDER TO OBTAN VALUES FROM PRE-3.1 CONFIG FILES always_use_cpu : bool = Field(default=False, description="If true, use the CPU for rendering even if a GPU is available.", category='Memory/Performance') free_gpu_mem : Optional[bool] = Field(default=None, description="If true, purge model from GPU after each generation.", category='Memory/Performance')