mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +01:00
feat: feat: new endpoint-style endpoint select
fix: a wrong use of bingai params
This commit is contained in:
parent
adcc021c9e
commit
e8e3903b78
18 changed files with 7891 additions and 233 deletions
|
|
@ -32,13 +32,15 @@ const askBing = async ({
|
||||||
jailbreakConversationId: jailbreakConversationId || jailbreak,
|
jailbreakConversationId: jailbreakConversationId || jailbreak,
|
||||||
parentMessageId,
|
parentMessageId,
|
||||||
conversationId,
|
conversationId,
|
||||||
conversationSignature,
|
|
||||||
clientId,
|
|
||||||
invocationId,
|
|
||||||
toneStyle,
|
toneStyle,
|
||||||
onProgress
|
onProgress
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (conversationSignature) options.conversationSignature = conversationSignature;
|
||||||
|
if (conversationSignature) options.clientId = clientId;
|
||||||
|
if (conversationSignature) options.invocationId = invocationId;
|
||||||
|
if (conversationSignature) options.toneStyle = toneStyle;
|
||||||
|
|
||||||
if (options?.jailbreakConversationId == 'false') {
|
if (options?.jailbreakConversationId == 'false') {
|
||||||
options.jailbreakConversationId = false;
|
options.jailbreakConversationId = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,9 @@ const migrateToSupportBetterCustomization = async () => {
|
||||||
convo.endpoint = 'chatGPTBrowser';
|
convo.endpoint = 'chatGPTBrowser';
|
||||||
convo.model = 'text-davinci-002-render-sha';
|
convo.model = 'text-davinci-002-render-sha';
|
||||||
convo.jailbreak = true;
|
convo.jailbreak = true;
|
||||||
|
} else {
|
||||||
|
convo.endpoint = 'openAI';
|
||||||
|
convo.model = 'gpt-3.5-turbo';
|
||||||
}
|
}
|
||||||
|
|
||||||
promises.push(convo.save());
|
promises.push(convo.save());
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,8 @@ const convoSchema = mongoose.Schema(
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
invocationId: {
|
invocationId: {
|
||||||
type: String,
|
type: Number,
|
||||||
default: null
|
default: 1
|
||||||
},
|
},
|
||||||
toneStyle: {
|
toneStyle: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,12 @@ router.post('/', async (req, res) => {
|
||||||
|
|
||||||
if (!overrideParentMessageId) {
|
if (!overrideParentMessageId) {
|
||||||
await saveBingMessage(userMessage);
|
await saveBingMessage(userMessage);
|
||||||
await saveConvo(req?.session?.user?.username, { ...userMessage, ...endpointOption, conversationId });
|
await saveConvo(req?.session?.user?.username, {
|
||||||
|
...userMessage,
|
||||||
|
...endpointOption,
|
||||||
|
conversationId,
|
||||||
|
endpoint
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return await ask({
|
return await ask({
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,12 @@ router.post('/', async (req, res) => {
|
||||||
|
|
||||||
if (!overrideParentMessageId) {
|
if (!overrideParentMessageId) {
|
||||||
await saveMessage(userMessage);
|
await saveMessage(userMessage);
|
||||||
await saveConvo(req?.session?.user?.username, { ...userMessage, ...endpointOption, conversationId });
|
await saveConvo(req?.session?.user?.username, {
|
||||||
|
...userMessage,
|
||||||
|
...endpointOption,
|
||||||
|
conversationId,
|
||||||
|
endpoint
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return await ask({
|
return await ask({
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,12 @@ router.post('/', async (req, res) => {
|
||||||
|
|
||||||
if (!overrideParentMessageId) {
|
if (!overrideParentMessageId) {
|
||||||
await saveMessage(userMessage);
|
await saveMessage(userMessage);
|
||||||
await saveConvo(req?.session?.user?.username, { ...userMessage, ...endpointOption, conversationId });
|
await saveConvo(req?.session?.user?.username, {
|
||||||
|
...userMessage,
|
||||||
|
...endpointOption,
|
||||||
|
conversationId,
|
||||||
|
endpoint
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return await ask({
|
return await ask({
|
||||||
|
|
|
||||||
24
client/src/components/Input/Endpoints/EndpointItem.jsx
Normal file
24
client/src/components/Input/Endpoints/EndpointItem.jsx
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { DropdownMenuRadioItem } from '../../ui/DropdownMenu.tsx';
|
||||||
|
import getIcon from '~/utils/getIcon';
|
||||||
|
|
||||||
|
export default function ModelItem({ endpoint, value, onSelect }) {
|
||||||
|
const icon = getIcon({
|
||||||
|
size: 20,
|
||||||
|
endpoint,
|
||||||
|
error: false,
|
||||||
|
className: 'mr-2'
|
||||||
|
});
|
||||||
|
|
||||||
|
// regular model
|
||||||
|
return (
|
||||||
|
<DropdownMenuRadioItem
|
||||||
|
value={value}
|
||||||
|
className="dark:font-semibold dark:text-gray-100 dark:hover:bg-gray-800"
|
||||||
|
>
|
||||||
|
{icon}
|
||||||
|
{endpoint}
|
||||||
|
{endpoint in ['azureOpenAI', 'openAI'] && <sup>$</sup>}
|
||||||
|
</DropdownMenuRadioItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
17
client/src/components/Input/Endpoints/EndpointItems.jsx
Normal file
17
client/src/components/Input/Endpoints/EndpointItems.jsx
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import React from 'react';
|
||||||
|
import EndpointItem from './EndpointItem';
|
||||||
|
|
||||||
|
export default function EndpointItems({ endpoints, onSelect }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{endpoints.map(endpoint => (
|
||||||
|
<EndpointItem
|
||||||
|
key={endpoint}
|
||||||
|
value={endpoint}
|
||||||
|
onSelect={onSelect}
|
||||||
|
endpoint={endpoint}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
188
client/src/components/Input/Endpoints/EndpointMenu.jsx
Normal file
188
client/src/components/Input/Endpoints/EndpointMenu.jsx
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
// import ModelDialog from './ModelDialog';
|
||||||
|
import EndpointItems from './EndpointItems';
|
||||||
|
import { swr } from '~/utils/fetchers';
|
||||||
|
import getIcon from '~/utils/getIcon';
|
||||||
|
|
||||||
|
import { Button } from '../../ui/Button.tsx';
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuRadioGroup,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuTrigger
|
||||||
|
} from '../../ui/DropdownMenu.tsx';
|
||||||
|
import { Dialog } from '../../ui/Dialog.tsx';
|
||||||
|
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
export default function EndpointMenu() {
|
||||||
|
// const [modelSave, setModelSave] = useState(false);
|
||||||
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
|
|
||||||
|
// const models = useRecoilValue(store.models);
|
||||||
|
const availableEndpoints = useRecoilValue(store.availableEndpoints);
|
||||||
|
// const setCustomGPTModels = useSetRecoilState(store.customGPTModels);
|
||||||
|
|
||||||
|
const conversation = useRecoilValue(store.conversation) || {};
|
||||||
|
const { endpoint, conversationId } = conversation;
|
||||||
|
// const { model, promptPrefix, chatGptLabel, conversationId } = conversation;
|
||||||
|
const { newConversation } = store.useConversation();
|
||||||
|
|
||||||
|
// fetch the list of saved chatgptCustom
|
||||||
|
// const { data, isLoading, mutate } = swr(`/api/customGpts`, res => {
|
||||||
|
// const fetchedModels = res.map(modelItem => ({
|
||||||
|
// ...modelItem,
|
||||||
|
// name: modelItem.chatGptLabel,
|
||||||
|
// model: 'chatgptCustom'
|
||||||
|
// }));
|
||||||
|
|
||||||
|
// setCustomGPTModels(fetchedModels);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// update the default model when availableModels changes
|
||||||
|
// typically, availableModels changes => modelsFilter or customGPTModels changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (conversationId == 'new') {
|
||||||
|
newConversation();
|
||||||
|
}
|
||||||
|
}, [availableEndpoints]);
|
||||||
|
|
||||||
|
// save selected model to localstoreage
|
||||||
|
useEffect(() => {
|
||||||
|
if (endpoint) localStorage.setItem('lastConversationSetup', JSON.stringify(conversation));
|
||||||
|
}, [conversation]);
|
||||||
|
|
||||||
|
// set the current model
|
||||||
|
const onChange = (newEndpoint, value = null) => {
|
||||||
|
setMenuOpen(false);
|
||||||
|
|
||||||
|
if (!newEndpoint) return;
|
||||||
|
else if (newEndpoint === endpoint) return;
|
||||||
|
else {
|
||||||
|
newConversation({}, newEndpoint);
|
||||||
|
}
|
||||||
|
// } else if (newModel === model && value === chatGptLabel) {
|
||||||
|
// // bypass if not changed
|
||||||
|
// return;
|
||||||
|
// } else if (newModel === 'chatgptCustom' && value === null) {
|
||||||
|
// // return;
|
||||||
|
// } else if (newModel !== 'chatgptCustom') {
|
||||||
|
// newConversation({
|
||||||
|
// model: newModel,
|
||||||
|
// chatGptLabel: null,
|
||||||
|
// promptPrefix: null
|
||||||
|
// });
|
||||||
|
// } else if (newModel === 'chatgptCustom') {
|
||||||
|
// const targetModel = models.find(element => element.value == value);
|
||||||
|
// if (targetModel) {
|
||||||
|
// const chatGptLabel = targetModel?.chatGptLabel;
|
||||||
|
// const promptPrefix = targetModel?.promptPrefix;
|
||||||
|
// newConversation({
|
||||||
|
// model: newModel,
|
||||||
|
// chatGptLabel,
|
||||||
|
// promptPrefix
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
// const onOpenChange = open => {
|
||||||
|
// mutate();
|
||||||
|
// if (!open) {
|
||||||
|
// setModelSave(false);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handleSaveState = value => {
|
||||||
|
// if (!modelSave) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// setCustomGPTModels(value);
|
||||||
|
// setModelSave(false);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const defaultColorProps = [
|
||||||
|
// 'text-gray-500',
|
||||||
|
// 'hover:bg-gray-100',
|
||||||
|
// 'hover:bg-opacity-20',
|
||||||
|
// 'disabled:hover:bg-transparent',
|
||||||
|
// 'dark:data-[state=open]:bg-gray-800',
|
||||||
|
// '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',
|
||||||
|
// 'data-[state=open]:bg-green-100',
|
||||||
|
// 'dark:text-emerald-300',
|
||||||
|
// 'hover:bg-green-100',
|
||||||
|
// 'disabled:hover:bg-transparent',
|
||||||
|
// 'dark:data-[state=open]:bg-green-900',
|
||||||
|
// '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;
|
||||||
|
const icon = getIcon({
|
||||||
|
size: 32,
|
||||||
|
...conversation,
|
||||||
|
isCreatedByUser: false,
|
||||||
|
error: false,
|
||||||
|
button: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
// onOpenChange={onOpenChange}
|
||||||
|
>
|
||||||
|
<DropdownMenu
|
||||||
|
open={menuOpen}
|
||||||
|
onOpenChange={setMenuOpen}
|
||||||
|
>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
// style={{backgroundColor: 'rgb(16, 163, 127)'}}
|
||||||
|
className={`absolute top-[0.25px] mb-0 ml-1 items-center rounded-md border-0 p-1 outline-none focus:ring-0 focus:ring-offset-0 disabled:top-[0.25px] dark:data-[state=open]:bg-opacity-50 md:top-1 md:left-1 md:ml-0 md:pl-1 md:disabled:top-1`}
|
||||||
|
>
|
||||||
|
{icon}
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent
|
||||||
|
className="w-56 dark:bg-gray-700"
|
||||||
|
onCloseAutoFocus={event => event.preventDefault()}
|
||||||
|
>
|
||||||
|
<DropdownMenuLabel className="dark:text-gray-300">Select an AI Endpoint</DropdownMenuLabel>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuRadioGroup
|
||||||
|
value={endpoint}
|
||||||
|
onValueChange={onChange}
|
||||||
|
className="overflow-y-auto"
|
||||||
|
>
|
||||||
|
{availableEndpoints.length ? (
|
||||||
|
<EndpointItems
|
||||||
|
endpoints={availableEndpoints}
|
||||||
|
onSelect={onChange}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<DropdownMenuLabel className="dark:text-gray-300">No endpoint available.</DropdownMenuLabel>
|
||||||
|
)}
|
||||||
|
</DropdownMenuRadioGroup>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
{/* <ModelDialog
|
||||||
|
mutate={mutate}
|
||||||
|
setModelSave={setModelSave}
|
||||||
|
handleSaveState={handleSaveState}
|
||||||
|
/> */}
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,205 +0,0 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
|
||||||
import axios from 'axios';
|
|
||||||
import ModelDialog from './ModelDialog';
|
|
||||||
import MenuItems from './MenuItems';
|
|
||||||
import { swr } from '~/utils/fetchers';
|
|
||||||
import getIcon from '~/utils/getIcon';
|
|
||||||
|
|
||||||
import { Button } from '../../ui/Button.tsx';
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuRadioGroup,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuTrigger
|
|
||||||
} from '../../ui/DropdownMenu.tsx';
|
|
||||||
import { Dialog } from '../../ui/Dialog.tsx';
|
|
||||||
|
|
||||||
import store from '~/store';
|
|
||||||
|
|
||||||
export default function ModelMenu() {
|
|
||||||
const [modelSave, setModelSave] = useState(false);
|
|
||||||
const [menuOpen, setMenuOpen] = useState(false);
|
|
||||||
|
|
||||||
const models = useRecoilValue(store.models);
|
|
||||||
const availableModels = useRecoilValue(store.availableModels);
|
|
||||||
const setCustomGPTModels = useSetRecoilState(store.customGPTModels);
|
|
||||||
|
|
||||||
const conversation = useRecoilValue(store.conversation) || {};
|
|
||||||
const { model, promptPrefix, chatGptLabel, conversationId } = conversation;
|
|
||||||
const { newConversation } = store.useConversation();
|
|
||||||
|
|
||||||
// fetch the list of saved chatgptCustom
|
|
||||||
const { data, isLoading, mutate } = swr(`/api/customGpts`, res => {
|
|
||||||
const fetchedModels = res.map(modelItem => ({
|
|
||||||
...modelItem,
|
|
||||||
name: modelItem.chatGptLabel,
|
|
||||||
model: 'chatgptCustom'
|
|
||||||
}));
|
|
||||||
|
|
||||||
setCustomGPTModels(fetchedModels);
|
|
||||||
});
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// mutate();
|
|
||||||
// try {
|
|
||||||
// const lastSelected = JSON.parse(localStorage.getItem('model'));
|
|
||||||
|
|
||||||
// if (lastSelected === 'chatgptCustom') {
|
|
||||||
// return;
|
|
||||||
// } else if (initial[lastSelected]) {
|
|
||||||
// dispatch(setModel(lastSelected));
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// console.log(err);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
// update the default model when availableModels changes
|
|
||||||
// typically, availableModels changes => modelsFilter or customGPTModels changes
|
|
||||||
useEffect(() => {
|
|
||||||
if (conversationId == 'new') {
|
|
||||||
newConversation();
|
|
||||||
}
|
|
||||||
}, [availableModels]);
|
|
||||||
|
|
||||||
// save selected model to localstoreage
|
|
||||||
useEffect(() => {
|
|
||||||
if (model) localStorage.setItem('model', JSON.stringify({ model, chatGptLabel, promptPrefix }));
|
|
||||||
}, [model]);
|
|
||||||
|
|
||||||
// set the current model
|
|
||||||
const onChange = (newModel, value = null) => {
|
|
||||||
setMenuOpen(false);
|
|
||||||
|
|
||||||
if (!newModel) {
|
|
||||||
return;
|
|
||||||
} else if (newModel === model && value === chatGptLabel) {
|
|
||||||
// bypass if not changed
|
|
||||||
return;
|
|
||||||
} else if (newModel === 'chatgptCustom' && value === null) {
|
|
||||||
// return;
|
|
||||||
} else if (newModel !== 'chatgptCustom') {
|
|
||||||
newConversation({
|
|
||||||
model: newModel,
|
|
||||||
chatGptLabel: null,
|
|
||||||
promptPrefix: null
|
|
||||||
});
|
|
||||||
} else if (newModel === 'chatgptCustom') {
|
|
||||||
const targetModel = models.find(element => element.value == value);
|
|
||||||
if (targetModel) {
|
|
||||||
const chatGptLabel = targetModel?.chatGptLabel;
|
|
||||||
const promptPrefix = targetModel?.promptPrefix;
|
|
||||||
newConversation({
|
|
||||||
model: newModel,
|
|
||||||
chatGptLabel,
|
|
||||||
promptPrefix
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onOpenChange = open => {
|
|
||||||
mutate();
|
|
||||||
if (!open) {
|
|
||||||
setModelSave(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSaveState = value => {
|
|
||||||
if (!modelSave) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setCustomGPTModels(value);
|
|
||||||
setModelSave(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultColorProps = [
|
|
||||||
'text-gray-500',
|
|
||||||
'hover:bg-gray-100',
|
|
||||||
'hover:bg-opacity-20',
|
|
||||||
'disabled:hover:bg-transparent',
|
|
||||||
'dark:data-[state=open]:bg-gray-800',
|
|
||||||
'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',
|
|
||||||
'data-[state=open]:bg-green-100',
|
|
||||||
'dark:text-emerald-300',
|
|
||||||
'hover:bg-green-100',
|
|
||||||
'disabled:hover:bg-transparent',
|
|
||||||
'dark:data-[state=open]:bg-green-900',
|
|
||||||
'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;
|
|
||||||
const icon = getIcon({
|
|
||||||
size: 32,
|
|
||||||
sender: chatGptLabel || model,
|
|
||||||
isCreatedByUser: false,
|
|
||||||
model,
|
|
||||||
chatGptLabel,
|
|
||||||
promptPrefix,
|
|
||||||
error: false,
|
|
||||||
button: true
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog onOpenChange={onOpenChange}>
|
|
||||||
<DropdownMenu
|
|
||||||
open={menuOpen}
|
|
||||||
onOpenChange={setMenuOpen}
|
|
||||||
>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
// style={{backgroundColor: 'rgb(16, 163, 127)'}}
|
|
||||||
className={`absolute top-[0.25px] mb-0 ml-1 items-center rounded-md border-0 p-1 outline-none md:ml-0 ${colorProps.join(
|
|
||||||
' '
|
|
||||||
)} focus:ring-0 focus:ring-offset-0 disabled:top-[0.25px] dark:data-[state=open]:bg-opacity-50 md:top-1 md:left-1 md:pl-1 md:disabled:top-1`}
|
|
||||||
>
|
|
||||||
{icon}
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent
|
|
||||||
className="w-56 dark:bg-gray-700"
|
|
||||||
onCloseAutoFocus={event => event.preventDefault()}
|
|
||||||
>
|
|
||||||
<DropdownMenuLabel className="dark:text-gray-300">Select a Model</DropdownMenuLabel>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuRadioGroup
|
|
||||||
value={chatGptLabel || model}
|
|
||||||
onValueChange={onChange}
|
|
||||||
className="overflow-y-auto"
|
|
||||||
>
|
|
||||||
{availableModels.length ? (
|
|
||||||
<MenuItems
|
|
||||||
models={availableModels}
|
|
||||||
onSelect={onChange}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<DropdownMenuLabel className="dark:text-gray-300">No model available.</DropdownMenuLabel>
|
|
||||||
)}
|
|
||||||
</DropdownMenuRadioGroup>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
<ModelDialog
|
|
||||||
mutate={mutate}
|
|
||||||
setModelSave={setModelSave}
|
|
||||||
handleSaveState={handleSaveState}
|
|
||||||
/>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { useRecoilValue, useRecoilState } from 'recoil';
|
||||||
import SubmitButton from './SubmitButton';
|
import SubmitButton from './SubmitButton';
|
||||||
import AdjustToneButton from './AdjustToneButton';
|
import AdjustToneButton from './AdjustToneButton';
|
||||||
import BingStyles from './BingStyles';
|
import BingStyles from './BingStyles';
|
||||||
// import ModelMenu from './Models/ModelMenu';
|
import EndpointMenu from './Endpoints/EndpointMenu';
|
||||||
import Footer from './Footer';
|
import Footer from './Footer';
|
||||||
import TextareaAutosize from 'react-textarea-autosize';
|
import TextareaAutosize from 'react-textarea-autosize';
|
||||||
import RegenerateIcon from '../svg/RegenerateIcon';
|
import RegenerateIcon from '../svg/RegenerateIcon';
|
||||||
|
|
@ -167,7 +167,7 @@ export default function TextChat({ isSearchView = false }) {
|
||||||
disabled ? 'dark:bg-gray-900' : 'dark:bg-gray-700'
|
disabled ? 'dark:bg-gray-900' : 'dark:bg-gray-700'
|
||||||
} dark:text-white dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] md:py-3 md:pl-4`}
|
} dark:text-white dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] md:py-3 md:pl-4`}
|
||||||
>
|
>
|
||||||
{/* <ModelMenu /> */}
|
<EndpointMenu />
|
||||||
<TextareaAutosize
|
<TextareaAutosize
|
||||||
tabIndex="0"
|
tabIndex="0"
|
||||||
autoFocus
|
autoFocus
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import getDefaultConversation from '~/utils/getDefaultConversation';
|
||||||
// jailbreakConversationId: null,
|
// jailbreakConversationId: null,
|
||||||
// conversationSignature: null,
|
// conversationSignature: null,
|
||||||
// clientId: null,
|
// clientId: null,
|
||||||
// invocationId: null,
|
// invocationId: 1,
|
||||||
// toneStyle: null,
|
// toneStyle: null,
|
||||||
// suggestions: []
|
// suggestions: []
|
||||||
// };
|
// };
|
||||||
|
|
@ -61,10 +61,13 @@ const useConversation = () => {
|
||||||
|
|
||||||
const switchToConversation = useRecoilCallback(
|
const switchToConversation = useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot }) =>
|
||||||
async (_conversation, messages = null) => {
|
async (_conversation, messages = null, targetEndpoint = null) => {
|
||||||
const prevConversation = await snapshot.getPromise(conversation);
|
const prevConversation = await snapshot.getPromise(conversation);
|
||||||
const availableEndpoints = await snapshot.getPromise(endpoints.availableEndpoints);
|
const endpointsFilter = await snapshot.getPromise(endpoints.endpointsFilter);
|
||||||
_switchToConversation(_conversation, messages, { availableEndpoints, prevConversation });
|
_switchToConversation(_conversation, messages, targetEndpoint, {
|
||||||
|
endpointsFilter,
|
||||||
|
prevConversation
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
@ -72,27 +75,34 @@ const useConversation = () => {
|
||||||
const _switchToConversation = (
|
const _switchToConversation = (
|
||||||
conversation,
|
conversation,
|
||||||
messages = null,
|
messages = null,
|
||||||
{ availableEndpoints = [], prevConversation = {} }
|
targetEndpoint = null,
|
||||||
|
{ endpointsFilter = {}, prevConversation = {} }
|
||||||
) => {
|
) => {
|
||||||
let { endpoint = null } = conversation;
|
let { endpoint = null } = conversation;
|
||||||
|
|
||||||
if (endpoint === null)
|
if (endpoint === null)
|
||||||
// get the default model
|
// get the default model
|
||||||
conversation = getDefaultConversation({ conversation, availableEndpoints, prevConversation });
|
conversation = getDefaultConversation({
|
||||||
console.log(conversation);
|
conversation,
|
||||||
|
endpointsFilter,
|
||||||
|
prevConversation,
|
||||||
|
targetEndpoint
|
||||||
|
});
|
||||||
|
|
||||||
setConversation(conversation);
|
setConversation(conversation);
|
||||||
setMessages(messages);
|
setMessages(messages);
|
||||||
resetLatestMessage();
|
resetLatestMessage();
|
||||||
};
|
};
|
||||||
|
|
||||||
const newConversation = (template = {}) => {
|
const newConversation = (template = {}, targetEndpoint = null) => {
|
||||||
switchToConversation(
|
switchToConversation(
|
||||||
{
|
{
|
||||||
conversationId: 'new',
|
conversationId: 'new',
|
||||||
title: 'New Chat',
|
title: 'New Chat',
|
||||||
...template
|
...template
|
||||||
},
|
},
|
||||||
[]
|
[],
|
||||||
|
targetEndpoint
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@ const buildDefaultConversation = ({ conversation, endpoint, lastConversationSetu
|
||||||
endpoint,
|
endpoint,
|
||||||
jailbreak: lastConversationSetup?.jailbreak || false,
|
jailbreak: lastConversationSetup?.jailbreak || false,
|
||||||
jailbreakConversationId: lastConversationSetup?.jailbreakConversationId || null,
|
jailbreakConversationId: lastConversationSetup?.jailbreakConversationId || null,
|
||||||
conversationSignature: lastConversationSetup?.conversationSignature || null,
|
conversationSignature: null,
|
||||||
clientId: lastConversationSetup?.clientId || null,
|
clientId: null,
|
||||||
invocationId: lastConversationSetup?.invocationId || null,
|
invocationId: 1,
|
||||||
toneStyle: lastConversationSetup?.toneStyle || 'fast',
|
toneStyle: lastConversationSetup?.toneStyle || 'fast',
|
||||||
suggestions: lastConversationSetup?.suggestions || []
|
suggestions: []
|
||||||
};
|
};
|
||||||
} else if (endpoint === 'chatGPTBrowser') {
|
} else if (endpoint === 'chatGPTBrowser') {
|
||||||
conversation = {
|
conversation = {
|
||||||
|
|
@ -44,11 +44,27 @@ const buildDefaultConversation = ({ conversation, endpoint, lastConversationSetu
|
||||||
return conversation;
|
return conversation;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDefaultConversation = ({ conversation, prevConversation, availableEndpoints }) => {
|
const getDefaultConversation = ({ conversation, prevConversation, endpointsFilter, targetEndpoint }) => {
|
||||||
|
if (targetEndpoint) {
|
||||||
|
// try to use current model
|
||||||
|
const endpoint = targetEndpoint;
|
||||||
|
if (endpointsFilter?.[endpoint]) {
|
||||||
|
conversation = buildDefaultConversation({
|
||||||
|
conversation,
|
||||||
|
endpoint,
|
||||||
|
lastConversationSetup: {}
|
||||||
|
});
|
||||||
|
return conversation;
|
||||||
|
} else {
|
||||||
|
console.log(endpoint);
|
||||||
|
console.warn(`Illegal target endpoint ${targetEndpoint} ${endpointsFilter}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// try to use current model
|
// try to use current model
|
||||||
const { endpoint = null } = prevConversation || {};
|
const { endpoint = null } = prevConversation || {};
|
||||||
if (endpoint in availableEndpoints) {
|
if (endpointsFilter?.[endpoint]) {
|
||||||
conversation = buildDefaultConversation({
|
conversation = buildDefaultConversation({
|
||||||
conversation,
|
conversation,
|
||||||
endpoint,
|
endpoint,
|
||||||
|
|
@ -63,14 +79,15 @@ const getDefaultConversation = ({ conversation, prevConversation, availableEndpo
|
||||||
const lastConversationSetup = JSON.parse(localStorage.getItem('lastConversationSetup'));
|
const lastConversationSetup = JSON.parse(localStorage.getItem('lastConversationSetup'));
|
||||||
const { endpoint = null } = lastConversationSetup;
|
const { endpoint = null } = lastConversationSetup;
|
||||||
|
|
||||||
if (endpoint in availableEndpoints) {
|
if (endpointsFilter?.[endpoint]) {
|
||||||
conversation = buildDefaultConversation({ conversation, endpoint, lastConversationSetup });
|
conversation = buildDefaultConversation({ conversation, endpoint, lastConversationSetup });
|
||||||
return conversation;
|
return conversation;
|
||||||
}
|
}
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
|
|
||||||
// if anything happens, reset to default model
|
// if anything happens, reset to default model
|
||||||
const endpoint = availableEndpoints?.[0];
|
|
||||||
|
const endpoint = ['openAI', 'azureOpenAI', 'bingAI', 'chatGPTBrowser'].find(e => endpointsFilter?.[e]);
|
||||||
if (endpoint) {
|
if (endpoint) {
|
||||||
conversation = buildDefaultConversation({ conversation, endpoint });
|
conversation = buildDefaultConversation({ conversation, endpoint });
|
||||||
return conversation;
|
return conversation;
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ const useMessageHandler = () => {
|
||||||
jailbreakConversationId: currentConversation?.jailbreakConversationId || null,
|
jailbreakConversationId: currentConversation?.jailbreakConversationId || null,
|
||||||
conversationSignature: currentConversation?.conversationSignature || null,
|
conversationSignature: currentConversation?.conversationSignature || null,
|
||||||
clientId: currentConversation?.clientId || null,
|
clientId: currentConversation?.clientId || null,
|
||||||
invocationId: currentConversation?.invocationId || null,
|
invocationId: currentConversation?.invocationId || 1,
|
||||||
toneStyle: currentConversation?.toneStyle || 'fast',
|
toneStyle: currentConversation?.toneStyle || 'fast',
|
||||||
suggestions: currentConversation?.suggestions || []
|
suggestions: currentConversation?.suggestions || []
|
||||||
};
|
};
|
||||||
|
|
|
||||||
7587
client/yarn.lock
Normal file
7587
client/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue