2023-08-21 17:07:07 +03:00
|
|
|
import { useTranslation } from "react-i18next";
|
2023-08-07 15:13:41 +03:00
|
|
|
|
2023-11-30 14:49:04 +03:00
|
|
|
import { useChatContext } from "@/lib/context";
|
2023-08-21 17:07:07 +03:00
|
|
|
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
2023-08-22 11:05:52 +03:00
|
|
|
import { useFetch, useToast } from "@/lib/hooks";
|
2023-06-22 18:50:06 +03:00
|
|
|
|
2023-09-26 11:35:52 +03:00
|
|
|
import { useHandleStream } from "./useHandleStream";
|
2024-01-23 04:37:45 +03:00
|
|
|
|
2023-09-26 11:35:52 +03:00
|
|
|
import { ChatQuestion } from "../types";
|
2023-11-30 14:49:04 +03:00
|
|
|
import { generatePlaceHolderMessage } from "../utils/generatePlaceHolderMessage";
|
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-06-28 20:39:27 +03:00
|
|
|
const { currentBrain } = useBrainContext();
|
2023-06-22 18:50:06 +03:00
|
|
|
|
2023-08-21 17:07:07 +03:00
|
|
|
const { t } = useTranslation(["chat"]);
|
|
|
|
const { publish } = useToast();
|
2023-09-26 11:35:52 +03:00
|
|
|
const { handleStream } = useHandleStream();
|
2023-11-30 14:49:04 +03:00
|
|
|
const { removeMessage, updateStreamingHistory } = useChatContext();
|
2023-06-30 11:10:59 +03:00
|
|
|
|
2023-09-26 11:35:52 +03:00
|
|
|
const handleFetchError = async (response: Response) => {
|
|
|
|
if (response.status === 429) {
|
|
|
|
publish({
|
|
|
|
variant: "danger",
|
|
|
|
text: t("tooManyRequests", { ns: "chat" }),
|
2023-06-30 11:10:59 +03:00
|
|
|
});
|
|
|
|
|
2023-09-26 11:35:52 +03:00
|
|
|
return;
|
|
|
|
}
|
2023-06-30 11:10:59 +03:00
|
|
|
|
2023-09-26 11:35:52 +03:00
|
|
|
const errorMessage = (await response.json()) as { detail: string };
|
|
|
|
publish({
|
|
|
|
variant: "danger",
|
|
|
|
text: errorMessage.detail,
|
|
|
|
});
|
2023-06-30 11:10:59 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
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-21 17:07:07 +03:00
|
|
|
"Content-Type": "application/json",
|
|
|
|
Accept: "text/event-stream",
|
2023-06-30 11:10:59 +03:00
|
|
|
};
|
2023-11-30 14:49:04 +03:00
|
|
|
|
|
|
|
const placeHolderMessage = generatePlaceHolderMessage({
|
|
|
|
user_message: chatQuestion.question ?? "",
|
|
|
|
chat_id: chatId,
|
|
|
|
});
|
|
|
|
updateStreamingHistory(placeHolderMessage);
|
|
|
|
|
2023-06-30 11:10:59 +03:00
|
|
|
const body = JSON.stringify(chatQuestion);
|
2023-09-26 11:35:52 +03:00
|
|
|
|
2023-06-30 11:10:59 +03:00
|
|
|
try {
|
2024-02-15 01:01:35 +03:00
|
|
|
let url = `/chat/${chatId}/question/stream`;
|
|
|
|
if (currentBrain?.id) {
|
|
|
|
url += `?brain_id=${currentBrain.id}`;
|
|
|
|
}
|
|
|
|
const response = await fetchInstance.post(url, body, headers);
|
2023-09-26 11:35:52 +03:00
|
|
|
if (!response.ok) {
|
|
|
|
void handleFetchError(response);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2023-06-30 11:10:59 +03:00
|
|
|
|
|
|
|
if (response.body === null) {
|
2023-08-21 17:07:07 +03:00
|
|
|
throw new Error(t("resposeBodyNull", { ns: "chat" }));
|
2023-06-30 11:10:59 +03:00
|
|
|
}
|
|
|
|
|
2023-11-30 14:49:04 +03:00
|
|
|
await handleStream(response.body.getReader(), () =>
|
|
|
|
removeMessage(placeHolderMessage.message_id)
|
|
|
|
);
|
2023-06-30 11:10:59 +03:00
|
|
|
} catch (error) {
|
2023-09-26 11:35:52 +03:00
|
|
|
publish({
|
|
|
|
variant: "danger",
|
|
|
|
text: String(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
|
|
|
};
|
|
|
|
};
|