-
Notifications
You must be signed in to change notification settings - Fork 2.7k
feat: dynamic model fields in workflow editor #8577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
+469
−3,087
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
hipsterusername
approved these changes
Sep 17, 2025
maryhipp
approved these changes
Sep 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That diff tho 🤩
…dynamic UI generation
42c9228
to
0366091
Compare
…cate the model ui types
Though we have no current use for it, for the sake of future node authors' ease of experimentation, I added |
5 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
frontend
PRs that change frontend files
invocations
PRs that change invocations
python
PRs that change python files
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a new system for dynamically generating Workflow Editor model drop-downs. This pattern is has a few benefits:
Context
Nodes often need a drop-down in the UI that lists a specific base, type, and/or variant of model. For example, the
Main Model - SD1.5
(main_model_loader
) node needs to display a list of SD1.5 main models only.Informing the frontend that it should only show SD1.5 main models was a small technical challenge. Pydantic creates OpenAPI schemas for each node class, and we parse those into something the Workflow Editor can use to dynamically build node UIs. Python type annotations are what determine the "type" of the field.
For example, in the
Main Model - SD1.5
node, we had a field definition like this:ModelIdentifierField
- a pydantic model - ends up in the OpenAPI schema, then the frontend sees this annotation and knows this field can accept a model. But, as described above, we don't need just any model - we need exclusively SD1.5 main models.We could have created new python classes for every type of model, using them as type annotations. For example:
This could get pretty hairy, with many different classes, each of which with their own pydantic model. In an effort to make things a bit simpler and more flexible, we added the
ui_type
arg. This doesn't affect pydantic or OpenAPI schema generation, but it gives the frontend an extra hint.In the
Main Model - SD1.5
node, we set the arg toUIType.MainModel
:This tells the frontend "This is a
ModelIdentifierField
, but it has this extra constraint of needing only SD1.5 main models.".The frontend requires a lot of special handling and boilerplate to understand each of the
UIType
values:(We'd still need this special handling if we used different pydantic classes for each model, but we'd also have a crapload of special handling in the backend in that case.)
Solution
It's really simple. Instead of exposing a
ui_type
arg, we expose a few optional args that let the node describe the models it needs. Each of these args supports either a single or list of allowed types.ui_model_base: BaseModelType | list[BaseModelType]
indicates which architectures are allowed (e.g. SD1.5, SD1.5 and SDXL, FLUX, etc).ui_model_type: ModelType | list[ModelType]
indicates which types of models are allowed (e.g. main, ControlNet, LoRA, etc.ui_model_variant: ModelVariantType | ClipVariantType | list[ModelVariantType | ClipVariantType]
indicates which variants are allowed. This is currently only used to differentiate between CLIP-L and CLIP-G.So for that
Main Model - SD1.5
node, we now write themodel
field like this:In the Workflow Editor frontend codebase, we now have only 1 model field component, compared to like 20 before. This one component filters its downdown based on the args.
The change is fully backwards compatible with existing workflows, with no data migration or compatibility layer required. Workflow Editor field types are not stored in the user's workflows, so we can modify them freely without breaking anything.
Less Boilerplate
Let's say we want to add support for Qwen-Image. We'd do all the same backend changes, then create the Qwen-Image model loader. It would have a model field that looks like this:
That's it! The frontend will see
BaseModelType.QwenImage
and automatically show Qwen-Image models in the node. Zero frontend code changes required to support it in the Workflow Editor.Reduced Footguns
There are a bajillion combinations of base model and model types. For example, ControlNet works with SD1.5, SDXL, and FLUX (maybe others I'm forgetting). We have a node for SD1.5/SDXL and another for FLUX.
But our ControlNet model fields were all defined like this:
Note that there is nothing that tells the frontend if this is for SD1.5/SDXL, or FLUX. Regardless of the base model of the node, we showed a list of all ControlNet models. It was possible to select FLUX models on the SD1.5/SDXL node and vice-versa. If you chose the wrong model, you'd get a cryptic error during denoising.
With the new system, we can be more specific and only show the correct models:
Simpler Implementation and Extension
The schema parsing required for the Workflow Editor is simpler thanks to this change. We don't need special handling and can simply filter models based on the args to narrow the list shown in a drop-down.
Extending the system is pretty easy, too. For example, if we needed to only show checkpoint-format models in a node for whatever reason, we would could
ui_model_format
. It would require editing only a handful of files:invokeai/app/invocations/fields.py
to add the arg to the input field definitionsinvokeai/frontend/web/src/features/nodes/types/field.ts
to add the arg to the workflow editor's input field template schema (requires a matching zod schema for the format enum)invokeai/frontend/web/src/features/nodes/util/schema/buildFieldInputTemplate.ts
to parse the value from OpenAPI schema and add it to the input field templateinvokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ModelIdentifierFieldInputComponent.tsx
to filter the model dropdown list based on the new argBackwards Compatible
As mentioned above, the change is fully backwards compatible with existing workflows. What about the existing
ui_type: UIType
in theInputField
helper, and custom nodes?Well, all of the model-related
UIType
s map directly to some combination of base, type and variant. Ininvokeai/app/invocations/fields.py
you'll see a long (but very simple) conditional that sets the appropriateui_model_[base|type|variant]
for eachUIType
.I already migrated all core nodes from
UIType
to the new args, but custom nodes should continue to work with no code changes required. The conditional logic just kinda migrates them automatically at runtime.TODO
We supportWe do needUIType
for output fields. I need to think more about it, but I think it's fine to just ignoreUIType
for outputs. I don't think it serves any functional or user-facing purpose.UIType
for output fields. It's used forAny
andScheduler
fields.Related Issues / Discussions
n/a
QA Instructions
Try out the workflow editor, especially custom nodes. Besides the reduced footguns for model fields (i.e. you may no longer select FLUX ControlNets in the SD1.5/SDXL ControlNet node), this should be a transparent change.
Merge Plan
n/a
Checklist
What's New
copy (if doing a release after this PR)