Andrchest's picture
Single commit for HF2
365de9c
{% 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">
<!-- {% for message in history %}
<div class="message {{ message.role }}-message">
<div class="message-header">
{{ "You" if message.role == "user" else "Assistant" }}
</div>
<div class="message-content">{{ message.content | safe }}</div>
</div>
{% endfor %} -->
</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 }};
// Conversation state
let conversationId = initialChatId || null;
if (initialHistory && Array.isArray(initialHistory)) {
initialHistory.forEach(msg => {
addMessageToChat(msg.role, msg.content);
});
}
// Main chat function
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(); // expects { "updated_message": "..." }
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;
}
}
// Message display helper
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; // always return the ID so you can update it later
}
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;
}
// New chat handler
document.querySelector('form[action="/new_chat"]').addEventListener('submit', function(e) {
e.preventDefault();
conversationId = null;
conversationHistory = [];
document.getElementById('chat-messages').innerHTML = '';
this.submit();
});
</script>
{% endblock %}