InvokeAI/invokeai/app/invocations
psychedelicious 731860c332 feat(nodes): JIT graph nodes validation
We use pydantic to validate a union of valid invocations when instantiating a graph.

Previously, we constructed the union while creating the `Graph` class. This introduces a dependency on the order of imports.

For example, consider a setup where we have 3 invocations in the app:

- Python executes the module where `FirstInvocation` is defined, registering `FirstInvocation`.
- Python executes the module where `SecondInvocation` is defined, registering `SecondInvocation`.
- Python executes the module where `Graph` is defined. A union of invocations is created and used to define the `Graph.nodes` field. The union contains `FirstInvocation` and `SecondInvocation`.
- Python executes the module where `ThirdInvocation` is defined, registering `ThirdInvocation`.
- A graph is created that includes `ThirdInvocation`. Pydantic validates the graph using the union, which does not know about `ThirdInvocation`, raising a `ValidationError` about an unknown invocation type.

This scenario has been particularly problematic in tests, where we may create invocations dynamically. The test files have to be structured in such a way that the imports happen in the right order. It's a major pain.

This PR refactors the validation of graph nodes to resolve this issue:

- `BaseInvocation` gets a new method `get_typeadapter`. This builds a pydantic `TypeAdapter` for the union of all registered invocations, caching it after the first call.
- `Graph.nodes`'s type is widened to `dict[str, BaseInvocation]`. This actually is a nice bonus, because we get better type hints whenever we reference `some_graph.nodes`.
- A "plain" field validator takes over the validation logic for `Graph.nodes`. "Plain" validators totally override pydantic's own validation logic. The validator grabs the `TypeAdapter` from `BaseInvocation`, then validates each node with it. The validation is identical to the previous implementation - we get the same errors.

`BaseInvocationOutput` gets the same treatment.
2024-03-01 10:42:33 +11:00
..
custom_nodes fix: removed custom module 2024-03-01 10:42:33 +11:00
__init__.py resolve which paths can be None 2023-11-28 09:30:49 +11:00
baseinvocation.py feat(nodes): JIT graph nodes validation 2024-03-01 10:42:33 +11:00
collections.py fix(nodes): restore type annotations for InvocationContext 2024-03-01 10:42:33 +11:00
compel.py feat(nodes): JIT graph nodes validation 2024-03-01 10:42:33 +11:00
constants.py chore: ruff formatting 2024-03-01 10:42:33 +11:00
controlnet_image_processors.py one more redundant RGB convert removed 2024-03-01 10:42:33 +11:00
cv.py feat(nodes): add WithBoard field helper class 2024-03-01 10:42:33 +11:00
facetools.py feat(nodes): add WithBoard field helper class 2024-03-01 10:42:33 +11:00
fields.py fix(nodes): rearrange fields.py to avoid needing forward refs 2024-03-01 10:42:33 +11:00
image.py chore: ruff formatting 2024-03-01 10:42:33 +11:00
infill.py feat(nodes): add WithBoard field helper class 2024-03-01 10:42:33 +11:00
ip_adapter.py feat(nodes): update invocation context for mm2, update nodes model usage 2024-03-01 10:42:33 +11:00
latent.py Tidy names and locations of modules 2024-03-01 10:42:33 +11:00
math.py fix(nodes): restore type annotations for InvocationContext 2024-03-01 10:42:33 +11:00
metadata.py fix(nodes): restore type annotations for InvocationContext 2024-03-01 10:42:33 +11:00
model.py feat(nodes): update invocation context for mm2, update nodes model usage 2024-03-01 10:42:33 +11:00
noise.py feat(nodes): use LATENT_SCALE_FACTOR in primitives.py, noise.py 2024-03-01 10:42:33 +11:00
param_easing.py fix(nodes): restore type annotations for InvocationContext 2024-03-01 10:42:33 +11:00
primitives.py feat(nodes): use LATENT_SCALE_FACTOR in primitives.py, noise.py 2024-03-01 10:42:33 +11:00
prompt.py fix(nodes): restore type annotations for InvocationContext 2024-03-01 10:42:33 +11:00
sdxl.py feat(nodes): update invocation context for mm2, update nodes model usage 2024-03-01 10:42:33 +11:00
strings.py fix(nodes): restore type annotations for InvocationContext 2024-03-01 10:42:33 +11:00
t2i_adapter.py BREAKING CHANGES: invocations now require model key, not base/type/name 2024-03-01 10:42:33 +11:00
tiles.py feat(nodes): add WithBoard field helper class 2024-03-01 10:42:33 +11:00
upscale.py feat(nodes): add WithBoard field helper class 2024-03-01 10:42:33 +11:00
util.py fix(nodes): fix constraints/validation for controlnet 2024-01-02 07:28:53 -05:00