Split javascript code into multiple files

This commit is contained in:
ParisNeo 2023-04-08 12:54:51 +02:00
parent 88c7f68a93
commit 76f4d9efd1
6 changed files with 310 additions and 299 deletions

15
app.py
View File

@ -328,7 +328,7 @@ GPT4All:Welcome! I'm here to assist you with anything you need. What can I do fo
self.chatbot_bindings.generate(
self.current_message,
new_text_callback=self.new_text_callback,#_with_yield,
n_predict=len(self.current_message)+args.n_predict,
n_predict=len(self.current_message)+self.args.n_predict,
temp=self.args.temp,
top_k=self.args.top_k,
top_p=self.args.top_p,
@ -458,7 +458,18 @@ GPT4All:Welcome! I'm here to assist you with anything you need. What can I do fo
def update_model_params(self):
data = request.get_json()
self.args.temp = data["temp"]
self.args.temp = float(data["temp"])
self.args.top_k = float(data["top_k"])
self.args.top_p = float(data["top_p"])
self.args.repeat_penalty = float(data["repeat_penalty"])
self.args.repeat_last_n = float(data["repeat_last_n"])
print("Parameters changed to:")
print(f"\tTemperature:{self.args.temp}")
print(f"\top_k:{self.args.top_k}")
print(f"\top_p:{self.args.top_p}")
print(f"\repeat_penalty:{self.args.repeat_penalty}")
print(f"\repeat_last_n:{self.args.repeat_last_n}")
return jsonify({"status":"ok"})

View File

@ -162,257 +162,6 @@ function addMessage(sender, message, id, can_edit=false) {
const exportButton = document.getElementById('export-button');
exportButton.addEventListener('click', () => {
const messages = Array.from(chatWindow.querySelectorAll('.message')).map(messageElement => {
const senderElement = messageElement.querySelector('.sender');
const messageTextElement= messageElement.querySelector('.message-text');
const sender = senderElement.textContent;
const messageText = messageTextElement.textContent;
return { sender, messageText };
});
const exportFormat = 'json'; // replace with desired export format
if (exportFormat === 'text') {
const exportText = messages.map(({ sender, messageText }) => `${sender}: ${messageText}`).join('\n');
downloadTextFile(exportText);
} else if (exportFormat === 'json') {
fetch('/export')
.then(response => response.json())
.then(data => {
db_data = JSON.stringify(data)
// Do something with the data, such as displaying it on the page
console.log(db_data);
downloadJsonFile(db_data);
})
.catch(error => {
// Handle any errors that occur
console.error(error);
});
} else {
console.error(`Unsupported export format: ${exportFormat}`);
}
});
function downloadTextFile(text) {
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
downloadUrl(url);
}
function downloadJsonFile(json) {
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
downloadUrl(url);
}
function downloadUrl(url) {
const link = document.createElement('a');
link.href = url;
link.download = 'chat.txt';
link.click();
}
const newDiscussionBtn = document.querySelector('#new-discussion-btn');
newDiscussionBtn.addEventListener('click', () => {
const discussionName = prompt('Enter a name for the new discussion:');
if (discussionName) {
const sendbtn = document.querySelector("#submit-input")
const waitAnimation = document.querySelector("#wait-animation")
sendbtn.style.display="none";
waitAnimation.style.display="block";
// Add the discussion to the discussion list
const discussionItem = document.createElement('li');
discussionItem.textContent = discussionName;
fetch(`/new_discussion?title=${discussionName}`)
.then(response => response.json())
.then(data => {
console.log(`New chat ${data}`)
// Select the new discussion
//selectDiscussion(discussionId);
chatWindow.innerHTML=""
addMessage("GPT4ALL", welcome_message,0);
populate_discussions_list()
sendbtn.style.display="block";
waitAnimation.style.display="none";
})
.catch(error => {
// Handle any errors that occur
console.error(error);
});
}
});
function populate_discussions_list()
{
// Populate discussions list
const discussionsList = document.querySelector('#discussions-list');
discussionsList.innerHTML = "";
fetch('/discussions')
.then(response => response.json())
.then(discussions => {
discussions.forEach(discussion => {
const buttonWrapper = document.createElement('div');
//buttonWrapper.classList.add('flex', 'space-x-2', 'mt-2');
buttonWrapper.classList.add('flex', 'items-center', 'mt-2', 'py-4', 'text-left');
const renameButton = document.createElement('button');
renameButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded', 'mr-2');
const renameImg = document.createElement('img');
renameImg.src = "/static/images/edit_discussion.png";
renameImg.style.width='20px'
renameImg.style.height='20px'
renameButton.appendChild(renameImg);
//renameButton.style.backgroundImage = "/rename_discussion.svg"; //.textContent = 'Rename';
renameButton.addEventListener('click', () => {
const dialog = document.createElement('dialog');
dialog.classList.add('bg-white', 'rounded', 'p-4');
const inputLabel = document.createElement('label');
inputLabel.textContent = 'New name: ';
const inputField = document.createElement('input');
inputField.classList.add('border', 'border-gray-400', 'rounded', 'py-1', 'px-2');
inputField.setAttribute('type', 'text');
inputField.setAttribute('name', 'title');
inputField.setAttribute('value', discussion.title);
inputLabel.appendChild(inputField);
dialog.appendChild(inputLabel);
const cancelButton = document.createElement('button');
cancelButton.textContent = 'Cancel';
cancelButton.addEventListener('click', () => {
dialog.close();
});
const renameConfirmButton = document.createElement('button');
renameConfirmButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-2', 'px-4', 'rounded', 'ml-2');
renameConfirmButton.textContent = 'Rename';
renameConfirmButton.addEventListener('click', () => {
const newTitle = inputField.value;
if (newTitle === '') {
alert('New name cannot be empty');
} else {
fetch('/rename', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: discussion.id, title: newTitle })
})
.then(response => {
if (response.ok) {
discussion.title = newTitle;
discussionButton.textContent = newTitle;
dialog.close();
} else {
alert('Failed to rename discussion');
}
})
.catch(error => {
console.error('Failed to rename discussion:', error);
alert('Failed to rename discussion');
});
}
});
dialog.appendChild(cancelButton);
dialog.appendChild(renameConfirmButton);
document.body.appendChild(dialog);
dialog.showModal();
});
const deleteButton = document.createElement('button');
deleteButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded', 'ml-2');
const deleteImg = document.createElement('img');
deleteImg.src = "/static/images/delete_discussion.png";
deleteImg.style.width='20px'
deleteImg.style.height='20px'
deleteButton.addEventListener('click', () => {
fetch('/delete_discussion', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: discussion.id})
})
.then(response => {
if (response.ok) {
buttonWrapper.remove();
} else {
alert('Failed to delete discussion');
}
})
.catch(error => {
console.error('Failed to delete discussion:', error);
alert('Failed to delete discussion');
});
});
deleteButton.appendChild(deleteImg);
deleteButton.addEventListener('click', () => {
});
const discussionButton = document.createElement('button');
discussionButton.classList.add('flex-grow', 'w-full', 'bg-blue-500', 'hover:bg-blue-700', 'text-white', 'font-bold', 'py-2', 'px-4', 'rounded', 'text-left', 'hover:text-white');
discussionButton.textContent = discussion.title;
discussionButton.addEventListener('click', () => {
// send query with discussion id to reveal discussion messages
fetch('/get_messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: discussion.id })
})
.then(response => {
if (response.ok) {
response.text().then(data => {
const messages = JSON.parse(data);
console.log(messages)
// process messages
var container = document.getElementById('chat-window');
container.innerHTML = '';
messages.forEach(message => {
addMessage(message.sender, message.content, message.id, true);
});
});
} else {
alert('Failed to query the discussion');
}
})
.catch(error => {
console.error('Failed to get messages:', error);
alert('Failed to get messages');
});
console.log(`Showing messages for discussion ${discussion.id}`);
});
buttonWrapper.appendChild(renameButton);
buttonWrapper.appendChild(deleteButton);
buttonWrapper.appendChild(discussionButton);
discussionsList.appendChild(buttonWrapper);
});
})
.catch(error => {
console.error('Failed to get discussions:', error);
alert('Failed to get discussions');
});
}
// First time we populate the discussions list
populate_discussions_list()
@ -541,49 +290,3 @@ function uncollapse(id){
content.classList.toggle('active');
}
// submitting the model
// Add event listener to form submit button
const submitButton = document.getElementById('submit-model-params');
submitButton.addEventListener('click', (event) => {
// Prevent default form submission
event.preventDefault();
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');
// 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
};
// 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);
});
});

52
static/js/db_export.js Normal file
View File

@ -0,0 +1,52 @@
const exportButton = document.getElementById('export-button');
exportButton.addEventListener('click', () => {
const messages = Array.from(chatWindow.querySelectorAll('.message')).map(messageElement => {
const senderElement = messageElement.querySelector('.sender');
const messageTextElement= messageElement.querySelector('.message-text');
const sender = senderElement.textContent;
const messageText = messageTextElement.textContent;
return { sender, messageText };
});
const exportFormat = 'json'; // replace with desired export format
if (exportFormat === 'text') {
const exportText = messages.map(({ sender, messageText }) => `${sender}: ${messageText}`).join('\n');
downloadTextFile(exportText);
} else if (exportFormat === 'json') {
fetch('/export')
.then(response => response.json())
.then(data => {
db_data = JSON.stringify(data)
// Do something with the data, such as displaying it on the page
console.log(db_data);
downloadJsonFile(db_data);
})
.catch(error => {
// Handle any errors that occur
console.error(error);
});
} else {
console.error(`Unsupported export format: ${exportFormat}`);
}
});
function downloadTextFile(text) {
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
downloadUrl(url);
}
function downloadJsonFile(json) {
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
downloadUrl(url);
}
function downloadUrl(url) {
const link = document.createElement('a');
link.href = url;
link.download = 'chat.txt';
link.click();
}

199
static/js/discussions.js Normal file
View File

@ -0,0 +1,199 @@
function populate_discussions_list()
{
// Populate discussions list
const discussionsList = document.querySelector('#discussions-list');
discussionsList.innerHTML = "";
fetch('/discussions')
.then(response => response.json())
.then(discussions => {
discussions.forEach(discussion => {
const buttonWrapper = document.createElement('div');
//buttonWrapper.classList.add('flex', 'space-x-2', 'mt-2');
buttonWrapper.classList.add('flex', 'items-center', 'mt-2', 'py-4', 'text-left');
const renameButton = document.createElement('button');
renameButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded', 'mr-2');
const renameImg = document.createElement('img');
renameImg.src = "/static/images/edit_discussion.png";
renameImg.style.width='20px'
renameImg.style.height='20px'
renameButton.appendChild(renameImg);
//renameButton.style.backgroundImage = "/rename_discussion.svg"; //.textContent = 'Rename';
renameButton.addEventListener('click', () => {
const dialog = document.createElement('dialog');
dialog.classList.add('bg-white', 'rounded', 'p-4');
const inputLabel = document.createElement('label');
inputLabel.textContent = 'New name: ';
const inputField = document.createElement('input');
inputField.classList.add('border', 'border-gray-400', 'rounded', 'py-1', 'px-2');
inputField.setAttribute('type', 'text');
inputField.setAttribute('name', 'title');
inputField.setAttribute('value', discussion.title);
inputLabel.appendChild(inputField);
dialog.appendChild(inputLabel);
const cancelButton = document.createElement('button');
cancelButton.textContent = 'Cancel';
cancelButton.addEventListener('click', () => {
dialog.close();
});
const renameConfirmButton = document.createElement('button');
renameConfirmButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-2', 'px-4', 'rounded', 'ml-2');
renameConfirmButton.textContent = 'Rename';
renameConfirmButton.addEventListener('click', () => {
const newTitle = inputField.value;
if (newTitle === '') {
alert('New name cannot be empty');
} else {
fetch('/rename', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: discussion.id, title: newTitle })
})
.then(response => {
if (response.ok) {
discussion.title = newTitle;
discussionButton.textContent = newTitle;
dialog.close();
} else {
alert('Failed to rename discussion');
}
})
.catch(error => {
console.error('Failed to rename discussion:', error);
alert('Failed to rename discussion');
});
}
});
dialog.appendChild(cancelButton);
dialog.appendChild(renameConfirmButton);
document.body.appendChild(dialog);
dialog.showModal();
});
const deleteButton = document.createElement('button');
deleteButton.classList.add('bg-green-500', 'hover:bg-green-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded', 'ml-2');
const deleteImg = document.createElement('img');
deleteImg.src = "/static/images/delete_discussion.png";
deleteImg.style.width='20px'
deleteImg.style.height='20px'
deleteButton.addEventListener('click', () => {
fetch('/delete_discussion', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: discussion.id})
})
.then(response => {
if (response.ok) {
buttonWrapper.remove();
} else {
alert('Failed to delete discussion');
}
})
.catch(error => {
console.error('Failed to delete discussion:', error);
alert('Failed to delete discussion');
});
});
deleteButton.appendChild(deleteImg);
deleteButton.addEventListener('click', () => {
});
const discussionButton = document.createElement('button');
discussionButton.classList.add('flex-grow', 'w-full', 'bg-blue-500', 'hover:bg-blue-700', 'text-white', 'font-bold', 'py-2', 'px-4', 'rounded', 'text-left', 'hover:text-white');
discussionButton.textContent = discussion.title;
discussionButton.addEventListener('click', () => {
// send query with discussion id to reveal discussion messages
fetch('/get_messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: discussion.id })
})
.then(response => {
if (response.ok) {
response.text().then(data => {
const messages = JSON.parse(data);
console.log(messages)
// process messages
var container = document.getElementById('chat-window');
container.innerHTML = '';
messages.forEach(message => {
addMessage(message.sender, message.content, message.id, true);
});
});
} else {
alert('Failed to query the discussion');
}
})
.catch(error => {
console.error('Failed to get messages:', error);
alert('Failed to get messages');
});
console.log(`Showing messages for discussion ${discussion.id}`);
});
buttonWrapper.appendChild(renameButton);
buttonWrapper.appendChild(deleteButton);
buttonWrapper.appendChild(discussionButton);
discussionsList.appendChild(buttonWrapper);
});
})
.catch(error => {
console.error('Failed to get discussions:', error);
alert('Failed to get discussions');
});
}
// First time we populate the discussions list
populate_discussions_list()
const newDiscussionBtn = document.querySelector('#new-discussion-btn');
newDiscussionBtn.addEventListener('click', () => {
const discussionName = prompt('Enter a name for the new discussion:');
if (discussionName) {
const sendbtn = document.querySelector("#submit-input")
const waitAnimation = document.querySelector("#wait-animation")
sendbtn.style.display="none";
waitAnimation.style.display="block";
// Add the discussion to the discussion list
const discussionItem = document.createElement('li');
discussionItem.textContent = discussionName;
fetch(`/new_discussion?title=${discussionName}`)
.then(response => response.json())
.then(data => {
console.log(`New chat ${data}`)
// Select the new discussion
//selectDiscussion(discussionId);
chatWindow.innerHTML=""
addMessage("GPT4ALL", welcome_message,0);
populate_discussions_list()
sendbtn.style.display="block";
waitAnimation.style.display="none";
})
.catch(error => {
// Handle any errors that occur
console.error(error);
});
}
});

42
static/js/settings.js Normal file
View File

@ -0,0 +1,42 @@
const submitButton = document.getElementById('submit-model-params');
submitButton.addEventListener('click', (event) => {
// Prevent default form submission
event.preventDefault();
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');
// 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
};
// 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);
});
});

View File

@ -79,5 +79,9 @@
</footer>
<script src="{{ url_for('static', filename='js/marked.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/chat.js') }}"></script>
<script src="{{ url_for('static', filename='js/discussions.js') }}"></script>
<script src="{{ url_for('static', filename='js/settings.js') }}"></script>
<script src="{{ url_for('static', filename='js/db_export.js') }}"></script>
</body>
</html>