2023-06-30 11:10:59 +03:00
|
|
|
/* eslint-disable max-lines */
|
|
|
|
|
2023-08-18 11:32:22 +03:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2023-08-07 15:13:41 +03:00
|
|
|
|
2023-08-18 11:32:22 +03:00
|
|
|
import { useBrainContext } from '@/lib/context/BrainProvider/hooks/useBrainContext';
|
|
|
|
import { useChatContext } from '@/lib/context/ChatProvider/hooks/useChatContext';
|
|
|
|
import { useFetch } from '@/lib/hooks';
|
2023-06-22 18:50:06 +03:00
|
|
|
|
2023-08-18 11:32:22 +03:00
|
|
|
import { ChatHistory, ChatQuestion } from '../types';
|
2023-06-22 18:50:06 +03:00
|
|
|
|
2023-06-30 11:10:59 +03:00
|
|
|
interface UseChatService {
|
|
|
|
addStreamQuestion: (
|
|
|
|
chatId: string,
|
|
|
|
chatQuestion: ChatQuestion
|
|
|
|
) => Promise<void>;
|
|
|
|
}
|
|
|
|
|
2023-07-05 19:33:18 +03:00
|
|
|
export const useQuestion = (): UseChatService => {
|
2023-06-30 11:10:59 +03:00
|
|
|
const { fetchInstance } = useFetch();
|
2023-08-11 11:06:20 +03:00
|
|
|
const { updateStreamingHistory } = useChatContext();
|
2023-06-28 20:39:27 +03:00
|
|
|
const { currentBrain } = useBrainContext();
|
2023-06-22 18:50:06 +03:00
|
|
|
|
2023-08-18 11:32:22 +03:00
|
|
|
const { t } = useTranslation(['chat']);
|
2023-06-30 11:10:59 +03:00
|
|
|
|
|
|
|
const handleStream = async (
|
|
|
|
reader: ReadableStreamDefaultReader<Uint8Array>
|
|
|
|
): Promise<void> => {
|
2023-08-18 11:32:22 +03:00
|
|
|
const decoder = new TextDecoder('utf-8');
|
2023-06-30 11:10:59 +03:00
|
|
|
|
|
|
|
const handleStreamRecursively = async () => {
|
|
|
|
const { done, value } = await reader.read();
|
|
|
|
|
|
|
|
if (done) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const dataStrings = decoder
|
|
|
|
.decode(value)
|
|
|
|
.trim()
|
2023-08-18 11:32:22 +03:00
|
|
|
.split('data: ')
|
2023-06-30 11:10:59 +03:00
|
|
|
.filter(Boolean);
|
|
|
|
|
|
|
|
dataStrings.forEach((data) => {
|
|
|
|
try {
|
|
|
|
const parsedData = JSON.parse(data) as ChatHistory;
|
|
|
|
updateStreamingHistory(parsedData);
|
|
|
|
} catch (error) {
|
2023-08-18 11:32:22 +03:00
|
|
|
console.error(t('errorParsingData', { ns: 'chat' }), error);
|
2023-06-30 11:10:59 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
await handleStreamRecursively();
|
|
|
|
};
|
|
|
|
|
|
|
|
await handleStreamRecursively();
|
|
|
|
};
|
|
|
|
|
|
|
|
const addStreamQuestion = async (
|
2023-06-22 18:50:06 +03:00
|
|
|
chatId: string,
|
|
|
|
chatQuestion: ChatQuestion
|
2023-06-30 11:10:59 +03:00
|
|
|
): Promise<void> => {
|
|
|
|
const headers = {
|
2023-08-18 11:32:22 +03:00
|
|
|
'Content-Type': 'application/json',
|
|
|
|
Accept: 'text/event-stream',
|
2023-06-30 11:10:59 +03:00
|
|
|
};
|
|
|
|
const body = JSON.stringify(chatQuestion);
|
2023-08-18 11:32:22 +03:00
|
|
|
console.log('Calling API...');
|
2023-06-30 11:10:59 +03:00
|
|
|
try {
|
|
|
|
const response = await fetchInstance.post(
|
2023-08-18 11:32:22 +03:00
|
|
|
`/chat/${chatId}/question/stream?brain_id=${currentBrain?.id ?? ''}`,
|
2023-06-30 11:10:59 +03:00
|
|
|
body,
|
|
|
|
headers
|
|
|
|
);
|
|
|
|
|
|
|
|
if (response.body === null) {
|
2023-08-18 11:32:22 +03:00
|
|
|
throw new Error(t('resposeBodyNull', { ns: 'chat' }));
|
2023-06-30 11:10:59 +03:00
|
|
|
}
|
|
|
|
|
2023-08-18 11:32:22 +03:00
|
|
|
console.log(t('receivedResponse'), response);
|
2023-06-30 11:10:59 +03:00
|
|
|
await handleStream(response.body.getReader());
|
|
|
|
} catch (error) {
|
2023-08-18 11:32:22 +03:00
|
|
|
console.error(t('errorCallingAPI', { ns: 'chat' }), error);
|
2023-06-30 11:10:59 +03:00
|
|
|
}
|
2023-06-22 18:50:06 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
2023-06-30 11:10:59 +03:00
|
|
|
addStreamQuestion,
|
2023-06-22 18:50:06 +03:00
|
|
|
};
|
|
|
|
};
|