🐞 fix: Handle Empty Model Error in Assistants Form (#2265)

This commit is contained in:
Danny Avila 2024-04-01 09:20:11 -04:00 committed by GitHub
parent cc92597f14
commit d07396d308
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 16 deletions

View file

@ -18,6 +18,8 @@ import type { LucideIcon } from 'lucide-react';
export type GenericSetter<T> = (value: T | ((currentValue: T) => T)) => void; export type GenericSetter<T> = (value: T | ((currentValue: T) => T)) => void;
export type LastSelectedModels = Record<EModelEndpoint, string>;
export type NavLink = { export type NavLink = {
title: string; title: string;
label?: string; label?: string;

View file

@ -317,19 +317,28 @@ export default function AssistantPanel({
<Controller <Controller
name="model" name="model"
control={control} control={control}
render={({ field }) => ( rules={{ required: true, minLength: 1 }}
<SelectDropDown render={({ field, fieldState: { error } }) => (
emptyTitle={true} <>
value={field.value} <SelectDropDown
setValue={field.onChange} emptyTitle={true}
availableValues={modelsQuery.data?.[EModelEndpoint.assistants] ?? []} value={field.value}
showAbove={false} setValue={field.onChange}
showLabel={false} availableValues={modelsQuery.data?.[EModelEndpoint.assistants] ?? []}
className={cn( showAbove={false}
cardStyle, showLabel={false}
'flex h-[40px] w-full flex-none items-center justify-center px-4 hover:cursor-pointer', className={cn(
cardStyle,
'flex h-[40px] w-full flex-none items-center justify-center px-4 hover:cursor-pointer',
)}
containerClassName={cn('rounded-md', error ? 'border-red-500 border-2' : '')}
/>
{error && (
<span className="text-sm text-red-500 transition duration-300 ease-in-out">
{localize('com_ui_field_required')}
</span>
)} )}
/> </>
)} )}
/> />
</div> </div>

View file

@ -4,17 +4,24 @@ import {
defaultAssistantFormValues, defaultAssistantFormValues,
defaultOrderQuery, defaultOrderQuery,
isImageVisionTool, isImageVisionTool,
EModelEndpoint,
Capabilities, Capabilities,
FileSources, FileSources,
} from 'librechat-data-provider'; } from 'librechat-data-provider';
import type { UseFormReset } from 'react-hook-form'; import type { UseFormReset } from 'react-hook-form';
import type { UseMutationResult } from '@tanstack/react-query'; import type { UseMutationResult } from '@tanstack/react-query';
import type { Assistant, AssistantCreateParams } from 'librechat-data-provider'; import type { Assistant, AssistantCreateParams } from 'librechat-data-provider';
import type { AssistantForm, Actions, TAssistantOption, ExtendedFile } from '~/common'; import type {
AssistantForm,
Actions,
TAssistantOption,
ExtendedFile,
LastSelectedModels,
} from '~/common';
import SelectDropDown from '~/components/ui/SelectDropDown'; import SelectDropDown from '~/components/ui/SelectDropDown';
import { useListAssistantsQuery } from '~/data-provider'; import { useListAssistantsQuery } from '~/data-provider';
import { useLocalize, useLocalStorage } from '~/hooks';
import { useFileMapContext } from '~/Providers'; import { useFileMapContext } from '~/Providers';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils'; import { cn } from '~/utils';
const keys = new Set(['name', 'id', 'description', 'instructions', 'model']); const keys = new Set(['name', 'id', 'description', 'instructions', 'model']);
@ -35,6 +42,10 @@ export default function AssistantSelect({
const localize = useLocalize(); const localize = useLocalize();
const fileMap = useFileMapContext(); const fileMap = useFileMapContext();
const lastSelectedAssistant = useRef<string | null>(null); const lastSelectedAssistant = useRef<string | null>(null);
const [lastSelectedModels] = useLocalStorage<LastSelectedModels>(
'lastSelectedModel',
{} as LastSelectedModels,
);
const assistants = useListAssistantsQuery(defaultOrderQuery, { const assistants = useListAssistantsQuery(defaultOrderQuery, {
select: (res) => select: (res) =>
@ -79,7 +90,10 @@ export default function AssistantSelect({
createMutation.reset(); createMutation.reset();
if (!assistant) { if (!assistant) {
setCurrentAssistantId(undefined); setCurrentAssistantId(undefined);
return reset(defaultAssistantFormValues); return reset({
...defaultAssistantFormValues,
model: lastSelectedModels?.[EModelEndpoint.assistants] ?? '',
});
} }
const update = { const update = {
@ -127,7 +141,7 @@ export default function AssistantSelect({
reset(formValues); reset(formValues);
setCurrentAssistantId(assistant?.id); setCurrentAssistantId(assistant?.id);
}, },
[assistants.data, reset, setCurrentAssistantId, createMutation], [assistants.data, reset, setCurrentAssistantId, createMutation, lastSelectedModels],
); );
useEffect(() => { useEffect(() => {

View file

@ -46,6 +46,7 @@ export default {
com_assistants_update_error: 'There was an error updating your assistant.', com_assistants_update_error: 'There was an error updating your assistant.',
com_assistants_create_success: 'Successfully created', com_assistants_create_success: 'Successfully created',
com_assistants_create_error: 'There was an error creating your assistant.', com_assistants_create_error: 'There was an error creating your assistant.',
com_ui_field_required: 'This field is required',
com_ui_download_error: 'Error downloading file. The file may have been deleted.', com_ui_download_error: 'Error downloading file. The file may have been deleted.',
com_ui_attach_error_type: 'Unsupported file type for endpoint:', com_ui_attach_error_type: 'Unsupported file type for endpoint:',
com_ui_attach_error_size: 'File size limit exceeded for endpoint:', com_ui_attach_error_size: 'File size limit exceeded for endpoint:',