-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
feat(nodes/ui): refactor field types, workflows #5157
Closed
psychedelicious
wants to merge
26
commits into
invoke-ai:main
from
psychedelicious:feat/refactor-field-types
Closed
feat(nodes/ui): refactor field types, workflows #5157
psychedelicious
wants to merge
26
commits into
invoke-ai:main
from
psychedelicious:feat/refactor-field-types
Conversation
This file contains 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
13 tasks
psychedelicious
changed the title
feat(nodes/ui): refactor field types
feat(nodes/ui): refactor field types, workflows
Nov 24, 2023
psychedelicious
force-pushed
the
feat/refactor-field-types
branch
from
November 25, 2023 04:52
aefc8fc
to
a27f627
Compare
psychedelicious
added a commit
to psychedelicious/XYGrid_nodes
that referenced
this pull request
Nov 25, 2023
These changes are needed for compatibility with invoke-ai/InvokeAI#5157, though leaving them in won't cause any problems - just a warning.
psychedelicious
added a commit
to psychedelicious/XYGrid_nodes
that referenced
this pull request
Nov 25, 2023
These changes are needed for compatibility with invoke-ai/InvokeAI#5157, though leaving them in won't cause any problems - just a warning.
psychedelicious
force-pushed
the
feat/refactor-field-types
branch
3 times, most recently
from
November 27, 2023 01:51
5f77227
to
f12f22a
Compare
Node authors may now create their own arbitrary/custom field types. Any pydantic model is supported. Two notes: 1. Your field type's class name must be unique. Suggest prefixing fields with something related to the node pack as a kind of namespace. 2. Custom field types function as connection-only fields. For example, if your custom field has string attributes, you will not get a text input for that attribute when you give a node a field with your custom type. This is the same behaviour as other complex fields that don't have custom UIs in the workflow editor - like, say, a string collection. feat(ui): fix tooltips for custom types We need to hold onto the original type of the field so they don't all just show up as "Unknown". fix(ui): fix ts error with custom fields feat(ui): custom field types connection validation In the initial commit, a custom field's original type was added to the *field templates* only as `originalType`. Custom fields' `type` property was `"Custom"`*. This allowed for type safety throughout the UI logic. *Actually, it was `"Unknown"`, but I changed it to custom for clarity. Connection validation logic, however, uses the *field instance* of the node/field. Like the templates, *field instances* with custom types have their `type` set to `"Custom"`, but they didn't have an `originalType` property. As a result, all custom fields could be connected to all other custom fields. To resolve this, we need to add `originalType` to the *field instances*, then switch the validation logic to use this instead of `type`. This ended up needing a bit of fanagling: - If we make `originalType` a required property on field instances, existing workflows will break during connection validation, because they won't have this property. We'd need a new layer of logic to migrate the workflows, adding the new `originalType` property. While this layer is probably needed anyways, typing `originalType` as optional is much simpler. Workflow migration logic can come layer. (Technically, we could remove all references to field types from the workflow files, and let the templates hold all this information. This feels like a significant change and I'm reluctant to do it now.) - Because `originalType` is optional, anywhere we care about the type of a field, we need to use it over `type`. So there are a number of `field.originalType ?? field.type` expressions. This is a bit of a gotcha, we'll need to remember this in the future. - We use `Array.prototype.includes()` often in the workflow editor, e.g. `COLLECTION_TYPES.includes(type)`. In these cases, the const array is of type `FieldType[]`, and `type` is is `FieldType`. Because we now support custom types, the arg `type` is now widened from `FieldType` to `string`. This causes a TS error. This behaviour is somewhat controversial (see microsoft/TypeScript#14520). These expressions are now rewritten as `COLLECTION_TYPES.some((t) => t === type)` to satisfy TS. It's logically equivalent. fix(ui): typo feat(ui): add CustomCollection and CustomPolymorphic field types feat(ui): add validation for CustomCollection & CustomPolymorphic types - Update connection validation for custom types - Use simple string parsing to determine if a field is a collection or polymorphic type. - No longer need to keep a list of collection and polymorphic types. - Added runtime checks in `baseinvocation.py` to ensure no fields are named in such a way that it could mess up the new parsing chore(ui): remove errant console.log fix(ui): rename 'nodes.currentConnectionFieldType' -> 'nodes.connectionStartFieldType' This was confusingly named and kept tripping me up. Renamed to be consistent with the `reactflow` `ConnectionStartParams` type. fix(ui): fix ts error feat(nodes): add runtime check for custom field names "Custom", "CustomCollection" and "CustomPolymorphic" are reserved field names. chore(ui): add TODO for revising field type names wip refactor fieldtype structured wip refactor field types wip refactor types wip refactor types fix node layout refactor field types chore: mypy organisation organisation organisation fix(nodes): fix field orig_required, field_kind and input statuses feat(nodes): remove broken implementation of default_factory on InputField Use of this could break connection validation due to the difference in node schemas required fields and invoke() required args. Removed entirely for now. It wasn't ever actually used by the system, because all graphs always had values provided for fields where default_factory was used. Also, pydantic is smart enough to not reuse the same object when specifying a default value - it clones the object first. So, the common pattern of `default_factory=list` is extraneous. It can just be `default=[]`. fix(nodes): fix InputField name validation workflow validation validation chore: ruff feat(nodes): fix up baseinvocation comments fix(ui): improve typing & logic of buildFieldInputTemplate improved error handling in parseFieldType fix: back compat for deprecated default_factory and UIType feat(nodes): do not show node packs loaded log if none loaded chore(ui): typegen
When a node is updated with new fields and workflow needs to be updated, the fields now display "Unknown input/output: FieldName".
We can use the autogenerated types to avoid types
Custom nodes have a new attribute `node_pack` indicating the node pack they came from. - This is displayed in the UI in the icon icon tooltip. - If a workflow is loaded and a node is unavailable, its node pack will be displayed (if it is known). - If a workflow is migrated from v1 to v2, and the node is unknown, it falls back to "Unknown". If the missing node pack is installed and the node is updated, the node pack will be updated as expected.
psychedelicious
force-pushed
the
feat/refactor-field-types
branch
from
November 27, 2023 01:53
f12f22a
to
1d5be9c
Compare
psychedelicious
requested review from
blessedcoolant,
maryhipp,
hipsterusername,
Kyle0654 and
brandonrising
as code owners
November 27, 2023 01:59
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What type of PR is this? (check all applicable)
Have you discussed this change with the InvokeAI team?
Have you updated all relevant documentation?
Description
This PR is a substantial refactor of the frontend workflows logic.
There are some minimal changes to python code to support the frontend changes.
Python Changes
UIType
enum members, which are no longer needed. If adeprecated type is used, a warning will be logged and the type ignored.
default_factory
arg toInputField()
andOutputField()
. Ifthis arg is used, the callback will be called during invocation registration,
and set as the
default
value. A warning will be logged.callback could actually do something (like a random seed), we actually
always provided a valid value directly, so the callbacks were never actually
called during graph execution.
_InputField
->InputJSONSchemaExtra
)Changes outside
baseinvocation.py
are minor and support these changes.Frontend Changes
The main frontend change is a refactor of fields, workflows and their types.
This involved renaming and shuffling many files and so there are a ton of small
changes throughout the code with new names or import paths.
Fields
The biggest changes are to fields, particularly field types.
Field Types
Previously, field types were strings. For example, integers would be
"integer"
,"IntegerCollection"
or"IntegerPolymorphic"
.Adding a new field type was a major pain, and there was a lot of fiddly logic
related to edge validation.
Field types are now structured. Here's integer:
Stateful and Stateless Field Types
Fields are now conceptually categorized as stateful or stateless.
Stateful fields are things like integers, strings or images. They have state
(value) in the frontend, and UI components allowing users to change their value.
Stateless fields are things like
UNetField
orControlField
. The user cannotdirectly change these fields - they are created and consumed only in python - so
they have no UI component.
The signature of a stateless field type is a wider version of a stateful field:
The handling of fields is now generalized such that node authors may freely
create pydantic models for their fields. Many "official" field types are
stateless, and all "custom" field types in community nodes are stateless.
Connection validation still works as it did previously.
zod Schemas and Types
All workflow-related schemas and types have been rewritten, see files in
invokeai/frontend/web/src/features/nodes/types/
.Almost everything is now a zod schema with inferred TS types (previously there
was a lot of pure TS). The OpenAPI schema types are still pure TS.
The naming conventions for these things have been revised and made consistent.
There are many small changes in components and hooks resulting from newly named
schemas, types and type-guards.
Other Changes
invokeai/frontend/web/src/features/nodes/util/workflow/migrations.ts
)in
invokeai/frontend/web/src/features/nodes/types/v1/
and used duringmigration.
feedback)
and node pack name will be displayed
some field schemas)
their implementation on frontend
Related Tickets & Documents
QA Instructions, Screenshots, Recordings
Sorry for the size of this. I don't think I could split up the frontend changes into separate PRs without breaking the app - I rewrote a substantial portion of workflow-related logic across the frontend, and a partial implementation would leave it nonfunctional.
The changes are scoped to the workflow editor. Workflows that work on 3.4.0post2 should work in this PR.
You should be able to add custom fields. I made a small node pack with custom fields to test.
Everything in the workflow editor should work just like it did before.