File size: 7,496 Bytes
1ccf000 13e5b3b 2893f3c 13e5b3b 2893f3c c61873b 13e5b3b 2893f3c 13e5b3b 2893f3c 13e5b3b 1ccf000 13e5b3b 2893f3c c61873b 13e5b3b 2893f3c 13e5b3b 1ccf000 13e5b3b 1ccf000 13e5b3b a665b4f 13e5b3b a665b4f 1ccf000 13e5b3b 1ccf000 a665b4f 1ccf000 13e5b3b 1ccf000 a665b4f 13e5b3b a665b4f 13e5b3b a665b4f 13e5b3b a665b4f 13e5b3b 1ccf000 13e5b3b 1ccf000 13e5b3b a665b4f 13e5b3b 1ccf000 a665b4f 13e5b3b a665b4f 13e5b3b a665b4f 13e5b3b 1ccf000 13e5b3b 1ccf000 13e5b3b a665b4f 13e5b3b a665b4f 13e5b3b a665b4f 13e5b3b a665b4f 1ccf000 a665b4f 1ccf000 2893f3c 13e5b3b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
const chatbox = document.getElementById('chatbox');
const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');
// --- addMessage function (inchangée) ---
function addMessage(role, text) {
const messageDiv = document.createElement('div');
messageDiv.classList.add('message', role === 'user' ? 'user-message' : 'assistant-message');
messageDiv.innerHTML = text.replace(/\n/g, '<br>');
chatbox.appendChild(messageDiv);
chatbox.scrollTop = chatbox.scrollHeight;
}
// --- processSSEBuffer function (inchangée - version Méthode 1) ---
function processSSEBuffer(buffer, targetDiv, currentResponseAccumulated) {
console.log("Processing buffer:", buffer); // LOG AJOUTÉ
let messages = buffer.split('\n\n');
let incomplete = buffer.endsWith('\n\n') ? '' : messages.pop();
let newResponsePart = '';
messages.forEach(message => {
if (!message.trim()) return;
let eventType = 'message';
let dataLines = [];
message.split('\n').forEach(line => {
if (line.startsWith('event: ')) {
eventType = line.substring(7).trim();
} else if (line.startsWith('data: ')) {
dataLines.push(line.substring(6));
}
});
let data = dataLines.join('\n');
console.log(`--> SSE Event Parsed: ${eventType}, Data: ${data.substring(0, 100)}...`); // LOG AJOUTÉ
if (eventType === 'message') {
if (targetDiv.querySelector('.thinking')) {
console.log("Replacing 'thinking' indicator"); // LOG AJOUTÉ
targetDiv.innerHTML = '';
}
newResponsePart += data;
} else if (eventType === 'end') {
console.log("Fin de stream détectée (event: end)"); // LOG AJOUTÉ
sendButton.disabled = false;
} else if (eventType === 'error') {
console.error("Erreur SSE du serveur:", data); // LOG AJOUTÉ
currentResponseAccumulated += `<br><strong style="color: #ffaaaa;">خطأ من الخادم: ${data}</strong>`;
sendButton.disabled = false;
}
});
const updatedResponse = currentResponseAccumulated + newResponsePart;
// Limiter la fréquence de mise à jour de innerHTML si beaucoup de petits chunks
targetDiv.innerHTML = updatedResponse.replace(/\n/g, '<br>');
chatbox.scrollTop = chatbox.scrollHeight;
// console.log("Updated Response:", updatedResponse.substring(0, 100) + "..."); // Optionnel: peut être très verbeux
return { incomplete: incomplete, updatedResponse: updatedResponse };
}
// --- adjustTextareaHeight function (inchangée) ---
function adjustTextareaHeight() { /* ... */ }
// --- askQuestion function (avec plus de logs) ---
async function askQuestion() {
console.log("askQuestion called"); // LOG AJOUTÉ
const question = messageInput.value.trim();
if (!question) {
console.log("Question is empty, aborting."); // LOG AJOUTÉ
return;
}
addMessage('user', question);
messageInput.value = '';
sendButton.disabled = true;
adjustTextareaHeight(); // Réajuste après vidage
console.log("User message added, button disabled."); // LOG AJOUTÉ
// Crée un placeholder pour la réponse de l'assistant
const assistantMessageDiv = document.createElement('div');
assistantMessageDiv.classList.add('message', 'assistant-message');
assistantMessageDiv.innerHTML = '<span class="thinking">...</span>'; // Indicateur visuel simple
chatbox.appendChild(assistantMessageDiv);
chatbox.scrollTop = chatbox.scrollHeight;
console.log("Assistant placeholder added."); // LOG AJOUTÉ
let currentResponse = ""; // Déclaration initiale
let buffer = ''; // Initialisation buffer
const decoder = new TextDecoder(); // Initialisation decoder
try {
console.log("Initiating fetch to /ask"); // LOG AJOUTÉ
const response = await fetch('/ask', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'text/event-stream'
},
body: JSON.stringify({ question: question })
});
console.log(`Fetch response received. Status: ${response.status}, OK: ${response.ok}`); // LOG AJOUTÉ
if (!response.ok || !response.body) {
// Essayer de lire le corps de l'erreur si possible
let errorBody = "N/A";
try {
errorBody = await response.text();
} catch (e) {}
throw new Error(`Erreur serveur: ${response.status} ${response.statusText}. Body: ${errorBody}`);
}
const reader = response.body.getReader();
console.log("ReadableStream reader obtained. Starting read loop."); // LOG AJOUTÉ
while (true) {
console.log("Calling reader.read()..."); // LOG AJOUTÉ
const { done, value } = await reader.read();
if (done) {
console.log("Reader finished (done=true). Processing remaining buffer."); // LOG AJOUTÉ
// Traiter le reste du buffer
const result = processSSEBuffer(buffer, assistantMessageDiv, currentResponse);
currentResponse = result.updatedResponse;
console.log("Final response after stream ended:", currentResponse.substring(0,100)+"..."); // LOG AJOUTÉ
break; // Sort de la boucle
}
// Decode et ajoute au buffer
const chunk = decoder.decode(value, { stream: true });
console.log("Received chunk:", chunk); // LOG AJOUTÉ (peut être volumineux)
buffer += chunk;
// Traite le buffer et met à jour currentResponse/buffer
console.log("Processing buffer with new chunk..."); // LOG AJOUTÉ
const result = processSSEBuffer(buffer, assistantMessageDiv, currentResponse);
currentResponse = result.updatedResponse;
buffer = result.incomplete;
console.log("Buffer remaining:", buffer); // LOG AJOUTÉ
}
} catch (error) {
console.error('Erreur dans askQuestion (fetch ou stream):', error); // LOG AJOUTÉ
// Affiche l'erreur dans la bulle de l'assistant
if (assistantMessageDiv) {
// Append error to existing content if any, otherwise set it
assistantMessageDiv.innerHTML += `<br><br><strong style="color: #ffaaaa;">حدث خطأ: ${error.message}</strong>`;
chatbox.scrollTop = chatbox.scrollHeight; // Scroll pour voir l'erreur
} else {
// Fallback si assistantMessageDiv n'existe pas (ne devrait pas arriver ici)
addMessage('assistant', `<strong style="color: #ffaaaa;">حدث خطأ: ${error.message}</strong>`);
}
} finally {
console.log("Executing finally block: Enabling button."); // LOG AJOUTÉ
sendButton.disabled = false;
}
}
// --- Écouteurs d'événements (inchangés) ---
sendButton.addEventListener('click', askQuestion);
messageInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
askQuestion();
}
});
messageInput.addEventListener('input', adjustTextareaHeight);
adjustTextareaHeight(); // Appel initial
console.log("Chat script loaded and listeners attached."); // LOG AJOUTÉ |