mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
hook MM default model settings up to API
This commit is contained in:
@ -741,6 +741,8 @@
|
|||||||
"customConfig": "Custom Config",
|
"customConfig": "Custom Config",
|
||||||
"customConfigFileLocation": "Custom Config File Location",
|
"customConfigFileLocation": "Custom Config File Location",
|
||||||
"customSaveLocation": "Custom Save Location",
|
"customSaveLocation": "Custom Save Location",
|
||||||
|
"defaultSettings": "Default Settings",
|
||||||
|
"defaultSettingsSaved": "Default Settings Saved",
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"deleteConfig": "Delete Config",
|
"deleteConfig": "Delete Config",
|
||||||
"deleteModel": "Delete Model",
|
"deleteModel": "Delete Model",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants';
|
import type { CONTROLNET_PROCESSORS } from 'features/controlAdapters/store/constants';
|
||||||
|
import type { ParameterPrecision, ParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
||||||
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import type { O } from 'ts-toolbelt';
|
import type { O } from 'ts-toolbelt';
|
||||||
import { ParameterPrecision, ParameterScheduler } from '../../features/parameters/types/parameterSchemas';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A disable-able application feature
|
* A disable-able application feature
|
||||||
|
@ -1,33 +1,13 @@
|
|||||||
import { Button, Flex, Heading } from '@invoke-ai/ui-library';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { SubmitHandler, useForm } from 'react-hook-form';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { SettingToggle } from './DefaultSettings/SettingToggle';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { DefaultCfgScale } from './DefaultSettings/DefaultCfgScale';
|
import Loading from 'common/components/Loading/Loading';
|
||||||
import { DefaultSteps } from './DefaultSettings/DefaultSteps';
|
import { selectConfigSlice } from 'features/system/store/configSlice';
|
||||||
import { useAppSelector } from '../../../../app/store/storeHooks';
|
import { isNil } from 'lodash-es';
|
||||||
import { DefaultScheduler } from './DefaultSettings/DefaultScheduler';
|
import { useMemo } from 'react';
|
||||||
import { selectGenerationSlice } from '../../../parameters/store/generationSlice';
|
import { useGetModelMetadataQuery } from 'services/api/endpoints/models';
|
||||||
import { createMemoizedSelector } from '../../../../app/store/createMemoizedSelector';
|
|
||||||
import { selectConfigSlice } from '../../../system/store/configSlice';
|
|
||||||
import { DefaultVaePrecision } from './DefaultSettings/DefaultVaePrecision';
|
|
||||||
import { DefaultCfgRescaleMultiplier } from './DefaultSettings/DefaultCfgRescaleMultiplier';
|
|
||||||
import { DefaultVae } from './DefaultSettings/DefaultVae';
|
|
||||||
import { t } from 'i18next';
|
|
||||||
import { IoPencil } from 'react-icons/io5';
|
|
||||||
import { each } from 'lodash-es';
|
|
||||||
|
|
||||||
export interface FormField<T> {
|
import { DefaultSettingsForm } from './DefaultSettings/DefaultSettingsForm';
|
||||||
value: T;
|
|
||||||
isEnabled: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DefaultSettingsFormData = {
|
|
||||||
vae: FormField<string | null>;
|
|
||||||
vaePrecision: FormField<string>;
|
|
||||||
scheduler: FormField<string>;
|
|
||||||
steps: FormField<number>;
|
|
||||||
cfgScale: FormField<number>;
|
|
||||||
cfgRescaleMultiplier: FormField<number>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialStatesSelector = createMemoizedSelector(selectConfigSlice, (config) => {
|
const initialStatesSelector = createMemoizedSelector(selectConfigSlice, (config) => {
|
||||||
const { steps, guidance, scheduler, cfgRescaleMultiplier, vaePrecision } = config.sd;
|
const { steps, guidance, scheduler, cfgRescaleMultiplier, vaePrecision } = config.sd;
|
||||||
@ -42,78 +22,45 @@ const initialStatesSelector = createMemoizedSelector(selectConfigSlice, (config)
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const DefaultSettings = () => {
|
export const DefaultSettings = () => {
|
||||||
|
const selectedModelKey = useAppSelector((s) => s.modelmanagerV2.selectedModelKey);
|
||||||
|
|
||||||
|
const { data, isLoading } = useGetModelMetadataQuery(selectedModelKey ?? skipToken);
|
||||||
const { initialSteps, initialCfg, initialScheduler, initialCfgRescaleMultiplier, initialVaePrecision } =
|
const { initialSteps, initialCfg, initialScheduler, initialCfgRescaleMultiplier, initialVaePrecision } =
|
||||||
useAppSelector(initialStatesSelector);
|
useAppSelector(initialStatesSelector);
|
||||||
|
|
||||||
const { handleSubmit, control, formState } = useForm<DefaultSettingsFormData>({
|
const defaultSettingsDefaults = useMemo(() => {
|
||||||
defaultValues: {
|
return {
|
||||||
vae: { isEnabled: false, value: null },
|
vae: { isEnabled: !isNil(data?.default_settings?.vae), value: data?.default_settings?.vae || 'default' },
|
||||||
vaePrecision: { isEnabled: false, value: initialVaePrecision },
|
vaePrecision: {
|
||||||
scheduler: { isEnabled: false, value: initialScheduler },
|
isEnabled: !isNil(data?.default_settings?.vae_precision),
|
||||||
steps: { isEnabled: false, value: initialSteps },
|
value: data?.default_settings?.vae_precision || initialVaePrecision || 'fp32',
|
||||||
cfgScale: { isEnabled: false, value: initialCfg },
|
},
|
||||||
cfgRescaleMultiplier: { isEnabled: false, value: initialCfgRescaleMultiplier },
|
scheduler: {
|
||||||
|
isEnabled: !isNil(data?.default_settings?.scheduler),
|
||||||
|
value: data?.default_settings?.scheduler || initialScheduler || 'euler',
|
||||||
|
},
|
||||||
|
steps: { isEnabled: !isNil(data?.default_settings?.steps), value: data?.default_settings?.steps || initialSteps },
|
||||||
|
cfgScale: {
|
||||||
|
isEnabled: !isNil(data?.default_settings?.cfg_scale),
|
||||||
|
value: data?.default_settings?.cfg_scale || initialCfg,
|
||||||
|
},
|
||||||
|
cfgRescaleMultiplier: {
|
||||||
|
isEnabled: !isNil(data?.default_settings?.cfg_rescale_multiplier),
|
||||||
|
value: data?.default_settings?.cfg_rescale_multiplier || initialCfgRescaleMultiplier,
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit: SubmitHandler<DefaultSettingsFormData> = (data) => {
|
|
||||||
const body: { [key: string]: string | number | null } = {};
|
|
||||||
each(data, (value, key) => {
|
|
||||||
if (value.isEnabled) {
|
|
||||||
body[key] = value.value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log(body);
|
|
||||||
};
|
};
|
||||||
|
}, [
|
||||||
|
data?.default_settings,
|
||||||
|
initialSteps,
|
||||||
|
initialCfg,
|
||||||
|
initialScheduler,
|
||||||
|
initialCfgRescaleMultiplier,
|
||||||
|
initialVaePrecision,
|
||||||
|
]);
|
||||||
|
|
||||||
return (
|
if (isLoading) {
|
||||||
<>
|
return <Loading />;
|
||||||
<Flex gap="2" justifyContent="space-between" w="full" mb={5}>
|
}
|
||||||
<Heading fontSize="md">Default Settings</Heading>
|
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
leftIcon={<IoPencil />}
|
|
||||||
colorScheme="invokeYellow"
|
|
||||||
isDisabled={!formState.isDirty}
|
|
||||||
onClick={handleSubmit(onSubmit)}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
{t('common.save')}
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Flex flexDir="column" gap={8}>
|
return <DefaultSettingsForm defaultSettingsDefaults={defaultSettingsDefaults} />;
|
||||||
<Flex gap={8}>
|
|
||||||
<Flex gap={4} w="full">
|
|
||||||
<SettingToggle control={control} name="vae" />
|
|
||||||
<DefaultVae control={control} name="vae" />
|
|
||||||
</Flex>
|
|
||||||
<Flex gap={4} w="full">
|
|
||||||
<SettingToggle control={control} name="vaePrecision" />
|
|
||||||
<DefaultVaePrecision control={control} name="vaePrecision" />
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
<Flex gap={8}>
|
|
||||||
<Flex gap={4} w="full">
|
|
||||||
<SettingToggle control={control} name="scheduler" />
|
|
||||||
<DefaultScheduler control={control} name="scheduler" />
|
|
||||||
</Flex>
|
|
||||||
<Flex gap={4} w="full">
|
|
||||||
<SettingToggle control={control} name="steps" />
|
|
||||||
<DefaultSteps control={control} name="steps" />
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
<Flex gap={8}>
|
|
||||||
<Flex gap={4} w="full">
|
|
||||||
<SettingToggle control={control} name="cfgScale" />
|
|
||||||
<DefaultCfgScale control={control} name="cfgScale" />
|
|
||||||
</Flex>
|
|
||||||
<Flex gap={4} w="full">
|
|
||||||
<SettingToggle control={control} name="cfgRescaleMultiplier" />
|
|
||||||
<DefaultCfgRescaleMultiplier control={control} name="cfgRescaleMultiplier" />
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import { FormControl, FormLabel, CompositeSlider, CompositeNumberInput, Flex } from '@invoke-ai/ui-library';
|
import { CompositeNumberInput, CompositeSlider, Flex,FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
import { useMemo } from 'react';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||||
|
import { useCallback,useMemo } from 'react';
|
||||||
|
import type {UseControllerProps } from 'react-hook-form';
|
||||||
|
import { useController } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useAppSelector } from '../../../../../app/store/storeHooks';
|
|
||||||
import { InformationalPopover } from '../../../../../common/components/InformationalPopover/InformationalPopover';
|
import type { DefaultSettingsFormData } from './DefaultSettingsForm';
|
||||||
import { UseControllerProps, useController } from 'react-hook-form';
|
|
||||||
import { DefaultSettingsFormData } from '../DefaultSettings';
|
|
||||||
import { useCallback } from 'react';
|
|
||||||
|
|
||||||
type DefaultCfgRescaleMultiplierType = DefaultSettingsFormData['cfgRescaleMultiplier'];
|
type DefaultCfgRescaleMultiplierType = DefaultSettingsFormData['cfgRescaleMultiplier'];
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import { FormControl, FormLabel, CompositeSlider, CompositeNumberInput, Flex } from '@invoke-ai/ui-library';
|
import { CompositeNumberInput, CompositeSlider, Flex,FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
import { useMemo } from 'react';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||||
|
import { useCallback,useMemo } from 'react';
|
||||||
|
import type {UseControllerProps } from 'react-hook-form';
|
||||||
|
import { useController } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useAppSelector } from '../../../../../app/store/storeHooks';
|
|
||||||
import { InformationalPopover } from '../../../../../common/components/InformationalPopover/InformationalPopover';
|
import type { DefaultSettingsFormData } from './DefaultSettingsForm';
|
||||||
import { UseControllerProps, useController } from 'react-hook-form';
|
|
||||||
import { DefaultSettingsFormData } from '../DefaultSettings';
|
|
||||||
import { useCallback } from 'react';
|
|
||||||
|
|
||||||
type DefaultCfgType = DefaultSettingsFormData['cfgScale'];
|
type DefaultCfgType = DefaultSettingsFormData['cfgScale'];
|
||||||
|
|
||||||
|
@ -4,9 +4,11 @@ import { InformationalPopover } from 'common/components/InformationalPopover/Inf
|
|||||||
import { SCHEDULER_OPTIONS } from 'features/parameters/types/constants';
|
import { SCHEDULER_OPTIONS } from 'features/parameters/types/constants';
|
||||||
import { isParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
import { isParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
import type {UseControllerProps } from 'react-hook-form';
|
||||||
|
import { useController } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { DefaultSettingsFormData } from '../DefaultSettings';
|
|
||||||
import { UseControllerProps, useController } from 'react-hook-form';
|
import type { DefaultSettingsFormData } from './DefaultSettingsForm';
|
||||||
|
|
||||||
type DefaultSchedulerType = DefaultSettingsFormData['scheduler'];
|
type DefaultSchedulerType = DefaultSettingsFormData['scheduler'];
|
||||||
|
|
||||||
|
@ -0,0 +1,147 @@
|
|||||||
|
import { Button, Flex, Heading } from '@invoke-ai/ui-library';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import type { ParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
||||||
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
|
import { makeToast } from 'features/system/util/makeToast';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import type { SubmitHandler } from 'react-hook-form';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { IoPencil } from 'react-icons/io5';
|
||||||
|
import { useUpdateModelMetadataMutation } from 'services/api/endpoints/models';
|
||||||
|
|
||||||
|
import { DefaultCfgRescaleMultiplier } from './DefaultCfgRescaleMultiplier';
|
||||||
|
import { DefaultCfgScale } from './DefaultCfgScale';
|
||||||
|
import { DefaultScheduler } from './DefaultScheduler';
|
||||||
|
import { DefaultSteps } from './DefaultSteps';
|
||||||
|
import { DefaultVae } from './DefaultVae';
|
||||||
|
import { DefaultVaePrecision } from './DefaultVaePrecision';
|
||||||
|
import { SettingToggle } from './SettingToggle';
|
||||||
|
|
||||||
|
export interface FormField<T> {
|
||||||
|
value: T;
|
||||||
|
isEnabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DefaultSettingsFormData = {
|
||||||
|
vae: FormField<string>;
|
||||||
|
vaePrecision: FormField<string>;
|
||||||
|
scheduler: FormField<ParameterScheduler>;
|
||||||
|
steps: FormField<number>;
|
||||||
|
cfgScale: FormField<number>;
|
||||||
|
cfgRescaleMultiplier: FormField<number>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DefaultSettingsForm = ({
|
||||||
|
defaultSettingsDefaults,
|
||||||
|
}: {
|
||||||
|
defaultSettingsDefaults: DefaultSettingsFormData;
|
||||||
|
}) => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const selectedModelKey = useAppSelector((s) => s.modelmanagerV2.selectedModelKey);
|
||||||
|
|
||||||
|
const [editModelMetadata, { isLoading }] = useUpdateModelMetadataMutation();
|
||||||
|
|
||||||
|
const { handleSubmit, control, formState } = useForm<DefaultSettingsFormData>({
|
||||||
|
defaultValues: defaultSettingsDefaults,
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = useCallback<SubmitHandler<DefaultSettingsFormData>>(
|
||||||
|
(data) => {
|
||||||
|
if (!selectedModelKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
vae: data.vae.isEnabled ? data.vae.value : null,
|
||||||
|
vae_precision: data.vaePrecision.isEnabled ? data.vaePrecision.value : null,
|
||||||
|
cfg_scale: data.cfgScale.isEnabled ? data.cfgScale.value : null,
|
||||||
|
cfg_rescale_multiplier: data.cfgRescaleMultiplier.isEnabled ? data.cfgRescaleMultiplier.value : null,
|
||||||
|
steps: data.steps.isEnabled ? data.steps.value : null,
|
||||||
|
scheduler: data.scheduler.isEnabled ? data.scheduler.value : null,
|
||||||
|
};
|
||||||
|
|
||||||
|
editModelMetadata({
|
||||||
|
key: selectedModelKey,
|
||||||
|
body: { default_settings: body },
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.then((_) => {
|
||||||
|
dispatch(
|
||||||
|
addToast(
|
||||||
|
makeToast({
|
||||||
|
title: t('modelManager.defaultSettingsSaved'),
|
||||||
|
status: 'success',
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error) {
|
||||||
|
dispatch(
|
||||||
|
addToast(
|
||||||
|
makeToast({
|
||||||
|
title: `${error.data.detail} `,
|
||||||
|
status: 'error',
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[selectedModelKey, dispatch, editModelMetadata]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Flex gap="2" justifyContent="space-between" w="full" mb={5}>
|
||||||
|
<Heading fontSize="md">{t('modelManager.defaultSettings')}</Heading>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
leftIcon={<IoPencil />}
|
||||||
|
colorScheme="invokeYellow"
|
||||||
|
isDisabled={!formState.isDirty}
|
||||||
|
onClick={handleSubmit(onSubmit)}
|
||||||
|
type="submit"
|
||||||
|
isLoading={isLoading}
|
||||||
|
>
|
||||||
|
{t('common.save')}
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex flexDir="column" gap={8}>
|
||||||
|
<Flex gap={8}>
|
||||||
|
<Flex gap={4} w="full">
|
||||||
|
<SettingToggle control={control} name="vae" />
|
||||||
|
<DefaultVae control={control} name="vae" />
|
||||||
|
</Flex>
|
||||||
|
<Flex gap={4} w="full">
|
||||||
|
<SettingToggle control={control} name="vaePrecision" />
|
||||||
|
<DefaultVaePrecision control={control} name="vaePrecision" />
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
<Flex gap={8}>
|
||||||
|
<Flex gap={4} w="full">
|
||||||
|
<SettingToggle control={control} name="scheduler" />
|
||||||
|
<DefaultScheduler control={control} name="scheduler" />
|
||||||
|
</Flex>
|
||||||
|
<Flex gap={4} w="full">
|
||||||
|
<SettingToggle control={control} name="steps" />
|
||||||
|
<DefaultSteps control={control} name="steps" />
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
<Flex gap={8}>
|
||||||
|
<Flex gap={4} w="full">
|
||||||
|
<SettingToggle control={control} name="cfgScale" />
|
||||||
|
<DefaultCfgScale control={control} name="cfgScale" />
|
||||||
|
</Flex>
|
||||||
|
<Flex gap={4} w="full">
|
||||||
|
<SettingToggle control={control} name="cfgRescaleMultiplier" />
|
||||||
|
<DefaultCfgRescaleMultiplier control={control} name="cfgRescaleMultiplier" />
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -1,11 +1,12 @@
|
|||||||
import { FormControl, FormLabel, CompositeSlider, CompositeNumberInput, Flex } from '@invoke-ai/ui-library';
|
import { CompositeNumberInput, CompositeSlider, Flex,FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
import { useMemo } from 'react';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||||
|
import { useCallback,useMemo } from 'react';
|
||||||
|
import type {UseControllerProps } from 'react-hook-form';
|
||||||
|
import { useController } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useAppSelector } from '../../../../../app/store/storeHooks';
|
|
||||||
import { InformationalPopover } from '../../../../../common/components/InformationalPopover/InformationalPopover';
|
import type { DefaultSettingsFormData } from './DefaultSettingsForm';
|
||||||
import { UseControllerProps, useController } from 'react-hook-form';
|
|
||||||
import { DefaultSettingsFormData } from '../DefaultSettings';
|
|
||||||
import { useCallback } from 'react';
|
|
||||||
|
|
||||||
type DefaultSteps = DefaultSettingsFormData['steps'];
|
type DefaultSteps = DefaultSettingsFormData['steps'];
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import type { ComboboxOnChange } from '@invoke-ai/ui-library';
|
import type { ComboboxOnChange } from '@invoke-ai/ui-library';
|
||||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
|
||||||
import { useCallback, useMemo } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { DefaultSettingsFormData } from '../DefaultSettings';
|
|
||||||
import { UseControllerProps, useController } from 'react-hook-form';
|
|
||||||
import { useGetModelConfigQuery, useGetVaeModelsQuery } from '../../../../../services/api/endpoints/models';
|
|
||||||
import { map } from 'lodash-es';
|
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { useAppSelector } from '../../../../../app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||||
|
import { map } from 'lodash-es';
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
|
import type {UseControllerProps } from 'react-hook-form';
|
||||||
|
import { useController } from 'react-hook-form';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useGetModelConfigQuery, useGetVaeModelsQuery } from 'services/api/endpoints/models';
|
||||||
|
|
||||||
|
import type { DefaultSettingsFormData } from './DefaultSettingsForm';
|
||||||
|
|
||||||
type DefaultVaeType = DefaultSettingsFormData['vae'];
|
type DefaultVaeType = DefaultSettingsFormData['vae'];
|
||||||
|
|
||||||
@ -25,13 +27,15 @@ export function DefaultVae(props: UseControllerProps<DefaultSettingsFormData>) {
|
|||||||
.filter((vae) => vae.base === modelData?.base)
|
.filter((vae) => vae.base === modelData?.base)
|
||||||
.map((vae) => ({ label: vae.name, value: vae.key }));
|
.map((vae) => ({ label: vae.name, value: vae.key }));
|
||||||
|
|
||||||
return { compatibleOptions };
|
const defaultOption = { label: 'Default VAE', value: 'default' };
|
||||||
|
|
||||||
|
return { compatibleOptions: [defaultOption, ...compatibleOptions] };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const onChange = useCallback<ComboboxOnChange>(
|
const onChange = useCallback<ComboboxOnChange>(
|
||||||
(v) => {
|
(v) => {
|
||||||
const newValue = !v?.value ? null : v.value;
|
const newValue = !v?.value ? 'default' : v.value;
|
||||||
|
|
||||||
const updatedValue = {
|
const updatedValue = {
|
||||||
...(field.value as DefaultVaeType),
|
...(field.value as DefaultVaeType),
|
||||||
@ -55,14 +59,7 @@ export function DefaultVae(props: UseControllerProps<DefaultSettingsFormData>) {
|
|||||||
<InformationalPopover feature="paramVAE">
|
<InformationalPopover feature="paramVAE">
|
||||||
<FormLabel>{t('modelManager.vae')}</FormLabel>
|
<FormLabel>{t('modelManager.vae')}</FormLabel>
|
||||||
</InformationalPopover>
|
</InformationalPopover>
|
||||||
<Combobox
|
<Combobox isDisabled={isDisabled} value={value} options={compatibleOptions} onChange={onChange} />
|
||||||
isDisabled={isDisabled}
|
|
||||||
isClearable
|
|
||||||
value={value}
|
|
||||||
placeholder={value ? value.value : t('models.defaultVAE')}
|
|
||||||
options={compatibleOptions}
|
|
||||||
onChange={onChange}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import type { ComboboxOnChange } from '@invoke-ai/ui-library';
|
import type { ComboboxOnChange } from '@invoke-ai/ui-library';
|
||||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||||
import { isParameterPrecision, isParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
import { isParameterPrecision } from 'features/parameters/types/parameterSchemas';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
import type {UseControllerProps } from 'react-hook-form';
|
||||||
|
import { useController } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { DefaultSettingsFormData } from '../DefaultSettings';
|
|
||||||
import { UseControllerProps, useController } from 'react-hook-form';
|
import type { DefaultSettingsFormData } from './DefaultSettingsForm';
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{ label: 'FP16', value: 'fp16' },
|
{ label: 'FP16', value: 'fp16' },
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { UseControllerProps, useController, useFormContext, useWatch } from 'react-hook-form';
|
|
||||||
import { DefaultSettingsFormData, FormField } from '../DefaultSettings';
|
|
||||||
import { useCallback } from 'react';
|
|
||||||
import { Switch } from '@invoke-ai/ui-library';
|
import { Switch } from '@invoke-ai/ui-library';
|
||||||
import { ChangeEvent } from 'react';
|
import type { ChangeEvent } from 'react';
|
||||||
|
import { useCallback , useMemo } from 'react';
|
||||||
|
import type { UseControllerProps} from 'react-hook-form';
|
||||||
|
import { useController } from 'react-hook-form';
|
||||||
|
|
||||||
|
import type { DefaultSettingsFormData, FormField } from './DefaultSettingsForm';
|
||||||
|
|
||||||
interface Props<T> extends UseControllerProps<DefaultSettingsFormData> {
|
interface Props<T> extends UseControllerProps<DefaultSettingsFormData> {
|
||||||
name: keyof DefaultSettingsFormData;
|
name: keyof DefaultSettingsFormData;
|
||||||
@ -11,6 +13,10 @@ interface Props<T> extends UseControllerProps<DefaultSettingsFormData> {
|
|||||||
export function SettingToggle<T>(props: Props<T>) {
|
export function SettingToggle<T>(props: Props<T>) {
|
||||||
const { field } = useController(props);
|
const { field } = useController(props);
|
||||||
|
|
||||||
|
const value = useMemo(() => {
|
||||||
|
return !!(field.value as FormField<T>).isEnabled;
|
||||||
|
}, [field.value]);
|
||||||
|
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(e: ChangeEvent<HTMLInputElement>) => {
|
(e: ChangeEvent<HTMLInputElement>) => {
|
||||||
const updatedValue: FormField<T> = {
|
const updatedValue: FormField<T> = {
|
||||||
@ -22,5 +28,5 @@ export function SettingToggle<T>(props: Props<T>) {
|
|||||||
[field]
|
[field]
|
||||||
);
|
);
|
||||||
|
|
||||||
return <Switch onChange={onChange} />;
|
return <Switch isChecked={value} onChange={onChange} />;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Box, Button, Flex, Heading, Text } from '@invoke-ai/ui-library';
|
import { Box, Button, Flex, Text } from '@invoke-ai/ui-library';
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { setSelectedModelMode } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
import { setSelectedModelMode } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
||||||
@ -17,9 +17,9 @@ import type {
|
|||||||
VAEModelConfig,
|
VAEModelConfig,
|
||||||
} from 'services/api/types';
|
} from 'services/api/types';
|
||||||
|
|
||||||
|
import { DefaultSettings } from './DefaultSettings';
|
||||||
import { ModelAttrView } from './ModelAttrView';
|
import { ModelAttrView } from './ModelAttrView';
|
||||||
import { ModelConvert } from './ModelConvert';
|
import { ModelConvert } from './ModelConvert';
|
||||||
import { DefaultSettings } from './DefaultSettings';
|
|
||||||
|
|
||||||
export const ModelView = () => {
|
export const ModelView = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -38,6 +38,7 @@ type GetModelConfigResponse = paths['/api/v2/models/i/{key}']['get']['responses'
|
|||||||
type GetModelMetadataResponse =
|
type GetModelMetadataResponse =
|
||||||
paths['/api/v2/models/i/{key}/metadata']['get']['responses']['200']['content']['application/json'];
|
paths['/api/v2/models/i/{key}/metadata']['get']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
|
|
||||||
type ListModelsArg = NonNullable<paths['/api/v2/models/']['get']['parameters']['query']>;
|
type ListModelsArg = NonNullable<paths['/api/v2/models/']['get']['parameters']['query']>;
|
||||||
|
|
||||||
type DeleteMainModelArg = {
|
type DeleteMainModelArg = {
|
||||||
|
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user