2024-02-22 17:14:25 +08:00
|
|
|
import { MessageType } from '@/constants/chat';
|
2024-02-27 19:05:50 +08:00
|
|
|
import { fileIconMap } from '@/constants/common';
|
2024-04-09 19:01:57 +08:00
|
|
|
import {
|
2024-08-27 14:45:17 +08:00
|
|
|
useFetchManualConversation,
|
|
|
|
useFetchManualDialog,
|
|
|
|
useFetchNextConversation,
|
|
|
|
useFetchNextConversationList,
|
|
|
|
useFetchNextDialog,
|
|
|
|
useGetChatSearchParams,
|
|
|
|
useRemoveNextConversation,
|
|
|
|
useRemoveNextDialog,
|
|
|
|
useSetNextDialog,
|
|
|
|
useUpdateNextConversation,
|
2024-07-17 19:07:34 +08:00
|
|
|
} from '@/hooks/chat-hooks';
|
2024-04-19 16:55:23 +08:00
|
|
|
import {
|
|
|
|
useSetModalState,
|
|
|
|
useShowDeleteConfirm,
|
|
|
|
useTranslate,
|
2024-07-17 19:07:34 +08:00
|
|
|
} from '@/hooks/common-hooks';
|
2024-07-17 17:08:24 +08:00
|
|
|
import { useSendMessageWithSse } from '@/hooks/logic-hooks';
|
2024-08-15 09:19:17 +08:00
|
|
|
import {
|
|
|
|
IAnswer,
|
|
|
|
IConversation,
|
|
|
|
IDialog,
|
|
|
|
Message,
|
|
|
|
} from '@/interfaces/database/chat';
|
2024-03-05 16:30:28 +08:00
|
|
|
import { IChunk } from '@/interfaces/database/knowledge';
|
2024-02-27 19:05:50 +08:00
|
|
|
import { getFileExtension } from '@/utils';
|
2024-08-29 11:24:27 +08:00
|
|
|
import { buildMessageUuid } from '@/utils/chat';
|
2024-08-27 14:45:17 +08:00
|
|
|
import { useMutationState } from '@tanstack/react-query';
|
|
|
|
import { get } from 'lodash';
|
2024-06-24 18:23:22 +08:00
|
|
|
import trim from 'lodash/trim';
|
2024-03-19 19:21:35 +08:00
|
|
|
import {
|
|
|
|
ChangeEventHandler,
|
|
|
|
useCallback,
|
|
|
|
useEffect,
|
|
|
|
useMemo,
|
|
|
|
useRef,
|
|
|
|
useState,
|
|
|
|
} from 'react';
|
2024-08-27 14:45:17 +08:00
|
|
|
import { useSearchParams } from 'umi';
|
2024-02-22 17:14:25 +08:00
|
|
|
import { v4 as uuid } from 'uuid';
|
2024-03-06 19:17:45 +08:00
|
|
|
import { ChatSearchParams } from './constants';
|
2024-02-22 17:14:25 +08:00
|
|
|
import {
|
|
|
|
IClientConversation,
|
|
|
|
IMessage,
|
|
|
|
VariableTableDataType,
|
|
|
|
} from './interface';
|
2024-02-20 18:10:20 +08:00
|
|
|
|
2024-03-11 16:13:34 +08:00
|
|
|
export const useSelectCurrentDialog = () => {
|
2024-08-27 14:45:17 +08:00
|
|
|
const data = useMutationState({
|
|
|
|
filters: { mutationKey: ['fetchDialog'] },
|
|
|
|
select: (mutation) => {
|
|
|
|
return get(mutation, 'state.data.data', {});
|
2024-02-22 17:14:25 +08:00
|
|
|
},
|
2024-08-27 14:45:17 +08:00
|
|
|
});
|
2024-02-22 17:14:25 +08:00
|
|
|
|
2024-08-27 14:45:17 +08:00
|
|
|
return (data.at(-1) ?? {}) as IDialog;
|
2024-02-22 17:14:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
export const useSelectPromptConfigParameters = (): VariableTableDataType[] => {
|
2024-08-27 14:45:17 +08:00
|
|
|
const { data: currentDialog } = useFetchNextDialog();
|
2024-02-22 17:14:25 +08:00
|
|
|
|
|
|
|
const finalParameters: VariableTableDataType[] = useMemo(() => {
|
|
|
|
const parameters = currentDialog?.prompt_config?.parameters ?? [];
|
|
|
|
if (!currentDialog.id) {
|
|
|
|
// The newly created chat has a default parameter
|
|
|
|
return [{ key: uuid(), variable: 'knowledge', optional: false }];
|
|
|
|
}
|
|
|
|
return parameters.map((x) => ({
|
|
|
|
key: uuid(),
|
|
|
|
variable: x.key,
|
|
|
|
optional: x.optional,
|
|
|
|
}));
|
|
|
|
}, [currentDialog]);
|
|
|
|
|
|
|
|
return finalParameters;
|
|
|
|
};
|
|
|
|
|
2024-04-09 19:01:57 +08:00
|
|
|
export const useDeleteDialog = () => {
|
2024-04-02 15:44:09 +08:00
|
|
|
const showDeleteConfirm = useShowDeleteConfirm();
|
2024-02-22 17:14:25 +08:00
|
|
|
|
2024-08-27 14:45:17 +08:00
|
|
|
const { removeDialog } = useRemoveNextDialog();
|
2024-02-22 17:14:25 +08:00
|
|
|
|
|
|
|
const onRemoveDialog = (dialogIds: Array<string>) => {
|
2024-08-27 14:45:17 +08:00
|
|
|
showDeleteConfirm({ onOk: () => removeDialog(dialogIds) });
|
2024-02-22 17:14:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
return { onRemoveDialog };
|
|
|
|
};
|
|
|
|
|
2024-02-28 16:28:33 +08:00
|
|
|
export const useHandleItemHover = () => {
|
|
|
|
const [activated, setActivated] = useState<string>('');
|
|
|
|
|
|
|
|
const handleItemEnter = (id: string) => {
|
|
|
|
setActivated(id);
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleItemLeave = () => {
|
|
|
|
setActivated('');
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
activated,
|
|
|
|
handleItemEnter,
|
|
|
|
handleItemLeave,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-03-11 16:13:34 +08:00
|
|
|
export const useEditDialog = () => {
|
|
|
|
const [dialog, setDialog] = useState<IDialog>({} as IDialog);
|
2024-08-27 14:45:17 +08:00
|
|
|
const { fetchDialog } = useFetchManualDialog();
|
|
|
|
const { setDialog: submitDialog, loading } = useSetNextDialog();
|
2024-03-11 16:13:34 +08:00
|
|
|
|
|
|
|
const {
|
|
|
|
visible: dialogEditVisible,
|
|
|
|
hideModal: hideDialogEditModal,
|
|
|
|
showModal: showDialogEditModal,
|
|
|
|
} = useSetModalState();
|
|
|
|
|
2024-08-07 10:19:14 +08:00
|
|
|
const hideModal = useCallback(() => {
|
|
|
|
setDialog({} as IDialog);
|
|
|
|
hideDialogEditModal();
|
|
|
|
}, [hideDialogEditModal]);
|
|
|
|
|
2024-03-11 16:13:34 +08:00
|
|
|
const onDialogEditOk = useCallback(
|
|
|
|
async (dialog: IDialog) => {
|
|
|
|
const ret = await submitDialog(dialog);
|
|
|
|
|
|
|
|
if (ret === 0) {
|
2024-08-07 10:19:14 +08:00
|
|
|
hideModal();
|
2024-03-11 16:13:34 +08:00
|
|
|
}
|
|
|
|
},
|
2024-08-07 10:19:14 +08:00
|
|
|
[submitDialog, hideModal],
|
2024-03-11 16:13:34 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
const handleShowDialogEditModal = useCallback(
|
|
|
|
async (dialogId?: string) => {
|
|
|
|
if (dialogId) {
|
2024-08-27 14:45:17 +08:00
|
|
|
const ret = await fetchDialog(dialogId);
|
2024-03-11 16:13:34 +08:00
|
|
|
if (ret.retcode === 0) {
|
|
|
|
setDialog(ret.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
showDialogEditModal();
|
|
|
|
},
|
|
|
|
[showDialogEditModal, fetchDialog],
|
|
|
|
);
|
|
|
|
|
|
|
|
const clearDialog = useCallback(() => {
|
|
|
|
setDialog({} as IDialog);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
return {
|
|
|
|
dialogSettingLoading: loading,
|
|
|
|
initialDialog: dialog,
|
|
|
|
onDialogEditOk,
|
|
|
|
dialogEditVisible,
|
2024-08-07 10:19:14 +08:00
|
|
|
hideDialogEditModal: hideModal,
|
2024-03-11 16:13:34 +08:00
|
|
|
showDialogEditModal: handleShowDialogEditModal,
|
|
|
|
clearDialog,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-02-22 17:14:25 +08:00
|
|
|
//#region conversation
|
|
|
|
|
2024-04-09 19:01:57 +08:00
|
|
|
export const useSelectDerivedConversationList = () => {
|
2024-08-27 14:45:17 +08:00
|
|
|
const { t } = useTranslate('chat');
|
|
|
|
|
2024-02-26 18:38:54 +08:00
|
|
|
const [list, setList] = useState<Array<IConversation>>([]);
|
2024-08-27 14:45:17 +08:00
|
|
|
const { data: currentDialog } = useFetchNextDialog();
|
|
|
|
const { data: conversationList, loading } = useFetchNextConversationList();
|
2024-02-26 18:38:54 +08:00
|
|
|
const { dialogId } = useGetChatSearchParams();
|
|
|
|
const prologue = currentDialog?.prompt_config?.prologue ?? '';
|
2024-08-27 14:45:17 +08:00
|
|
|
|
2024-02-26 18:38:54 +08:00
|
|
|
const addTemporaryConversation = useCallback(() => {
|
2024-03-08 19:33:33 +08:00
|
|
|
setList((pre) => {
|
|
|
|
if (dialogId) {
|
|
|
|
const nextList = [
|
|
|
|
{
|
|
|
|
id: '',
|
2024-07-09 10:43:52 +08:00
|
|
|
name: t('newConversation'),
|
2024-03-08 19:33:33 +08:00
|
|
|
dialog_id: dialogId,
|
|
|
|
message: [
|
|
|
|
{
|
|
|
|
content: prologue,
|
|
|
|
role: MessageType.Assistant,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
} as IConversation,
|
|
|
|
...conversationList,
|
|
|
|
];
|
|
|
|
return nextList;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pre;
|
2024-02-26 18:38:54 +08:00
|
|
|
});
|
2024-07-17 14:49:11 +08:00
|
|
|
}, [conversationList, dialogId, prologue, t]);
|
2024-02-26 18:38:54 +08:00
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
addTemporaryConversation();
|
|
|
|
}, [addTemporaryConversation]);
|
|
|
|
|
2024-08-27 14:45:17 +08:00
|
|
|
return { list, addTemporaryConversation, loading };
|
2024-02-26 18:38:54 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
export const useClickConversationCard = () => {
|
|
|
|
const [currentQueryParameters, setSearchParams] = useSearchParams();
|
|
|
|
const newQueryParameters: URLSearchParams = useMemo(
|
|
|
|
() => new URLSearchParams(currentQueryParameters.toString()),
|
|
|
|
[currentQueryParameters],
|
|
|
|
);
|
|
|
|
|
|
|
|
const handleClickConversation = useCallback(
|
|
|
|
(conversationId: string) => {
|
|
|
|
newQueryParameters.set(ChatSearchParams.ConversationId, conversationId);
|
|
|
|
setSearchParams(newQueryParameters);
|
|
|
|
},
|
|
|
|
[newQueryParameters, setSearchParams],
|
|
|
|
);
|
|
|
|
|
|
|
|
return { handleClickConversation };
|
|
|
|
};
|
|
|
|
|
2024-02-22 17:14:25 +08:00
|
|
|
export const useSetConversation = () => {
|
|
|
|
const { dialogId } = useGetChatSearchParams();
|
2024-08-27 14:45:17 +08:00
|
|
|
const { updateConversation } = useUpdateNextConversation();
|
2024-02-22 17:14:25 +08:00
|
|
|
|
2024-02-29 14:26:59 +08:00
|
|
|
const setConversation = useCallback(
|
|
|
|
(message: string) => {
|
2024-04-09 19:01:57 +08:00
|
|
|
return updateConversation({
|
|
|
|
dialog_id: dialogId,
|
|
|
|
name: message,
|
|
|
|
message: [
|
|
|
|
{
|
|
|
|
role: MessageType.Assistant,
|
|
|
|
content: message,
|
|
|
|
},
|
|
|
|
],
|
2024-02-29 14:26:59 +08:00
|
|
|
});
|
|
|
|
},
|
2024-04-09 19:01:57 +08:00
|
|
|
[updateConversation, dialogId],
|
2024-02-29 14:26:59 +08:00
|
|
|
);
|
2024-02-22 17:14:25 +08:00
|
|
|
|
|
|
|
return { setConversation };
|
|
|
|
};
|
|
|
|
|
2024-02-28 16:28:33 +08:00
|
|
|
export const useSelectCurrentConversation = () => {
|
2024-02-29 14:26:59 +08:00
|
|
|
const [currentConversation, setCurrentConversation] =
|
|
|
|
useState<IClientConversation>({} as IClientConversation);
|
2024-08-27 14:45:17 +08:00
|
|
|
const { data: conversation, loading } = useFetchNextConversation();
|
|
|
|
const { data: dialog } = useFetchNextDialog();
|
2024-03-06 19:17:45 +08:00
|
|
|
const { conversationId, dialogId } = useGetChatSearchParams();
|
2024-02-22 17:14:25 +08:00
|
|
|
|
2024-08-29 11:24:27 +08:00
|
|
|
// Show the entered message in the conversation immediately after sending the message
|
2024-05-16 20:15:02 +08:00
|
|
|
const addNewestConversation = useCallback(
|
2024-08-29 11:24:27 +08:00
|
|
|
(message: Message, answer: string = '') => {
|
2024-05-16 20:15:02 +08:00
|
|
|
setCurrentConversation((pre) => {
|
|
|
|
return {
|
|
|
|
...pre,
|
|
|
|
message: [
|
|
|
|
...pre.message,
|
|
|
|
{
|
2024-08-29 11:24:27 +08:00
|
|
|
...message,
|
|
|
|
id: buildMessageUuid(message),
|
2024-05-16 20:15:02 +08:00
|
|
|
} as IMessage,
|
|
|
|
{
|
|
|
|
role: MessageType.Assistant,
|
|
|
|
content: answer,
|
2024-08-29 11:24:27 +08:00
|
|
|
id: buildMessageUuid({ ...message, role: MessageType.Assistant }),
|
2024-07-17 14:49:11 +08:00
|
|
|
reference: {},
|
2024-05-16 20:15:02 +08:00
|
|
|
} as IMessage,
|
|
|
|
],
|
|
|
|
};
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
|
2024-08-29 11:24:27 +08:00
|
|
|
// Add the streaming message to the last item in the message list
|
2024-05-16 20:15:02 +08:00
|
|
|
const addNewestAnswer = useCallback((answer: IAnswer) => {
|
2024-02-29 14:26:59 +08:00
|
|
|
setCurrentConversation((pre) => {
|
2024-05-16 20:15:02 +08:00
|
|
|
const latestMessage = pre.message?.at(-1);
|
|
|
|
|
|
|
|
if (latestMessage) {
|
|
|
|
return {
|
|
|
|
...pre,
|
|
|
|
message: [
|
|
|
|
...pre.message.slice(0, -1),
|
|
|
|
{
|
|
|
|
...latestMessage,
|
|
|
|
content: answer.answer,
|
|
|
|
reference: answer.reference,
|
2024-08-29 11:24:27 +08:00
|
|
|
id: buildMessageUuid({
|
|
|
|
id: answer.id,
|
|
|
|
role: MessageType.Assistant,
|
|
|
|
}),
|
|
|
|
prompt: answer.prompt,
|
2024-05-16 20:15:02 +08:00
|
|
|
} as IMessage,
|
|
|
|
],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
return pre;
|
2024-02-29 14:26:59 +08:00
|
|
|
});
|
|
|
|
}, []);
|
|
|
|
|
2024-03-19 19:21:35 +08:00
|
|
|
const removeLatestMessage = useCallback(() => {
|
|
|
|
setCurrentConversation((pre) => {
|
2024-05-16 20:15:02 +08:00
|
|
|
const nextMessages = pre.message?.slice(0, -2) ?? [];
|
2024-03-19 19:21:35 +08:00
|
|
|
return {
|
|
|
|
...pre,
|
|
|
|
message: nextMessages,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}, []);
|
|
|
|
|
2024-03-05 12:01:48 +08:00
|
|
|
const addPrologue = useCallback(() => {
|
2024-03-08 19:33:33 +08:00
|
|
|
if (dialogId !== '' && conversationId === '') {
|
2024-03-05 12:01:48 +08:00
|
|
|
const prologue = dialog.prompt_config?.prologue;
|
|
|
|
|
|
|
|
const nextMessage = {
|
|
|
|
role: MessageType.Assistant,
|
|
|
|
content: prologue,
|
|
|
|
id: uuid(),
|
|
|
|
} as IMessage;
|
|
|
|
|
|
|
|
setCurrentConversation({
|
|
|
|
id: '',
|
2024-03-06 19:17:45 +08:00
|
|
|
dialog_id: dialogId,
|
2024-03-05 12:01:48 +08:00
|
|
|
reference: [],
|
|
|
|
message: [nextMessage],
|
|
|
|
} as any);
|
|
|
|
}
|
2024-03-06 19:17:45 +08:00
|
|
|
}, [conversationId, dialog, dialogId]);
|
2024-02-29 14:26:59 +08:00
|
|
|
|
|
|
|
useEffect(() => {
|
2024-03-05 12:01:48 +08:00
|
|
|
addPrologue();
|
|
|
|
}, [addPrologue]);
|
2024-02-29 14:26:59 +08:00
|
|
|
|
2024-03-05 12:01:48 +08:00
|
|
|
useEffect(() => {
|
2024-04-09 19:01:57 +08:00
|
|
|
if (conversationId) {
|
|
|
|
setCurrentConversation(conversation);
|
|
|
|
}
|
|
|
|
}, [conversation, conversationId]);
|
2024-02-29 14:26:59 +08:00
|
|
|
|
2024-05-16 20:15:02 +08:00
|
|
|
return {
|
|
|
|
currentConversation,
|
|
|
|
addNewestConversation,
|
|
|
|
removeLatestMessage,
|
|
|
|
addNewestAnswer,
|
2024-08-27 14:45:17 +08:00
|
|
|
loading,
|
2024-05-16 20:15:02 +08:00
|
|
|
};
|
2024-02-28 16:28:33 +08:00
|
|
|
};
|
|
|
|
|
2024-02-29 14:26:59 +08:00
|
|
|
export const useScrollToBottom = (currentConversation: IClientConversation) => {
|
|
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
|
|
|
|
|
|
const scrollToBottom = useCallback(() => {
|
|
|
|
if (currentConversation.id) {
|
|
|
|
ref.current?.scrollIntoView({ behavior: 'instant' });
|
|
|
|
}
|
|
|
|
}, [currentConversation]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
scrollToBottom();
|
|
|
|
}, [scrollToBottom]);
|
|
|
|
|
|
|
|
return ref;
|
|
|
|
};
|
|
|
|
|
2024-02-28 16:28:33 +08:00
|
|
|
export const useFetchConversationOnMount = () => {
|
|
|
|
const { conversationId } = useGetChatSearchParams();
|
2024-05-16 20:15:02 +08:00
|
|
|
const {
|
|
|
|
currentConversation,
|
|
|
|
addNewestConversation,
|
|
|
|
removeLatestMessage,
|
|
|
|
addNewestAnswer,
|
2024-08-27 14:45:17 +08:00
|
|
|
loading,
|
2024-05-16 20:15:02 +08:00
|
|
|
} = useSelectCurrentConversation();
|
2024-02-29 14:26:59 +08:00
|
|
|
const ref = useScrollToBottom(currentConversation);
|
2024-02-28 16:28:33 +08:00
|
|
|
|
2024-03-19 19:21:35 +08:00
|
|
|
return {
|
|
|
|
currentConversation,
|
|
|
|
addNewestConversation,
|
|
|
|
ref,
|
|
|
|
removeLatestMessage,
|
2024-05-16 20:15:02 +08:00
|
|
|
addNewestAnswer,
|
2024-08-22 18:01:48 +08:00
|
|
|
conversationId,
|
2024-08-27 14:45:17 +08:00
|
|
|
loading,
|
2024-03-19 19:21:35 +08:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export const useHandleMessageInputChange = () => {
|
|
|
|
const [value, setValue] = useState('');
|
|
|
|
|
|
|
|
const handleInputChange: ChangeEventHandler<HTMLInputElement> = (e) => {
|
|
|
|
const value = e.target.value;
|
|
|
|
const nextValue = value.replaceAll('\\n', '\n').replaceAll('\\t', '\t');
|
2024-06-28 17:32:38 +08:00
|
|
|
setValue(nextValue);
|
2024-03-19 19:21:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
handleInputChange,
|
|
|
|
value,
|
|
|
|
setValue,
|
|
|
|
};
|
2024-02-22 17:14:25 +08:00
|
|
|
};
|
|
|
|
|
2024-03-19 19:21:35 +08:00
|
|
|
export const useSendMessage = (
|
|
|
|
conversation: IClientConversation,
|
2024-08-15 09:19:17 +08:00
|
|
|
addNewestConversation: (message: Partial<Message>, answer?: string) => void,
|
2024-03-19 19:21:35 +08:00
|
|
|
removeLatestMessage: () => void,
|
2024-05-16 20:15:02 +08:00
|
|
|
addNewestAnswer: (answer: IAnswer) => void,
|
2024-03-19 19:21:35 +08:00
|
|
|
) => {
|
2024-02-22 17:14:25 +08:00
|
|
|
const { setConversation } = useSetConversation();
|
|
|
|
const { conversationId } = useGetChatSearchParams();
|
2024-03-19 19:21:35 +08:00
|
|
|
const { handleInputChange, value, setValue } = useHandleMessageInputChange();
|
2024-04-09 19:01:57 +08:00
|
|
|
|
2024-02-22 17:14:25 +08:00
|
|
|
const { handleClickConversation } = useClickConversationCard();
|
2024-07-17 17:08:24 +08:00
|
|
|
const { send, answer, done, setDone } = useSendMessageWithSse();
|
2024-02-22 17:14:25 +08:00
|
|
|
|
2024-02-29 14:26:59 +08:00
|
|
|
const sendMessage = useCallback(
|
2024-08-29 11:24:27 +08:00
|
|
|
async (message: Message, documentIds: string[], id?: string) => {
|
2024-06-11 18:01:19 +08:00
|
|
|
const res = await send({
|
2024-04-09 19:01:57 +08:00
|
|
|
conversation_id: id ?? conversationId,
|
|
|
|
messages: [
|
2024-08-29 11:24:27 +08:00
|
|
|
...(conversation?.message ?? []),
|
2024-04-09 19:01:57 +08:00
|
|
|
{
|
2024-08-29 11:24:27 +08:00
|
|
|
...message,
|
2024-08-14 17:26:47 +08:00
|
|
|
doc_ids: documentIds,
|
2024-04-09 19:01:57 +08:00
|
|
|
},
|
|
|
|
],
|
2024-02-29 14:26:59 +08:00
|
|
|
});
|
2024-03-05 19:28:44 +08:00
|
|
|
|
2024-06-11 18:01:19 +08:00
|
|
|
if (res && (res?.response.status !== 200 || res?.data?.retcode !== 0)) {
|
|
|
|
// cancel loading
|
2024-08-29 11:24:27 +08:00
|
|
|
setValue(message.content);
|
2024-06-11 18:01:19 +08:00
|
|
|
console.info('removeLatestMessage111');
|
|
|
|
removeLatestMessage();
|
|
|
|
} else {
|
2024-03-05 19:28:44 +08:00
|
|
|
if (id) {
|
2024-05-16 20:15:02 +08:00
|
|
|
console.info('111');
|
2024-03-19 19:21:35 +08:00
|
|
|
// new conversation
|
2024-03-05 19:28:44 +08:00
|
|
|
handleClickConversation(id);
|
|
|
|
} else {
|
2024-05-16 20:15:02 +08:00
|
|
|
console.info('222');
|
|
|
|
// fetchConversation(conversationId);
|
2024-03-05 19:28:44 +08:00
|
|
|
}
|
|
|
|
}
|
2024-02-29 14:26:59 +08:00
|
|
|
},
|
2024-03-05 19:28:44 +08:00
|
|
|
[
|
|
|
|
conversation?.message,
|
|
|
|
conversationId,
|
|
|
|
handleClickConversation,
|
2024-03-19 19:21:35 +08:00
|
|
|
removeLatestMessage,
|
|
|
|
setValue,
|
2024-05-16 20:15:02 +08:00
|
|
|
send,
|
2024-03-05 19:28:44 +08:00
|
|
|
],
|
2024-02-29 14:26:59 +08:00
|
|
|
);
|
2024-02-22 17:14:25 +08:00
|
|
|
|
2024-02-29 14:26:59 +08:00
|
|
|
const handleSendMessage = useCallback(
|
2024-08-29 11:24:27 +08:00
|
|
|
async (message: Message, documentIds: string[]) => {
|
2024-02-29 14:26:59 +08:00
|
|
|
if (conversationId !== '') {
|
2024-08-15 09:19:17 +08:00
|
|
|
sendMessage(message, documentIds);
|
2024-02-29 14:26:59 +08:00
|
|
|
} else {
|
2024-08-29 11:24:27 +08:00
|
|
|
const data = await setConversation(message.content);
|
2024-02-29 14:26:59 +08:00
|
|
|
if (data.retcode === 0) {
|
|
|
|
const id = data.data.id;
|
2024-08-15 09:19:17 +08:00
|
|
|
sendMessage(message, documentIds, id);
|
2024-02-29 14:26:59 +08:00
|
|
|
}
|
2024-02-22 17:14:25 +08:00
|
|
|
}
|
2024-02-29 14:26:59 +08:00
|
|
|
},
|
2024-03-05 19:28:44 +08:00
|
|
|
[conversationId, setConversation, sendMessage],
|
2024-02-29 14:26:59 +08:00
|
|
|
);
|
2024-02-22 17:14:25 +08:00
|
|
|
|
2024-05-16 20:15:02 +08:00
|
|
|
useEffect(() => {
|
2024-07-17 17:08:24 +08:00
|
|
|
// #1289
|
2024-07-17 14:49:11 +08:00
|
|
|
if (answer.answer && answer?.conversationId === conversationId) {
|
2024-05-16 20:15:02 +08:00
|
|
|
addNewestAnswer(answer);
|
|
|
|
}
|
2024-07-17 14:49:11 +08:00
|
|
|
}, [answer, addNewestAnswer, conversationId]);
|
2024-05-16 20:15:02 +08:00
|
|
|
|
2024-07-17 17:08:24 +08:00
|
|
|
useEffect(() => {
|
|
|
|
// #1289 switch to another conversion window when the last conversion answer doesn't finish.
|
|
|
|
if (conversationId) {
|
|
|
|
setDone(true);
|
|
|
|
}
|
|
|
|
}, [setDone, conversationId]);
|
|
|
|
|
2024-08-14 17:26:47 +08:00
|
|
|
const handlePressEnter = useCallback(
|
2024-08-15 09:19:17 +08:00
|
|
|
(documentIds: string[]) => {
|
2024-08-14 17:26:47 +08:00
|
|
|
if (trim(value) === '') return;
|
2024-08-29 11:24:27 +08:00
|
|
|
const id = uuid();
|
2024-08-15 09:19:17 +08:00
|
|
|
|
2024-08-29 11:24:27 +08:00
|
|
|
addNewestConversation({
|
|
|
|
content: value,
|
|
|
|
doc_ids: documentIds,
|
|
|
|
id,
|
|
|
|
role: MessageType.User,
|
|
|
|
});
|
2024-08-14 17:26:47 +08:00
|
|
|
if (done) {
|
|
|
|
setValue('');
|
2024-08-29 11:24:27 +08:00
|
|
|
handleSendMessage(
|
|
|
|
{ id, content: value.trim(), role: MessageType.User },
|
|
|
|
documentIds,
|
|
|
|
);
|
2024-08-14 17:26:47 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
[addNewestConversation, handleSendMessage, done, setValue, value],
|
|
|
|
);
|
2024-03-19 19:21:35 +08:00
|
|
|
|
|
|
|
return {
|
|
|
|
handlePressEnter,
|
|
|
|
handleInputChange,
|
|
|
|
value,
|
2024-06-24 16:41:45 +08:00
|
|
|
setValue,
|
2024-05-16 20:15:02 +08:00
|
|
|
loading: !done,
|
2024-03-19 19:21:35 +08:00
|
|
|
};
|
2024-02-22 17:14:25 +08:00
|
|
|
};
|
|
|
|
|
2024-02-27 19:05:50 +08:00
|
|
|
export const useGetFileIcon = () => {
|
|
|
|
const getFileIcon = (filename: string) => {
|
|
|
|
const ext: string = getFileExtension(filename);
|
|
|
|
const iconPath = fileIconMap[ext as keyof typeof fileIconMap];
|
|
|
|
return `@/assets/svg/file-icon/${iconPath}`;
|
|
|
|
};
|
|
|
|
|
|
|
|
return getFileIcon;
|
|
|
|
};
|
|
|
|
|
2024-04-09 19:01:57 +08:00
|
|
|
export const useDeleteConversation = () => {
|
2024-02-28 16:28:33 +08:00
|
|
|
const { handleClickConversation } = useClickConversationCard();
|
2024-04-02 15:44:09 +08:00
|
|
|
const showDeleteConfirm = useShowDeleteConfirm();
|
2024-08-27 14:45:17 +08:00
|
|
|
const { removeConversation } = useRemoveNextConversation();
|
2024-02-28 16:28:33 +08:00
|
|
|
|
2024-04-09 19:01:57 +08:00
|
|
|
const deleteConversation = (conversationIds: Array<string>) => async () => {
|
2024-08-27 14:45:17 +08:00
|
|
|
const ret = await removeConversation(conversationIds);
|
2024-02-28 16:28:33 +08:00
|
|
|
if (ret === 0) {
|
|
|
|
handleClickConversation('');
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
};
|
|
|
|
|
|
|
|
const onRemoveConversation = (conversationIds: Array<string>) => {
|
2024-04-09 19:01:57 +08:00
|
|
|
showDeleteConfirm({ onOk: deleteConversation(conversationIds) });
|
2024-02-28 16:28:33 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
return { onRemoveConversation };
|
|
|
|
};
|
|
|
|
|
|
|
|
export const useRenameConversation = () => {
|
|
|
|
const [conversation, setConversation] = useState<IClientConversation>(
|
|
|
|
{} as IClientConversation,
|
|
|
|
);
|
2024-08-27 14:45:17 +08:00
|
|
|
const { fetchConversation } = useFetchManualConversation();
|
2024-02-28 16:28:33 +08:00
|
|
|
const {
|
|
|
|
visible: conversationRenameVisible,
|
|
|
|
hideModal: hideConversationRenameModal,
|
|
|
|
showModal: showConversationRenameModal,
|
|
|
|
} = useSetModalState();
|
2024-08-27 14:45:17 +08:00
|
|
|
const { updateConversation, loading } = useUpdateNextConversation();
|
2024-02-28 16:28:33 +08:00
|
|
|
|
|
|
|
const onConversationRenameOk = useCallback(
|
|
|
|
async (name: string) => {
|
2024-04-09 19:01:57 +08:00
|
|
|
const ret = await updateConversation({
|
|
|
|
...conversation,
|
|
|
|
conversation_id: conversation.id,
|
|
|
|
name,
|
2024-02-28 16:28:33 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
if (ret.retcode === 0) {
|
|
|
|
hideConversationRenameModal();
|
|
|
|
}
|
|
|
|
},
|
2024-04-09 19:01:57 +08:00
|
|
|
[updateConversation, conversation, hideConversationRenameModal],
|
2024-02-28 16:28:33 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
const handleShowConversationRenameModal = useCallback(
|
|
|
|
async (conversationId: string) => {
|
2024-08-27 14:45:17 +08:00
|
|
|
const ret = await fetchConversation(conversationId);
|
2024-02-28 16:28:33 +08:00
|
|
|
if (ret.retcode === 0) {
|
|
|
|
setConversation(ret.data);
|
|
|
|
}
|
|
|
|
showConversationRenameModal();
|
|
|
|
},
|
|
|
|
[showConversationRenameModal, fetchConversation],
|
|
|
|
);
|
|
|
|
|
|
|
|
return {
|
|
|
|
conversationRenameLoading: loading,
|
|
|
|
initialConversationName: conversation.name,
|
|
|
|
onConversationRenameOk,
|
|
|
|
conversationRenameVisible,
|
|
|
|
hideConversationRenameModal,
|
|
|
|
showConversationRenameModal: handleShowConversationRenameModal,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-03-05 16:30:28 +08:00
|
|
|
export const useClickDrawer = () => {
|
|
|
|
const { visible, showModal, hideModal } = useSetModalState();
|
|
|
|
const [selectedChunk, setSelectedChunk] = useState<IChunk>({} as IChunk);
|
|
|
|
const [documentId, setDocumentId] = useState<string>('');
|
|
|
|
|
|
|
|
const clickDocumentButton = useCallback(
|
|
|
|
(documentId: string, chunk: IChunk) => {
|
|
|
|
showModal();
|
|
|
|
setSelectedChunk(chunk);
|
|
|
|
setDocumentId(documentId);
|
|
|
|
},
|
|
|
|
[showModal],
|
|
|
|
);
|
|
|
|
|
|
|
|
return {
|
|
|
|
clickDocumentButton,
|
|
|
|
visible,
|
|
|
|
showModal,
|
|
|
|
hideModal,
|
|
|
|
selectedChunk,
|
|
|
|
documentId,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-03-20 11:13:51 +08:00
|
|
|
export const useGetSendButtonDisabled = () => {
|
|
|
|
const { dialogId, conversationId } = useGetChatSearchParams();
|
|
|
|
|
|
|
|
return dialogId === '' && conversationId === '';
|
|
|
|
};
|
2024-06-24 16:41:45 +08:00
|
|
|
|
|
|
|
export const useSendButtonDisabled = (value: string) => {
|
2024-06-24 18:23:22 +08:00
|
|
|
return trim(value) === '';
|
2024-06-24 16:41:45 +08:00
|
|
|
};
|
2024-08-22 18:01:48 +08:00
|
|
|
|
|
|
|
export const useCreateConversationBeforeUploadDocument = () => {
|
|
|
|
const { setConversation } = useSetConversation();
|
|
|
|
const { dialogId } = useGetChatSearchParams();
|
|
|
|
|
|
|
|
const { handleClickConversation } = useClickConversationCard();
|
|
|
|
|
|
|
|
const createConversationBeforeUploadDocument = useCallback(
|
|
|
|
async (message: string) => {
|
|
|
|
const data = await setConversation(message);
|
|
|
|
if (data.retcode === 0) {
|
|
|
|
const id = data.data.id;
|
|
|
|
handleClickConversation(id);
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
},
|
|
|
|
[setConversation, handleClickConversation],
|
|
|
|
);
|
|
|
|
|
|
|
|
return {
|
|
|
|
createConversationBeforeUploadDocument,
|
|
|
|
dialogId,
|
|
|
|
};
|
|
|
|
};
|
2024-02-22 17:14:25 +08:00
|
|
|
//#endregion
|