diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx
index e667c17d3e..4e1f3d8240 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx
@@ -2,6 +2,7 @@ import { ButtonGroup, Flex } from '@chakra-ui/react';
import IAIButton from 'common/components/IAIButton';
import { useState } from 'react';
import AutoAddModels from './AutoAddModels';
+import ManualAddModels from './ManualAddModels';
export default function AddModels() {
const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>(
@@ -40,7 +41,7 @@ export default function AddModels() {
}}
>
{addModelMode === 'simple' && }
- {addModelMode === 'advanced' && null}
+ {addModelMode === 'advanced' && }
);
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddCheckpoint.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddCheckpoint.tsx
new file mode 100644
index 0000000000..efee656d81
--- /dev/null
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddCheckpoint.tsx
@@ -0,0 +1,20 @@
+import { useForm } from '@mantine/form';
+import { CheckpointModelConfig } from 'services/api/types';
+
+export default function ManualAddCheckpoint() {
+ const manualAddCheckpointForm = useForm({
+ initialValues: {
+ model_name: '',
+ base_model: 'sd-1',
+ model_type: 'main',
+ path: '',
+ description: '',
+ model_format: 'checkpoint',
+ error: undefined,
+ vae: '',
+ variant: 'normal',
+ config: '',
+ },
+ });
+ return ManualAddCheckpoint
;
+}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddDiffusers.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddDiffusers.tsx
new file mode 100644
index 0000000000..1e51006dcd
--- /dev/null
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddDiffusers.tsx
@@ -0,0 +1,102 @@
+import { Flex } from '@chakra-ui/react';
+import { useForm } from '@mantine/form';
+import { makeToast } from 'app/components/Toaster';
+import { useAppDispatch } from 'app/store/storeHooks';
+import IAIButton from 'common/components/IAIButton';
+import IAIMantineTextInput from 'common/components/IAIMantineInput';
+import { addToast } from 'features/system/store/systemSlice';
+import { useTranslation } from 'react-i18next';
+import { useAddMainModelsMutation } from 'services/api/endpoints/models';
+import { DiffusersModelConfig } from 'services/api/types';
+import BaseModelSelect from '../shared/BaseModelSelect';
+import ModelVariantSelect from '../shared/ModelVariantSelect';
+
+export default function ManualAddDiffusers() {
+ const { t } = useTranslation();
+ const dispatch = useAppDispatch();
+
+ const [addMainModel] = useAddMainModelsMutation();
+
+ const manualAddDiffusersForm = useForm({
+ initialValues: {
+ model_name: '',
+ base_model: 'sd-1',
+ model_type: 'main',
+ path: '',
+ description: '',
+ model_format: 'diffusers',
+ error: undefined,
+ vae: '',
+ variant: 'normal',
+ },
+ });
+ const manualAddDiffusersFormHandler = (values: DiffusersModelConfig) => {
+ console.log(values);
+ addMainModel({
+ body: values,
+ })
+ .unwrap()
+ .then((_) => {
+ dispatch(
+ addToast(
+ makeToast({
+ title: `Model Added: ${values.model_name}`,
+ status: 'success',
+ })
+ )
+ );
+ manualAddDiffusersForm.reset();
+ })
+ .catch((error) => {
+ if (error) {
+ dispatch(
+ addToast(
+ makeToast({
+ title: 'Model Add Failed',
+ status: 'error',
+ })
+ )
+ );
+ }
+ });
+ };
+
+ return (
+
+ );
+}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddModels.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddModels.tsx
new file mode 100644
index 0000000000..2783e4e6b3
--- /dev/null
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ManualAddModels.tsx
@@ -0,0 +1,46 @@
+import { Flex } from '@chakra-ui/react';
+import { SelectItem } from '@mantine/core';
+import IAIMantineSelect from 'common/components/IAIMantineSelect';
+import { useState } from 'react';
+import ManualAddCheckpoint from './ManualAddCheckpoint';
+import ManualAddDiffusers from './ManualAddDiffusers';
+
+const manualAddModeData: SelectItem[] = [
+ { label: 'Diffusers', value: 'diffusers' },
+ { label: 'Checkpoint / Safetensors', value: 'checkpoint' },
+];
+
+type ManualAddMode = 'diffusers' | 'checkpoint';
+
+export default function ManualAddModels() {
+ const [manualAddMode, setManualAddMode] =
+ useState('diffusers');
+
+ return (
+
+ {
+ if (!v) return;
+ setManualAddMode(v as ManualAddMode);
+ }}
+ />
+
+
+ {manualAddMode === 'diffusers' && }
+ {manualAddMode === 'checkpoint' && }
+
+
+ );
+}
diff --git a/invokeai/frontend/web/src/services/api/endpoints/models.ts b/invokeai/frontend/web/src/services/api/endpoints/models.ts
index 2a5e5547b3..e0177ca8d1 100644
--- a/invokeai/frontend/web/src/services/api/endpoints/models.ts
+++ b/invokeai/frontend/web/src/services/api/endpoints/models.ts
@@ -86,6 +86,13 @@ type ImportMainModelArg = {
type ImportMainModelResponse =
paths['/api/v1/models/import']['post']['responses']['201']['content']['application/json'];
+type AddMainModelArg = {
+ body: MainModelConfig;
+};
+
+type AddMainModelResponse =
+ paths['/api/v1/models/add']['post']['responses']['201']['content']['application/json'];
+
type SearchFolderResponse =
paths['/api/v1/models/search']['get']['responses']['200']['content']['application/json'];
@@ -189,6 +196,16 @@ export const modelsApi = api.injectEndpoints({
},
invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }],
}),
+ addMainModels: build.mutation({
+ query: ({ body }) => {
+ return {
+ url: `models/add`,
+ method: 'POST',
+ body: body,
+ };
+ },
+ invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }],
+ }),
deleteMainModels: build.mutation<
DeleteMainModelResponse,
DeleteMainModelArg
@@ -378,6 +395,7 @@ export const {
useUpdateMainModelsMutation,
useDeleteMainModelsMutation,
useImportMainModelsMutation,
+ useAddMainModelsMutation,
useConvertMainModelsMutation,
useMergeMainModelsMutation,
useGetModelsInFolderQuery,