Spaces:
Running
Running
Add 2 files
Browse files- index.html +323 -38
index.html
CHANGED
@@ -1,41 +1,326 @@
|
|
1 |
<!DOCTYPE html>
|
2 |
-
<html>
|
3 |
-
|
4 |
-
<
|
5 |
-
<meta name="viewport" content="width=device-width, initial-scale=1.0"
|
6 |
-
<
|
|
|
|
|
7 |
<style>
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
31 |
</style>
|
32 |
-
|
33 |
-
|
34 |
-
<
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>RAG Chat Agent</title>
|
7 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
8 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
9 |
<style>
|
10 |
+
.chat-container {
|
11 |
+
height: calc(100vh - 200px);
|
12 |
+
}
|
13 |
+
.message-animation {
|
14 |
+
animation: fadeIn 0.3s ease-in-out;
|
15 |
+
}
|
16 |
+
@keyframes fadeIn {
|
17 |
+
from { opacity: 0; transform: translateY(10px); }
|
18 |
+
to { opacity: 1; transform: translateY(0); }
|
19 |
+
}
|
20 |
+
.typing-indicator span {
|
21 |
+
animation: bounce 1.5s infinite ease-in-out;
|
22 |
+
display: inline-block;
|
23 |
+
}
|
24 |
+
.typing-indicator span:nth-child(2) {
|
25 |
+
animation-delay: 0.2s;
|
26 |
+
}
|
27 |
+
.typing-indicator span:nth-child(3) {
|
28 |
+
animation-delay: 0.4s;
|
29 |
+
}
|
30 |
+
@keyframes bounce {
|
31 |
+
0%, 100% { transform: translateY(0); }
|
32 |
+
50% { transform: translateY(-5px); }
|
33 |
+
}
|
34 |
</style>
|
35 |
+
</head>
|
36 |
+
<body class="bg-gray-100">
|
37 |
+
<div class="container mx-auto max-w-4xl p-4">
|
38 |
+
<header class="bg-white rounded-lg shadow-md p-6 mb-6">
|
39 |
+
<div class="flex items-center justify-between">
|
40 |
+
<div>
|
41 |
+
<h1 class="text-3xl font-bold text-indigo-600">RAG Chat Agent</h1>
|
42 |
+
<p class="text-gray-600">Retrieval-Augmented Generation powered by Hugging Face</p>
|
43 |
+
</div>
|
44 |
+
<div class="flex space-x-2">
|
45 |
+
<button id="clear-chat" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-lg transition">
|
46 |
+
<i class="fas fa-trash-alt mr-2"></i>Clear Chat
|
47 |
+
</button>
|
48 |
+
<button id="settings-btn" class="bg-indigo-100 hover:bg-indigo-200 text-indigo-700 px-4 py-2 rounded-lg transition">
|
49 |
+
<i class="fas fa-cog mr-2"></i>Settings
|
50 |
+
</button>
|
51 |
+
</div>
|
52 |
+
</div>
|
53 |
+
</header>
|
54 |
+
|
55 |
+
<div class="bg-white rounded-lg shadow-md overflow-hidden">
|
56 |
+
<!-- Chat area -->
|
57 |
+
<div id="chat-area" class="chat-container p-4 overflow-y-auto">
|
58 |
+
<div class="text-center py-10 text-gray-500">
|
59 |
+
<i class="fas fa-robot text-4xl mb-4 text-indigo-400"></i>
|
60 |
+
<h3 class="text-xl font-medium">Welcome to RAG Chat</h3>
|
61 |
+
<p class="mt-2">Ask me anything and I'll retrieve relevant information to answer your questions.</p>
|
62 |
+
</div>
|
63 |
+
</div>
|
64 |
+
|
65 |
+
<!-- Input area -->
|
66 |
+
<div class="border-t border-gray-200 p-4 bg-gray-50">
|
67 |
+
<div id="typing-indicator" class="typing-indicator mb-2 text-gray-500 hidden">
|
68 |
+
<span>.</span><span>.</span><span>.</span>
|
69 |
+
</div>
|
70 |
+
<div class="flex space-x-2">
|
71 |
+
<input
|
72 |
+
id="user-input"
|
73 |
+
type="text"
|
74 |
+
placeholder="Type your question here..."
|
75 |
+
class="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
76 |
+
autocomplete="off"
|
77 |
+
>
|
78 |
+
<button
|
79 |
+
id="send-btn"
|
80 |
+
class="bg-indigo-600 hover:bg-indigo-700 text-white px-6 py-3 rounded-lg transition flex items-center justify-center"
|
81 |
+
>
|
82 |
+
<i class="fas fa-paper-plane mr-2"></i>Send
|
83 |
+
</button>
|
84 |
+
</div>
|
85 |
+
<div class="mt-2 text-xs text-gray-500 flex justify-between">
|
86 |
+
<span>Press Enter to send</span>
|
87 |
+
<span id="status-indicator" class="text-green-500 hidden">Connected</span>
|
88 |
+
</div>
|
89 |
+
</div>
|
90 |
+
</div>
|
91 |
+
|
92 |
+
<!-- Settings modal -->
|
93 |
+
<div id="settings-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
|
94 |
+
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-md">
|
95 |
+
<div class="flex justify-between items-center mb-4">
|
96 |
+
<h3 class="text-xl font-bold text-gray-800">Settings</h3>
|
97 |
+
<button id="close-settings" class="text-gray-500 hover:text-gray-700">
|
98 |
+
<i class="fas fa-times"></i>
|
99 |
+
</button>
|
100 |
+
</div>
|
101 |
+
|
102 |
+
<div class="space-y-4">
|
103 |
+
<div>
|
104 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Model</label>
|
105 |
+
<select class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
|
106 |
+
<option>facebook/rag-token-nq</option>
|
107 |
+
<option>facebook/rag-sequence-nq</option>
|
108 |
+
<option>custom-model</option>
|
109 |
+
</select>
|
110 |
+
</div>
|
111 |
+
|
112 |
+
<div>
|
113 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Retrieval Documents</label>
|
114 |
+
<input type="file" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm">
|
115 |
+
<p class="mt-1 text-xs text-gray-500">Upload documents to enhance retrieval (PDF, TXT, DOCX)</p>
|
116 |
+
</div>
|
117 |
+
|
118 |
+
<div>
|
119 |
+
<label class="flex items-center">
|
120 |
+
<input type="checkbox" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded">
|
121 |
+
<span class="ml-2 text-sm text-gray-700">Show confidence scores</span>
|
122 |
+
</label>
|
123 |
+
</div>
|
124 |
+
</div>
|
125 |
+
|
126 |
+
<div class="mt-6 flex justify-end space-x-3">
|
127 |
+
<button id="cancel-settings" class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50">
|
128 |
+
Cancel
|
129 |
+
</button>
|
130 |
+
<button id="save-settings" class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700">
|
131 |
+
Save
|
132 |
+
</button>
|
133 |
+
</div>
|
134 |
+
</div>
|
135 |
+
</div>
|
136 |
+
|
137 |
+
<!-- Source references modal -->
|
138 |
+
<div id="sources-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
|
139 |
+
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-2xl max-h-[80vh] overflow-y-auto">
|
140 |
+
<div class="flex justify-between items-center mb-4">
|
141 |
+
<h3 class="text-xl font-bold text-gray-800">Retrieved Sources</h3>
|
142 |
+
<button id="close-sources" class="text-gray-500 hover:text-gray-700">
|
143 |
+
<i class="fas fa-times"></i>
|
144 |
+
</button>
|
145 |
+
</div>
|
146 |
+
|
147 |
+
<div id="sources-content" class="space-y-4">
|
148 |
+
<!-- Sources will be populated here -->
|
149 |
+
</div>
|
150 |
+
</div>
|
151 |
+
</div>
|
152 |
+
</div>
|
153 |
+
|
154 |
+
<script>
|
155 |
+
document.addEventListener('DOMContentLoaded', function() {
|
156 |
+
// DOM elements
|
157 |
+
const chatArea = document.getElementById('chat-area');
|
158 |
+
const userInput = document.getElementById('user-input');
|
159 |
+
const sendBtn = document.getElementById('send-btn');
|
160 |
+
const clearChatBtn = document.getElementById('clear-chat');
|
161 |
+
const settingsBtn = document.getElementById('settings-btn');
|
162 |
+
const settingsModal = document.getElementById('settings-modal');
|
163 |
+
const closeSettings = document.getElementById('close-settings');
|
164 |
+
const cancelSettings = document.getElementById('cancel-settings');
|
165 |
+
const saveSettings = document.getElementById('save-settings');
|
166 |
+
const sourcesModal = document.getElementById('sources-modal');
|
167 |
+
const closeSources = document.getElementById('close-sources');
|
168 |
+
const sourcesContent = document.getElementById('sources-content');
|
169 |
+
const typingIndicator = document.getElementById('typing-indicator');
|
170 |
+
const statusIndicator = document.getElementById('status-indicator');
|
171 |
+
|
172 |
+
// Simulate connection status
|
173 |
+
setTimeout(() => {
|
174 |
+
statusIndicator.classList.remove('hidden');
|
175 |
+
}, 1000);
|
176 |
+
|
177 |
+
// Send message function
|
178 |
+
function sendMessage() {
|
179 |
+
const message = userInput.value.trim();
|
180 |
+
if (!message) return;
|
181 |
+
|
182 |
+
// Add user message to chat
|
183 |
+
addMessage('user', message);
|
184 |
+
userInput.value = '';
|
185 |
+
|
186 |
+
// Show typing indicator
|
187 |
+
typingIndicator.classList.remove('hidden');
|
188 |
+
|
189 |
+
// Simulate API call with timeout
|
190 |
+
setTimeout(() => {
|
191 |
+
typingIndicator.classList.add('hidden');
|
192 |
+
|
193 |
+
// Simulated response (in a real app, this would come from your RAG backend)
|
194 |
+
const responses = [
|
195 |
+
"Based on the retrieved information, I can tell you that...",
|
196 |
+
"The documents I found suggest that...",
|
197 |
+
"According to my sources...",
|
198 |
+
"I couldn't find a definitive answer, but here's what I discovered..."
|
199 |
+
];
|
200 |
+
|
201 |
+
const randomResponse = responses[Math.floor(Math.random() * responses.length)];
|
202 |
+
const sources = [
|
203 |
+
{ title: "Research Paper on Topic X", snippet: "The study found that..." },
|
204 |
+
{ title: "Wikipedia Article", snippet: "According to Wikipedia..." },
|
205 |
+
{ title: "Technical Documentation", snippet: "The official docs state..." }
|
206 |
+
];
|
207 |
+
|
208 |
+
addMessage('bot', randomResponse, sources);
|
209 |
+
|
210 |
+
// Scroll to bottom
|
211 |
+
chatArea.scrollTop = chatArea.scrollHeight;
|
212 |
+
}, 1500);
|
213 |
+
}
|
214 |
+
|
215 |
+
// Add message to chat
|
216 |
+
function addMessage(sender, content, sources = null) {
|
217 |
+
const messageDiv = document.createElement('div');
|
218 |
+
messageDiv.classList.add('message-animation', 'mb-4');
|
219 |
+
|
220 |
+
if (sender === 'user') {
|
221 |
+
messageDiv.innerHTML = `
|
222 |
+
<div class="flex justify-end">
|
223 |
+
<div class="bg-indigo-600 text-white rounded-l-lg rounded-br-lg max-w-3/4 p-4">
|
224 |
+
<p>${content}</p>
|
225 |
+
</div>
|
226 |
+
</div>
|
227 |
+
`;
|
228 |
+
} else {
|
229 |
+
messageDiv.innerHTML = `
|
230 |
+
<div class="flex">
|
231 |
+
<div class="bg-gray-200 text-gray-800 rounded-r-lg rounded-bl-lg max-w-3/4 p-4">
|
232 |
+
<p>${content}</p>
|
233 |
+
${sources ? `<button class="view-sources mt-2 text-xs text-indigo-600 hover:text-indigo-800" data-sources='${JSON.stringify(sources)}'>
|
234 |
+
<i class="fas fa-book-open mr-1"></i>View sources
|
235 |
+
</button>` : ''}
|
236 |
+
</div>
|
237 |
+
</div>
|
238 |
+
`;
|
239 |
+
}
|
240 |
+
|
241 |
+
chatArea.appendChild(messageDiv);
|
242 |
+
|
243 |
+
// Remove welcome message if it's still there
|
244 |
+
const welcomeMessage = chatArea.querySelector('.text-center');
|
245 |
+
if (welcomeMessage) {
|
246 |
+
welcomeMessage.remove();
|
247 |
+
}
|
248 |
+
|
249 |
+
// Add event listeners to view sources buttons
|
250 |
+
if (sender === 'bot' && sources) {
|
251 |
+
const viewSourcesBtn = messageDiv.querySelector('.view-sources');
|
252 |
+
viewSourcesBtn.addEventListener('click', function() {
|
253 |
+
const sourcesData = JSON.parse(this.getAttribute('data-sources'));
|
254 |
+
showSources(sourcesData);
|
255 |
+
});
|
256 |
+
}
|
257 |
+
|
258 |
+
// Scroll to bottom
|
259 |
+
chatArea.scrollTop = chatArea.scrollHeight;
|
260 |
+
}
|
261 |
+
|
262 |
+
// Show sources modal
|
263 |
+
function showSources(sources) {
|
264 |
+
sourcesContent.innerHTML = '';
|
265 |
+
|
266 |
+
sources.forEach((source, index) => {
|
267 |
+
const sourceDiv = document.createElement('div');
|
268 |
+
sourceDiv.classList.add('p-4', 'border', 'border-gray-200', 'rounded-lg');
|
269 |
+
sourceDiv.innerHTML = `
|
270 |
+
<h4 class="font-medium text-indigo-600">${source.title}</h4>
|
271 |
+
<p class="mt-2 text-gray-700">${source.snippet}</p>
|
272 |
+
<div class="mt-3 flex justify-end">
|
273 |
+
<button class="text-xs bg-gray-100 hover:bg-gray-200 px-3 py-1 rounded">
|
274 |
+
<i class="fas fa-external-link-alt mr-1"></i>View full document
|
275 |
+
</button>
|
276 |
+
</div>
|
277 |
+
`;
|
278 |
+
sourcesContent.appendChild(sourceDiv);
|
279 |
+
});
|
280 |
+
|
281 |
+
sourcesModal.classList.remove('hidden');
|
282 |
+
}
|
283 |
+
|
284 |
+
// Event listeners
|
285 |
+
sendBtn.addEventListener('click', sendMessage);
|
286 |
+
|
287 |
+
userInput.addEventListener('keypress', function(e) {
|
288 |
+
if (e.key === 'Enter') {
|
289 |
+
sendMessage();
|
290 |
+
}
|
291 |
+
});
|
292 |
+
|
293 |
+
clearChatBtn.addEventListener('click', function() {
|
294 |
+
chatArea.innerHTML = `
|
295 |
+
<div class="text-center py-10 text-gray-500">
|
296 |
+
<i class="fas fa-robot text-4xl mb-4 text-indigo-400"></i>
|
297 |
+
<h3 class="text-xl font-medium">Welcome to RAG Chat</h3>
|
298 |
+
<p class="mt-2">Ask me anything and I'll retrieve relevant information to answer your questions.</p>
|
299 |
+
</div>
|
300 |
+
`;
|
301 |
+
});
|
302 |
+
|
303 |
+
settingsBtn.addEventListener('click', function() {
|
304 |
+
settingsModal.classList.remove('hidden');
|
305 |
+
});
|
306 |
+
|
307 |
+
closeSettings.addEventListener('click', function() {
|
308 |
+
settingsModal.classList.add('hidden');
|
309 |
+
});
|
310 |
+
|
311 |
+
cancelSettings.addEventListener('click', function() {
|
312 |
+
settingsModal.classList.add('hidden');
|
313 |
+
});
|
314 |
+
|
315 |
+
saveSettings.addEventListener('click', function() {
|
316 |
+
// In a real app, you would save settings here
|
317 |
+
settingsModal.classList.add('hidden');
|
318 |
+
});
|
319 |
+
|
320 |
+
closeSources.addEventListener('click', function() {
|
321 |
+
sourcesModal.classList.add('hidden');
|
322 |
+
});
|
323 |
+
});
|
324 |
+
</script>
|
325 |
+
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=matuteiglesias/test-rag-agent" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
|
326 |
+
</html>
|