Reality123b commited on
Commit
622fa09
·
verified ·
1 Parent(s): 3c9310d

Update application/templates/index.html

Browse files
Files changed (1) hide show
  1. application/templates/index.html +251 -35
application/templates/index.html CHANGED
@@ -13,7 +13,7 @@
13
  width: 12px;
14
  }
15
  ::-webkit-scrollbar-track {
16
- background: transparent;
17
  }
18
  ::-webkit-scrollbar-thumb {
19
  background: rgb(43, 43, 43);
@@ -29,7 +29,7 @@ html,body{
29
  width: 100vw;
30
  height: 100vh;
31
  overflow: hidden;
32
- scrollbar-width: thin;
33
  scrollbar-color: rgb(41, 41, 41) transparent;
34
  font-family: 'Inter';
35
  }
@@ -105,7 +105,7 @@ nav{
105
  gap: 1vh;
106
  position: relative;
107
  font-size: medium;
108
-
109
  }
110
  .prevChat{
111
  min-height: 5vh;
@@ -145,8 +145,8 @@ nav{
145
  z-index: 50;
146
  top: 8vh;
147
  display: flex;
148
- flex-direction: column;
149
- justify-content: flex-end;
150
  z-index: 1;
151
  }
152
  .inputs {
@@ -162,8 +162,8 @@ nav{
162
  border-top-left-radius: 20px;
163
  border-bottom-right-radius: 50px;
164
  font-size: large;
165
- position: relative;
166
- margin-top: auto;
167
  align-self: center;
168
  }
169
  .textBox{
@@ -185,11 +185,11 @@ nav{
185
  height: 6vh;
186
  }
187
  .messages {
188
- overflow-y: auto;
189
  color: white;
190
  padding: 10px;
191
  display: flex;
192
- flex-direction: column;
193
  position: relative;
194
  }
195
  .user{
@@ -201,7 +201,7 @@ nav{
201
  font-weight: 300;
202
  border-radius: 10px;
203
  line-height: 130%;
204
-
205
  }
206
  .user p{
207
  color: #b4b4b4;
@@ -217,10 +217,10 @@ nav{
217
  }
218
  .ai p {
219
  opacity: 0.9;
220
- font-weight: 300;
221
  font-size: medium;
222
  line-height: 1.6;
223
- color: #c5c5c5;
224
  background-color: rgba(28, 28, 28, 0.5);
225
  padding: 20px;
226
  border-radius: 10px;
@@ -284,7 +284,7 @@ code{
284
  font-family: 'Inter';
285
  font-weight: 300;
286
  font-size: 15px;
287
- color: #cfcfcf;
288
  opacity: 0.9;
289
  padding-left: 10px;
290
  }
@@ -380,12 +380,10 @@ code{
380
  transition: max-height 0.3s ease-out;
381
  }
382
  .thinking-content.open {
383
- max-height: 500px;
384
  transition: max-height 0.5s ease-in;
385
  }
386
  </style>
387
- <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
388
- <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
389
  <title>Chat Completion Demo</title>
390
  </head>
391
  <body>
@@ -414,49 +412,267 @@ code{
414
  </div>
415
  </div>
416
  <script>
417
- // Add this to your existing JavaScript or create a new script
418
  function createThinkingElement(thinkingContent) {
419
  const container = document.createElement('div');
420
  container.className = 'thinking-container';
421
-
422
  const header = document.createElement('div');
423
  header.className = 'thinking-header';
424
-
425
  const title = document.createElement('span');
426
  title.className = 'thinking-title';
427
- title.textContent = 'Reasoning about it';
428
-
429
  const arrow = document.createElement('i');
430
  arrow.className = 'fa-solid fa-chevron-down thinking-arrow';
431
-
432
  const content = document.createElement('div');
433
  content.className = 'thinking-content';
434
- content.textContent = thinkingContent;
435
-
436
  header.appendChild(title);
437
  header.appendChild(arrow);
438
  container.appendChild(header);
439
  container.appendChild(content);
440
-
441
  header.addEventListener('click', () => {
442
  arrow.classList.toggle('open');
443
  content.classList.toggle('open');
444
  });
445
-
446
  return container;
447
  }
448
- // Example usage in your message processing logic:
449
- function processMessage(message) {
450
- const thinkMatch = message.match(/<think>(.*?)<\/think>/s);
451
- if (thinkMatch) {
452
- const thinkingContent = thinkMatch[1].trim();
 
 
 
 
 
 
 
 
 
 
453
  const thinkingElement = createThinkingElement(thinkingContent);
454
- // Insert the thinking element into your message container
455
- document.getElementById('messages').appendChild(thinkingElement);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
456
  }
457
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
458
  </script>
459
- <script src="{{ url_for('static', filename='js/script.js') }}" type="module"></script>
460
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
 
461
  </body>
462
- </html>
 
13
  width: 12px;
14
  }
15
  ::-webkit-scrollbar-track {
16
+ background: transparent;
17
  }
18
  ::-webkit-scrollbar-thumb {
19
  background: rgb(43, 43, 43);
 
29
  width: 100vw;
30
  height: 100vh;
31
  overflow: hidden;
32
+ scrollbar-width: thin;
33
  scrollbar-color: rgb(41, 41, 41) transparent;
34
  font-family: 'Inter';
35
  }
 
105
  gap: 1vh;
106
  position: relative;
107
  font-size: medium;
108
+
109
  }
110
  .prevChat{
111
  min-height: 5vh;
 
145
  z-index: 50;
146
  top: 8vh;
147
  display: flex;
148
+ flex-direction: column;
149
+ justify-content: flex-end;
150
  z-index: 1;
151
  }
152
  .inputs {
 
162
  border-top-left-radius: 20px;
163
  border-bottom-right-radius: 50px;
164
  font-size: large;
165
+ position: relative;
166
+ margin-top: auto;
167
  align-self: center;
168
  }
169
  .textBox{
 
185
  height: 6vh;
186
  }
187
  .messages {
188
+ overflow-y: auto;
189
  color: white;
190
  padding: 10px;
191
  display: flex;
192
+ flex-direction: column;
193
  position: relative;
194
  }
195
  .user{
 
201
  font-weight: 300;
202
  border-radius: 10px;
203
  line-height: 130%;
204
+
205
  }
206
  .user p{
207
  color: #b4b4b4;
 
217
  }
218
  .ai p {
219
  opacity: 0.9;
220
+ font-weight: 300;
221
  font-size: medium;
222
  line-height: 1.6;
223
+ color: #c5c5c5;
224
  background-color: rgba(28, 28, 28, 0.5);
225
  padding: 20px;
226
  border-radius: 10px;
 
284
  font-family: 'Inter';
285
  font-weight: 300;
286
  font-size: 15px;
287
+ color: #cfcfcf;
288
  opacity: 0.9;
289
  padding-left: 10px;
290
  }
 
380
  transition: max-height 0.3s ease-out;
381
  }
382
  .thinking-content.open {
383
+ max-height: 500px; /* Adjust as needed */
384
  transition: max-height 0.5s ease-in;
385
  }
386
  </style>
 
 
387
  <title>Chat Completion Demo</title>
388
  </head>
389
  <body>
 
412
  </div>
413
  </div>
414
  <script>
415
+ // Put the JavaScript code here, *inside* the <script> tags
416
  function createThinkingElement(thinkingContent) {
417
  const container = document.createElement('div');
418
  container.className = 'thinking-container';
419
+
420
  const header = document.createElement('div');
421
  header.className = 'thinking-header';
422
+
423
  const title = document.createElement('span');
424
  title.className = 'thinking-title';
425
+ title.textContent = 'Reasoning';
426
+
427
  const arrow = document.createElement('i');
428
  arrow.className = 'fa-solid fa-chevron-down thinking-arrow';
429
+
430
  const content = document.createElement('div');
431
  content.className = 'thinking-content';
432
+ content.innerHTML = thinkingContent; // Use innerHTML to allow for formatting
433
+
434
  header.appendChild(title);
435
  header.appendChild(arrow);
436
  container.appendChild(header);
437
  container.appendChild(content);
438
+
439
  header.addEventListener('click', () => {
440
  arrow.classList.toggle('open');
441
  content.classList.toggle('open');
442
  });
443
+
444
  return container;
445
  }
446
+
447
+ async function displayAIMessage(message) {
448
+ const messagesContainer = document.getElementById('messages');
449
+ const aiMessageDiv = document.createElement('div');
450
+ aiMessageDiv.className = 'ai';
451
+
452
+ // Check for <think> tags
453
+ const thinkRegex = /<think>(.*?)<\/think>/s;
454
+ const match = message.match(thinkRegex);
455
+
456
+ if (match) {
457
+ const thinkingContent = match[1].trim();
458
+ const otherContent = message.replace(thinkRegex, '').trim();
459
+
460
+ // Create and append the "Reasoning" element
461
  const thinkingElement = createThinkingElement(thinkingContent);
462
+ aiMessageDiv.appendChild(thinkingElement);
463
+
464
+ // Create and append the regular AI message content (if any)
465
+ if (otherContent) {
466
+ const aiTextP = document.createElement('p');
467
+ aiTextP.innerHTML = otherContent.replace(/\n/g, '<br>');
468
+ aiMessageDiv.appendChild(aiTextP);
469
+ }
470
+ } else {
471
+ // No <think> tags, just display the message normally
472
+ const aiTextP = document.createElement('p');
473
+ aiTextP.innerHTML = message.replace(/\n/g, '<br>');
474
+ aiMessageDiv.appendChild(aiTextP);
475
+ }
476
+
477
+ messagesContainer.appendChild(aiMessageDiv);
478
+ messagesContainer.scrollTop = messagesContainer.scrollHeight; // Scroll to bottom
479
+ hljs.highlightAll();
480
+ }
481
+
482
+
483
+
484
+ const sendBtn = document.getElementById("sendBtn");
485
+ const textBox = document.getElementById("textBox");
486
+ const hamburger = document.getElementById("hamburger");
487
+ const menu = document.getElementById("menu");
488
+ const newChat = document.getElementById("newChat");
489
+ const prevChatsCont = document.getElementById("prevChatsCont");
490
+ const models = document.getElementById("models");
491
+ const webSearchBtn = document.getElementById("webSearch");
492
+ let chats; //store the chats array.
493
+
494
+ function addChatToMenu(chat) {
495
+ const prevChat = document.createElement("div");
496
+ prevChat.className = "prevChat";
497
+ const icon = document.createElement("i");
498
+ icon.className = "fa-regular fa-message";
499
+ prevChat.appendChild(icon);
500
+
501
+ const chatTitle = document.createElement("p");
502
+ // Use the first user message as the chat title (or a default if none)
503
+ const firstUserMessage = chat.find(msg => msg.role === 'user')?.content || 'New Chat';
504
+
505
+ // Shorten the title to, say, 20 characters, and add "..." if it's longer
506
+ chatTitle.textContent = firstUserMessage.length > 20 ? firstUserMessage.substring(0, 20) + "..." : firstUserMessage;
507
+
508
+ prevChat.appendChild(chatTitle);
509
+ prevChat.addEventListener("click", () => loadChat(chat)); // Load chat on click
510
+ prevChatsCont.appendChild(prevChat);
511
+ }
512
+
513
+ function loadChat(chat) {
514
+ // Clear current messages
515
+ const messagesContainer = document.getElementById("messages");
516
+ messagesContainer.innerHTML = "";
517
+
518
+ // Display messages from the selected chat
519
+ chat.forEach(msg => {
520
+ if (msg.role === 'user') {
521
+ displayUserMessage(msg.content);
522
+ } else if (msg.role === 'assistant') {
523
+ displayAIMessage(msg.content);
524
+ }
525
+ });
526
+ }
527
+
528
+ function saveChats() {
529
+ localStorage.setItem('chats', JSON.stringify(chats));
530
+ }
531
+
532
+ function loadChats() {
533
+ const storedChats = localStorage.getItem('chats');
534
+ if (storedChats) {
535
+ chats = JSON.parse(storedChats);
536
+ chats.forEach(addChatToMenu);
537
+ } else {
538
+ chats = []; // Initialize as an empty array if no chats are stored
539
+ }
540
+ }
541
+
542
+
543
+ async function getModels() {
544
+ try {
545
+ const response = await fetch('/models');
546
+ if (!response.ok) {
547
+ throw new Error(`HTTP error! status: ${response.status}`);
548
+ }
549
+ const modelsList = await response.json();
550
+ modelsList.forEach(model => {
551
+ const option = document.createElement("option");
552
+ option.value = model.id;
553
+ option.textContent = model.id;
554
+ models.appendChild(option)
555
+ });
556
+ } catch (error) {
557
+ console.error("Could not fetch models:", error);
558
+ }
559
+ }
560
+ // Call getModels when the script loads
561
+ getModels();
562
+ loadChats();
563
+
564
+
565
+ function startNewChat() {
566
+ // Clear the message display area
567
+ const messagesContainer = document.getElementById("messages");
568
+ messagesContainer.innerHTML = "";
569
+
570
+ // Clear the input box
571
+ textBox.value = "";
572
+
573
+ // Reset the chats array to an empty array for a fresh start
574
+ chats = [];
575
+ //also delete it from storage
576
+ localStorage.removeItem("chats");
577
+ prevChatsCont.innerHTML = ""; //clear the chat list
578
+ }
579
+
580
+ // Attach the event listener to the "New Chat" button
581
+ newChat.addEventListener("click", startNewChat);
582
+
583
+
584
+ function displayUserMessage(message) {
585
+ const messagesContainer = document.getElementById('messages');
586
+ const userMessageDiv = document.createElement('div');
587
+ userMessageDiv.className = 'user';
588
+ const userTextP = document.createElement('p');
589
+ userTextP.textContent = message;
590
+ userMessageDiv.appendChild(userTextP);
591
+ messagesContainer.appendChild(userMessageDiv);
592
+ messagesContainer.scrollTop = messagesContainer.scrollHeight; // Scroll to bottom
593
+ }
594
+
595
+
596
+
597
+ let isWebSearchEnabled = false; // Keep track of web search state
598
+
599
+ webSearchBtn.addEventListener('click', () => {
600
+ isWebSearchEnabled = !isWebSearchEnabled; // Toggle the state
601
+ // Change the icon based on the state
602
+ webSearchBtn.innerHTML = isWebSearchEnabled ? '<i class="fa-solid fa-x"></i>' : '<i class="fa-solid fa-globe"></i>';
603
+ // Optionally, provide visual feedback (e.g., change background color)
604
+ webSearchBtn.style.backgroundColor = isWebSearchEnabled ? 'red' : 'transparent';
605
+ });
606
+
607
+ // Function to send message
608
+ async function sendMessage() {
609
+ const userMessage = textBox.value.trim();
610
+ if (!userMessage) return; // Don't send empty messages
611
+
612
+ displayUserMessage(userMessage);
613
+
614
+ // Add user message to the current chat
615
+ const currentChat = chats[chats.length - 1] || []; // Get current chat or an empty array
616
+ currentChat.push({ role: 'user', content: userMessage });
617
+ if (chats.length === 0 || chats[chats.length -1].length > 0) { //if there are no chats yet, or if the current chat is not new
618
+ chats.push(currentChat); //add it to the main array
619
+ } else {
620
+ chats[chats.length-1] = currentChat;
621
+ }
622
+
623
+ addChatToMenu(currentChat); // Add to menu (or update if existing)
624
+ textBox.value = ""; // Clear input
625
+
626
+
627
+ // Send message to server
628
+ try {
629
+ const selectedModel = models.value; // Get selected model
630
+
631
+ const response = await fetch('/chat', {
632
+ method: 'POST',
633
+ headers: {
634
+ 'Content-Type': 'application/json',
635
+ },
636
+ body: JSON.stringify({
637
+ message: userMessage,
638
+ model: selectedModel, // Send model ID
639
+ web_search: isWebSearchEnabled // Include web search status
640
+ }),
641
+ });
642
+
643
+ if (!response.ok) {
644
+ throw new Error(`HTTP error! status: ${response.status}`);
645
+ }
646
+
647
+ const data = await response.json();
648
+ const aiResponse = data.choices[0].message.content;
649
+
650
+ //push ai response into current chat
651
+ currentChat.push({role: 'assistant', content: aiResponse});
652
+ displayAIMessage(aiResponse);
653
+
654
+ saveChats()
655
+
656
+
657
+ } catch (error) {
658
+ console.error("Could not fetch:", error);
659
  }
660
  }
661
+
662
+ // Event listeners
663
+ sendBtn.addEventListener('click', sendMessage);
664
+ textBox.addEventListener('keydown', (e) => {
665
+ if (e.key === 'Enter' && !e.shiftKey) {
666
+ e.preventDefault();
667
+ sendMessage();
668
+ }
669
+ });
670
+
671
+ hamburger.addEventListener("click", ()=>{
672
+ menu.style.width = menu.style.width === "200px" ? "0px" : "200px";
673
+ })
674
  </script>
 
675
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
676
+
677
  </body>
678
+ </html>