ui: cleanup (#3418)

- tidy up a lot of cruft
- `sampler` --> `scheduler`
This commit is contained in:
blessedcoolant 2023-05-16 15:27:12 +12:00 committed by GitHub
commit 30af20a056
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 223 additions and 567 deletions

View File

@ -450,7 +450,7 @@
"cfgScale": "CFG Scale",
"width": "Width",
"height": "Height",
"sampler": "Sampler",
"scheduler": "Scheduler",
"seed": "Seed",
"imageToImage": "Image to Image",
"randomizeSeed": "Randomize Seed",

View File

@ -6,7 +6,7 @@ import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton'
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
import { Box, Flex, Grid, Portal } from '@chakra-ui/react';
import { APP_HEIGHT, APP_WIDTH } from 'theme/util/constants';
import GalleryDrawer from 'features/gallery/components/ImageGalleryPanel';
import GalleryDrawer from 'features/gallery/components/GalleryPanel';
import Lightbox from 'features/lightbox/components/Lightbox';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { memo, ReactNode, useCallback, useEffect, useState } from 'react';
@ -22,7 +22,6 @@ import { languageSelector } from 'features/system/store/systemSelectors';
import i18n from 'i18n';
import Toaster from './Toaster';
import GlobalHotkeys from './GlobalHotkeys';
import AuxiliaryProgressIndicator from './AuxiliaryProgressIndicator';
const DEFAULT_CONFIG = {};

View File

@ -1,6 +1,6 @@
// TODO: use Enums?
export const SCHEDULERS: Array<string> = [
export const SCHEDULERS = [
'ddim',
'lms',
'euler',
@ -17,7 +17,12 @@ export const SCHEDULERS: Array<string> = [
'heun',
'heun_k',
'unipc',
];
] as const;
export type Scheduler = (typeof SCHEDULERS)[number];
export const isScheduler = (x: string): x is Scheduler =>
SCHEDULERS.includes(x as Scheduler);
// Valid image widths
export const WIDTHS: Array<number> = Array.from(Array(64)).map(

View File

@ -3,18 +3,8 @@ import { CanvasState } from './canvasTypes';
/**
* Canvas slice persist denylist
*/
const itemsToDenylist: (keyof CanvasState)[] = [
'cursorPosition',
'isCanvasInitialized',
'doesCanvasNeedScaling',
];
export const canvasPersistDenylist: (keyof CanvasState)[] = [
'cursorPosition',
'isCanvasInitialized',
'doesCanvasNeedScaling',
];
export const canvasDenylist = itemsToDenylist.map(
(denylistItem) => `canvas.${denylistItem}`
);

View File

@ -47,10 +47,7 @@ import {
FaTrash,
FaWrench,
} from 'react-icons/fa';
import {
gallerySelector,
selectedImageSelector,
} from '../store/gallerySelectors';
import { gallerySelector } from '../store/gallerySelectors';
import DeleteImageModal from './DeleteImageModal';
import { useCallback } from 'react';
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
@ -73,15 +70,15 @@ const currentImageButtonsSelector = createSelector(
uiSelector,
lightboxSelector,
activeTabNameSelector,
selectedImageSelector,
],
(system, gallery, postprocessing, ui, lightbox, activeTabName, image) => {
(system, gallery, postprocessing, ui, lightbox, activeTabName) => {
const {
isProcessing,
isConnected,
isGFPGANAvailable,
isESRGANAvailable,
shouldConfirmOnDelete,
progressImage,
} = system;
const { upscalingLevel, facetoolStrength } = postprocessing;
@ -90,7 +87,7 @@ const currentImageButtonsSelector = createSelector(
const { shouldShowImageDetails, shouldHidePreview } = ui;
const { intermediateImage, currentImage } = gallery;
const { selectedImage } = gallery;
return {
canDeleteImage: isConnected && !isProcessing,
@ -101,15 +98,14 @@ const currentImageButtonsSelector = createSelector(
isESRGANAvailable,
upscalingLevel,
facetoolStrength,
shouldDisableToolbarButtons: Boolean(intermediateImage) || !currentImage,
currentImage,
shouldDisableToolbarButtons: Boolean(progressImage) || !selectedImage,
shouldShowImageDetails,
activeTabName,
isLightboxOpen,
shouldHidePreview,
image,
seed: image?.metadata?.invokeai?.node?.seed,
prompt: image?.metadata?.invokeai?.node?.prompt,
image: selectedImage,
seed: selectedImage?.metadata?.invokeai?.node?.seed,
prompt: selectedImage?.metadata?.invokeai?.node?.prompt,
};
},
{

View File

@ -4,18 +4,18 @@ import { useAppSelector } from 'app/store/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors';
import { isEqual } from 'lodash-es';
import { selectedImageSelector } from '../store/gallerySelectors';
import { gallerySelector } from '../store/gallerySelectors';
import CurrentImageButtons from './CurrentImageButtons';
import CurrentImagePreview from './CurrentImagePreview';
import { FaImage } from 'react-icons/fa';
export const currentImageDisplaySelector = createSelector(
[systemSelector, selectedImageSelector],
(system, selectedImage) => {
[systemSelector, gallerySelector],
(system, gallery) => {
const { progressImage } = system;
return {
hasAnImageToDisplay: selectedImage || progressImage,
hasAnImageToDisplay: gallery.selectedImage || progressImage,
};
},
{

View File

@ -1,10 +1,6 @@
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { gallerySelector } from 'features/gallery/store/gallerySelectors';
import {
// selectNextImage,
// selectPrevImage,
setGalleryImageMinimumWidth,
} from 'features/gallery/store/gallerySlice';
import { setGalleryImageMinimumWidth } from 'features/gallery/store/gallerySlice';
import { clamp, isEqual } from 'lodash-es';
import { useHotkeys } from 'react-hotkeys-hook';
@ -23,20 +19,7 @@ import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvas
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
import { memo } from 'react';
// const GALLERY_TAB_WIDTHS: Record<
// InvokeTabName,
// { galleryMinWidth: number; galleryMaxWidth: number }
// > = {
// txt2img: { galleryMinWidth: 200, galleryMaxWidth: 500 },
// img2img: { galleryMinWidth: 200, galleryMaxWidth: 500 },
// generate: { galleryMinWidth: 200, galleryMaxWidth: 500 },
// unifiedCanvas: { galleryMinWidth: 200, galleryMaxWidth: 200 },
// nodes: { galleryMinWidth: 200, galleryMaxWidth: 500 },
// postprocessing: { galleryMinWidth: 200, galleryMaxWidth: 500 },
// training: { galleryMinWidth: 200, galleryMaxWidth: 500 },
// };
const galleryPanelSelector = createSelector(
const selector = createSelector(
[
activeTabNameSelector,
uiSelector,
@ -76,41 +59,13 @@ const GalleryDrawer = () => {
// isStaging,
// isResizable,
// isLightboxOpen,
} = useAppSelector(galleryPanelSelector);
// const handleSetShouldPinGallery = () => {
// dispatch(togglePinGalleryPanel());
// dispatch(requestCanvasRescale());
// };
// const handleToggleGallery = () => {
// dispatch(toggleGalleryPanel());
// shouldPinGallery && dispatch(requestCanvasRescale());
// };
} = useAppSelector(selector);
const handleCloseGallery = () => {
dispatch(setShouldShowGallery(false));
shouldPinGallery && dispatch(requestCanvasRescale());
};
// const resolution = useResolution();
// useHotkeys(
// 'g',
// () => {
// handleToggleGallery();
// },
// [shouldPinGallery]
// );
// useHotkeys(
// 'shift+g',
// () => {
// handleSetShouldPinGallery();
// },
// [shouldPinGallery]
// );
useHotkeys(
'esc',
() => {
@ -155,54 +110,6 @@ const GalleryDrawer = () => {
[galleryImageMinimumWidth]
);
// const calcGalleryMinHeight = () => {
// if (resolution === 'desktop') return;
// return 300;
// };
// const imageGalleryContent = () => {
// return (
// <Flex
// w="100vw"
// h={{ base: 300, xl: '100vh' }}
// paddingRight={{ base: 8, xl: 0 }}
// paddingBottom={{ base: 4, xl: 0 }}
// >
// <ImageGalleryContent />
// </Flex>
// );
// };
// const resizableImageGalleryContent = () => {
// return (
// <ResizableDrawer
// direction="right"
// isResizable={isResizable || !shouldPinGallery}
// isOpen={shouldShowGallery}
// onClose={handleCloseGallery}
// isPinned={shouldPinGallery && !isLightboxOpen}
// minWidth={
// shouldPinGallery
// ? GALLERY_TAB_WIDTHS[activeTabName].galleryMinWidth
// : 200
// }
// maxWidth={
// shouldPinGallery
// ? GALLERY_TAB_WIDTHS[activeTabName].galleryMaxWidth
// : undefined
// }
// minHeight={calcGalleryMinHeight()}
// >
// <ImageGalleryContent />
// </ResizableDrawer>
// );
// };
// const renderImageGallery = () => {
// if (['mobile', 'tablet'].includes(resolution)) return imageGalleryContent();
// return resizableImageGalleryContent();
// };
if (shouldPinGallery) {
return null;
}
@ -218,8 +125,6 @@ const GalleryDrawer = () => {
<ImageGalleryContent />
</ResizableDrawer>
);
// return renderImageGallery();
};
export default memo(GalleryDrawer);

View File

@ -15,10 +15,7 @@ import IAICheckbox from 'common/components/IAICheckbox';
import IAIIconButton from 'common/components/IAIIconButton';
import IAIPopover from 'common/components/IAIPopover';
import IAISlider from 'common/components/IAISlider';
import {
gallerySelector,
imageGallerySelector,
} from 'features/gallery/store/gallerySelectors';
import { gallerySelector } from 'features/gallery/store/gallerySelectors';
import {
setCurrentCategory,
setGalleryImageMinimumWidth,
@ -57,11 +54,12 @@ import { Virtuoso, VirtuosoGrid } from 'react-virtuoso';
import { Image as ImageType } from 'app/types/invokeai';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import GalleryProgressImage from './GalleryProgressImage';
import { uiSelector } from 'features/ui/store/uiSelectors';
const GALLERY_SHOW_BUTTONS_MIN_WIDTH = 290;
const PROGRESS_IMAGE_PLACEHOLDER = 'PROGRESS_IMAGE_PLACEHOLDER';
const selector = createSelector(
const categorySelector = createSelector(
[(state: RootState) => state],
(state) => {
const { results, uploads, system, gallery } = state;
@ -92,6 +90,33 @@ const selector = createSelector(
defaultSelectorOptions
);
const mainSelector = createSelector(
[gallerySelector, uiSelector],
(gallery, ui) => {
const {
currentCategory,
galleryImageMinimumWidth,
galleryImageObjectFit,
shouldAutoSwitchToNewImages,
shouldUseSingleGalleryColumn,
selectedImage,
} = gallery;
const { shouldPinGallery } = ui;
return {
currentCategory,
shouldPinGallery,
galleryImageMinimumWidth,
galleryImageObjectFit,
shouldAutoSwitchToNewImages,
shouldUseSingleGalleryColumn,
selectedImage,
};
},
defaultSelectorOptions
);
const ImageGalleryContent = () => {
const dispatch = useAppDispatch();
const { t } = useTranslation();
@ -113,7 +138,6 @@ const ImageGalleryContent = () => {
});
const {
// images,
currentCategory,
shouldPinGallery,
galleryImageMinimumWidth,
@ -121,10 +145,10 @@ const ImageGalleryContent = () => {
shouldAutoSwitchToNewImages,
shouldUseSingleGalleryColumn,
selectedImage,
} = useAppSelector(imageGallerySelector);
} = useAppSelector(mainSelector);
const { images, areMoreImagesAvailable, isLoading } =
useAppSelector(selector);
useAppSelector(categorySelector);
const handleClickLoadMore = () => {
if (currentCategory === 'results') {

View File

@ -19,7 +19,7 @@ import {
setHeight,
setImg2imgStrength,
setPerlin,
setSampler,
setScheduler,
setSeamless,
setSeed,
setSeedWeights,
@ -202,9 +202,9 @@ const ImageMetadataViewer = memo(({ image }: ImageMetadataViewerProps) => {
)}
{node.scheduler && (
<MetadataItem
label="Sampler"
label="Scheduler"
value={node.scheduler}
onClick={() => dispatch(setSampler(node.scheduler))}
onClick={() => dispatch(setScheduler(node.scheduler))}
/>
)}
{node.steps && (

View File

@ -3,16 +3,7 @@ import { GalleryState } from './gallerySlice';
/**
* Gallery slice persist denylist
*/
const itemsToDenylist: (keyof GalleryState)[] = [
'currentCategory',
'shouldAutoSwitchToNewImages',
];
export const galleryPersistDenylist: (keyof GalleryState)[] = [
'currentCategory',
'shouldAutoSwitchToNewImages',
];
export const galleryDenylist = itemsToDenylist.map(
(denylistItem) => `gallery.${denylistItem}`
);

View File

@ -1,83 +1,3 @@
import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store/store';
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
import {
activeTabNameSelector,
uiSelector,
} from 'features/ui/store/uiSelectors';
import { isEqual } from 'lodash-es';
import { selectResultsById, selectResultsEntities } from './resultsSlice';
import { selectUploadsAll, selectUploadsById } from './uploadsSlice';
export const gallerySelector = (state: RootState) => state.gallery;
export const imageGallerySelector = createSelector(
[
(state: RootState) => state,
gallerySelector,
uiSelector,
lightboxSelector,
activeTabNameSelector,
],
(state, gallery, ui, lightbox, activeTabName) => {
const {
currentCategory,
galleryImageMinimumWidth,
galleryImageObjectFit,
shouldAutoSwitchToNewImages,
galleryWidth,
shouldUseSingleGalleryColumn,
selectedImage,
} = gallery;
const { shouldPinGallery } = ui;
const { isLightboxOpen } = lightbox;
const images =
currentCategory === 'results'
? selectResultsEntities(state)
: selectUploadsAll(state);
return {
shouldPinGallery,
galleryImageMinimumWidth,
galleryImageObjectFit,
galleryGridTemplateColumns: shouldUseSingleGalleryColumn
? 'auto'
: `repeat(auto-fill, minmax(${galleryImageMinimumWidth}px, auto))`,
shouldAutoSwitchToNewImages,
currentCategory,
images,
galleryWidth,
shouldEnableResize:
isLightboxOpen ||
(activeTabName === 'unifiedCanvas' && shouldPinGallery)
? false
: true,
shouldUseSingleGalleryColumn,
selectedImage,
};
},
{
memoizeOptions: {
resultEqualityCheck: isEqual,
},
}
);
export const selectedImageSelector = createSelector(
[(state: RootState) => state, gallerySelector],
(state, gallery) => {
const selectedImage = gallery.selectedImage;
if (selectedImage?.type === 'results') {
return selectResultsById(state, selectedImage.name);
}
if (selectedImage?.type === 'uploads') {
return selectUploadsById(state, selectedImage.name);
}
}
);

View File

@ -10,14 +10,10 @@ import {
type GalleryImageObjectFitType = 'contain' | 'cover';
export interface GalleryState {
/**
* The selected image
*/
selectedImage?: Image;
galleryImageMinimumWidth: number;
galleryImageObjectFit: GalleryImageObjectFitType;
shouldAutoSwitchToNewImages: boolean;
galleryWidth: number;
shouldUseSingleGalleryColumn: boolean;
currentCategory: 'results' | 'uploads';
}
@ -26,7 +22,6 @@ export const initialGalleryState: GalleryState = {
galleryImageMinimumWidth: 64,
galleryImageObjectFit: 'cover',
shouldAutoSwitchToNewImages: true,
galleryWidth: 300,
shouldUseSingleGalleryColumn: false,
currentCategory: 'results',
};
@ -58,9 +53,6 @@ export const gallerySlice = createSlice({
) => {
state.currentCategory = action.payload;
},
setGalleryWidth: (state, action: PayloadAction<number>) => {
state.galleryWidth = action.payload;
},
setShouldUseSingleGalleryColumn: (
state,
action: PayloadAction<boolean>
@ -93,24 +85,28 @@ export const gallerySlice = createSlice({
builder.addCase(receivedResultImagesPage.fulfilled, (state, action) => {
// rehydrate selectedImage URL when results list comes in
// solves case when outdated URL is in local storage
if (state.selectedImage) {
const selectedImage = state.selectedImage;
if (selectedImage) {
const selectedImageInResults = action.payload.items.find(
(image) => image.image_name === state.selectedImage!.name
(image) => image.image_name === selectedImage.name
);
if (selectedImageInResults) {
state.selectedImage.url = selectedImageInResults.image_url;
selectedImage.url = selectedImageInResults.image_url;
state.selectedImage = selectedImage;
}
}
});
builder.addCase(receivedUploadImagesPage.fulfilled, (state, action) => {
// rehydrate selectedImage URL when results list comes in
// solves case when outdated URL is in local storage
if (state.selectedImage) {
const selectedImage = state.selectedImage;
if (selectedImage) {
const selectedImageInResults = action.payload.items.find(
(image) => image.image_name === state.selectedImage!.name
(image) => image.image_name === selectedImage.name
);
if (selectedImageInResults) {
state.selectedImage.url = selectedImageInResults.image_url;
selectedImage.url = selectedImageInResults.image_url;
state.selectedImage = selectedImage;
}
}
});
@ -122,7 +118,6 @@ export const {
setGalleryImageMinimumWidth,
setGalleryImageObjectFit,
setShouldAutoSwitchToNewImages,
setGalleryWidth,
setShouldUseSingleGalleryColumn,
setCurrentCategory,
} = gallerySlice.actions;

View File

@ -3,12 +3,6 @@ import { ResultsState } from './resultsSlice';
/**
* Results slice persist denylist
*
* Currently denylisting results slice entirely, see persist config in store.ts
* Currently denylisting results slice entirely, see `serialize.ts`
*/
const itemsToDenylist: (keyof ResultsState)[] = [];
export const resultsPersistDenylist: (keyof ResultsState)[] = [];
export const resultsDenylist = itemsToDenylist.map(
(denylistItem) => `results.${denylistItem}`
);

View File

@ -3,11 +3,6 @@ import { UploadsState } from './uploadsSlice';
/**
* Uploads slice persist denylist
*
* Currently denylisting uploads slice entirely, see persist config in store.ts
* Currently denylisting uploads slice entirely, see `serialize.ts`
*/
const itemsToDenylist: (keyof UploadsState)[] = [];
export const uploadsPersistDenylist: (keyof UploadsState)[] = [];
export const uploadsDenylist = itemsToDenylist.map(
(denylistItem) => `uploads.${denylistItem}`
);

View File

@ -3,11 +3,6 @@ import { LightboxState } from './lightboxSlice';
/**
* Lightbox slice persist denylist
*/
const itemsToDenylist: (keyof LightboxState)[] = ['isLightboxOpen'];
export const lightboxPersistDenylist: (keyof LightboxState)[] = [
'isLightboxOpen',
];
export const lightboxDenylist = itemsToDenylist.map(
(denylistItem) => `lightbox.${denylistItem}`
);

View File

@ -3,12 +3,7 @@ import { NodesState } from './nodesSlice';
/**
* Nodes slice persist denylist
*/
const itemsToDenylist: (keyof NodesState)[] = ['schema', 'invocationTemplates'];
export const nodesPersistDenylist: (keyof NodesState)[] = [
'schema',
'invocationTemplates',
];
export const nodesDenylist = itemsToDenylist.map(
(denylistItem) => `nodes.${denylistItem}`
);

View File

@ -26,16 +26,18 @@ const buildBaseNode = (
| ImageToImageInvocation
| InpaintInvocation
| undefined => {
const dimensionsOverride = state.canvas.boundingBoxDimensions;
if (nodeType === 'txt2img') {
return buildTxt2ImgNode(state, state.canvas.boundingBoxDimensions);
return buildTxt2ImgNode(state, dimensionsOverride);
}
if (nodeType === 'img2img') {
return buildImg2ImgNode(state, state.canvas.boundingBoxDimensions);
return buildImg2ImgNode(state, dimensionsOverride);
}
if (nodeType === 'inpaint' || nodeType === 'outpaint') {
return buildInpaintNode(state, state.canvas.boundingBoxDimensions);
return buildInpaintNode(state, dimensionsOverride);
}
};

View File

@ -25,7 +25,7 @@ export const buildImg2ImgNode = (
width,
height,
cfgScale,
sampler,
scheduler,
model,
img2imgStrength: strength,
shouldFitToWidthHeight: fit,
@ -43,14 +43,14 @@ export const buildImg2ImgNode = (
width,
height,
cfg_scale: cfgScale,
scheduler: sampler as ImageToImageInvocation['scheduler'],
scheduler,
model,
strength,
fit,
};
// on Canvas tab, we do not manually specific init image
if (activeTabName === 'img2img') {
if (activeTabName !== 'unifiedCanvas') {
if (!initialImage) {
// TODO: handle this more better
throw 'no initial image';

View File

@ -1,17 +1,16 @@
import { v4 as uuidv4 } from 'uuid';
import { RootState } from 'app/store/store';
import { InpaintInvocation } from 'services/api';
import { initialImageSelector } from 'features/parameters/store/generationSelectors';
import { O } from 'ts-toolbelt';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
export const buildInpaintNode = (
state: RootState,
overrides: O.Partial<InpaintInvocation, 'deep'> = {}
): InpaintInvocation => {
const nodeId = uuidv4();
const { generation, models } = state;
const { selectedModelName } = models;
const { generation } = state;
const activeTabName = activeTabNameSelector(state);
const {
prompt,
@ -21,21 +20,15 @@ export const buildInpaintNode = (
width,
height,
cfgScale,
sampler,
seamless,
scheduler,
model,
img2imgStrength: strength,
shouldFitToWidthHeight: fit,
shouldRandomizeSeed,
initialImage,
} = generation;
const initialImage = initialImageSelector(state);
if (!initialImage) {
// TODO: handle this
// throw 'no initial image';
}
const imageToImageNode: InpaintInvocation = {
const inpaintNode: InpaintInvocation = {
id: nodeId,
type: 'inpaint',
prompt: `${prompt} [${negativePrompt}]`,
@ -43,25 +36,30 @@ export const buildInpaintNode = (
width,
height,
cfg_scale: cfgScale,
scheduler: sampler as InpaintInvocation['scheduler'],
seamless,
model: selectedModelName,
progress_images: true,
image: initialImage
? {
image_name: initialImage.name,
image_type: initialImage.type,
}
: undefined,
scheduler,
model,
strength,
fit,
};
if (!shouldRandomizeSeed) {
imageToImageNode.seed = seed;
// on Canvas tab, we do not manually specific init image
if (activeTabName !== 'unifiedCanvas') {
if (!initialImage) {
// TODO: handle this more better
throw 'no initial image';
}
inpaintNode.image = {
image_name: initialImage.name,
image_type: initialImage.type,
};
}
Object.assign(imageToImageNode, overrides);
if (!shouldRandomizeSeed) {
inpaintNode.seed = seed;
}
return imageToImageNode;
Object.assign(inpaintNode, overrides);
return inpaintNode;
};

View File

@ -18,7 +18,7 @@ export const buildTxt2ImgNode = (
width,
height,
cfgScale: cfg_scale,
sampler,
scheduler,
shouldRandomizeSeed,
model,
} = generation;
@ -31,7 +31,7 @@ export const buildTxt2ImgNode = (
width,
height,
cfg_scale,
scheduler: sampler as TextToImageInvocation['scheduler'],
scheduler,
model,
};

View File

@ -1,15 +1,15 @@
import { Scheduler } from 'app/constants';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAICustomSelect from 'common/components/IAICustomSelect';
import IAISelect from 'common/components/IAISelect';
import { setSampler } from 'features/parameters/store/generationSlice';
import { setScheduler } from 'features/parameters/store/generationSlice';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { ChangeEvent, memo, useCallback } from 'react';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const ParamSampler = () => {
const sampler = useAppSelector(
(state: RootState) => state.generation.sampler
const ParamScheduler = () => {
const scheduler = useAppSelector(
(state: RootState) => state.generation.scheduler
);
const activeTabName = useAppSelector(activeTabNameSelector);
@ -28,15 +28,15 @@ const ParamSampler = () => {
if (!v) {
return;
}
dispatch(setSampler(v));
dispatch(setScheduler(v as Scheduler));
},
[dispatch]
);
return (
<IAICustomSelect
label={t('parameters.sampler')}
selectedItem={sampler}
label={t('parameters.scheduler')}
selectedItem={scheduler}
setSelectedItem={handleChange}
items={
['img2img', 'unifiedCanvas'].includes(activeTabName)
@ -48,4 +48,4 @@ const ParamSampler = () => {
);
};
export default memo(ParamSampler);
export default memo(ParamScheduler);

View File

@ -1,13 +1,13 @@
import { Box, Flex } from '@chakra-ui/react';
import { memo } from 'react';
import ParamSampler from './ParamSampler';
import ModelSelect from 'features/system/components/ModelSelect';
import ParamScheduler from './ParamScheduler';
const ParamSchedulerAndModel = () => {
return (
<Flex gap={3} w="full">
<Box w="16rem">
<ParamSampler />
<ParamScheduler />
</Box>
<Box w="full">
<ModelSelect />

View File

@ -3,9 +3,4 @@ import { GenerationState } from './generationSlice';
/**
* Generation slice persist denylist
*/
const itemsToDenylist: (keyof GenerationState)[] = [];
export const generationPersistDenylist: (keyof GenerationState)[] = [];
export const generationDenylist = itemsToDenylist.map(
(denylistItem) => `generation.${denylistItem}`
);

View File

@ -5,19 +5,19 @@ import promptToString from 'common/util/promptToString';
import { clamp, sample } from 'lodash-es';
import { setAllParametersReducer } from './setAllParametersReducer';
import { receivedModels } from 'services/thunks/model';
import { Scheduler } from 'app/constants';
export interface GenerationState {
cfgScale: number;
height: number;
img2imgStrength: number;
infillMethod: string;
initialImage?: InvokeAI.Image; // can be an Image or url
initialImage?: InvokeAI.Image;
iterations: number;
maskPath: string;
perlin: number;
prompt: string;
negativePrompt: string;
sampler: string;
scheduler: Scheduler;
seamBlur: number;
seamSize: number;
seamSteps: number;
@ -48,11 +48,10 @@ export const initialGenerationState: GenerationState = {
img2imgStrength: 0.75,
infillMethod: 'patchmatch',
iterations: 1,
maskPath: '',
perlin: 0,
prompt: '',
negativePrompt: '',
sampler: 'lms',
scheduler: 'lms',
seamBlur: 16,
seamSize: 96,
seamSteps: 30,
@ -135,8 +134,8 @@ export const generationSlice = createSlice({
setWidth: (state, action: PayloadAction<number>) => {
state.width = action.payload;
},
setSampler: (state, action: PayloadAction<string>) => {
state.sampler = action.payload;
setScheduler: (state, action: PayloadAction<Scheduler>) => {
state.scheduler = action.payload;
},
setSeed: (state, action: PayloadAction<number>) => {
state.seed = action.payload;
@ -145,9 +144,6 @@ export const generationSlice = createSlice({
setImg2imgStrength: (state, action: PayloadAction<number>) => {
state.img2imgStrength = action.payload;
},
setMaskPath: (state, action: PayloadAction<string>) => {
state.maskPath = action.payload;
},
setSeamless: (state, action: PayloadAction<boolean>) => {
state.shouldUseSeamless = action.payload;
},
@ -163,19 +159,6 @@ export const generationSlice = createSlice({
resetSeed: (state) => {
state.seed = -1;
},
setParameter: (
state,
action: PayloadAction<{ key: string; value: string | number | boolean }>
) => {
// TODO: This probably needs to be refactored.
// TODO: This probably also needs to be fixed after the reorg.
const { key, value } = action.payload;
const temp = { ...state, [key]: value };
if (key === 'seed') {
temp.shouldRandomizeSeed = false;
}
return temp;
},
setShouldGenerateVariations: (state, action: PayloadAction<boolean>) => {
state.shouldGenerateVariations = action.payload;
},
@ -258,14 +241,11 @@ export const {
setHeight,
setImg2imgStrength,
setInfillMethod,
// setInitialImage,
setIterations,
setMaskPath,
setParameter,
setPerlin,
setPrompt,
setNegativePrompt,
setSampler,
setScheduler,
setSeamBlur,
setSeamSize,
setSeamSteps,

View File

@ -3,9 +3,4 @@ import { PostprocessingState } from './postprocessingSlice';
/**
* Postprocessing slice persist denylist
*/
const itemsToDenylist: (keyof PostprocessingState)[] = [];
export const postprocessingPersistDenylist: (keyof PostprocessingState)[] = [];
export const postprocessingDenylist = itemsToDenylist.map(
(denylistItem) => `postprocessing.${denylistItem}`
);

View File

@ -2,6 +2,7 @@ import { Draft, PayloadAction } from '@reduxjs/toolkit';
import { Image } from 'app/types/invokeai';
import { GenerationState } from './generationSlice';
import { ImageToImageInvocation } from 'services/api';
import { isScheduler } from 'app/constants';
export const setAllParametersReducer = (
state: Draft<GenerationState>,
@ -34,7 +35,10 @@ export const setAllParametersReducer = (
state.prompt = String(prompt);
}
if (scheduler !== undefined) {
state.sampler = String(scheduler);
const schedulerString = String(scheduler);
if (isScheduler(schedulerString)) {
state.scheduler = schedulerString;
}
}
if (seed !== undefined) {
state.seed = Number(seed);

View File

@ -13,26 +13,15 @@ export const modelsAdapter = createEntityAdapter<Model>({
sortComparer: (a, b) => a.name.localeCompare(b.name),
});
type AdditionalModelsState = {
selectedModelName: string;
};
export const initialModelsState =
modelsAdapter.getInitialState<AdditionalModelsState>({
selectedModelName: '',
});
export const initialModelsState = modelsAdapter.getInitialState();
export type ModelsState = typeof initialModelsState;
export const modelsSlice = createSlice({
name: 'models',
initialState: modelsAdapter.getInitialState(),
// initialState: initialModelsState,
initialState: initialModelsState,
reducers: {
modelAdded: modelsAdapter.upsertOne,
// modelSelected: (state, action: PayloadAction<string>) => {
// state.selectedModelName = action.payload;
// },
},
extraReducers(builder) {
/**
@ -41,32 +30,10 @@ export const modelsSlice = createSlice({
builder.addCase(receivedModels.fulfilled, (state, action) => {
const models = action.payload;
modelsAdapter.setAll(state, models);
// If the current selected model is `''` or isn't actually in the list of models,
// choose a random model
// if (
// !state.selectedModelName ||
// !keys(models).includes(state.selectedModelName)
// ) {
// const randomModel = sample(models);
// if (randomModel) {
// state.selectedModelName = randomModel.name;
// } else {
// state.selectedModelName = '';
// }
// }
});
},
});
// export const selectedModelSelector = (state: RootState) => {
// const { selectedModelName } = state.models;
// const selectedModel = selectModelsById(state, selectedModelName);
// return selectedModel ?? null;
// };
export const {
selectAll: selectModelsAll,
selectById: selectModelsById,
@ -75,9 +42,6 @@ export const {
selectTotal: selectModelsTotal,
} = modelsAdapter.getSelectors<RootState>((state) => state.models);
export const {
modelAdded,
// modelSelected
} = modelsSlice.actions;
export const { modelAdded } = modelsSlice.actions;
export default modelsSlice.reducer;

View File

@ -3,9 +3,4 @@ import { ModelsState } from './modelSlice';
/**
* Models slice persist denylist
*/
const itemsToDenylist: (keyof ModelsState)[] = ['entities', 'ids'];
export const modelsPersistDenylist: (keyof ModelsState)[] = ['entities', 'ids'];
export const modelsDenylist = itemsToDenylist.map(
(denylistItem) => `models.${denylistItem}`
);

View File

@ -5,14 +5,12 @@ import { SystemState } from './systemSlice';
*/
export const systemPersistDenylist: (keyof SystemState)[] = [
'currentIteration',
'currentStatus',
'currentStep',
'isCancelable',
'isConnected',
'isESRGANAvailable',
'isGFPGANAvailable',
'isProcessing',
'socketId',
'totalIterations',
'totalSteps',
'openModel',

View File

@ -143,73 +143,15 @@ export const systemSlice = createSlice({
setCurrentStatus: (state, action: PayloadAction<TFuncKey>) => {
state.statusTranslationKey = action.payload;
},
errorOccurred: (state) => {
state.isProcessing = false;
state.isCancelable = true;
state.currentStep = 0;
state.totalSteps = 0;
state.currentIteration = 0;
state.totalIterations = 0;
state.currentStatusHasSteps = false;
state.statusTranslationKey = 'common.statusError';
},
setIsConnected: (state, action: PayloadAction<boolean>) => {
state.isConnected = action.payload;
state.isProcessing = false;
state.isCancelable = true;
state.currentStep = 0;
state.totalSteps = 0;
state.currentIteration = 0;
state.totalIterations = 0;
state.currentStatusHasSteps = false;
},
setShouldConfirmOnDelete: (state, action: PayloadAction<boolean>) => {
state.shouldConfirmOnDelete = action.payload;
},
setShouldDisplayGuides: (state, action: PayloadAction<boolean>) => {
state.shouldDisplayGuides = action.payload;
},
processingCanceled: (state) => {
state.isProcessing = false;
state.isCancelable = true;
state.currentStep = 0;
state.totalSteps = 0;
state.currentIteration = 0;
state.totalIterations = 0;
state.currentStatusHasSteps = false;
state.statusTranslationKey = 'common.statusProcessingCanceled';
},
generationRequested: (state) => {
state.isProcessing = true;
state.isCancelable = true;
state.currentStep = 0;
state.totalSteps = 0;
state.currentIteration = 0;
state.totalIterations = 0;
state.currentStatusHasSteps = false;
state.statusTranslationKey = 'common.statusPreparing';
},
setIsCancelable: (state, action: PayloadAction<boolean>) => {
state.isCancelable = action.payload;
},
modelChangeRequested: (state) => {
state.statusTranslationKey = 'common.statusLoadingModel';
state.isCancelable = false;
state.isProcessing = true;
state.currentStatusHasSteps = false;
},
modelConvertRequested: (state) => {
state.statusTranslationKey = 'common.statusConvertingModel';
state.isCancelable = false;
state.isProcessing = true;
state.currentStatusHasSteps = false;
},
modelMergingRequested: (state) => {
state.statusTranslationKey = 'common.statusMergingModels';
state.isCancelable = false;
state.isProcessing = true;
state.currentStatusHasSteps = false;
},
setEnableImageDebugging: (state, action: PayloadAction<boolean>) => {
state.enableImageDebugging = action.payload;
},
@ -219,14 +161,6 @@ export const systemSlice = createSlice({
clearToastQueue: (state) => {
state.toastQueue = [];
},
setProcessingIndeterminateTask: (
state,
action: PayloadAction<TFuncKey>
) => {
state.isProcessing = true;
state.statusTranslationKey = action.payload;
state.currentStatusHasSteps = false;
},
setSearchFolder: (state, action: PayloadAction<string | null>) => {
state.searchFolder = action.payload;
},
@ -485,21 +419,13 @@ export const systemSlice = createSlice({
export const {
setIsProcessing,
setIsConnected,
setShouldConfirmOnDelete,
setCurrentStatus,
setShouldDisplayGuides,
processingCanceled,
errorOccurred,
setIsCancelable,
modelChangeRequested,
modelConvertRequested,
modelMergingRequested,
setEnableImageDebugging,
generationRequested,
addToast,
clearToastQueue,
setProcessingIndeterminateTask,
setSearchFolder,
setFoundModels,
setOpenModel,

View File

@ -21,11 +21,7 @@ import UnifiedCanvasParameters from './tabs/UnifiedCanvas/UnifiedCanvasParameter
const selector = createSelector(
[uiSelector, activeTabNameSelector, lightboxSelector],
(ui, activeTabName, lightbox) => {
const {
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
} = ui;
const { shouldPinParametersPanel, shouldShowParametersPanel } = ui;
const { isLightboxOpen } = lightbox;
@ -33,7 +29,6 @@ const selector = createSelector(
activeTabName,
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
};
},
defaultSelectorOptions

View File

@ -3,11 +3,4 @@ import { UIState } from './uiTypes';
/**
* UI slice persist denylist
*/
const itemsToDenylist: (keyof UIState)[] = ['floatingProgressImageRect'];
export const uiPersistDenylist: (keyof UIState)[] = [
'floatingProgressImageRect',
];
export const uiDenylist = itemsToDenylist.map(
(denylistItem) => `ui.${denylistItem}`
);
export const uiPersistDenylist: (keyof UIState)[] = [];

View File

@ -1,16 +1,14 @@
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import { setActiveTabReducer } from './extraReducers';
import { InvokeTabName, tabMap } from './tabMap';
import { AddNewModelType, Coordinates, Rect, UIState } from './uiTypes';
import { initialImageSelected } from 'features/parameters/store/actions';
import { InvokeTabName } from './tabMap';
import { AddNewModelType, UIState } from './uiTypes';
import { initialImageChanged } from 'features/parameters/store/generationSlice';
import { SCHEDULERS } from 'app/constants';
export const initialUIState: UIState = {
activeTab: 0,
currentTheme: 'dark',
parametersPanelScrollPosition: 0,
shouldPinParametersPanel: true,
shouldShowParametersPanel: true,
shouldShowImageDetails: false,
@ -21,13 +19,7 @@ export const initialUIState: UIState = {
shouldPinGallery: true,
shouldShowGallery: true,
shouldHidePreview: false,
textTabAccordionState: [],
imageTabAccordionState: [],
canvasTabAccordionState: [],
floatingProgressImageRect: { x: 0, y: 0, width: 0, height: 0 },
shouldShowProgressImages: false,
shouldShowProgressInViewer: false,
shouldShowImageParameters: false,
schedulers: SCHEDULERS,
};
@ -41,12 +33,6 @@ export const uiSlice = createSlice({
setCurrentTheme: (state, action: PayloadAction<string>) => {
state.currentTheme = action.payload;
},
setParametersPanelScrollPosition: (
state,
action: PayloadAction<number>
) => {
state.parametersPanelScrollPosition = action.payload;
},
setShouldPinParametersPanel: (state, action: PayloadAction<boolean>) => {
state.shouldPinParametersPanel = action.payload;
state.shouldShowParametersPanel = true;
@ -75,9 +61,6 @@ export const uiSlice = createSlice({
setAddNewModelUIOption: (state, action: PayloadAction<AddNewModelType>) => {
state.addNewModelUIOption = action.payload;
},
setShouldPinGallery: (state, action: PayloadAction<boolean>) => {
state.shouldPinGallery = action.payload;
},
setShouldShowGallery: (state, action: PayloadAction<boolean>) => {
state.shouldShowGallery = action.payload;
},
@ -108,46 +91,9 @@ export const uiSlice = createSlice({
state.shouldShowParametersPanel = true;
}
},
openAccordionItemsChanged: (state, action: PayloadAction<number[]>) => {
if (tabMap[state.activeTab] === 'txt2img') {
state.textTabAccordionState = action.payload;
}
if (tabMap[state.activeTab] === 'img2img') {
state.imageTabAccordionState = action.payload;
}
if (tabMap[state.activeTab] === 'unifiedCanvas') {
state.canvasTabAccordionState = action.payload;
}
},
floatingProgressImageMoved: (state, action: PayloadAction<Coordinates>) => {
state.floatingProgressImageRect = {
...state.floatingProgressImageRect,
...action.payload,
};
},
floatingProgressImageResized: (
state,
action: PayloadAction<Partial<Rect>>
) => {
state.floatingProgressImageRect = {
...state.floatingProgressImageRect,
...action.payload,
};
},
setShouldShowProgressImages: (state, action: PayloadAction<boolean>) => {
state.shouldShowProgressImages = action.payload;
},
setShouldShowProgressInViewer: (state, action: PayloadAction<boolean>) => {
state.shouldShowProgressInViewer = action.payload;
},
shouldShowImageParametersChanged: (
state,
action: PayloadAction<boolean>
) => {
state.shouldShowImageParameters = action.payload;
},
setSchedulers: (state, action: PayloadAction<string[]>) => {
state.schedulers = [];
state.schedulers = action.payload;
@ -163,7 +109,6 @@ export const uiSlice = createSlice({
export const {
setActiveTab,
setCurrentTheme,
setParametersPanelScrollPosition,
setShouldPinParametersPanel,
setShouldShowParametersPanel,
setShouldShowImageDetails,
@ -172,19 +117,13 @@ export const {
setShouldUseSliders,
setAddNewModelUIOption,
setShouldHidePreview,
setShouldPinGallery,
setShouldShowGallery,
togglePanels,
togglePinGalleryPanel,
togglePinParametersPanel,
toggleParametersPanel,
toggleGalleryPanel,
openAccordionItemsChanged,
floatingProgressImageMoved,
floatingProgressImageResized,
setShouldShowProgressImages,
setShouldShowProgressInViewer,
shouldShowImageParametersChanged,
setSchedulers,
} = uiSlice.actions;

View File

@ -15,7 +15,6 @@ export type Rect = Coordinates & Dimensions;
export interface UIState {
activeTab: number;
currentTheme: string;
parametersPanelScrollPosition: number;
shouldPinParametersPanel: boolean;
shouldShowParametersPanel: boolean;
shouldShowImageDetails: boolean;
@ -26,12 +25,6 @@ export interface UIState {
shouldHidePreview: boolean;
shouldPinGallery: boolean;
shouldShowGallery: boolean;
textTabAccordionState: number[];
imageTabAccordionState: number[];
canvasTabAccordionState: number[];
floatingProgressImageRect: Rect;
shouldShowProgressImages: boolean;
shouldShowProgressInViewer: boolean;
shouldShowImageParameters: boolean;
schedulers: string[];
}

View File

@ -3,12 +3,14 @@
/* eslint-disable */
/**
* DO NOT DELETE EVEN THOUGH IT IS NOT USED!
*
* Custom `request.ts` file for OpenAPI code generator.
*
* Patches the request logic in such a way that we can extract headers from requests.
*
* Copied from https://github.com/ferdikoomen/openapi-typescript-codegen/issues/829#issuecomment-1228224477
*
*
* This file should be excluded in `tsconfig.json` and ignored by prettier/eslint!
*/

View File

@ -65,6 +65,7 @@ export type { PaginatedResults_ImageResponse_ } from './models/PaginatedResults_
export type { ParamIntInvocation } from './models/ParamIntInvocation';
export type { PasteImageInvocation } from './models/PasteImageInvocation';
export type { PromptOutput } from './models/PromptOutput';
export type { RandomIntInvocation } from './models/RandomIntInvocation';
export type { RandomRangeInvocation } from './models/RandomRangeInvocation';
export type { RangeInvocation } from './models/RangeInvocation';
export type { ResizeLatentsInvocation } from './models/ResizeLatentsInvocation';
@ -137,6 +138,7 @@ export { $PaginatedResults_ImageResponse_ } from './schemas/$PaginatedResults_Im
export { $ParamIntInvocation } from './schemas/$ParamIntInvocation';
export { $PasteImageInvocation } from './schemas/$PasteImageInvocation';
export { $PromptOutput } from './schemas/$PromptOutput';
export { $RandomIntInvocation } from './schemas/$RandomIntInvocation';
export { $RandomRangeInvocation } from './schemas/$RandomRangeInvocation';
export { $RangeInvocation } from './schemas/$RangeInvocation';
export { $ResizeLatentsInvocation } from './schemas/$ResizeLatentsInvocation';

View File

@ -28,6 +28,7 @@ import type { MultiplyInvocation } from './MultiplyInvocation';
import type { NoiseInvocation } from './NoiseInvocation';
import type { ParamIntInvocation } from './ParamIntInvocation';
import type { PasteImageInvocation } from './PasteImageInvocation';
import type { RandomIntInvocation } from './RandomIntInvocation';
import type { RandomRangeInvocation } from './RandomRangeInvocation';
import type { RangeInvocation } from './RangeInvocation';
import type { ResizeLatentsInvocation } from './ResizeLatentsInvocation';
@ -47,7 +48,7 @@ export type Graph = {
/**
* The nodes in this graph
*/
nodes?: Record<string, (LoadImageInvocation | ShowImageInvocation | CropImageInvocation | PasteImageInvocation | MaskFromAlphaInvocation | BlurInvocation | LerpInvocation | InverseLerpInvocation | CompelInvocation | NoiseInvocation | TextToLatentsInvocation | LatentsToImageInvocation | ResizeLatentsInvocation | ScaleLatentsInvocation | ImageToLatentsInvocation | AddInvocation | SubtractInvocation | MultiplyInvocation | DivideInvocation | ParamIntInvocation | CvInpaintInvocation | RangeInvocation | RandomRangeInvocation | UpscaleInvocation | RestoreFaceInvocation | TextToImageInvocation | InfillColorInvocation | InfillTileInvocation | InfillPatchMatchInvocation | GraphInvocation | IterateInvocation | CollectInvocation | LatentsToLatentsInvocation | ImageToImageInvocation | InpaintInvocation)>;
nodes?: Record<string, (LoadImageInvocation | ShowImageInvocation | CropImageInvocation | PasteImageInvocation | MaskFromAlphaInvocation | BlurInvocation | LerpInvocation | InverseLerpInvocation | CompelInvocation | NoiseInvocation | TextToLatentsInvocation | LatentsToImageInvocation | ResizeLatentsInvocation | ScaleLatentsInvocation | ImageToLatentsInvocation | AddInvocation | SubtractInvocation | MultiplyInvocation | DivideInvocation | RandomIntInvocation | ParamIntInvocation | CvInpaintInvocation | RangeInvocation | RandomRangeInvocation | UpscaleInvocation | RestoreFaceInvocation | TextToImageInvocation | InfillColorInvocation | InfillTileInvocation | InfillPatchMatchInvocation | GraphInvocation | IterateInvocation | CollectInvocation | LatentsToLatentsInvocation | ImageToImageInvocation | InpaintInvocation)>;
/**
* The connections between nodes and their fields in this graph
*/

View File

@ -40,7 +40,7 @@ export type ImageToImageInvocation = {
/**
* The scheduler to use
*/
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'heun_k' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
/**
* The model to use (currently ignored)
*/

View File

@ -41,7 +41,7 @@ export type InpaintInvocation = {
/**
* The scheduler to use
*/
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'heun_k' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
/**
* The model to use (currently ignored)
*/

View File

@ -8,10 +8,18 @@ import type { LatentsField } from './LatentsField';
* Base class for invocations that output latents
*/
export type LatentsOutput = {
type?: 'latent_output';
type?: 'latents_output';
/**
* The output latents
*/
latents?: LatentsField;
/**
* The width of the latents in pixels
*/
width: number;
/**
* The height of the latents in pixels
*/
height: number;
};

View File

@ -37,7 +37,7 @@ export type LatentsToLatentsInvocation = {
/**
* The scheduler to use
*/
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'heun_k' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
/**
* The model to use (currently ignored)
*/

View File

@ -13,5 +13,13 @@ export type NoiseOutput = {
* The output noise
*/
noise?: LatentsField;
/**
* The width of the noise in pixels
*/
width: number;
/**
* The height of the noise in pixels
*/
height: number;
};

View File

@ -0,0 +1,15 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
/**
* Outputs a single random integer.
*/
export type RandomIntInvocation = {
/**
* The id of this node. Must be unique among all nodes.
*/
id: string;
type?: 'rand_int';
};

View File

@ -38,7 +38,7 @@ export type TextToImageInvocation = {
/**
* The scheduler to use
*/
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'heun_k' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
/**
* The model to use (currently ignored)
*/

View File

@ -37,7 +37,7 @@ export type TextToLatentsInvocation = {
/**
* The scheduler to use
*/
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
scheduler?: 'ddim' | 'ddpm' | 'deis' | 'lms' | 'pndm' | 'heun' | 'heun_k' | 'euler' | 'euler_k' | 'euler_a' | 'kdpm_2' | 'kdpm_2_a' | 'dpmpp_2s' | 'dpmpp_2m' | 'dpmpp_2m_k' | 'unipc';
/**
* The model to use (currently ignored)
*/

View File

@ -49,6 +49,8 @@ export const $Graph = {
type: 'MultiplyInvocation',
}, {
type: 'DivideInvocation',
}, {
type: 'RandomIntInvocation',
}, {
type: 'ParamIntInvocation',
}, {

View File

@ -14,5 +14,15 @@ export const $LatentsOutput = {
type: 'LatentsField',
}],
},
width: {
type: 'number',
description: `The width of the latents in pixels`,
isRequired: true,
},
height: {
type: 'number',
description: `The height of the latents in pixels`,
isRequired: true,
},
},
} as const;

View File

@ -14,5 +14,15 @@ export const $NoiseOutput = {
type: 'LatentsField',
}],
},
width: {
type: 'number',
description: `The width of the noise in pixels`,
isRequired: true,
},
height: {
type: 'number',
description: `The height of the noise in pixels`,
isRequired: true,
},
},
} as const;

View File

@ -0,0 +1,16 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $RandomIntInvocation = {
description: `Outputs a single random integer.`,
properties: {
id: {
type: 'string',
description: `The id of this node. Must be unique among all nodes.`,
isRequired: true,
},
type: {
type: 'Enum',
},
},
} as const;

View File

@ -30,6 +30,7 @@ import type { NoiseInvocation } from '../models/NoiseInvocation';
import type { PaginatedResults_GraphExecutionState_ } from '../models/PaginatedResults_GraphExecutionState_';
import type { ParamIntInvocation } from '../models/ParamIntInvocation';
import type { PasteImageInvocation } from '../models/PasteImageInvocation';
import type { RandomIntInvocation } from '../models/RandomIntInvocation';
import type { RandomRangeInvocation } from '../models/RandomRangeInvocation';
import type { RangeInvocation } from '../models/RangeInvocation';
import type { ResizeLatentsInvocation } from '../models/ResizeLatentsInvocation';
@ -149,7 +150,7 @@ export class SessionsService {
* The id of the session
*/
sessionId: string,
requestBody: (LoadImageInvocation | ShowImageInvocation | CropImageInvocation | PasteImageInvocation | MaskFromAlphaInvocation | BlurInvocation | LerpInvocation | InverseLerpInvocation | CompelInvocation | NoiseInvocation | TextToLatentsInvocation | LatentsToImageInvocation | ResizeLatentsInvocation | ScaleLatentsInvocation | ImageToLatentsInvocation | AddInvocation | SubtractInvocation | MultiplyInvocation | DivideInvocation | ParamIntInvocation | CvInpaintInvocation | RangeInvocation | RandomRangeInvocation | UpscaleInvocation | RestoreFaceInvocation | TextToImageInvocation | InfillColorInvocation | InfillTileInvocation | InfillPatchMatchInvocation | GraphInvocation | IterateInvocation | CollectInvocation | LatentsToLatentsInvocation | ImageToImageInvocation | InpaintInvocation),
requestBody: (LoadImageInvocation | ShowImageInvocation | CropImageInvocation | PasteImageInvocation | MaskFromAlphaInvocation | BlurInvocation | LerpInvocation | InverseLerpInvocation | CompelInvocation | NoiseInvocation | TextToLatentsInvocation | LatentsToImageInvocation | ResizeLatentsInvocation | ScaleLatentsInvocation | ImageToLatentsInvocation | AddInvocation | SubtractInvocation | MultiplyInvocation | DivideInvocation | RandomIntInvocation | ParamIntInvocation | CvInpaintInvocation | RangeInvocation | RandomRangeInvocation | UpscaleInvocation | RestoreFaceInvocation | TextToImageInvocation | InfillColorInvocation | InfillTileInvocation | InfillPatchMatchInvocation | GraphInvocation | IterateInvocation | CollectInvocation | LatentsToLatentsInvocation | ImageToImageInvocation | InpaintInvocation),
}): CancelablePromise<string> {
return __request(OpenAPI, {
method: 'POST',
@ -186,7 +187,7 @@ export class SessionsService {
* The path to the node in the graph
*/
nodePath: string,
requestBody: (LoadImageInvocation | ShowImageInvocation | CropImageInvocation | PasteImageInvocation | MaskFromAlphaInvocation | BlurInvocation | LerpInvocation | InverseLerpInvocation | CompelInvocation | NoiseInvocation | TextToLatentsInvocation | LatentsToImageInvocation | ResizeLatentsInvocation | ScaleLatentsInvocation | ImageToLatentsInvocation | AddInvocation | SubtractInvocation | MultiplyInvocation | DivideInvocation | ParamIntInvocation | CvInpaintInvocation | RangeInvocation | RandomRangeInvocation | UpscaleInvocation | RestoreFaceInvocation | TextToImageInvocation | InfillColorInvocation | InfillTileInvocation | InfillPatchMatchInvocation | GraphInvocation | IterateInvocation | CollectInvocation | LatentsToLatentsInvocation | ImageToImageInvocation | InpaintInvocation),
requestBody: (LoadImageInvocation | ShowImageInvocation | CropImageInvocation | PasteImageInvocation | MaskFromAlphaInvocation | BlurInvocation | LerpInvocation | InverseLerpInvocation | CompelInvocation | NoiseInvocation | TextToLatentsInvocation | LatentsToImageInvocation | ResizeLatentsInvocation | ScaleLatentsInvocation | ImageToLatentsInvocation | AddInvocation | SubtractInvocation | MultiplyInvocation | DivideInvocation | RandomIntInvocation | ParamIntInvocation | CvInpaintInvocation | RangeInvocation | RandomRangeInvocation | UpscaleInvocation | RestoreFaceInvocation | TextToImageInvocation | InfillColorInvocation | InfillTileInvocation | InfillPatchMatchInvocation | GraphInvocation | IterateInvocation | CollectInvocation | LatentsToLatentsInvocation | ImageToImageInvocation | InpaintInvocation),
}): CancelablePromise<GraphExecutionState> {
return __request(OpenAPI, {
method: 'PUT',