Merge branch 'main' into nodepromptsize

This commit is contained in:
mickr777
2023-07-29 12:43:29 +10:00
committed by GitHub
239 changed files with 10360 additions and 8889 deletions

View File

@@ -1,3 +1,3 @@
'''
"""
Initialization file for invokeai.frontend.web
'''
"""

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -12,7 +12,7 @@
margin: 0;
}
</style>
<script type="module" crossorigin src="./assets/index-e2437518.js"></script>
<script type="module" crossorigin src="./assets/index-bad7ff83.js"></script>
</head>
<body dir="ltr">

View File

@@ -23,6 +23,7 @@
"menu": "Menu"
},
"common": {
"communityLabel": "Community",
"hotkeysLabel": "Hotkeys",
"darkMode": "Dark Mode",
"lightMode": "Light Mode",
@@ -102,8 +103,7 @@
"openInNewTab": "Open in New Tab",
"dontAskMeAgain": "Don't ask me again",
"areYouSure": "Are you sure?",
"imagePrompt": "Image Prompt",
"clearNodes": "Are you sure you want to clear all nodes?"
"imagePrompt": "Image Prompt"
},
"gallery": {
"generations": "Generations",
@@ -340,6 +340,7 @@
"allModels": "All Models",
"checkpointModels": "Checkpoints",
"diffusersModels": "Diffusers",
"loraModels": "LoRAs",
"safetensorModels": "SafeTensors",
"modelAdded": "Model Added",
"modelUpdated": "Model Updated",
@@ -615,6 +616,11 @@
"initialImageNotSetDesc": "Could not load initial image",
"nodesSaved": "Nodes Saved",
"nodesLoaded": "Nodes Loaded",
"nodesNotValidGraph": "Not a valid InvokeAI Node Graph",
"nodesNotValidJSON": "Not a valid JSON",
"nodesCorruptedGraph": "Cannot load. Graph seems to be corrupted.",
"nodesUnrecognizedTypes": "Cannot load. Graph has unrecognized types",
"nodesBrokenConnections": "Cannot load. Some connections are broken.",
"nodesLoadedFailed": "Failed To Load Nodes",
"nodesCleared": "Nodes Cleared"
},
@@ -700,9 +706,10 @@
},
"nodes": {
"reloadSchema": "Reload Schema",
"saveNodes": "Save Nodes",
"loadNodes": "Load Nodes",
"clearNodes": "Clear Nodes",
"saveGraph": "Save Graph",
"loadGraph": "Load Graph (saved from Node Editor) (Do not copy-paste metadata)",
"clearGraph": "Clear Graph",
"clearGraphDesc": "Are you sure you want to clear all nodes?",
"zoomInNodes": "Zoom In",
"zoomOutNodes": "Zoom Out",
"fitViewportNodes": "Fit View",

View File

@@ -53,11 +53,11 @@
]
},
"dependencies": {
"@chakra-ui/anatomy": "^2.1.1",
"@chakra-ui/anatomy": "^2.2.0",
"@chakra-ui/icons": "^2.0.19",
"@chakra-ui/react": "^2.7.1",
"@chakra-ui/react": "^2.8.0",
"@chakra-ui/styled-system": "^2.9.1",
"@chakra-ui/theme-tools": "^2.0.18",
"@chakra-ui/theme-tools": "^2.1.0",
"@dagrejs/graphlib": "^2.1.13",
"@dnd-kit/core": "^6.0.8",
"@dnd-kit/modifiers": "^6.0.1",

View File

@@ -23,6 +23,7 @@
"menu": "Menu"
},
"common": {
"communityLabel": "Community",
"hotkeysLabel": "Hotkeys",
"darkMode": "Dark Mode",
"lightMode": "Light Mode",
@@ -339,6 +340,7 @@
"allModels": "All Models",
"checkpointModels": "Checkpoints",
"diffusersModels": "Diffusers",
"loraModels": "LoRAs",
"safetensorModels": "SafeTensors",
"modelAdded": "Model Added",
"modelUpdated": "Model Updated",

View File

@@ -1,4 +1,8 @@
import { setInfillMethod } from 'features/parameters/store/generationSlice';
import {
shouldUseNSFWCheckerChanged,
shouldUseWatermarkerChanged,
} from 'features/system/store/systemSlice';
import { appInfoApi } from 'services/api/endpoints/appInfo';
import { startAppListening } from '..';
@@ -6,12 +10,24 @@ export const addAppConfigReceivedListener = () => {
startAppListening({
matcher: appInfoApi.endpoints.getAppConfig.matchFulfilled,
effect: async (action, { getState, dispatch }) => {
const { infill_methods } = action.payload;
const {
infill_methods = [],
nsfw_methods = [],
watermarking_methods = [],
} = action.payload;
const infillMethod = getState().generation.infillMethod;
if (!infill_methods.includes(infillMethod)) {
dispatch(setInfillMethod(infill_methods[0]));
}
if (!nsfw_methods.includes('nsfw_checker')) {
dispatch(shouldUseNSFWCheckerChanged(false));
}
if (!watermarking_methods.includes('invisible_watermark')) {
dispatch(shouldUseWatermarkerChanged(false));
}
},
});
};

View File

@@ -1,13 +1,10 @@
import { logger } from 'app/logging/logger';
import { LIST_TAG } from 'services/api';
import { appInfoApi } from 'services/api/endpoints/appInfo';
import { modelsApi } from 'services/api/endpoints/models';
import { receivedOpenAPISchema } from 'services/api/thunks/schema';
import { appSocketConnected, socketConnected } from 'services/events/actions';
import { startAppListening } from '../..';
import {
ALL_BASE_MODELS,
NON_REFINER_BASE_MODELS,
REFINER_BASE_MODELS,
} from 'services/api/constants';
export const addSocketConnectedEventListener = () => {
startAppListening({
@@ -29,15 +26,18 @@ export const addSocketConnectedEventListener = () => {
dispatch(appSocketConnected(action.payload));
// update all server state
dispatch(modelsApi.endpoints.getMainModels.initiate(REFINER_BASE_MODELS));
dispatch(
modelsApi.endpoints.getMainModels.initiate(NON_REFINER_BASE_MODELS)
modelsApi.util.invalidateTags([
{ type: 'MainModel', id: LIST_TAG },
{ type: 'SDXLRefinerModel', id: LIST_TAG },
{ type: 'LoRAModel', id: LIST_TAG },
{ type: 'ControlNetModel', id: LIST_TAG },
{ type: 'VaeModel', id: LIST_TAG },
{ type: 'TextualInversionModel', id: LIST_TAG },
{ type: 'ScannedModels', id: LIST_TAG },
])
);
dispatch(modelsApi.endpoints.getMainModels.initiate(ALL_BASE_MODELS));
dispatch(modelsApi.endpoints.getControlNetModels.initiate());
dispatch(modelsApi.endpoints.getLoRAModels.initiate());
dispatch(modelsApi.endpoints.getTextualInversionModels.initiate());
dispatch(modelsApi.endpoints.getVaeModels.initiate());
dispatch(appInfoApi.util.invalidateTags(['AppConfig', 'AppVersion']));
},
});
};

View File

@@ -114,6 +114,11 @@ const IAISlider = (props: IAIFullSliderProps) => {
setLocalInputValue(value);
}, [value]);
const numberInputMin = useMemo(
() => (sliderNumberInputProps?.min ? sliderNumberInputProps.min : min),
[min, sliderNumberInputProps?.min]
);
const numberInputMax = useMemo(
() => (sliderNumberInputProps?.max ? sliderNumberInputProps.max : max),
[max, sliderNumberInputProps?.max]
@@ -129,24 +134,23 @@ const IAISlider = (props: IAIFullSliderProps) => {
const handleInputBlur = useCallback(
(e: FocusEvent<HTMLInputElement>) => {
if (e.target.value === '') {
e.target.value = String(min);
e.target.value = String(numberInputMin);
}
const clamped = clamp(
isInteger
? Math.floor(Number(e.target.value))
: Number(localInputValue),
min,
numberInputMin,
numberInputMax
);
const quantized = roundDownToMultiple(clamped, step);
onChange(quantized);
setLocalInputValue(quantized);
},
[isInteger, localInputValue, min, numberInputMax, onChange, step]
[isInteger, localInputValue, numberInputMin, numberInputMax, onChange, step]
);
const handleInputChange = useCallback((v: number | string) => {
console.log('input');
setLocalInputValue(v);
}, []);
@@ -310,7 +314,7 @@ const IAISlider = (props: IAIFullSliderProps) => {
{withInput && (
<NumberInput
min={min}
min={numberInputMin}
max={numberInputMax}
step={step}
value={localInputValue}

View File

@@ -5,8 +5,8 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
// import { validateSeedWeights } from 'common/util/seedWeightPairs';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { forEach } from 'lodash-es';
import { NON_REFINER_BASE_MODELS } from 'services/api/constants';
import { modelsApi } from '../../services/api/endpoints/models';
import { ALL_BASE_MODELS } from 'services/api/constants';
const readinessSelector = createSelector(
[stateSelector, activeTabNameSelector],
@@ -25,7 +25,7 @@ const readinessSelector = createSelector(
}
const { isSuccess: mainModelsSuccessfullyLoaded } =
modelsApi.endpoints.getMainModels.select(ALL_BASE_MODELS)(state);
modelsApi.endpoints.getMainModels.select(NON_REFINER_BASE_MODELS)(state);
if (!mainModelsSuccessfullyLoaded) {
isReady = false;
reasonsWhyNotReady.push('Models are not loaded');

View File

@@ -57,6 +57,11 @@ const ParamEmbeddingPopover = (props: Props) => {
});
});
// Sort Alphabetically
data.sort((a, b) =>
a.label && b.label ? (a.label?.localeCompare(b.label) ? -1 : 1) : -1
);
return data.sort((a, b) => (a.disabled && !b.disabled ? 1 : -1));
}, [embeddingQueryData, currentMainModel?.base_model]);

View File

@@ -1,5 +1,6 @@
import { Link, MenuItem } from '@chakra-ui/react';
import { MenuItem } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { skipToken } from '@reduxjs/toolkit/dist/query';
import { useAppToaster } from 'app/components/Toaster';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
@@ -33,10 +34,9 @@ import {
useRemoveImageFromBoardMutation,
} from 'services/api/endpoints/images';
import { ImageDTO } from 'services/api/types';
import { useDebounce } from 'use-debounce';
import { AddImageToBoardContext } from '../../../../app/contexts/AddImageToBoardContext';
import { sentImageToCanvas, sentImageToImg2Img } from '../../store/actions';
import { useDebounce } from 'use-debounce';
import { skipToken } from '@reduxjs/toolkit/dist/query';
type SingleSelectionMenuItemsProps = {
imageDTO: ImageDTO;
@@ -154,21 +154,29 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
return (
<>
<Link href={imageDTO.image_url} target="_blank">
<MenuItem icon={<FaExternalLinkAlt />}>
{t('common.openInNewTab')}
</MenuItem>
</Link>
<MenuItem
as="a"
href={imageDTO.image_url}
target="_blank"
icon={<FaExternalLinkAlt />}
>
{t('common.openInNewTab')}
</MenuItem>
{isClipboardAPIAvailable && (
<MenuItem icon={<FaCopy />} onClickCapture={handleCopyImage}>
{t('parameters.copyImage')}
</MenuItem>
)}
<Link download={true} href={imageDTO.image_url} target="_blank">
<MenuItem icon={<FaDownload />} w="100%">
{t('parameters.downloadImage')}
</MenuItem>
</Link>
<MenuItem
as="a"
download={true}
href={imageDTO.image_url}
target="_blank"
icon={<FaDownload />}
w="100%"
>
{t('parameters.downloadImage')}
</MenuItem>
<MenuItem
icon={<FaQuoteRight />}
onClickCapture={handleRecallPrompt}

View File

@@ -48,6 +48,7 @@ const ParamLora = (props: Props) => {
handleReset={handleReset}
withSliderMarks
sliderMarks={[-1, 0, 1, 2]}
sliderNumberInputProps={{ min: -50, max: 50 }}
/>
<IAIIconButton
size="sm"

View File

@@ -54,7 +54,12 @@ const ParamLoRASelect = () => {
});
});
return data.sort((a, b) => (a.disabled && !b.disabled ? 1 : -1));
// Sort Alphabetically
data.sort((a, b) =>
a.label && b.label ? (a.label?.localeCompare(b.label) ? 1 : -1) : -1
);
return data.sort((a, b) => (a.disabled && !b.disabled ? -1 : 1));
}, [loras, loraModels, currentMainModel?.base_model]);
const handleChange = useCallback(

View File

@@ -0,0 +1,70 @@
import { RootState } from 'app/store/store';
import { NonNullableGraph } from 'features/nodes/types/types';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import {
ImageNSFWBlurInvocation,
LatentsToImageInvocation,
MetadataAccumulatorInvocation,
} from 'services/api/types';
import {
LATENTS_TO_IMAGE,
METADATA_ACCUMULATOR,
NSFW_CHECKER,
} from './constants';
export const addNSFWCheckerToGraph = (
state: RootState,
graph: NonNullableGraph,
nodeIdToAddTo = LATENTS_TO_IMAGE
): void => {
const activeTabName = activeTabNameSelector(state);
const is_intermediate =
activeTabName === 'unifiedCanvas' ? !state.canvas.shouldAutoSave : false;
const nodeToAddTo = graph.nodes[nodeIdToAddTo] as
| LatentsToImageInvocation
| undefined;
const metadataAccumulator = graph.nodes[METADATA_ACCUMULATOR] as
| MetadataAccumulatorInvocation
| undefined;
if (!nodeToAddTo) {
// something has gone terribly awry
return;
}
nodeToAddTo.is_intermediate = true;
const nsfwCheckerNode: ImageNSFWBlurInvocation = {
id: NSFW_CHECKER,
type: 'img_nsfw',
is_intermediate,
};
graph.nodes[NSFW_CHECKER] = nsfwCheckerNode;
graph.edges.push({
source: {
node_id: nodeIdToAddTo,
field: 'image',
},
destination: {
node_id: NSFW_CHECKER,
field: 'image',
},
});
if (metadataAccumulator) {
graph.edges.push({
source: {
node_id: METADATA_ACCUMULATOR,
field: 'metadata',
},
destination: {
node_id: NSFW_CHECKER,
field: 'metadata',
},
});
}
};

View File

@@ -0,0 +1,95 @@
import { RootState } from 'app/store/store';
import { NonNullableGraph } from 'features/nodes/types/types';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import {
ImageNSFWBlurInvocation,
ImageWatermarkInvocation,
LatentsToImageInvocation,
MetadataAccumulatorInvocation,
} from 'services/api/types';
import {
LATENTS_TO_IMAGE,
METADATA_ACCUMULATOR,
NSFW_CHECKER,
WATERMARKER,
} from './constants';
export const addWatermarkerToGraph = (
state: RootState,
graph: NonNullableGraph,
nodeIdToAddTo = LATENTS_TO_IMAGE
): void => {
const activeTabName = activeTabNameSelector(state);
const is_intermediate =
activeTabName === 'unifiedCanvas' ? !state.canvas.shouldAutoSave : false;
const nodeToAddTo = graph.nodes[nodeIdToAddTo] as
| LatentsToImageInvocation
| undefined;
const nsfwCheckerNode = graph.nodes[NSFW_CHECKER] as
| ImageNSFWBlurInvocation
| undefined;
const metadataAccumulator = graph.nodes[METADATA_ACCUMULATOR] as
| MetadataAccumulatorInvocation
| undefined;
if (!nodeToAddTo) {
// something has gone terribly awry
return;
}
const watermarkerNode: ImageWatermarkInvocation = {
id: WATERMARKER,
type: 'img_watermark',
is_intermediate,
};
graph.nodes[WATERMARKER] = watermarkerNode;
// no matter the situation, we want the l2i node to be intermediate
nodeToAddTo.is_intermediate = true;
if (nsfwCheckerNode) {
// if we are using NSFW checker, we need to "disable" it output by marking it intermediate,
// then connect it to the watermark node
nsfwCheckerNode.is_intermediate = true;
graph.edges.push({
source: {
node_id: NSFW_CHECKER,
field: 'image',
},
destination: {
node_id: WATERMARKER,
field: 'image',
},
});
} else {
// otherwise we just connect to the watermark node
graph.edges.push({
source: {
node_id: nodeIdToAddTo,
field: 'image',
},
destination: {
node_id: WATERMARKER,
field: 'image',
},
});
}
if (metadataAccumulator) {
graph.edges.push({
source: {
node_id: METADATA_ACCUMULATOR,
field: 'metadata',
},
destination: {
node_id: WATERMARKER,
field: 'metadata',
},
});
}
};

View File

@@ -10,7 +10,9 @@ import {
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
import { addLoRAsToGraph } from './addLoRAsToGraph';
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
import { addVAEToGraph } from './addVAEToGraph';
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
import {
CLIP_SKIP,
IMAGE_TO_IMAGE_GRAPH,
@@ -103,11 +105,6 @@ export const buildCanvasImageToImageGraph = (
is_intermediate: true,
skipped_layers: clipSkip,
},
[LATENTS_TO_IMAGE]: {
is_intermediate: !shouldAutoSave,
type: 'l2i',
id: LATENTS_TO_IMAGE,
},
[LATENTS_TO_LATENTS]: {
type: 'l2l',
id: LATENTS_TO_LATENTS,
@@ -126,6 +123,11 @@ export const buildCanvasImageToImageGraph = (
// image_name: initialImage.image_name,
// },
},
[LATENTS_TO_IMAGE]: {
type: 'l2i',
id: LATENTS_TO_IMAGE,
is_intermediate: !shouldAutoSave,
},
},
edges: [
{
@@ -333,5 +335,16 @@ export const buildCanvasImageToImageGraph = (
// add controlnet, mutating `graph`
addControlNetToLinearGraph(state, graph, LATENTS_TO_LATENTS);
// NSFW & watermark - must be last thing added to graph
if (state.system.shouldUseNSFWChecker) {
// must add before watermarker!
addNSFWCheckerToGraph(state, graph);
}
if (state.system.shouldUseWatermarker) {
// must add after nsfw checker!
addWatermarkerToGraph(state, graph);
}
return graph;
};

View File

@@ -8,7 +8,9 @@ import {
RangeOfSizeInvocation,
} from 'services/api/types';
import { addLoRAsToGraph } from './addLoRAsToGraph';
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
import { addVAEToGraph } from './addVAEToGraph';
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
import {
CLIP_SKIP,
INPAINT,
@@ -249,5 +251,16 @@ export const buildCanvasInpaintGraph = (
(graph.nodes[RANGE_OF_SIZE] as RangeOfSizeInvocation).start = seed;
}
// NSFW & watermark - must be last thing added to graph
if (state.system.shouldUseNSFWChecker) {
// must add before watermarker!
addNSFWCheckerToGraph(state, graph, INPAINT);
}
if (state.system.shouldUseWatermarker) {
// must add after nsfw checker!
addWatermarkerToGraph(state, graph, INPAINT);
}
return graph;
};

View File

@@ -5,7 +5,9 @@ import { initialGenerationState } from 'features/parameters/store/generationSlic
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
import { addLoRAsToGraph } from './addLoRAsToGraph';
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
import { addVAEToGraph } from './addVAEToGraph';
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
import {
CLIP_SKIP,
LATENTS_TO_IMAGE,
@@ -238,5 +240,16 @@ export const buildCanvasTextToImageGraph = (
// add controlnet, mutating `graph`
addControlNetToLinearGraph(state, graph, TEXT_TO_LATENTS);
// NSFW & watermark - must be last thing added to graph
if (state.system.shouldUseNSFWChecker) {
// must add before watermarker!
addNSFWCheckerToGraph(state, graph);
}
if (state.system.shouldUseWatermarker) {
// must add after nsfw checker!
addWatermarkerToGraph(state, graph);
}
return graph;
};

View File

@@ -9,7 +9,9 @@ import {
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
import { addLoRAsToGraph } from './addLoRAsToGraph';
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
import { addVAEToGraph } from './addVAEToGraph';
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
import {
CLIP_SKIP,
IMAGE_TO_IMAGE_GRAPH,
@@ -297,42 +299,6 @@ export const buildLinearImageToImageGraph = (
});
}
// TODO: add batch functionality
// if (isBatchEnabled && asInitialImage && batchImageNames.length > 0) {
// // we are going to connect an iterate up to the init image
// delete (graph.nodes[IMAGE_TO_LATENTS] as ImageToLatentsInvocation).image;
// const imageCollection: ImageCollectionInvocation = {
// id: IMAGE_COLLECTION,
// type: 'image_collection',
// images: batchImageNames.map((image_name) => ({ image_name })),
// };
// const imageCollectionIterate: IterateInvocation = {
// id: IMAGE_COLLECTION_ITERATE,
// type: 'iterate',
// };
// graph.nodes[IMAGE_COLLECTION] = imageCollection;
// graph.nodes[IMAGE_COLLECTION_ITERATE] = imageCollectionIterate;
// graph.edges.push({
// source: { node_id: IMAGE_COLLECTION, field: 'collection' },
// destination: {
// node_id: IMAGE_COLLECTION_ITERATE,
// field: 'collection',
// },
// });
// graph.edges.push({
// source: { node_id: IMAGE_COLLECTION_ITERATE, field: 'item' },
// destination: {
// node_id: IMAGE_TO_LATENTS,
// field: 'image',
// },
// });
// }
// add metadata accumulator, which is only mostly populated - some fields are added later
graph.nodes[METADATA_ACCUMULATOR] = {
id: METADATA_ACCUMULATOR,
@@ -379,5 +345,16 @@ export const buildLinearImageToImageGraph = (
// add controlnet, mutating `graph`
addControlNetToLinearGraph(state, graph, LATENTS_TO_LATENTS);
// NSFW & watermark - must be last thing added to graph
if (state.system.shouldUseNSFWChecker) {
// must add before watermarker!
addNSFWCheckerToGraph(state, graph);
}
if (state.system.shouldUseWatermarker) {
// must add after nsfw checker!
addWatermarkerToGraph(state, graph);
}
return graph;
};

View File

@@ -7,7 +7,9 @@ import {
ImageToLatentsInvocation,
} from 'services/api/types';
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
import { addSDXLRefinerToGraph } from './addSDXLRefinerToGraph';
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
import {
IMAGE_TO_LATENTS,
LATENTS_TO_IMAGE,
@@ -48,6 +50,7 @@ export const buildLinearSDXLImageToImageGraph = (
const {
positiveStylePrompt,
negativeStylePrompt,
shouldConcatSDXLStylePrompt,
shouldUseSDXLRefiner,
refinerStart,
sdxlImg2ImgDenoisingStrength: strength,
@@ -89,13 +92,17 @@ export const buildLinearSDXLImageToImageGraph = (
type: 'sdxl_compel_prompt',
id: POSITIVE_CONDITIONING,
prompt: positivePrompt,
style: positiveStylePrompt,
style: shouldConcatSDXLStylePrompt
? `${positivePrompt} ${positiveStylePrompt}`
: positiveStylePrompt,
},
[NEGATIVE_CONDITIONING]: {
type: 'sdxl_compel_prompt',
id: NEGATIVE_CONDITIONING,
prompt: negativePrompt,
style: negativeStylePrompt,
style: shouldConcatSDXLStylePrompt
? `${negativePrompt} ${negativeStylePrompt}`
: negativeStylePrompt,
},
[NOISE]: {
type: 'noise',
@@ -365,5 +372,16 @@ export const buildLinearSDXLImageToImageGraph = (
// add dynamic prompts - also sets up core iteration and seed
addDynamicPromptsToGraph(state, graph);
// NSFW & watermark - must be last thing added to graph
if (state.system.shouldUseNSFWChecker) {
// must add before watermarker!
addNSFWCheckerToGraph(state, graph);
}
if (state.system.shouldUseWatermarker) {
// must add after nsfw checker!
addWatermarkerToGraph(state, graph);
}
return graph;
};

View File

@@ -3,7 +3,9 @@ import { RootState } from 'app/store/store';
import { NonNullableGraph } from 'features/nodes/types/types';
import { initialGenerationState } from 'features/parameters/store/generationSlice';
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
import { addSDXLRefinerToGraph } from './addSDXLRefinerToGraph';
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
import {
LATENTS_TO_IMAGE,
METADATA_ACCUMULATOR,
@@ -37,6 +39,7 @@ export const buildLinearSDXLTextToImageGraph = (
const {
positiveStylePrompt,
negativeStylePrompt,
shouldConcatSDXLStylePrompt,
shouldUseSDXLRefiner,
refinerStart,
} = state.sdxl;
@@ -72,13 +75,17 @@ export const buildLinearSDXLTextToImageGraph = (
type: 'sdxl_compel_prompt',
id: POSITIVE_CONDITIONING,
prompt: positivePrompt,
style: positiveStylePrompt,
style: shouldConcatSDXLStylePrompt
? `${positivePrompt} ${positiveStylePrompt}`
: positiveStylePrompt,
},
[NEGATIVE_CONDITIONING]: {
type: 'sdxl_compel_prompt',
id: NEGATIVE_CONDITIONING,
prompt: negativePrompt,
style: negativeStylePrompt,
style: shouldConcatSDXLStylePrompt
? `${negativePrompt} ${negativeStylePrompt}`
: negativeStylePrompt,
},
[NOISE]: {
type: 'noise',
@@ -247,5 +254,16 @@ export const buildLinearSDXLTextToImageGraph = (
// add dynamic prompts - also sets up core iteration and seed
addDynamicPromptsToGraph(state, graph);
// NSFW & watermark - must be last thing added to graph
if (state.system.shouldUseNSFWChecker) {
// must add before watermarker!
addNSFWCheckerToGraph(state, graph);
}
if (state.system.shouldUseWatermarker) {
// must add after nsfw checker!
addWatermarkerToGraph(state, graph);
}
return graph;
};

View File

@@ -5,7 +5,9 @@ import { initialGenerationState } from 'features/parameters/store/generationSlic
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
import { addLoRAsToGraph } from './addLoRAsToGraph';
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
import { addVAEToGraph } from './addVAEToGraph';
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
import {
CLIP_SKIP,
LATENTS_TO_IMAGE,
@@ -227,5 +229,16 @@ export const buildLinearTextToImageGraph = (
// add controlnet, mutating `graph`
addControlNetToLinearGraph(state, graph, TEXT_TO_LATENTS);
// NSFW & watermark - must be last thing added to graph
if (state.system.shouldUseNSFWChecker) {
// must add before watermarker!
addNSFWCheckerToGraph(state, graph);
}
if (state.system.shouldUseWatermarker) {
// must add after nsfw checker!
addWatermarkerToGraph(state, graph);
}
return graph;
};

View File

@@ -3,6 +3,8 @@ export const POSITIVE_CONDITIONING = 'positive_conditioning';
export const NEGATIVE_CONDITIONING = 'negative_conditioning';
export const TEXT_TO_LATENTS = 'text_to_latents';
export const LATENTS_TO_IMAGE = 'latents_to_image';
export const NSFW_CHECKER = 'nsfw_checker';
export const WATERMARKER = 'invisible_watermark';
export const NOISE = 'noise';
export const RANDOM_INT = 'rand_int';
export const RANGE_OF_SIZE = 'range_of_size';

View File

@@ -7,9 +7,9 @@ import { activeTabNameSelector } from '../../../../ui/store/uiSelectors';
const aspectRatios = [
{ name: 'Free', value: null },
{ name: 'Portrait', value: 0.67 / 1 },
{ name: 'Wide', value: 16 / 9 },
{ name: 'Square', value: 1 / 1 },
{ name: '2:3', value: 2 / 3 },
{ name: '16:9', value: 16 / 9 },
{ name: '1:1', value: 1 / 1 },
];
export default function ParamAspectRatio() {

View File

@@ -148,7 +148,7 @@ const ParamPositiveConditioning = () => {
<Box
sx={{
position: 'absolute',
top: shouldPinParametersPanel ? 6 : 0,
top: shouldPinParametersPanel ? 5 : 0,
insetInlineEnd: 0,
}}
>

View File

@@ -0,0 +1,17 @@
import { Flex } from '@chakra-ui/react';
import ParamNegativeConditioning from 'features/parameters/components/Parameters/Core/ParamNegativeConditioning';
import ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning';
export default function ParamPromptArea() {
return (
<Flex
sx={{
flexDirection: 'column',
gap: 2,
}}
>
<ParamPositiveConditioning />
<ParamNegativeConditioning />
</Flex>
);
}

View File

@@ -1,3 +1,5 @@
import { components } from 'services/api/schema';
export const MODEL_TYPE_MAP = {
'sd-1': 'Stable Diffusion 1.x',
'sd-2': 'Stable Diffusion 2.x',
@@ -5,6 +7,13 @@ export const MODEL_TYPE_MAP = {
'sdxl-refiner': 'Stable Diffusion XL Refiner',
};
export const MODEL_TYPE_SHORT_MAP = {
'sd-1': 'SD1',
'sd-2': 'SD2',
sdxl: 'SDXL',
'sdxl-refiner': 'SDXLR',
};
export const clipSkipMap = {
'sd-1': {
maxClip: 12,
@@ -23,3 +32,12 @@ export const clipSkipMap = {
markers: [0, 1, 2, 3, 5, 10, 15, 20, 24],
},
};
type LoRAModelFormatMap = {
[key in components['schemas']['LoRAModelFormat']]: string;
};
export const LORA_MODEL_FORMAT_MAP: LoRAModelFormatMap = {
lycoris: 'LyCORIS',
diffusers: 'Diffusers',
};

View File

@@ -0,0 +1,43 @@
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIIconButton from 'common/components/IAIIconButton';
import { FaLink } from 'react-icons/fa';
import { setShouldConcatSDXLStylePrompt } from '../store/sdxlSlice';
export default function ParamSDXLConcatButton() {
const shouldConcatSDXLStylePrompt = useAppSelector(
(state: RootState) => state.sdxl.shouldConcatSDXLStylePrompt
);
const shouldPinParametersPanel = useAppSelector(
(state: RootState) => state.ui.shouldPinParametersPanel
);
const dispatch = useAppDispatch();
const handleShouldConcatPromptChange = () => {
dispatch(setShouldConcatSDXLStylePrompt(!shouldConcatSDXLStylePrompt));
};
return (
<IAIIconButton
aria-label="Concat"
tooltip="Concatenates Basic Prompt with Style (Recommended)"
variant="outline"
isChecked={shouldConcatSDXLStylePrompt}
onClick={handleShouldConcatPromptChange}
icon={<FaLink />}
size="xs"
sx={{
position: 'absolute',
insetInlineEnd: 1,
top: shouldPinParametersPanel ? 12 : 20,
border: 'none',
color: shouldConcatSDXLStylePrompt ? 'accent.500' : 'base.500',
_hover: {
bg: 'none',
},
}}
></IAIIconButton>
);
}

View File

@@ -13,15 +13,20 @@ import { useIsReadyToInvoke } from 'common/hooks/useIsReadyToInvoke';
import AddEmbeddingButton from 'features/embedding/components/AddEmbeddingButton';
import ParamEmbeddingPopover from 'features/embedding/components/ParamEmbeddingPopover';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { AnimatePresence } from 'framer-motion';
import { isEqual } from 'lodash-es';
import { flushSync } from 'react-dom';
import { setNegativeStylePromptSDXL } from '../store/sdxlSlice';
import SDXLConcatLink from './SDXLConcatLink';
const promptInputSelector = createSelector(
[stateSelector, activeTabNameSelector],
({ sdxl }, activeTabName) => {
const { negativeStylePrompt, shouldConcatSDXLStylePrompt } = sdxl;
return {
prompt: sdxl.negativeStylePrompt,
prompt: negativeStylePrompt,
shouldConcatSDXLStylePrompt,
activeTabName,
};
},
@@ -37,11 +42,13 @@ const promptInputSelector = createSelector(
*/
const ParamSDXLNegativeStyleConditioning = () => {
const dispatch = useAppDispatch();
const { prompt, activeTabName } = useAppSelector(promptInputSelector);
const isReady = useIsReadyToInvoke();
const promptRef = useRef<HTMLTextAreaElement>(null);
const { isOpen, onClose, onOpen } = useDisclosure();
const { prompt, activeTabName, shouldConcatSDXLStylePrompt } =
useAppSelector(promptInputSelector);
const handleChangePrompt = useCallback(
(e: ChangeEvent<HTMLTextAreaElement>) => {
dispatch(setNegativeStylePromptSDXL(e.target.value));
@@ -111,6 +118,20 @@ const ParamSDXLNegativeStyleConditioning = () => {
return (
<Box position="relative">
<AnimatePresence>
{shouldConcatSDXLStylePrompt && (
<Box
sx={{
position: 'absolute',
left: '3',
w: '94%',
top: '-17px',
}}
>
<SDXLConcatLink />
</Box>
)}
</AnimatePresence>
<FormControl>
<ParamEmbeddingPopover
isOpen={isOpen}

View File

@@ -13,15 +13,20 @@ import { useIsReadyToInvoke } from 'common/hooks/useIsReadyToInvoke';
import AddEmbeddingButton from 'features/embedding/components/AddEmbeddingButton';
import ParamEmbeddingPopover from 'features/embedding/components/ParamEmbeddingPopover';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { AnimatePresence } from 'framer-motion';
import { isEqual } from 'lodash-es';
import { flushSync } from 'react-dom';
import { setPositiveStylePromptSDXL } from '../store/sdxlSlice';
import SDXLConcatLink from './SDXLConcatLink';
const promptInputSelector = createSelector(
[stateSelector, activeTabNameSelector],
({ sdxl }, activeTabName) => {
const { positiveStylePrompt, shouldConcatSDXLStylePrompt } = sdxl;
return {
prompt: sdxl.positiveStylePrompt,
prompt: positiveStylePrompt,
shouldConcatSDXLStylePrompt,
activeTabName,
};
},
@@ -37,11 +42,13 @@ const promptInputSelector = createSelector(
*/
const ParamSDXLPositiveStyleConditioning = () => {
const dispatch = useAppDispatch();
const { prompt, activeTabName } = useAppSelector(promptInputSelector);
const isReady = useIsReadyToInvoke();
const promptRef = useRef<HTMLTextAreaElement>(null);
const { isOpen, onClose, onOpen } = useDisclosure();
const { prompt, activeTabName, shouldConcatSDXLStylePrompt } =
useAppSelector(promptInputSelector);
const handleChangePrompt = useCallback(
(e: ChangeEvent<HTMLTextAreaElement>) => {
dispatch(setPositiveStylePromptSDXL(e.target.value));
@@ -111,6 +118,20 @@ const ParamSDXLPositiveStyleConditioning = () => {
return (
<Box position="relative">
<AnimatePresence>
{shouldConcatSDXLStylePrompt && (
<Box
sx={{
position: 'absolute',
left: '3',
w: '94%',
top: '-17px',
}}
>
<SDXLConcatLink />
</Box>
)}
</AnimatePresence>
<FormControl>
<ParamEmbeddingPopover
isOpen={isOpen}

View File

@@ -0,0 +1,23 @@
import { Flex } from '@chakra-ui/react';
import ParamNegativeConditioning from 'features/parameters/components/Parameters/Core/ParamNegativeConditioning';
import ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning';
import ParamSDXLConcatButton from './ParamSDXLConcatButton';
import ParamSDXLNegativeStyleConditioning from './ParamSDXLNegativeStyleConditioning';
import ParamSDXLPositiveStyleConditioning from './ParamSDXLPositiveStyleConditioning';
export default function ParamSDXLPromptArea() {
return (
<Flex
sx={{
flexDirection: 'column',
gap: 2,
}}
>
<ParamPositiveConditioning />
<ParamSDXLConcatButton />
<ParamSDXLPositiveStyleConditioning />
<ParamNegativeConditioning />
<ParamSDXLNegativeStyleConditioning />
</Flex>
);
}

View File

@@ -0,0 +1,101 @@
import { Box, Flex } from '@chakra-ui/react';
import { CSSObject } from '@emotion/react';
import { motion } from 'framer-motion';
import { FaLink } from 'react-icons/fa';
const sharedConcatLinkStyle: CSSObject = {
position: 'absolute',
bg: 'none',
w: 'full',
minH: 2,
borderRadius: 0,
borderLeft: 'none',
borderRight: 'none',
zIndex: 2,
maskImage:
'radial-gradient(circle at center, black, black 65%, black 30%, black 15%, transparent)',
};
export default function SDXLConcatLink() {
return (
<Flex>
<Box
as={motion.div}
initial={{
scaleX: 0,
borderWidth: 0,
display: 'none',
}}
animate={{
display: ['block', 'block', 'block', 'none'],
scaleX: [0, 0.25, 0.5, 1],
borderWidth: [0, 3, 3, 0],
transition: { duration: 0.37, times: [0, 0.25, 0.5, 1] },
}}
sx={{
top: '1px',
borderTop: 'none',
borderColor: 'base.400',
...sharedConcatLinkStyle,
_dark: {
borderColor: 'accent.500',
},
}}
/>
<Box
as={motion.div}
initial={{
opacity: 0,
scale: 0,
}}
animate={{
opacity: [0, 1, 1, 1],
scale: [0, 0.75, 1.5, 1],
transition: { duration: 0.42, times: [0, 0.25, 0.5, 1] },
}}
exit={{
opacity: 0,
scale: 0,
}}
sx={{
zIndex: 3,
position: 'absolute',
left: '48%',
top: '3px',
p: 1,
borderRadius: 4,
bg: 'accent.400',
color: 'base.50',
_dark: {
bg: 'accent.500',
},
}}
>
<FaLink size={12} />
</Box>
<Box
as={motion.div}
initial={{
scaleX: 0,
borderWidth: 0,
display: 'none',
}}
animate={{
display: ['block', 'block', 'block', 'none'],
scaleX: [0, 0.25, 0.5, 1],
borderWidth: [0, 3, 3, 0],
transition: { duration: 0.37, times: [0, 0.25, 0.5, 1] },
}}
sx={{
top: '17px',
borderBottom: 'none',
borderColor: 'base.400',
...sharedConcatLinkStyle,
_dark: {
borderColor: 'accent.500',
},
}}
/>
</Flex>
);
}

View File

@@ -1,21 +1,14 @@
import ParamDynamicPromptsCollapse from 'features/dynamicPrompts/components/ParamDynamicPromptsCollapse';
import ParamNegativeConditioning from 'features/parameters/components/Parameters/Core/ParamNegativeConditioning';
import ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning';
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
// import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import ParamSDXLNegativeStyleConditioning from './ParamSDXLNegativeStyleConditioning';
import ParamSDXLPositiveStyleConditioning from './ParamSDXLPositiveStyleConditioning';
import ParamSDXLPromptArea from './ParamSDXLPromptArea';
import ParamSDXLRefinerCollapse from './ParamSDXLRefinerCollapse';
import SDXLImageToImageTabCoreParameters from './SDXLImageToImageTabCoreParameters';
const SDXLImageToImageTabParameters = () => {
return (
<>
<ParamPositiveConditioning />
<ParamSDXLPositiveStyleConditioning />
<ParamNegativeConditioning />
<ParamSDXLNegativeStyleConditioning />
<ParamSDXLPromptArea />
<ProcessButtons />
<SDXLImageToImageTabCoreParameters />
<ParamSDXLRefinerCollapse />

View File

@@ -1,20 +1,14 @@
import ParamDynamicPromptsCollapse from 'features/dynamicPrompts/components/ParamDynamicPromptsCollapse';
import ParamNegativeConditioning from 'features/parameters/components/Parameters/Core/ParamNegativeConditioning';
import ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning';
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import TextToImageTabCoreParameters from 'features/ui/components/tabs/TextToImage/TextToImageTabCoreParameters';
import ParamSDXLNegativeStyleConditioning from './ParamSDXLNegativeStyleConditioning';
import ParamSDXLPositiveStyleConditioning from './ParamSDXLPositiveStyleConditioning';
import ParamSDXLPromptArea from './ParamSDXLPromptArea';
import ParamSDXLRefinerCollapse from './ParamSDXLRefinerCollapse';
const SDXLTextToImageTabParameters = () => {
return (
<>
<ParamPositiveConditioning />
<ParamSDXLPositiveStyleConditioning />
<ParamNegativeConditioning />
<ParamSDXLNegativeStyleConditioning />
<ParamSDXLPromptArea />
<ProcessButtons />
<TextToImageTabCoreParameters />
<ParamSDXLRefinerCollapse />

View File

@@ -10,6 +10,7 @@ import { MainModelField } from 'services/api/types';
type SDXLInitialState = {
positiveStylePrompt: PositiveStylePromptSDXLParam;
negativeStylePrompt: NegativeStylePromptSDXLParam;
shouldConcatSDXLStylePrompt: boolean;
shouldUseSDXLRefiner: boolean;
sdxlImg2ImgDenoisingStrength: number;
refinerModel: MainModelField | null;
@@ -23,6 +24,7 @@ type SDXLInitialState = {
const sdxlInitialState: SDXLInitialState = {
positiveStylePrompt: '',
negativeStylePrompt: '',
shouldConcatSDXLStylePrompt: true,
shouldUseSDXLRefiner: false,
sdxlImg2ImgDenoisingStrength: 0.7,
refinerModel: null,
@@ -43,6 +45,9 @@ const sdxlSlice = createSlice({
setNegativeStylePromptSDXL: (state, action: PayloadAction<string>) => {
state.negativeStylePrompt = action.payload;
},
setShouldConcatSDXLStylePrompt: (state, action: PayloadAction<boolean>) => {
state.shouldConcatSDXLStylePrompt = action.payload;
},
setShouldUseSDXLRefiner: (state, action: PayloadAction<boolean>) => {
state.shouldUseSDXLRefiner = action.payload;
},
@@ -76,6 +81,7 @@ const sdxlSlice = createSlice({
export const {
setPositiveStylePromptSDXL,
setNegativeStylePromptSDXL,
setShouldConcatSDXLStylePrompt,
setShouldUseSDXLRefiner,
setSDXLImg2ImgDenoisingStrength,
refinerModelChanged,

View File

@@ -1,32 +0,0 @@
import { useColorMode } from '@chakra-ui/react';
import IAIIconButton from 'common/components/IAIIconButton';
import { useTranslation } from 'react-i18next';
import { FaMoon, FaSun } from 'react-icons/fa';
const ColorModeButton = () => {
const { colorMode, toggleColorMode } = useColorMode();
const { t } = useTranslation();
return (
<IAIIconButton
aria-label={
colorMode === 'dark' ? t('common.lightMode') : t('common.darkMode')
}
tooltip={
colorMode === 'dark' ? t('common.lightMode') : t('common.darkMode')
}
size="sm"
icon={
colorMode === 'dark' ? (
<FaSun fontSize={19} />
) : (
<FaMoon fontSize={18} />
)
}
onClick={toggleColorMode}
variant="link"
/>
);
};
export default ColorModeButton;

View File

@@ -1,50 +0,0 @@
import {
IconButton,
Menu,
MenuButton,
MenuItemOption,
MenuList,
MenuOptionGroup,
Tooltip,
} from '@chakra-ui/react';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { map } from 'lodash-es';
import { useTranslation } from 'react-i18next';
import { IoLanguage } from 'react-icons/io5';
import { LANGUAGES } from '../store/constants';
import { languageSelector } from '../store/systemSelectors';
import { languageChanged } from '../store/systemSlice';
export default function LanguagePicker() {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const language = useAppSelector(languageSelector);
return (
<Menu closeOnSelect={false}>
<Tooltip label={t('common.languagePickerLabel')} hasArrow>
<MenuButton
as={IconButton}
icon={<IoLanguage />}
variant="link"
aria-label={t('common.languagePickerLabel')}
fontSize={22}
minWidth={8}
/>
</Tooltip>
<MenuList>
<MenuOptionGroup value={language}>
{map(LANGUAGES, (languageName, l: keyof typeof LANGUAGES) => (
<MenuItemOption
key={l}
value={l}
onClick={() => dispatch(languageChanged(l))}
>
{languageName}
</MenuItemOption>
))}
</MenuOptionGroup>
</MenuList>
</Menu>
);
}

View File

@@ -10,6 +10,7 @@ import {
ModalOverlay,
Text,
useDisclosure,
useColorMode,
} from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { VALID_LOG_LEVELS } from 'app/logging/logger';
@@ -26,6 +27,8 @@ import {
setShouldConfirmOnDelete,
shouldAntialiasProgressImageChanged,
shouldLogToConsoleChanged,
shouldUseNSFWCheckerChanged,
shouldUseWatermarkerChanged,
} from 'features/system/store/systemSlice';
import {
setShouldShowProgressInViewer,
@@ -42,10 +45,15 @@ import {
} from 'react';
import { useTranslation } from 'react-i18next';
import { LogLevelName } from 'roarr';
import { useGetAppConfigQuery } from 'services/api/endpoints/appInfo';
import SettingSwitch from './SettingSwitch';
import SettingsClearIntermediates from './SettingsClearIntermediates';
import SettingsSchedulers from './SettingsSchedulers';
import StyledFlex from './StyledFlex';
import { useFeatureStatus } from '../../hooks/useFeatureStatus';
import { LANGUAGES } from '../../store/constants';
import { languageChanged } from '../../store/systemSlice';
import { languageSelector } from '../../store/systemSelectors';
const selector = createSelector(
[stateSelector],
@@ -57,6 +65,8 @@ const selector = createSelector(
shouldLogToConsole,
shouldAntialiasProgressImage,
isNodesEnabled,
shouldUseNSFWChecker,
shouldUseWatermarker,
} = system;
const {
@@ -78,6 +88,8 @@ const selector = createSelector(
shouldAntialiasProgressImage,
shouldShowAdvancedOptions,
isNodesEnabled,
shouldUseNSFWChecker,
shouldUseWatermarker,
};
},
{
@@ -92,6 +104,7 @@ type ConfigOptions = {
shouldShowAdvancedOptionsSettings: boolean;
shouldShowClearIntermediates: boolean;
shouldShowNodesToggle: boolean;
shouldShowLocalizationToggle: boolean;
};
type SettingsModalProps = {
@@ -113,6 +126,8 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
const shouldShowClearIntermediates =
config?.shouldShowClearIntermediates ?? true;
const shouldShowNodesToggle = config?.shouldShowNodesToggle ?? true;
const shouldShowLocalizationToggle =
config?.shouldShowLocalizationToggle ?? true;
useEffect(() => {
if (!shouldShowDeveloperSettings) {
@@ -120,6 +135,16 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
}
}, [shouldShowDeveloperSettings, dispatch]);
const { isNSFWCheckerAvailable, isWatermarkerAvailable } =
useGetAppConfigQuery(undefined, {
selectFromResult: ({ data }) => ({
isNSFWCheckerAvailable:
data?.nsfw_methods.includes('nsfw_checker') ?? false,
isWatermarkerAvailable:
data?.watermarking_methods.includes('invisible_watermark') ?? false,
}),
});
const {
isOpen: isSettingsModalOpen,
onOpen: onSettingsModalOpen,
@@ -143,6 +168,8 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
shouldAntialiasProgressImage,
shouldShowAdvancedOptions,
isNodesEnabled,
shouldUseNSFWChecker,
shouldUseWatermarker,
} = useAppSelector(selector);
const handleClickResetWebUI = useCallback(() => {
@@ -166,6 +193,13 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
[dispatch]
);
const handleLanguageChanged = useCallback(
(l: string) => {
dispatch(languageChanged(l as keyof typeof LANGUAGES));
},
[dispatch]
);
const handleLogToConsoleChanged = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
dispatch(shouldLogToConsoleChanged(e.target.checked));
@@ -180,6 +214,12 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
[dispatch]
);
const { colorMode, toggleColorMode } = useColorMode();
const isLocalizationEnabled =
useFeatureStatus('localization').isFeatureEnabled;
const language = useAppSelector(languageSelector);
return (
<>
{cloneElement(children, {
@@ -221,10 +261,31 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
<StyledFlex>
<Heading size="sm">{t('settings.generation')}</Heading>
<SettingsSchedulers />
<SettingSwitch
label="Enable NSFW Checker"
isDisabled={!isNSFWCheckerAvailable}
isChecked={shouldUseNSFWChecker}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
dispatch(shouldUseNSFWCheckerChanged(e.target.checked))
}
/>
<SettingSwitch
label="Enable Invisible Watermark"
isDisabled={!isWatermarkerAvailable}
isChecked={shouldUseWatermarker}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
dispatch(shouldUseWatermarkerChanged(e.target.checked))
}
/>
</StyledFlex>
<StyledFlex>
<Heading size="sm">{t('settings.ui')}</Heading>
<SettingSwitch
label={t('common.darkMode')}
isChecked={colorMode === 'dark'}
onChange={toggleColorMode}
/>
<SettingSwitch
label={t('settings.useSlidersForAll')}
isChecked={shouldUseSliders}
@@ -267,6 +328,18 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
onChange={handleToggleNodes}
/>
)}
{shouldShowLocalizationToggle && (
<IAIMantineSelect
disabled={!isLocalizationEnabled}
label={t('common.languagePickerLabel')}
value={language}
data={Object.entries(LANGUAGES).map(([value, label]) => ({
value,
label,
}))}
onChange={handleLanguageChanged}
/>
)}
</StyledFlex>
{shouldShowDeveloperSettings && (

View File

@@ -10,9 +10,9 @@ import { map } from 'lodash-es';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const data = map(SCHEDULER_LABEL_MAP, (value, label) => ({
value,
label,
const data = map(SCHEDULER_LABEL_MAP, (label, name) => ({
value: name,
label: label,
})).sort((a, b) => a.label.localeCompare(b.label));
export default function SettingsSchedulers() {

View File

@@ -1,28 +1,40 @@
import { Flex, Spacer } from '@chakra-ui/react';
import { memo } from 'react';
import StatusIndicator from './StatusIndicator';
import { Link } from '@chakra-ui/react';
import {
Flex,
Menu,
MenuButton,
MenuGroup,
MenuItem,
MenuList,
Spacer,
} from '@chakra-ui/react';
import IAIIconButton from 'common/components/IAIIconButton';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { FaBug, FaDiscord, FaGithub, FaKeyboard } from 'react-icons/fa';
import { MdSettings } from 'react-icons/md';
import {
FaBars,
FaBug,
FaCog,
FaDiscord,
FaGithub,
FaKeyboard,
} from 'react-icons/fa';
import { menuListMotionProps } from 'theme/components/menu';
import { useFeatureStatus } from '../hooks/useFeatureStatus';
import ColorModeButton from './ColorModeButton';
import HotkeysModal from './HotkeysModal/HotkeysModal';
import InvokeAILogoComponent from './InvokeAILogoComponent';
import LanguagePicker from './LanguagePicker';
import SettingsModal from './SettingsModal/SettingsModal';
import StatusIndicator from './StatusIndicator';
const SiteHeader = () => {
const { t } = useTranslation();
const isLocalizationEnabled =
useFeatureStatus('localization').isFeatureEnabled;
const isBugLinkEnabled = useFeatureStatus('bugLink').isFeatureEnabled;
const isDiscordLinkEnabled = useFeatureStatus('discordLink').isFeatureEnabled;
const isGithubLinkEnabled = useFeatureStatus('githubLink').isFeatureEnabled;
const githubLink = 'http://github.com/invoke-ai/InvokeAI';
const discordLink = 'https://discord.gg/ZmtBAhwWhy';
return (
<Flex
sx={{
@@ -34,87 +46,61 @@ const SiteHeader = () => {
<Spacer />
<StatusIndicator />
<HotkeysModal>
<IAIIconButton
aria-label={t('common.hotkeysLabel')}
tooltip={t('common.hotkeysLabel')}
size="sm"
<Menu>
<MenuButton
as={IAIIconButton}
variant="link"
data-variant="link"
fontSize={20}
icon={<FaKeyboard />}
aria-label={t('accessibility.menu')}
icon={<FaBars />}
sx={{ boxSize: 8 }}
/>
</HotkeysModal>
{isLocalizationEnabled && <LanguagePicker />}
{isBugLinkEnabled && (
<Link
isExternal
href="http://github.com/invoke-ai/InvokeAI/issues"
marginBottom="-0.25rem"
>
<IAIIconButton
aria-label={t('common.reportBugLabel')}
tooltip={t('common.reportBugLabel')}
variant="link"
data-variant="link"
fontSize={20}
size="sm"
icon={<FaBug />}
/>
</Link>
)}
{isGithubLinkEnabled && (
<Link
isExternal
href="http://github.com/invoke-ai/InvokeAI"
marginBottom="-0.25rem"
>
<IAIIconButton
aria-label={t('common.githubLabel')}
tooltip={t('common.githubLabel')}
variant="link"
data-variant="link"
fontSize={20}
size="sm"
icon={<FaGithub />}
/>
</Link>
)}
{isDiscordLinkEnabled && (
<Link
isExternal
href="https://discord.gg/ZmtBAhwWhy"
marginBottom="-0.25rem"
>
<IAIIconButton
aria-label={t('common.discordLabel')}
tooltip={t('common.discordLabel')}
variant="link"
data-variant="link"
fontSize={20}
size="sm"
icon={<FaDiscord />}
/>
</Link>
)}
<ColorModeButton />
<SettingsModal>
<IAIIconButton
aria-label={t('common.settingsLabel')}
tooltip={t('common.settingsLabel')}
variant="link"
data-variant="link"
fontSize={22}
size="sm"
icon={<MdSettings />}
/>
</SettingsModal>
<MenuList motionProps={menuListMotionProps}>
<MenuGroup title={t('common.communityLabel')}>
{isGithubLinkEnabled && (
<MenuItem
as="a"
href={githubLink}
target="_blank"
icon={<FaGithub />}
>
{t('common.githubLabel')}
</MenuItem>
)}
{isBugLinkEnabled && (
<MenuItem
as="a"
href={`${githubLink}/issues`}
target="_blank"
icon={<FaBug />}
>
{t('common.reportBugLabel')}
</MenuItem>
)}
{isDiscordLinkEnabled && (
<MenuItem
as="a"
href={discordLink}
target="_blank"
icon={<FaDiscord />}
>
{t('common.discordLabel')}
</MenuItem>
)}
</MenuGroup>
<MenuGroup title={t('common.settingsLabel')}>
<HotkeysModal>
<MenuItem as="button" icon={<FaKeyboard />}>
{t('common.hotkeysLabel')}
</MenuItem>
</HotkeysModal>
<SettingsModal>
<MenuItem as="button" icon={<FaCog />}>
{t('common.settingsLabel')}
</MenuItem>
</SettingsModal>
</MenuGroup>
</MenuList>
</Menu>
</Flex>
);
};

View File

@@ -1,111 +0,0 @@
import { Flex, Link } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import { FaBug, FaDiscord, FaGithub, FaKeyboard } from 'react-icons/fa';
import { MdSettings } from 'react-icons/md';
import HotkeysModal from './HotkeysModal/HotkeysModal';
import LanguagePicker from './LanguagePicker';
import SettingsModal from './SettingsModal/SettingsModal';
import IAIIconButton from 'common/components/IAIIconButton';
import { useFeatureStatus } from '../hooks/useFeatureStatus';
const SiteHeaderMenu = () => {
const { t } = useTranslation();
const isLocalizationEnabled =
useFeatureStatus('localization').isFeatureEnabled;
const isBugLinkEnabled = useFeatureStatus('bugLink').isFeatureEnabled;
const isDiscordLinkEnabled = useFeatureStatus('discordLink').isFeatureEnabled;
const isGithubLinkEnabled = useFeatureStatus('githubLink').isFeatureEnabled;
return (
<Flex
alignItems="center"
flexDirection={{ base: 'column', xl: 'row' }}
gap={{ base: 4, xl: 1 }}
>
<HotkeysModal>
<IAIIconButton
aria-label={t('common.hotkeysLabel')}
tooltip={t('common.hotkeysLabel')}
size="sm"
variant="link"
data-variant="link"
fontSize={20}
icon={<FaKeyboard />}
/>
</HotkeysModal>
{isLocalizationEnabled && <LanguagePicker />}
{isBugLinkEnabled && (
<Link
isExternal
href="http://github.com/invoke-ai/InvokeAI/issues"
marginBottom="-0.25rem"
>
<IAIIconButton
aria-label={t('common.reportBugLabel')}
tooltip={t('common.reportBugLabel')}
variant="link"
data-variant="link"
fontSize={20}
size="sm"
icon={<FaBug />}
/>
</Link>
)}
{isGithubLinkEnabled && (
<Link
isExternal
href="http://github.com/invoke-ai/InvokeAI"
marginBottom="-0.25rem"
>
<IAIIconButton
aria-label={t('common.githubLabel')}
tooltip={t('common.githubLabel')}
variant="link"
data-variant="link"
fontSize={20}
size="sm"
icon={<FaGithub />}
/>
</Link>
)}
{isDiscordLinkEnabled && (
<Link
isExternal
href="https://discord.gg/ZmtBAhwWhy"
marginBottom="-0.25rem"
>
<IAIIconButton
aria-label={t('common.discordLabel')}
tooltip={t('common.discordLabel')}
variant="link"
data-variant="link"
fontSize={20}
size="sm"
icon={<FaDiscord />}
/>
</Link>
)}
<SettingsModal>
<IAIIconButton
aria-label={t('common.settingsLabel')}
tooltip={t('common.settingsLabel')}
variant="link"
data-variant="link"
fontSize={22}
size="sm"
icon={<MdSettings />}
/>
</SettingsModal>
</Flex>
);
};
SiteHeaderMenu.displayName = 'SiteHeaderMenu';
export default SiteHeaderMenu;

View File

@@ -87,6 +87,8 @@ export interface SystemState {
language: keyof typeof LANGUAGES;
isUploading: boolean;
isNodesEnabled: boolean;
shouldUseNSFWChecker: boolean;
shouldUseWatermarker: boolean;
}
export const initialSystemState: SystemState = {
@@ -119,6 +121,8 @@ export const initialSystemState: SystemState = {
language: 'en',
isUploading: false,
isNodesEnabled: false,
shouldUseNSFWChecker: false,
shouldUseWatermarker: false,
};
export const systemSlice = createSlice({
@@ -194,6 +198,12 @@ export const systemSlice = createSlice({
setIsNodesEnabled(state, action: PayloadAction<boolean>) {
state.isNodesEnabled = action.payload;
},
shouldUseNSFWCheckerChanged(state, action: PayloadAction<boolean>) {
state.shouldUseNSFWChecker = action.payload;
},
shouldUseWatermarkerChanged(state, action: PayloadAction<boolean>) {
state.shouldUseWatermarker = action.payload;
},
},
extraReducers(builder) {
/**
@@ -409,6 +419,8 @@ export const {
languageChanged,
progressImageSet,
setIsNodesEnabled,
shouldUseNSFWCheckerChanged,
shouldUseWatermarkerChanged,
} = systemSlice.actions;
export default systemSlice.reducer;

View File

@@ -227,7 +227,8 @@ const InvokeTabs = () => {
id="gallery"
order={3}
defaultSize={
galleryMinSizePct > DEFAULT_GALLERY_PCT
galleryMinSizePct > DEFAULT_GALLERY_PCT &&
galleryMinSizePct < 100 // prevent this error https://github.com/bvaughn/react-resizable-panels/blob/main/packages/react-resizable-panels/src/Panel.ts#L96
? galleryMinSizePct
: DEFAULT_GALLERY_PCT
}

View File

@@ -1,7 +1,10 @@
import { Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import SDXLImageToImageTabParameters from 'features/sdxl/components/SDXLImageToImageTabParameters';
import SDXLTextToImageTabParameters from 'features/sdxl/components/SDXLTextToImageTabParameters';
import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent';
import {
activeTabNameSelector,
@@ -39,13 +42,23 @@ const ParametersDrawer = () => {
dispatch(setShouldShowParametersPanel(false));
};
const model = useAppSelector((state: RootState) => state.generation.model);
const drawerContent = useMemo(() => {
if (activeTabName === 'txt2img') {
return <TextToImageTabParameters />;
return model && model.base_model === 'sdxl' ? (
<SDXLTextToImageTabParameters />
) : (
<TextToImageTabParameters />
);
}
if (activeTabName === 'img2img') {
return <ImageToImageTabParameters />;
return model && model.base_model === 'sdxl' ? (
<SDXLImageToImageTabParameters />
) : (
<ImageToImageTabParameters />
);
}
if (activeTabName === 'unifiedCanvas') {
@@ -53,7 +66,7 @@ const ParametersDrawer = () => {
}
return null;
}, [activeTabName]);
}, [activeTabName, model]);
if (shouldPinParametersPanel) {
return null;

View File

@@ -2,20 +2,18 @@ import ParamDynamicPromptsCollapse from 'features/dynamicPrompts/components/Para
import ParamLoraCollapse from 'features/lora/components/ParamLoraCollapse';
import ParamAdvancedCollapse from 'features/parameters/components/Parameters/Advanced/ParamAdvancedCollapse';
import ParamControlNetCollapse from 'features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse';
import ParamNegativeConditioning from 'features/parameters/components/Parameters/Core/ParamNegativeConditioning';
import ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning';
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
// import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse';
import ParamPromptArea from 'features/parameters/components/Parameters/Prompt/ParamPromptArea';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import ImageToImageTabCoreParameters from './ImageToImageTabCoreParameters';
const ImageToImageTabParameters = () => {
return (
<>
<ParamPositiveConditioning />
<ParamNegativeConditioning />
<ParamPromptArea />
<ProcessButtons />
<ImageToImageTabCoreParameters />
<ParamControlNetCollapse />

View File

@@ -3,20 +3,31 @@ import { Flex, Text } from '@chakra-ui/react';
import { useState } from 'react';
import {
MainModelConfigEntity,
DiffusersModelConfigEntity,
LoRAModelConfigEntity,
useGetMainModelsQuery,
useGetLoRAModelsQuery,
} from 'services/api/endpoints/models';
import CheckpointModelEdit from './ModelManagerPanel/CheckpointModelEdit';
import DiffusersModelEdit from './ModelManagerPanel/DiffusersModelEdit';
import LoRAModelEdit from './ModelManagerPanel/LoRAModelEdit';
import ModelList from './ModelManagerPanel/ModelList';
import { ALL_BASE_MODELS } from 'services/api/constants';
export default function ModelManagerPanel() {
const [selectedModelId, setSelectedModelId] = useState<string>();
const { model } = useGetMainModelsQuery(ALL_BASE_MODELS, {
const { mainModel } = useGetMainModelsQuery(ALL_BASE_MODELS, {
selectFromResult: ({ data }) => ({
model: selectedModelId ? data?.entities[selectedModelId] : undefined,
mainModel: selectedModelId ? data?.entities[selectedModelId] : undefined,
}),
});
const { loraModel } = useGetLoRAModelsQuery(undefined, {
selectFromResult: ({ data }) => ({
loraModel: selectedModelId ? data?.entities[selectedModelId] : undefined,
}),
});
const model = mainModel ? mainModel : loraModel;
return (
<Flex sx={{ gap: 8, w: 'full', h: 'full' }}>
@@ -30,7 +41,7 @@ export default function ModelManagerPanel() {
}
type ModelEditProps = {
model: MainModelConfigEntity | undefined;
model: MainModelConfigEntity | LoRAModelConfigEntity | undefined;
};
const ModelEdit = (props: ModelEditProps) => {
@@ -41,7 +52,16 @@ const ModelEdit = (props: ModelEditProps) => {
}
if (model?.model_format === 'diffusers') {
return <DiffusersModelEdit key={model.id} model={model} />;
return (
<DiffusersModelEdit
key={model.id}
model={model as DiffusersModelConfigEntity}
/>
);
}
if (model?.model_type === 'lora') {
return <LoRAModelEdit key={model.id} model={model} />;
}
return (

View File

@@ -1,6 +1,5 @@
import { Badge, Divider, Flex, Text } from '@chakra-ui/react';
import { useForm } from '@mantine/form';
import { makeToast } from 'features/system/util/makeToast';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIButton from 'common/components/IAIButton';
import IAIMantineTextInput from 'common/components/IAIMantineInput';
@@ -8,6 +7,7 @@ import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
import { selectIsBusy } from 'features/system/store/systemSelectors';
import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
import { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
@@ -115,7 +115,7 @@ export default function CheckpointModelEdit(props: CheckpointModelEditProps) {
{MODEL_TYPE_MAP[model.base_model]} Model
</Text>
</Flex>
{!['sdxl', 'sdxl-refiner'].includes(model.base_model) ? (
{![''].includes(model.base_model) ? (
<ModelConvert model={model} />
) : (
<Badge

View File

@@ -0,0 +1,137 @@
import { Divider, Flex, Text } from '@chakra-ui/react';
import { useForm } from '@mantine/form';
import { makeToast } from 'features/system/util/makeToast';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIButton from 'common/components/IAIButton';
import IAIMantineTextInput from 'common/components/IAIMantineInput';
import { selectIsBusy } from 'features/system/store/systemSelectors';
import { addToast } from 'features/system/store/systemSlice';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import {
LORA_MODEL_FORMAT_MAP,
MODEL_TYPE_MAP,
} from 'features/parameters/types/constants';
import {
LoRAModelConfigEntity,
useUpdateLoRAModelsMutation,
} from 'services/api/endpoints/models';
import { LoRAModelConfig } from 'services/api/types';
import BaseModelSelect from '../shared/BaseModelSelect';
type LoRAModelEditProps = {
model: LoRAModelConfigEntity;
};
export default function LoRAModelEdit(props: LoRAModelEditProps) {
const isBusy = useAppSelector(selectIsBusy);
const { model } = props;
const [updateLoRAModel, { isLoading }] = useUpdateLoRAModelsMutation();
const dispatch = useAppDispatch();
const { t } = useTranslation();
const loraEditForm = useForm<LoRAModelConfig>({
initialValues: {
model_name: model.model_name ? model.model_name : '',
base_model: model.base_model,
model_type: 'lora',
path: model.path ? model.path : '',
description: model.description ? model.description : '',
model_format: model.model_format,
},
validate: {
path: (value) =>
value.trim().length === 0 ? 'Must provide a path' : null,
},
});
const editModelFormSubmitHandler = useCallback(
(values: LoRAModelConfig) => {
const responseBody = {
base_model: model.base_model,
model_name: model.model_name,
body: values,
};
updateLoRAModel(responseBody)
.unwrap()
.then((payload) => {
loraEditForm.setValues(payload as LoRAModelConfig);
dispatch(
addToast(
makeToast({
title: t('modelManager.modelUpdated'),
status: 'success',
})
)
);
})
.catch((_) => {
loraEditForm.reset();
dispatch(
addToast(
makeToast({
title: t('modelManager.modelUpdateFailed'),
status: 'error',
})
)
);
});
},
[
dispatch,
loraEditForm,
model.base_model,
model.model_name,
t,
updateLoRAModel,
]
);
return (
<Flex flexDirection="column" rowGap={4} width="100%">
<Flex flexDirection="column">
<Text fontSize="lg" fontWeight="bold">
{model.model_name}
</Text>
<Text fontSize="sm" color="base.400">
{MODEL_TYPE_MAP[model.base_model]} Model {' '}
{LORA_MODEL_FORMAT_MAP[model.model_format]} format
</Text>
</Flex>
<Divider />
<form
onSubmit={loraEditForm.onSubmit((values) =>
editModelFormSubmitHandler(values)
)}
>
<Flex flexDirection="column" overflowY="scroll" gap={4}>
<IAIMantineTextInput
label={t('modelManager.name')}
{...loraEditForm.getInputProps('model_name')}
/>
<IAIMantineTextInput
label={t('modelManager.description')}
{...loraEditForm.getInputProps('description')}
/>
<BaseModelSelect {...loraEditForm.getInputProps('base_model')} />
<IAIMantineTextInput
label={t('modelManager.modelLocation')}
{...loraEditForm.getInputProps('path')}
/>
<IAIButton
type="submit"
isDisabled={isBusy || isLoading}
isLoading={isLoading}
>
{t('modelManager.updateModel')}
</IAIButton>
</Flex>
</form>
</Flex>
);
}

View File

@@ -9,6 +9,8 @@ import { useTranslation } from 'react-i18next';
import {
MainModelConfigEntity,
useGetMainModelsQuery,
useGetLoRAModelsQuery,
LoRAModelConfigEntity,
} from 'services/api/endpoints/models';
import ModelListItem from './ModelListItem';
import { ALL_BASE_MODELS } from 'services/api/constants';
@@ -20,22 +22,42 @@ type ModelListProps = {
type ModelFormat = 'images' | 'checkpoint' | 'diffusers';
type ModelType = 'main' | 'lora';
type CombinedModelFormat = ModelFormat | 'lora';
const ModelList = (props: ModelListProps) => {
const { selectedModelId, setSelectedModelId } = props;
const { t } = useTranslation();
const [nameFilter, setNameFilter] = useState<string>('');
const [modelFormatFilter, setModelFormatFilter] =
useState<ModelFormat>('images');
useState<CombinedModelFormat>('images');
const { filteredDiffusersModels } = useGetMainModelsQuery(ALL_BASE_MODELS, {
selectFromResult: ({ data }) => ({
filteredDiffusersModels: modelsFilter(data, 'diffusers', nameFilter),
filteredDiffusersModels: modelsFilter(
data,
'main',
'diffusers',
nameFilter
),
}),
});
const { filteredCheckpointModels } = useGetMainModelsQuery(ALL_BASE_MODELS, {
selectFromResult: ({ data }) => ({
filteredCheckpointModels: modelsFilter(data, 'checkpoint', nameFilter),
filteredCheckpointModels: modelsFilter(
data,
'main',
'checkpoint',
nameFilter
),
}),
});
const { filteredLoraModels } = useGetLoRAModelsQuery(undefined, {
selectFromResult: ({ data }) => ({
filteredLoraModels: modelsFilter(data, 'lora', undefined, nameFilter),
}),
});
@@ -68,6 +90,13 @@ const ModelList = (props: ModelListProps) => {
>
{t('modelManager.checkpointModels')}
</IAIButton>
<IAIButton
size="sm"
onClick={() => setModelFormatFilter('lora')}
isChecked={modelFormatFilter === 'lora'}
>
{t('modelManager.loraModels')}
</IAIButton>
</ButtonGroup>
<IAIInput
@@ -118,6 +147,24 @@ const ModelList = (props: ModelListProps) => {
</Flex>
</StyledModelContainer>
)}
{['images', 'lora'].includes(modelFormatFilter) &&
filteredLoraModels.length > 0 && (
<StyledModelContainer>
<Flex sx={{ gap: 2, flexDir: 'column' }}>
<Text variant="subtext" fontSize="sm">
LoRAs
</Text>
{filteredLoraModels.map((model) => (
<ModelListItem
key={model.id}
model={model}
isSelected={selectedModelId === model.id}
setSelectedModelId={setSelectedModelId}
/>
))}
</Flex>
</StyledModelContainer>
)}
</Flex>
</Flex>
</Flex>
@@ -126,12 +173,13 @@ const ModelList = (props: ModelListProps) => {
export default ModelList;
const modelsFilter = (
data: EntityState<MainModelConfigEntity> | undefined,
model_format: ModelFormat,
const modelsFilter = <T extends MainModelConfigEntity | LoRAModelConfigEntity>(
data: EntityState<T> | undefined,
model_type: ModelType,
model_format: ModelFormat | undefined,
nameFilter: string
) => {
const filteredModels: MainModelConfigEntity[] = [];
const filteredModels: T[] = [];
forEach(data?.entities, (model) => {
if (!model) {
return;
@@ -141,9 +189,11 @@ const modelsFilter = (
.toLowerCase()
.includes(nameFilter.toLowerCase());
const matchesFormat = model.model_format === model_format;
const matchesFormat =
model_format === undefined || model.model_format === model_format;
const matchesType = model.model_type === model_type;
if (matchesFilter && matchesFormat) {
if (matchesFilter && matchesFormat && matchesType) {
filteredModels.push(model);
}
});

View File

@@ -9,29 +9,26 @@ import { selectIsBusy } from 'features/system/store/systemSelectors';
import { addToast } from 'features/system/store/systemSlice';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { MODEL_TYPE_SHORT_MAP } from 'features/parameters/types/constants';
import {
MainModelConfigEntity,
LoRAModelConfigEntity,
useDeleteMainModelsMutation,
useDeleteLoRAModelsMutation,
} from 'services/api/endpoints/models';
type ModelListItemProps = {
model: MainModelConfigEntity;
model: MainModelConfigEntity | LoRAModelConfigEntity;
isSelected: boolean;
setSelectedModelId: (v: string | undefined) => void;
};
const modelBaseTypeMap = {
'sd-1': 'SD1',
'sd-2': 'SD2',
sdxl: 'SDXL',
'sdxl-refiner': 'SDXLR',
};
export default function ModelListItem(props: ModelListItemProps) {
const isBusy = useAppSelector(selectIsBusy);
const { t } = useTranslation();
const dispatch = useAppDispatch();
const [deleteMainModel] = useDeleteMainModelsMutation();
const [deleteLoRAModel] = useDeleteLoRAModelsMutation();
const { model, isSelected, setSelectedModelId } = props;
@@ -40,7 +37,10 @@ export default function ModelListItem(props: ModelListItemProps) {
}, [model.id, setSelectedModelId]);
const handleModelDelete = useCallback(() => {
deleteMainModel(model)
const method = { main: deleteMainModel, lora: deleteLoRAModel }[
model.model_type
];
method(model)
.unwrap()
.then((_) => {
dispatch(
@@ -60,14 +60,21 @@ export default function ModelListItem(props: ModelListItemProps) {
title: `${t('modelManager.modelDeleteFailed')}: ${
model.model_name
}`,
status: 'success',
status: 'error',
})
)
);
}
});
setSelectedModelId(undefined);
}, [deleteMainModel, model, setSelectedModelId, dispatch, t]);
}, [
deleteMainModel,
deleteLoRAModel,
model,
setSelectedModelId,
dispatch,
t,
]);
return (
<Flex sx={{ gap: 2, alignItems: 'center', w: 'full' }}>
@@ -100,8 +107,8 @@ export default function ModelListItem(props: ModelListItemProps) {
<Flex gap={4} alignItems="center">
<Badge minWidth={14} p={0.5} fontSize="sm" variant="solid">
{
modelBaseTypeMap[
model.base_model as keyof typeof modelBaseTypeMap
MODEL_TYPE_SHORT_MAP[
model.base_model as keyof typeof MODEL_TYPE_SHORT_MAP
]
}
</Badge>

View File

@@ -1,7 +1,7 @@
import { Flex } from '@chakra-ui/react';
import { RootState } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import TextToImageSDXLTabParameters from 'features/sdxl/components/SDXLTextToImageTabParameters';
import SDXLTextToImageTabParameters from 'features/sdxl/components/SDXLTextToImageTabParameters';
import { memo } from 'react';
import ParametersPinnedWrapper from '../../ParametersPinnedWrapper';
import TextToImageTabMain from './TextToImageTabMain';
@@ -13,7 +13,7 @@ const TextToImageTab = () => {
<Flex sx={{ gap: 4, w: 'full', h: 'full' }}>
<ParametersPinnedWrapper>
{model && model.base_model === 'sdxl' ? (
<TextToImageSDXLTabParameters />
<SDXLTextToImageTabParameters />
) : (
<TextToImageTabParameters />
)}

View File

@@ -2,20 +2,18 @@ import ParamDynamicPromptsCollapse from 'features/dynamicPrompts/components/Para
import ParamLoraCollapse from 'features/lora/components/ParamLoraCollapse';
import ParamAdvancedCollapse from 'features/parameters/components/Parameters/Advanced/ParamAdvancedCollapse';
import ParamControlNetCollapse from 'features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse';
import ParamNegativeConditioning from 'features/parameters/components/Parameters/Core/ParamNegativeConditioning';
import ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning';
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
// import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import ParamPromptArea from '../../../../parameters/components/Parameters/Prompt/ParamPromptArea';
import TextToImageTabCoreParameters from './TextToImageTabCoreParameters';
const TextToImageTabParameters = () => {
return (
<>
<ParamPositiveConditioning />
<ParamNegativeConditioning />
<ParamPromptArea />
<ProcessButtons />
<TextToImageTabCoreParameters />
<ParamControlNetCollapse />

View File

@@ -4,18 +4,16 @@ import ParamAdvancedCollapse from 'features/parameters/components/Parameters/Adv
import ParamInfillAndScalingCollapse from 'features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillAndScalingCollapse';
import ParamSeamCorrectionCollapse from 'features/parameters/components/Parameters/Canvas/SeamCorrection/ParamSeamCorrectionCollapse';
import ParamControlNetCollapse from 'features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse';
import ParamNegativeConditioning from 'features/parameters/components/Parameters/Core/ParamNegativeConditioning';
import ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning';
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
// import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse';
import ParamPromptArea from 'features/parameters/components/Parameters/Prompt/ParamPromptArea';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import UnifiedCanvasCoreParameters from './UnifiedCanvasCoreParameters';
const UnifiedCanvasParameters = () => {
return (
<>
<ParamPositiveConditioning />
<ParamNegativeConditioning />
<ParamPromptArea />
<ProcessButtons />
<UnifiedCanvasCoreParameters />
<ParamControlNetCollapse />

View File

@@ -3,7 +3,6 @@ export type { PartialAppConfig } from './app/types/invokeai';
export { default as IAIIconButton } from './common/components/IAIIconButton';
export { default as IAIPopover } from './common/components/IAIPopover';
export { default as ParamMainModelSelect } from './features/parameters/components/Parameters/MainModel/ParamMainModelSelect';
export { default as ColorModeButton } from './features/system/components/ColorModeButton';
export { default as InvokeAiLogoComponent } from './features/system/components/InvokeAILogoComponent';
export { default as SettingsModal } from './features/system/components/SettingsModal/SettingsModal';
export { default as StatusIndicator } from './features/system/components/StatusIndicator';

View File

@@ -8,6 +8,7 @@ export const appInfoApi = api.injectEndpoints({
url: `app/version`,
method: 'GET',
}),
providesTags: ['AppVersion'],
keepUnusedDataFor: 86400000, // 1 day
}),
getAppConfig: build.query<AppConfig, void>({
@@ -15,6 +16,7 @@ export const appInfoApi = api.injectEndpoints({
url: `app/config`,
method: 'GET',
}),
providesTags: ['AppConfig'],
keepUnusedDataFor: 86400000, // 1 day
}),
}),

View File

@@ -52,9 +52,17 @@ type UpdateMainModelArg = {
body: MainModelConfig;
};
type UpdateLoRAModelArg = {
base_model: BaseModelType;
model_name: string;
body: LoRAModelConfig;
};
type UpdateMainModelResponse =
paths['/api/v1/models/{base_model}/{model_type}/{model_name}']['patch']['responses']['200']['content']['application/json'];
type UpdateLoRAModelResponse = UpdateMainModelResponse;
type DeleteMainModelArg = {
base_model: BaseModelType;
model_name: string;
@@ -62,6 +70,10 @@ type DeleteMainModelArg = {
type DeleteMainModelResponse = void;
type DeleteLoRAModelArg = DeleteMainModelArg;
type DeleteLoRAModelResponse = void;
type ConvertMainModelArg = {
base_model: BaseModelType;
model_name: string;
@@ -320,6 +332,31 @@ export const modelsApi = api.injectEndpoints({
);
},
}),
updateLoRAModels: build.mutation<
UpdateLoRAModelResponse,
UpdateLoRAModelArg
>({
query: ({ base_model, model_name, body }) => {
return {
url: `models/${base_model}/lora/${model_name}`,
method: 'PATCH',
body: body,
};
},
invalidatesTags: [{ type: 'LoRAModel', id: LIST_TAG }],
}),
deleteLoRAModels: build.mutation<
DeleteLoRAModelResponse,
DeleteLoRAModelArg
>({
query: ({ base_model, model_name }) => {
return {
url: `models/${base_model}/lora/${model_name}`,
method: 'DELETE',
};
},
invalidatesTags: [{ type: 'LoRAModel', id: LIST_TAG }],
}),
getControlNetModels: build.query<
EntityState<ControlNetModelConfigEntity>,
void
@@ -467,6 +504,8 @@ export const {
useAddMainModelsMutation,
useConvertMainModelsMutation,
useMergeMainModelsMutation,
useDeleteLoRAModelsMutation,
useUpdateLoRAModelsMutation,
useSyncModelsMutation,
useGetModelsInFolderQuery,
useGetCheckpointConfigsQuery,

View File

@@ -318,6 +318,21 @@ export type components = {
* @description List of available infill methods
*/
infill_methods: (string)[];
/**
* Upscaling Methods
* @description List of upscaling methods
*/
upscaling_methods: (components["schemas"]["Upscaler"])[];
/**
* Nsfw Methods
* @description List of NSFW checking methods
*/
nsfw_methods: (string)[];
/**
* Watermarking Methods
* @description List of invisible watermark methods
*/
watermarking_methods: (string)[];
};
/**
* AppVersion
@@ -886,8 +901,8 @@ export type components = {
*/
resize_mode?: "just_resize" | "crop_resize" | "fill_resize" | "just_resize_simple";
};
/** ControlNetModelConfig */
ControlNetModelConfig: {
/** ControlNetModelCheckpointConfig */
ControlNetModelCheckpointConfig: {
/** Model Name */
model_name: string;
base_model: components["schemas"]["BaseModelType"];
@@ -900,7 +915,34 @@ export type components = {
path: string;
/** Description */
description?: string;
model_format: components["schemas"]["ControlNetModelFormat"];
/**
* Model Format
* @enum {string}
*/
model_format: "checkpoint";
error?: components["schemas"]["ModelError"];
/** Config */
config: string;
};
/** ControlNetModelDiffusersConfig */
ControlNetModelDiffusersConfig: {
/** Model Name */
model_name: string;
base_model: components["schemas"]["BaseModelType"];
/**
* Model Type
* @enum {string}
*/
model_type: "controlnet";
/** Path */
path: string;
/** Description */
description?: string;
/**
* Model Format
* @enum {string}
*/
model_format: "diffusers";
error?: components["schemas"]["ModelError"];
};
/**
@@ -916,12 +958,6 @@ export type components = {
/** @description Base model */
base_model: components["schemas"]["BaseModelType"];
};
/**
* ControlNetModelFormat
* @description An enumeration.
* @enum {string}
*/
ControlNetModelFormat: "checkpoint" | "diffusers";
/**
* ControlOutput
* @description node output for ControlNet info
@@ -1345,7 +1381,7 @@ export type components = {
* @description The nodes in this graph
*/
nodes?: {
[key: string]: (components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"]) | undefined;
[key: string]: (components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"]) | undefined;
};
/**
* Edges
@@ -1388,7 +1424,7 @@ export type components = {
* @description The results of node executions
*/
results: {
[key: string]: (components["schemas"]["ImageOutput"] | components["schemas"]["MaskOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["CompelOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["PromptOutput"] | components["schemas"]["PromptCollectionOutput"] | components["schemas"]["IntOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["IntCollectionOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]) | undefined;
[key: string]: (components["schemas"]["ImageOutput"] | components["schemas"]["MaskOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["CompelOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["IntOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["IntCollectionOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["PromptOutput"] | components["schemas"]["PromptCollectionOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]) | undefined;
};
/**
* Errors
@@ -1935,6 +1971,39 @@ export type components = {
*/
image2?: components["schemas"]["ImageField"];
};
/**
* ImageNSFWBlurInvocation
* @description Add blur to NSFW-flagged images
*/
ImageNSFWBlurInvocation: {
/**
* Id
* @description The id of this node. Must be unique among all nodes.
*/
id: string;
/**
* Is Intermediate
* @description Whether or not this node is an intermediate node.
* @default false
*/
is_intermediate?: boolean;
/**
* Type
* @default img_nsfw
* @enum {string}
*/
type?: "img_nsfw";
/**
* Image
* @description The image to check
*/
image?: components["schemas"]["ImageField"];
/**
* Metadata
* @description Optional core metadata to be written to the image
*/
metadata?: components["schemas"]["CoreMetadata"];
};
/**
* ImageOutput
* @description Base class for invocations that output an image
@@ -2215,6 +2284,45 @@ export type components = {
*/
thumbnail_url: string;
};
/**
* ImageWatermarkInvocation
* @description Add an invisible watermark to an image
*/
ImageWatermarkInvocation: {
/**
* Id
* @description The id of this node. Must be unique among all nodes.
*/
id: string;
/**
* Is Intermediate
* @description Whether or not this node is an intermediate node.
* @default false
*/
is_intermediate?: boolean;
/**
* Type
* @default img_watermark
* @enum {string}
*/
type?: "img_watermark";
/**
* Image
* @description The image to check
*/
image?: components["schemas"]["ImageField"];
/**
* Text
* @description Watermark text
* @default InvokeAI
*/
text?: string;
/**
* Metadata
* @description Optional core metadata to be written to the image
*/
metadata?: components["schemas"]["CoreMetadata"];
};
/**
* InfillColorInvocation
* @description Infills transparent areas of an image with a solid color
@@ -2644,7 +2752,7 @@ export type components = {
vae?: components["schemas"]["VaeField"];
/**
* Tiled
* @description Decode latents by overlaping tiles(less memory consumption)
* @description Decode latents by overlapping tiles(less memory consumption)
* @default false
*/
tiled?: boolean;
@@ -3520,7 +3628,7 @@ export type components = {
/** ModelsList */
ModelsList: {
/** Models */
models: (components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"])[];
models: (components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelCheckpointConfig"] | components["schemas"]["ControlNetModelDiffusersConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"])[];
};
/**
* MultiplyInvocation
@@ -5309,6 +5417,19 @@ export type components = {
*/
loras: (components["schemas"]["LoraInfo"])[];
};
/** Upscaler */
Upscaler: {
/**
* Upscaling Method
* @description Name of upscaling method
*/
upscaling_method: string;
/**
* Upscaling Models
* @description List of upscaling models for this method
*/
upscaling_models: (string)[];
};
/**
* VAEModelField
* @description Vae model field
@@ -5435,12 +5556,6 @@ export type components = {
*/
image?: components["schemas"]["ImageField"];
};
/**
* StableDiffusion1ModelFormat
* @description An enumeration.
* @enum {string}
*/
StableDiffusion1ModelFormat: "checkpoint" | "diffusers";
/**
* StableDiffusion2ModelFormat
* @description An enumeration.
@@ -5453,6 +5568,18 @@ export type components = {
* @enum {string}
*/
StableDiffusionXLModelFormat: "checkpoint" | "diffusers";
/**
* ControlNetModelFormat
* @description An enumeration.
* @enum {string}
*/
ControlNetModelFormat: "checkpoint" | "diffusers";
/**
* StableDiffusion1ModelFormat
* @description An enumeration.
* @enum {string}
*/
StableDiffusion1ModelFormat: "checkpoint" | "diffusers";
};
responses: never;
parameters: never;
@@ -5563,7 +5690,7 @@ export type operations = {
};
requestBody: {
content: {
"application/json": components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
"application/json": components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
};
};
responses: {
@@ -5600,7 +5727,7 @@ export type operations = {
};
requestBody: {
content: {
"application/json": components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
"application/json": components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
};
};
responses: {
@@ -5864,14 +5991,14 @@ export type operations = {
};
requestBody: {
content: {
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelCheckpointConfig"] | components["schemas"]["ControlNetModelDiffusersConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
};
};
responses: {
/** @description The model was updated successfully */
200: {
content: {
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelCheckpointConfig"] | components["schemas"]["ControlNetModelDiffusersConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
};
};
/** @description Bad request */
@@ -5902,7 +6029,7 @@ export type operations = {
/** @description The model imported successfully */
201: {
content: {
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelCheckpointConfig"] | components["schemas"]["ControlNetModelDiffusersConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
};
};
/** @description The model could not be found */
@@ -5928,14 +6055,14 @@ export type operations = {
add_model: {
requestBody: {
content: {
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelCheckpointConfig"] | components["schemas"]["ControlNetModelDiffusersConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
};
};
responses: {
/** @description The model added successfully */
201: {
content: {
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelCheckpointConfig"] | components["schemas"]["ControlNetModelDiffusersConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
};
};
/** @description The model could not be found */
@@ -5975,7 +6102,7 @@ export type operations = {
/** @description Model converted successfully */
200: {
content: {
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelCheckpointConfig"] | components["schemas"]["ControlNetModelDiffusersConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
};
};
/** @description Bad request */
@@ -6064,7 +6191,7 @@ export type operations = {
/** @description Model converted successfully */
200: {
content: {
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
"application/json": components["schemas"]["StableDiffusion1ModelCheckpointConfig"] | components["schemas"]["StableDiffusion1ModelDiffusersConfig"] | components["schemas"]["VaeModelConfig"] | components["schemas"]["LoRAModelConfig"] | components["schemas"]["ControlNetModelCheckpointConfig"] | components["schemas"]["ControlNetModelDiffusersConfig"] | components["schemas"]["TextualInversionModelConfig"] | components["schemas"]["StableDiffusion2ModelCheckpointConfig"] | components["schemas"]["StableDiffusion2ModelDiffusersConfig"] | components["schemas"]["StableDiffusionXLModelCheckpointConfig"] | components["schemas"]["StableDiffusionXLModelDiffusersConfig"];
};
};
/** @description Incompatible models */

View File

@@ -42,8 +42,13 @@ export type ControlField = components['schemas']['ControlField'];
// Model Configs
export type LoRAModelConfig = components['schemas']['LoRAModelConfig'];
export type VaeModelConfig = components['schemas']['VaeModelConfig'];
export type ControlNetModelCheckpointConfig =
components['schemas']['ControlNetModelCheckpointConfig'];
export type ControlNetModelDiffusersConfig =
components['schemas']['ControlNetModelDiffusersConfig'];
export type ControlNetModelConfig =
components['schemas']['ControlNetModelConfig'];
| ControlNetModelCheckpointConfig
| ControlNetModelDiffusersConfig;
export type TextualInversionModelConfig =
components['schemas']['TextualInversionModelConfig'];
export type DiffusersModelConfig =
@@ -134,6 +139,12 @@ export type ESRGANInvocation = TypeReq<
export type DivideInvocation = TypeReq<
components['schemas']['DivideInvocation']
>;
export type ImageNSFWBlurInvocation = TypeReq<
components['schemas']['ImageNSFWBlurInvocation']
>;
export type ImageWatermarkInvocation = TypeReq<
components['schemas']['ImageWatermarkInvocation']
>;
// ControlNet Nodes
export type ControlNetInvocation = TypeReq<

View File

@@ -33,12 +33,16 @@ const invokeAI = definePartsStyle((props) => ({
bg: mode('base.200', 'base.800')(props),
_hover: {
bg: mode('base.300', 'base.700')(props),
svg: {
opacity: 1,
},
},
_focus: {
bg: mode('base.400', 'base.600')(props),
},
svg: {
opacity: 0.5,
opacity: 0.7,
fontSize: 14,
},
},
}));

View File

@@ -13,6 +13,15 @@ const invokeAI = defineStyle((props) => ({
var(--invokeai-colors-base-200) 70%,
var(--invokeai-colors-base-200) 100%)`,
},
_disabled: {
'::-webkit-resizer': {
backgroundImage: `linear-gradient(135deg,
var(--invokeai-colors-base-50) 0%,
var(--invokeai-colors-base-50) 70%,
var(--invokeai-colors-base-200) 70%,
var(--invokeai-colors-base-200) 100%)`,
},
},
_dark: {
'::-webkit-resizer': {
backgroundImage: `linear-gradient(135deg,
@@ -21,6 +30,15 @@ const invokeAI = defineStyle((props) => ({
var(--invokeai-colors-base-800) 70%,
var(--invokeai-colors-base-800) 100%)`,
},
_disabled: {
'::-webkit-resizer': {
backgroundImage: `linear-gradient(135deg,
var(--invokeai-colors-base-900) 0%,
var(--invokeai-colors-base-900) 70%,
var(--invokeai-colors-base-800) 70%,
var(--invokeai-colors-base-800) 100%)`,
},
},
},
}));

File diff suppressed because it is too large Load Diff