Skip to content

Commit a61ca4a

Browse files
committed
timeout and streaming
1 parent 012b6fa commit a61ca4a

File tree

1 file changed

+133
-69
lines changed
  • mongodb-rag-docs/src/components/ChatbotInterface

1 file changed

+133
-69
lines changed

mongodb-rag-docs/src/components/ChatbotInterface/index.js

Lines changed: 133 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -132,88 +132,152 @@ export default function ChatbotInterface() {
132132
const handleStreamedChat = async (input, history) => {
133133
// Clean up any existing EventSource
134134
cleanupEventSource();
135-
136-
// Prepare the query parameters
137-
const queryParams = new URLSearchParams({
138-
sessionId: sessionId || '',
139-
});
140-
141-
// Create new EventSource connection
142-
eventSourceRef.current = new EventSource(
143-
`https://mongodb-rag-docs-backend.vercel.app/api/chat?${queryParams.toString()}`
144-
);
145-
146-
// Initialize streaming message
147-
setCurrentStreamedMessage('');
148-
let sourcesData = null;
149-
150-
// Handle different event types
151-
eventSourceRef.current.addEventListener('token', (event) => {
152-
const { token } = JSON.parse(event.data);
153-
setCurrentStreamedMessage(prev => prev + token);
154-
});
155-
156-
eventSourceRef.current.addEventListener('sources', (event) => {
157-
sourcesData = JSON.parse(event.data).sources;
158-
});
159-
160-
eventSourceRef.current.addEventListener('error', (event) => {
161-
const error = JSON.parse(event.data);
162-
console.error('Streaming error:', error);
163-
cleanupEventSource();
164-
setIsLoading(false);
165-
166-
// Add error message to chat
167-
setMessages(msgs => [...msgs, {
168-
role: 'assistant',
169-
content: `Error: ${error.message || 'An error occurred'}`
170-
}]);
171-
});
172-
173-
eventSourceRef.current.addEventListener('done', () => {
174-
// Add the complete message with sources
175-
setMessages(msgs => [...msgs, {
176-
role: 'assistant',
177-
content: currentStreamedMessage,
178-
sources: sourcesData
179-
}]);
180-
181-
// Cleanup
182-
cleanupEventSource();
183-
setIsLoading(false);
184-
setCurrentStreamedMessage('');
185-
});
186-
187-
// Send the actual chat message
135+
188136
try {
137+
// First, initiate the chat request
189138
const response = await fetch('https://mongodb-rag-docs-backend.vercel.app/api/chat', {
190139
method: 'POST',
191140
headers: { 'Content-Type': 'application/json' },
192141
body: JSON.stringify({
193142
query: input,
194143
sessionId: sessionId,
195-
history: !sessionId ? history : undefined
144+
history: !sessionId ? history : undefined,
145+
stream: true // Indicate we want streaming response
196146
})
197147
});
198-
148+
199149
if (!response.ok) {
200-
throw new Error('Failed to send chat message');
201-
}
202-
203-
// Handle session ID if it's a new session
204-
const data = await response.json();
205-
if (data.sessionId && !sessionId) {
206-
setSessionId(data.sessionId);
150+
throw new Error(`HTTP error! status: ${response.status}`);
207151
}
152+
153+
// Get the stream ID from the response
154+
const { streamId } = await response.json();
155+
156+
// Now connect to the streaming endpoint with the stream ID
157+
eventSourceRef.current = new EventSource(
158+
`https://mongodb-rag-docs-backend.vercel.app/api/chat/stream/${streamId}`
159+
);
160+
161+
// Initialize streaming message
162+
setCurrentStreamedMessage('');
163+
let sourcesData = null;
164+
165+
// Handle different event types
166+
eventSourceRef.current.addEventListener('token', (event) => {
167+
try {
168+
const { token } = JSON.parse(event.data);
169+
setCurrentStreamedMessage(prev => prev + token);
170+
} catch (error) {
171+
console.warn('Error parsing token event:', error);
172+
}
173+
});
174+
175+
eventSourceRef.current.addEventListener('sources', (event) => {
176+
try {
177+
sourcesData = JSON.parse(event.data).sources;
178+
} catch (error) {
179+
console.warn('Error parsing sources event:', error);
180+
}
181+
});
182+
183+
eventSourceRef.current.addEventListener('error', (event) => {
184+
const error = event.data ? JSON.parse(event.data) : { message: 'Stream connection error' };
185+
console.error('Streaming error:', error);
186+
cleanupEventSource();
187+
setIsLoading(false);
188+
189+
// Add error message to chat
190+
setMessages(msgs => [...msgs, {
191+
role: 'assistant',
192+
content: `Error: ${error.message || 'An error occurred'}`
193+
}]);
194+
});
195+
196+
eventSourceRef.current.addEventListener('done', () => {
197+
// Add the complete message with sources
198+
setMessages(msgs => [...msgs, {
199+
role: 'assistant',
200+
content: currentStreamedMessage,
201+
sources: sourcesData
202+
}]);
203+
204+
// Cleanup
205+
cleanupEventSource();
206+
setIsLoading(false);
207+
setCurrentStreamedMessage('');
208+
});
209+
210+
// Handle connection opening
211+
eventSourceRef.current.addEventListener('open', () => {
212+
console.log('Stream connection opened');
213+
});
214+
208215
} catch (error) {
209-
console.error('Error sending chat message:', error);
210-
cleanupEventSource();
211-
setIsLoading(false);
216+
console.error('Error setting up stream:', error);
217+
throw error; // Let the caller handle the error
218+
}
219+
};
220+
221+
const handleSubmit = async (e) => {
222+
e.preventDefault();
223+
if (!input.trim()) return;
224+
225+
// Add user message
226+
const userMessage = { role: 'user', content: input };
227+
setMessages(msgs => [...msgs, userMessage]);
228+
setInput('');
229+
setIsLoading(true);
230+
setShowSampleQuestions(true);
231+
232+
try {
233+
// Try streaming first
234+
await handleStreamedChat(input, messages);
235+
} catch (error) {
236+
console.error('Streaming failed, falling back to regular chat:', error);
212237

213-
setMessages(msgs => [...msgs, {
214-
role: 'assistant',
215-
content: 'Sorry, I encountered an error. Please try again later.'
216-
}]);
238+
// Fallback to non-streaming implementation
239+
try {
240+
const response = await fetch('https://mongodb-rag-docs-backend.vercel.app/api/chat', {
241+
method: 'POST',
242+
headers: { 'Content-Type': 'application/json' },
243+
body: JSON.stringify({
244+
query: input,
245+
sessionId: sessionId,
246+
history: !sessionId ? messages : undefined,
247+
stream: false // Explicitly request non-streaming response
248+
})
249+
});
250+
251+
if (!response.ok) {
252+
throw new Error(`HTTP error! status: ${response.status}`);
253+
}
254+
255+
const data = await response.json();
256+
257+
if (data.sessionId && !sessionId) {
258+
setSessionId(data.sessionId);
259+
}
260+
261+
setMessages(msgs => [
262+
...msgs,
263+
{
264+
role: 'assistant',
265+
content: data.answer,
266+
sources: data.sources
267+
}
268+
]);
269+
} catch (error) {
270+
console.error('Chat error:', error);
271+
setMessages(msgs => [
272+
...msgs,
273+
{
274+
role: 'assistant',
275+
content: 'Sorry, I encountered an error. Please try again later.'
276+
}
277+
]);
278+
}
279+
} finally {
280+
setIsLoading(false);
217281
}
218282
};
219283

0 commit comments

Comments
 (0)