mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-22 08:12:00 +02:00
🔄 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:
parent
248dfb8b5b
commit
f9a0166352
5 changed files with 98 additions and 13 deletions
|
@ -196,6 +196,7 @@ export type TEditPresetProps = {
|
||||||
title?: string;
|
title?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TSetOptions = (options: Record<string, unknown>) => void;
|
||||||
export type TSetOptionsPayload = {
|
export type TSetOptionsPayload = {
|
||||||
setOption: TSetOption;
|
setOption: TSetOption;
|
||||||
setExample: TSetExample;
|
setExample: TSetExample;
|
||||||
|
@ -205,6 +206,7 @@ export type TSetOptionsPayload = {
|
||||||
// getConversation: () => TConversation | TPreset | null;
|
// getConversation: () => TConversation | TPreset | null;
|
||||||
checkPluginSelection: (value: string) => boolean;
|
checkPluginSelection: (value: string) => boolean;
|
||||||
setTools: (newValue: string, remove?: boolean) => void;
|
setTools: (newValue: string, remove?: boolean) => void;
|
||||||
|
setOptions?: TSetOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TPresetItemProps = {
|
export type TPresetItemProps = {
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
import { useRecoilState } from 'recoil';
|
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 { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
||||||
import { cn, defaultTextProps, removeFocusOutlines, mapEndpoints } from '~/utils';
|
import type { TModelsConfig, TEndpointsConfig } from 'librechat-data-provider';
|
||||||
import { Input, Label, Dropdown, Dialog, DialogClose, DialogButton } from '~/components/';
|
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 PopoverButtons from '~/components/Chat/Input/PopoverButtons';
|
||||||
import DialogTemplate from '~/components/ui/DialogTemplate';
|
import DialogTemplate from '~/components/ui/DialogTemplate';
|
||||||
import { useSetIndexOptions, useLocalize, useDebouncedInput } from '~/hooks';
|
|
||||||
import { EndpointSettings } from '~/components/Endpoints';
|
import { EndpointSettings } from '~/components/Endpoints';
|
||||||
import { useChatContext } from '~/Providers';
|
import { useChatContext } from '~/Providers';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
@ -17,8 +27,9 @@ const EditPresetDialog = ({
|
||||||
submitPreset: () => void;
|
submitPreset: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
const { preset, setPreset } = useChatContext();
|
const { preset, setPreset } = useChatContext();
|
||||||
const { setOption } = useSetIndexOptions(preset);
|
const { setOption, setOptions, setAgentOption } = useSetIndexOptions(preset);
|
||||||
const [onTitleChange, title] = useDebouncedInput({
|
const [onTitleChange, title] = useDebouncedInput({
|
||||||
setOption,
|
setOption,
|
||||||
optionKey: 'title',
|
optionKey: 'title',
|
||||||
|
@ -30,6 +41,67 @@ const EditPresetDialog = ({
|
||||||
select: mapEndpoints,
|
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 || {};
|
const { endpoint, endpointType, model } = preset || {};
|
||||||
if (!endpoint) {
|
if (!endpoint) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -76,7 +148,7 @@ const EditPresetDialog = ({
|
||||||
</Label>
|
</Label>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
value={endpoint || ''}
|
value={endpoint || ''}
|
||||||
onChange={(value) => setOption('endpoint')(value)}
|
onChange={switchEndpoint}
|
||||||
options={availableEndpoints}
|
options={availableEndpoints}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,12 +7,10 @@ const AlertDialog = AlertDialogPrimitive.Root;
|
||||||
|
|
||||||
const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
|
const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
|
||||||
|
|
||||||
const AlertDialogPortal = ({
|
type AlertPortalProps = AlertDialogPrimitive.AlertDialogPortalProps & { className?: string };
|
||||||
className = '',
|
|
||||||
children,
|
const AlertDialogPortal = ({ className = '', children, ...props }: AlertPortalProps) => (
|
||||||
...props
|
<AlertDialogPrimitive.Portal className={cn(className)} {...(props as AlertPortalProps)}>
|
||||||
}: AlertDialogPrimitive.AlertDialogPortalProps) => (
|
|
||||||
<AlertDialogPrimitive.Portal className={cn(className)} {...props}>
|
|
||||||
<div className="fixed inset-0 z-50 flex items-end justify-center sm:items-center">
|
<div className="fixed inset-0 z-50 flex items-end justify-center sm:items-center">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
import type { TPreset, TPlugin } from 'librechat-data-provider';
|
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 { useChatContext } from '~/Providers/ChatContext';
|
||||||
import { cleanupPreset } from '~/utils';
|
import { cleanupPreset } from '~/utils';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
@ -17,6 +17,18 @@ const usePresetIndexOptions: TUsePresetOptions = (_preset) => {
|
||||||
}
|
}
|
||||||
const getConversation: () => TPreset | null = () => 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 setOption: TSetOption = (param) => (newValue) => {
|
||||||
const update = {};
|
const update = {};
|
||||||
update[param] = newValue;
|
update[param] = newValue;
|
||||||
|
@ -155,6 +167,7 @@ const usePresetIndexOptions: TUsePresetOptions = (_preset) => {
|
||||||
setOption,
|
setOption,
|
||||||
setExample,
|
setExample,
|
||||||
addExample,
|
addExample,
|
||||||
|
setOptions,
|
||||||
removeExample,
|
removeExample,
|
||||||
getConversation,
|
getConversation,
|
||||||
checkPluginSelection,
|
checkPluginSelection,
|
||||||
|
|
|
@ -157,13 +157,13 @@ const useSetIndexOptions: TUseSetOptions = (preset = false) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
setTools,
|
||||||
setOption,
|
setOption,
|
||||||
setExample,
|
setExample,
|
||||||
addExample,
|
addExample,
|
||||||
removeExample,
|
removeExample,
|
||||||
setAgentOption,
|
setAgentOption,
|
||||||
checkPluginSelection,
|
checkPluginSelection,
|
||||||
setTools,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue