Skip to content

Commit 87601d2

Browse files
committed
added streaming to chat. fixed pdf reader
1 parent 10a4d2c commit 87601d2

10 files changed

Lines changed: 489 additions & 670 deletions

File tree

frontend/src/api/apiClient.ts

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ const handleSubmitFeedback = async (
4444

4545
const handleSendDrugSummary = async (message: FormValues["message"], guid: string) => {
4646
try {
47-
4847
const endpoint = guid ? `/v1/api/embeddings/ask_embeddings?guid=${guid}` : '/v1/api/embeddings/ask_embeddings';
4948
const response = await api.post(endpoint, {
5049
message,
@@ -57,6 +56,117 @@ const handleSendDrugSummary = async (message: FormValues["message"], guid: strin
5756
}
5857
};
5958

59+
interface StreamCallbacks {
60+
onContent?: (content: string) => void;
61+
onComplete?: (data: { embeddings_info: any[]; done: boolean }) => void;
62+
onError?: (error: string) => void;
63+
onMetadata?: (data: { question: string; embeddings_count: number }) => void;
64+
}
65+
66+
const handleSendDrugSummaryStream = async (
67+
message: string,
68+
guid: string,
69+
callbacks: StreamCallbacks
70+
): Promise<void> => {
71+
const token = localStorage.getItem("access");
72+
const endpoint = `/v1/api/embeddings/ask_embeddings?stream=true${
73+
guid ? `&guid=${guid}` : ""
74+
}`;
75+
76+
try {
77+
const response = await fetch(baseURL + endpoint, {
78+
method: "POST",
79+
headers: {
80+
"Content-Type": "application/json",
81+
Authorization: `JWT ${token}`,
82+
},
83+
body: JSON.stringify({ message }),
84+
});
85+
86+
if (!response.ok) {
87+
throw new Error(`HTTP error! status: ${response.status}`);
88+
}
89+
90+
if (!response.body) {
91+
throw new Error("No response body");
92+
}
93+
94+
const reader = response.body.getReader();
95+
const decoder = new TextDecoder("utf-8");
96+
let buffer = "";
97+
98+
// eslint-disable-next-line no-constant-condition
99+
while (true) {
100+
const { done, value } = await reader.read();
101+
if (done) break;
102+
103+
const chunk = decoder.decode(value, { stream: true });
104+
buffer += chunk;
105+
106+
const lines = buffer.split("\n");
107+
buffer = lines.pop() || ""; // Save incomplete line
108+
109+
for (const line of lines) {
110+
if (!line.trim().startsWith("data: ")) continue;
111+
112+
const jsonStr = line.slice(6).trim();
113+
if (!jsonStr) continue;
114+
115+
try {
116+
const data = JSON.parse(jsonStr);
117+
118+
if (data.content) {
119+
callbacks.onContent?.(data.content);
120+
} else if (data.done) {
121+
callbacks.onComplete?.({ embeddings_info: [], done: true });
122+
} else if (data.error) {
123+
callbacks.onError?.(data.error);
124+
} else if (data.type) {
125+
switch (data.type) {
126+
case "metadata":
127+
callbacks.onMetadata?.({
128+
question: data.question,
129+
embeddings_count: data.embeddings_count,
130+
});
131+
break;
132+
case "content":
133+
callbacks.onContent?.(data.content);
134+
break;
135+
case "complete":
136+
callbacks.onComplete?.(data);
137+
break;
138+
case "error":
139+
callbacks.onError?.(data.error);
140+
break;
141+
}
142+
}
143+
} catch (parseError) {
144+
console.error("Failed to parse SSE data:", parseError, "Raw line:", line);
145+
}
146+
}
147+
}
148+
} catch (error) {
149+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
150+
console.error("Error in stream:", errorMessage);
151+
callbacks.onError?.(errorMessage);
152+
throw error;
153+
}
154+
};
155+
156+
157+
// Legacy function for backward compatibility
158+
const handleSendDrugSummaryStreamLegacy = async (
159+
message: string,
160+
guid: string,
161+
onChunk: (chunk: string) => void,
162+
): Promise<void> => {
163+
return handleSendDrugSummaryStream(message, guid, {
164+
onContent: onChunk,
165+
onError: (error) => console.error("Stream error:", error),
166+
onComplete: () => console.log("Stream completed")
167+
});
168+
};
169+
60170
const fetchConversations = async (): Promise<Conversation[]> => {
61171
try {
62172
const response = await api.get(`/chatgpt/conversations/`);
@@ -143,4 +253,6 @@ export {
143253
continueConversation,
144254
deleteConversation,
145255
updateConversationTitle,
146-
};
256+
handleSendDrugSummaryStream,
257+
handleSendDrugSummaryStreamLegacy
258+
};

frontend/src/assets/chat-arrow.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)