Skip to content

Commit 6e5a529

Browse files
feat(nodes): add ui_model_[base|type|variant] to InputField args for dynamic UI generation
1 parent 8c742a6 commit 6e5a529

File tree

1 file changed

+104
-2
lines changed

1 file changed

+104
-2
lines changed

invokeai/app/invocations/fields.py

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from invokeai.app.util.metaenum import MetaEnum
99
from invokeai.backend.image_util.segment_anything.shared import BoundingBox
10+
from invokeai.backend.model_manager.taxonomy import BaseModelType, ClipVariantType, ModelType, ModelVariantType
1011
from invokeai.backend.util.logging import InvokeAILogger
1112

1213
logger = InvokeAILogger.get_logger()
@@ -39,7 +40,7 @@ class UIType(str, Enum, metaclass=MetaEnum):
3940
used, and the type will be ignored. They are included here for backwards compatibility.
4041
"""
4142

42-
# region Model Field Types
43+
# region Quasi-deprecated Model Field Types - use ui_model_[base|type|variant] instead
4344
MainModel = "MainModelField"
4445
CogView4MainModel = "CogView4MainModelField"
4546
FluxMainModel = "FluxMainModelField"
@@ -409,6 +410,9 @@ class InputFieldJSONSchemaExtra(BaseModel):
409410
ui_component: Optional[UIComponent] = None
410411
ui_order: Optional[int] = None
411412
ui_choice_labels: Optional[dict[str, str]] = None
413+
ui_model_base: Optional[list[BaseModelType]] = None
414+
ui_model_type: Optional[list[ModelType]] = None
415+
ui_model_variant: Optional[list[ClipVariantType | ModelVariantType]] = None
412416

413417
model_config = ConfigDict(
414418
validate_assignment=True,
@@ -501,6 +505,9 @@ def InputField(
501505
ui_hidden: Optional[bool] = None,
502506
ui_order: Optional[int] = None,
503507
ui_choice_labels: Optional[dict[str, str]] = None,
508+
ui_model_base: Optional[BaseModelType | list[BaseModelType]] = None,
509+
ui_model_type: Optional[ModelType | list[ModelType]] = None,
510+
ui_model_variant: Optional[ClipVariantType | ModelVariantType | list[ClipVariantType | ModelVariantType]] = None,
504511
) -> Any:
505512
"""
506513
Creates an input field for an invocation.
@@ -538,7 +545,87 @@ def InputField(
538545
)
539546

540547
if ui_type is not None:
541-
json_schema_extra_.ui_type = ui_type
548+
if ui_model_base is not None or ui_model_type is not None or ui_model_variant is not None:
549+
logger.warning("Use either ui_type or ui_model_[base|type|variant]. Ignoring ui_type.")
550+
# Map old-style UIType to new-style ui_model_[base|type|variant]
551+
elif ui_type is UIType.MainModel:
552+
json_schema_extra_.ui_model_type = [ModelType.Main]
553+
elif ui_type is UIType.CogView4MainModel:
554+
json_schema_extra_.ui_model_base = [BaseModelType.CogView4]
555+
json_schema_extra_.ui_model_type = [ModelType.Main]
556+
elif ui_type is UIType.FluxMainModel:
557+
json_schema_extra_.ui_model_base = [BaseModelType.Flux]
558+
json_schema_extra_.ui_model_type = [ModelType.Main]
559+
elif ui_type is UIType.SD3MainModel:
560+
json_schema_extra_.ui_model_base = [BaseModelType.StableDiffusion3]
561+
json_schema_extra_.ui_model_type = [ModelType.Main]
562+
elif ui_type is UIType.SDXLMainModel:
563+
json_schema_extra_.ui_model_base = [BaseModelType.StableDiffusionXL]
564+
json_schema_extra_.ui_model_type = [ModelType.Main]
565+
elif ui_type is UIType.SDXLRefinerModel:
566+
json_schema_extra_.ui_model_base = [BaseModelType.StableDiffusionXLRefiner]
567+
json_schema_extra_.ui_model_type = [ModelType.Main]
568+
# Think this UIType is unused...?
569+
# elif ui_type is UIType.ONNXModel:
570+
# json_schema_extra_.ui_model_base =
571+
# json_schema_extra_.ui_model_type =
572+
elif ui_type is UIType.VAEModel:
573+
json_schema_extra_.ui_model_type = [ModelType.VAE]
574+
elif ui_type is UIType.FluxVAEModel:
575+
json_schema_extra_.ui_model_base = [BaseModelType.Flux]
576+
json_schema_extra_.ui_model_type = [ModelType.VAE]
577+
elif ui_type is UIType.LoRAModel:
578+
json_schema_extra_.ui_model_type = [ModelType.LoRA]
579+
elif ui_type is UIType.ControlNetModel:
580+
json_schema_extra_.ui_model_type = [ModelType.ControlNet]
581+
elif ui_type is UIType.IPAdapterModel:
582+
json_schema_extra_.ui_model_type = [ModelType.IPAdapter]
583+
elif ui_type is UIType.T2IAdapterModel:
584+
json_schema_extra_.ui_model_type = [ModelType.T2IAdapter]
585+
elif ui_type is UIType.T5EncoderModel:
586+
json_schema_extra_.ui_model_type = [ModelType.T5Encoder]
587+
elif ui_type is UIType.CLIPEmbedModel:
588+
json_schema_extra_.ui_model_type = [ModelType.CLIPEmbed]
589+
elif ui_type is UIType.CLIPLEmbedModel:
590+
json_schema_extra_.ui_model_type = [ModelType.CLIPEmbed]
591+
json_schema_extra_.ui_model_variant = [ClipVariantType.L]
592+
elif ui_type is UIType.CLIPGEmbedModel:
593+
json_schema_extra_.ui_model_type = [ModelType.CLIPEmbed]
594+
json_schema_extra_.ui_model_variant = [ClipVariantType.G]
595+
elif ui_type is UIType.SpandrelImageToImageModel:
596+
json_schema_extra_.ui_model_type = [ModelType.SpandrelImageToImage]
597+
elif ui_type is UIType.ControlLoRAModel:
598+
json_schema_extra_.ui_model_type = [ModelType.ControlLoRa]
599+
elif ui_type is UIType.SigLipModel:
600+
json_schema_extra_.ui_model_type = [ModelType.SigLIP]
601+
elif ui_type is UIType.FluxReduxModel:
602+
json_schema_extra_.ui_model_type = [ModelType.FluxRedux]
603+
elif ui_type is UIType.LlavaOnevisionModel:
604+
json_schema_extra_.ui_model_type = [ModelType.LlavaOnevision]
605+
elif ui_type is UIType.Imagen3Model:
606+
json_schema_extra_.ui_model_base = [BaseModelType.Imagen3]
607+
json_schema_extra_.ui_model_type = [ModelType.Main]
608+
elif ui_type is UIType.Imagen4Model:
609+
json_schema_extra_.ui_model_base = [BaseModelType.Imagen4]
610+
json_schema_extra_.ui_model_type = [ModelType.Main]
611+
elif ui_type is UIType.ChatGPT4oModel:
612+
json_schema_extra_.ui_model_base = [BaseModelType.ChatGPT4o]
613+
json_schema_extra_.ui_model_type = [ModelType.Main]
614+
elif ui_type is UIType.Gemini2_5Model:
615+
json_schema_extra_.ui_model_base = [BaseModelType.Gemini2_5]
616+
json_schema_extra_.ui_model_type = [ModelType.Main]
617+
elif ui_type is UIType.FluxKontextModel:
618+
json_schema_extra_.ui_model_base = [BaseModelType.FluxKontext]
619+
json_schema_extra_.ui_model_type = [ModelType.Main]
620+
elif ui_type is UIType.Veo3Model:
621+
json_schema_extra_.ui_model_base = [BaseModelType.Veo3]
622+
json_schema_extra_.ui_model_type = [ModelType.Video]
623+
elif ui_type is UIType.RunwayModel:
624+
json_schema_extra_.ui_model_base = [BaseModelType.Runway]
625+
json_schema_extra_.ui_model_type = [ModelType.Video]
626+
else:
627+
json_schema_extra_.ui_type = ui_type
628+
542629
if ui_component is not None:
543630
json_schema_extra_.ui_component = ui_component
544631
if ui_hidden is not None:
@@ -547,6 +634,21 @@ def InputField(
547634
json_schema_extra_.ui_order = ui_order
548635
if ui_choice_labels is not None:
549636
json_schema_extra_.ui_choice_labels = ui_choice_labels
637+
if ui_model_base is not None:
638+
if isinstance(ui_model_base, list):
639+
json_schema_extra_.ui_model_base = ui_model_base
640+
else:
641+
json_schema_extra_.ui_model_base = [ui_model_base]
642+
if ui_model_type is not None:
643+
if isinstance(ui_model_type, list):
644+
json_schema_extra_.ui_model_type = ui_model_type
645+
else:
646+
json_schema_extra_.ui_model_type = [ui_model_type]
647+
if ui_model_variant is not None:
648+
if isinstance(ui_model_variant, list):
649+
json_schema_extra_.ui_model_variant = ui_model_variant
650+
else:
651+
json_schema_extra_.ui_model_variant = [ui_model_variant]
550652

551653
"""
552654
There is a conflict between the typing of invocation definitions and the typing of an invocation's

0 commit comments

Comments
 (0)