diff --git a/app.py b/app.py
index e79a44f6..9b91f864 100644
--- a/app.py
+++ b/app.py
@@ -87,6 +87,10 @@ class Gpt4AllWebUI:
self.add_endpoint(
"/message_rank_down", "message_rank_down", self.message_rank_down, methods=["GET"]
)
+ self.add_endpoint(
+ "/delete_message", "delete_message", self.delete_message, methods=["GET"]
+ )
+
self.add_endpoint(
"/update_model_params", "update_model_params", self.update_model_params, methods=["POST"]
@@ -103,6 +107,13 @@ class Gpt4AllWebUI:
self.add_endpoint(
"/training", "training", self.training, methods=["GET"]
)
+ self.add_endpoint(
+ "/main", "main", self.main, methods=["GET"]
+ )
+
+ self.add_endpoint(
+ "/settings", "settings", self.settings, methods=["GET"]
+ )
self.add_endpoint(
"/help", "help", self.help, methods=["GET"]
@@ -358,6 +369,12 @@ GPT4All:Welcome! I'm here to assist you with anything you need. What can I do fo
new_rank = self.current_discussion.message_rank_down(discussion_id)
return jsonify({"new_rank": new_rank})
+ def delete_message(self):
+ discussion_id = request.args.get("id")
+ new_rank = self.current_discussion.delete_message(discussion_id)
+ return jsonify({"new_rank": new_rank})
+
+
def new_discussion(self):
title = request.args.get("title")
self.current_discussion = self.db.create_discussion(title)
@@ -402,6 +419,12 @@ GPT4All:Welcome! I'm here to assist you with anything you need. What can I do fo
def get_config(self):
return jsonify(self.config)
+ def main(self):
+ return render_template("main.html")
+
+ def settings(self):
+ return render_template("settings.html")
+
def help(self):
return render_template("help.html")
@@ -459,7 +482,7 @@ if __name__ == "__main__":
help="launch Flask server in debug mode",
)
parser.add_argument(
- "--host", type=str, default="localhost", help="the hostname to listen on"
+ "--host", type=str, default=None, help="the hostname to listen on"
)
parser.add_argument("--port", type=int, default=None, help="the port to listen on")
parser.add_argument(
diff --git a/db.py b/db.py
index 4f4a4cf0..11d32fad 100644
--- a/db.py
+++ b/db.py
@@ -90,7 +90,7 @@ class DiscussionsDB:
return cursor.fetchone()
- def delete(self, query):
+ def delete(self, query, params=None):
"""
Execute the specified SQL delete query on the database,
with optional parameters.
@@ -98,7 +98,10 @@ class DiscussionsDB:
"""
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
- cursor.execute(query)
+ if params is None:
+ cursor.execute(query)
+ else:
+ cursor.execute(query, params)
conn.commit()
def insert(self, query, params=None):
@@ -276,5 +279,14 @@ class Discussion:
f"UPDATE message SET rank = ? WHERE id = ?",(new_rank,message_id)
)
return new_rank
+
+ def delete_message(self, message_id):
+ """Delete the message
+
+ Args:
+ message_id (int): The id of the message to be deleted
+ """
+ # Retrieve current rank value for message_id
+ self.discussions_db.delete("DELETE FROM message WHERE id=?", (message_id,))
# ========================================================================================================================
diff --git a/static/images/refresh.png b/static/images/refresh.png
new file mode 100644
index 00000000..eba88e28
Binary files /dev/null and b/static/images/refresh.png differ
diff --git a/static/images/thumb_down.png b/static/images/thumb_down.png
new file mode 100644
index 00000000..d493eb68
Binary files /dev/null and b/static/images/thumb_down.png differ
diff --git a/static/images/thumb_up.png b/static/images/thumb_up.png
new file mode 100644
index 00000000..1c7953a9
Binary files /dev/null and b/static/images/thumb_up.png differ
diff --git a/static/js/chat.js b/static/js/chat.js
index c8a2a564..52d76a7d 100644
--- a/static/js/chat.js
+++ b/static/js/chat.js
@@ -1,279 +1,236 @@
-const chatWindow = document.getElementById('chat-window');
-const chatForm = document.getElementById('chat-form');
-const userInput = document.getElementById('user-input');
-
-chatForm.addEventListener('submit', event => {
- event.preventDefault();
-
- // get user input and clear input field
- message = userInput.value;
- userInput.value = '';
-
- // add user message to chat window
- const sendbtn = document.querySelector("#submit-input")
- const waitAnimation = document.querySelector("#wait-animation")
- sendbtn.style.display="none";
- waitAnimation.style.display="block";
- fetch('/bot', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({ message })
- }).then(function(response) {
- const stream = new ReadableStream({
- start(controller) {
- const reader = response.body.getReader();
- function push() {
- reader.read().then(function(result) {
- if (result.done) {
- sendbtn.style.display="block";
- waitAnimation.style.display="none";
- controller.close();
- return;
- }
- controller.enqueue(result.value);
- push();
- })
- }
- push();
- }
- });
- const textDecoder = new TextDecoder();
- const readableStreamDefaultReader = stream.getReader();
- let entry_counter = 0
- function readStream() {
- readableStreamDefaultReader.read().then(function(result) {
- if (result.done) {
- return;
- }
-
- text = textDecoder.decode(result.value);
-
- // The server will first send a json containing information about the message just sent
- if(entry_counter==0)
- {
- // We parse it and
- infos = JSON.parse(text)
- addMessage('User', infos.message, infos.id, 0, can_edit=true);
- elements = addMessage('GPT4ALL', '', infos.response_id, 0, can_edit=true);
- messageTextElement=elements['messageTextElement'];
- hiddenElement=elements['hiddenElement'];
- entry_counter ++;
- }
- else{
- // For the other enrtries, these are just the text of the chatbot
- for (const char of text) {
- txt = hiddenElement.innerHTML;
- if (char != '\f') {
- txt += char
- hiddenElement.innerHTML = txt
- messageTextElement.innerHTML = txt.replace(/\n/g, "
")
- }
-
- // scroll to bottom of chat window
- chatWindow.scrollTop = chatWindow.scrollHeight;
- }
- entry_counter ++;
- }
-
- readStream();
- });
- }
- readStream();
- });
-
-});
-
-
function addMessage(sender, message, id, rank=0, can_edit=false) {
- console.log(id)
- const messageElement = document.createElement('div');
- messageElement.classList.add('bg-secondary', 'drop-shadow-sm', 'p-4', 'mx-6', 'my-4', 'flex', 'flex-col', 'space-x-2', 'rounded-lg', 'shadow-lg', 'bg-gray-800', 'hover:bg-gray-700', 'transition-colors', 'duration-300');
+ const chatWindow = document.getElementById('chat-window');
+ const chatForm = document.getElementById('chat-form');
+ const userInput = document.getElementById('user-input');
- //messageElement.classList.add(sender);
- messageElement.setAttribute('id', id);
-
- const senderElement = document.createElement('div');
- senderElement.classList.add('font-normal', 'underline', 'text-sm');
- senderElement.innerHTML = sender;
-
- const messageTextElement = document.createElement('div');
- messageTextElement.classList.add('font-medium', 'text-md');
- messageTextElement.innerText = message;
- // Create a hidden div element needed to buffer responses before commiting them to the visible message
- const hiddenElement = document.createElement('div');
- hiddenElement.style.display = 'none';
- hiddenElement.innerHTML = '';
-
- messageElement.appendChild(senderElement);
- messageElement.appendChild(messageTextElement);
- if(can_edit)
- {
- // Create buttons container
- const buttonsContainer = document.createElement('div');
- // Add the 'flex' class to the div
- buttonsContainer.classList.add('flex');
-
- // Add the 'justify-end' class to the div
- buttonsContainer.classList.add('justify-end');
-
- // Set the width and height of the container to 100%
- buttonsContainer.style.width = '100%';
- buttonsContainer.style.height = '100%';
-
- const editButton = document.createElement('button');
- editButton.classList.add('my-1','mx-1','outline-none','px-4','bg-accent','text-white','rounded-md','hover:bg-[#7ba0ea]','active:bg-blue-100','transition-colors','ease-in-out');
- editButton.style.float = 'right'; // set the float property to right
- editButton.style.display='inline-block'
- editButton.innerHTML = 'Edit';
- editButton.addEventListener('click', () => {
- const inputField = document.createElement('input');
- inputField.type = 'text';
- inputField.classList.add('font-medium', 'text-md', 'border', 'border-gray-300', 'p-1');
- inputField.value = messageTextElement.innerHTML;
-
- buttonsContainer.style.display="none"
+ console.log(id)
+ const messageElement = document.createElement('div');
+ messageElement.classList.add('bg-secondary', 'drop-shadow-sm', 'p-4', 'mx-6', 'my-4', 'flex', 'flex-col', 'space-x-2', 'rounded-lg', 'shadow-lg', 'bg-gray-800', 'hover:bg-gray-700', 'transition-colors', 'duration-300');
+
+ //messageElement.classList.add(sender);
+ messageElement.setAttribute('id', id);
- const saveButton = document.createElement('button');
- saveButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-2', 'px-4', 'rounded', 'my-2', 'ml-2');
- saveButton.innerHTML = 'Save';
- saveButton.addEventListener('click', () => {
- const newText = inputField.value;
- messageTextElement.innerHTML = newText;
- // make request to update message
- const url = `/update_message?id=${id}&message=${newText}`;
- fetch(url)
- .then(response => {
- if (!response.ok) {
- throw new Error('Network response was not ok');
- }
- else{
- console.log("Updated")
- }
- })
- .catch(error => {
- console.error('There was a problem updating the message:', error);
- });
- buttonsContainer.style.display='inline-block'
- messageElement.replaceChild(messageTextElement, inputField);
- //messageElement.removeChild(inputField);
- messageElement.removeChild(saveButton);
- });
+ const senderElement = document.createElement('div');
+ senderElement.classList.add('font-normal', 'underline', 'text-sm');
+ senderElement.innerHTML = sender;
+
+ const messageTextElement = document.createElement('div');
+ messageTextElement.classList.add('font-medium', 'text-md');
+ messageTextElement.innerText = message;
+ // Create a hidden div element needed to buffer responses before commiting them to the visible message
+ const hiddenElement = document.createElement('div');
+ hiddenElement.style.display = 'none';
+ hiddenElement.innerHTML = '';
+
+ messageElement.appendChild(senderElement);
+ messageElement.appendChild(messageTextElement);
+ if(can_edit)
+ {
+ // Create buttons container
+ const buttonsContainer = document.createElement('div');
+ // Add the 'flex' class to the div
+ buttonsContainer.classList.add('flex');
+
+ // Add the 'justify-end' class to the div
+ buttonsContainer.classList.add('justify-end');
+
+ // Set the width and height of the container to 100%
+ buttonsContainer.style.width = '100%';
+ buttonsContainer.style.height = '100%';
+
+ const editButton = document.createElement('button');
+ editButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded',"w-10","h-10");
+ editButton.style.float = 'right'; // set the float property to right
+ editButton.style.display='inline-block'
+ editButton.innerHTML = '';
+ const editImg = document.createElement('img');
+ editImg.src = "/static/images/edit_discussion.png";
+ editImg.classList.add('py-1', 'px-1', 'rounded', 'w-10', 'h-10');
+ editButton.appendChild(editImg)
+
+ editButton.addEventListener('click', () => {
+ const inputField = document.createElement('input');
+ inputField.type = 'text';
+ inputField.classList.add('font-medium', 'text-md', 'border', 'border-gray-300', 'p-1');
+ inputField.value = messageTextElement.innerHTML;
+
+ buttonsContainer.style.display="none"
+
+ const saveButton = document.createElement('button');
+ saveButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-2', 'px-4', 'rounded', 'my-2', 'ml-2');
+ saveButton.innerHTML = 'Save';
+ saveButton.addEventListener('click', () => {
+ const newText = inputField.value;
+ messageTextElement.innerHTML = newText;
+ // make request to update message
+ const url = `/update_message?id=${id}&message=${newText}`;
+ fetch(url)
+ .then(response => {
+ if (!response.ok) {
+ throw new Error('Network response was not ok');
+ }
+ else{
+ console.log("Updated")
+ }
+ })
+ .catch(error => {
+ console.error('There was a problem updating the message:', error);
+ });
+ buttonsContainer.style.display='inline-block'
+ messageElement.replaceChild(messageTextElement, inputField);
+ //messageElement.removeChild(inputField);
+ messageElement.removeChild(saveButton);
+ });
+
+ messageElement.replaceChild(inputField, messageTextElement);
+ messageElement.appendChild(saveButton);
+ inputField.focus();
+ });
+
+ const deleteButton = document.createElement('button');
+ deleteButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded',"w-10","h-10");
+ deleteButton.style.float = 'right'; // set the float property to right
+ deleteButton.style.display='inline-block'
+ deleteButton.innerHTML = '';
+ const deleteImg = document.createElement('img');
+ deleteImg.src = "/static/images/delete_discussion.png";
+ deleteImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
+ deleteButton.appendChild(deleteImg)
+ deleteButton.addEventListener('click', () => {
+ const url = `/delete_message?id=${id}`;
+ fetch(url)
+ .then(response => response.json())
+ .then(data => {
+ console.log(data.new_rank)
+ messageElement.style.display="none"
+ })
+ .catch(error => {
+ console.error('There was a problem updating the message:', error);
+ });
+ });
+ const rank_up = document.createElement('button');
+ rank_up.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded',"w-10","h-10");
+ rank_up.style.float = 'right'; // set the float property to right
+ rank_up.style.display='inline-block'
+ rank_up.innerHTML = '';
+ const thumbUpImg = document.createElement('img');
+ thumbUpImg.src = "/static/images/thumb_up.png";
+ thumbUpImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
+ rank_up.appendChild(thumbUpImg)
+ const thumbUpBadge = document.createElement('span');
+ thumbUpBadge.innerText = "";
+ thumbUpBadge.classList.add('inline-flex', 'items-center', 'justify-center', 'h-4', 'w-4', 'rounded-full', 'bg-red-500', 'text-white', 'text-xs', 'top-0', 'right-0');
+ rank_up.appendChild(thumbUpBadge)
+
+ rank_up.addEventListener('click', () => {
+ const url = `/message_rank_up?id=${id}`;
+ fetch(url)
+ .then(response => response.json())
+ .then(data => {
+ console.log(data.new_rank)
+ if(data.new_rank>0){
+ thumbUpBadge.innerText=`${data.new_rank}`
+ thumbDownBadge.innerText=``
+ thumbUpBadge.display=`block`
+ thumbDownBadge.display='none'
+ }
+ else if(data.new_rank<0){
+ thumbUpBadge.innerText=``
+ thumbDownBadge.innerText=`${data.new_rank}`
+ thumbUpBadge.display=`none`
+ thumbDownBadge.display='block'
+ }
+ else{
+ thumbUpBadge.innerText=``
+ thumbDownBadge.innerText=``
+ thumbUpBadge.display=`none`
+ thumbDownBadge.display='none'
+ }
+ })
+ .catch(error => {
+ console.error('There was a problem updating the message:', error);
+ });
+ });
+
+ const rank_down = document.createElement('button');
+ rank_down.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded',"w-10","h-10");
+ rank_down.style.float = 'right'; // set the float property to right
+ rank_down.style.display='inline-block'
+ rank_down.innerHTML = '';
+ const thumbDownImg = document.createElement('img');
+ thumbDownImg.src = "/static/images/thumb_down.png";
+ thumbDownImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
+ rank_down.appendChild(thumbDownImg)
+ const thumbDownBadge = document.createElement('span');
+ thumbDownBadge.innerText = "";
+ thumbDownBadge.classList.add('inline-flex', 'items-center', 'justify-center', 'h-4', 'w-4', 'rounded-full', 'bg-red-500', 'text-white', 'text-xs', 'top-0', 'right-0');
+ rank_down.appendChild(thumbDownBadge)
+
+ rank_down.addEventListener('click', () => {
+ const url = `/message_rank_down?id=${id}`;
+ fetch(url)
+ .then(response => response.json())
+ .then(data => {
+ console.log(data)
+ if(data.new_rank>0){
+ thumbUpBadge.innerText=`${data.new_rank}`
+ thumbDownBadge.innerText=``
+ thumbUpBadge.display=`block`
+ thumbDownBadge.display='none'
+ }
+ else if(data.new_rank<0){
+ thumbUpBadge.innerText=``
+ thumbDownBadge.innerText=`${data.new_rank}`
+ thumbUpBadge.display=`none`
+ thumbDownBadge.display='block'
+ }
+ else{
+ thumbUpBadge.innerText=``
+ thumbDownBadge.innerText=``
+ thumbUpBadge.display=`none`
+ thumbDownBadge.display='none'
+ }
+ })
+ .catch(error => {
+ console.error('There was a problem updating the message:', error);
+ });
+ });
+
+ buttonsContainer.appendChild(editButton);
+ buttonsContainer.appendChild(deleteButton);
+
+ buttonsContainer.appendChild(rank_up);
+ buttonsContainer.appendChild(rank_down);
+ messageElement.appendChild(buttonsContainer);
+ if(rank>0){
+ thumbUpBadge.innerText=`${rank}`
+ thumbDownBadge.innerText=``
+ thumbUpBadge.display=`block`
+ thumbDownBadge.display='none'
+ }
+ else if(rank<0){
+ thumbUpBadge.innerText=``
+ thumbDownBadge.innerText=`${rank}`
+ thumbUpBadge.display=`none`
+ thumbDownBadge.display='block'
+ }
+ else{
+ thumbUpBadge.innerText=``
+ thumbDownBadge.innerText=``
+ thumbUpBadge.display=`none`
+ thumbDownBadge.display='none'
+ }
- messageElement.replaceChild(inputField, messageTextElement);
- messageElement.appendChild(saveButton);
- inputField.focus();
- });
-
- const rank_up = document.createElement('button');
- rank_up.classList.add('my-1','mx-1','outline-none','px-4','bg-accent','text-white','rounded-md','hover:bg-[#7ba0ea]','active:bg-[#3d73e1]','transition-colors','ease-in-out');
- rank_up.style.float = 'right'; // set the float property to right
- rank_up.style.display='inline-block'
- rank_up.innerHTML = 'Up';
- rank_up.addEventListener('click', () => {
- const url = `/message_rank_up?id=${id}`;
- fetch(url)
- .then(response => response.json())
- .then(data => {
- console.log(data.new_rank)
- if(data.new_rank>0){
- rank_up.innerText=`Up(${data.new_rank})`
- rank_down.innerText=`Down`
- }
- else if(data.new_rank<0){
- rank_up.innerText=`Up`
- rank_down.innerText=`Down(${data.new_rank})`
- }
- else{
- rank_up.innerText=`Up`
- rank_down.innerText=`Down`
- }
- })
- .catch(error => {
- console.error('There was a problem updating the message:', error);
- });
- });
-
- const rank_down = document.createElement('button');
- rank_down.classList.add('my-1','mx-1','outline-none','px-4','bg-accent','text-white','rounded-md','hover:bg-[#7ba0ea]','active:bg-[#3d73e1]','transition-colors','ease-in-out');
- rank_down.style.float = 'right'; // set the float property to right
- rank_down.style.display='inline-block'
- rank_down.innerHTML = 'Down';
- rank_down.addEventListener('click', () => {
- const url = `/message_rank_down?id=${id}`;
- fetch(url)
- .then(response => response.json())
- .then(data => {
- console.log(data)
- if(data.new_rank>0){
- rank_up.innerText=`Up(${data.new_rank})`
- rank_down.innerText=`Down`
- }
- else if(data.new_rank<0){
- rank_up.innerText=`Up`
- rank_down.innerText=`Down(${data.new_rank})`
- }
- })
- .catch(error => {
- console.error('There was a problem updating the message:', error);
- });
- });
-
- buttonsContainer.appendChild(editButton);
- buttonsContainer.appendChild(rank_up);
- buttonsContainer.appendChild(rank_down);
- messageElement.appendChild(buttonsContainer);
- if(rank>0){
- rank_up.innerText=`Up(${rank})`
- rank_down.innerText=`Down`
}
- else if(rank<0){
- rank_up.innerText=`Up`
- rank_down.innerText=`Down(${rank})`
+ chatWindow.appendChild(messageElement);
+ chatWindow.appendChild(hiddenElement);
+
+ // scroll to bottom of chat window
+ chatWindow.scrollTop = chatWindow.scrollHeight;
+
+ // Return all needed stuff
+ return {
+ 'messageTextElement':messageTextElement,
+ 'hiddenElement':hiddenElement
}
-
- }
- chatWindow.appendChild(messageElement);
- chatWindow.appendChild(hiddenElement);
-
- // scroll to bottom of chat window
- chatWindow.scrollTop = chatWindow.scrollHeight;
-
- // Return all needed stuff
- return {'messageTextElement':messageTextElement, 'hiddenElement':hiddenElement}
-}
-
-const welcome_message = `
-This is a very early testing Web UI of GPT4All chatbot.
-Keep in mind that this is a 7B parameters model running on your own PC's CPU. It is literally 24 times smaller than GPT-3 in terms of parameter count.
-While it is still new and not as powerful as GPT-3.5 or GPT-4, it can still be useful for many applications.
-Many people are building models out there and you can try the models and compare them yourself.
-Any feedback and contribution is welcomed.
-This Web UI is a binding to the GPT4All model that allows you to test a chatbot locally on your machine. Feel free to ask questions or give instructions.
-
-Examples:
-
-- A color description has been provided. Find the CSS code associated with that color. A light red color with a medium light shade of pink.
-- Come up with an interesting idea for a new movie plot. Your plot should be described with a title and a summary.
-- Reverse a string in python.
-- List 10 dogs.
-- Write me a poem about the fall of Julius Ceasar into a ceasar salad in iambic pentameter.
-- What is a three word topic describing the following keywords: baseball, football, soccer.
-- Act as ChefAI an AI that has the ability to create recipes for any occasion. Instruction: Give me a recipe for my next anniversary.
-- who is Abraham Lincoln?.
-- write a letter to my collegue and tell him I can't make it to work today. Make it humorous.
-- write a poem about love between two AIs.
-Welcome! I'm here to assist you with anything you need. What can I do for you today?
-`;
-
-addMessage("GPT4ALL",welcome_message,0,0,false);
-
-// Code for collapsable text
-const collapsibles = document.querySelectorAll('.collapsible');
-function uncollapse(id){
- console.log("uncollapsing")
- const content = document.querySelector(`#${id}`);
- content.classList.toggle('active');
-}
-
+}
\ No newline at end of file
diff --git a/static/js/discussions.js b/static/js/discussions.js
index 5484d2ea..97020482 100644
--- a/static/js/discussions.js
+++ b/static/js/discussions.js
@@ -13,7 +13,7 @@ function populate_discussions_list()
buttonWrapper.classList.add('flex', 'items-center', 'mt-2', 'px-2', 'py-1', 'text-left');
const renameButton = document.createElement('button');
- renameButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-2', 'px-2', 'rounded', 'ml-2', 'mr-2',"w-20","h-20");
+ renameButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded',"w-10","h-10");
const renameImg = document.createElement('img');
renameImg.src = "/static/images/edit_discussion.png";
renameImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
@@ -77,7 +77,7 @@ function populate_discussions_list()
dialog.showModal();
});
const deleteButton = document.createElement('button');
- deleteButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'rounded', 'ml-2', 'mr-2', "w-20", "h-20");
+ deleteButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded',"w-10","h-10");
const deleteImg = document.createElement('img');
deleteImg.src = "/static/images/delete_discussion.png";
deleteImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
@@ -110,7 +110,7 @@ function populate_discussions_list()
});
const discussionButton = document.createElement('button');
- discussionButton.classList.add('bg-blue-500', 'hover:bg-blue-700', 'text-white', 'font-bold', 'rounded', 'ml-2', 'w-full', 'h-20');
+ discussionButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-2', 'px-4', 'rounded', 'ml-2', 'w-full');
discussionButton.textContent = discussion.title;
discussionButton.addEventListener('click', () => {
// send query with discussion id to reveal discussion messages
diff --git a/static/js/main.js b/static/js/main.js
new file mode 100644
index 00000000..41ca8f4e
--- /dev/null
+++ b/static/js/main.js
@@ -0,0 +1,104 @@
+function update_main(){
+ const chatWindow = document.getElementById('chat-window');
+ const chatForm = document.getElementById('chat-form');
+ const userInput = document.getElementById('user-input');
+
+ chatForm.addEventListener('submit', event => {
+ event.preventDefault();
+
+ // get user input and clear input field
+ message = userInput.value;
+ userInput.value = '';
+
+ // add user message to chat window
+ const sendbtn = document.querySelector("#submit-input")
+ const waitAnimation = document.querySelector("#wait-animation")
+ sendbtn.style.display="none";
+ waitAnimation.style.display="block";
+ fetch('/bot', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ message })
+ }).then(function(response) {
+ const stream = new ReadableStream({
+ start(controller) {
+ const reader = response.body.getReader();
+ function push() {
+ reader.read().then(function(result) {
+ if (result.done) {
+ sendbtn.style.display="block";
+ waitAnimation.style.display="none";
+ controller.close();
+ return;
+ }
+ controller.enqueue(result.value);
+ push();
+ })
+ }
+ push();
+ }
+ });
+ const textDecoder = new TextDecoder();
+ const readableStreamDefaultReader = stream.getReader();
+ let entry_counter = 0
+ function readStream() {
+ readableStreamDefaultReader.read().then(function(result) {
+ if (result.done) {
+ return;
+ }
+
+ text = textDecoder.decode(result.value);
+
+ // The server will first send a json containing information about the message just sent
+ if(entry_counter==0)
+ {
+ // We parse it and
+ infos = JSON.parse(text)
+ addMessage('User', infos.message, infos.id, 0, can_edit=true);
+ elements = addMessage('GPT4ALL', '', infos.response_id, 0, can_edit=true);
+ messageTextElement=elements['messageTextElement'];
+ hiddenElement=elements['hiddenElement'];
+ entry_counter ++;
+ }
+ else{
+ // For the other enrtries, these are just the text of the chatbot
+ for (const char of text) {
+ txt = hiddenElement.innerHTML;
+ if (char != '\f') {
+ txt += char
+ hiddenElement.innerHTML = txt
+ messageTextElement.innerHTML = txt.replace(/\n/g, "
")
+ }
+
+ // scroll to bottom of chat window
+ chatWindow.scrollTop = chatWindow.scrollHeight;
+ }
+ entry_counter ++;
+ }
+
+ readStream();
+ });
+ }
+ readStream();
+ });
+
+ });
+
+ const welcome_message = `
+ Welcome! I'm here to assist you with anything you need. What can I do for you today?
+ `;
+
+ addMessage("GPT4ALL",welcome_message,0,0,false);
+
+}
+fetch('/main')
+.then(response => response.text())
+.then(html => {
+ document.getElementById('main').innerHTML = html;
+ update_main();
+})
+.catch(error => {
+ console.error('Error loading main page:', error);
+});
diff --git a/static/js/settings.js b/static/js/settings.js
index 8e24cfde..e31048b2 100644
--- a/static/js/settings.js
+++ b/static/js/settings.js
@@ -1,3 +1,121 @@
+
+fetch('/settings')
+.then(response => response.text())
+.then(html => {
+ document.getElementById('settings').innerHTML = html;
+
+ modelInput = document.getElementById('model');
+ seedInput = document.getElementById('seed');
+ tempInput = document.getElementById('temp');
+ nPredictInput = document.getElementById('n-predict');
+ topKInput = document.getElementById('top-k');
+ topPInput = document.getElementById('top-p');
+ repeatPenaltyInput = document.getElementById('repeat-penalty');
+ repeatLastNInput = document.getElementById('repeat-last-n');
+
+ temperatureValue = document.getElementById('temperature-value');
+ n_predictValue = document.getElementById('n-predict-value');
+ topkValue = document.getElementById('top-k-value');
+ toppValue = document.getElementById('top-p-value');
+
+ repeatPenaltyValue = document.getElementById('repeat-penalty-value');
+ repeatLastNValue = document.getElementById('repeat-last-n');
+
+ tempInput.addEventListener('input',() => {
+ temperatureValue.textContent =`Temperature(${tempInput.value})`
+ })
+
+ nPredictInput.addEventListener('input',() => {
+ n_predictValue.textContent =`N Predict(${nPredictInput.value})`
+ })
+
+ topKInput.addEventListener('input',() => {
+ topkValue.textContent =`Top-K(${topKInput.value})`
+ })
+
+ topPInput.addEventListener('input',() => {
+ toppValue.textContent =`Top-P(${topPInput.value})`
+ })
+
+ repeatPenaltyInput.addEventListener('input',() => {
+ repeatPenaltyValue.textContent =`Repeat penalty(${repeatPenaltyInput.value})`
+ })
+
+ repeatLastNInput.addEventListener('input',() => {
+ repeatLastNValue.textContent =`Repeat last N(${repeatLastNInput.value})`
+ })
+
+
+
+ fetch('/get_config')
+ .then((response) => response.json())
+ .then((data) => {
+ console.log(data);
+ modelInput.value = data["model"]
+ seedInput.value = data["seed"]
+ tempInput.value = data["temp"]
+ nPredictInput.value = data["n_predict"]
+ topKInput.value = data["top_k"]
+ topPInput.value = data["top_p"]
+
+ repeatPenaltyInput.textContent = data["repeat_penalty"]
+ repeatLastNInput.textContent = data["repeat_last_n"]
+
+ temperatureValue.textContent =`Temperature(${data["temp"]})`
+ n_predictValue.textContent =`N Predict(${data["n_predict"]})`
+
+ topkValue.textContent =`Top-K(${data["top_k"]})`
+ toppValue.textContent =`Top-P(${data["top_p"]})`
+
+ repeatPenaltyValue.textContent =`Repeat penalty(${data["repeat_penalty"]})`
+ repeatLastNValue.textContent =`Repeat last N(${data["repeat_last_n"]})`
+ })
+ .catch((error) => {
+ console.error('Error:', error);
+ });
+
+
+ const submitButton = document.getElementById('submit-model-params');
+ submitButton.addEventListener('click', (event) => {
+ // Prevent default form submission
+ event.preventDefault();
+
+ // Get form values and put them in an object
+ const formValues = {
+ model: modelInput.value,
+ seed: seedInput.value,
+ temp: tempInput.value,
+ nPredict: nPredictInput.value,
+ topK: topKInput.value,
+ topP: topPInput.value,
+ repeatPenalty: repeatPenaltyInput.value,
+ repeatLastN: repeatLastNInput.value
+ };
+ console.log(formValues);
+ // Use fetch to send form values to Flask endpoint
+ fetch('/update_model_params', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(formValues),
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ console.log(data);
+ })
+ .catch((error) => {
+ console.error('Error:', error);
+ });
+ });
+
+
+
+})
+.catch(error => {
+ console.error('Error loading settings page:', error);
+});
+
function populate_models(){
// Get a reference to the