From cc747c066c67c8ea5c7f03519ef939e7e717e18d Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Thu, 16 Nov 2023 18:47:31 +1100 Subject: [PATCH 1/2] fix(nodes): fix hrf_enabled metadata item It was a float but should be a bool --- invokeai/app/invocations/metadata.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/invokeai/app/invocations/metadata.py b/invokeai/app/invocations/metadata.py index ed8a091f8d..d837e6297f 100644 --- a/invokeai/app/invocations/metadata.py +++ b/invokeai/app/invocations/metadata.py @@ -112,7 +112,7 @@ GENERATION_MODES = Literal[ ] -@invocation("core_metadata", title="Core Metadata", tags=["metadata"], category="metadata", version="1.0.0") +@invocation("core_metadata", title="Core Metadata", tags=["metadata"], category="metadata", version="1.0.1") class CoreMetadataInvocation(BaseInvocation): """Collects core generation metadata into a MetadataField""" @@ -160,7 +160,7 @@ class CoreMetadataInvocation(BaseInvocation): ) # High resolution fix metadata. - hrf_enabled: Optional[float] = InputField( + hrf_enabled: Optional[bool] = InputField( default=None, description="Whether or not high resolution fix was enabled.", ) From 4599517c6c309d71cd32a535076c2e12c585d75f Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Thu, 16 Nov 2023 18:56:27 +1100 Subject: [PATCH 2/2] feat: add private node for linear UI image outputting Add a LinearUIOutputInvocation node to be the new terminal node for Linear UI graphs. This node is private and hidden from the Workflow Editor, as it is an implementation detail. The Linear UI was using the Save Image node for this purpose. It allowed every linear graph to end a single node type, which handled saving metadata and board. This substantially reduced the complexity of the linear graphs. This caused two related issues: - Images were saved to disk twice - Noticeable delay between when an image was decoded and showed up in the UI To resolve this, the new LinearUIOutputInvocation node will handle adding an image to a board if one is provided. Metadata is no longer provided in this unified node. Instead, the metadata graph helpers now need to know the node to add metadata to and provide it to the last node that actually outputs an image. This is a `l2i` node for txt2img & img2img graphs, and a different image-outputting node for canvas graphs. HRF poses another complication, in that it changes the terminal node. To handle this, a new metadata util is added called `setMetadataReceivingNode()`. HRF calls this to change the node that should receive the graph's metadata. This resolves the duplicate images issue and improves perf without otherwise changing the user experience. --- invokeai/app/invocations/image.py | 31 +++++- .../listeners/controlNetImageProcessed.ts | 23 +---- .../ImageMetadataActions.tsx | 2 + .../nodes/util/graphBuilders/addHrfToGraph.ts | 3 +- ...eImageNode.ts => addLinearUIOutputNode.ts} | 16 ++-- .../graphBuilders/buildAdHocUpscaleGraph.ts | 16 ++-- .../buildCanvasImageToImageGraph.ts | 46 +++++---- .../graphBuilders/buildCanvasInpaintGraph.ts | 4 +- .../graphBuilders/buildCanvasOutpaintGraph.ts | 4 +- .../buildCanvasSDXLImageToImageGraph.ts | 44 +++++---- .../buildCanvasSDXLInpaintGraph.ts | 4 +- .../buildCanvasSDXLOutpaintGraph.ts | 4 +- .../buildCanvasSDXLTextToImageGraph.ts | 40 ++++---- .../buildCanvasTextToImageGraph.ts | 42 ++++---- .../buildLinearImageToImageGraph.ts | 40 ++++---- .../buildLinearSDXLImageToImageGraph.ts | 42 ++++---- .../buildLinearSDXLTextToImageGraph.ts | 38 ++++---- .../buildLinearTextToImageGraph.ts | 36 +++---- .../nodes/util/graphBuilders/constants.ts | 2 +- .../nodes/util/graphBuilders/metadata.ts | 25 ++++- .../src/features/nodes/util/parseSchema.ts | 2 +- .../frontend/web/src/services/api/schema.d.ts | 95 +++++++++++++------ .../frontend/web/src/services/api/types.ts | 2 +- 23 files changed, 336 insertions(+), 225 deletions(-) rename invokeai/frontend/web/src/features/nodes/util/graphBuilders/{addSaveImageNode.ts => addLinearUIOutputNode.ts} (84%) diff --git a/invokeai/app/invocations/image.py b/invokeai/app/invocations/image.py index 1e0adbd37a..fb59fdf7fd 100644 --- a/invokeai/app/invocations/image.py +++ b/invokeai/app/invocations/image.py @@ -8,7 +8,7 @@ import numpy from PIL import Image, ImageChops, ImageFilter, ImageOps from invokeai.app.invocations.primitives import BoardField, ColorField, ImageField, ImageOutput -from invokeai.app.services.image_records.image_records_common import ImageCategory, ResourceOrigin +from invokeai.app.services.image_records.image_records_common import ImageCategory, ImageRecordChanges, ResourceOrigin from invokeai.app.shared.fields import FieldDescriptions from invokeai.backend.image_util.invisible_watermark import InvisibleWatermark from invokeai.backend.image_util.safety_checker import SafetyChecker @@ -1017,3 +1017,32 @@ class SaveImageInvocation(BaseInvocation, WithWorkflow, WithMetadata): width=image_dto.width, height=image_dto.height, ) + + +@invocation( + "linear_ui_output", + title="Linear UI Image Output", + tags=["primitives", "image"], + category="primitives", + version="1.0.0", + use_cache=False, +) +class LinearUIOutputInvocation(BaseInvocation, WithWorkflow, WithMetadata): + """Handles Linear UI Image Outputting tasks.""" + + image: ImageField = InputField(description=FieldDescriptions.image) + board: Optional[BoardField] = InputField(default=None, description=FieldDescriptions.board, input=Input.Direct) + + def invoke(self, context: InvocationContext) -> ImageOutput: + image_dto = context.services.images.get_dto(self.image.image_name) + + if self.board: + context.services.board_images.add_image_to_board(self.board.board_id, self.image.image_name) + + context.services.images.update(self.image.image_name, changes=ImageRecordChanges(is_intermediate=False)) + + return ImageOutput( + image=ImageField(image_name=self.image.image_name), + width=image_dto.width, + height=image_dto.height, + ) diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts index a454e5ca48..1996ec99a5 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts @@ -8,7 +8,6 @@ import { selectControlAdapterById, } from 'features/controlAdapters/store/controlAdaptersSlice'; import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types'; -import { SAVE_IMAGE } from 'features/nodes/util/graphBuilders/constants'; import { addToast } from 'features/system/store/systemSlice'; import { t } from 'i18next'; import { imagesApi } from 'services/api/endpoints/images'; @@ -38,6 +37,7 @@ export const addControlNetImageProcessedListener = () => { // ControlNet one-off procressing graph is just the processor node, no edges. // Also we need to grab the image. + const nodeId = ca.processorNode.id; const enqueueBatchArg: BatchConfig = { prepend: true, batch: { @@ -46,27 +46,10 @@ export const addControlNetImageProcessedListener = () => { [ca.processorNode.id]: { ...ca.processorNode, is_intermediate: true, + use_cache: false, image: { image_name: ca.controlImage }, }, - [SAVE_IMAGE]: { - id: SAVE_IMAGE, - type: 'save_image', - is_intermediate: true, - use_cache: false, - }, }, - edges: [ - { - source: { - node_id: ca.processorNode.id, - field: 'image', - }, - destination: { - node_id: SAVE_IMAGE, - field: 'image', - }, - }, - ], }, runs: 1, }, @@ -90,7 +73,7 @@ export const addControlNetImageProcessedListener = () => { socketInvocationComplete.match(action) && action.payload.data.queue_batch_id === enqueueResult.batch.batch_id && - action.payload.data.source_node_id === SAVE_IMAGE + action.payload.data.source_node_id === nodeId ); // We still have to check the output type diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx index 9053ce973d..ce5b178fa2 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx @@ -157,6 +157,8 @@ const ImageMetadataActions = (props: Props) => { return null; } + console.log(metadata); + return ( <> {metadata.created_by && ( diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addHrfToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addHrfToGraph.ts index d1df9bb9c2..9825ce754e 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addHrfToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addHrfToGraph.ts @@ -23,7 +23,7 @@ import { RESIZE_HRF, VAE_LOADER, } from './constants'; -import { upsertMetadata } from './metadata'; +import { setMetadataReceivingNode, upsertMetadata } from './metadata'; // Copy certain connections from previous DENOISE_LATENTS to new DENOISE_LATENTS_HRF. function copyConnectionsToDenoiseLatentsHrf(graph: NonNullableGraph): void { @@ -369,4 +369,5 @@ export const addHrfToGraph = ( hrf_enabled: hrfEnabled, hrf_method: hrfMethod, }); + setMetadataReceivingNode(graph, LATENTS_TO_IMAGE_HRF_HR); }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSaveImageNode.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addLinearUIOutputNode.ts similarity index 84% rename from invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSaveImageNode.ts rename to invokeai/frontend/web/src/features/nodes/util/graphBuilders/addLinearUIOutputNode.ts index 171bd37de8..926fa3a8f3 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSaveImageNode.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addLinearUIOutputNode.ts @@ -1,20 +1,20 @@ import { RootState } from 'app/store/store'; import { NonNullableGraph } from 'features/nodes/types/types'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; -import { SaveImageInvocation } from 'services/api/types'; +import { LinearUIOutputInvocation } from 'services/api/types'; import { CANVAS_OUTPUT, LATENTS_TO_IMAGE, LATENTS_TO_IMAGE_HRF_HR, + LINEAR_UI_OUTPUT, NSFW_CHECKER, - SAVE_IMAGE, WATERMARKER, } from './constants'; /** * Set the `use_cache` field on the linear/canvas graph's final image output node to False. */ -export const addSaveImageNode = ( +export const addLinearUIOutputNode = ( state: RootState, graph: NonNullableGraph ): void => { @@ -23,18 +23,18 @@ export const addSaveImageNode = ( activeTabName === 'unifiedCanvas' ? !state.canvas.shouldAutoSave : false; const { autoAddBoardId } = state.gallery; - const saveImageNode: SaveImageInvocation = { - id: SAVE_IMAGE, - type: 'save_image', + const linearUIOutputNode: LinearUIOutputInvocation = { + id: LINEAR_UI_OUTPUT, + type: 'linear_ui_output', is_intermediate, use_cache: false, board: autoAddBoardId === 'none' ? undefined : { board_id: autoAddBoardId }, }; - graph.nodes[SAVE_IMAGE] = saveImageNode; + graph.nodes[LINEAR_UI_OUTPUT] = linearUIOutputNode; const destination = { - node_id: SAVE_IMAGE, + node_id: LINEAR_UI_OUTPUT, field: 'image', }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildAdHocUpscaleGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildAdHocUpscaleGraph.ts index 5af8edbdfc..73551202b8 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildAdHocUpscaleGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildAdHocUpscaleGraph.ts @@ -4,9 +4,9 @@ import { ESRGANModelName } from 'features/parameters/store/postprocessingSlice'; import { ESRGANInvocation, Graph, - SaveImageInvocation, + LinearUIOutputInvocation, } from 'services/api/types'; -import { REALESRGAN as ESRGAN, SAVE_IMAGE } from './constants'; +import { REALESRGAN as ESRGAN, LINEAR_UI_OUTPUT } from './constants'; import { addCoreMetadataNode, upsertMetadata } from './metadata'; type Arg = { @@ -28,9 +28,9 @@ export const buildAdHocUpscaleGraph = ({ is_intermediate: true, }; - const saveImageNode: SaveImageInvocation = { - id: SAVE_IMAGE, - type: 'save_image', + const linearUIOutputNode: LinearUIOutputInvocation = { + id: LINEAR_UI_OUTPUT, + type: 'linear_ui_output', use_cache: false, is_intermediate: false, board: autoAddBoardId === 'none' ? undefined : { board_id: autoAddBoardId }, @@ -40,7 +40,7 @@ export const buildAdHocUpscaleGraph = ({ id: `adhoc-esrgan-graph`, nodes: { [ESRGAN]: realesrganNode, - [SAVE_IMAGE]: saveImageNode, + [LINEAR_UI_OUTPUT]: linearUIOutputNode, }, edges: [ { @@ -49,14 +49,14 @@ export const buildAdHocUpscaleGraph = ({ field: 'image', }, destination: { - node_id: SAVE_IMAGE, + node_id: LINEAR_UI_OUTPUT, field: 'image', }, }, ], }; - addCoreMetadataNode(graph, {}); + addCoreMetadataNode(graph, {}, ESRGAN); upsertMetadata(graph, { esrgan_model: esrganModelName, }); diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts index 9d957c3a4a..a86fdb4ce6 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts @@ -6,7 +6,7 @@ import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addLoRAsToGraph } from './addLoRAsToGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -308,24 +308,30 @@ export const buildCanvasImageToImageGraph = ( }); } - addCoreMetadataNode(graph, { - generation_mode: 'img2img', - cfg_scale, - width: !isUsingScaledDimensions ? width : scaledBoundingBoxDimensions.width, - height: !isUsingScaledDimensions - ? height - : scaledBoundingBoxDimensions.height, - positive_prompt: positivePrompt, - negative_prompt: negativePrompt, - model, - seed, - steps, - rand_device: use_cpu ? 'cpu' : 'cuda', - scheduler, - clip_skip: clipSkip, - strength, - init_image: initialImage.image_name, - }); + addCoreMetadataNode( + graph, + { + generation_mode: 'img2img', + cfg_scale, + width: !isUsingScaledDimensions + ? width + : scaledBoundingBoxDimensions.width, + height: !isUsingScaledDimensions + ? height + : scaledBoundingBoxDimensions.height, + positive_prompt: positivePrompt, + negative_prompt: negativePrompt, + model, + seed, + steps, + rand_device: use_cpu ? 'cpu' : 'cuda', + scheduler, + clip_skip: clipSkip, + strength, + init_image: initialImage.image_name, + }, + CANVAS_OUTPUT + ); // Add Seamless To Graph if (seamlessXAxis || seamlessYAxis) { @@ -357,7 +363,7 @@ export const buildCanvasImageToImageGraph = ( addWatermarkerToGraph(state, graph, CANVAS_OUTPUT); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts index c786bad017..48052e2a94 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts @@ -13,7 +13,7 @@ import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addLoRAsToGraph } from './addLoRAsToGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -666,7 +666,7 @@ export const buildCanvasInpaintGraph = ( addWatermarkerToGraph(state, graph, CANVAS_OUTPUT); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts index e7e27fabfa..31cf5ca7e8 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts @@ -12,7 +12,7 @@ import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addLoRAsToGraph } from './addLoRAsToGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -770,7 +770,7 @@ export const buildCanvasOutpaintGraph = ( addWatermarkerToGraph(state, graph, CANVAS_OUTPUT); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLImageToImageGraph.ts index c1ecde5395..8281c9c248 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLImageToImageGraph.ts @@ -7,7 +7,7 @@ import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; import { addSDXLLoRAsToGraph } from './addSDXLLoRAstoGraph'; import { addSDXLRefinerToGraph } from './addSDXLRefinerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; import { addWatermarkerToGraph } from './addWatermarkerToGraph'; @@ -319,23 +319,29 @@ export const buildCanvasSDXLImageToImageGraph = ( }); } - addCoreMetadataNode(graph, { - generation_mode: 'img2img', - cfg_scale, - width: !isUsingScaledDimensions ? width : scaledBoundingBoxDimensions.width, - height: !isUsingScaledDimensions - ? height - : scaledBoundingBoxDimensions.height, - positive_prompt: positivePrompt, - negative_prompt: negativePrompt, - model, - seed, - steps, - rand_device: use_cpu ? 'cpu' : 'cuda', - scheduler, - strength, - init_image: initialImage.image_name, - }); + addCoreMetadataNode( + graph, + { + generation_mode: 'img2img', + cfg_scale, + width: !isUsingScaledDimensions + ? width + : scaledBoundingBoxDimensions.width, + height: !isUsingScaledDimensions + ? height + : scaledBoundingBoxDimensions.height, + positive_prompt: positivePrompt, + negative_prompt: negativePrompt, + model, + seed, + steps, + rand_device: use_cpu ? 'cpu' : 'cuda', + scheduler, + strength, + init_image: initialImage.image_name, + }, + CANVAS_OUTPUT + ); // Add Seamless To Graph if (seamlessXAxis || seamlessYAxis) { @@ -380,7 +386,7 @@ export const buildCanvasSDXLImageToImageGraph = ( addWatermarkerToGraph(state, graph, CANVAS_OUTPUT); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts index f302c4c62f..40626e289a 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts @@ -14,7 +14,7 @@ import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; import { addSDXLLoRAsToGraph } from './addSDXLLoRAstoGraph'; import { addSDXLRefinerToGraph } from './addSDXLRefinerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -696,7 +696,7 @@ export const buildCanvasSDXLInpaintGraph = ( addWatermarkerToGraph(state, graph, CANVAS_OUTPUT); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts index 501417b00d..c7302cd56d 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts @@ -13,7 +13,7 @@ import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; import { addSDXLLoRAsToGraph } from './addSDXLLoRAstoGraph'; import { addSDXLRefinerToGraph } from './addSDXLRefinerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -799,7 +799,7 @@ export const buildCanvasSDXLOutpaintGraph = ( addWatermarkerToGraph(state, graph, CANVAS_OUTPUT); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLTextToImageGraph.ts index e43891eba4..2a712f2ef3 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLTextToImageGraph.ts @@ -10,7 +10,7 @@ import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; import { addSDXLLoRAsToGraph } from './addSDXLLoRAstoGraph'; import { addSDXLRefinerToGraph } from './addSDXLRefinerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -301,21 +301,27 @@ export const buildCanvasSDXLTextToImageGraph = ( }); } - addCoreMetadataNode(graph, { - generation_mode: 'txt2img', - cfg_scale, - width: !isUsingScaledDimensions ? width : scaledBoundingBoxDimensions.width, - height: !isUsingScaledDimensions - ? height - : scaledBoundingBoxDimensions.height, - positive_prompt: positivePrompt, - negative_prompt: negativePrompt, - model, - seed, - steps, - rand_device: use_cpu ? 'cpu' : 'cuda', - scheduler, - }); + addCoreMetadataNode( + graph, + { + generation_mode: 'txt2img', + cfg_scale, + width: !isUsingScaledDimensions + ? width + : scaledBoundingBoxDimensions.width, + height: !isUsingScaledDimensions + ? height + : scaledBoundingBoxDimensions.height, + positive_prompt: positivePrompt, + negative_prompt: negativePrompt, + model, + seed, + steps, + rand_device: use_cpu ? 'cpu' : 'cuda', + scheduler, + }, + CANVAS_OUTPUT + ); // Add Seamless To Graph if (seamlessXAxis || seamlessYAxis) { @@ -360,7 +366,7 @@ export const buildCanvasSDXLTextToImageGraph = ( addWatermarkerToGraph(state, graph, CANVAS_OUTPUT); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts index 6e48c14086..5c0c91ca71 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts @@ -9,7 +9,7 @@ import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addLoRAsToGraph } from './addLoRAsToGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -289,22 +289,28 @@ export const buildCanvasTextToImageGraph = ( }); } - addCoreMetadataNode(graph, { - generation_mode: 'txt2img', - cfg_scale, - width: !isUsingScaledDimensions ? width : scaledBoundingBoxDimensions.width, - height: !isUsingScaledDimensions - ? height - : scaledBoundingBoxDimensions.height, - positive_prompt: positivePrompt, - negative_prompt: negativePrompt, - model, - seed, - steps, - rand_device: use_cpu ? 'cpu' : 'cuda', - scheduler, - clip_skip: clipSkip, - }); + addCoreMetadataNode( + graph, + { + generation_mode: 'txt2img', + cfg_scale, + width: !isUsingScaledDimensions + ? width + : scaledBoundingBoxDimensions.width, + height: !isUsingScaledDimensions + ? height + : scaledBoundingBoxDimensions.height, + positive_prompt: positivePrompt, + negative_prompt: negativePrompt, + model, + seed, + steps, + rand_device: use_cpu ? 'cpu' : 'cuda', + scheduler, + clip_skip: clipSkip, + }, + CANVAS_OUTPUT + ); // Add Seamless To Graph if (seamlessXAxis || seamlessYAxis) { @@ -336,7 +342,7 @@ export const buildCanvasTextToImageGraph = ( addWatermarkerToGraph(state, graph, CANVAS_OUTPUT); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts index 3b13c746c9..e13e7f3e53 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts @@ -9,7 +9,7 @@ import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addLoRAsToGraph } from './addLoRAsToGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -311,22 +311,26 @@ export const buildLinearImageToImageGraph = ( }); } - addCoreMetadataNode(graph, { - generation_mode: 'img2img', - cfg_scale, - height, - width, - positive_prompt: positivePrompt, - negative_prompt: negativePrompt, - model, - seed, - steps, - rand_device: use_cpu ? 'cpu' : 'cuda', - scheduler, - clip_skip: clipSkip, - strength, - init_image: initialImage.imageName, - }); + addCoreMetadataNode( + graph, + { + generation_mode: 'img2img', + cfg_scale, + height, + width, + positive_prompt: positivePrompt, + negative_prompt: negativePrompt, + model, + seed, + steps, + rand_device: use_cpu ? 'cpu' : 'cuda', + scheduler, + clip_skip: clipSkip, + strength, + init_image: initialImage.imageName, + }, + IMAGE_TO_LATENTS + ); // Add Seamless To Graph if (seamlessXAxis || seamlessYAxis) { @@ -358,7 +362,7 @@ export const buildLinearImageToImageGraph = ( addWatermarkerToGraph(state, graph); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLImageToImageGraph.ts index 54f8e05d21..94586c97ba 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLImageToImageGraph.ts @@ -10,7 +10,7 @@ import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; import { addSDXLLoRAsToGraph } from './addSDXLLoRAstoGraph'; import { addSDXLRefinerToGraph } from './addSDXLRefinerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -331,23 +331,27 @@ export const buildLinearSDXLImageToImageGraph = ( }); } - addCoreMetadataNode(graph, { - generation_mode: 'sdxl_img2img', - cfg_scale, - height, - width, - positive_prompt: positivePrompt, - negative_prompt: negativePrompt, - model, - seed, - steps, - rand_device: use_cpu ? 'cpu' : 'cuda', - scheduler, - strength, - init_image: initialImage.imageName, - positive_style_prompt: positiveStylePrompt, - negative_style_prompt: negativeStylePrompt, - }); + addCoreMetadataNode( + graph, + { + generation_mode: 'sdxl_img2img', + cfg_scale, + height, + width, + positive_prompt: positivePrompt, + negative_prompt: negativePrompt, + model, + seed, + steps, + rand_device: use_cpu ? 'cpu' : 'cuda', + scheduler, + strength, + init_image: initialImage.imageName, + positive_style_prompt: positiveStylePrompt, + negative_style_prompt: negativeStylePrompt, + }, + IMAGE_TO_LATENTS + ); // Add Seamless To Graph if (seamlessXAxis || seamlessYAxis) { @@ -388,7 +392,7 @@ export const buildLinearSDXLImageToImageGraph = ( addWatermarkerToGraph(state, graph); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLTextToImageGraph.ts index 37fbbf7f43..37e9b293c6 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLTextToImageGraph.ts @@ -6,7 +6,7 @@ import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; import { addSDXLLoRAsToGraph } from './addSDXLLoRAstoGraph'; import { addSDXLRefinerToGraph } from './addSDXLRefinerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -225,21 +225,25 @@ export const buildLinearSDXLTextToImageGraph = ( ], }; - addCoreMetadataNode(graph, { - generation_mode: 'sdxl_txt2img', - cfg_scale, - height, - width, - positive_prompt: positivePrompt, - negative_prompt: negativePrompt, - model, - seed, - steps, - rand_device: use_cpu ? 'cpu' : 'cuda', - scheduler, - positive_style_prompt: positiveStylePrompt, - negative_style_prompt: negativeStylePrompt, - }); + addCoreMetadataNode( + graph, + { + generation_mode: 'sdxl_txt2img', + cfg_scale, + height, + width, + positive_prompt: positivePrompt, + negative_prompt: negativePrompt, + model, + seed, + steps, + rand_device: use_cpu ? 'cpu' : 'cuda', + scheduler, + positive_style_prompt: positiveStylePrompt, + negative_style_prompt: negativeStylePrompt, + }, + LATENTS_TO_IMAGE + ); // Add Seamless To Graph if (seamlessXAxis || seamlessYAxis) { @@ -280,7 +284,7 @@ export const buildLinearSDXLTextToImageGraph = ( addWatermarkerToGraph(state, graph); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts index 8e0143f180..f097cf0c42 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts @@ -10,7 +10,7 @@ import { addHrfToGraph } from './addHrfToGraph'; import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addLoRAsToGraph } from './addLoRAsToGraph'; import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph'; -import { addSaveImageNode } from './addSaveImageNode'; +import { addLinearUIOutputNode } from './addLinearUIOutputNode'; import { addSeamlessToLinearGraph } from './addSeamlessToLinearGraph'; import { addT2IAdaptersToLinearGraph } from './addT2IAdapterToLinearGraph'; import { addVAEToGraph } from './addVAEToGraph'; @@ -234,20 +234,24 @@ export const buildLinearTextToImageGraph = ( ], }; - addCoreMetadataNode(graph, { - generation_mode: 'txt2img', - cfg_scale, - height, - width, - positive_prompt: positivePrompt, - negative_prompt: negativePrompt, - model, - seed, - steps, - rand_device: use_cpu ? 'cpu' : 'cuda', - scheduler, - clip_skip: clipSkip, - }); + addCoreMetadataNode( + graph, + { + generation_mode: 'txt2img', + cfg_scale, + height, + width, + positive_prompt: positivePrompt, + negative_prompt: negativePrompt, + model, + seed, + steps, + rand_device: use_cpu ? 'cpu' : 'cuda', + scheduler, + clip_skip: clipSkip, + }, + LATENTS_TO_IMAGE + ); // Add Seamless To Graph if (seamlessXAxis || seamlessYAxis) { @@ -286,7 +290,7 @@ export const buildLinearTextToImageGraph = ( addWatermarkerToGraph(state, graph); } - addSaveImageNode(state, graph); + addLinearUIOutputNode(state, graph); return graph; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts index 811b2604b1..3839822133 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts @@ -9,7 +9,7 @@ export const LATENTS_TO_IMAGE_HRF_LR = 'latents_to_image_hrf_lr'; export const IMAGE_TO_LATENTS_HRF = 'image_to_latents_hrf'; export const RESIZE_HRF = 'resize_hrf'; export const ESRGAN_HRF = 'esrgan_hrf'; -export const SAVE_IMAGE = 'save_image'; +export const LINEAR_UI_OUTPUT = 'linear_ui_output'; export const NSFW_CHECKER = 'nsfw_checker'; export const WATERMARKER = 'invisible_watermark'; export const NOISE = 'noise'; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/metadata.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/metadata.ts index b673be9e4a..c80e1c80c6 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/metadata.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/metadata.ts @@ -1,11 +1,12 @@ import { NonNullableGraph } from 'features/nodes/types/types'; import { CoreMetadataInvocation } from 'services/api/types'; import { JsonObject } from 'type-fest'; -import { METADATA, SAVE_IMAGE } from './constants'; +import { METADATA } from './constants'; export const addCoreMetadataNode = ( graph: NonNullableGraph, - metadata: Partial + metadata: Partial, + nodeId: string ): void => { graph.nodes[METADATA] = { id: METADATA, @@ -19,7 +20,7 @@ export const addCoreMetadataNode = ( field: 'metadata', }, destination: { - node_id: SAVE_IMAGE, + node_id: nodeId, field: 'metadata', }, }); @@ -64,3 +65,21 @@ export const getHasMetadata = (graph: NonNullableGraph): boolean => { return Boolean(metadataNode); }; + +export const setMetadataReceivingNode = ( + graph: NonNullableGraph, + nodeId: string +) => { + graph.edges = graph.edges.filter((edge) => edge.source.node_id !== METADATA); + + graph.edges.push({ + source: { + node_id: METADATA, + field: 'metadata', + }, + destination: { + node_id: nodeId, + field: 'metadata', + }, + }); +}; diff --git a/invokeai/frontend/web/src/features/nodes/util/parseSchema.ts b/invokeai/frontend/web/src/features/nodes/util/parseSchema.ts index 7c6f4e638f..8737fc52b9 100644 --- a/invokeai/frontend/web/src/features/nodes/util/parseSchema.ts +++ b/invokeai/frontend/web/src/features/nodes/util/parseSchema.ts @@ -19,7 +19,7 @@ const RESERVED_INPUT_FIELD_NAMES = ['id', 'type', 'use_cache']; const RESERVED_OUTPUT_FIELD_NAMES = ['type']; const RESERVED_FIELD_TYPES = ['IsIntermediate']; -const invocationDenylist: AnyInvocationType[] = ['graph']; +const invocationDenylist: AnyInvocationType[] = ['graph', 'linear_ui_output']; const isReservedInputField = (nodeType: string, fieldName: string) => { if (RESERVED_INPUT_FIELD_NAMES.includes(fieldName)) { diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index 81bfed5a1a..6788835152 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -2127,7 +2127,7 @@ export type components = { * Hrf Enabled * @description Whether or not high resolution fix was enabled. */ - hrf_enabled?: number | null; + hrf_enabled?: boolean | null; /** * Hrf Method * @description The high resolution fix upscale method. @@ -3216,7 +3216,7 @@ export type components = { * @description The nodes in this graph */ nodes?: { - [key: string]: components["schemas"]["GraphInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ColorMapImageProcessorInvocation"] | components["schemas"]["TestInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["TestInvocation2"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["TestInvocation3"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"]; + [key: string]: components["schemas"]["ImageScaleInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["TestInvocation2"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["ColorMapImageProcessorInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["TestInvocation3"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["LinearUIOutputInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["TestInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"]; }; /** * Edges @@ -3253,7 +3253,7 @@ export type components = { * @description The results of node executions */ results: { - [key: string]: components["schemas"]["IntegerOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["String2Output"] | components["schemas"]["VAEOutput"]; + [key: string]: components["schemas"]["SeamlessModeOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["String2Output"] | components["schemas"]["ImageOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["ConditioningOutput"]; }; /** * Errors @@ -5243,6 +5243,43 @@ export type components = { */ type: "leres_image_processor"; }; + /** + * Linear UI Image Output + * @description Handles Linear UI Image Outputting tasks. + */ + LinearUIOutputInvocation: { + /** @description Optional metadata to be saved with the image */ + metadata?: components["schemas"]["MetadataField"] | null; + /** @description Optional workflow to be saved with the image */ + workflow?: components["schemas"]["WorkflowField"] | null; + /** + * 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 false + */ + use_cache?: boolean; + /** @description The image to process */ + image?: components["schemas"]["ImageField"]; + /** @description The board to save the image to */ + board?: components["schemas"]["BoardField"] | null; + /** + * type + * @default linear_ui_output + * @constant + */ + type: "linear_ui_output"; + }; /** * Lineart Anime Processor * @description Applies line art anime processing to image @@ -9664,12 +9701,6 @@ export type components = { /** Ui Order */ ui_order: number | null; }; - /** - * StableDiffusionXLModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; /** * StableDiffusionOnnxModelFormat * @description An enumeration. @@ -9677,41 +9708,47 @@ export type components = { */ StableDiffusionOnnxModelFormat: "olive" | "onnx"; /** - * T2IAdapterModelFormat + * ControlNetModelFormat * @description An enumeration. * @enum {string} */ - T2IAdapterModelFormat: "diffusers"; - /** - * StableDiffusion1ModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; - /** - * StableDiffusion2ModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; + ControlNetModelFormat: "checkpoint" | "diffusers"; /** * CLIPVisionModelFormat * @description An enumeration. * @enum {string} */ CLIPVisionModelFormat: "diffusers"; + /** + * T2IAdapterModelFormat + * @description An enumeration. + * @enum {string} + */ + T2IAdapterModelFormat: "diffusers"; + /** + * StableDiffusionXLModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; + /** + * StableDiffusion2ModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; + /** + * StableDiffusion1ModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; /** * IPAdapterModelFormat * @description An enumeration. * @enum {string} */ IPAdapterModelFormat: "invokeai"; - /** - * ControlNetModelFormat - * @description An enumeration. - * @enum {string} - */ - ControlNetModelFormat: "checkpoint" | "diffusers"; }; responses: never; parameters: never; diff --git a/invokeai/frontend/web/src/services/api/types.ts b/invokeai/frontend/web/src/services/api/types.ts index 9038374912..ce3e75a584 100644 --- a/invokeai/frontend/web/src/services/api/types.ts +++ b/invokeai/frontend/web/src/services/api/types.ts @@ -142,7 +142,7 @@ export type DivideInvocation = s['DivideInvocation']; export type ImageNSFWBlurInvocation = s['ImageNSFWBlurInvocation']; export type ImageWatermarkInvocation = s['ImageWatermarkInvocation']; export type SeamlessModeInvocation = s['SeamlessModeInvocation']; -export type SaveImageInvocation = s['SaveImageInvocation']; +export type LinearUIOutputInvocation = s['LinearUIOutputInvocation']; export type MetadataInvocation = s['MetadataInvocation']; export type CoreMetadataInvocation = s['CoreMetadataInvocation']; export type MetadataItemInvocation = s['MetadataItemInvocation'];