diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 64eeaf79fa..17154cce87 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -942,6 +942,7 @@ "modelConverted": "Model Converted", "modelDeleted": "Model Deleted", "modelDeleteFailed": "Failed to delete model", + "modelFormat": "Model Format", "modelImageDeleted": "Model Image Deleted", "modelImageDeleteFailed": "Model Image Delete Failed", "modelImageUpdated": "Model Image Updated", diff --git a/invokeai/frontend/web/src/features/modelManagerV2/models.ts b/invokeai/frontend/web/src/features/modelManagerV2/models.ts index 798ed1ac0e..ec4ddf1a1d 100644 --- a/invokeai/frontend/web/src/features/modelManagerV2/models.ts +++ b/invokeai/frontend/web/src/features/modelManagerV2/models.ts @@ -1,4 +1,4 @@ -import type { BaseModelType, ModelType, ModelVariantType } from 'features/nodes/types/common'; +import type { BaseModelType, ModelFormat, ModelType, ModelVariantType } from 'features/nodes/types/common'; import type { AnyModelConfig } from 'services/api/types'; import { isCLIPEmbedModelConfig, @@ -225,6 +225,24 @@ export const MODEL_VARIANT_TO_LONG_NAME: Record = { depth: 'Depth', }; +export const MODEL_FORMAT_TO_LONG_NAME: Record = { + omi: 'OMI', + diffusers: 'Diffusers', + checkpoint: 'Checkpoint', + lycoris: 'LyCORIS', + onnx: 'ONNX', + olive: 'Olive', + embedding_file: 'Embedding (file)', + embedding_folder: 'Embedding (folder)', + invokeai: 'InvokeAI', + t5_encoder: 'T5 Encoder', + bnb_quantized_int8b: 'BNB Quantized (int8b)', + bnb_quantized_nf4b: 'BNB Quantized (nf4b)', + gguf_quantized: 'GGUF Quantized', + api: 'API', + unknown: 'Unknown', +}; + /** * List of base models that make API requests */ diff --git a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/Fields/ModelFormatSelect.tsx b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/Fields/ModelFormatSelect.tsx new file mode 100644 index 0000000000..1057ab7784 --- /dev/null +++ b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/Fields/ModelFormatSelect.tsx @@ -0,0 +1,32 @@ +import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library'; +import { Combobox } from '@invoke-ai/ui-library'; +import { typedMemo } from 'common/util/typedMemo'; +import { MODEL_FORMAT_TO_LONG_NAME } from 'features/modelManagerV2/models'; +import { useCallback, useMemo } from 'react'; +import type { Control } from 'react-hook-form'; +import { useController } from 'react-hook-form'; +import type { UpdateModelArg } from 'services/api/endpoints/models'; +import { objectEntries } from 'tsafe'; + +const options: ComboboxOption[] = objectEntries(MODEL_FORMAT_TO_LONG_NAME).map(([value, label]) => ({ + label, + value, +})); + +type Props = { + control: Control; +}; + +const ModelFormatSelect = ({ control }: Props) => { + const { field } = useController({ control, name: 'format' }); + const value = useMemo(() => options.find((o) => o.value === field.value), [field.value]); + const onChange = useCallback( + (v) => { + field.onChange(v?.value); + }, + [field] + ); + return ; +}; + +export default typedMemo(ModelFormatSelect); diff --git a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/ModelEdit.tsx b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/ModelEdit.tsx index 12f591f9a3..5a5c04c278 100644 --- a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/ModelEdit.tsx +++ b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/ModelEdit.tsx @@ -22,6 +22,7 @@ import { type UpdateModelArg, useUpdateModelMutation } from 'services/api/endpoi import type { AnyModelConfig } from 'services/api/types'; import BaseModelSelect from './Fields/BaseModelSelect'; +import ModelFormatSelect from './Fields/ModelFormatSelect'; import ModelTypeSelect from './Fields/ModelTypeSelect'; import ModelVariantSelect from './Fields/ModelVariantSelect'; import PredictionTypeSelect from './Fields/PredictionTypeSelect'; @@ -132,6 +133,10 @@ export const ModelEdit = memo(({ modelConfig }: Props) => { {t('modelManager.modelType')} + + {t('modelManager.modelFormat')} + + {modelConfig.type !== 'clip_vision' && ( {t('modelManager.baseModel')} diff --git a/invokeai/frontend/web/src/features/nodes/types/common.ts b/invokeai/frontend/web/src/features/nodes/types/common.ts index 8bab74f2d2..2be17026d0 100644 --- a/invokeai/frontend/web/src/features/nodes/types/common.ts +++ b/invokeai/frontend/web/src/features/nodes/types/common.ts @@ -167,6 +167,7 @@ export const zModelFormat = z.enum([ 'api', 'unknown', ]); +export type ModelFormat = z.infer; export const zModelIdentifierField = z.object({ key: z.string().min(1),