diff --git a/invokeai/app/invocations/canvas_workflow.py b/invokeai/app/invocations/canvas_workflow.py new file mode 100644 index 00000000000..779a13a1033 --- /dev/null +++ b/invokeai/app/invocations/canvas_workflow.py @@ -0,0 +1,52 @@ +"""Canvas workflow bridge invocations.""" + +from invokeai.app.invocations.baseinvocation import ( + BaseInvocation, + Classification, + invocation, +) +from invokeai.app.invocations.fields import ImageField, Input, InputField, WithBoard, WithMetadata +from invokeai.app.invocations.primitives import ImageOutput +from invokeai.app.services.shared.invocation_context import InvocationContext + + +@invocation( + "canvas_composite_raster_input", + title="Canvas Composite Input", + tags=["canvas", "workflow", "canvas-workflow-input"], + category="canvas", + version="1.0.0", + classification=Classification.Beta, +) +class CanvasCompositeRasterInputInvocation(BaseInvocation, WithMetadata, WithBoard): + """Provides the flattened canvas raster layer to a workflow.""" + + image: ImageField = InputField( + description="The flattened canvas raster layer.", + input=Input.Direct, + ) + + def invoke(self, context: InvocationContext) -> ImageOutput: + image_dto = context.images.get_dto(self.image.image_name) + return ImageOutput.build(image_dto=image_dto) + + +@invocation( + "canvas_workflow_output", + title="Canvas Workflow Output", + tags=["canvas", "workflow", "canvas-workflow-output"], + category="canvas", + version="1.0.0", + classification=Classification.Beta, +) +class CanvasWorkflowOutputInvocation(BaseInvocation, WithMetadata, WithBoard): + """Designates the workflow image output used by the canvas.""" + + image: ImageField = InputField( + description="The workflow's resulting image.", + input=Input.Connection, + ) + + def invoke(self, context: InvocationContext) -> ImageOutput: + image_dto = context.images.get_dto(self.image.image_name) + return ImageOutput.build(image_dto=image_dto) diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index f7a310fc321..b4c318cfb35 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -2128,6 +2128,16 @@ "recalculateRects": "Recalculate Rects", "clipToBbox": "Clip Strokes to Bbox", "outputOnlyMaskedRegions": "Output Only Generated Regions", + "canvasWorkflowLabel": "Canvas Workflow", + "canvasWorkflowInstructions": "Select a workflow containing the canvas composite input and canvas workflow output nodes to drive custom canvas generation.", + "canvasWorkflowSelectedDescription": "This workflow is currently configured for canvas generation.", + "canvasWorkflowSelectButton": "Select Workflow", + "canvasWorkflowSelected": "Canvas workflow selected", + "canvasWorkflowModalTitle": "Select Canvas Workflow", + "canvasWorkflowModalDescription": "Choose a workflow containing the canvas composite input and canvas workflow output nodes. Only workflows that meet these requirements can be used from the canvas.", + "selectCanvasWorkflowTooltip": "Select a workflow to run from the canvas", + "changeCanvasWorkflowTooltip": "Change canvas workflow", + "canvasWorkflowChangeButton": "Change Workflow", "addLayer": "Add Layer", "duplicate": "Duplicate", "moveToFront": "Move to Front", diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasWorkflowRehydrated.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasWorkflowRehydrated.ts new file mode 100644 index 00000000000..984cd5525f9 --- /dev/null +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasWorkflowRehydrated.ts @@ -0,0 +1,35 @@ +import type { AppStartListening } from 'app/store/store'; +import { selectCanvasWorkflow } from 'features/controlLayers/store/canvasWorkflowSlice'; +import { REMEMBER_REHYDRATED } from 'redux-remember'; + +/** + * When the app rehydrates from storage, we need to populate the canvasWorkflowNodes + * shadow slice if a canvas workflow was previously selected. + * + * This ensures that exposed fields are visible when the page loads with a workflow already selected. + */ +export const addCanvasWorkflowRehydratedListener = (startListening: AppStartListening) => { + startListening({ + type: REMEMBER_REHYDRATED, + effect: (_action, { dispatch, getState }) => { + const state = getState(); + const { workflow, inputNodeId } = state.canvasWorkflow; + + // If there's a canvas workflow already selected, we need to load it into shadow nodes + if (workflow && inputNodeId) { + // Manually dispatch the fulfilled action to populate shadow nodes + // We can't use the thunk because the workflow is already loaded + dispatch({ + type: selectCanvasWorkflow.fulfilled.type, + payload: { + workflow, + inputNodeId, + outputNodeId: state.canvasWorkflow.outputNodeId, + workflowId: state.canvasWorkflow.selectedWorkflowId, + fieldValues: state.canvasWorkflow.fieldValues, + }, + }); + } + }, + }); +}; diff --git a/invokeai/frontend/web/src/app/store/store.ts b/invokeai/frontend/web/src/app/store/store.ts index 12fcfa5a406..4ddcac28cf8 100644 --- a/invokeai/frontend/web/src/app/store/store.ts +++ b/invokeai/frontend/web/src/app/store/store.ts @@ -24,6 +24,8 @@ import { changeBoardModalSliceConfig } from 'features/changeBoardModal/store/sli import { canvasSettingsSliceConfig } from 'features/controlLayers/store/canvasSettingsSlice'; import { canvasSliceConfig } from 'features/controlLayers/store/canvasSlice'; import { canvasSessionSliceConfig } from 'features/controlLayers/store/canvasStagingAreaSlice'; +import { canvasWorkflowNodesSliceConfig } from 'features/controlLayers/store/canvasWorkflowNodesSlice'; +import { canvasWorkflowSliceConfig } from 'features/controlLayers/store/canvasWorkflowSlice'; import { lorasSliceConfig } from 'features/controlLayers/store/lorasSlice'; import { paramsSliceConfig } from 'features/controlLayers/store/paramsSlice'; import { refImagesSliceConfig } from 'features/controlLayers/store/refImagesSlice'; @@ -55,6 +57,7 @@ import { actionSanitizer } from './middleware/devtools/actionSanitizer'; import { actionsDenylist } from './middleware/devtools/actionsDenylist'; import { stateSanitizer } from './middleware/devtools/stateSanitizer'; import { addArchivedOrDeletedBoardListener } from './middleware/listenerMiddleware/listeners/addArchivedOrDeletedBoardListener'; +import { addCanvasWorkflowRehydratedListener } from './middleware/listenerMiddleware/listeners/canvasWorkflowRehydrated'; import { addImageUploadedFulfilledListener } from './middleware/listenerMiddleware/listeners/imageUploaded'; export const listenerMiddleware = createListenerMiddleware(); @@ -65,6 +68,8 @@ const log = logger('system'); const SLICE_CONFIGS = { [canvasSessionSliceConfig.slice.reducerPath]: canvasSessionSliceConfig, [canvasSettingsSliceConfig.slice.reducerPath]: canvasSettingsSliceConfig, + [canvasWorkflowSliceConfig.slice.reducerPath]: canvasWorkflowSliceConfig, + [canvasWorkflowNodesSliceConfig.slice.reducerPath]: canvasWorkflowNodesSliceConfig, [canvasSliceConfig.slice.reducerPath]: canvasSliceConfig, [changeBoardModalSliceConfig.slice.reducerPath]: changeBoardModalSliceConfig, [configSliceConfig.slice.reducerPath]: configSliceConfig, @@ -91,6 +96,8 @@ const ALL_REDUCERS = { [api.reducerPath]: api.reducer, [canvasSessionSliceConfig.slice.reducerPath]: canvasSessionSliceConfig.slice.reducer, [canvasSettingsSliceConfig.slice.reducerPath]: canvasSettingsSliceConfig.slice.reducer, + [canvasWorkflowSliceConfig.slice.reducerPath]: canvasWorkflowSliceConfig.slice.reducer, + [canvasWorkflowNodesSliceConfig.slice.reducerPath]: canvasWorkflowNodesSliceConfig.slice.reducer, // Undoable! [canvasSliceConfig.slice.reducerPath]: undoable( canvasSliceConfig.slice.reducer, @@ -289,3 +296,6 @@ addAppConfigReceivedListener(startAppListening); addAdHocPostProcessingRequestedListener(startAppListening); addSetDefaultSettingsListener(startAppListening); + +// Canvas workflow fields +addCanvasWorkflowRehydratedListener(startAppListening); diff --git a/invokeai/frontend/web/src/app/store/storeHooks.ts b/invokeai/frontend/web/src/app/store/storeHooks.ts index cd0e41e55d1..46a1a72d473 100644 --- a/invokeai/frontend/web/src/app/store/storeHooks.ts +++ b/invokeai/frontend/web/src/app/store/storeHooks.ts @@ -1,8 +1,31 @@ import type { AppStore, AppThunkDispatch, RootState } from 'app/store/store'; +import { useIsCanvasWorkflow } from 'app/store/workflowContext'; +import { injectCanvasWorkflowKey, injectNodesWorkflowKey } from 'features/nodes/store/actionRouter'; +import { useCallback } from 'react'; import type { TypedUseSelectorHook } from 'react-redux'; import { useDispatch, useSelector, useStore } from 'react-redux'; // Use throughout your app instead of plain `useDispatch` and `useSelector` -export const useAppDispatch = () => useDispatch(); +export const useAppDispatch = (): AppThunkDispatch => { + const isCanvasWorkflow = useIsCanvasWorkflow(); + const dispatch = useDispatch(); + + return useCallback( + ((action: Parameters[0]) => { + // Inject workflow routing metadata into actions + if (typeof action === 'object' && action !== null && 'type' in action) { + if (isCanvasWorkflow) { + injectCanvasWorkflowKey(action); + } else { + injectNodesWorkflowKey(action); + } + } + + return dispatch(action); + }) as AppThunkDispatch, + [dispatch, isCanvasWorkflow] + ); +}; + export const useAppSelector: TypedUseSelectorHook = useSelector; export const useAppStore = () => useStore.withTypes()(); diff --git a/invokeai/frontend/web/src/app/store/workflowContext.ts b/invokeai/frontend/web/src/app/store/workflowContext.ts new file mode 100644 index 00000000000..a59c1fa55a5 --- /dev/null +++ b/invokeai/frontend/web/src/app/store/workflowContext.ts @@ -0,0 +1,15 @@ +import { createContext, useContext } from 'react'; + +/** + * Context to track whether we're in a canvas workflow or nodes workflow. + * This is used by the useAppDispatch hook to inject the appropriate action routing metadata. + */ +export const WorkflowContext = createContext<{ isCanvasWorkflow: boolean } | null>(null); + +/** + * Hook to check if we're in a canvas workflow context. + */ +export const useIsCanvasWorkflow = (): boolean => { + const context = useContext(WorkflowContext); + return context?.isCanvasWorkflow ?? false; +}; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowElementContext.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowElementContext.tsx new file mode 100644 index 00000000000..cf81af7eeac --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowElementContext.tsx @@ -0,0 +1,45 @@ +import { useAppSelector } from 'app/store/storeHooks'; +import { WorkflowContext } from 'app/store/workflowContext'; +import { selectCanvasWorkflowNodesSlice } from 'features/controlLayers/store/canvasWorkflowNodesSlice'; +import type { FormElement } from 'features/nodes/types/workflow'; +import type { PropsWithChildren } from 'react'; +import { createContext, memo, useContext, useMemo } from 'react'; + +/** + * Context that provides element lookup from canvas workflow nodes instead of regular nodes. + * This ensures that when viewing canvas workflow fields, we read from the shadow slice. + */ + +type CanvasWorkflowElementContextValue = { + getElement: (id: string) => FormElement | undefined; +}; + +const CanvasWorkflowElementContext = createContext(null); + +export const CanvasWorkflowElementProvider = memo(({ children }: PropsWithChildren) => { + const nodesState = useAppSelector(selectCanvasWorkflowNodesSlice); + + const elementValue = useMemo( + () => ({ + getElement: (id: string) => nodesState.form.elements[id], + }), + [nodesState.form.elements] + ); + + const workflowValue = useMemo(() => ({ isCanvasWorkflow: true }), []); + + return ( + + {children} + + ); +}); +CanvasWorkflowElementProvider.displayName = 'CanvasWorkflowElementProvider'; + +/** + * Hook to get an element, using canvas workflow context if available, + * otherwise falls back to regular nodes. + */ +export const useCanvasWorkflowElement = (): ((id: string) => FormElement | undefined) | null => { + return useContext(CanvasWorkflowElementContext)?.getElement ?? null; +}; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowFieldsPanel.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowFieldsPanel.tsx new file mode 100644 index 00000000000..36289c6b267 --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowFieldsPanel.tsx @@ -0,0 +1,45 @@ +import { Flex, Text } from '@invoke-ai/ui-library'; +import { useAppSelector } from 'app/store/storeHooks'; +import { CanvasWorkflowElementProvider } from 'features/controlLayers/components/CanvasWorkflowElementContext'; +import { CanvasWorkflowModeProvider } from 'features/controlLayers/components/CanvasWorkflowModeContext'; +import { CanvasWorkflowRootContainer } from 'features/controlLayers/components/CanvasWorkflowRootContainer'; +import { selectCanvasWorkflowNodesSlice } from 'features/controlLayers/store/canvasWorkflowNodesSlice'; +import { memo } from 'react'; + +/** + * Renders the exposed fields for a canvas workflow. + * + * This component renders the workflow's form in view mode. + * Each field element is wrapped with the appropriate InvocationNodeContext + * in CanvasWorkflowFormElementComponent. + */ +export const CanvasWorkflowFieldsPanel = memo(() => { + const nodesState = useAppSelector(selectCanvasWorkflowNodesSlice); + + // Check if form is empty + const rootElement = nodesState.form.elements[nodesState.form.rootElementId]; + if ( + !rootElement || + !('data' in rootElement) || + !rootElement.data || + !('children' in rootElement.data) || + rootElement.data.children.length === 0 + ) { + return ( + + No fields exposed in this workflow + + ); + } + + return ( + + + + + + + + ); +}); +CanvasWorkflowFieldsPanel.displayName = 'CanvasWorkflowFieldsPanel'; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowFormElementComponent.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowFormElementComponent.tsx new file mode 100644 index 00000000000..9320d60a6de --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowFormElementComponent.tsx @@ -0,0 +1,129 @@ +import type { SystemStyleObject } from '@invoke-ai/ui-library'; +import { Flex } from '@invoke-ai/ui-library'; +import { useAppSelector } from 'app/store/storeHooks'; +import { selectCanvasWorkflowNodesSlice } from 'features/controlLayers/store/canvasWorkflowNodesSlice'; +import { + ContainerContextProvider, + DepthContextProvider, + useContainerContext, + useDepthContext, +} from 'features/nodes/components/sidePanel/builder/contexts'; +import { DividerElement } from 'features/nodes/components/sidePanel/builder/DividerElement'; +import { HeadingElement } from 'features/nodes/components/sidePanel/builder/HeadingElement'; +import { NodeFieldElementViewMode } from 'features/nodes/components/sidePanel/builder/NodeFieldElementViewMode'; +import { TextElement } from 'features/nodes/components/sidePanel/builder/TextElement'; +import { + CONTAINER_CLASS_NAME, + isContainerElement, + isDividerElement, + isHeadingElement, + isNodeFieldElement, + isTextElement, +} from 'features/nodes/types/workflow'; +import { memo } from 'react'; +import type { Equals } from 'tsafe'; +import { assert } from 'tsafe'; + +import { CanvasWorkflowInvocationNodeContextProvider } from './CanvasWorkflowInvocationContext'; + +const containerViewModeSx: SystemStyleObject = { + gap: 2, + '&[data-self-layout="column"]': { + flexDir: 'column', + alignItems: 'stretch', + }, + '&[data-self-layout="row"]': { + flexDir: 'row', + alignItems: 'flex-start', + overflowX: 'auto', + overflowY: 'visible', + h: 'min-content', + flexShrink: 0, + }, + '&[data-parent-layout="column"]': { + w: 'full', + h: 'min-content', + }, + '&[data-parent-layout="row"]': { + flex: '1 1 0', + minW: 32, + }, +}; + +/** + * Container element for canvas workflow fields. + * This reads from the canvas workflow nodes slice. + */ +const CanvasWorkflowContainerElement = memo(({ id }: { id: string }) => { + const nodesState = useAppSelector(selectCanvasWorkflowNodesSlice); + const el = nodesState.form.elements[id]; + const depth = useDepthContext(); + const containerCtx = useContainerContext(); + + if (!el || !isContainerElement(el)) { + return null; + } + + const { data } = el; + const { children, layout } = data; + + return ( + + + + {children.map((childId) => ( + + ))} + + + + ); +}); +CanvasWorkflowContainerElement.displayName = 'CanvasWorkflowContainerElement'; + +/** + * Renders a form element from canvas workflow nodes. + * Recursively handles all element types. + */ +export const CanvasWorkflowFormElementComponent = memo(({ id }: { id: string }) => { + const nodesState = useAppSelector(selectCanvasWorkflowNodesSlice); + const el = nodesState.form.elements[id]; + + if (!el) { + return null; + } + + if (isContainerElement(el)) { + return ; + } + + if (isNodeFieldElement(el)) { + return ( + + + + ); + } + + if (isDividerElement(el)) { + return ; + } + + if (isHeadingElement(el)) { + return ; + } + + if (isTextElement(el)) { + return ; + } + + assert>(false, `Unhandled type for element with id ${id}`); +}); +CanvasWorkflowFormElementComponent.displayName = 'CanvasWorkflowFormElementComponent'; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowInvocationContext.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowInvocationContext.tsx new file mode 100644 index 00000000000..4d7c01f8ab1 --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowInvocationContext.tsx @@ -0,0 +1,216 @@ +import { useStore } from '@nanostores/react'; +import type { Selector } from '@reduxjs/toolkit'; +import { createSelector } from '@reduxjs/toolkit'; +import type { RootState } from 'app/store/store'; +import { InvocationNodeContext } from 'features/nodes/components/flow/nodes/Invocation/context'; +import { $templates } from 'features/nodes/store/nodesSlice'; +import type { InvocationNode } from 'features/nodes/types/invocation'; +import { getNeedsUpdate } from 'features/nodes/util/node/nodeUpdate'; +import type { PropsWithChildren } from 'react'; +import { memo, useMemo } from 'react'; + +/** + * Provides InvocationNodeContext for canvas workflow nodes. + * + * This is a wrapper around InvocationNodeContextProvider that redirects + * node selectors to use the canvasWorkflowNodes slice instead of the nodes slice. + * This allows all existing field components to work without modification. + */ + +const getSelectorFromCache = (cache: Map, key: string, fallback: () => T): T => { + let selector = cache.get(key); + if (!selector) { + selector = fallback(); + cache.set(key, selector); + } + return selector as T; +}; + +// Create custom selectors that read from canvasWorkflowNodes instead of nodes +const selectCanvasWorkflowNodes = (state: RootState) => state.canvasWorkflowNodes.nodes; +const selectCanvasWorkflowEdges = (state: RootState) => state.canvasWorkflowNodes.edges; +const selectCanvasWorkflowNodeFieldElements = (state: RootState) => { + const form = state.canvasWorkflowNodes.form; + return Object.values(form.elements).filter( + (el): el is Extract => el.type === 'node-field' + ); +}; + +export const CanvasWorkflowInvocationNodeContextProvider = memo( + ({ nodeId, children }: PropsWithChildren<{ nodeId: string }>) => { + const templates = useStore($templates); + + const value = useMemo(() => { + const cache: Map> = new Map(); + + const selectNodeSafe = getSelectorFromCache(cache, 'selectNodeSafe', () => + createSelector(selectCanvasWorkflowNodes, (nodes) => { + return (nodes.find(({ id, type }) => type === 'invocation' && id === nodeId) ?? + null) as InvocationNode | null; + }) + ); + const selectNodeDataSafe = getSelectorFromCache(cache, 'selectNodeDataSafe', () => + createSelector(selectNodeSafe, (node) => { + return node?.data ?? null; + }) + ); + const selectNodeTypeSafe = getSelectorFromCache(cache, 'selectNodeTypeSafe', () => + createSelector(selectNodeDataSafe, (data) => { + return data?.type ?? null; + }) + ); + const selectNodeTemplateSafe = getSelectorFromCache(cache, 'selectNodeTemplateSafe', () => + createSelector(selectNodeTypeSafe, (type) => { + return type ? (templates[type] ?? null) : null; + }) + ); + const selectNodeInputsSafe = getSelectorFromCache(cache, 'selectNodeInputsSafe', () => + createSelector(selectNodeDataSafe, (data) => { + return data?.inputs ?? null; + }) + ); + const buildSelectInputFieldSafe = (fieldName: string) => + getSelectorFromCache(cache, `buildSelectInputFieldSafe-${fieldName}`, () => + createSelector(selectNodeInputsSafe, (inputs) => { + return inputs?.[fieldName] ?? null; + }) + ); + const buildSelectInputFieldTemplateSafe = (fieldName: string) => + getSelectorFromCache(cache, `buildSelectInputFieldTemplateSafe-${fieldName}`, () => + createSelector(selectNodeTemplateSafe, (template) => { + return template?.inputs?.[fieldName] ?? null; + }) + ); + const buildSelectOutputFieldTemplateSafe = (fieldName: string) => + getSelectorFromCache(cache, `buildSelectOutputFieldTemplateSafe-${fieldName}`, () => + createSelector(selectNodeTemplateSafe, (template) => { + return template?.outputs?.[fieldName] ?? null; + }) + ); + + const selectNodeOrThrow = getSelectorFromCache(cache, 'selectNodeOrThrow', () => + createSelector(selectCanvasWorkflowNodes, (nodes) => { + const node = nodes.find(({ id, type }) => type === 'invocation' && id === nodeId) as + | InvocationNode + | undefined; + if (node === undefined) { + throw new Error(`Cannot find node with id ${nodeId}`); + } + return node; + }) + ); + const selectNodeDataOrThrow = getSelectorFromCache(cache, 'selectNodeDataOrThrow', () => + createSelector(selectNodeOrThrow, (node) => { + return node.data; + }) + ); + const selectNodeTypeOrThrow = getSelectorFromCache(cache, 'selectNodeTypeOrThrow', () => + createSelector(selectNodeDataOrThrow, (data) => { + return data.type; + }) + ); + const selectNodeTemplateOrThrow = getSelectorFromCache(cache, 'selectNodeTemplateOrThrow', () => + createSelector(selectNodeTypeOrThrow, (type) => { + const template = templates[type]; + if (template === undefined) { + throw new Error(`Cannot find template for node with id ${nodeId} with type ${type}`); + } + return template; + }) + ); + const selectNodeInputsOrThrow = getSelectorFromCache(cache, 'selectNodeInputsOrThrow', () => + createSelector(selectNodeDataOrThrow, (data) => { + return data.inputs; + }) + ); + const buildSelectInputFieldOrThrow = (fieldName: string) => + getSelectorFromCache(cache, `buildSelectInputFieldOrThrow-${fieldName}`, () => + createSelector(selectNodeInputsOrThrow, (inputs) => { + const field = inputs[fieldName]; + if (field === undefined) { + throw new Error(`Cannot find input field with name ${fieldName} in node ${nodeId}`); + } + return field; + }) + ); + const buildSelectInputFieldTemplateOrThrow = (fieldName: string) => + getSelectorFromCache(cache, `buildSelectInputFieldTemplateOrThrow-${fieldName}`, () => + createSelector(selectNodeTemplateOrThrow, (template) => { + const fieldTemplate = template.inputs[fieldName]; + if (fieldTemplate === undefined) { + throw new Error(`Cannot find input field template with name ${fieldName} in node ${nodeId}`); + } + return fieldTemplate; + }) + ); + const buildSelectOutputFieldTemplateOrThrow = (fieldName: string) => + getSelectorFromCache(cache, `buildSelectOutputFieldTemplateOrThrow-${fieldName}`, () => + createSelector(selectNodeTemplateOrThrow, (template) => { + const fieldTemplate = template.outputs[fieldName]; + if (fieldTemplate === undefined) { + throw new Error(`Cannot find output field template with name ${fieldName} in node ${nodeId}`); + } + return fieldTemplate; + }) + ); + + const buildSelectIsInputFieldConnected = (fieldName: string) => + getSelectorFromCache(cache, `buildSelectIsInputFieldConnected-${fieldName}`, () => + createSelector(selectCanvasWorkflowEdges, (edges) => { + return edges.some((edge) => { + return edge.target === nodeId && edge.targetHandle === fieldName; + }); + }) + ); + + const buildSelectIsInputFieldAddedToForm = (fieldName: string) => + getSelectorFromCache(cache, `buildSelectIsInputFieldAddedToForm-${fieldName}`, () => + createSelector(selectCanvasWorkflowNodeFieldElements, (nodeFieldElements) => { + return nodeFieldElements.some( + (el) => el.data.fieldIdentifier.nodeId === nodeId && el.data.fieldIdentifier.fieldName === fieldName + ); + }) + ); + + const selectNodeNeedsUpdate = getSelectorFromCache(cache, 'selectNodeNeedsUpdate', () => + createSelector([selectNodeDataSafe, selectNodeTemplateSafe], (data, template) => { + if (!data || !template) { + return false; + } + return getNeedsUpdate(data, template); + }) + ); + + return { + nodeId, + + selectNodeSafe, + selectNodeDataSafe, + selectNodeTypeSafe, + selectNodeTemplateSafe, + selectNodeInputsSafe, + + buildSelectInputFieldSafe, + buildSelectInputFieldTemplateSafe, + buildSelectOutputFieldTemplateSafe, + buildSelectIsInputFieldAddedToForm, + + selectNodeOrThrow, + selectNodeDataOrThrow, + selectNodeTypeOrThrow, + selectNodeTemplateOrThrow, + selectNodeInputsOrThrow, + + buildSelectInputFieldOrThrow, + buildSelectInputFieldTemplateOrThrow, + buildSelectOutputFieldTemplateOrThrow, + + buildSelectIsInputFieldConnected, + selectNodeNeedsUpdate, + }; + }, [nodeId, templates]); + + return {children}; + } +); +CanvasWorkflowInvocationNodeContextProvider.displayName = 'CanvasWorkflowInvocationNodeContextProvider'; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowModeContext.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowModeContext.tsx new file mode 100644 index 00000000000..14a2646cc31 --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowModeContext.tsx @@ -0,0 +1,14 @@ +import { CanvasWorkflowModeContext } from 'features/nodes/hooks/useWorkflowMode'; +import type { PropsWithChildren } from 'react'; +import { memo } from 'react'; + +/** + * Context provider to override the workflow mode for canvas workflows. + * Canvas workflows should always render fields in view mode, regardless of + * the workflow tab's current mode. + */ + +export const CanvasWorkflowModeProvider = memo(({ children }: PropsWithChildren) => { + return {children}; +}); +CanvasWorkflowModeProvider.displayName = 'CanvasWorkflowModeProvider'; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowRootContainer.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowRootContainer.tsx new file mode 100644 index 00000000000..f232553e432 --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowRootContainer.tsx @@ -0,0 +1,58 @@ +import type { SystemStyleObject } from '@invoke-ai/ui-library'; +import { Box } from '@invoke-ai/ui-library'; +import { useAppSelector } from 'app/store/storeHooks'; +import { selectCanvasWorkflowNodesSlice } from 'features/controlLayers/store/canvasWorkflowNodesSlice'; +import { ContainerContextProvider, DepthContextProvider } from 'features/nodes/components/sidePanel/builder/contexts'; +import { isContainerElement, ROOT_CONTAINER_CLASS_NAME } from 'features/nodes/types/workflow'; +import { memo } from 'react'; + +import { CanvasWorkflowFormElementComponent } from './CanvasWorkflowFormElementComponent'; + +const rootViewModeSx: SystemStyleObject = { + position: 'relative', + alignItems: 'center', + borderRadius: 'base', + w: 'full', + h: 'full', + gap: 2, + display: 'flex', + flex: 1, + maxW: '768px', + '&[data-self-layout="column"]': { + flexDir: 'column', + alignItems: 'stretch', + }, + '&[data-self-layout="row"]': { + flexDir: 'row', + alignItems: 'flex-start', + }, +}; + +/** + * Root container for canvas workflow fields. + * This reads from the canvas workflow nodes slice instead of the main nodes slice. + */ +export const CanvasWorkflowRootContainer = memo(() => { + const nodesState = useAppSelector(selectCanvasWorkflowNodesSlice); + const el = nodesState.form.elements[nodesState.form.rootElementId]; + + if (!el || !isContainerElement(el)) { + return null; + } + + const { id, data } = el; + const { children, layout } = data; + + return ( + + + + {children.map((childId) => ( + + ))} + + + + ); +}); +CanvasWorkflowRootContainer.displayName = 'CanvasWorkflowRootContainer'; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/shared.test.ts b/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/shared.test.ts index f16b9023164..ae050491bc9 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/shared.test.ts +++ b/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/shared.test.ts @@ -64,7 +64,7 @@ describe('StagingAreaApi Utility Functions', () => { expect(getOutputImageName(queueItem)).toBe('test-output.png'); }); - it('should return null when no canvas output node found', () => { + it('should use fallback when no canvas output node found', () => { const queueItem = { item_id: 1, status: 'completed', @@ -93,7 +93,8 @@ describe('StagingAreaApi Utility Functions', () => { }, } as unknown as S['SessionQueueItem']; - expect(getOutputImageName(queueItem)).toBe(null); + // Fallback mechanism finds image in other nodes when no canvas_output node exists + expect(getOutputImageName(queueItem)).toBe('test-output.png'); }); it('should return null when output node has no results', () => { diff --git a/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/shared.ts b/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/shared.ts index fe98408df58..216f1f70113 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/shared.ts +++ b/invokeai/frontend/web/src/features/controlLayers/components/StagingArea/shared.ts @@ -21,13 +21,28 @@ export const getOutputImageName = (item: S['SessionQueueItem']) => { )?.[1][0]; const output = nodeId ? item.session.results[nodeId] : undefined; - if (!output) { + const getImageNameFromOutput = (result?: S['GraphExecutionState']['results'][string]) => { + if (!result) { + return null; + } + for (const [_name, value] of objectEntries(result)) { + if (isImageField(value)) { + return value.image_name; + } + } return null; + }; + + const imageName = getImageNameFromOutput(output); + if (imageName) { + return imageName; } - for (const [_name, value] of objectEntries(output)) { - if (isImageField(value)) { - return value.image_name; + // Fallback: search all results for an image field. Custom workflows may not have a canvas_output-prefixed node id. + for (const result of Object.values(item.session.results)) { + const fallbackName = getImageNameFromOutput(result); + if (fallbackName) { + return fallbackName; } } diff --git a/invokeai/frontend/web/src/features/controlLayers/store/canvasWorkflowNodesSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/canvasWorkflowNodesSlice.ts new file mode 100644 index 00000000000..ae0ddb8a67c --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/store/canvasWorkflowNodesSlice.ts @@ -0,0 +1,312 @@ +import type { PayloadAction, UnknownAction } from '@reduxjs/toolkit'; +import { createSlice, isAnyOf } from '@reduxjs/toolkit'; +import type { RootState } from 'app/store/store'; +import type { SliceConfig } from 'app/store/types'; +import { deepClone } from 'common/util/deepClone'; +import { isCanvasWorkflowAction } from 'features/nodes/store/actionRouter'; +import { getFormFieldInitialValues } from 'features/nodes/store/nodesSlice'; +import * as nodesSliceActions from 'features/nodes/store/nodesSlice'; +import type { NodesState } from 'features/nodes/store/types'; +import { zNodesState } from 'features/nodes/store/types'; +import { SHARED_NODE_PROPERTIES } from 'features/nodes/types/constants'; +import type { StatefulFieldValue } from 'features/nodes/types/field'; +import { + zBoardFieldValue, + zBooleanFieldValue, + zColorFieldValue, + zEnumFieldValue, + zFloatFieldCollectionValue, + zFloatFieldValue, + zFloatGeneratorFieldValue, + zImageFieldCollectionValue, + zImageFieldValue, + zImageGeneratorFieldValue, + zIntegerFieldCollectionValue, + zIntegerFieldValue, + zIntegerGeneratorFieldValue, + zModelIdentifierFieldValue, + zSchedulerFieldValue, + zStatefulFieldValue, + zStringFieldCollectionValue, + zStringFieldValue, + zStringGeneratorFieldValue, +} from 'features/nodes/types/field'; +import type { AnyNode } from 'features/nodes/types/invocation'; +import { isInvocationNode } from 'features/nodes/types/invocation'; +import type { ContainerElement } from 'features/nodes/types/workflow'; +import { isContainerElement } from 'features/nodes/types/workflow'; +import type { z } from 'zod'; + +import { selectCanvasWorkflow } from './canvasWorkflowSlice'; + +/** + * This slice holds a shadow copy of canvas workflow nodes in the same format as the nodes slice. + * This allows the existing field components to work without modification. + * + * The nodes in this slice are completely separate from the workflow tab nodes. + */ + +const getInitialState = (): NodesState => ({ + _version: 1, + formFieldInitialValues: {}, + name: '', + author: '', + description: '', + version: '', + contact: '', + tags: '', + notes: '', + exposedFields: [], + meta: { version: '3.0.0', category: 'user' }, + form: { + elements: { + root: { + id: 'root', + type: 'container', + data: { + layout: 'column', + children: [], + }, + }, + }, + rootElementId: 'root', + }, + nodes: [], + edges: [], + id: undefined, +}); + +type FieldValueAction = PayloadAction<{ + nodeId: string; + fieldName: string; + value: T; +}>; + +const fieldValueReducer = ( + state: NodesState, + action: FieldValueAction, + schema: z.ZodType +) => { + const { nodeId, fieldName, value } = action.payload; + const nodeIndex = state.nodes.findIndex((n) => n.id === nodeId); + const node = state.nodes?.[nodeIndex]; + if (!isInvocationNode(node)) { + return; + } + const field = node.data?.inputs[fieldName]; + if (!field) { + return; + } + const result = schema.safeParse(value); + if (!result.success) { + return; + } + field.value = result.data; +}; + +const slice = createSlice({ + name: 'canvasWorkflowNodes', + initialState: getInitialState(), + reducers: {}, + extraReducers(builder) { + // addCase must come before addMatcher + builder.addCase(selectCanvasWorkflow.fulfilled, (state, action) => { + const { workflow, inputNodeId } = action.payload; + const { nodes, edges, ...workflowExtra } = workflow; + + // Filter out form elements that reference the canvas input node + // The input node is the canvas_composite_raster_input that will be populated by the graph builder + const filteredForm = { + ...workflowExtra.form, + elements: { ...workflowExtra.form.elements }, + }; + + const rootElement = filteredForm.elements[filteredForm.rootElementId]; + if (rootElement && 'data' in rootElement && rootElement.data && 'children' in rootElement.data) { + // Recursively filter out node field elements for the canvas input node + const filterNodeFields = (elementId: string): boolean => { + const element = filteredForm.elements[elementId]; + if (!element) { + return false; + } + + if (element.type === 'node-field') { + const nodeId = element.data.fieldIdentifier.nodeId; + // Exclude fields from the canvas input node only + if (nodeId === inputNodeId) { + delete filteredForm.elements[elementId]; + return false; + } + } + + if (isContainerElement(element)) { + // Filter children and update the container + const filteredChildren = element.data.children.filter(filterNodeFields); + const updatedElement: ContainerElement = { + ...element, + data: { + ...element.data, + children: filteredChildren, + }, + }; + filteredForm.elements[elementId] = updatedElement; + } + + return true; + }; + + // Start filtering from root + if (isContainerElement(rootElement)) { + const filteredChildren = rootElement.data.children.filter(filterNodeFields); + const updatedRootElement: ContainerElement = { + ...rootElement, + data: { + ...rootElement.data, + children: filteredChildren, + }, + }; + filteredForm.elements[filteredForm.rootElementId] = updatedRootElement; + } + } + + const formFieldInitialValues = getFormFieldInitialValues(filteredForm, nodes); + + const loadedNodes = nodes.map((node: AnyNode) => ({ ...SHARED_NODE_PROPERTIES, ...node })); + + // Load the canvas workflow into shadow nodes with filtered form + return { + ...getInitialState(), + ...deepClone(workflowExtra), + form: filteredForm, + formFieldInitialValues, + nodes: loadedNodes, + edges, + }; + }); + builder.addCase(selectCanvasWorkflow.rejected, () => { + return getInitialState(); + }); + + // Listen for field mutation actions from nodesSlice and handle them if they're for canvas workflow + // addMatcher must come after addCase + builder.addMatcher( + isAnyOf( + nodesSliceActions.fieldValueReset, + nodesSliceActions.fieldStringValueChanged, + nodesSliceActions.fieldStringCollectionValueChanged, + nodesSliceActions.fieldIntegerValueChanged, + nodesSliceActions.fieldFloatValueChanged, + nodesSliceActions.fieldFloatCollectionValueChanged, + nodesSliceActions.fieldIntegerCollectionValueChanged, + nodesSliceActions.fieldBooleanValueChanged, + nodesSliceActions.fieldBoardValueChanged, + nodesSliceActions.fieldImageValueChanged, + nodesSliceActions.fieldImageCollectionValueChanged, + nodesSliceActions.fieldColorValueChanged, + nodesSliceActions.fieldModelIdentifierValueChanged, + nodesSliceActions.fieldEnumModelValueChanged, + nodesSliceActions.fieldSchedulerValueChanged, + nodesSliceActions.fieldFloatGeneratorValueChanged, + nodesSliceActions.fieldIntegerGeneratorValueChanged, + nodesSliceActions.fieldStringGeneratorValueChanged, + nodesSliceActions.fieldImageGeneratorValueChanged + ), + ( + state, + action: PayloadAction<{ nodeId: string; fieldName: string; value: StatefulFieldValue }> & UnknownAction + ) => { + // Only handle if this is a canvas workflow action + if (!isCanvasWorkflowAction(action)) { + return; + } + + // Determine which schema to use based on action type + const actionType = action.type; + let schema; + if (actionType.includes('String')) { + schema = zStringFieldValue; + } else if (actionType.includes('StringCollection')) { + schema = zStringFieldCollectionValue; + } else if ( + actionType.includes('Integer') && + !actionType.includes('Generator') && + !actionType.includes('Collection') + ) { + schema = zIntegerFieldValue; + } else if (actionType.includes('IntegerCollection')) { + schema = zIntegerFieldCollectionValue; + } else if ( + actionType.includes('Float') && + !actionType.includes('Generator') && + !actionType.includes('Collection') + ) { + schema = zFloatFieldValue; + } else if (actionType.includes('FloatCollection')) { + schema = zFloatFieldCollectionValue; + } else if (actionType.includes('Boolean')) { + schema = zBooleanFieldValue; + } else if (actionType.includes('Board')) { + schema = zBoardFieldValue; + } else if ( + actionType.includes('Image') && + !actionType.includes('Generator') && + !actionType.includes('Collection') + ) { + schema = zImageFieldValue; + } else if (actionType.includes('ImageCollection')) { + schema = zImageFieldCollectionValue; + } else if (actionType.includes('Color')) { + schema = zColorFieldValue; + } else if (actionType.includes('ModelIdentifier')) { + schema = zModelIdentifierFieldValue; + } else if (actionType.includes('Enum')) { + schema = zEnumFieldValue; + } else if (actionType.includes('Scheduler')) { + schema = zSchedulerFieldValue; + } else if (actionType.includes('FloatGenerator')) { + schema = zFloatGeneratorFieldValue; + } else if (actionType.includes('IntegerGenerator')) { + schema = zIntegerGeneratorFieldValue; + } else if (actionType.includes('StringGenerator')) { + schema = zStringGeneratorFieldValue; + } else if (actionType.includes('ImageGenerator')) { + schema = zImageGeneratorFieldValue; + } else { + schema = zStatefulFieldValue; + } + + fieldValueReducer(state, action, schema); + } + ); + }, +}); + +// No need to export these actions anymore - they are handled via action routing +// export const { ... } = slice.actions; + +export const canvasWorkflowNodesSliceConfig: SliceConfig = { + slice, + schema: zNodesState, + getInitialState, + persistConfig: { + migrate: (state) => state as NodesState, + // Only persist nodes and edges - field changes should persist, but not other workflow metadata + persistDenylist: [ + '_version', + 'formFieldInitialValues', + 'name', + 'author', + 'description', + 'version', + 'contact', + 'tags', + 'notes', + 'exposedFields', + 'meta', + 'form', + 'id', + ], + }, +}; + +export const selectCanvasWorkflowNodesSlice = (state: RootState) => state.canvasWorkflowNodes; diff --git a/invokeai/frontend/web/src/features/controlLayers/store/canvasWorkflowSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/canvasWorkflowSlice.ts new file mode 100644 index 00000000000..5c62da245c5 --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/store/canvasWorkflowSlice.ts @@ -0,0 +1,287 @@ +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import { logger } from 'app/logging/logger'; +import type { RootState } from 'app/store/store'; +import type { SliceConfig } from 'app/store/types'; +import { parseify } from 'common/util/serialize'; +import { $templates, getFormFieldInitialValues } from 'features/nodes/store/nodesSlice'; +import type { NodesState, Templates } from 'features/nodes/store/types'; +import { getInvocationNodeErrors } from 'features/nodes/store/util/fieldValidators'; +import type { StatefulFieldValue } from 'features/nodes/types/field'; +import type { WorkflowV3 } from 'features/nodes/types/workflow'; +import { isWorkflowInvocationNode, zWorkflowV3 } from 'features/nodes/types/workflow'; +import { validateWorkflow } from 'features/nodes/util/workflow/validateWorkflow'; +import { serializeError } from 'serialize-error'; +import { boardsApi } from 'services/api/endpoints/boards'; +import { imagesApi } from 'services/api/endpoints/images'; +import { modelsApi } from 'services/api/endpoints/models'; +import { workflowsApi } from 'services/api/endpoints/workflows'; +import { z } from 'zod'; + +const log = logger('canvas'); + +const zCanvasWorkflowState = z.object({ + selectedWorkflowId: z.string().nullable(), + workflow: zWorkflowV3.nullable(), + inputNodeId: z.string().nullable(), + outputNodeId: z.string().nullable(), + fieldValues: z.record(z.string(), z.any()), + status: z.enum(['idle', 'loading', 'succeeded', 'failed']), + error: z.string().nullable(), +}); + +export type CanvasWorkflowState = z.infer; + +const getInitialState = (): CanvasWorkflowState => ({ + selectedWorkflowId: null, + workflow: null, + inputNodeId: null, + outputNodeId: null, + fieldValues: {}, + status: 'idle', + error: null, +}); + +const INPUT_TAG = 'canvas-workflow-input'; +const OUTPUT_TAG = 'canvas-workflow-output'; + +const validateCanvasWorkflow = async ( + workflow: unknown, + templates: Templates, + checkImageAccess: (name: string) => Promise, + checkBoardAccess: (id: string) => Promise, + checkModelAccess: (key: string) => Promise +): Promise<{ workflow: WorkflowV3; inputNodeId: string; outputNodeId: string }> => { + // First, use the robust validateWorkflow utility to handle parsing, migration, and general validation + const { workflow: validatedWorkflow, warnings } = await validateWorkflow({ + workflow, + templates, + checkImageAccess, + checkBoardAccess, + checkModelAccess, + }); + + // Log any warnings from validation + if (warnings.length > 0) { + log.warn({ warnings }, 'Canvas workflow validation warnings'); + } + + // Now perform canvas-specific validation + const invocationNodes = validatedWorkflow.nodes.filter(isWorkflowInvocationNode); + + const inputNodes = invocationNodes.filter((node) => { + const template = templates[node.data.type]; + return Boolean(template && template.tags.includes(INPUT_TAG)); + }); + + const outputNodes = invocationNodes.filter((node) => { + const template = templates[node.data.type]; + return Boolean(template && template.tags.includes(OUTPUT_TAG)); + }); + + if (inputNodes.length === 0) { + throw new Error('A canvas workflow must include at least one input node with the "canvas-workflow-input" tag.'); + } + + if (inputNodes.length > 1) { + throw new Error( + `A canvas workflow must include exactly one input node, but found ${inputNodes.length}. Remove extra input nodes.` + ); + } + + if (outputNodes.length === 0) { + throw new Error('A canvas workflow must include at least one output node with the "canvas-workflow-output" tag.'); + } + + if (outputNodes.length > 1) { + throw new Error( + `A canvas workflow must include exactly one output node, but found ${outputNodes.length}. Remove extra output nodes.` + ); + } + + const inputNode = inputNodes[0]!; + const outputNode = outputNodes[0]!; + + const inputTemplate = templates[inputNode.data.type]; + if (!inputTemplate) { + throw new Error(`Input node template "${inputNode.data.type}" not found.`); + } + if (!('image' in inputTemplate.inputs)) { + throw new Error('Canvas input node must expose an image field.'); + } + + const outputTemplate = templates[outputNode.data.type]; + if (!outputTemplate) { + throw new Error(`Output node template "${outputNode.data.type}" not found.`); + } + if (!('image' in outputTemplate.inputs)) { + throw new Error('Canvas output node must accept an image input field named "image".'); + } + + // Validate that required fields without connections have values using the existing field validator + // Create a temporary nodes state for validation - only nodes and edges are used by the validator + const tempNodesState = { + nodes: invocationNodes, + edges: validatedWorkflow.edges, + } as NodesState; + + for (const node of invocationNodes) { + const errors = getInvocationNodeErrors(node.id, templates, tempNodesState); + + // Filter out "no image input" errors for the input node - it will be populated by the graph builder + const relevantErrors = errors.filter((error) => { + if (error.type === 'field-error' && error.nodeId === inputNode.id && error.fieldName === 'image') { + return false; // Skip validation for the input node's image field + } + return true; + }); + + if (relevantErrors.length > 0) { + const firstError = relevantErrors[0]; + if (firstError) { + if (firstError.type === 'field-error') { + throw new Error(`${firstError.prefix}: ${firstError.issue}`); + } else { + throw new Error(`Node "${node.id}": ${firstError.issue}`); + } + } + } + } + + return { workflow: validatedWorkflow, inputNodeId: inputNode.id, outputNodeId: outputNode.id }; +}; + +export const selectCanvasWorkflow = createAsyncThunk< + { + workflowId: string; + workflow: WorkflowV3; + inputNodeId: string; + outputNodeId: string; + fieldValues: Record; + }, + string, + { rejectValue: string } +>('canvasWorkflow/select', async (workflowId, { dispatch, rejectWithValue }) => { + const request = dispatch(workflowsApi.endpoints.getWorkflow.initiate(workflowId, { subscribe: false })); + try { + const result = await request.unwrap(); + const templates = $templates.get(); + if (!Object.keys(templates).length) { + throw new Error('Invocation templates are not yet available.'); + } + + // Define access check functions for workflow validation + const checkImageAccess = async (name: string): Promise => { + const imageRequest = dispatch(imagesApi.endpoints.getImageDTO.initiate(name)); + try { + await imageRequest.unwrap(); + return true; + } catch { + return false; + } finally { + imageRequest.unsubscribe(); + } + }; + + const checkBoardAccess = async (id: string): Promise => { + const boardsRequest = dispatch(boardsApi.endpoints.listAllBoards.initiate({})); + try { + const boards = await boardsRequest.unwrap(); + return boards.some((board) => board.board_id === id); + } catch { + return false; + } finally { + boardsRequest.unsubscribe(); + } + }; + + const checkModelAccess = async (key: string): Promise => { + const modelRequest = dispatch(modelsApi.endpoints.getModelConfig.initiate(key)); + try { + await modelRequest.unwrap(); + return true; + } catch { + return false; + } finally { + modelRequest.unsubscribe(); + } + }; + + // Use validateWorkflow to parse, migrate, and validate the workflow + const { workflow, inputNodeId, outputNodeId } = await validateCanvasWorkflow( + result.workflow, + templates, + checkImageAccess, + checkBoardAccess, + checkModelAccess + ); + const fieldValues = getFormFieldInitialValues(workflow.form, workflow.nodes); + return { workflowId: result.workflow_id, workflow, inputNodeId, outputNodeId, fieldValues }; + } catch (error) { + const message = error instanceof Error ? error.message : 'Unable to load workflow.'; + log.error({ error: serializeError(error as Error) }, 'Failed to load canvas workflow'); + return rejectWithValue(message); + } finally { + request.unsubscribe(); + } +}); + +const slice = createSlice({ + name: 'canvasWorkflow', + initialState: getInitialState(), + reducers: { + canvasWorkflowCleared: () => getInitialState(), + canvasWorkflowFieldValueChanged: ( + state, + action: PayloadAction<{ elementId: string; value: StatefulFieldValue }> + ) => { + state.fieldValues[action.payload.elementId] = action.payload.value; + }, + }, + extraReducers(builder) { + builder + .addCase(selectCanvasWorkflow.pending, (state) => { + state.status = 'loading'; + state.error = null; + }) + .addCase(selectCanvasWorkflow.fulfilled, (state, action) => { + state.selectedWorkflowId = action.payload.workflowId; + state.workflow = action.payload.workflow; + state.inputNodeId = action.payload.inputNodeId; + state.outputNodeId = action.payload.outputNodeId; + state.fieldValues = action.payload.fieldValues; + state.status = 'succeeded'; + state.error = null; + }) + .addCase(selectCanvasWorkflow.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.payload ?? action.error.message ?? 'Unable to load workflow.'; + }); + }, +}); + +export const { canvasWorkflowCleared } = slice.actions; + +export const canvasWorkflowSliceConfig: SliceConfig = { + slice, + schema: zCanvasWorkflowState, + getInitialState, + persistConfig: { + migrate: (state) => { + const parsed = zCanvasWorkflowState.safeParse(state); + if (!parsed.success) { + log.warn({ error: parseify(parsed.error) }, 'Failed to migrate canvas workflow state, resetting to defaults'); + return getInitialState(); + } + return { + ...parsed.data, + fieldValues: parsed.data.fieldValues ?? {}, + status: 'idle', + error: null, + } satisfies CanvasWorkflowState; + }, + persistDenylist: ['status', 'error'], + }, +}; + +export const selectCanvasWorkflowSlice = (state: RootState) => state.canvasWorkflow; diff --git a/invokeai/frontend/web/src/features/dnd/dnd.ts b/invokeai/frontend/web/src/features/dnd/dnd.ts index 0aef104869f..e8594c8123a 100644 --- a/invokeai/frontend/web/src/features/dnd/dnd.ts +++ b/invokeai/frontend/web/src/features/dnd/dnd.ts @@ -288,10 +288,10 @@ export const setNodeImageFieldImageDndTarget: DndTarget { + handler: ({ sourceData, targetData, dispatch, getState }) => { const { imageDTO } = sourceData.payload; const { fieldIdentifier } = targetData.payload; - setNodeImageFieldImage({ fieldIdentifier, imageDTO, dispatch }); + setNodeImageFieldImage({ fieldIdentifier, imageDTO, dispatch, getState }); }, }; //#endregion diff --git a/invokeai/frontend/web/src/features/imageActions/actions.ts b/invokeai/frontend/web/src/features/imageActions/actions.ts index 14d27e900c1..801b99eeeeb 100644 --- a/invokeai/frontend/web/src/features/imageActions/actions.ts +++ b/invokeai/frontend/web/src/features/imageActions/actions.ts @@ -35,6 +35,7 @@ import { import { calculateNewSize } from 'features/controlLayers/util/getScaledBoundingBoxDimensions'; import { imageToCompareChanged, selectionChanged } from 'features/gallery/store/gallerySlice'; import type { BoardId } from 'features/gallery/store/types'; +import { injectCanvasWorkflowKey, injectNodesWorkflowKey } from 'features/nodes/store/actionRouter'; import { fieldImageValueChanged } from 'features/nodes/store/nodesSlice'; import type { FieldIdentifier } from 'features/nodes/types/field'; import { upscaleInitialImageChanged } from 'features/parameters/store/upscaleSlice'; @@ -71,9 +72,37 @@ export const setNodeImageFieldImage = (arg: { imageDTO: ImageDTO; fieldIdentifier: FieldIdentifier; dispatch: AppDispatch; + getState?: AppGetState; }) => { - const { imageDTO, fieldIdentifier, dispatch } = arg; - dispatch(fieldImageValueChanged({ ...fieldIdentifier, value: imageDTO })); + const { imageDTO, fieldIdentifier, dispatch, getState } = arg; + + // Create the action + const action = fieldImageValueChanged({ ...fieldIdentifier, value: imageDTO }); + + // Only inject workflow routing metadata if getState is available (DND path) + // Otherwise, the action will be handled by useAppDispatch (UI component path) + if (getState) { + // Check if this node belongs to canvas workflow or regular nodes workflow + // We need to check the active tab to determine which workflow is currently being used + const state = getState(); + const activeTab = state.ui.activeTab; + const canvasWorkflowNode = state.canvasWorkflowNodes.nodes.find((n) => n.id === fieldIdentifier.nodeId); + + // Determine which workflow to route to based on active tab and node presence + // Priority: active tab determines the workflow, as the same workflow might be loaded in both slices + const shouldUseCanvasWorkflow = activeTab === 'canvas' && canvasWorkflowNode; + + // Inject the appropriate workflow routing metadata + if (shouldUseCanvasWorkflow) { + // This is a canvas workflow node - inject canvas workflow key + injectCanvasWorkflowKey(action); + } else { + // This is a regular nodes workflow node - inject nodes workflow key + injectNodesWorkflowKey(action); + } + } + + dispatch(action); }; export const setComparisonImage = (arg: { image_name: string; dispatch: AppDispatch }) => { diff --git a/invokeai/frontend/web/src/features/nodes/components/NodesWorkflowProvider.tsx b/invokeai/frontend/web/src/features/nodes/components/NodesWorkflowProvider.tsx new file mode 100644 index 00000000000..350190eb296 --- /dev/null +++ b/invokeai/frontend/web/src/features/nodes/components/NodesWorkflowProvider.tsx @@ -0,0 +1,15 @@ +import { WorkflowContext } from 'app/store/workflowContext'; +import type { PropsWithChildren } from 'react'; +import { memo, useMemo } from 'react'; + +/** + * Provider that marks the nodes/workflow editor context. + * This ensures field actions are routed to the nodes slice, not the canvas workflow slice. + */ +export const NodesWorkflowProvider = memo(({ children }: PropsWithChildren) => { + const value = useMemo(() => ({ isCanvasWorkflow: false }), []); + + return {children}; +}); + +NodesWorkflowProvider.displayName = 'NodesWorkflowProvider'; diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/context.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/context.tsx index 8618511d77d..ec458840542 100644 --- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/context.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/context.tsx @@ -47,7 +47,7 @@ type InvocationNodeContextValue = { selectNodeNeedsUpdate: Selector; }; -const InvocationNodeContext = createContext(null); +export const InvocationNodeContext = createContext(null); const getSelectorFromCache = (cache: Map, key: string, fallback: () => T): T => { let selector = cache.get(key); diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowListMenu/WorkflowListMenuTrigger.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowListMenu/WorkflowListMenuTrigger.tsx index f83c460ded4..6642f5634b3 100644 --- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowListMenu/WorkflowListMenuTrigger.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/sidePanel/WorkflowListMenu/WorkflowListMenuTrigger.tsx @@ -2,6 +2,7 @@ import { Button, Text } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { selectWorkflowName } from 'features/nodes/store/selectors'; import { useWorkflowLibraryModal } from 'features/nodes/store/workflowLibraryModal'; +import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { PiFolderOpenFill } from 'react-icons/pi'; @@ -10,8 +11,12 @@ export const WorkflowListMenuTrigger = () => { const { t } = useTranslation(); const workflowName = useAppSelector(selectWorkflowName); + const onClick = useCallback(() => { + workflowLibraryModal.open(); + }, [workflowLibraryModal]); + return ( - + + + + + + + + ); + } return ( diff --git a/invokeai/frontend/web/src/features/ui/layouts/workflows-tab-auto-layout.tsx b/invokeai/frontend/web/src/features/ui/layouts/workflows-tab-auto-layout.tsx index 06ae423e447..41bc05b4c48 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/workflows-tab-auto-layout.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/workflows-tab-auto-layout.tsx @@ -4,6 +4,7 @@ import { BoardsPanel } from 'features/gallery/components/BoardsListPanelContent' import { GalleryPanel } from 'features/gallery/components/Gallery'; import { ImageViewerPanel } from 'features/gallery/components/ImageViewer/ImageViewerPanel'; import NodeEditor from 'features/nodes/components/NodeEditor'; +import { NodesWorkflowProvider } from 'features/nodes/components/NodesWorkflowProvider'; import WorkflowsTabLeftPanel from 'features/nodes/components/sidePanel/WorkflowsTabLeftPanel'; import { FloatingLeftPanelButtons } from 'features/ui/components/FloatingLeftPanelButtons'; import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightPanelButtons'; @@ -53,9 +54,17 @@ const tabComponents = { [DOCKVIEW_TAB_LAUNCHPAD_ID]: DockviewTabLaunchpad, }; +// Wrap NodeEditor with NodesWorkflowProvider to ensure action routing works correctly +const NodeEditorWithProvider = memo(() => ( + + + +)); +NodeEditorWithProvider.displayName = 'NodeEditorWithProvider'; + const mainPanelComponents: AutoLayoutDockviewComponents = { [LAUNCHPAD_PANEL_ID]: withPanelContainer(WorkflowsLaunchpadPanel), - [WORKSPACE_PANEL_ID]: withPanelContainer(NodeEditor), + [WORKSPACE_PANEL_ID]: withPanelContainer(NodeEditorWithProvider), [VIEWER_PANEL_ID]: withPanelContainer(ImageViewerPanel), }; diff --git a/invokeai/frontend/web/src/services/api/schema.ts b/invokeai/frontend/web/src/services/api/schema.ts index a7964ce12ae..b224fdb2cd3 100644 --- a/invokeai/frontend/web/src/services/api/schema.ts +++ b/invokeai/frontend/web/src/services/api/schema.ts @@ -4166,6 +4166,47 @@ export type components = { */ type: "canny_edge_detection"; }; + /** + * Canvas Composite Input + * @description Provides the flattened canvas raster layer to a workflow. + */ + CanvasCompositeRasterInputInvocation: { + /** + * @description The board to save the image to + * @default null + */ + board?: components["schemas"]["BoardField"] | null; + /** + * @description Optional metadata to be saved with the image + * @default null + */ + metadata?: components["schemas"]["MetadataField"] | 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 true + */ + use_cache?: boolean; + /** @description The flattened canvas raster layer. */ + image: components["schemas"]["ImageField"]; + /** + * type + * @default canvas_composite_raster_input + * @constant + */ + type: "canvas_composite_raster_input"; + }; /** * Canvas Paste Back * @description Combines two images by using the mask provided. Intended for use on the Unified Canvas. @@ -4286,6 +4327,50 @@ export type components = { */ type: "canvas_v2_mask_and_crop"; }; + /** + * Canvas Workflow Output + * @description Designates the workflow image output used by the canvas. + */ + CanvasWorkflowOutputInvocation: { + /** + * @description The board to save the image to + * @default null + */ + board?: components["schemas"]["BoardField"] | null; + /** + * @description Optional metadata to be saved with the image + * @default null + */ + metadata?: components["schemas"]["MetadataField"] | 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 true + */ + use_cache?: boolean; + /** + * @description The workflow's resulting image. + * @default null + */ + image?: components["schemas"]["ImageField"] | null; + /** + * type + * @default canvas_workflow_output + * @constant + */ + type: "canvas_workflow_output"; + }; /** * Center Pad or Crop Image * @description Pad or crop an image's sides from the center by specified pixels. Positive values are outside of the image. @@ -9351,7 +9436,7 @@ export type components = { * @description The nodes in this graph */ nodes?: { - [key: string]: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; + [key: string]: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasCompositeRasterInputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CanvasWorkflowOutputInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; }; /** * Edges @@ -12184,7 +12269,7 @@ export type components = { * Invocation * @description The ID of the invocation */ - invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; + invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasCompositeRasterInputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CanvasWorkflowOutputInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; /** * Invocation Source Id * @description The ID of the prepared invocation's source node @@ -12242,7 +12327,7 @@ export type components = { * Invocation * @description The ID of the invocation */ - invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; + invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasCompositeRasterInputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CanvasWorkflowOutputInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; /** * Invocation Source Id * @description The ID of the prepared invocation's source node @@ -12289,8 +12374,10 @@ export type components = { calculate_image_tiles_even_split: components["schemas"]["CalculateImageTilesOutput"]; calculate_image_tiles_min_overlap: components["schemas"]["CalculateImageTilesOutput"]; canny_edge_detection: components["schemas"]["ImageOutput"]; + canvas_composite_raster_input: components["schemas"]["ImageOutput"]; canvas_paste_back: components["schemas"]["ImageOutput"]; canvas_v2_mask_and_crop: components["schemas"]["ImageOutput"]; + canvas_workflow_output: components["schemas"]["ImageOutput"]; clip_skip: components["schemas"]["CLIPSkipInvocationOutput"]; cogview4_denoise: components["schemas"]["LatentsOutput"]; cogview4_i2l: components["schemas"]["LatentsOutput"]; @@ -12535,7 +12622,7 @@ export type components = { * Invocation * @description The ID of the invocation */ - invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; + invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasCompositeRasterInputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CanvasWorkflowOutputInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; /** * Invocation Source Id * @description The ID of the prepared invocation's source node @@ -12604,7 +12691,7 @@ export type components = { * Invocation * @description The ID of the invocation */ - invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; + invocation: components["schemas"]["AddInvocation"] | components["schemas"]["AlphaMaskToTensorInvocation"] | components["schemas"]["ApplyMaskTensorToImageInvocation"] | components["schemas"]["ApplyMaskToImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["BoundingBoxInvocation"] | components["schemas"]["CLIPSkipInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["CannyEdgeDetectionInvocation"] | components["schemas"]["CanvasCompositeRasterInputInvocation"] | components["schemas"]["CanvasPasteBackInvocation"] | components["schemas"]["CanvasV2MaskAndCropInvocation"] | components["schemas"]["CanvasWorkflowOutputInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["CogView4DenoiseInvocation"] | components["schemas"]["CogView4ImageToLatentsInvocation"] | components["schemas"]["CogView4LatentsToImageInvocation"] | components["schemas"]["CogView4ModelLoaderInvocation"] | components["schemas"]["CogView4TextEncoderInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ColorMapInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ContentShuffleInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CropImageToBoundingBoxInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["DWOpenposeDetectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["DenoiseLatentsMetaInvocation"] | components["schemas"]["DepthAnythingDepthEstimationInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ExpandMaskWithFadeInvocation"] | components["schemas"]["FLUXLoRACollectionLoader"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["FloatBatchInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FloatGenerator"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["FluxControlLoRALoaderInvocation"] | components["schemas"]["FluxControlNetInvocation"] | components["schemas"]["FluxDenoiseInvocation"] | components["schemas"]["FluxDenoiseLatentsMetaInvocation"] | components["schemas"]["FluxFillInvocation"] | components["schemas"]["FluxIPAdapterInvocation"] | components["schemas"]["FluxKontextConcatenateImagesInvocation"] | components["schemas"]["FluxKontextInvocation"] | components["schemas"]["FluxLoRALoaderInvocation"] | components["schemas"]["FluxModelLoaderInvocation"] | components["schemas"]["FluxReduxInvocation"] | components["schemas"]["FluxTextEncoderInvocation"] | components["schemas"]["FluxVaeDecodeInvocation"] | components["schemas"]["FluxVaeEncodeInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["GetMaskBoundingBoxInvocation"] | components["schemas"]["GroundingDinoInvocation"] | components["schemas"]["HEDEdgeDetectionInvocation"] | components["schemas"]["HeuristicResizeInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["ImageBatchInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageGenerator"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageMaskToTensorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageNoiseInvocation"] | components["schemas"]["ImagePanelLayoutInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["IntegerBatchInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["IntegerGenerator"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["InvertTensorMaskInvocation"] | components["schemas"]["InvokeAdjustImageHuePlusInvocation"] | components["schemas"]["InvokeEquivalentAchromaticLightnessInvocation"] | components["schemas"]["InvokeImageBlendInvocation"] | components["schemas"]["InvokeImageCompositorInvocation"] | components["schemas"]["InvokeImageDilateOrErodeInvocation"] | components["schemas"]["InvokeImageEnhanceInvocation"] | components["schemas"]["InvokeImageValueThresholdsInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["LineartAnimeEdgeDetectionInvocation"] | components["schemas"]["LineartEdgeDetectionInvocation"] | components["schemas"]["LlavaOnevisionVllmInvocation"] | components["schemas"]["LoRACollectionLoader"] | components["schemas"]["LoRALoaderInvocation"] | components["schemas"]["LoRASelectorInvocation"] | components["schemas"]["MLSDDetectionInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MaskFromIDInvocation"] | components["schemas"]["MaskTensorToImageInvocation"] | components["schemas"]["MediaPipeFaceDetectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["MetadataFieldExtractorInvocation"] | components["schemas"]["MetadataFromImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["MetadataItemLinkedInvocation"] | components["schemas"]["MetadataToBoolCollectionInvocation"] | components["schemas"]["MetadataToBoolInvocation"] | components["schemas"]["MetadataToControlnetsInvocation"] | components["schemas"]["MetadataToFloatCollectionInvocation"] | components["schemas"]["MetadataToFloatInvocation"] | components["schemas"]["MetadataToIPAdaptersInvocation"] | components["schemas"]["MetadataToIntegerCollectionInvocation"] | components["schemas"]["MetadataToIntegerInvocation"] | components["schemas"]["MetadataToLorasCollectionInvocation"] | components["schemas"]["MetadataToLorasInvocation"] | components["schemas"]["MetadataToModelInvocation"] | components["schemas"]["MetadataToSDXLLorasInvocation"] | components["schemas"]["MetadataToSDXLModelInvocation"] | components["schemas"]["MetadataToSchedulerInvocation"] | components["schemas"]["MetadataToStringCollectionInvocation"] | components["schemas"]["MetadataToStringInvocation"] | components["schemas"]["MetadataToT2IAdaptersInvocation"] | components["schemas"]["MetadataToVAEInvocation"] | components["schemas"]["ModelIdentifierInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["NormalMapInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["PasteImageIntoBoundingBoxInvocation"] | components["schemas"]["PiDiNetEdgeDetectionInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RectangleMaskInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SD3DenoiseInvocation"] | components["schemas"]["SD3ImageToLatentsInvocation"] | components["schemas"]["SD3LatentsToImageInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLLoRACollectionLoader"] | components["schemas"]["SDXLLoRALoaderInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["Sd3ModelLoaderInvocation"] | components["schemas"]["Sd3TextEncoderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["SegmentAnythingInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SpandrelImageToImageAutoscaleInvocation"] | components["schemas"]["SpandrelImageToImageInvocation"] | components["schemas"]["StringBatchInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["StringGenerator"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["TiledMultiDiffusionDenoiseLatents"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["VAELoaderInvocation"]; /** * Invocation Source Id * @description The ID of the prepared invocation's source node