mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-29 13:46:18 +01:00
148 lines
4.4 KiB
TypeScript
148 lines
4.4 KiB
TypeScript
|
|
import { useRecoilValue } from 'recoil';
|
||
|
|
import { useCallback, useRef, useEffect } from 'react';
|
||
|
|
import { LocalStorageKeys, isAssistantsEndpoint } from 'librechat-data-provider';
|
||
|
|
import { useGetModelsQuery, useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
||
|
|
import type {
|
||
|
|
TPreset,
|
||
|
|
TModelsConfig,
|
||
|
|
TConversation,
|
||
|
|
TEndpointsConfig,
|
||
|
|
} from 'librechat-data-provider';
|
||
|
|
import type { SetterOrUpdater } from 'recoil';
|
||
|
|
import type { AssistantListItem } from '~/common';
|
||
|
|
import { getEndpointField, buildDefaultConvo, getDefaultEndpoint } from '~/utils';
|
||
|
|
import useAssistantListMap from '~/hooks/Assistants/useAssistantListMap';
|
||
|
|
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 && setConversation) {
|
||
|
|
setConversation((prevState) => {
|
||
|
|
if (!prevState) {
|
||
|
|
return prevState;
|
||
|
|
}
|
||
|
|
const update = {
|
||
|
|
...prevState,
|
||
|
|
conversationId: rootConvo.conversationId,
|
||
|
|
} as TConversation;
|
||
|
|
|
||
|
|
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 &&
|
||
|
|
isAssistantEndpoint &&
|
||
|
|
conversation.conversationId === 'new'
|
||
|
|
) {
|
||
|
|
const assistant = assistants.find((asst) => asst.id === conversation.assistant_id);
|
||
|
|
conversation.model = assistant?.model;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (conversation.assistant_id && !isAssistantEndpoint) {
|
||
|
|
conversation.assistant_id = undefined;
|
||
|
|
}
|
||
|
|
|
||
|
|
const models = modelsConfig?.[defaultEndpoint] ?? [];
|
||
|
|
conversation = buildDefaultConvo({
|
||
|
|
conversation,
|
||
|
|
lastConversationSetup: preset as TConversation,
|
||
|
|
endpoint: defaultEndpoint,
|
||
|
|
models,
|
||
|
|
});
|
||
|
|
|
||
|
|
if (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;
|