mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 09:50:15 +01:00
⌚ fix: Wait for Initial Message Save & Correct Latest Message (#3399)
* chore: assistants, unsupported assistant, better logging * chore: remove unnecessary logger in validateAssistant middleware * fix: resolve initial conversation save/promise before saving response * chore: Import and organize dependencies in Speech component * fix: conversation statefulness - Latest Message (at index 0) should not be reset if existing convo - add debugging context for clearAllLatestMessages - Added logging concerning latest Message updates (dev mode only) - update latest message Set logic, also checks for change in conversation Id - consolidated latest message helpers to client/src/utils/messages.ts
This commit is contained in:
parent
9e7615f832
commit
2ad097647c
25 changed files with 275 additions and 113 deletions
|
|
@ -107,6 +107,16 @@ export default function useChatFunctions({
|
|||
const intermediateId = overrideUserMessageId ?? v4();
|
||||
parentMessageId = parentMessageId || latestMessage?.messageId || Constants.NO_PARENT;
|
||||
|
||||
logger.dir('Ask function called with:', {
|
||||
index,
|
||||
latestMessage,
|
||||
conversationId,
|
||||
intermediateId,
|
||||
parentMessageId,
|
||||
currentMessages,
|
||||
});
|
||||
logger.log('=====================================');
|
||||
|
||||
if (conversationId == Constants.NEW_CONVO) {
|
||||
parentMessageId = Constants.NO_PARENT;
|
||||
currentMessages = [];
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import type {
|
|||
TModelsConfig,
|
||||
TEndpointsConfig,
|
||||
} from 'librechat-data-provider';
|
||||
import { buildDefaultConvo, getDefaultEndpoint, getEndpointField } from '~/utils';
|
||||
import { buildDefaultConvo, getDefaultEndpoint, getEndpointField, logger } from '~/utils';
|
||||
import store from '~/store';
|
||||
|
||||
const useConversation = () => {
|
||||
|
|
@ -60,6 +60,10 @@ const useConversation = () => {
|
|||
setMessages(messages);
|
||||
setSubmission({} as TSubmission);
|
||||
resetLatestMessage();
|
||||
logger.log(
|
||||
'[useConversation] Switched to conversation and reset Latest Message',
|
||||
conversation,
|
||||
);
|
||||
|
||||
if (conversation.conversationId === 'new' && !modelsData) {
|
||||
queryClient.invalidateQueries([QueryKeys.messages, 'new']);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useSetRecoilState } from 'recoil';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { QueryKeys, EModelEndpoint, LocalStorageKeys } from 'librechat-data-provider';
|
||||
import { QueryKeys, EModelEndpoint, LocalStorageKeys, Constants } from 'librechat-data-provider';
|
||||
import type { TConversation, TEndpointsConfig, TModelsConfig } from 'librechat-data-provider';
|
||||
import { buildDefaultConvo, getDefaultEndpoint, getEndpointField } from '~/utils';
|
||||
import store from '~/store';
|
||||
|
|
@ -10,7 +10,7 @@ const useNavigateToConvo = (index = 0) => {
|
|||
const navigate = useNavigate();
|
||||
const queryClient = useQueryClient();
|
||||
const clearAllConversations = store.useClearConvoState();
|
||||
const clearAllLatestMessages = store.useClearLatestMessages();
|
||||
const clearAllLatestMessages = store.useClearLatestMessages(`useNavigateToConvo ${index}`);
|
||||
const setSubmission = useSetRecoilState(store.submissionByIndex(index));
|
||||
const { setConversation } = store.useCreateConversationAtom(index);
|
||||
|
||||
|
|
@ -50,10 +50,10 @@ const useNavigateToConvo = (index = 0) => {
|
|||
}
|
||||
clearAllConversations(true);
|
||||
setConversation(convo);
|
||||
navigate(`/c/${convo.conversationId ?? 'new'}`);
|
||||
navigate(`/c/${convo.conversationId ?? Constants.NEW_CONVO}`);
|
||||
};
|
||||
|
||||
const navigateWithLastTools = (conversation: TConversation) => {
|
||||
const navigateWithLastTools = (conversation: TConversation, _resetLatestMessage?: boolean) => {
|
||||
// set conversation to the new conversation
|
||||
if (conversation?.endpoint === EModelEndpoint.gptPlugins) {
|
||||
let lastSelectedTools = [];
|
||||
|
|
@ -63,12 +63,15 @@ const useNavigateToConvo = (index = 0) => {
|
|||
} catch (e) {
|
||||
// console.error(e);
|
||||
}
|
||||
navigateToConvo({
|
||||
...conversation,
|
||||
tools: conversation?.tools?.length ? conversation?.tools : lastSelectedTools,
|
||||
});
|
||||
navigateToConvo(
|
||||
{
|
||||
...conversation,
|
||||
tools: conversation?.tools?.length ? conversation?.tools : lastSelectedTools,
|
||||
},
|
||||
_resetLatestMessage,
|
||||
);
|
||||
} else {
|
||||
navigateToConvo(conversation);
|
||||
navigateToConvo(conversation, _resetLatestMessage);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { useEffect, useRef, useCallback } from 'react';
|
||||
import { isAssistantsEndpoint } from 'librechat-data-provider';
|
||||
import { Constants, isAssistantsEndpoint } from 'librechat-data-provider';
|
||||
import type { TMessageProps } from '~/common';
|
||||
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
||||
import { getLatestText, getLengthAndFirstFiveChars } from '~/utils';
|
||||
import useCopyToClipboard from './useCopyToClipboard';
|
||||
import { getTextKey, logger } from '~/utils';
|
||||
|
||||
export default function useMessageHelpers(props: TMessageProps) {
|
||||
const latestText = useRef<string | number>('');
|
||||
|
|
@ -27,7 +27,8 @@ export default function useMessageHelpers(props: TMessageProps) {
|
|||
const isLast = !children?.length;
|
||||
|
||||
useEffect(() => {
|
||||
if (conversation?.conversationId === 'new') {
|
||||
const convoId = conversation?.conversationId;
|
||||
if (convoId === Constants.NEW_CONVO) {
|
||||
return;
|
||||
}
|
||||
if (!message) {
|
||||
|
|
@ -37,15 +38,25 @@ export default function useMessageHelpers(props: TMessageProps) {
|
|||
return;
|
||||
}
|
||||
|
||||
const text = getLatestText(message);
|
||||
const textKey = `${message?.messageId ?? ''}${getLengthAndFirstFiveChars(text)}`;
|
||||
const textKey = getTextKey(message, convoId);
|
||||
|
||||
if (textKey === latestText.current) {
|
||||
return;
|
||||
// Check for text/conversation change
|
||||
const logInfo = {
|
||||
textKey,
|
||||
'latestText.current': latestText.current,
|
||||
messageId: message?.messageId,
|
||||
convoId,
|
||||
};
|
||||
if (
|
||||
textKey !== latestText.current ||
|
||||
(latestText.current && convoId !== latestText.current.split(Constants.COMMON_DIVIDER)[2])
|
||||
) {
|
||||
logger.log('[useMessageHelpers] Setting latest message: ', logInfo);
|
||||
latestText.current = textKey;
|
||||
setLatestMessage({ ...message });
|
||||
} else {
|
||||
logger.log('No change in latest message', logInfo);
|
||||
}
|
||||
|
||||
latestText.current = textKey;
|
||||
setLatestMessage({ ...message });
|
||||
}, [isLast, message, setLatestMessage, conversation?.conversationId]);
|
||||
|
||||
const enterEdit = useCallback(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { useRecoilValue } from 'recoil';
|
||||
import { Constants } from 'librechat-data-provider';
|
||||
import { useEffect, useRef, useCallback, useMemo, useState } from 'react';
|
||||
import type { TMessage } from 'librechat-data-provider';
|
||||
import { useChatContext, useAddedChatContext } from '~/Providers';
|
||||
import { getLatestText, getLengthAndFirstFiveChars } from '~/utils';
|
||||
import { getTextKey, logger } from '~/utils';
|
||||
import store from '~/store';
|
||||
|
||||
export default function useMessageProcess({ message }: { message?: TMessage | null }) {
|
||||
|
|
@ -26,7 +27,8 @@ export default function useMessageProcess({ message }: { message?: TMessage | nu
|
|||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (conversation?.conversationId === 'new') {
|
||||
const convoId = conversation?.conversationId;
|
||||
if (convoId === Constants.NEW_CONVO) {
|
||||
return;
|
||||
}
|
||||
if (!message) {
|
||||
|
|
@ -36,15 +38,27 @@ export default function useMessageProcess({ message }: { message?: TMessage | nu
|
|||
return;
|
||||
}
|
||||
|
||||
const text = getLatestText(message);
|
||||
const textKey = `${message?.messageId ?? ''}${getLengthAndFirstFiveChars(text)}`;
|
||||
const textKey = getTextKey(message, convoId);
|
||||
|
||||
if (textKey === latestText.current) {
|
||||
return;
|
||||
// Check for text/conversation change
|
||||
const logInfo = {
|
||||
textKey,
|
||||
'latestText.current': latestText.current,
|
||||
messageId: message?.messageId,
|
||||
convoId,
|
||||
};
|
||||
if (
|
||||
textKey !== latestText.current ||
|
||||
(convoId &&
|
||||
latestText.current &&
|
||||
convoId !== latestText.current.split(Constants.COMMON_DIVIDER)[2])
|
||||
) {
|
||||
logger.log('[useMessageProcess] Setting latest message: ', logInfo);
|
||||
latestText.current = textKey;
|
||||
setLatestMessage({ ...message });
|
||||
} else {
|
||||
logger.log('No change in latest message', logInfo);
|
||||
}
|
||||
|
||||
latestText.current = textKey;
|
||||
setLatestMessage({ ...message });
|
||||
}, [hasNoChildren, message, setLatestMessage, conversation?.conversationId]);
|
||||
|
||||
const handleScroll = useCallback(() => {
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ const useNewConvo = (index = 0) => {
|
|||
const { data: startupConfig } = useGetStartupConfig();
|
||||
const clearAllConversations = store.useClearConvoState();
|
||||
const defaultPreset = useRecoilValue(store.defaultPreset);
|
||||
const clearAllLatestMessages = store.useClearLatestMessages();
|
||||
const { setConversation } = store.useCreateConversationAtom(index);
|
||||
const [files, setFiles] = useRecoilState(store.filesByIndex(index));
|
||||
const clearAllLatestMessages = store.useClearLatestMessages(`useNewConvo ${index}`);
|
||||
const setSubmission = useSetRecoilState<TSubmission | null>(store.submissionByIndex(index));
|
||||
const { data: endpointsConfig = {} as TEndpointsConfig } = useGetEndpointsQuery();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue