Spaces:
Running
Running
File size: 7,888 Bytes
48ec4db b32f862 48ec4db |
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 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
{% 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">
<!-- Messages will be dynamically added by JavaScript -->
</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;
// Initialize chat history
if (initialHistory && Array.isArray(initialHistory)) {
initialHistory.forEach(msg => {
addMessageToChat(msg.role, msg.content);
});
}
// Main chat function with WebSocket
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', 'Thinking...', 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 data = await response.json();
const taskId = data.resp_task_id;
console.log(taskId)
if (!taskId) throw new Error('No task ID received');
// Connect to WebSocket for streaming
streamResponse(taskId, loadingId);
} catch (error) {
removeMessage(loadingId);
addMessageToChat('assistant', `Error: ${error.message}`, false, 'error');
console.error('Error:', error);
}
});
// WebSocket streaming function
function streamResponse(taskId, loadingId) {
const ws = new WebSocket(`wss://${window.location.host}/ws/response/${taskId}`);
let fullMessage = '';
ws.onopen = () => {
console.log(`WebSocket connected for task: ${taskId}`);
};
ws.onmessage = async (event) => {
try {
const data = JSON.parse(event.data);
if (data.status === 'completed') {
ws.close();
try {
const replaceResp = await fetch('/replace_message', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: fullMessage,
chat_id: conversationId
})
});
const json = await replaceResp.json();
const updatedMessage = json.updated_message;
removeMessage(loadingId);
addMessageToChat('assistant', updatedMessage);
} catch (error) {
removeMessage(loadingId);
addMessageToChat('assistant', `Error replacing message: ${error.message}`, false, 'error');
}
} else if (data.status === 'failed') {
ws.close();
removeMessage(loadingId);
addMessageToChat('assistant', `Error: ${data.error}`, false, 'error');
} else {
fullMessage += event.data;
updateMessageContent(loadingId, marked.parse(fullMessage));
}
} catch {
fullMessage += event.data;
updateMessageContent(loadingId, marked.parse(fullMessage));
}
};
ws.onclose = () => {
console.log(`WebSocket closed for task: ${taskId}`);
if (!fullMessage) {
removeMessage(loadingId);
addMessageToChat('assistant', 'No response received', false, 'error');
}
};
ws.onerror = (error) => {
console.error(`WebSocket error for task ${taskId}:`, error);
removeMessage(loadingId);
addMessageToChat('assistant', 'WebSocket error occurred', false, 'error');
ws.close();
};
}
// Update message content
function updateMessageContent(messageId, newContent) {
const element = document.getElementById(messageId);
if (element) {
const contentDiv = element.querySelector('.message-content');
if (contentDiv) contentDiv.innerHTML = newContent;
document.getElementById('chat-messages').scrollTop = document.getElementById('chat-messages').scrollHeight;
}
}
// Add message to chat
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;
}
// Remove message
function removeMessage(messageId) {
const element = document.getElementById(messageId);
if (element) element.remove();
}
// Escape HTML
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;
document.getElementById('chat-messages').innerHTML = '';
this.submit();
});
</script>
{% endblock %} |