| import { useRecoilValue } from 'recoil'; |
| import { useCallback, useRef, useEffect } from 'react'; |
| import { useGetModelsQuery } from 'librechat-data-provider/react-query'; |
| import { getEndpointField, LocalStorageKeys, isAssistantsEndpoint } from 'librechat-data-provider'; |
| import type { |
| TEndpointsConfig, |
| EModelEndpoint, |
| TModelsConfig, |
| TConversation, |
| TPreset, |
| } from 'librechat-data-provider'; |
| import type { AssistantListItem } from '~/common'; |
| import type { SetterOrUpdater } from 'recoil'; |
| import useAssistantListMap from '~/hooks/Assistants/useAssistantListMap'; |
| import { buildDefaultConvo, getDefaultEndpoint, logger } from '~/utils'; |
| import { useGetEndpointsQuery } from '~/data-provider'; |
| import { mainTextareaId } from '~/common'; |
| import store from '~/store'; |
|
|
| const useGenerateConvo = ({ |
| index = 0, |
| rootIndex, |
| setConversation, |
| }: { |
| index?: number; |
| rootIndex: number; |
| setConversation?: SetterOrUpdater<TConversation | null>; |
| }) => { |
| const modelsQuery = useGetModelsQuery(); |
| const assistantsListMap = useAssistantListMap(); |
| const { data: endpointsConfig = {} as TEndpointsConfig } = useGetEndpointsQuery(); |
|
|
| const timeoutIdRef = useRef<NodeJS.Timeout>(); |
| const rootConvo = useRecoilValue(store.conversationByKeySelector(rootIndex)); |
|
|
| useEffect(() => { |
| if (rootConvo?.conversationId != null && setConversation) { |
| setConversation((prevState) => { |
| if (!prevState) { |
| return prevState; |
| } |
| const update = { |
| ...prevState, |
| conversationId: rootConvo.conversationId, |
| } as TConversation; |
|
|
| logger.log('conversation', 'Setting conversation from `useNewConvo`', update); |
| return update; |
| }); |
| } |
| }, [rootConvo?.conversationId, setConversation]); |
|
|
| const generateConversation = useCallback( |
| ({ |
| template = {}, |
| preset, |
| modelsData, |
| }: { |
| template?: Partial<TConversation>; |
| preset?: Partial<TPreset>; |
| modelsData?: TModelsConfig; |
| } = {}) => { |
| let conversation = { |
| conversationId: 'new', |
| title: 'New Chat', |
| endpoint: null, |
| ...template, |
| createdAt: '', |
| updatedAt: '', |
| }; |
|
|
| if (rootConvo?.conversationId) { |
| conversation.conversationId = rootConvo.conversationId; |
| } |
|
|
| const modelsConfig = modelsData ?? modelsQuery.data; |
|
|
| const defaultEndpoint = getDefaultEndpoint({ |
| convoSetup: preset ?? conversation, |
| endpointsConfig, |
| }); |
|
|
| const endpointType = getEndpointField(endpointsConfig, defaultEndpoint, 'type'); |
| if (!conversation.endpointType && endpointType) { |
| conversation.endpointType = endpointType; |
| } else if (conversation.endpointType && !endpointType) { |
| conversation.endpointType = undefined; |
| } |
|
|
| const isAssistantEndpoint = isAssistantsEndpoint(defaultEndpoint); |
| const assistants: AssistantListItem[] = assistantsListMap[defaultEndpoint ?? ''] ?? []; |
|
|
| if ( |
| conversation.assistant_id && |
| !assistantsListMap[defaultEndpoint ?? '']?.[conversation.assistant_id] |
| ) { |
| conversation.assistant_id = undefined; |
| } |
|
|
| if (!conversation.assistant_id && isAssistantEndpoint) { |
| conversation.assistant_id = |
| localStorage.getItem(`${LocalStorageKeys.ASST_ID_PREFIX}${index}${defaultEndpoint}`) ?? |
| assistants[0]?.id; |
| } |
|
|
| if ( |
| conversation.assistant_id != null && |
| isAssistantEndpoint && |
| conversation.conversationId === 'new' |
| ) { |
| const assistant = assistants.find((asst) => asst.id === conversation.assistant_id); |
| conversation.model = assistant?.model; |
| } |
|
|
| if (conversation.assistant_id != null && !isAssistantEndpoint) { |
| conversation.assistant_id = undefined; |
| } |
|
|
| const models = modelsConfig?.[defaultEndpoint ?? ''] ?? []; |
| conversation = buildDefaultConvo({ |
| conversation, |
| lastConversationSetup: preset as TConversation, |
| endpoint: defaultEndpoint ?? ('' as EModelEndpoint), |
| models, |
| }); |
|
|
| if (preset?.title != null && preset.title !== '') { |
| conversation.title = preset.title; |
| } |
|
|
| if (setConversation) { |
| setConversation(conversation); |
| } |
|
|
| clearTimeout(timeoutIdRef.current); |
| timeoutIdRef.current = setTimeout(() => { |
| const textarea = document.getElementById(mainTextareaId); |
| if (textarea) { |
| textarea.focus(); |
| } |
| }, 150); |
| return conversation; |
| }, |
| [assistantsListMap, endpointsConfig, index, modelsQuery.data, rootConvo, setConversation], |
| ); |
|
|
| return { generateConversation }; |
| }; |
|
|
| export default useGenerateConvo; |
|
|