🔄 refactor(EditPresetDialog): Update Model on Endpoint Change (#2936)

* refactor(EditPresetDialog): dynamically update current editable preset model on endpoint change

* feat: Add null check for models in EditPresetDialog

* chore(AlertDialogPortal): typing

* fix(EditPresetDialog): prevent Unknown endpoint edge case for custom endpoints
This commit is contained in:
Danny Avila 2024-05-31 11:43:14 -04:00 committed by GitHub
parent 248dfb8b5b
commit f9a0166352
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 98 additions and 13 deletions

View file

@ -196,6 +196,7 @@ export type TEditPresetProps = {
title?: string;
};
export type TSetOptions = (options: Record<string, unknown>) => void;
export type TSetOptionsPayload = {
setOption: TSetOption;
setExample: TSetExample;
@ -205,6 +206,7 @@ export type TSetOptionsPayload = {
// getConversation: () => TConversation | TPreset | null;
checkPluginSelection: (value: string) => boolean;
setTools: (newValue: string, remove?: boolean) => void;
setOptions?: TSetOptions;
};
export type TPresetItemProps = {

View file

@ -1,10 +1,20 @@
import { useRecoilState } from 'recoil';
import { useCallback, useEffect } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { QueryKeys } from 'librechat-data-provider';
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
import { cn, defaultTextProps, removeFocusOutlines, mapEndpoints } from '~/utils';
import { Input, Label, Dropdown, Dialog, DialogClose, DialogButton } from '~/components/';
import type { TModelsConfig, TEndpointsConfig } from 'librechat-data-provider';
import {
cn,
defaultTextProps,
removeFocusOutlines,
mapEndpoints,
getConvoSwitchLogic,
} from '~/utils';
import { Input, Label, Dropdown, Dialog, DialogClose, DialogButton } from '~/components';
import { useSetIndexOptions, useLocalize, useDebouncedInput } from '~/hooks';
import PopoverButtons from '~/components/Chat/Input/PopoverButtons';
import DialogTemplate from '~/components/ui/DialogTemplate';
import { useSetIndexOptions, useLocalize, useDebouncedInput } from '~/hooks';
import { EndpointSettings } from '~/components/Endpoints';
import { useChatContext } from '~/Providers';
import store from '~/store';
@ -17,8 +27,9 @@ const EditPresetDialog = ({
submitPreset: () => void;
}) => {
const localize = useLocalize();
const queryClient = useQueryClient();
const { preset, setPreset } = useChatContext();
const { setOption } = useSetIndexOptions(preset);
const { setOption, setOptions, setAgentOption } = useSetIndexOptions(preset);
const [onTitleChange, title] = useDebouncedInput({
setOption,
optionKey: 'title',
@ -30,6 +41,67 @@ const EditPresetDialog = ({
select: mapEndpoints,
});
useEffect(() => {
if (!preset) {
return;
}
if (!preset.endpoint) {
return;
}
const modelsConfig = queryClient.getQueryData<TModelsConfig>([QueryKeys.models]);
if (!modelsConfig) {
return;
}
const models = modelsConfig[preset.endpoint];
if (!models) {
return;
}
if (!models.length) {
return;
}
if (preset.model === models[0]) {
return;
}
if (!models.includes(preset.model ?? '')) {
console.log('setting model', models[0]);
setOption('model')(models[0]);
}
if (preset.agentOptions?.model === models[0]) {
return;
}
if (preset.agentOptions?.model && !models.includes(preset.agentOptions.model)) {
console.log('setting agent model', models[0]);
setAgentOption('model')(models[0]);
}
}, [preset, queryClient, setOption, setAgentOption]);
const switchEndpoint = useCallback(
(newEndpoint: string) => {
if (!setOptions) {
return console.warn('setOptions is not defined');
}
const { newEndpointType } = getConvoSwitchLogic({
newEndpoint,
modularChat: true,
conversation: null,
endpointsConfig: queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]) ?? {},
});
setOptions({
endpoint: newEndpoint,
endpointType: newEndpointType,
});
},
[queryClient, setOptions],
);
const { endpoint, endpointType, model } = preset || {};
if (!endpoint) {
return null;
@ -76,7 +148,7 @@ const EditPresetDialog = ({
</Label>
<Dropdown
value={endpoint || ''}
onChange={(value) => setOption('endpoint')(value)}
onChange={switchEndpoint}
options={availableEndpoints}
/>
</div>

View file

@ -7,12 +7,10 @@ const AlertDialog = AlertDialogPrimitive.Root;
const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
const AlertDialogPortal = ({
className = '',
children,
...props
}: AlertDialogPrimitive.AlertDialogPortalProps) => (
<AlertDialogPrimitive.Portal className={cn(className)} {...props}>
type AlertPortalProps = AlertDialogPrimitive.AlertDialogPortalProps & { className?: string };
const AlertDialogPortal = ({ className = '', children, ...props }: AlertPortalProps) => (
<AlertDialogPrimitive.Portal className={cn(className)} {...(props as AlertPortalProps)}>
<div className="fixed inset-0 z-50 flex items-end justify-center sm:items-center">
{children}
</div>

View file

@ -1,6 +1,6 @@
import { useRecoilValue, useSetRecoilState } from 'recoil';
import type { TPreset, TPlugin } from 'librechat-data-provider';
import type { TSetOptionsPayload, TSetExample, TSetOption } from '~/common';
import type { TSetOptionsPayload, TSetExample, TSetOption, TSetOptions } from '~/common';
import { useChatContext } from '~/Providers/ChatContext';
import { cleanupPreset } from '~/utils';
import store from '~/store';
@ -17,6 +17,18 @@ const usePresetIndexOptions: TUsePresetOptions = (_preset) => {
}
const getConversation: () => TPreset | null = () => preset;
const setOptions: TSetOptions = (options) => {
const update = { ...options };
setPreset((prevState) =>
cleanupPreset({
preset: {
...prevState,
...update,
},
}),
);
};
const setOption: TSetOption = (param) => (newValue) => {
const update = {};
update[param] = newValue;
@ -155,6 +167,7 @@ const usePresetIndexOptions: TUsePresetOptions = (_preset) => {
setOption,
setExample,
addExample,
setOptions,
removeExample,
getConversation,
checkPluginSelection,

View file

@ -157,13 +157,13 @@ const useSetIndexOptions: TUseSetOptions = (preset = false) => {
};
return {
setTools,
setOption,
setExample,
addExample,
removeExample,
setAgentOption,
checkPluginSelection,
setTools,
};
};