merge with main

This commit is contained in:
Lincoln Stein 2023-05-15 09:07:17 -04:00
commit 7ef0d2aa35
26 changed files with 488 additions and 161 deletions

View File

@ -9,7 +9,8 @@ SCHEDULER_MAP = dict(
deis=(DEISMultistepScheduler, dict()), deis=(DEISMultistepScheduler, dict()),
lms=(LMSDiscreteScheduler, dict()), lms=(LMSDiscreteScheduler, dict()),
pndm=(PNDMScheduler, dict()), pndm=(PNDMScheduler, dict()),
heun=(HeunDiscreteScheduler, dict()), heun=(HeunDiscreteScheduler, dict(use_karras_sigmas=False)),
heun_k=(HeunDiscreteScheduler, dict(use_karras_sigmas=True)),
euler=(EulerDiscreteScheduler, dict(use_karras_sigmas=False)), euler=(EulerDiscreteScheduler, dict(use_karras_sigmas=False)),
euler_k=(EulerDiscreteScheduler, dict(use_karras_sigmas=True)), euler_k=(EulerDiscreteScheduler, dict(use_karras_sigmas=True)),
euler_a=(EulerAncestralDiscreteScheduler, dict()), euler_a=(EulerAncestralDiscreteScheduler, dict()),

View File

@ -2,34 +2,37 @@
"""invokeai.util.logging """invokeai.util.logging
Logging class for InvokeAI that produces console messages that follow Logging class for InvokeAI that produces console messages
the conventions established in InvokeAI 1.X through 2.X.
Usage:
One way to use it:
from invokeai.backend.util.logging import InvokeAILogger from invokeai.backend.util.logging import InvokeAILogger
logger = InvokeAILogger.getLogger(__name__) logger = InvokeAILogger.getLogger(name='InvokeAI') // Initialization
logger.critical('this is critical') (or)
logger.error('this is an error') logger = InvokeAILogger.getLogger(__name__) // To use the filename
logger.warning('this is a warning')
logger.info('this is info') logger.critical('this is critical') // Critical Message
logger.debug('this is debugging') logger.error('this is an error') // Error Message
logger.warning('this is a warning') // Warning Message
logger.info('this is info') // Info Message
logger.debug('this is debugging') // Debug Message
Console messages: Console messages:
### this is critical [12-05-2023 20]::[InvokeAI]::CRITICAL --> This is an info message [In Bold Red]
*** this is an error *** [12-05-2023 20]::[InvokeAI]::ERROR --> This is an info message [In Red]
** this is a warning [12-05-2023 20]::[InvokeAI]::WARNING --> This is an info message [In Yellow]
>> this is info [12-05-2023 20]::[InvokeAI]::INFO --> This is an info message [In Grey]
| this is debugging [12-05-2023 20]::[InvokeAI]::DEBUG --> This is an info message [In Grey]
Another way: Alternate Method (in this case the logger name will be set to InvokeAI):
import invokeai.backend.util.logging as ialog import invokeai.backend.util.logging as IAILogger
ialogger.debug('this is a debugging message') IAILogger.debug('this is a debugging message')
""" """
import logging import logging
# module level functions # module level functions
def debug(msg, *args, **kwargs): def debug(msg, *args, **kwargs):
InvokeAILogger.getLogger().debug(msg, *args, **kwargs) InvokeAILogger.getLogger().debug(msg, *args, **kwargs)
@ -42,7 +45,7 @@ def warning(msg, *args, **kwargs):
def error(msg, *args, **kwargs): def error(msg, *args, **kwargs):
InvokeAILogger.getLogger().error(msg, *args, **kwargs) InvokeAILogger.getLogger().error(msg, *args, **kwargs)
def critical(msg, *args, **kwargs): def critical(msg, *args, **kwargs):
InvokeAILogger.getLogger().critical(msg, *args, **kwargs) InvokeAILogger.getLogger().critical(msg, *args, **kwargs)
@ -55,49 +58,47 @@ def disable(level=logging.CRITICAL):
def basicConfig(**kwargs): def basicConfig(**kwargs):
InvokeAILogger.getLogger().basicConfig(**kwargs) InvokeAILogger.getLogger().basicConfig(**kwargs)
def getLogger(name: str=None)->logging.Logger: def getLogger(name: str = None) -> logging.Logger:
return InvokeAILogger.getLogger(name) return InvokeAILogger.getLogger(name)
class InvokeAILogFormatter(logging.Formatter): class InvokeAILogFormatter(logging.Formatter):
''' '''
Repurposed from: Custom Formatting for the InvokeAI Logger
https://stackoverflow.com/questions/14844970/modifying-logging-message-format-based-on-message-logging-level-in-python3
''' '''
crit_fmt = "### %(msg)s"
err_fmt = "*** %(msg)s"
warn_fmt = "** %(msg)s"
info_fmt = ">> %(msg)s"
dbg_fmt = " | %(msg)s"
def __init__(self): # Color Codes
super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%') grey = "\x1b[38;20m"
yellow = "\x1b[33;20m"
red = "\x1b[31;20m"
cyan = "\x1b[36;20m"
bold_red = "\x1b[31;1m"
reset = "\x1b[0m"
# Log Format
format = "[%(asctime)s]::[%(name)s]::%(levelname)s --> %(message)s"
## More Formatting Options: %(pathname)s, %(filename)s, %(module)s, %(lineno)d
# Format Map
FORMATS = {
logging.DEBUG: cyan + format + reset,
logging.INFO: grey + format + reset,
logging.WARNING: yellow + format + reset,
logging.ERROR: red + format + reset,
logging.CRITICAL: bold_red + format + reset
}
def format(self, record): def format(self, record):
# Remember the format used when the logging module log_fmt = self.FORMATS.get(record.levelno)
# was installed (in the event that this formatter is formatter = logging.Formatter(log_fmt, datefmt="%d-%m-%Y %H:%M:%S")
# used with the vanilla logging module. return formatter.format(record)
format_orig = self._style._fmt
if record.levelno == logging.DEBUG:
self._style._fmt = InvokeAILogFormatter.dbg_fmt
if record.levelno == logging.INFO:
self._style._fmt = InvokeAILogFormatter.info_fmt
if record.levelno == logging.WARNING:
self._style._fmt = InvokeAILogFormatter.warn_fmt
if record.levelno == logging.ERROR:
self._style._fmt = InvokeAILogFormatter.err_fmt
if record.levelno == logging.CRITICAL:
self._style._fmt = InvokeAILogFormatter.crit_fmt
# parent class does the work
result = super().format(record)
self._style._fmt = format_orig
return result
class InvokeAILogger(object): class InvokeAILogger(object):
loggers = dict() loggers = dict()
@classmethod @classmethod
def getLogger(self, name:str='invokeai')->logging.Logger: def getLogger(self, name: str = 'InvokeAI') -> logging.Logger:
if name not in self.loggers: if name not in self.loggers:
logger = logging.getLogger(name) logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)

View File

@ -9,6 +9,7 @@ SAMPLER_CHOICES = [
"lms", "lms",
"pndm", "pndm",
"heun", "heun",
'heun_k',
"euler", "euler",
"euler_k", "euler_k",
"euler_a", "euler_a",

View File

@ -62,11 +62,13 @@
"@dagrejs/graphlib": "^2.1.12", "@dagrejs/graphlib": "^2.1.12",
"@emotion/react": "^11.10.6", "@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6", "@emotion/styled": "^11.10.6",
"@floating-ui/react-dom": "^2.0.0",
"@fontsource/inter": "^4.5.15", "@fontsource/inter": "^4.5.15",
"@reduxjs/toolkit": "^1.9.5", "@reduxjs/toolkit": "^1.9.5",
"@roarr/browser-log-writer": "^1.1.5", "@roarr/browser-log-writer": "^1.1.5",
"chakra-ui-contextmenu": "^1.0.5", "chakra-ui-contextmenu": "^1.0.5",
"dateformat": "^5.0.3", "dateformat": "^5.0.3",
"downshift": "^7.6.0",
"formik": "^2.2.9", "formik": "^2.2.9",
"framer-motion": "^10.12.4", "framer-motion": "^10.12.4",
"fuse.js": "^6.6.2", "fuse.js": "^6.6.2",

View File

@ -540,7 +540,10 @@
"consoleLogLevel": "Log Level", "consoleLogLevel": "Log Level",
"shouldLogToConsole": "Console Logging", "shouldLogToConsole": "Console Logging",
"developer": "Developer", "developer": "Developer",
"general": "General" "general": "General",
"generation": "Generation",
"ui": "User Interface",
"availableSchedulers": "Available Schedulers"
}, },
"toast": { "toast": {
"serverError": "Server Error", "serverError": "Server Error",

View File

@ -30,9 +30,14 @@ const DEFAULT_CONFIG = {};
interface Props { interface Props {
config?: PartialAppConfig; config?: PartialAppConfig;
headerComponent?: ReactNode; headerComponent?: ReactNode;
setIsReady?: (isReady: boolean) => void;
} }
const App = ({ config = DEFAULT_CONFIG, headerComponent }: Props) => { const App = ({
config = DEFAULT_CONFIG,
headerComponent,
setIsReady,
}: Props) => {
useToastWatcher(); useToastWatcher();
useGlobalHotkeys(); useGlobalHotkeys();
@ -61,6 +66,16 @@ const App = ({ config = DEFAULT_CONFIG, headerComponent }: Props) => {
setLoadingOverridden(true); setLoadingOverridden(true);
}, []); }, []);
useEffect(() => {
if (isApplicationReady && setIsReady) {
setIsReady(true);
}
return () => {
setIsReady && setIsReady(false);
};
}, [isApplicationReady, setIsReady]);
return ( return (
<Grid w="100vw" h="100vh" position="relative" overflow="hidden"> <Grid w="100vw" h="100vh" position="relative" overflow="hidden">
{isLightboxEnabled && <Lightbox />} {isLightboxEnabled && <Lightbox />}

View File

@ -24,9 +24,16 @@ interface Props extends PropsWithChildren {
token?: string; token?: string;
config?: PartialAppConfig; config?: PartialAppConfig;
headerComponent?: ReactNode; headerComponent?: ReactNode;
setIsReady?: (isReady: boolean) => void;
} }
const InvokeAIUI = ({ apiUrl, token, config, headerComponent }: Props) => { const InvokeAIUI = ({
apiUrl,
token,
config,
headerComponent,
setIsReady,
}: Props) => {
useEffect(() => { useEffect(() => {
// configure API client token // configure API client token
if (token) { if (token) {
@ -55,7 +62,11 @@ const InvokeAIUI = ({ apiUrl, token, config, headerComponent }: Props) => {
<Provider store={store}> <Provider store={store}>
<React.Suspense fallback={<Loading />}> <React.Suspense fallback={<Loading />}>
<ThemeLocaleProvider> <ThemeLocaleProvider>
<App config={config} headerComponent={headerComponent} /> <App
config={config}
headerComponent={headerComponent}
setIsReady={setIsReady}
/>
</ThemeLocaleProvider> </ThemeLocaleProvider>
</React.Suspense> </React.Suspense>
</Provider> </Provider>

View File

@ -1,29 +1,24 @@
// TODO: use Enums? // TODO: use Enums?
export const DIFFUSERS_SCHEDULERS: Array<string> = [ export const SCHEDULERS: Array<string> = [
'ddim', 'ddim',
'ddpm',
'deis',
'lms', 'lms',
'pndm',
'heun',
'euler', 'euler',
'euler_k', 'euler_k',
'euler_a', 'euler_a',
'kdpm_2',
'kdpm_2_a',
'dpmpp_2s', 'dpmpp_2s',
'dpmpp_2m', 'dpmpp_2m',
'dpmpp_2m_k', 'dpmpp_2m_k',
'kdpm_2',
'kdpm_2_a',
'deis',
'ddpm',
'pndm',
'heun',
'heun_k',
'unipc', 'unipc',
]; ];
export const IMG2IMG_DIFFUSERS_SCHEDULERS = DIFFUSERS_SCHEDULERS.filter(
(scheduler) => {
return scheduler !== 'dpmpp_2s';
}
);
// Valid image widths // Valid image widths
export const WIDTHS: Array<number> = Array.from(Array(64)).map( export const WIDTHS: Array<number> = Array.from(Array(64)).map(
(_x, i) => (i + 1) * 64 (_x, i) => (i + 1) * 64

View File

@ -52,6 +52,7 @@ export type CommonGeneratedImageMetadata = {
| 'lms' | 'lms'
| 'pndm' | 'pndm'
| 'heun' | 'heun'
| 'heun_k'
| 'euler' | 'euler'
| 'euler_k' | 'euler_k'
| 'euler_a' | 'euler_a'

View File

@ -0,0 +1,172 @@
import { CheckIcon } from '@chakra-ui/icons';
import {
Box,
Flex,
FlexProps,
FormControl,
FormControlProps,
FormLabel,
Grid,
GridItem,
List,
ListItem,
Select,
Text,
Tooltip,
TooltipProps,
} from '@chakra-ui/react';
import { autoUpdate, offset, shift, useFloating } from '@floating-ui/react-dom';
import { useSelect } from 'downshift';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
import { memo } from 'react';
type IAICustomSelectProps = {
label?: string;
items: string[];
selectedItem: string;
setSelectedItem: (v: string | null | undefined) => void;
withCheckIcon?: boolean;
formControlProps?: FormControlProps;
buttonProps?: FlexProps;
tooltip?: string;
tooltipProps?: Omit<TooltipProps, 'children'>;
};
const IAICustomSelect = (props: IAICustomSelectProps) => {
const {
label,
items,
setSelectedItem,
selectedItem,
withCheckIcon,
formControlProps,
tooltip,
buttonProps,
tooltipProps,
} = props;
const {
isOpen,
getToggleButtonProps,
getLabelProps,
getMenuProps,
highlightedIndex,
getItemProps,
} = useSelect({
items,
selectedItem,
onSelectedItemChange: ({ selectedItem: newSelectedItem }) =>
setSelectedItem(newSelectedItem),
});
const { refs, floatingStyles } = useFloating<HTMLButtonElement>({
whileElementsMounted: autoUpdate,
middleware: [offset(4), shift({ crossAxis: true, padding: 8 })],
});
return (
<FormControl sx={{ w: 'full' }} {...formControlProps}>
{label && (
<FormLabel
{...getLabelProps()}
onClick={() => {
refs.floating.current && refs.floating.current.focus();
}}
>
{label}
</FormLabel>
)}
<Tooltip label={tooltip} {...tooltipProps}>
<Select
{...getToggleButtonProps({ ref: refs.setReference })}
{...buttonProps}
as={Flex}
sx={{
alignItems: 'center',
userSelect: 'none',
cursor: 'pointer',
}}
>
<Text sx={{ fontSize: 'sm', fontWeight: 500, color: 'base.100' }}>
{selectedItem}
</Text>
</Select>
</Tooltip>
<Box {...getMenuProps()}>
{isOpen && (
<List
as={Flex}
ref={refs.setFloating}
sx={{
...floatingStyles,
width: 'max-content',
top: 0,
left: 0,
flexDirection: 'column',
zIndex: 1,
bg: 'base.800',
borderRadius: 'base',
border: '1px',
borderColor: 'base.700',
shadow: 'dark-lg',
py: 2,
px: 0,
h: 'fit-content',
maxH: 64,
}}
>
<OverlayScrollbarsComponent>
{items.map((item, index) => (
<ListItem
sx={{
bg: highlightedIndex === index ? 'base.700' : undefined,
py: 1,
paddingInlineStart: 3,
paddingInlineEnd: 6,
cursor: 'pointer',
transitionProperty: 'common',
transitionDuration: '0.15s',
}}
key={`${item}${index}`}
{...getItemProps({ item, index })}
>
{withCheckIcon ? (
<Grid gridTemplateColumns="1.25rem auto">
<GridItem>
{selectedItem === item && <CheckIcon boxSize={2} />}
</GridItem>
<GridItem>
<Text
sx={{
fontSize: 'sm',
color: 'base.100',
fontWeight: 500,
}}
>
{item}
</Text>
</GridItem>
</Grid>
) : (
<Text
sx={{
fontSize: 'sm',
color: 'base.100',
fontWeight: 500,
}}
>
{item}
</Text>
)}
</ListItem>
))}
</OverlayScrollbarsComponent>
</List>
)}
</Box>
</FormControl>
);
};
export default memo(IAICustomSelect);

View File

@ -4,10 +4,10 @@ import { useAppSelector } from 'app/store/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { MdPhoto } from 'react-icons/md';
import { selectedImageSelector } from '../store/gallerySelectors'; import { selectedImageSelector } from '../store/gallerySelectors';
import CurrentImageButtons from './CurrentImageButtons'; import CurrentImageButtons from './CurrentImageButtons';
import CurrentImagePreview from './CurrentImagePreview'; import CurrentImagePreview from './CurrentImagePreview';
import { FaImage } from 'react-icons/fa';
export const currentImageDisplaySelector = createSelector( export const currentImageDisplaySelector = createSelector(
[systemSelector, selectedImageSelector], [systemSelector, selectedImageSelector],
@ -61,7 +61,7 @@ const CurrentImageDisplay = () => {
</> </>
) : ( ) : (
<Icon <Icon
as={MdPhoto} as={FaImage}
sx={{ sx={{
boxSize: 24, boxSize: 24,
color: 'base.500', color: 'base.500',

View File

@ -1,9 +1,6 @@
import {
DIFFUSERS_SCHEDULERS,
IMG2IMG_DIFFUSERS_SCHEDULERS,
} from 'app/constants';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAICustomSelect from 'common/components/IAICustomSelect';
import IAISelect from 'common/components/IAISelect'; import IAISelect from 'common/components/IAISelect';
import { setSampler } from 'features/parameters/store/generationSlice'; import { setSampler } from 'features/parameters/store/generationSlice';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
@ -17,25 +14,36 @@ const ParamSampler = () => {
const activeTabName = useAppSelector(activeTabNameSelector); const activeTabName = useAppSelector(activeTabNameSelector);
const schedulers = useAppSelector((state: RootState) => state.ui.schedulers);
const img2imgSchedulers = schedulers.filter((scheduler) => {
return !['dpmpp_2s'].includes(scheduler);
});
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { t } = useTranslation(); const { t } = useTranslation();
const handleChange = useCallback( const handleChange = useCallback(
(e: ChangeEvent<HTMLSelectElement>) => dispatch(setSampler(e.target.value)), (v: string | null | undefined) => {
if (!v) {
return;
}
dispatch(setSampler(v));
},
[dispatch] [dispatch]
); );
return ( return (
<IAISelect <IAICustomSelect
label={t('parameters.sampler')} label={t('parameters.sampler')}
value={sampler} selectedItem={sampler}
onChange={handleChange} setSelectedItem={handleChange}
validValues={ items={
activeTabName === 'img2img' || activeTabName == 'unifiedCanvas' ['img2img', 'unifiedCanvas'].includes(activeTabName)
? IMG2IMG_DIFFUSERS_SCHEDULERS ? img2imgSchedulers
: DIFFUSERS_SCHEDULERS : schedulers
} }
minWidth={36} withCheckIcon
/> />
); );
}; };

View File

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

View File

@ -1,4 +1,4 @@
import { Flex, Image } from '@chakra-ui/react'; import { Flex, Icon, Image } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import SelectImagePlaceholder from 'common/components/SelectImagePlaceholder'; import SelectImagePlaceholder from 'common/components/SelectImagePlaceholder';
@ -13,6 +13,7 @@ import { generationSelector } from 'features/parameters/store/generationSelector
import { initialImageSelected } from 'features/parameters/store/actions'; import { initialImageSelected } from 'features/parameters/store/actions';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import ImageFallbackSpinner from 'features/gallery/components/ImageFallbackSpinner'; import ImageFallbackSpinner from 'features/gallery/components/ImageFallbackSpinner';
import { FaImage } from 'react-icons/fa';
const selector = createSelector( const selector = createSelector(
[generationSelector], [generationSelector],
@ -83,7 +84,15 @@ const InitialImagePreview = () => {
<ImageMetadataOverlay image={initialImage} /> <ImageMetadataOverlay image={initialImage} />
</> </>
)} )}
{!initialImage?.url && <SelectImagePlaceholder />} {!initialImage?.url && (
<Icon
as={FaImage}
sx={{
boxSize: 24,
color: 'base.500',
}}
/>
)}
</Flex> </Flex>
); );
}; };

View File

@ -2,8 +2,9 @@ import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit';
import * as InvokeAI from 'app/types/invokeai'; import * as InvokeAI from 'app/types/invokeai';
import promptToString from 'common/util/promptToString'; import promptToString from 'common/util/promptToString';
import { clamp } from 'lodash-es'; import { clamp, sample } from 'lodash-es';
import { setAllParametersReducer } from './setAllParametersReducer'; import { setAllParametersReducer } from './setAllParametersReducer';
import { receivedModels } from 'services/thunks/model';
export interface GenerationState { export interface GenerationState {
cfgScale: number; cfgScale: number;
@ -236,6 +237,16 @@ export const generationSlice = createSlice({
state.model = action.payload; state.model = action.payload;
}, },
}, },
extraReducers: (builder) => {
builder.addCase(receivedModels.fulfilled, (state, action) => {
if (!state.model) {
const randomModel = sample(action.payload);
if (randomModel) {
state.model = randomModel.name;
}
}
});
},
}); });
export const { export const {

View File

@ -17,8 +17,17 @@ const InvokeAILogoComponent = () => {
h="32px" h="32px"
minW="32px" minW="32px"
minH="32px" minH="32px"
userSelect="none"
/> />
<Flex gap={3} display={{ base: 'inherit', sm: 'none', md: 'inherit' }}> <Flex
gap={3}
display={{
base: 'inherit',
sm: 'none',
md: 'inherit',
userSelect: 'none',
}}
>
<Text fontSize="xl"> <Text fontSize="xl">
invoke <strong>ai</strong> invoke <strong>ai</strong>
</Text> </Text>

View File

@ -1,21 +1,20 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { ChangeEvent, memo } from 'react'; import { memo, useCallback } from 'react';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISelect from 'common/components/IAISelect';
import { selectModelsById, selectModelsIds } from '../store/modelSlice'; import { selectModelsById, selectModelsIds } from '../store/modelSlice';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { modelSelected } from 'features/parameters/store/generationSlice'; import { modelSelected } from 'features/parameters/store/generationSlice';
import { generationSelector } from 'features/parameters/store/generationSelectors'; import { generationSelector } from 'features/parameters/store/generationSelectors';
import IAICustomSelect from 'common/components/IAICustomSelect';
const selector = createSelector( const selector = createSelector(
[(state: RootState) => state, generationSelector], [(state: RootState) => state, generationSelector],
(state, generation) => { (state, generation) => {
// const selectedModel = selectedModelSelector(state);
const selectedModel = selectModelsById(state, generation.model); const selectedModel = selectModelsById(state, generation.model);
const allModelNames = selectModelsIds(state); const allModelNames = selectModelsIds(state).map((id) => String(id));
return { return {
allModelNames, allModelNames,
selectedModel, selectedModel,
@ -32,19 +31,25 @@ const ModelSelect = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { t } = useTranslation(); const { t } = useTranslation();
const { allModelNames, selectedModel } = useAppSelector(selector); const { allModelNames, selectedModel } = useAppSelector(selector);
const handleChangeModel = (e: ChangeEvent<HTMLSelectElement>) => { const handleChangeModel = useCallback(
dispatch(modelSelected(e.target.value)); (v: string | null | undefined) => {
}; if (!v) {
return;
}
dispatch(modelSelected(v));
},
[dispatch]
);
return ( return (
<IAISelect <IAICustomSelect
label={t('modelManager.model')} label={t('modelManager.model')}
style={{ fontSize: 'sm' }} tooltip={selectedModel?.description}
aria-label={t('accessibility.modelSelect')} items={allModelNames}
tooltip={selectedModel?.description || ''} selectedItem={selectedModel?.name ?? ''}
value={selectedModel?.name || undefined} setSelectedItem={handleChangeModel}
validValues={allModelNames} withCheckIcon={true}
onChange={handleChangeModel} tooltipProps={{ placement: 'top', hasArrow: true }}
/> />
); );
}; };

View File

@ -40,6 +40,7 @@ import { useTranslation } from 'react-i18next';
import { VALID_LOG_LEVELS } from 'app/logging/useLogger'; import { VALID_LOG_LEVELS } from 'app/logging/useLogger';
import { LogLevelName } from 'roarr'; import { LogLevelName } from 'roarr';
import { LOCALSTORAGE_KEYS, LOCALSTORAGE_PREFIX } from 'app/store/constants'; import { LOCALSTORAGE_KEYS, LOCALSTORAGE_PREFIX } from 'app/store/constants';
import SettingsSchedulers from './SettingsSchedulers';
const selector = createSelector( const selector = createSelector(
[systemSelector, uiSelector], [systemSelector, uiSelector],
@ -171,7 +172,6 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
<Flex sx={{ gap: 4, flexDirection: 'column' }}> <Flex sx={{ gap: 4, flexDirection: 'column' }}>
<Flex sx={modalSectionStyles}> <Flex sx={modalSectionStyles}>
<Heading size="sm">{t('settings.general')}</Heading> <Heading size="sm">{t('settings.general')}</Heading>
<IAISwitch <IAISwitch
label={t('settings.confirmOnDelete')} label={t('settings.confirmOnDelete')}
isChecked={shouldConfirmOnDelete} isChecked={shouldConfirmOnDelete}
@ -179,6 +179,15 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
dispatch(setShouldConfirmOnDelete(e.target.checked)) dispatch(setShouldConfirmOnDelete(e.target.checked))
} }
/> />
</Flex>
<Flex sx={modalSectionStyles}>
<Heading size="sm">{t('settings.generation')}</Heading>
<SettingsSchedulers />
</Flex>
<Flex sx={modalSectionStyles}>
<Heading size="sm">{t('settings.ui')}</Heading>
<IAISwitch <IAISwitch
label={t('settings.displayHelpIcons')} label={t('settings.displayHelpIcons')}
isChecked={shouldDisplayGuides} isChecked={shouldDisplayGuides}

View File

@ -0,0 +1,49 @@
import {
Box,
Menu,
MenuButton,
MenuItemOption,
MenuList,
MenuOptionGroup,
} from '@chakra-ui/react';
import { SCHEDULERS } from 'app/constants';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIButton from 'common/components/IAIButton';
import { setSchedulers } from 'features/ui/store/uiSlice';
import { isArray } from 'lodash-es';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
import { useTranslation } from 'react-i18next';
export default function SettingsSchedulers() {
const schedulers = useAppSelector((state: RootState) => state.ui.schedulers);
const dispatch = useAppDispatch();
const { t } = useTranslation();
const schedulerSettingsHandler = (v: string | string[]) => {
if (isArray(v)) dispatch(setSchedulers(v.sort()));
};
return (
<Menu closeOnSelect={false}>
<MenuButton as={IAIButton}>
{t('settings.availableSchedulers')}
</MenuButton>
<MenuList maxHeight={64} overflowY="scroll">
<MenuOptionGroup
value={schedulers}
type="checkbox"
onChange={schedulerSettingsHandler}
>
{SCHEDULERS.map((scheduler) => (
<MenuItemOption key={scheduler} value={scheduler}>
{scheduler}
</MenuItemOption>
))}
</MenuOptionGroup>
</MenuList>
</Menu>
);
}

View File

@ -1,5 +1,5 @@
import { memo } from 'react'; import { memo } from 'react';
import { Box, Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { uiSelector } from 'features/ui/store/uiSelectors'; import { uiSelector } from 'features/ui/store/uiSelectors';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
@ -9,11 +9,10 @@ import ParamSteps from 'features/parameters/components/Parameters/Core/ParamStep
import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale'; import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale';
import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth'; import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth';
import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight'; import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight';
import ParamSampler from 'features/parameters/components/Parameters/Core/ParamSampler';
import ModelSelect from 'features/system/components/ModelSelect';
import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength'; import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength';
import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit'; import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit';
import { generationSelector } from 'features/parameters/store/generationSelectors'; import { generationSelector } from 'features/parameters/store/generationSelectors';
import ParamSchedulerAndModel from 'features/parameters/components/Parameters/Core/ParamSchedulerAndModel';
const selector = createSelector( const selector = createSelector(
[uiSelector, generationSelector], [uiSelector, generationSelector],
@ -48,14 +47,7 @@ const ImageToImageTabCoreParameters = () => {
<ParamHeight isDisabled={!shouldFitToWidthHeight} /> <ParamHeight isDisabled={!shouldFitToWidthHeight} />
<ImageToImageStrength /> <ImageToImageStrength />
<ImageToImageFit /> <ImageToImageFit />
<Flex gap={3} w="full"> <ParamSchedulerAndModel />
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
</Flex> </Flex>
) : ( ) : (
<Flex sx={{ gap: 2, flexDirection: 'column' }}> <Flex sx={{ gap: 2, flexDirection: 'column' }}>
@ -64,14 +56,7 @@ const ImageToImageTabCoreParameters = () => {
<ParamSteps /> <ParamSteps />
<ParamCFGScale /> <ParamCFGScale />
</Flex> </Flex>
<Flex gap={3} w="full"> <ParamSchedulerAndModel />
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
<ParamWidth isDisabled={!shouldFitToWidthHeight} /> <ParamWidth isDisabled={!shouldFitToWidthHeight} />
<ParamHeight isDisabled={!shouldFitToWidthHeight} /> <ParamHeight isDisabled={!shouldFitToWidthHeight} />
<ImageToImageStrength /> <ImageToImageStrength />

View File

@ -3,14 +3,13 @@ import ParamSteps from 'features/parameters/components/Parameters/Core/ParamStep
import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale'; import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale';
import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth'; import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth';
import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight'; import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight';
import ParamSampler from 'features/parameters/components/Parameters/Core/ParamSampler'; import { Flex } from '@chakra-ui/react';
import ModelSelect from 'features/system/components/ModelSelect';
import { Box, Flex } from '@chakra-ui/react';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { uiSelector } from 'features/ui/store/uiSelectors'; import { uiSelector } from 'features/ui/store/uiSelectors';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { memo } from 'react'; import { memo } from 'react';
import ParamSchedulerAndModel from 'features/parameters/components/Parameters/Core/ParamSchedulerAndModel';
const selector = createSelector( const selector = createSelector(
uiSelector, uiSelector,
@ -42,14 +41,7 @@ const TextToImageTabCoreParameters = () => {
<ParamCFGScale /> <ParamCFGScale />
<ParamWidth /> <ParamWidth />
<ParamHeight /> <ParamHeight />
<Flex gap={3} w="full"> <ParamSchedulerAndModel />
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
</Flex> </Flex>
) : ( ) : (
<Flex sx={{ gap: 2, flexDirection: 'column' }}> <Flex sx={{ gap: 2, flexDirection: 'column' }}>
@ -58,14 +50,7 @@ const TextToImageTabCoreParameters = () => {
<ParamSteps /> <ParamSteps />
<ParamCFGScale /> <ParamCFGScale />
</Flex> </Flex>
<Flex gap={3} w="full"> <ParamSchedulerAndModel />
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
<ParamWidth /> <ParamWidth />
<ParamHeight /> <ParamHeight />
</Flex> </Flex>

View File

@ -1,10 +1,9 @@
import { memo } from 'react'; import { memo } from 'react';
import { Box, Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { uiSelector } from 'features/ui/store/uiSelectors'; import { uiSelector } from 'features/ui/store/uiSelectors';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import ModelSelect from 'features/system/components/ModelSelect';
import ParamIterations from 'features/parameters/components/Parameters/Core/ParamIterations'; import ParamIterations from 'features/parameters/components/Parameters/Core/ParamIterations';
import ParamSteps from 'features/parameters/components/Parameters/Core/ParamSteps'; import ParamSteps from 'features/parameters/components/Parameters/Core/ParamSteps';
import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale'; import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale';
@ -12,7 +11,7 @@ import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidt
import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight'; import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight';
import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength'; import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength';
import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit'; import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit';
import ParamSampler from 'features/parameters/components/Parameters/Core/ParamSampler'; import ParamSchedulerAndModel from 'features/parameters/components/Parameters/Core/ParamSchedulerAndModel';
const selector = createSelector( const selector = createSelector(
uiSelector, uiSelector,
@ -46,14 +45,7 @@ const UnifiedCanvasCoreParameters = () => {
<ParamHeight /> <ParamHeight />
<ImageToImageStrength /> <ImageToImageStrength />
<ImageToImageFit /> <ImageToImageFit />
<Flex gap={3} w="full"> <ParamSchedulerAndModel />
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
</Flex> </Flex>
) : ( ) : (
<Flex sx={{ gap: 2, flexDirection: 'column' }}> <Flex sx={{ gap: 2, flexDirection: 'column' }}>
@ -62,14 +54,7 @@ const UnifiedCanvasCoreParameters = () => {
<ParamSteps /> <ParamSteps />
<ParamCFGScale /> <ParamCFGScale />
</Flex> </Flex>
<Flex gap={3} w="full"> <ParamSchedulerAndModel />
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
<ParamWidth /> <ParamWidth />
<ParamHeight /> <ParamHeight />
<ImageToImageStrength /> <ImageToImageStrength />

View File

@ -5,6 +5,7 @@ import { InvokeTabName, tabMap } from './tabMap';
import { AddNewModelType, Coordinates, Rect, UIState } from './uiTypes'; import { AddNewModelType, Coordinates, Rect, UIState } from './uiTypes';
import { initialImageSelected } from 'features/parameters/store/actions'; import { initialImageSelected } from 'features/parameters/store/actions';
import { initialImageChanged } from 'features/parameters/store/generationSlice'; import { initialImageChanged } from 'features/parameters/store/generationSlice';
import { SCHEDULERS } from 'app/constants';
export const initialUIState: UIState = { export const initialUIState: UIState = {
activeTab: 0, activeTab: 0,
@ -27,6 +28,7 @@ export const initialUIState: UIState = {
shouldShowProgressImages: false, shouldShowProgressImages: false,
shouldShowProgressInViewer: false, shouldShowProgressInViewer: false,
shouldShowImageParameters: false, shouldShowImageParameters: false,
schedulers: SCHEDULERS,
}; };
export const uiSlice = createSlice({ export const uiSlice = createSlice({
@ -146,6 +148,10 @@ export const uiSlice = createSlice({
) => { ) => {
state.shouldShowImageParameters = action.payload; state.shouldShowImageParameters = action.payload;
}, },
setSchedulers: (state, action: PayloadAction<string[]>) => {
state.schedulers = [];
state.schedulers = action.payload;
},
}, },
extraReducers(builder) { extraReducers(builder) {
builder.addCase(initialImageChanged, (state) => { builder.addCase(initialImageChanged, (state) => {
@ -179,6 +185,7 @@ export const {
setShouldShowProgressImages, setShouldShowProgressImages,
setShouldShowProgressInViewer, setShouldShowProgressInViewer,
shouldShowImageParametersChanged, shouldShowImageParametersChanged,
setSchedulers,
} = uiSlice.actions; } = uiSlice.actions;
export default uiSlice.reducer; export default uiSlice.reducer;

View File

@ -33,4 +33,5 @@ export interface UIState {
shouldShowProgressImages: boolean; shouldShowProgressImages: boolean;
shouldShowProgressInViewer: boolean; shouldShowProgressInViewer: boolean;
shouldShowImageParameters: boolean; shouldShowImageParameters: boolean;
schedulers: string[];
} }

View File

@ -57,7 +57,7 @@
dependencies: dependencies:
regenerator-runtime "^0.13.11" regenerator-runtime "^0.13.11"
"@babel/runtime@^7.1.2": "@babel/runtime@^7.1.2", "@babel/runtime@^7.14.8":
version "7.21.5" version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
@ -1198,6 +1198,25 @@
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b" resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b"
integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng== integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==
"@floating-ui/core@^1.2.6":
version "1.2.6"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.2.6.tgz#d21ace437cc919cdd8f1640302fa8851e65e75c0"
integrity sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==
"@floating-ui/dom@^1.2.7":
version "1.2.7"
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.2.7.tgz#c123e4db014b07b97e996cd459245fa217049c6b"
integrity sha512-DyqylONj1ZaBnzj+uBnVfzdjjCkFCL2aA9ESHLyUOGSqb03RpbLMImP1ekIQXYs4KLk9jAjJfZAU8hXfWSahEg==
dependencies:
"@floating-ui/core" "^1.2.6"
"@floating-ui/react-dom@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.0.tgz#7514baac526c818892bbcc84e1c3115008c029f9"
integrity sha512-Ke0oU3SeuABC2C4OFu2mSAwHIP5WUiV98O9YWoHV4Q5aT6E9k06DV0Khi5uYspR8xmmBk08t8ZDcz3TR3ARkEg==
dependencies:
"@floating-ui/dom" "^1.2.7"
"@fontsource/inter@^4.5.15": "@fontsource/inter@^4.5.15":
version "4.5.15" version "4.5.15"
resolved "https://registry.yarnpkg.com/@fontsource/inter/-/inter-4.5.15.tgz#eed1873d68755d3b52d6fcfcfa3493118430a512" resolved "https://registry.yarnpkg.com/@fontsource/inter/-/inter-4.5.15.tgz#eed1873d68755d3b52d6fcfcfa3493118430a512"
@ -2680,6 +2699,11 @@ compute-scroll-into-view@1.0.20:
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz#1768b5522d1172754f5d0c9b02de3af6be506a43" resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz#1768b5522d1172754f5d0c9b02de3af6be506a43"
integrity sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg== integrity sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==
compute-scroll-into-view@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-2.0.4.tgz#2b444b2b9e4724819d2531efacb7ac094155fdf6"
integrity sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g==
concat-map@0.0.1: concat-map@0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@ -3131,6 +3155,17 @@ dot-prop@^5.2.0:
dependencies: dependencies:
is-obj "^2.0.0" is-obj "^2.0.0"
downshift@^7.6.0:
version "7.6.0"
resolved "https://registry.yarnpkg.com/downshift/-/downshift-7.6.0.tgz#de04fb2962bd6c4ea94589c797c91f34aa9816f3"
integrity sha512-VSoTVynTAsabou/hbZ6HJHUVhtBiVOjQoBsCPcQq5eAROIGP+9XKMp9asAKQ3cEcUP4oe0fFdD2pziUjhFY33Q==
dependencies:
"@babel/runtime" "^7.14.8"
compute-scroll-into-view "^2.0.4"
prop-types "^15.7.2"
react-is "^17.0.2"
tslib "^2.3.0"
duplexer3@^0.1.4: duplexer3@^0.1.4:
version "0.1.5" version "0.1.5"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
@ -5356,7 +5391,7 @@ pretty-ms@^7.0.1:
dependencies: dependencies:
parse-ms "^2.1.0" parse-ms "^2.1.0"
prop-types@^15.6.2, prop-types@^15.8.1: prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1" version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -5517,6 +5552,11 @@ react-is@^16.13.1, react-is@^16.7.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-is@^18.0.0: react-is@^18.0.0:
version "18.2.0" version "18.2.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
@ -6485,7 +6525,7 @@ tslib@^1.10.0, tslib@^1.8.1:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0:
version "2.5.0" version "2.5.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==

View File

@ -2,6 +2,9 @@
# Copyright (c) 2022 Kyle Schouviller (https://github.com/kyle0654) # Copyright (c) 2022 Kyle Schouviller (https://github.com/kyle0654)
import logging
logging.getLogger("xformers").addFilter(lambda record: 'A matching Triton is not available' not in record.getMessage())
import os import os
import sys import sys