mirror of
https://github.com/StanGirard/quivr.git
synced 2024-12-25 20:32:11 +03:00
6f047f4a39
* feat: streaming for standard brain picking * fix(bug): private llm * wip: test Co-authored-by: Mamadou DICKO <mamadoudicko@users.noreply.github.com> * wip: almost good Co-authored-by: Mamadou DICKO <mamadoudicko@users.noreply.github.com> * feat: useFetch * chore: remove 💀 * chore: fix linting * fix: forward the request if not streaming * feat: streaming for standard brain picking * fix(bug): private llm * wip: test Co-authored-by: Mamadou DICKO <mamadoudicko@users.noreply.github.com> * wip: almost good Co-authored-by: Mamadou DICKO <mamadoudicko@users.noreply.github.com> * feat: useFetch * chore: remove 💀 * chore: fix linting * fix: forward the request if not streaming * fix: 💀 code * fix: check_user_limit * feat: brain_id to new chat stream * fix: missing imports * feat: message_id created on backend Co-authored-by: Mamadou DICKO <mamadoudicko@users.noreply.github.com> * chore: remove dead * remove: cpython * remove: dead --------- Co-authored-by: Mamadou DICKO <mamadoudicko@users.noreply.github.com>
138 lines
3.5 KiB
TypeScript
138 lines
3.5 KiB
TypeScript
/* eslint-disable max-lines */
|
|
|
|
import { useCallback } from "react";
|
|
|
|
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
|
import { useAxios, useFetch } from "@/lib/hooks";
|
|
|
|
import { useChatContext } from "../context/ChatContext";
|
|
import { ChatEntity, ChatHistory, ChatQuestion } from "../types";
|
|
|
|
interface UseChatService {
|
|
createChat: (name: { name: string }) => Promise<ChatEntity>;
|
|
getChatHistory: (chatId: string | undefined) => Promise<ChatHistory[]>;
|
|
addQuestion: (chatId: string, chatQuestion: ChatQuestion) => Promise<void>;
|
|
addStreamQuestion: (
|
|
chatId: string,
|
|
chatQuestion: ChatQuestion
|
|
) => Promise<void>;
|
|
}
|
|
|
|
export const useChatService = (): UseChatService => {
|
|
const { axiosInstance } = useAxios();
|
|
const { fetchInstance } = useFetch();
|
|
const { updateHistory, updateStreamingHistory } = useChatContext();
|
|
const { currentBrain } = useBrainContext();
|
|
const createChat = async ({
|
|
name,
|
|
}: {
|
|
name: string;
|
|
}): Promise<ChatEntity> => {
|
|
const response = (await axiosInstance.post<ChatEntity>(`/chat`, { name }))
|
|
.data;
|
|
|
|
return response;
|
|
};
|
|
|
|
const getChatHistory = useCallback(
|
|
async (chatId: string | undefined): Promise<ChatHistory[]> => {
|
|
if (chatId === undefined) {
|
|
return [];
|
|
}
|
|
const response = (
|
|
await axiosInstance.get<ChatHistory[]>(`/chat/${chatId}/history`)
|
|
).data;
|
|
|
|
return response;
|
|
},
|
|
[axiosInstance]
|
|
);
|
|
|
|
const addQuestion = async (
|
|
chatId: string,
|
|
chatQuestion: ChatQuestion
|
|
): Promise<void> => {
|
|
if (currentBrain?.id === undefined) {
|
|
throw new Error("No current brain");
|
|
}
|
|
|
|
const response = await axiosInstance.post<ChatHistory>(
|
|
`/chat/${chatId}/question?brain_id=${currentBrain.id}`,
|
|
chatQuestion
|
|
);
|
|
|
|
updateHistory(response.data);
|
|
};
|
|
|
|
const handleStream = async (
|
|
reader: ReadableStreamDefaultReader<Uint8Array>
|
|
): Promise<void> => {
|
|
const decoder = new TextDecoder("utf-8");
|
|
|
|
const handleStreamRecursively = async () => {
|
|
const { done, value } = await reader.read();
|
|
|
|
if (done) {
|
|
return;
|
|
}
|
|
|
|
const dataStrings = decoder
|
|
.decode(value)
|
|
.trim()
|
|
.split("data: ")
|
|
.filter(Boolean);
|
|
|
|
dataStrings.forEach((data) => {
|
|
try {
|
|
const parsedData = JSON.parse(data) as ChatHistory;
|
|
updateStreamingHistory(parsedData);
|
|
} catch (error) {
|
|
console.error("Error parsing data:", error);
|
|
}
|
|
});
|
|
|
|
await handleStreamRecursively();
|
|
};
|
|
|
|
await handleStreamRecursively();
|
|
};
|
|
|
|
const addStreamQuestion = async (
|
|
chatId: string,
|
|
chatQuestion: ChatQuestion
|
|
): Promise<void> => {
|
|
if (currentBrain?.id === undefined) {
|
|
throw new Error("No current brain");
|
|
}
|
|
const headers = {
|
|
"Content-Type": "application/json",
|
|
Accept: "text/event-stream",
|
|
};
|
|
const body = JSON.stringify(chatQuestion);
|
|
|
|
try {
|
|
const response = await fetchInstance.post(
|
|
`/chat/${chatId}/question/stream?brain_id=${currentBrain.id}`,
|
|
body,
|
|
headers
|
|
);
|
|
|
|
if (response.body === null) {
|
|
throw new Error("Response body is null");
|
|
}
|
|
|
|
console.log("Received response. Starting to handle stream...");
|
|
await handleStream(response.body.getReader());
|
|
} catch (error) {
|
|
console.error("Error calling the API:", error);
|
|
}
|
|
};
|
|
|
|
return {
|
|
createChat,
|
|
getChatHistory,
|
|
addQuestion,
|
|
addStreamQuestion,
|
|
};
|
|
};
|