Update static/script.js
Browse files- static/script.js +85 -288
static/script.js
CHANGED
@@ -1,178 +1,3 @@
|
|
1 |
-
// const chatbox = document.getElementById('chatbox');
|
2 |
-
// const messageInput = document.getElementById('message-input');
|
3 |
-
// const sendButton = document.getElementById('send-button');
|
4 |
-
|
5 |
-
// // --- addMessage function (inchangée) ---
|
6 |
-
// function addMessage(role, text) {
|
7 |
-
// const messageDiv = document.createElement('div');
|
8 |
-
// messageDiv.classList.add('message', role === 'user' ? 'user-message' : 'assistant-message');
|
9 |
-
// messageDiv.innerHTML = text.replace(/\n/g, '<br>');
|
10 |
-
// chatbox.appendChild(messageDiv);
|
11 |
-
// chatbox.scrollTop = chatbox.scrollHeight;
|
12 |
-
// }
|
13 |
-
|
14 |
-
// // --- processSSEBuffer function (inchangée - version Méthode 1) ---
|
15 |
-
// function processSSEBuffer(buffer, targetDiv, currentResponseAccumulated) {
|
16 |
-
// console.log("Processing buffer:", buffer); // LOG AJOUTÉ
|
17 |
-
// let messages = buffer.split('\n\n');
|
18 |
-
// let incomplete = buffer.endsWith('\n\n') ? '' : messages.pop();
|
19 |
-
// let newResponsePart = '';
|
20 |
-
|
21 |
-
// messages.forEach(message => {
|
22 |
-
// if (!message.trim()) return;
|
23 |
-
// let eventType = 'message';
|
24 |
-
// let dataLines = [];
|
25 |
-
// message.split('\n').forEach(line => {
|
26 |
-
// if (line.startsWith('event: ')) {
|
27 |
-
// eventType = line.substring(7).trim();
|
28 |
-
// } else if (line.startsWith('data: ')) {
|
29 |
-
// dataLines.push(line.substring(6));
|
30 |
-
// }
|
31 |
-
// });
|
32 |
-
// let data = dataLines.join('\n');
|
33 |
-
// console.log(`--> SSE Event Parsed: ${eventType}, Data: ${data.substring(0, 100)}...`); // LOG AJOUTÉ
|
34 |
-
|
35 |
-
// if (eventType === 'message') {
|
36 |
-
// if (targetDiv.querySelector('.thinking')) {
|
37 |
-
// console.log("Replacing 'thinking' indicator"); // LOG AJOUTÉ
|
38 |
-
// targetDiv.innerHTML = '';
|
39 |
-
// }
|
40 |
-
// newResponsePart += data;
|
41 |
-
// } else if (eventType === 'end') {
|
42 |
-
// console.log("Fin de stream détectée (event: end)"); // LOG AJOUTÉ
|
43 |
-
// sendButton.disabled = false;
|
44 |
-
// } else if (eventType === 'error') {
|
45 |
-
// console.error("Erreur SSE du serveur:", data); // LOG AJOUTÉ
|
46 |
-
// currentResponseAccumulated += `<br><strong style="color: #ffaaaa;">خطأ من الخادم: ${data}</strong>`;
|
47 |
-
// sendButton.disabled = false;
|
48 |
-
// }
|
49 |
-
// });
|
50 |
-
|
51 |
-
// const updatedResponse = currentResponseAccumulated + newResponsePart;
|
52 |
-
// // Limiter la fréquence de mise à jour de innerHTML si beaucoup de petits chunks
|
53 |
-
// targetDiv.innerHTML = updatedResponse.replace(/\n/g, '<br>');
|
54 |
-
// chatbox.scrollTop = chatbox.scrollHeight;
|
55 |
-
// // console.log("Updated Response:", updatedResponse.substring(0, 100) + "..."); // Optionnel: peut être très verbeux
|
56 |
-
|
57 |
-
// return { incomplete: incomplete, updatedResponse: updatedResponse };
|
58 |
-
// }
|
59 |
-
|
60 |
-
// // --- adjustTextareaHeight function (inchangée) ---
|
61 |
-
// function adjustTextareaHeight() { /* ... */ }
|
62 |
-
|
63 |
-
|
64 |
-
// // --- askQuestion function (avec plus de logs) ---
|
65 |
-
// async function askQuestion() {
|
66 |
-
// console.log("askQuestion called"); // LOG AJOUTÉ
|
67 |
-
// const question = messageInput.value.trim();
|
68 |
-
// if (!question) {
|
69 |
-
// console.log("Question is empty, aborting."); // LOG AJOUTÉ
|
70 |
-
// return;
|
71 |
-
// }
|
72 |
-
|
73 |
-
// addMessage('user', question);
|
74 |
-
// messageInput.value = '';
|
75 |
-
// sendButton.disabled = true;
|
76 |
-
// adjustTextareaHeight(); // Réajuste après vidage
|
77 |
-
// console.log("User message added, button disabled."); // LOG AJOUTÉ
|
78 |
-
|
79 |
-
// // Crée un placeholder pour la réponse de l'assistant
|
80 |
-
// const assistantMessageDiv = document.createElement('div');
|
81 |
-
// assistantMessageDiv.classList.add('message', 'assistant-message');
|
82 |
-
// assistantMessageDiv.innerHTML = '<span class="thinking">...</span>'; // Indicateur visuel simple
|
83 |
-
// chatbox.appendChild(assistantMessageDiv);
|
84 |
-
// chatbox.scrollTop = chatbox.scrollHeight;
|
85 |
-
// console.log("Assistant placeholder added."); // LOG AJOUTÉ
|
86 |
-
|
87 |
-
// let currentResponse = ""; // Déclaration initiale
|
88 |
-
// let buffer = ''; // Initialisation buffer
|
89 |
-
// const decoder = new TextDecoder(); // Initialisation decoder
|
90 |
-
|
91 |
-
// try {
|
92 |
-
// console.log("Initiating fetch to /ask"); // LOG AJOUTÉ
|
93 |
-
// const response = await fetch('/ask', {
|
94 |
-
// method: 'POST',
|
95 |
-
// headers: {
|
96 |
-
// 'Content-Type': 'application/json',
|
97 |
-
// 'Accept': 'text/event-stream'
|
98 |
-
// },
|
99 |
-
// body: JSON.stringify({ question: question })
|
100 |
-
// });
|
101 |
-
|
102 |
-
// console.log(`Fetch response received. Status: ${response.status}, OK: ${response.ok}`); // LOG AJOUTÉ
|
103 |
-
|
104 |
-
// if (!response.ok || !response.body) {
|
105 |
-
// // Essayer de lire le corps de l'erreur si possible
|
106 |
-
// let errorBody = "N/A";
|
107 |
-
// try {
|
108 |
-
// errorBody = await response.text();
|
109 |
-
// } catch (e) {}
|
110 |
-
// throw new Error(`Erreur serveur: ${response.status} ${response.statusText}. Body: ${errorBody}`);
|
111 |
-
// }
|
112 |
-
|
113 |
-
// const reader = response.body.getReader();
|
114 |
-
// console.log("ReadableStream reader obtained. Starting read loop."); // LOG AJOUTÉ
|
115 |
-
|
116 |
-
// while (true) {
|
117 |
-
// console.log("Calling reader.read()..."); // LOG AJOUTÉ
|
118 |
-
// const { done, value } = await reader.read();
|
119 |
-
|
120 |
-
// if (done) {
|
121 |
-
// console.log("Reader finished (done=true). Processing remaining buffer."); // LOG AJOUTÉ
|
122 |
-
// // Traiter le reste du buffer
|
123 |
-
// const result = processSSEBuffer(buffer, assistantMessageDiv, currentResponse);
|
124 |
-
// currentResponse = result.updatedResponse;
|
125 |
-
// console.log("Final response after stream ended:", currentResponse.substring(0,100)+"..."); // LOG AJOUTÉ
|
126 |
-
// break; // Sort de la boucle
|
127 |
-
// }
|
128 |
-
|
129 |
-
// // Decode et ajoute au buffer
|
130 |
-
// const chunk = decoder.decode(value, { stream: true });
|
131 |
-
// console.log("Received chunk:", chunk); // LOG AJOUTÉ (peut être volumineux)
|
132 |
-
// buffer += chunk;
|
133 |
-
|
134 |
-
// // Traite le buffer et met à jour currentResponse/buffer
|
135 |
-
// console.log("Processing buffer with new chunk..."); // LOG AJOUTÉ
|
136 |
-
// const result = processSSEBuffer(buffer, assistantMessageDiv, currentResponse);
|
137 |
-
// currentResponse = result.updatedResponse;
|
138 |
-
// buffer = result.incomplete;
|
139 |
-
// console.log("Buffer remaining:", buffer); // LOG AJOUTÉ
|
140 |
-
|
141 |
-
// }
|
142 |
-
|
143 |
-
// } catch (error) {
|
144 |
-
// console.error('Erreur dans askQuestion (fetch ou stream):', error); // LOG AJOUTÉ
|
145 |
-
// // Affiche l'erreur dans la bulle de l'assistant
|
146 |
-
// if (assistantMessageDiv) {
|
147 |
-
// // Append error to existing content if any, otherwise set it
|
148 |
-
// assistantMessageDiv.innerHTML += `<br><br><strong style="color: #ffaaaa;">حدث خطأ: ${error.message}</strong>`;
|
149 |
-
// chatbox.scrollTop = chatbox.scrollHeight; // Scroll pour voir l'erreur
|
150 |
-
// } else {
|
151 |
-
// // Fallback si assistantMessageDiv n'existe pas (ne devrait pas arriver ici)
|
152 |
-
// addMessage('assistant', `<strong style="color: #ffaaaa;">حدث خطأ: ${error.message}</strong>`);
|
153 |
-
// }
|
154 |
-
// } finally {
|
155 |
-
// console.log("Executing finally block: Enabling button."); // LOG AJOUTÉ
|
156 |
-
// sendButton.disabled = false;
|
157 |
-
// }
|
158 |
-
// }
|
159 |
-
|
160 |
-
|
161 |
-
// // --- Écouteurs d'événements (inchangés) ---
|
162 |
-
// sendButton.addEventListener('click', askQuestion);
|
163 |
-
// messageInput.addEventListener('keypress', function(e) {
|
164 |
-
// if (e.key === 'Enter' && !e.shiftKey) {
|
165 |
-
// e.preventDefault();
|
166 |
-
// askQuestion();
|
167 |
-
// }
|
168 |
-
// });
|
169 |
-
// messageInput.addEventListener('input', adjustTextareaHeight);
|
170 |
-
// adjustTextareaHeight(); // Appel initial
|
171 |
-
|
172 |
-
// console.log("Chat script loaded and listeners attached."); // LOG AJOUTÉ
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
const chatbox = document.getElementById('chatbox');
|
177 |
const messageInput = document.getElementById('message-input');
|
178 |
const sendButton = document.getElementById('send-button');
|
@@ -181,62 +6,67 @@ const sendButton = document.getElementById('send-button');
|
|
181 |
function addMessage(role, text) {
|
182 |
const messageDiv = document.createElement('div');
|
183 |
messageDiv.classList.add('message', role === 'user' ? 'user-message' : 'assistant-message');
|
184 |
-
// Remplacer les sauts de ligne pour l'affichage HTML
|
185 |
messageDiv.innerHTML = text.replace(/\n/g, '<br>');
|
186 |
chatbox.appendChild(messageDiv);
|
187 |
chatbox.scrollTop = chatbox.scrollHeight;
|
188 |
}
|
189 |
|
190 |
-
// ---
|
191 |
-
|
192 |
-
|
193 |
-
const events = [];
|
194 |
let messages = buffer.split('\n\n');
|
195 |
-
let incomplete = buffer.endsWith('\n\n') ? '' : messages.pop();
|
|
|
196 |
|
197 |
messages.forEach(message => {
|
198 |
if (!message.trim()) return;
|
199 |
-
let eventType = 'message';
|
200 |
-
let data = ''; // Données associées à l'événement (peut être multi-lignes)
|
201 |
let dataLines = [];
|
202 |
-
|
203 |
message.split('\n').forEach(line => {
|
204 |
if (line.startsWith('event: ')) {
|
205 |
eventType = line.substring(7).trim();
|
206 |
} else if (line.startsWith('data: ')) {
|
207 |
-
dataLines.push(line.substring(6));
|
208 |
}
|
209 |
-
// Ignorer les lignes id: et : (commentaires)
|
210 |
});
|
|
|
|
|
211 |
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
} else {
|
219 |
-
|
220 |
-
|
|
|
|
|
|
|
|
|
221 |
}
|
222 |
});
|
223 |
|
224 |
-
|
225 |
-
|
|
|
|
|
|
|
226 |
|
|
|
|
|
227 |
|
228 |
// --- adjustTextareaHeight function (inchangée) ---
|
229 |
-
function adjustTextareaHeight() {
|
230 |
-
|
231 |
-
messageInput.style.height = (messageInput.scrollHeight) + 'px'; // Ajuste à la hauteur du contenu
|
232 |
-
}
|
233 |
|
234 |
-
// --- askQuestion function (
|
235 |
async function askQuestion() {
|
236 |
-
console.log("askQuestion called");
|
237 |
const question = messageInput.value.trim();
|
238 |
if (!question) {
|
239 |
-
console.log("Question is empty, aborting.");
|
240 |
return;
|
241 |
}
|
242 |
|
@@ -244,118 +74,85 @@ async function askQuestion() {
|
|
244 |
messageInput.value = '';
|
245 |
sendButton.disabled = true;
|
246 |
adjustTextareaHeight(); // Réajuste après vidage
|
247 |
-
console.log("User message added, button disabled.");
|
248 |
|
249 |
// Crée un placeholder pour la réponse de l'assistant
|
250 |
const assistantMessageDiv = document.createElement('div');
|
251 |
assistantMessageDiv.classList.add('message', 'assistant-message');
|
252 |
-
|
253 |
-
const thinkingSpan = document.createElement('span');
|
254 |
-
thinkingSpan.className = 'thinking';
|
255 |
-
thinkingSpan.textContent = '...';
|
256 |
-
assistantMessageDiv.appendChild(thinkingSpan);
|
257 |
chatbox.appendChild(assistantMessageDiv);
|
258 |
chatbox.scrollTop = chatbox.scrollHeight;
|
259 |
-
console.log("Assistant placeholder added.");
|
260 |
|
261 |
-
let
|
262 |
-
|
263 |
-
|
264 |
|
265 |
try {
|
266 |
-
console.log("Initiating fetch to /ask");
|
267 |
const response = await fetch('/ask', {
|
268 |
method: 'POST',
|
269 |
-
headers: {
|
|
|
|
|
|
|
270 |
body: JSON.stringify({ question: question })
|
271 |
});
|
272 |
-
|
|
|
273 |
|
274 |
if (!response.ok || !response.body) {
|
275 |
-
|
|
|
|
|
|
|
|
|
276 |
throw new Error(`Erreur serveur: ${response.status} ${response.statusText}. Body: ${errorBody}`);
|
277 |
}
|
278 |
|
279 |
const reader = response.body.getReader();
|
280 |
-
console.log("ReadableStream reader obtained. Starting read loop.");
|
281 |
|
282 |
-
// Boucle principale de lecture du stream
|
283 |
while (true) {
|
|
|
284 |
const { done, value } = await reader.read();
|
285 |
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
//
|
293 |
-
|
294 |
-
assistantMessageDiv.innerHTML = ''; // Vide le contenu (enlève le span '...')
|
295 |
-
isFirstChunk = false;
|
296 |
-
}
|
297 |
-
// Ajoute le nouveau morceau de texte (converti en HTML)
|
298 |
-
// Note: innerHTML peut être lent si les chunks sont très petits et nombreux.
|
299 |
-
// textContent serait plus rapide mais ne gère pas <br>.
|
300 |
-
assistantMessageDiv.innerHTML += rawChunk.replace(/\n/g, '<br>');
|
301 |
-
chatbox.scrollTop = chatbox.scrollHeight; // Scroll pendant l'ajout
|
302 |
-
// --- Fin Mise à jour UI Immédiate ---
|
303 |
-
|
304 |
-
// Ajoute le chunk au buffer pour détecter les événements spéciaux
|
305 |
-
buffer += rawChunk;
|
306 |
|
307 |
-
|
308 |
-
|
309 |
-
|
|
|
310 |
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
} else if (event.type === 'error') {
|
318 |
-
console.error("Erreur signalée par le serveur (event: error):", event.data);
|
319 |
-
// Ajoute l'erreur à la fin
|
320 |
-
assistantMessageDiv.innerHTML += `<br><strong style="color: #ffaaaa;">خطأ من الخادم: ${event.data.replace(/\n/g, '<br>')}</strong>`;
|
321 |
-
chatbox.scrollTop = chatbox.scrollHeight;
|
322 |
-
sendButton.disabled = false;
|
323 |
-
// Considérer de sortir de la boucle ici ?
|
324 |
-
}
|
325 |
-
// Gérer d'autres événements si nécessaire
|
326 |
-
}
|
327 |
-
// --- Fin Traitement Événements ---
|
328 |
-
} // Fin if(value)
|
329 |
|
330 |
-
|
331 |
-
if (done) {
|
332 |
-
console.log("Reader finished (done=true). Stream ended.");
|
333 |
-
// Traiter une dernière fois le buffer pour les événements ?
|
334 |
-
// Normalement pas nécessaire si les événements finissent par \n\n
|
335 |
-
if (buffer.trim()){
|
336 |
-
console.log("Processing final buffer content:", buffer);
|
337 |
-
const finalEventResult = parseSSEEvents(buffer);
|
338 |
-
for (const event of finalEventResult.events) { /* Gérer comme ci-dessus */ }
|
339 |
-
}
|
340 |
-
break; // Sortir de la boucle while
|
341 |
-
}
|
342 |
-
} // Fin while(true)
|
343 |
|
344 |
} catch (error) {
|
345 |
-
console.error('Erreur dans askQuestion (fetch ou stream):', error);
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
}
|
356 |
} finally {
|
357 |
-
console.log("Executing finally block.");
|
358 |
-
// Le bouton peut déjà avoir été réactivé par event: end/error, mais sécurité :
|
359 |
sendButton.disabled = false;
|
360 |
}
|
361 |
}
|
@@ -372,4 +169,4 @@ messageInput.addEventListener('keypress', function(e) {
|
|
372 |
messageInput.addEventListener('input', adjustTextareaHeight);
|
373 |
adjustTextareaHeight(); // Appel initial
|
374 |
|
375 |
-
console.log("Chat script loaded and listeners attached.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
const chatbox = document.getElementById('chatbox');
|
2 |
const messageInput = document.getElementById('message-input');
|
3 |
const sendButton = document.getElementById('send-button');
|
|
|
6 |
function addMessage(role, text) {
|
7 |
const messageDiv = document.createElement('div');
|
8 |
messageDiv.classList.add('message', role === 'user' ? 'user-message' : 'assistant-message');
|
|
|
9 |
messageDiv.innerHTML = text.replace(/\n/g, '<br>');
|
10 |
chatbox.appendChild(messageDiv);
|
11 |
chatbox.scrollTop = chatbox.scrollHeight;
|
12 |
}
|
13 |
|
14 |
+
// --- processSSEBuffer function (inchangée - version Méthode 1) ---
|
15 |
+
function processSSEBuffer(buffer, targetDiv, currentResponseAccumulated) {
|
16 |
+
console.log("Processing buffer:", buffer); // LOG AJOUTÉ
|
|
|
17 |
let messages = buffer.split('\n\n');
|
18 |
+
let incomplete = buffer.endsWith('\n\n') ? '' : messages.pop();
|
19 |
+
let newResponsePart = '';
|
20 |
|
21 |
messages.forEach(message => {
|
22 |
if (!message.trim()) return;
|
23 |
+
let eventType = 'message';
|
|
|
24 |
let dataLines = [];
|
|
|
25 |
message.split('\n').forEach(line => {
|
26 |
if (line.startsWith('event: ')) {
|
27 |
eventType = line.substring(7).trim();
|
28 |
} else if (line.startsWith('data: ')) {
|
29 |
+
dataLines.push(line.substring(6));
|
30 |
}
|
|
|
31 |
});
|
32 |
+
let data = dataLines.join('\n');
|
33 |
+
console.log(`--> SSE Event Parsed: ${eventType}, Data: ${data.substring(0, 100)}...`); // LOG AJOUTÉ
|
34 |
|
35 |
+
if (eventType === 'message') {
|
36 |
+
if (targetDiv.querySelector('.thinking')) {
|
37 |
+
console.log("Replacing 'thinking' indicator"); // LOG AJOUTÉ
|
38 |
+
targetDiv.innerHTML = '';
|
39 |
+
}
|
40 |
+
newResponsePart += data;
|
41 |
+
} else if (eventType === 'end') {
|
42 |
+
console.log("Fin de stream détectée (event: end)"); // LOG AJOUTÉ
|
43 |
+
sendButton.disabled = false;
|
44 |
+
} else if (eventType === 'error') {
|
45 |
+
console.error("Erreur SSE du serveur:", data); // LOG AJOUTÉ
|
46 |
+
currentResponseAccumulated += `<br><strong style="color: #ffaaaa;">خطأ من الخادم: ${data}</strong>`;
|
47 |
+
sendButton.disabled = false;
|
48 |
}
|
49 |
});
|
50 |
|
51 |
+
const updatedResponse = currentResponseAccumulated + newResponsePart;
|
52 |
+
// Limiter la fréquence de mise à jour de innerHTML si beaucoup de petits chunks
|
53 |
+
targetDiv.innerHTML = updatedResponse.replace(/\n/g, '<br>');
|
54 |
+
chatbox.scrollTop = chatbox.scrollHeight;
|
55 |
+
// console.log("Updated Response:", updatedResponse.substring(0, 100) + "..."); // Optionnel: peut être très verbeux
|
56 |
|
57 |
+
return { incomplete: incomplete, updatedResponse: updatedResponse };
|
58 |
+
}
|
59 |
|
60 |
// --- adjustTextareaHeight function (inchangée) ---
|
61 |
+
function adjustTextareaHeight() { /* ... */ }
|
62 |
+
|
|
|
|
|
63 |
|
64 |
+
// --- askQuestion function (avec plus de logs) ---
|
65 |
async function askQuestion() {
|
66 |
+
console.log("askQuestion called"); // LOG AJOUTÉ
|
67 |
const question = messageInput.value.trim();
|
68 |
if (!question) {
|
69 |
+
console.log("Question is empty, aborting."); // LOG AJOUTÉ
|
70 |
return;
|
71 |
}
|
72 |
|
|
|
74 |
messageInput.value = '';
|
75 |
sendButton.disabled = true;
|
76 |
adjustTextareaHeight(); // Réajuste après vidage
|
77 |
+
console.log("User message added, button disabled."); // LOG AJOUTÉ
|
78 |
|
79 |
// Crée un placeholder pour la réponse de l'assistant
|
80 |
const assistantMessageDiv = document.createElement('div');
|
81 |
assistantMessageDiv.classList.add('message', 'assistant-message');
|
82 |
+
assistantMessageDiv.innerHTML = '<span class="thinking">...</span>'; // Indicateur visuel simple
|
|
|
|
|
|
|
|
|
83 |
chatbox.appendChild(assistantMessageDiv);
|
84 |
chatbox.scrollTop = chatbox.scrollHeight;
|
85 |
+
console.log("Assistant placeholder added."); // LOG AJOUTÉ
|
86 |
|
87 |
+
let currentResponse = ""; // Déclaration initiale
|
88 |
+
let buffer = ''; // Initialisation buffer
|
89 |
+
const decoder = new TextDecoder(); // Initialisation decoder
|
90 |
|
91 |
try {
|
92 |
+
console.log("Initiating fetch to /ask"); // LOG AJOUTÉ
|
93 |
const response = await fetch('/ask', {
|
94 |
method: 'POST',
|
95 |
+
headers: {
|
96 |
+
'Content-Type': 'application/json',
|
97 |
+
'Accept': 'text/event-stream'
|
98 |
+
},
|
99 |
body: JSON.stringify({ question: question })
|
100 |
});
|
101 |
+
|
102 |
+
console.log(`Fetch response received. Status: ${response.status}, OK: ${response.ok}`); // LOG AJOUTÉ
|
103 |
|
104 |
if (!response.ok || !response.body) {
|
105 |
+
// Essayer de lire le corps de l'erreur si possible
|
106 |
+
let errorBody = "N/A";
|
107 |
+
try {
|
108 |
+
errorBody = await response.text();
|
109 |
+
} catch (e) {}
|
110 |
throw new Error(`Erreur serveur: ${response.status} ${response.statusText}. Body: ${errorBody}`);
|
111 |
}
|
112 |
|
113 |
const reader = response.body.getReader();
|
114 |
+
console.log("ReadableStream reader obtained. Starting read loop."); // LOG AJOUTÉ
|
115 |
|
|
|
116 |
while (true) {
|
117 |
+
console.log("Calling reader.read()..."); // LOG AJOUTÉ
|
118 |
const { done, value } = await reader.read();
|
119 |
|
120 |
+
if (done) {
|
121 |
+
console.log("Reader finished (done=true). Processing remaining buffer."); // LOG AJOUTÉ
|
122 |
+
// Traiter le reste du buffer
|
123 |
+
const result = processSSEBuffer(buffer, assistantMessageDiv, currentResponse);
|
124 |
+
currentResponse = result.updatedResponse;
|
125 |
+
console.log("Final response after stream ended:", currentResponse.substring(0,100)+"..."); // LOG AJOUTÉ
|
126 |
+
break; // Sort de la boucle
|
127 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
|
129 |
+
// Decode et ajoute au buffer
|
130 |
+
const chunk = decoder.decode(value, { stream: true });
|
131 |
+
console.log("Received chunk:", chunk); // LOG AJOUTÉ (peut être volumineux)
|
132 |
+
buffer += chunk;
|
133 |
|
134 |
+
// Traite le buffer et met à jour currentResponse/buffer
|
135 |
+
console.log("Processing buffer with new chunk..."); // LOG AJOUTÉ
|
136 |
+
const result = processSSEBuffer(buffer, assistantMessageDiv, currentResponse);
|
137 |
+
currentResponse = result.updatedResponse;
|
138 |
+
buffer = result.incomplete;
|
139 |
+
console.log("Buffer remaining:", buffer); // LOG AJOUTÉ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
|
141 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
|
143 |
} catch (error) {
|
144 |
+
console.error('Erreur dans askQuestion (fetch ou stream):', error); // LOG AJOUTÉ
|
145 |
+
// Affiche l'erreur dans la bulle de l'assistant
|
146 |
+
if (assistantMessageDiv) {
|
147 |
+
// Append error to existing content if any, otherwise set it
|
148 |
+
assistantMessageDiv.innerHTML += `<br><br><strong style="color: #ffaaaa;">حدث خطأ: ${error.message}</strong>`;
|
149 |
+
chatbox.scrollTop = chatbox.scrollHeight; // Scroll pour voir l'erreur
|
150 |
+
} else {
|
151 |
+
// Fallback si assistantMessageDiv n'existe pas (ne devrait pas arriver ici)
|
152 |
+
addMessage('assistant', `<strong style="color: #ffaaaa;">حدث خطأ: ${error.message}</strong>`);
|
153 |
+
}
|
|
|
154 |
} finally {
|
155 |
+
console.log("Executing finally block: Enabling button."); // LOG AJOUTÉ
|
|
|
156 |
sendButton.disabled = false;
|
157 |
}
|
158 |
}
|
|
|
169 |
messageInput.addEventListener('input', adjustTextareaHeight);
|
170 |
adjustTextareaHeight(); // Appel initial
|
171 |
|
172 |
+
console.log("Chat script loaded and listeners attached."); // LOG AJOUTÉ
|