diff --git a/invokeai/app/invocations/baseinvocation.py b/invokeai/app/invocations/baseinvocation.py index cd689a510b..05d8d515ea 100644 --- a/invokeai/app/invocations/baseinvocation.py +++ b/invokeai/app/invocations/baseinvocation.py @@ -39,6 +39,19 @@ class InvalidFieldError(TypeError): pass +class Classification(str, Enum, metaclass=MetaEnum): + """ + The feature classification of an Invocation. + - `Stable`: The invocation, including its inputs/outputs and internal logic, is stable. You may build workflows with it, having confidence that they will not break because of a change in this invocation. + - `Beta`: The invocation is not yet stable, but is planned to be stable in the future. Workflows built around this invocation may break, but we are committed to supporting this invocation long-term. + - `Prototype`: The invocation is not yet stable and may be removed from the application at any time. Workflows built around this invocation may break, and we are *not* committed to supporting this invocation. + """ + + Stable = "stable" + Beta = "beta" + Prototype = "prototype" + + class Input(str, Enum, metaclass=MetaEnum): """ The type of input a field accepts. @@ -439,6 +452,7 @@ class UIConfigBase(BaseModel): description='The node\'s version. Should be a valid semver string e.g. "1.0.0" or "3.8.13".', ) node_pack: Optional[str] = Field(default=None, description="Whether or not this is a custom node") + classification: Classification = Field(default=Classification.Stable, description="The node's classification") model_config = ConfigDict( validate_assignment=True, @@ -607,6 +621,7 @@ class BaseInvocation(ABC, BaseModel): schema["category"] = uiconfig.category if uiconfig.node_pack is not None: schema["node_pack"] = uiconfig.node_pack + schema["classification"] = uiconfig.classification schema["version"] = uiconfig.version if "required" not in schema or not isinstance(schema["required"], list): schema["required"] = [] @@ -782,6 +797,7 @@ def invocation( category: Optional[str] = None, version: Optional[str] = None, use_cache: Optional[bool] = True, + classification: Classification = Classification.Stable, ) -> Callable[[Type[TBaseInvocation]], Type[TBaseInvocation]]: """ Registers an invocation. @@ -792,6 +808,7 @@ def invocation( :param Optional[str] category: Adds a category to the invocation. Used to group the invocations in the UI. Defaults to None. :param Optional[str] version: Adds a version to the invocation. Must be a valid semver string. Defaults to None. :param Optional[bool] use_cache: Whether or not to use the invocation cache. Defaults to True. The user may override this in the workflow editor. + :param FeatureClassification classification: The classification of the invocation. Defaults to FeatureClassification.Stable. Use Beta or Prototype if the invocation is unstable. """ def wrapper(cls: Type[TBaseInvocation]) -> Type[TBaseInvocation]: @@ -812,6 +829,7 @@ def invocation( cls.UIConfig.title = title cls.UIConfig.tags = tags cls.UIConfig.category = category + cls.UIConfig.classification = classification # Grab the node pack's name from the module name, if it's a custom node is_custom_node = cls.__module__.rsplit(".", 1)[0] == "invokeai.app.invocations" diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index c948311c29..ec257ee044 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -1032,7 +1032,9 @@ "workflowValidation": "Workflow Validation Error", "workflowVersion": "Version", "zoomInNodes": "Zoom In", - "zoomOutNodes": "Zoom Out" + "zoomOutNodes": "Zoom Out", + "betaDesc": "This invocation is in beta. Until it is stable, it may have breaking changes during app updates. We plan to support this invocation long-term.", + "prototypeDesc": "This invocation is a prototype. It may have breaking changes during app updates and may be removed at any time." }, "parameters": { "aspectRatio": "Aspect Ratio", diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeClassificationIcon.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeClassificationIcon.tsx new file mode 100644 index 0000000000..049d7d2072 --- /dev/null +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeClassificationIcon.tsx @@ -0,0 +1,68 @@ +import { Icon, Tooltip } from '@chakra-ui/react'; +import { memo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { FaFlask } from 'react-icons/fa'; +import { useNodeClassification } from 'features/nodes/hooks/useNodeClassification'; +import { Classification } from 'features/nodes/types/common'; +import { FaHammer } from 'react-icons/fa6'; + +interface Props { + nodeId: string; +} + +const InvocationNodeClassificationIcon = ({ nodeId }: Props) => { + const classification = useNodeClassification(nodeId); + + if (!classification || classification === 'stable') { + return null; + } + + return ( + } + placement="top" + shouldWrapChildren + > + + + ); +}; + +export default memo(InvocationNodeClassificationIcon); + +const ClassificationTooltipContent = memo( + ({ classification }: { classification: Classification }) => { + const { t } = useTranslation(); + + if (classification === 'beta') { + return t('nodes.betaDesc'); + } + + if (classification === 'prototype') { + return t('nodes.prototypeDesc'); + } + + return null; + } +); + +ClassificationTooltipContent.displayName = 'ClassificationTooltipContent'; + +const getIcon = (classification: Classification) => { + if (classification === 'beta') { + return FaHammer; + } + + if (classification === 'prototype') { + return FaFlask; + } + + return undefined; +}; diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeHeader.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeHeader.tsx index bd8c44770c..77496abb3a 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeHeader.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/InvocationNodeHeader.tsx @@ -5,6 +5,7 @@ import NodeTitle from 'features/nodes/components/flow/nodes/common/NodeTitle'; import InvocationNodeCollapsedHandles from './InvocationNodeCollapsedHandles'; import InvocationNodeInfoIcon from './InvocationNodeInfoIcon'; import InvocationNodeStatusIndicator from './InvocationNodeStatusIndicator'; +import InvocationNodeClassificationIcon from 'features/nodes/components/flow/nodes/Invocation/InvocationNodeClassificationIcon'; type Props = { nodeId: string; @@ -31,6 +32,7 @@ const InvocationNodeHeader = ({ nodeId, isOpen }: Props) => { }} > + diff --git a/invokeai/frontend/web/src/features/nodes/hooks/useNodeClassification.ts b/invokeai/frontend/web/src/features/nodes/hooks/useNodeClassification.ts new file mode 100644 index 0000000000..773f6de249 --- /dev/null +++ b/invokeai/frontend/web/src/features/nodes/hooks/useNodeClassification.ts @@ -0,0 +1,23 @@ +import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; +import { stateSelector } from 'app/store/store'; +import { useAppSelector } from 'app/store/storeHooks'; +import { isInvocationNode } from 'features/nodes/types/invocation'; +import { useMemo } from 'react'; + +export const useNodeClassification = (nodeId: string) => { + const selector = useMemo( + () => + createMemoizedSelector(stateSelector, ({ nodes }) => { + const node = nodes.nodes.find((node) => node.id === nodeId); + if (!isInvocationNode(node)) { + return false; + } + const nodeTemplate = nodes.nodeTemplates[node?.data.type ?? '']; + return nodeTemplate?.classification; + }), + [nodeId] + ); + + const title = useAppSelector(selector); + return title; +}; diff --git a/invokeai/frontend/web/src/features/nodes/types/common.ts b/invokeai/frontend/web/src/features/nodes/types/common.ts index 460b301685..4dcebf0fe4 100644 --- a/invokeai/frontend/web/src/features/nodes/types/common.ts +++ b/invokeai/frontend/web/src/features/nodes/types/common.ts @@ -19,6 +19,9 @@ export const zColorField = z.object({ }); export type ColorField = z.infer; +export const zClassification = z.enum(['stable', 'beta', 'prototype']); +export type Classification = z.infer; + export const zSchedulerField = z.enum([ 'euler', 'deis', diff --git a/invokeai/frontend/web/src/features/nodes/types/invocation.ts b/invokeai/frontend/web/src/features/nodes/types/invocation.ts index 9e9fdeb955..927245aef4 100644 --- a/invokeai/frontend/web/src/features/nodes/types/invocation.ts +++ b/invokeai/frontend/web/src/features/nodes/types/invocation.ts @@ -1,6 +1,6 @@ import { Edge, Node } from 'reactflow'; import { z } from 'zod'; -import { zProgressImage } from './common'; +import { zClassification, zProgressImage } from './common'; import { zFieldInputInstance, zFieldInputTemplate, @@ -21,6 +21,7 @@ export const zInvocationTemplate = z.object({ version: zSemVer, useCache: z.boolean(), nodePack: z.string().min(1).nullish(), + classification: zClassification, }); export type InvocationTemplate = z.infer; // #endregion diff --git a/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts b/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts index 9ad391d7c3..c2930c2187 100644 --- a/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts +++ b/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts @@ -83,6 +83,7 @@ export const parseSchema = ( const description = schema.description ?? ''; const version = schema.version; const nodePack = schema.node_pack; + const classification = schema.classification; const inputs = reduce( schema.properties, @@ -245,6 +246,7 @@ export const parseSchema = ( outputs, useCache, nodePack, + classification, }; Object.assign(invocationsAccumulator, { [type]: invocation }); diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index 5a99f39e4e..aaa37d6370 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -100,7 +100,10 @@ export type paths = { get: operations["get_model_record"]; /** * Del Model Record - * @description Delete Model + * @description Delete model record from database. + * + * The configuration record will be removed. The corresponding weights files will be + * deleted as well if they reside within the InvokeAI "models" directory. */ delete: operations["del_model_record"]; /** @@ -116,6 +119,86 @@ export type paths = { */ post: operations["add_model_record"]; }; + "/api/v1/model/record/import": { + /** + * List Model Install Jobs + * @description Return list of model install jobs. + * + * If the optional 'source' argument is provided, then the list will be filtered + * for partial string matches against the install source. + */ + get: operations["list_model_install_jobs"]; + /** + * Import Model + * @description Add a model using its local path, repo_id, or remote URL. + * + * Models will be downloaded, probed, configured and installed in a + * series of background threads. The return object has `status` attribute + * that can be used to monitor progress. + * + * The source object is a discriminated Union of LocalModelSource, + * HFModelSource and URLModelSource. Set the "type" field to the + * appropriate value: + * + * * To install a local path using LocalModelSource, pass a source of form: + * `{ + * "type": "local", + * "path": "/path/to/model", + * "inplace": false + * }` + * The "inplace" flag, if true, will register the model in place in its + * current filesystem location. Otherwise, the model will be copied + * into the InvokeAI models directory. + * + * * To install a HuggingFace repo_id using HFModelSource, pass a source of form: + * `{ + * "type": "hf", + * "repo_id": "stabilityai/stable-diffusion-2.0", + * "variant": "fp16", + * "subfolder": "vae", + * "access_token": "f5820a918aaf01" + * }` + * The `variant`, `subfolder` and `access_token` fields are optional. + * + * * To install a remote model using an arbitrary URL, pass: + * `{ + * "type": "url", + * "url": "http://www.civitai.com/models/123456", + * "access_token": "f5820a918aaf01" + * }` + * The `access_token` field is optonal + * + * The model's configuration record will be probed and filled in + * automatically. To override the default guesses, pass "metadata" + * with a Dict containing the attributes you wish to override. + * + * Installation occurs in the background. Either use list_model_install_jobs() + * to poll for completion, or listen on the event bus for the following events: + * + * "model_install_started" + * "model_install_completed" + * "model_install_error" + * + * On successful completion, the event's payload will contain the field "key" + * containing the installed ID of the model. On an error, the event's payload + * will contain the fields "error_type" and "error" describing the nature of the + * error and its traceback, respectively. + */ + post: operations["import_model_record"]; + /** + * Prune Model Install Jobs + * @description Prune all completed and errored jobs from the install job list. + */ + patch: operations["prune_model_install_jobs"]; + }; + "/api/v1/model/record/sync": { + /** + * Sync Models To Config + * @description Traverse the models and autoimport directories. Model files without a corresponding + * record in the database are added. Orphan records without a models file are deleted. + */ + patch: operations["sync_models_to_config"]; + }; "/api/v1/images/upload": { /** * Upload Image @@ -946,6 +1029,16 @@ export type components = { */ prediction_type?: ("v_prediction" | "epsilon" | "sample") | null; }; + /** Body_import_model_record */ + Body_import_model_record: { + /** Source */ + source: components["schemas"]["LocalModelSource"] | components["schemas"]["HFModelSource"] | components["schemas"]["URLModelSource"]; + /** + * Config + * @description Dict of fields that override auto-probed values in the model config record, such as name, description and prediction_type + */ + config?: Record | null; + }; /** Body_merge_models */ Body_merge_models: { /** @description Model configuration */ @@ -1247,6 +1340,65 @@ export type components = { */ type: "infill_cv2"; }; + /** + * Calculate Image Tiles Even Split + * @description Calculate the coordinates and overlaps of tiles that cover a target image shape. + */ + CalculateImageTilesEvenSplitInvocation: { + /** + * Id + * @description The id of this instance of an invocation. Must be unique among all instances of invocations. + */ + id: string; + /** + * Is Intermediate + * @description Whether or not this is an intermediate invocation. + * @default false + */ + is_intermediate?: boolean; + /** + * Use Cache + * @description Whether or not to use the cache + * @default true + */ + use_cache?: boolean; + /** + * Image Width + * @description The image width, in pixels, to calculate tiles for. + * @default 1024 + */ + image_width?: number; + /** + * Image Height + * @description The image height, in pixels, to calculate tiles for. + * @default 1024 + */ + image_height?: number; + /** + * Num Tiles X + * @description Number of tiles to divide image into on the x axis + * @default 2 + */ + num_tiles_x?: number; + /** + * Num Tiles Y + * @description Number of tiles to divide image into on the y axis + * @default 2 + */ + num_tiles_y?: number; + /** + * Overlap Fraction + * @description Overlap between adjacent tiles as a fraction of the tile's dimensions (0-1) + * @default 0.25 + */ + overlap_fraction?: number; + /** + * type + * @default calculate_image_tiles_even_split + * @constant + */ + type: "calculate_image_tiles_even_split"; + }; /** * Calculate Image Tiles * @description Calculate the coordinates and overlaps of tiles that cover a target image shape. @@ -1306,6 +1458,65 @@ export type components = { */ type: "calculate_image_tiles"; }; + /** + * Calculate Image Tiles Minimum Overlap + * @description Calculate the coordinates and overlaps of tiles that cover a target image shape. + */ + CalculateImageTilesMinimumOverlapInvocation: { + /** + * Id + * @description The id of this instance of an invocation. Must be unique among all instances of invocations. + */ + id: string; + /** + * Is Intermediate + * @description Whether or not this is an intermediate invocation. + * @default false + */ + is_intermediate?: boolean; + /** + * Use Cache + * @description Whether or not to use the cache + * @default true + */ + use_cache?: boolean; + /** + * Image Width + * @description The image width, in pixels, to calculate tiles for. + * @default 1024 + */ + image_width?: number; + /** + * Image Height + * @description The image height, in pixels, to calculate tiles for. + * @default 1024 + */ + image_height?: number; + /** + * Tile Width + * @description The tile width, in pixels. + * @default 576 + */ + tile_width?: number; + /** + * Tile Height + * @description The tile height, in pixels. + * @default 576 + */ + tile_height?: number; + /** + * Min Overlap + * @description Minimum overlap between adjacent tiles, in pixels. + * @default 128 + */ + min_overlap?: number; + /** + * type + * @default calculate_image_tiles_min_overlap + * @constant + */ + type: "calculate_image_tiles_min_overlap"; + }; /** CalculateImageTilesOutput */ CalculateImageTilesOutput: { /** @@ -3509,7 +3720,7 @@ export type components = { * @description The nodes in this graph */ nodes?: { - [key: string]: components["schemas"]["SchedulerInvocation"] | components["schemas"]["ColorMapImageProcessorInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["LinearUIOutputInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["MaskCombineInvocation"]; + [key: string]: components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ColorMapImageProcessorInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LinearUIOutputInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"]; }; /** * Edges @@ -3546,7 +3757,7 @@ export type components = { * @description The results of node executions */ results: { - [key: string]: components["schemas"]["ModelLoaderOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["String2Output"] | components["schemas"]["ColorOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["TileToPropertiesOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["PairTileImageOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["CalculateImageTilesOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["ConditioningCollectionOutput"]; + [key: string]: components["schemas"]["ImageOutput"] | components["schemas"]["PairTileImageOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["TileToPropertiesOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["CalculateImageTilesOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["String2Output"]; }; /** * Errors @@ -3610,6 +3821,26 @@ export type components = { */ type: "graph_output"; }; + /** + * HFModelSource + * @description A HuggingFace repo_id, with optional variant and sub-folder. + */ + HFModelSource: { + /** Repo Id */ + repo_id: string; + /** Variant */ + variant?: string | null; + /** Subfolder */ + subfolder?: string | null; + /** Access Token */ + access_token?: string | null; + /** + * Type + * @default hf + * @constant + */ + type?: "hf"; + }; /** HTTPValidationError */ HTTPValidationError: { /** Detail */ @@ -4992,6 +5223,12 @@ export type components = { */ type: "infill_tile"; }; + /** + * InstallStatus + * @description State of an install job running in the background. + * @enum {string} + */ + InstallStatus: "waiting" | "running" | "completed" | "error"; /** * Integer Collection Primitive * @description A collection of integer primitive values @@ -5731,6 +5968,25 @@ export type components = { * @enum {string} */ LoRAModelFormat: "lycoris" | "diffusers"; + /** + * LocalModelSource + * @description A local file or directory path. + */ + LocalModelSource: { + /** Path */ + path: string; + /** + * Inplace + * @default false + */ + inplace?: boolean | null; + /** + * Type + * @default local + * @constant + */ + type?: "local"; + }; /** * LogLevel * @enum {integer} @@ -6267,9 +6523,17 @@ export type components = { * @description A list of tile images with tile properties. */ tiles_with_images?: components["schemas"]["TileWithImage"][]; + /** + * Blend Mode + * @description blending type Linear or Seam + * @default Seam + * @enum {string} + */ + blend_mode?: "Linear" | "Seam"; /** * Blend Amount * @description The amount to blend adjacent tiles in pixels. Must be <= the amount of overlap between adjacent tiles. + * @default 32 */ blend_amount?: number; /** @@ -6517,6 +6781,54 @@ export type components = { /** @description Info to load submodel */ submodel?: components["schemas"]["SubModelType"] | null; }; + /** + * ModelInstallJob + * @description Object that tracks the current status of an install request. + */ + ModelInstallJob: { + /** + * @description Current status of install process + * @default waiting + */ + status?: components["schemas"]["InstallStatus"]; + /** + * Config In + * @description Configuration information (e.g. 'description') to apply to model. + */ + config_in?: Record; + /** + * Config Out + * @description After successful installation, this will hold the configuration object. + */ + config_out?: (components["schemas"]["MainDiffusersConfig"] | components["schemas"]["MainCheckpointConfig"]) | (components["schemas"]["ONNXSD1Config"] | components["schemas"]["ONNXSD2Config"]) | (components["schemas"]["VaeDiffusersConfig"] | components["schemas"]["VaeCheckpointConfig"]) | (components["schemas"]["ControlNetDiffusersConfig"] | components["schemas"]["ControlNetCheckpointConfig"]) | components["schemas"]["LoRAConfig"] | components["schemas"]["TextualInversionConfig"] | components["schemas"]["IPAdapterConfig"] | components["schemas"]["CLIPVisionDiffusersConfig"] | components["schemas"]["T2IConfig"] | null; + /** + * Inplace + * @description Leave model in its current location; otherwise install under models directory + * @default false + */ + inplace?: boolean; + /** + * Source + * @description Source (URL, repo_id, or local path) of model + */ + source: components["schemas"]["LocalModelSource"] | components["schemas"]["HFModelSource"] | components["schemas"]["URLModelSource"]; + /** + * Local Path + * Format: path + * @description Path to locally-downloaded model; may be the same as the source + */ + local_path: string; + /** + * Error Type + * @description Class name of the exception that led to status==ERROR + */ + error_type?: string | null; + /** + * Error + * @description Error traceback + */ + error?: string | null; + }; /** * ModelLoaderOutput * @description Model loader output @@ -9687,6 +9999,25 @@ export type components = { */ type: "unet_output"; }; + /** + * URLModelSource + * @description A generic URL point to a checkpoint file. + */ + URLModelSource: { + /** + * Url + * Format: uri + */ + url: string; + /** Access Token */ + access_token?: string | null; + /** + * Type + * @default generic_url + * @constant + */ + type?: "generic_url"; + }; /** Upscaler */ Upscaler: { /** @@ -10200,6 +10531,15 @@ export type components = { * @enum {string} */ invokeai__backend__model_manager__config__SchedulerPredictionType: "epsilon" | "v_prediction" | "sample"; + /** + * Classification + * @description The feature classification of an Invocation. + * - `Stable`: The invocation, including its inputs/outputs and internal logic, is stable. You may build workflows with it, having confidence that they will not break because of a change in this invocation. + * - `Beta`: The invocation is not yet stable, but is planned to be stable in the future. Workflows built around this invocation may break, but we are committed to supporting this invocation long-term. + * - `Prototype`: The invocation is not yet stable and may be removed from the application at any time. Workflows built around this invocation may break, and we are *not* committed to supporting this invocation. + * @enum {string} + */ + Classification: "stable" | "beta" | "prototype"; /** * FieldKind * @description The kind of field. @@ -10323,6 +10663,11 @@ export type components = { * @default null */ node_pack: string | null; + /** + * @description The node's classification + * @default stable + */ + classification: components["schemas"]["Classification"]; }; /** * UIType @@ -10352,54 +10697,54 @@ export type components = { * @enum {string} */ UIType: "SDXLMainModelField" | "SDXLRefinerModelField" | "ONNXModelField" | "VAEModelField" | "LoRAModelField" | "ControlNetModelField" | "IPAdapterModelField" | "SchedulerField" | "AnyField" | "CollectionField" | "CollectionItemField" | "DEPRECATED_Boolean" | "DEPRECATED_Color" | "DEPRECATED_Conditioning" | "DEPRECATED_Control" | "DEPRECATED_Float" | "DEPRECATED_Image" | "DEPRECATED_Integer" | "DEPRECATED_Latents" | "DEPRECATED_String" | "DEPRECATED_BooleanCollection" | "DEPRECATED_ColorCollection" | "DEPRECATED_ConditioningCollection" | "DEPRECATED_ControlCollection" | "DEPRECATED_FloatCollection" | "DEPRECATED_ImageCollection" | "DEPRECATED_IntegerCollection" | "DEPRECATED_LatentsCollection" | "DEPRECATED_StringCollection" | "DEPRECATED_BooleanPolymorphic" | "DEPRECATED_ColorPolymorphic" | "DEPRECATED_ConditioningPolymorphic" | "DEPRECATED_ControlPolymorphic" | "DEPRECATED_FloatPolymorphic" | "DEPRECATED_ImagePolymorphic" | "DEPRECATED_IntegerPolymorphic" | "DEPRECATED_LatentsPolymorphic" | "DEPRECATED_StringPolymorphic" | "DEPRECATED_MainModel" | "DEPRECATED_UNet" | "DEPRECATED_Vae" | "DEPRECATED_CLIP" | "DEPRECATED_Collection" | "DEPRECATED_CollectionItem" | "DEPRECATED_Enum" | "DEPRECATED_WorkflowField" | "DEPRECATED_IsIntermediate" | "DEPRECATED_BoardField" | "DEPRECATED_MetadataItem" | "DEPRECATED_MetadataItemCollection" | "DEPRECATED_MetadataItemPolymorphic" | "DEPRECATED_MetadataDict"; - /** - * StableDiffusionOnnxModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusionOnnxModelFormat: "olive" | "onnx"; - /** - * T2IAdapterModelFormat - * @description An enumeration. - * @enum {string} - */ - T2IAdapterModelFormat: "diffusers"; /** * StableDiffusion2ModelFormat * @description An enumeration. * @enum {string} */ StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; - /** - * StableDiffusion1ModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; - /** - * CLIPVisionModelFormat - * @description An enumeration. - * @enum {string} - */ - CLIPVisionModelFormat: "diffusers"; - /** - * IPAdapterModelFormat - * @description An enumeration. - * @enum {string} - */ - IPAdapterModelFormat: "invokeai"; /** * StableDiffusionXLModelFormat * @description An enumeration. * @enum {string} */ StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; + /** + * StableDiffusionOnnxModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusionOnnxModelFormat: "olive" | "onnx"; + /** + * IPAdapterModelFormat + * @description An enumeration. + * @enum {string} + */ + IPAdapterModelFormat: "invokeai"; + /** + * CLIPVisionModelFormat + * @description An enumeration. + * @enum {string} + */ + CLIPVisionModelFormat: "diffusers"; + /** + * StableDiffusion1ModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; /** * ControlNetModelFormat * @description An enumeration. * @enum {string} */ ControlNetModelFormat: "checkpoint" | "diffusers"; + /** + * T2IAdapterModelFormat + * @description An enumeration. + * @enum {string} + */ + T2IAdapterModelFormat: "diffusers"; }; responses: never; parameters: never; @@ -10802,6 +11147,8 @@ export type operations = { base_models?: components["schemas"]["invokeai__backend__model_manager__config__BaseModelType"][] | null; /** @description The type of model to get */ model_type?: components["schemas"]["invokeai__backend__model_manager__config__ModelType"] | null; + /** @description Exact match on the name of the model */ + model_name?: string | null; }; }; responses: { @@ -10855,7 +11202,10 @@ export type operations = { }; /** * Del Model Record - * @description Delete Model + * @description Delete model record from database. + * + * The configuration record will be removed. The corresponding weights files will be + * deleted as well if they reside within the InvokeAI "models" directory. */ del_model_record: { parameters: { @@ -10957,6 +11307,157 @@ export type operations = { }; }; }; + /** + * List Model Install Jobs + * @description Return list of model install jobs. + * + * If the optional 'source' argument is provided, then the list will be filtered + * for partial string matches against the install source. + */ + list_model_install_jobs: { + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["ModelInstallJob"][]; + }; + }; + }; + }; + /** + * Import Model + * @description Add a model using its local path, repo_id, or remote URL. + * + * Models will be downloaded, probed, configured and installed in a + * series of background threads. The return object has `status` attribute + * that can be used to monitor progress. + * + * The source object is a discriminated Union of LocalModelSource, + * HFModelSource and URLModelSource. Set the "type" field to the + * appropriate value: + * + * * To install a local path using LocalModelSource, pass a source of form: + * `{ + * "type": "local", + * "path": "/path/to/model", + * "inplace": false + * }` + * The "inplace" flag, if true, will register the model in place in its + * current filesystem location. Otherwise, the model will be copied + * into the InvokeAI models directory. + * + * * To install a HuggingFace repo_id using HFModelSource, pass a source of form: + * `{ + * "type": "hf", + * "repo_id": "stabilityai/stable-diffusion-2.0", + * "variant": "fp16", + * "subfolder": "vae", + * "access_token": "f5820a918aaf01" + * }` + * The `variant`, `subfolder` and `access_token` fields are optional. + * + * * To install a remote model using an arbitrary URL, pass: + * `{ + * "type": "url", + * "url": "http://www.civitai.com/models/123456", + * "access_token": "f5820a918aaf01" + * }` + * The `access_token` field is optonal + * + * The model's configuration record will be probed and filled in + * automatically. To override the default guesses, pass "metadata" + * with a Dict containing the attributes you wish to override. + * + * Installation occurs in the background. Either use list_model_install_jobs() + * to poll for completion, or listen on the event bus for the following events: + * + * "model_install_started" + * "model_install_completed" + * "model_install_error" + * + * On successful completion, the event's payload will contain the field "key" + * containing the installed ID of the model. On an error, the event's payload + * will contain the fields "error_type" and "error" describing the nature of the + * error and its traceback, respectively. + */ + import_model_record: { + requestBody: { + content: { + "application/json": components["schemas"]["Body_import_model_record"]; + }; + }; + responses: { + /** @description The model imported successfully */ + 201: { + content: { + "application/json": components["schemas"]["ModelInstallJob"]; + }; + }; + /** @description There is already a model corresponding to this path or repo_id */ + 409: { + content: never; + }; + /** @description Unrecognized file/folder format */ + 415: { + content: never; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + /** @description The model appeared to import successfully, but could not be found in the model manager */ + 424: { + content: never; + }; + }; + }; + /** + * Prune Model Install Jobs + * @description Prune all completed and errored jobs from the install job list. + */ + prune_model_install_jobs: { + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": unknown; + }; + }; + /** @description All completed and errored jobs have been pruned */ + 204: { + content: never; + }; + /** @description Bad request */ + 400: { + content: never; + }; + }; + }; + /** + * Sync Models To Config + * @description Traverse the models and autoimport directories. Model files without a corresponding + * record in the database are added. Orphan records without a models file are deleted. + */ + sync_models_to_config: { + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": unknown; + }; + }; + /** @description Model config record database resynced with files on disk */ + 204: { + content: never; + }; + /** @description Bad request */ + 400: { + content: never; + }; + }; + }; /** * Upload Image * @description Uploads an image