🔀 fix: Address Convo/Preset Switching Issues (#2709)

* fix(schemas): interchangeability between chatGptLabel <> modelLabel

* fix: display error message from enforceModelSpecs when conversation already existed

* fix(Mention): use activeIndex on mention tab/enter

* fix: correctly navigate to new conversation when deleting/archiving a new, active convo
This commit is contained in:
Danny Avila 2024-05-14 15:19:58 -04:00 committed by GitHub
parent e42709bd1f
commit 94eeec354e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 74 additions and 51 deletions

View file

@ -99,7 +99,7 @@ export default function Mention({
} else if (e.key === 'ArrowUp') { } else if (e.key === 'ArrowUp') {
setActiveIndex((prevIndex) => (prevIndex - 1 + matches.length) % matches.length); setActiveIndex((prevIndex) => (prevIndex - 1 + matches.length) % matches.length);
} else if (e.key === 'Enter' || e.key === 'Tab') { } else if (e.key === 'Enter' || e.key === 'Tab') {
const mentionOption = matches[0] as MentionOption | undefined; const mentionOption = matches[activeIndex] as MentionOption | undefined;
if (mentionOption?.type === 'endpoint') { if (mentionOption?.type === 'endpoint') {
e.preventDefault(); e.preventDefault();
} else if (e.key === 'Enter') { } else if (e.key === 'Enter') {

View file

@ -1,12 +1,10 @@
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui'; import { useParams, useNavigate } from 'react-router-dom';
import type { MouseEvent, FocusEvent, KeyboardEvent } from 'react'; import type { MouseEvent, FocusEvent, KeyboardEvent } from 'react';
import { useParams } from 'react-router-dom'; import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui';
import { useArchiveConversationMutation } from '~/data-provider';
import { useConversations, useLocalize, useNewConvo } from '~/hooks'; import { useConversations, useLocalize, useNewConvo } from '~/hooks';
import { useToastContext } from '~/Providers'; import { useArchiveConversationMutation } from '~/data-provider';
import { NotificationSeverity } from '~/common'; import { NotificationSeverity } from '~/common';
import { useToastContext } from '~/Providers';
type ArchiveButtonProps = { type ArchiveButtonProps = {
conversationId: string; conversationId: string;
@ -23,8 +21,9 @@ export default function ArchiveButton({
className = '', className = '',
}: ArchiveButtonProps) { }: ArchiveButtonProps) {
const localize = useLocalize(); const localize = useLocalize();
const { newConversation } = useNewConvo(); const navigate = useNavigate();
const { showToast } = useToastContext(); const { showToast } = useToastContext();
const { newConversation } = useNewConvo();
const { refreshConversations } = useConversations(); const { refreshConversations } = useConversations();
const { conversationId: currentConvoId } = useParams(); const { conversationId: currentConvoId } = useParams();
@ -42,8 +41,9 @@ export default function ArchiveButton({
{ conversationId, isArchived: shouldArchive }, { conversationId, isArchived: shouldArchive },
{ {
onSuccess: () => { onSuccess: () => {
if (currentConvoId === conversationId) { if (currentConvoId === conversationId || currentConvoId === 'new') {
newConversation(); newConversation();
navigate('/c/new', { replace: true });
} }
refreshConversations(); refreshConversations();
retainView(); retainView();

View file

@ -1,7 +1,7 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useParams } from 'react-router-dom';
import { QueryKeys } from 'librechat-data-provider'; import { QueryKeys } from 'librechat-data-provider';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { useParams, useNavigate } from 'react-router-dom';
import type { TMessage } from 'librechat-data-provider'; import type { TMessage } from 'librechat-data-provider';
import { useDeleteConversationMutation } from '~/data-provider'; import { useDeleteConversationMutation } from '~/data-provider';
import { import {
@ -26,13 +26,15 @@ export default function DeleteButton({
className = '', className = '',
}) { }) {
const localize = useLocalize(); const localize = useLocalize();
const navigate = useNavigate();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { newConversation } = useNewConvo(); const { newConversation } = useNewConvo();
const { conversationId: currentConvoId } = useParams(); const { conversationId: currentConvoId } = useParams();
const deleteConvoMutation = useDeleteConversationMutation({ const deleteConvoMutation = useDeleteConversationMutation({
onSuccess: () => { onSuccess: () => {
if (currentConvoId === conversationId) { if (currentConvoId === conversationId || currentConvoId === 'new') {
newConversation(); newConversation();
navigate('/c/new', { replace: true });
} }
retainView(); retainView();
}, },

View file

@ -390,6 +390,11 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
}); });
setIsSubmitting(false); setIsSubmitting(false);
return; return;
} else if (!data.conversationId) {
const errorResponse = parseErrorResponse(data);
setMessages([...messages, message, errorResponse]);
setIsSubmitting(false);
return;
} }
console.log('Error:', data); console.log('Error:', data);

View file

@ -400,25 +400,33 @@ export const openAISchema = tConversationSchema
maxContextTokens: true, maxContextTokens: true,
max_tokens: true, max_tokens: true,
}) })
.transform((obj) => ({ .transform((obj) => {
...obj, const result = {
model: obj.model ?? openAISettings.model.default, ...obj,
chatGptLabel: obj.modelLabel ?? obj.chatGptLabel ?? null, model: obj.model ?? openAISettings.model.default,
promptPrefix: obj.promptPrefix ?? null, chatGptLabel: obj.chatGptLabel ?? obj.modelLabel ?? null,
temperature: obj.temperature ?? openAISettings.temperature.default, promptPrefix: obj.promptPrefix ?? null,
top_p: obj.top_p ?? openAISettings.top_p.default, temperature: obj.temperature ?? openAISettings.temperature.default,
presence_penalty: obj.presence_penalty ?? openAISettings.presence_penalty.default, top_p: obj.top_p ?? openAISettings.top_p.default,
frequency_penalty: obj.frequency_penalty ?? openAISettings.frequency_penalty.default, presence_penalty: obj.presence_penalty ?? openAISettings.presence_penalty.default,
resendFiles: frequency_penalty: obj.frequency_penalty ?? openAISettings.frequency_penalty.default,
typeof obj.resendFiles === 'boolean' ? obj.resendFiles : openAISettings.resendFiles.default, resendFiles:
imageDetail: obj.imageDetail ?? openAISettings.imageDetail.default, typeof obj.resendFiles === 'boolean' ? obj.resendFiles : openAISettings.resendFiles.default,
stop: obj.stop ?? undefined, imageDetail: obj.imageDetail ?? openAISettings.imageDetail.default,
iconURL: obj.iconURL ?? undefined, stop: obj.stop ?? undefined,
greeting: obj.greeting ?? undefined, iconURL: obj.iconURL ?? undefined,
spec: obj.spec ?? undefined, greeting: obj.greeting ?? undefined,
maxContextTokens: obj.maxContextTokens ?? undefined, spec: obj.spec ?? undefined,
max_tokens: obj.max_tokens ?? undefined, maxContextTokens: obj.maxContextTokens ?? undefined,
})) max_tokens: obj.max_tokens ?? undefined,
};
if (obj.modelLabel) {
result.modelLabel = null;
}
return result;
})
.catch(() => ({ .catch(() => ({
model: openAISettings.model.default, model: openAISettings.model.default,
chatGptLabel: null, chatGptLabel: null,
@ -605,27 +613,35 @@ export const gptPluginsSchema = tConversationSchema
spec: true, spec: true,
maxContextTokens: true, maxContextTokens: true,
}) })
.transform((obj) => ({ .transform((obj) => {
...obj, const result = {
model: obj.model ?? 'gpt-3.5-turbo', ...obj,
chatGptLabel: obj.modelLabel ?? obj.chatGptLabel ?? null, model: obj.model ?? 'gpt-3.5-turbo',
promptPrefix: obj.promptPrefix ?? null, chatGptLabel: obj.chatGptLabel ?? obj.modelLabel ?? null,
temperature: obj.temperature ?? 0.8, promptPrefix: obj.promptPrefix ?? null,
top_p: obj.top_p ?? 1, temperature: obj.temperature ?? 0.8,
presence_penalty: obj.presence_penalty ?? 0, top_p: obj.top_p ?? 1,
frequency_penalty: obj.frequency_penalty ?? 0, presence_penalty: obj.presence_penalty ?? 0,
tools: obj.tools ?? [], frequency_penalty: obj.frequency_penalty ?? 0,
agentOptions: obj.agentOptions ?? { tools: obj.tools ?? [],
agent: EAgent.functions, agentOptions: obj.agentOptions ?? {
skipCompletion: true, agent: EAgent.functions,
model: 'gpt-3.5-turbo', skipCompletion: true,
temperature: 0, model: 'gpt-3.5-turbo',
}, temperature: 0,
iconURL: obj.iconURL ?? undefined, },
greeting: obj.greeting ?? undefined, iconURL: obj.iconURL ?? undefined,
spec: obj.spec ?? undefined, greeting: obj.greeting ?? undefined,
maxContextTokens: obj.maxContextTokens ?? undefined, spec: obj.spec ?? undefined,
})) maxContextTokens: obj.maxContextTokens ?? undefined,
};
if (obj.modelLabel) {
result.modelLabel = null;
}
return result;
})
.catch(() => ({ .catch(() => ({
model: 'gpt-3.5-turbo', model: 'gpt-3.5-turbo',
chatGptLabel: null, chatGptLabel: null,