Spaces:
Running
Running
Update index.html
Browse files- index.html +600 -14
index.html
CHANGED
|
@@ -329,6 +329,191 @@
|
|
| 329 |
background: #ff5a5a;
|
| 330 |
}
|
| 331 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
/* === VOICE CONTROLS PANEL === */
|
| 333 |
.voice-controls {
|
| 334 |
position: absolute;
|
|
@@ -338,7 +523,7 @@
|
|
| 338 |
backdrop-filter: blur(10px);
|
| 339 |
border-radius: 20px;
|
| 340 |
padding: 25px;
|
| 341 |
-
width:
|
| 342 |
pointer-events: all;
|
| 343 |
border: 1px solid rgba(255, 255, 255, 0.1);
|
| 344 |
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
|
@@ -720,7 +905,13 @@
|
|
| 720 |
}
|
| 721 |
|
| 722 |
/* Responsive adjustments */
|
| 723 |
-
@media (max-width:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 724 |
.voice-controls {
|
| 725 |
right: 30px;
|
| 726 |
bottom: 400px;
|
|
@@ -740,6 +931,11 @@
|
|
| 740 |
padding: 20px;
|
| 741 |
width: 260px;
|
| 742 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 743 |
}
|
| 744 |
</style>
|
| 745 |
</head>
|
|
@@ -755,6 +951,76 @@
|
|
| 755 |
</div>
|
| 756 |
</div>
|
| 757 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 758 |
<!-- Voice Controls Panel -->
|
| 759 |
<div class="voice-controls">
|
| 760 |
<div class="voice-header">
|
|
@@ -852,7 +1118,7 @@
|
|
| 852 |
|
| 853 |
<div class="message message-ai">
|
| 854 |
<div class="message-content">
|
| 855 |
-
You can type your questions or click the microphone
|
| 856 |
</div>
|
| 857 |
<div class="message-time">Just now</div>
|
| 858 |
</div>
|
|
@@ -987,7 +1253,318 @@
|
|
| 987 |
document.getElementById('loadingText').textContent = text;
|
| 988 |
}
|
| 989 |
|
| 990 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 991 |
class VoiceSynthesis {
|
| 992 |
constructor() {
|
| 993 |
this.synth = window.speechSynthesis;
|
|
@@ -1304,7 +1881,8 @@
|
|
| 1304 |
|
| 1305 |
// Chat Interface Functionality
|
| 1306 |
class ChatInterface {
|
| 1307 |
-
constructor() {
|
|
|
|
| 1308 |
this.isListening = false;
|
| 1309 |
this.voiceAnimationInterval = null;
|
| 1310 |
this.initChat();
|
|
@@ -1440,7 +2018,7 @@
|
|
| 1440 |
}, 500);
|
| 1441 |
}
|
| 1442 |
|
| 1443 |
-
sendMessage() {
|
| 1444 |
const message = this.chatInput.value.trim();
|
| 1445 |
if (message === '') return;
|
| 1446 |
|
|
@@ -1452,7 +2030,7 @@
|
|
| 1452 |
this.autoResizeTextarea();
|
| 1453 |
|
| 1454 |
// Process and respond
|
| 1455 |
-
this.processAIResponse(message);
|
| 1456 |
}
|
| 1457 |
|
| 1458 |
addMessage(content, sender) {
|
|
@@ -1485,7 +2063,7 @@
|
|
| 1485 |
return div.innerHTML;
|
| 1486 |
}
|
| 1487 |
|
| 1488 |
-
processAIResponse(userMessage) {
|
| 1489 |
// Show typing indicator
|
| 1490 |
this.showTypingIndicator();
|
| 1491 |
|
|
@@ -1497,11 +2075,16 @@
|
|
| 1497 |
// Simulate AI processing time
|
| 1498 |
const processingTime = 1000 + Math.random() * 2000;
|
| 1499 |
|
| 1500 |
-
setTimeout(() => {
|
| 1501 |
this.hideTypingIndicator();
|
| 1502 |
|
| 1503 |
-
// Generate AI response
|
| 1504 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1505 |
|
| 1506 |
// Add AI response
|
| 1507 |
this.addMessage(response, 'ai');
|
|
@@ -1537,7 +2120,7 @@
|
|
| 1537 |
}
|
| 1538 |
|
| 1539 |
generateAIResponse(userMessage) {
|
| 1540 |
-
// Simple AI response generator
|
| 1541 |
const responses = {
|
| 1542 |
quantum: "Quantum computing leverages quantum mechanics to process information. Unlike classical bits (0 or 1), quantum bits (qubits) can exist in superposition, enabling parallel computation. Key concepts include superposition, entanglement, and quantum interference.",
|
| 1543 |
neural: "Neural networks learn through backpropagation and gradient descent. They adjust weights based on prediction errors, minimizing loss functions. Deep learning uses multiple layers to extract hierarchical features from data.",
|
|
@@ -1879,8 +2462,11 @@
|
|
| 1879 |
// Initialize 3D visualization
|
| 1880 |
window.visualization = new AITutorVisualization();
|
| 1881 |
|
| 1882 |
-
// Initialize
|
| 1883 |
-
window.
|
|
|
|
|
|
|
|
|
|
| 1884 |
|
| 1885 |
// Initialize voice synthesis
|
| 1886 |
if ('speechSynthesis' in window) {
|
|
|
|
| 329 |
background: #ff5a5a;
|
| 330 |
}
|
| 331 |
|
| 332 |
+
/* === RAG TRAINING PANEL === */
|
| 333 |
+
.rag-training-panel {
|
| 334 |
+
position: absolute;
|
| 335 |
+
top: 30px;
|
| 336 |
+
left: 350px;
|
| 337 |
+
width: 350px;
|
| 338 |
+
height: calc(100vh - 100px);
|
| 339 |
+
background: rgba(20, 20, 30, 0.9);
|
| 340 |
+
backdrop-filter: blur(10px);
|
| 341 |
+
border-radius: 20px;
|
| 342 |
+
padding: 25px;
|
| 343 |
+
pointer-events: all;
|
| 344 |
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
| 345 |
+
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
| 346 |
+
z-index: 102;
|
| 347 |
+
opacity: 0;
|
| 348 |
+
transform: translateY(20px);
|
| 349 |
+
animation: slideIn 0.5s ease 1.4s forwards;
|
| 350 |
+
display: flex;
|
| 351 |
+
flex-direction: column;
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
.rag-header {
|
| 355 |
+
display: flex;
|
| 356 |
+
align-items: center;
|
| 357 |
+
gap: 10px;
|
| 358 |
+
margin-bottom: 20px;
|
| 359 |
+
color: #a0b0ff;
|
| 360 |
+
font-size: 1.1em;
|
| 361 |
+
font-weight: 300;
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
.rag-section {
|
| 365 |
+
margin-bottom: 25px;
|
| 366 |
+
}
|
| 367 |
+
|
| 368 |
+
.rag-label {
|
| 369 |
+
display: block;
|
| 370 |
+
margin-bottom: 10px;
|
| 371 |
+
font-size: 0.9em;
|
| 372 |
+
color: #8892b0;
|
| 373 |
+
display: flex;
|
| 374 |
+
align-items: center;
|
| 375 |
+
gap: 8px;
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
.rag-textarea {
|
| 379 |
+
width: 100%;
|
| 380 |
+
height: 120px;
|
| 381 |
+
background: rgba(255, 255, 255, 0.07);
|
| 382 |
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
| 383 |
+
border-radius: 10px;
|
| 384 |
+
padding: 12px 15px;
|
| 385 |
+
color: white;
|
| 386 |
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
| 387 |
+
font-size: 0.9em;
|
| 388 |
+
resize: vertical;
|
| 389 |
+
transition: all 0.3s ease;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
.rag-textarea:focus {
|
| 393 |
+
outline: none;
|
| 394 |
+
border-color: #5a6cff;
|
| 395 |
+
background: rgba(255, 255, 255, 0.1);
|
| 396 |
+
box-shadow: 0 0 0 2px rgba(90, 108, 255, 0.2);
|
| 397 |
+
}
|
| 398 |
+
|
| 399 |
+
.rag-file-upload {
|
| 400 |
+
width: 100%;
|
| 401 |
+
padding: 20px;
|
| 402 |
+
border: 2px dashed rgba(90, 108, 255, 0.3);
|
| 403 |
+
border-radius: 10px;
|
| 404 |
+
text-align: center;
|
| 405 |
+
cursor: pointer;
|
| 406 |
+
transition: all 0.3s ease;
|
| 407 |
+
margin-bottom: 15px;
|
| 408 |
+
}
|
| 409 |
+
|
| 410 |
+
.rag-file-upload:hover {
|
| 411 |
+
border-color: #5a6cff;
|
| 412 |
+
background: rgba(90, 108, 255, 0.05);
|
| 413 |
+
}
|
| 414 |
+
|
| 415 |
+
.rag-file-upload input {
|
| 416 |
+
display: none;
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
.rag-file-info {
|
| 420 |
+
font-size: 0.8em;
|
| 421 |
+
color: #8892b0;
|
| 422 |
+
margin-bottom: 15px;
|
| 423 |
+
text-align: center;
|
| 424 |
+
}
|
| 425 |
+
|
| 426 |
+
.rag-controls {
|
| 427 |
+
display: grid;
|
| 428 |
+
grid-template-columns: 1fr 1fr;
|
| 429 |
+
gap: 10px;
|
| 430 |
+
margin-top: 20px;
|
| 431 |
+
}
|
| 432 |
+
|
| 433 |
+
.rag-btn {
|
| 434 |
+
padding: 12px;
|
| 435 |
+
background: rgba(90, 108, 255, 0.1);
|
| 436 |
+
border: 1px solid rgba(90, 108, 255, 0.3);
|
| 437 |
+
color: #a0b0ff;
|
| 438 |
+
border-radius: 10px;
|
| 439 |
+
cursor: pointer;
|
| 440 |
+
transition: all 0.3s ease;
|
| 441 |
+
display: flex;
|
| 442 |
+
align-items: center;
|
| 443 |
+
justify-content: center;
|
| 444 |
+
gap: 8px;
|
| 445 |
+
font-size: 0.9em;
|
| 446 |
+
}
|
| 447 |
+
|
| 448 |
+
.rag-btn:hover {
|
| 449 |
+
background: rgba(90, 108, 255, 0.2);
|
| 450 |
+
transform: translateY(-2px);
|
| 451 |
+
}
|
| 452 |
+
|
| 453 |
+
.rag-btn.primary {
|
| 454 |
+
background: linear-gradient(135deg, #5a6cff, #7a8aff);
|
| 455 |
+
color: white;
|
| 456 |
+
}
|
| 457 |
+
|
| 458 |
+
.rag-btn.primary:hover {
|
| 459 |
+
background: linear-gradient(135deg, #7a8aff, #9aafff);
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
.rag-progress {
|
| 463 |
+
width: 100%;
|
| 464 |
+
height: 6px;
|
| 465 |
+
background: rgba(255, 255, 255, 0.1);
|
| 466 |
+
border-radius: 3px;
|
| 467 |
+
overflow: hidden;
|
| 468 |
+
margin-top: 15px;
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
.rag-progress-bar {
|
| 472 |
+
height: 100%;
|
| 473 |
+
background: linear-gradient(90deg, #5a6cff, #00ff9d);
|
| 474 |
+
width: 0%;
|
| 475 |
+
transition: width 0.3s ease;
|
| 476 |
+
}
|
| 477 |
+
|
| 478 |
+
.rag-status {
|
| 479 |
+
display: flex;
|
| 480 |
+
align-items: center;
|
| 481 |
+
gap: 8px;
|
| 482 |
+
margin-top: 15px;
|
| 483 |
+
padding: 10px;
|
| 484 |
+
background: rgba(0, 255, 157, 0.1);
|
| 485 |
+
border-radius: 10px;
|
| 486 |
+
font-size: 0.85em;
|
| 487 |
+
color: #00ff9d;
|
| 488 |
+
border: 1px solid rgba(0, 255, 157, 0.2);
|
| 489 |
+
}
|
| 490 |
+
|
| 491 |
+
.rag-knowledge-list {
|
| 492 |
+
max-height: 200px;
|
| 493 |
+
overflow-y: auto;
|
| 494 |
+
background: rgba(255, 255, 255, 0.05);
|
| 495 |
+
border-radius: 10px;
|
| 496 |
+
padding: 10px;
|
| 497 |
+
margin-top: 10px;
|
| 498 |
+
}
|
| 499 |
+
|
| 500 |
+
.knowledge-item {
|
| 501 |
+
padding: 8px 12px;
|
| 502 |
+
background: rgba(255, 255, 255, 0.07);
|
| 503 |
+
border-radius: 8px;
|
| 504 |
+
margin-bottom: 8px;
|
| 505 |
+
font-size: 0.85em;
|
| 506 |
+
display: flex;
|
| 507 |
+
justify-content: space-between;
|
| 508 |
+
align-items: center;
|
| 509 |
+
}
|
| 510 |
+
|
| 511 |
+
.knowledge-item .delete-btn {
|
| 512 |
+
color: #ff5a5a;
|
| 513 |
+
cursor: pointer;
|
| 514 |
+
padding: 4px;
|
| 515 |
+
}
|
| 516 |
+
|
| 517 |
/* === VOICE CONTROLS PANEL === */
|
| 518 |
.voice-controls {
|
| 519 |
position: absolute;
|
|
|
|
| 523 |
backdrop-filter: blur(10px);
|
| 524 |
border-radius: 20px;
|
| 525 |
padding: 25px;
|
| 526 |
+
width: 300px;
|
| 527 |
pointer-events: all;
|
| 528 |
border: 1px solid rgba(255, 255, 255, 0.1);
|
| 529 |
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
|
|
|
| 905 |
}
|
| 906 |
|
| 907 |
/* Responsive adjustments */
|
| 908 |
+
@media (max-width: 1600px) {
|
| 909 |
+
.rag-training-panel {
|
| 910 |
+
left: 30px;
|
| 911 |
+
top: 150px;
|
| 912 |
+
height: calc(100vh - 180px);
|
| 913 |
+
}
|
| 914 |
+
|
| 915 |
.voice-controls {
|
| 916 |
right: 30px;
|
| 917 |
bottom: 400px;
|
|
|
|
| 931 |
padding: 20px;
|
| 932 |
width: 260px;
|
| 933 |
}
|
| 934 |
+
|
| 935 |
+
.rag-training-panel {
|
| 936 |
+
padding: 20px;
|
| 937 |
+
width: 320px;
|
| 938 |
+
}
|
| 939 |
}
|
| 940 |
</style>
|
| 941 |
</head>
|
|
|
|
| 951 |
</div>
|
| 952 |
</div>
|
| 953 |
|
| 954 |
+
<!-- RAG Training Panel -->
|
| 955 |
+
<div class="rag-training-panel">
|
| 956 |
+
<div class="rag-header">
|
| 957 |
+
<i class="fas fa-graduation-cap"></i>
|
| 958 |
+
<span>AI Tutor Training</span>
|
| 959 |
+
</div>
|
| 960 |
+
|
| 961 |
+
<div class="rag-section">
|
| 962 |
+
<label class="rag-label">
|
| 963 |
+
<i class="fas fa-book"></i>
|
| 964 |
+
Add Knowledge
|
| 965 |
+
</label>
|
| 966 |
+
<textarea class="rag-textarea" id="knowledgeText" placeholder="Enter text, notes, or educational content to teach the AI..."></textarea>
|
| 967 |
+
</div>
|
| 968 |
+
|
| 969 |
+
<div class="rag-section">
|
| 970 |
+
<label class="rag-label">
|
| 971 |
+
<i class="fas fa-file-upload"></i>
|
| 972 |
+
Upload Documents
|
| 973 |
+
</label>
|
| 974 |
+
<div class="rag-file-upload" id="fileUploadArea">
|
| 975 |
+
<i class="fas fa-cloud-upload-alt" style="font-size: 2em; margin-bottom: 10px; color: #5a6cff;"></i>
|
| 976 |
+
<div>Drag & drop files or click to browse</div>
|
| 977 |
+
<div style="font-size: 0.8em; margin-top: 5px;">Supports: PDF, TXT, DOCX, MD</div>
|
| 978 |
+
<input type="file" id="fileInput" accept=".pdf,.txt,.docx,.md" multiple>
|
| 979 |
+
</div>
|
| 980 |
+
<div class="rag-file-info">
|
| 981 |
+
Files will be processed for RAG training
|
| 982 |
+
</div>
|
| 983 |
+
</div>
|
| 984 |
+
|
| 985 |
+
<div class="rag-controls">
|
| 986 |
+
<button class="rag-btn" id="addKnowledgeBtn">
|
| 987 |
+
<i class="fas fa-plus"></i>
|
| 988 |
+
Add Text
|
| 989 |
+
</button>
|
| 990 |
+
<button class="rag-btn primary" id="trainBtn">
|
| 991 |
+
<i class="fas fa-brain"></i>
|
| 992 |
+
Train AI
|
| 993 |
+
</button>
|
| 994 |
+
</div>
|
| 995 |
+
|
| 996 |
+
<div class="rag-progress">
|
| 997 |
+
<div class="rag-progress-bar" id="trainingProgress"></div>
|
| 998 |
+
</div>
|
| 999 |
+
|
| 1000 |
+
<div class="rag-status" id="ragStatus" style="display: none;">
|
| 1001 |
+
<i class="fas fa-sync-alt fa-spin"></i>
|
| 1002 |
+
<span id="ragStatusText">Training in progress...</span>
|
| 1003 |
+
</div>
|
| 1004 |
+
|
| 1005 |
+
<div class="rag-section">
|
| 1006 |
+
<label class="rag-label">
|
| 1007 |
+
<i class="fas fa-database"></i>
|
| 1008 |
+
Knowledge Base
|
| 1009 |
+
</label>
|
| 1010 |
+
<div class="rag-knowledge-list" id="knowledgeList">
|
| 1011 |
+
<!-- Knowledge items will be added here -->
|
| 1012 |
+
<div class="knowledge-item">
|
| 1013 |
+
<span>Physics Basics</span>
|
| 1014 |
+
<i class="fas fa-trash delete-btn"></i>
|
| 1015 |
+
</div>
|
| 1016 |
+
<div class="knowledge-item">
|
| 1017 |
+
<span>Calculus Fundamentals</span>
|
| 1018 |
+
<i class="fas fa-trash delete-btn"></i>
|
| 1019 |
+
</div>
|
| 1020 |
+
</div>
|
| 1021 |
+
</div>
|
| 1022 |
+
</div>
|
| 1023 |
+
|
| 1024 |
<!-- Voice Controls Panel -->
|
| 1025 |
<div class="voice-controls">
|
| 1026 |
<div class="voice-header">
|
|
|
|
| 1118 |
|
| 1119 |
<div class="message message-ai">
|
| 1120 |
<div class="message-content">
|
| 1121 |
+
You can type your questions or click the microphone to speak. I'll respond with explanations, examples, and follow-up questions to enhance your understanding.
|
| 1122 |
</div>
|
| 1123 |
<div class="message-time">Just now</div>
|
| 1124 |
</div>
|
|
|
|
| 1253 |
document.getElementById('loadingText').textContent = text;
|
| 1254 |
}
|
| 1255 |
|
| 1256 |
+
// RAG AI Tutor System
|
| 1257 |
+
class RAGAITutor {
|
| 1258 |
+
constructor() {
|
| 1259 |
+
this.knowledgeBase = [];
|
| 1260 |
+
this.vectorStore = null;
|
| 1261 |
+
this.isTraining = false;
|
| 1262 |
+
this.currentSession = null;
|
| 1263 |
+
this.init();
|
| 1264 |
+
}
|
| 1265 |
+
|
| 1266 |
+
init() {
|
| 1267 |
+
this.setupEventListeners();
|
| 1268 |
+
this.loadSampleKnowledge();
|
| 1269 |
+
}
|
| 1270 |
+
|
| 1271 |
+
loadSampleKnowledge() {
|
| 1272 |
+
// Add some sample knowledge for demonstration
|
| 1273 |
+
this.addKnowledgeItem({
|
| 1274 |
+
id: Date.now(),
|
| 1275 |
+
title: "Physics Basics",
|
| 1276 |
+
content: "Newton's laws of motion: 1) An object at rest stays at rest unless acted upon by a force. 2) Force equals mass times acceleration. 3) For every action, there is an equal and opposite reaction.",
|
| 1277 |
+
type: "text",
|
| 1278 |
+
timestamp: new Date().toISOString()
|
| 1279 |
+
});
|
| 1280 |
+
|
| 1281 |
+
this.addKnowledgeItem({
|
| 1282 |
+
id: Date.now() + 1,
|
| 1283 |
+
title: "Calculus Fundamentals",
|
| 1284 |
+
content: "The derivative measures the rate of change of a function. The integral measures the accumulation of a quantity. The Fundamental Theorem of Calculus connects derivatives and integrals.",
|
| 1285 |
+
type: "text",
|
| 1286 |
+
timestamp: new Date().toISOString()
|
| 1287 |
+
});
|
| 1288 |
+
|
| 1289 |
+
this.updateKnowledgeList();
|
| 1290 |
+
}
|
| 1291 |
+
|
| 1292 |
+
setupEventListeners() {
|
| 1293 |
+
// Add knowledge button
|
| 1294 |
+
document.getElementById('addKnowledgeBtn').addEventListener('click', () => {
|
| 1295 |
+
this.addKnowledgeFromText();
|
| 1296 |
+
});
|
| 1297 |
+
|
| 1298 |
+
// Train button
|
| 1299 |
+
document.getElementById('trainBtn').addEventListener('click', () => {
|
| 1300 |
+
this.trainRAGModel();
|
| 1301 |
+
});
|
| 1302 |
+
|
| 1303 |
+
// File upload
|
| 1304 |
+
const fileInput = document.getElementById('fileInput');
|
| 1305 |
+
const uploadArea = document.getElementById('fileUploadArea');
|
| 1306 |
+
|
| 1307 |
+
uploadArea.addEventListener('click', () => {
|
| 1308 |
+
fileInput.click();
|
| 1309 |
+
});
|
| 1310 |
+
|
| 1311 |
+
uploadArea.addEventListener('dragover', (e) => {
|
| 1312 |
+
e.preventDefault();
|
| 1313 |
+
uploadArea.style.borderColor = '#5a6cff';
|
| 1314 |
+
uploadArea.style.background = 'rgba(90, 108, 255, 0.1)';
|
| 1315 |
+
});
|
| 1316 |
+
|
| 1317 |
+
uploadArea.addEventListener('dragleave', () => {
|
| 1318 |
+
uploadArea.style.borderColor = 'rgba(90, 108, 255, 0.3)';
|
| 1319 |
+
uploadArea.style.background = 'transparent';
|
| 1320 |
+
});
|
| 1321 |
+
|
| 1322 |
+
uploadArea.addEventListener('drop', (e) => {
|
| 1323 |
+
e.preventDefault();
|
| 1324 |
+
uploadArea.style.borderColor = 'rgba(90, 108, 255, 0.3)';
|
| 1325 |
+
uploadArea.style.background = 'transparent';
|
| 1326 |
+
|
| 1327 |
+
const files = e.dataTransfer.files;
|
| 1328 |
+
this.processUploadedFiles(files);
|
| 1329 |
+
});
|
| 1330 |
+
|
| 1331 |
+
fileInput.addEventListener('change', (e) => {
|
| 1332 |
+
const files = e.target.files;
|
| 1333 |
+
this.processUploadedFiles(files);
|
| 1334 |
+
});
|
| 1335 |
+
|
| 1336 |
+
// Knowledge list deletion
|
| 1337 |
+
document.getElementById('knowledgeList').addEventListener('click', (e) => {
|
| 1338 |
+
if (e.target.classList.contains('delete-btn')) {
|
| 1339 |
+
const item = e.target.closest('.knowledge-item');
|
| 1340 |
+
const title = item.querySelector('span').textContent;
|
| 1341 |
+
this.removeKnowledgeItem(title);
|
| 1342 |
+
}
|
| 1343 |
+
});
|
| 1344 |
+
}
|
| 1345 |
+
|
| 1346 |
+
addKnowledgeFromText() {
|
| 1347 |
+
const textArea = document.getElementById('knowledgeText');
|
| 1348 |
+
const content = textArea.value.trim();
|
| 1349 |
+
|
| 1350 |
+
if (!content) {
|
| 1351 |
+
this.showRAGStatus('Please enter some knowledge content', 'warning');
|
| 1352 |
+
return;
|
| 1353 |
+
}
|
| 1354 |
+
|
| 1355 |
+
const title = content.substring(0, 50) + (content.length > 50 ? '...' : '');
|
| 1356 |
+
|
| 1357 |
+
const knowledgeItem = {
|
| 1358 |
+
id: Date.now(),
|
| 1359 |
+
title: title,
|
| 1360 |
+
content: content,
|
| 1361 |
+
type: "text",
|
| 1362 |
+
timestamp: new Date().toISOString()
|
| 1363 |
+
};
|
| 1364 |
+
|
| 1365 |
+
this.addKnowledgeItem(knowledgeItem);
|
| 1366 |
+
textArea.value = '';
|
| 1367 |
+
this.showRAGStatus('Knowledge added successfully!', 'success');
|
| 1368 |
+
}
|
| 1369 |
+
|
| 1370 |
+
addKnowledgeItem(item) {
|
| 1371 |
+
this.knowledgeBase.push(item);
|
| 1372 |
+
this.updateKnowledgeList();
|
| 1373 |
+
}
|
| 1374 |
+
|
| 1375 |
+
removeKnowledgeItem(title) {
|
| 1376 |
+
this.knowledgeBase = this.knowledgeBase.filter(item => item.title !== title);
|
| 1377 |
+
this.updateKnowledgeList();
|
| 1378 |
+
this.showRAGStatus('Knowledge removed', 'info');
|
| 1379 |
+
}
|
| 1380 |
+
|
| 1381 |
+
updateKnowledgeList() {
|
| 1382 |
+
const list = document.getElementById('knowledgeList');
|
| 1383 |
+
list.innerHTML = '';
|
| 1384 |
+
|
| 1385 |
+
this.knowledgeBase.forEach(item => {
|
| 1386 |
+
const div = document.createElement('div');
|
| 1387 |
+
div.className = 'knowledge-item';
|
| 1388 |
+
div.innerHTML = `
|
| 1389 |
+
<span>${item.title}</span>
|
| 1390 |
+
<i class="fas fa-trash delete-btn"></i>
|
| 1391 |
+
`;
|
| 1392 |
+
list.appendChild(div);
|
| 1393 |
+
});
|
| 1394 |
+
}
|
| 1395 |
+
|
| 1396 |
+
async processUploadedFiles(files) {
|
| 1397 |
+
if (!files.length) return;
|
| 1398 |
+
|
| 1399 |
+
this.showRAGStatus(`Processing ${files.length} file(s)...`, 'processing');
|
| 1400 |
+
|
| 1401 |
+
for (let file of files) {
|
| 1402 |
+
await this.processFile(file);
|
| 1403 |
+
}
|
| 1404 |
+
|
| 1405 |
+
this.showRAGStatus('Files processed successfully!', 'success');
|
| 1406 |
+
this.updateKnowledgeList();
|
| 1407 |
+
}
|
| 1408 |
+
|
| 1409 |
+
async processFile(file) {
|
| 1410 |
+
return new Promise((resolve) => {
|
| 1411 |
+
const reader = new FileReader();
|
| 1412 |
+
|
| 1413 |
+
reader.onload = async (e) => {
|
| 1414 |
+
const content = e.target.result;
|
| 1415 |
+
const fileName = file.name.replace(/\.[^/.]+$/, ""); // Remove extension
|
| 1416 |
+
|
| 1417 |
+
const knowledgeItem = {
|
| 1418 |
+
id: Date.now(),
|
| 1419 |
+
title: `${fileName} (${file.type})`,
|
| 1420 |
+
content: content.substring(0, 5000), // Limit content
|
| 1421 |
+
type: file.type,
|
| 1422 |
+
filename: file.name,
|
| 1423 |
+
timestamp: new Date().toISOString()
|
| 1424 |
+
};
|
| 1425 |
+
|
| 1426 |
+
this.addKnowledgeItem(knowledgeItem);
|
| 1427 |
+
resolve();
|
| 1428 |
+
};
|
| 1429 |
+
|
| 1430 |
+
reader.onerror = () => {
|
| 1431 |
+
this.showRAGStatus(`Error reading file: ${file.name}`, 'error');
|
| 1432 |
+
resolve();
|
| 1433 |
+
};
|
| 1434 |
+
|
| 1435 |
+
reader.readAsText(file);
|
| 1436 |
+
});
|
| 1437 |
+
}
|
| 1438 |
+
|
| 1439 |
+
async trainRAGModel() {
|
| 1440 |
+
if (this.knowledgeBase.length === 0) {
|
| 1441 |
+
this.showRAGStatus('No knowledge to train on. Please add some content first.', 'warning');
|
| 1442 |
+
return;
|
| 1443 |
+
}
|
| 1444 |
+
|
| 1445 |
+
this.isTraining = true;
|
| 1446 |
+
this.showRAGStatus('Starting RAG training...', 'processing');
|
| 1447 |
+
|
| 1448 |
+
// Simulate training progress
|
| 1449 |
+
const progressBar = document.getElementById('trainingProgress');
|
| 1450 |
+
progressBar.style.width = '0%';
|
| 1451 |
+
|
| 1452 |
+
// Simulate training steps
|
| 1453 |
+
const steps = ['Preprocessing text', 'Creating embeddings', 'Building vector store', 'Optimizing retrieval'];
|
| 1454 |
+
|
| 1455 |
+
for (let i = 0; i < steps.length; i++) {
|
| 1456 |
+
this.showRAGStatus(steps[i], 'processing');
|
| 1457 |
+
progressBar.style.width = `${((i + 1) / steps.length) * 100}%`;
|
| 1458 |
+
|
| 1459 |
+
// Simulate processing time
|
| 1460 |
+
await this.sleep(1000);
|
| 1461 |
+
}
|
| 1462 |
+
|
| 1463 |
+
// In a real implementation, this would:
|
| 1464 |
+
// 1. Chunk the knowledge base
|
| 1465 |
+
// 2. Create embeddings using Hugging Face models
|
| 1466 |
+
// 3. Store in a vector database
|
| 1467 |
+
// 4. Set up retrieval mechanisms
|
| 1468 |
+
|
| 1469 |
+
// For demonstration, we'll simulate successful training
|
| 1470 |
+
this.vectorStore = {
|
| 1471 |
+
size: this.knowledgeBase.length,
|
| 1472 |
+
trainedAt: new Date().toISOString(),
|
| 1473 |
+
model: 'all-MiniLM-L6-v2' // Example embedding model
|
| 1474 |
+
};
|
| 1475 |
+
|
| 1476 |
+
this.isTraining = false;
|
| 1477 |
+
this.showRAGStatus(`RAG training complete! ${this.knowledgeBase.length} documents indexed.`, 'success');
|
| 1478 |
+
|
| 1479 |
+
// Reset progress bar after delay
|
| 1480 |
+
setTimeout(() => {
|
| 1481 |
+
progressBar.style.width = '0%';
|
| 1482 |
+
}, 2000);
|
| 1483 |
+
}
|
| 1484 |
+
|
| 1485 |
+
async queryKnowledge(query) {
|
| 1486 |
+
if (!this.vectorStore) {
|
| 1487 |
+
return "I haven't been trained on any specific knowledge yet. Please add some content and train me first!";
|
| 1488 |
+
}
|
| 1489 |
+
|
| 1490 |
+
// Simulate RAG retrieval
|
| 1491 |
+
// In a real implementation, this would:
|
| 1492 |
+
// 1. Embed the query
|
| 1493 |
+
// 2. Search vector store for similar chunks
|
| 1494 |
+
// 3. Retrieve top-k relevant documents
|
| 1495 |
+
// 4. Generate answer using LLM with retrieved context
|
| 1496 |
+
|
| 1497 |
+
// For demonstration, find relevant knowledge
|
| 1498 |
+
const relevantKnowledge = this.findRelevantKnowledge(query);
|
| 1499 |
+
|
| 1500 |
+
if (relevantKnowledge.length === 0) {
|
| 1501 |
+
return "I couldn't find specific information about that in my knowledge base. Could you rephrase or ask something else?";
|
| 1502 |
+
}
|
| 1503 |
+
|
| 1504 |
+
// Generate response based on retrieved knowledge
|
| 1505 |
+
return this.generateResponse(query, relevantKnowledge);
|
| 1506 |
+
}
|
| 1507 |
+
|
| 1508 |
+
findRelevantKnowledge(query) {
|
| 1509 |
+
const queryLower = query.toLowerCase();
|
| 1510 |
+
const relevant = [];
|
| 1511 |
+
|
| 1512 |
+
for (const item of this.knowledgeBase) {
|
| 1513 |
+
if (item.content.toLowerCase().includes(queryLower) ||
|
| 1514 |
+
item.title.toLowerCase().includes(queryLower)) {
|
| 1515 |
+
relevant.push(item);
|
| 1516 |
+
|
| 1517 |
+
// Limit to 3 most relevant items
|
| 1518 |
+
if (relevant.length >= 3) break;
|
| 1519 |
+
}
|
| 1520 |
+
}
|
| 1521 |
+
|
| 1522 |
+
return relevant;
|
| 1523 |
+
}
|
| 1524 |
+
|
| 1525 |
+
generateResponse(query, relevantKnowledge) {
|
| 1526 |
+
const context = relevantKnowledge.map(item => item.content).join('\n\n');
|
| 1527 |
+
|
| 1528 |
+
// Simulate LLM generation with context
|
| 1529 |
+
// In real implementation, use Hugging Face Inference API or similar
|
| 1530 |
+
return `Based on my knowledge base:\n\n${context}\n\nRegarding your question "${query}", here's what I can explain...`;
|
| 1531 |
+
}
|
| 1532 |
+
|
| 1533 |
+
showRAGStatus(message, type = 'info') {
|
| 1534 |
+
const statusEl = document.getElementById('ragStatus');
|
| 1535 |
+
const statusText = document.getElementById('ragStatusText');
|
| 1536 |
+
|
| 1537 |
+
statusText.textContent = message;
|
| 1538 |
+
|
| 1539 |
+
// Set color based on type
|
| 1540 |
+
const colors = {
|
| 1541 |
+
'info': '#5a6cff',
|
| 1542 |
+
'success': '#00ff9d',
|
| 1543 |
+
'warning': '#ffa500',
|
| 1544 |
+
'error': '#ff5a5a',
|
| 1545 |
+
'processing': '#a0b0ff'
|
| 1546 |
+
};
|
| 1547 |
+
|
| 1548 |
+
statusEl.style.borderColor = colors[type] + '30';
|
| 1549 |
+
statusEl.style.background = colors[type] + '10';
|
| 1550 |
+
statusEl.style.color = colors[type];
|
| 1551 |
+
|
| 1552 |
+
statusEl.style.display = 'flex';
|
| 1553 |
+
|
| 1554 |
+
// Auto-hide after 5 seconds unless it's a processing message
|
| 1555 |
+
if (type !== 'processing') {
|
| 1556 |
+
setTimeout(() => {
|
| 1557 |
+
statusEl.style.display = 'none';
|
| 1558 |
+
}, 5000);
|
| 1559 |
+
}
|
| 1560 |
+
}
|
| 1561 |
+
|
| 1562 |
+
sleep(ms) {
|
| 1563 |
+
return new Promise(resolve => setTimeout(resolve, ms));
|
| 1564 |
+
}
|
| 1565 |
+
}
|
| 1566 |
+
|
| 1567 |
+
// Advanced Voice Synthesis System
|
| 1568 |
class VoiceSynthesis {
|
| 1569 |
constructor() {
|
| 1570 |
this.synth = window.speechSynthesis;
|
|
|
|
| 1881 |
|
| 1882 |
// Chat Interface Functionality
|
| 1883 |
class ChatInterface {
|
| 1884 |
+
constructor(ragTutor) {
|
| 1885 |
+
this.ragTutor = ragTutor;
|
| 1886 |
this.isListening = false;
|
| 1887 |
this.voiceAnimationInterval = null;
|
| 1888 |
this.initChat();
|
|
|
|
| 2018 |
}, 500);
|
| 2019 |
}
|
| 2020 |
|
| 2021 |
+
async sendMessage() {
|
| 2022 |
const message = this.chatInput.value.trim();
|
| 2023 |
if (message === '') return;
|
| 2024 |
|
|
|
|
| 2030 |
this.autoResizeTextarea();
|
| 2031 |
|
| 2032 |
// Process and respond
|
| 2033 |
+
await this.processAIResponse(message);
|
| 2034 |
}
|
| 2035 |
|
| 2036 |
addMessage(content, sender) {
|
|
|
|
| 2063 |
return div.innerHTML;
|
| 2064 |
}
|
| 2065 |
|
| 2066 |
+
async processAIResponse(userMessage) {
|
| 2067 |
// Show typing indicator
|
| 2068 |
this.showTypingIndicator();
|
| 2069 |
|
|
|
|
| 2075 |
// Simulate AI processing time
|
| 2076 |
const processingTime = 1000 + Math.random() * 2000;
|
| 2077 |
|
| 2078 |
+
setTimeout(async () => {
|
| 2079 |
this.hideTypingIndicator();
|
| 2080 |
|
| 2081 |
+
// Generate AI response using RAG if available
|
| 2082 |
+
let response;
|
| 2083 |
+
if (this.ragTutor && this.ragTutor.vectorStore) {
|
| 2084 |
+
response = await this.ragTutor.queryKnowledge(userMessage);
|
| 2085 |
+
} else {
|
| 2086 |
+
response = this.generateAIResponse(userMessage);
|
| 2087 |
+
}
|
| 2088 |
|
| 2089 |
// Add AI response
|
| 2090 |
this.addMessage(response, 'ai');
|
|
|
|
| 2120 |
}
|
| 2121 |
|
| 2122 |
generateAIResponse(userMessage) {
|
| 2123 |
+
// Simple AI response generator (fallback when RAG is not trained)
|
| 2124 |
const responses = {
|
| 2125 |
quantum: "Quantum computing leverages quantum mechanics to process information. Unlike classical bits (0 or 1), quantum bits (qubits) can exist in superposition, enabling parallel computation. Key concepts include superposition, entanglement, and quantum interference.",
|
| 2126 |
neural: "Neural networks learn through backpropagation and gradient descent. They adjust weights based on prediction errors, minimizing loss functions. Deep learning uses multiple layers to extract hierarchical features from data.",
|
|
|
|
| 2462 |
// Initialize 3D visualization
|
| 2463 |
window.visualization = new AITutorVisualization();
|
| 2464 |
|
| 2465 |
+
// Initialize RAG AI Tutor
|
| 2466 |
+
window.ragTutor = new RAGAITutor();
|
| 2467 |
+
|
| 2468 |
+
// Initialize chat interface with RAG tutor
|
| 2469 |
+
window.chatInterface = new ChatInterface(window.ragTutor);
|
| 2470 |
|
| 2471 |
// Initialize voice synthesis
|
| 2472 |
if ('speechSynthesis' in window) {
|