|
{% extends "base.html" %} |
|
|
|
{% block title %} |
|
<title> |
|
The Ultimate RAG |
|
</title> |
|
{% endblock %} |
|
|
|
{% block content %} |
|
<div class="chat-page"> |
|
<div class="container py-4"> |
|
<div id="chat-messages" class="chat-messages"> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
<form id="chat-form" class="input-group mt-4" enctype="multipart/form-data"> |
|
<input type="text" class="form-control" name="prompt" placeholder="Ask your question here" id="queryInput"> |
|
<label class="btn btn-outline-secondary btn-primary"> |
|
π<input type="file" id="fileInput" name="files" multiple hidden> |
|
</label> |
|
<button type="button" class="btn text-white" id="searchButton">Send</button> |
|
</form> |
|
</div> |
|
</div> |
|
{% endblock %} |
|
|
|
{% block body_scripts %} |
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> |
|
<script> |
|
const initialChatId = "{{ chat_id }}"; |
|
const initialHistory = {{ history | tojson | safe }}; |
|
|
|
let conversationId = initialChatId || null; |
|
|
|
if (initialHistory && Array.isArray(initialHistory)) { |
|
initialHistory.forEach(msg => { |
|
addMessageToChat(msg.role, msg.content); |
|
}); |
|
} |
|
|
|
|
|
document.getElementById('searchButton').addEventListener('click', async function() { |
|
const query = document.getElementById('queryInput').value.trim(); |
|
if (!query) return alert('Please enter a question'); |
|
|
|
addMessageToChat('user', escapeHTML(query)); |
|
document.getElementById('queryInput').value = ''; |
|
const loadingId = addMessageToChat('assistant', '', true); |
|
|
|
try { |
|
const formData = new FormData(); |
|
const fileInput = document.getElementById('fileInput'); |
|
const files = fileInput.files; |
|
for (let i = 0; i < files.length; i++) { |
|
formData.append('files', files[i]); |
|
} |
|
formData.append('prompt', query); |
|
if (conversationId) formData.append('chat_id', conversationId); |
|
|
|
const response = await fetch('/message_with_docs', { |
|
method: 'POST', |
|
body: formData |
|
}); |
|
|
|
if (!response.ok) throw new Error(`HTTP error: ${response.status}`); |
|
|
|
const reader = response.body.getReader(); |
|
const decoder = new TextDecoder("utf-8"); |
|
let fullMessage = ""; |
|
|
|
while (true) { |
|
const { value, done } = await reader.read(); |
|
if (done) break; |
|
|
|
const chunk = decoder.decode(value, { stream: true }); |
|
fullMessage += chunk; |
|
updateMessageContent(loadingId, marked.parse(fullMessage)); |
|
} |
|
|
|
removeMessage(loadingId); |
|
const finalId = addMessageToChat('assistant', marked.parse(fullMessage)); |
|
|
|
try { |
|
const response = await fetch('/replace_message', { |
|
method: 'POST', |
|
headers: { "Content-Type": "application/json" }, |
|
body: JSON.stringify({ message: fullMessage, chat_id: initialChatId }) |
|
}); |
|
|
|
if (!response.ok) throw new Error(`Replace error: ${response.status}`); |
|
|
|
const data = await response.json(); |
|
|
|
updateMessageContent(finalId, marked.parse(data.updated_message)); |
|
|
|
} catch (error) { |
|
console.error("Error replacing message:", error); |
|
} |
|
|
|
} catch (error) { |
|
removeMessage(loadingId); |
|
addMessageToChat('assistant', `Error: ${error.message}`, false, 'error'); |
|
console.error('Error:', error); |
|
} |
|
}); |
|
|
|
function updateMessageContent(messageId, newContent) { |
|
const element = document.getElementById(messageId); |
|
if (element) { |
|
const contentDiv = element.querySelector('.message-content'); |
|
if (contentDiv) contentDiv.innerHTML = newContent; |
|
} |
|
} |
|
|
|
|
|
|
|
function addMessageToChat(role, content, isTemporary = false, className = '') { |
|
const chatMessages = document.getElementById('chat-messages'); |
|
const messageId = 'msg-' + Date.now(); |
|
|
|
const messageDiv = document.createElement('div'); |
|
messageDiv.className = `message ${role}-message ${className}`; |
|
messageDiv.id = messageId; |
|
|
|
messageDiv.innerHTML = ` |
|
<div class="message-header">${role === 'user' ? 'You' : 'Assistant'}</div> |
|
<div class="message-content">${marked.parse(content)}</div> |
|
`; |
|
|
|
chatMessages.appendChild(messageDiv); |
|
chatMessages.scrollTop = chatMessages.scrollHeight; |
|
|
|
return messageId; |
|
} |
|
|
|
|
|
function removeMessage(messageId) { |
|
const element = document.getElementById(messageId); |
|
if (element) element.remove(); |
|
} |
|
|
|
function escapeHTML(str) { |
|
const div = document.createElement('div'); |
|
div.textContent = str; |
|
return div.innerHTML; |
|
} |
|
|
|
document.querySelector('form[action="/new_chat"]').addEventListener('submit', function(e) { |
|
e.preventDefault(); |
|
conversationId = null; |
|
conversationHistory = []; |
|
document.getElementById('chat-messages').innerHTML = ''; |
|
this.submit(); |
|
}); |
|
</script> |
|
{% endblock %} |