in static/js/chat.js [257:342]
function handleUserQuery(userQuery, userQueryHTML, imgUrlPath) {
let contentMessage = userQuery;
if (imgUrlPath.trim()) {
contentMessage = [
{ type: "text", text: userQuery },
{ type: "image_url", image_url: { url: imgUrlPath } }
];
}
let chatMessage = { role: 'user', content: contentMessage };
messages.push(chatMessage);
let chatHistoryTextArea = document.getElementById('chatHistory');
chatHistoryTextArea.innerHTML += "<br/><br/>User: " + userQuery + "<br/>";
chatHistoryTextArea.scrollTop = chatHistoryTextArea.scrollHeight;
if (isSpeaking) { stopSpeaking(); }
// Use the stored conversationId (empty string on first call)
let payload = JSON.stringify({
spokenText: userQuery,
conversation_id: conversationId
});
let assistantReply = "";
let spokenSentence = "";
let displaySentence = "";
fetch("/speak", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: payload
})
.then(response => {
if (!response.ok) {
throw new Error(`Chat API response status: ${response.status} ${response.statusText}`);
}
chatHistoryTextArea.innerHTML += "Assistant: ";
const reader = response.body.getReader();
function read() {
return reader.read().then(({ value, done }) => {
if (done) return;
let chunk = new TextDecoder().decode(value, { stream: true });
// Check if the first 36 characters form a valid UUID.
if (chunk.length >= 37) {
let possibleId = chunk.substring(0, 36);
// Simple regex for UUID validation.
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (uuidRegex.test(possibleId)) {
// Store/update the conversationId and remove it from the chunk.
conversationId = possibleId;
console.log("Conversation ID: [", conversationId, "]");
chunk = chunk.substring(37);
}
}
assistantReply += chunk;
displaySentence += chunk;
spokenSentence += chunk;
if (chunk.trim() === "" || chunk.trim() === "\n") {
console.log("Speak Chunk: [", spokenSentence.trim(), "]");
speak(spokenSentence.trim());
spokenSentence = "";
}
chatHistoryTextArea.innerHTML += displaySentence;
chatHistoryTextArea.scrollTop = chatHistoryTextArea.scrollHeight;
displaySentence = "";
return read();
});
}
return read();
})
.then(() => {
if (spokenSentence !== "") {
speak(spokenSentence.trim());
spokenSentence = "";
}
let assistantMessage = { role: 'assistant', content: assistantReply };
messages.push(assistantMessage);
})
.catch(error => {
console.error("Error in handleUserQuery:", error);
});
}