| import { useCallback, useState } from 'react'; |
| import { QueryKeys } from 'librechat-data-provider'; |
| import { useQueryClient } from '@tanstack/react-query'; |
| import { useRecoilState, useResetRecoilState, useSetRecoilState } from 'recoil'; |
| import type { TMessage } from 'librechat-data-provider'; |
| import useChatFunctions from '~/hooks/Chat/useChatFunctions'; |
| import { useGetMessagesByConvoId } from '~/data-provider'; |
| import { useAuthContext } from '~/hooks/AuthContext'; |
| import useNewConvo from '~/hooks/useNewConvo'; |
| import store from '~/store'; |
|
|
| |
| export default function useChatHelpers(index = 0, paramId?: string) { |
| const clearAllSubmissions = store.useClearSubmissionState(); |
| const [files, setFiles] = useRecoilState(store.filesByIndex(index)); |
| const [filesLoading, setFilesLoading] = useState(false); |
|
|
| const queryClient = useQueryClient(); |
| const { isAuthenticated } = useAuthContext(); |
|
|
| const { newConversation } = useNewConvo(index); |
| const { useCreateConversationAtom } = store; |
| const { conversation, setConversation } = useCreateConversationAtom(index); |
| const { conversationId } = conversation ?? {}; |
|
|
| const queryParam = paramId === 'new' ? paramId : (conversationId ?? paramId ?? ''); |
|
|
| |
|
|
| const { data: _messages } = useGetMessagesByConvoId(conversationId ?? '', { |
| enabled: isAuthenticated, |
| }); |
|
|
| const resetLatestMessage = useResetRecoilState(store.latestMessageFamily(index)); |
| const [isSubmitting, setIsSubmitting] = useRecoilState(store.isSubmittingFamily(index)); |
| const [latestMessage, setLatestMessage] = useRecoilState(store.latestMessageFamily(index)); |
| const setSiblingIdx = useSetRecoilState( |
| store.messagesSiblingIdxFamily(latestMessage?.parentMessageId ?? null), |
| ); |
|
|
| const setMessages = useCallback( |
| (messages: TMessage[]) => { |
| queryClient.setQueryData<TMessage[]>([QueryKeys.messages, queryParam], messages); |
| if (queryParam === 'new' && conversationId && conversationId !== 'new') { |
| queryClient.setQueryData<TMessage[]>([QueryKeys.messages, conversationId], messages); |
| } |
| }, |
| [queryParam, queryClient, conversationId], |
| ); |
|
|
| const getMessages = useCallback(() => { |
| return queryClient.getQueryData<TMessage[]>([QueryKeys.messages, queryParam]); |
| }, [queryParam, queryClient]); |
|
|
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| const setSubmission = useSetRecoilState(store.submissionByIndex(index)); |
|
|
| const { ask, regenerate } = useChatFunctions({ |
| index, |
| files, |
| setFiles, |
| getMessages, |
| setMessages, |
| isSubmitting, |
| conversation, |
| latestMessage, |
| setSubmission, |
| setLatestMessage, |
| }); |
|
|
| const continueGeneration = () => { |
| if (!latestMessage) { |
| console.error('Failed to regenerate the message: latestMessage not found.'); |
| return; |
| } |
|
|
| const messages = getMessages(); |
|
|
| const parentMessage = messages?.find( |
| (element) => element.messageId == latestMessage.parentMessageId, |
| ); |
|
|
| if (parentMessage && parentMessage.isCreatedByUser) { |
| ask({ ...parentMessage }, { isContinued: true, isRegenerate: true, isEdited: true }); |
| } else { |
| console.error( |
| 'Failed to regenerate the message: parentMessage not found, or not created by user.', |
| ); |
| } |
| }; |
|
|
| const stopGenerating = () => clearAllSubmissions(); |
|
|
| const handleStopGenerating = (e: React.MouseEvent<HTMLButtonElement>) => { |
| e.preventDefault(); |
| stopGenerating(); |
| }; |
|
|
| const handleRegenerate = (e: React.MouseEvent<HTMLButtonElement>) => { |
| e.preventDefault(); |
| const parentMessageId = latestMessage?.parentMessageId ?? ''; |
| if (!parentMessageId) { |
| console.error('Failed to regenerate the message: parentMessageId not found.'); |
| return; |
| } |
| regenerate({ parentMessageId }); |
| }; |
|
|
| const handleContinue = (e: React.MouseEvent<HTMLButtonElement>) => { |
| e.preventDefault(); |
| continueGeneration(); |
| setSiblingIdx(0); |
| }; |
|
|
| const [showPopover, setShowPopover] = useRecoilState(store.showPopoverFamily(index)); |
| const [abortScroll, setAbortScroll] = useRecoilState(store.abortScrollFamily(index)); |
| const [preset, setPreset] = useRecoilState(store.presetByIndex(index)); |
| const [optionSettings, setOptionSettings] = useRecoilState(store.optionSettingsFamily(index)); |
| const [showAgentSettings, setShowAgentSettings] = useRecoilState( |
| store.showAgentSettingsFamily(index), |
| ); |
|
|
| return { |
| newConversation, |
| conversation, |
| setConversation, |
| |
| |
| isSubmitting, |
| setIsSubmitting, |
| getMessages, |
| setMessages, |
| setSiblingIdx, |
| latestMessage, |
| setLatestMessage, |
| resetLatestMessage, |
| ask, |
| index, |
| regenerate, |
| stopGenerating, |
| handleStopGenerating, |
| handleRegenerate, |
| handleContinue, |
| showPopover, |
| setShowPopover, |
| abortScroll, |
| setAbortScroll, |
| preset, |
| setPreset, |
| optionSettings, |
| setOptionSettings, |
| showAgentSettings, |
| setShowAgentSettings, |
| files, |
| setFiles, |
| filesLoading, |
| setFilesLoading, |
| }; |
| } |
|
|