LibreChat/client/src/components/Models/ModelMenu.jsx

139 lines
4.3 KiB
React
Raw Normal View History

import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { setModel, setDisabled, setCustomGpt, setCustomModel } from '~/store/submitSlice';
import { setConversation } from '~/store/convoSlice';
import ModelDialog from './ModelDialog';
import MenuItems from './MenuItems';
import manualSWR from '~/utils/fetchers';
import { setModels } from '~/store/modelSlice';
import GPTIcon from '../svg/GPTIcon';
import BingIcon from '../svg/BingIcon';
import { Button } from '../ui/Button.tsx';
2023-03-03 15:52:06 -05:00
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuRadioGroup,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '../ui/DropdownMenu.tsx';
import { Dialog } from '../ui/Dialog.tsx';
2023-03-03 15:52:06 -05:00
export default function ModelMenu() {
const dispatch = useDispatch();
const { model, customModel } = useSelector((state) => state.submit);
2023-03-04 20:48:59 -05:00
const { models, modelMap, initial } = useSelector((state) => state.models);
2023-03-06 14:04:06 -05:00
const { trigger } = manualSWR(`http://api:3080/customGpts`, 'get', (res) => {
if (models.length + res.length === models.length) {
return;
}
const fetchedModels = res.map((modelItem) => ({
...modelItem,
name: modelItem.chatGptLabel
}));
dispatch(setModels(fetchedModels));
});
useEffect(() => {
2023-03-05 15:30:40 -05:00
trigger();
const lastSelected = JSON.parse(localStorage.getItem('model'));
2023-03-04 20:48:59 -05:00
if (lastSelected && lastSelected !== 'chatgptCustom' && initial[lastSelected]) {
dispatch(setModel(lastSelected));
}
2023-03-03 15:52:06 -05:00
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
localStorage.setItem('model', JSON.stringify(model));
}, [model]);
2023-03-03 15:52:06 -05:00
const onChange = (value) => {
if (!value) {
return;
} else if (value === 'chatgptCustom') {
// dispatch(setMessages([]));
2023-03-04 20:48:59 -05:00
} else if (initial[value]) {
2023-03-03 15:52:06 -05:00
dispatch(setModel(value));
dispatch(setDisabled(false));
setCustomModel(null);
2023-03-04 20:48:59 -05:00
} else if (!initial[value]) {
const chatGptLabel = modelMap[value]?.chatGptLabel;
const promptPrefix = modelMap[value]?.promptPrefix;
dispatch(setCustomGpt({ chatGptLabel, promptPrefix }));
dispatch(setModel('chatgptCustom'));
setCustomModel(value);
} else if (!modelMap[value]) {
setCustomModel(null);
}
// Set new conversation
dispatch(
setConversation({
title: 'New Chat',
error: false,
conversationId: null,
parentMessageId: null
})
);
2023-03-03 15:52:06 -05:00
};
const defaultColorProps = [
'text-gray-500',
'hover:bg-gray-100',
'disabled:hover:bg-transparent',
'dark:hover:bg-opacity-20',
'dark:hover:bg-gray-900',
'dark:hover:text-gray-400',
'dark:disabled:hover:bg-transparent'
];
const chatgptColorProps = [
'text-green-700',
'dark:text-emerald-300',
'hover:bg-green-100',
'disabled:hover:bg-transparent',
'dark:hover:bg-opacity-50',
'dark:hover:bg-green-900',
'dark:hover:text-gray-100',
'dark:disabled:hover:bg-transparent'
];
const colorProps = model === 'chatgpt' ? chatgptColorProps : defaultColorProps;
2023-03-03 15:52:06 -05:00
const icon = model === 'bingai' ? <BingIcon button={true} /> : <GPTIcon button={true} />;
return (
2023-03-03 15:52:06 -05:00
<Dialog>
2023-03-05 13:31:12 -05:00
<DropdownMenu >
2023-03-03 15:52:06 -05:00
<DropdownMenuTrigger asChild>
<Button
variant="outline"
// style={{backgroundColor: 'rgb(16, 163, 127)'}}
className={`absolute bottom-0.5 rounded-md border-0 p-1 pl-2 outline-none ${colorProps.join(
' '
)} focus:ring-0 focus:ring-offset-0 disabled:bottom-0.5 dark:data-[state=open]:bg-gray-800 dark:data-[state=open]:bg-opacity-50 md:bottom-1 md:left-2 md:pl-1 md:disabled:bottom-1`}
2023-03-03 15:52:06 -05:00
>
{icon}
</Button>
</DropdownMenuTrigger>
2023-03-03 16:33:02 -05:00
<DropdownMenuContent className="w-56 dark:bg-gray-700">
2023-03-05 13:31:12 -05:00
<DropdownMenuLabel className="dark:text-gray-300">Select a Model</DropdownMenuLabel>
2023-03-03 15:52:06 -05:00
<DropdownMenuSeparator />
<DropdownMenuRadioGroup
2023-03-04 20:48:59 -05:00
value={customModel ? customModel : model}
2023-03-03 15:52:06 -05:00
onValueChange={onChange}
className="overflow-y-auto"
2023-03-03 15:52:06 -05:00
>
<MenuItems models={models} />
2023-03-03 15:52:06 -05:00
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
<ModelDialog mutate={trigger} modelMap={modelMap}/>
2023-03-03 15:52:06 -05:00
</Dialog>
);
}