LibreChat/client/src/hooks/Messages/useMessageProcess.tsx
Danny Avila 2ad097647c
⌚ 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
2024-07-20 01:51:59 -04:00

102 lines
3 KiB
TypeScript

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 { getTextKey, logger } from '~/utils';
import store from '~/store';
export default function useMessageProcess({ message }: { message?: TMessage | null }) {
const latestText = useRef<string | number>('');
const hasNoChildren = useMemo(() => !message?.children?.length, [message]);
const [siblingMessage, setSiblingMessage] = useState<TMessage | null>(null);
const {
index,
conversation,
latestMessage,
setAbortScroll,
setLatestMessage,
isSubmitting: isSubmittingRoot,
} = useChatContext();
const { isSubmitting: isSubmittingAdditional } = useAddedChatContext();
const latestMultiMessage = useRecoilValue(store.latestMessageFamily(index + 1));
const isSubmittingFamily = useMemo(
() => isSubmittingRoot || isSubmittingAdditional,
[isSubmittingRoot, isSubmittingAdditional],
);
useEffect(() => {
const convoId = conversation?.conversationId;
if (convoId === Constants.NEW_CONVO) {
return;
}
if (!message) {
return;
}
if (!hasNoChildren) {
return;
}
const textKey = getTextKey(message, convoId);
// 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);
}
}, [hasNoChildren, message, setLatestMessage, conversation?.conversationId]);
const handleScroll = useCallback(() => {
if (isSubmittingFamily) {
setAbortScroll(true);
} else {
setAbortScroll(false);
}
}, [isSubmittingFamily, setAbortScroll]);
const showSibling = useMemo(
() =>
(hasNoChildren && latestMultiMessage && !latestMultiMessage?.children?.length) ||
siblingMessage,
[hasNoChildren, latestMultiMessage, siblingMessage],
);
useEffect(() => {
if (
hasNoChildren &&
latestMultiMessage &&
latestMultiMessage.conversationId === message?.conversationId
) {
const newSibling = Object.assign({}, latestMultiMessage, {
parentMessageId: message?.parentMessageId,
depth: message?.depth,
});
setSiblingMessage(newSibling);
}
}, [hasNoChildren, latestMultiMessage, message, setSiblingMessage, latestMessage]);
return {
showSibling,
handleScroll,
conversation,
siblingMessage,
setSiblingMessage,
isSubmittingFamily,
latestMultiMessage,
};
}