2023-04-06 19:12:49 +00:00
|
|
|
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, true);
|
|
|
|
elements = addMessage('GPT4ALL', '', infos.response_id, 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, "<br>")
|
|
|
|
}
|
|
|
|
|
|
|
|
// scroll to bottom of chat window
|
|
|
|
chatWindow.scrollTop = chatWindow.scrollHeight;
|
|
|
|
}
|
|
|
|
entry_counter ++;
|
|
|
|
}
|
|
|
|
|
|
|
|
readStream();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
readStream();
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
function addMessage(sender, message, id, can_edit=false) {
|
|
|
|
console.log(id)
|
|
|
|
const messageElement = document.createElement('div');
|
2023-04-09 21:40:44 +00:00
|
|
|
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);
|
2023-04-06 19:12:49 +00:00
|
|
|
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');
|
2023-04-08 21:19:19 +00:00
|
|
|
messageTextElement.innerText = message;
|
2023-04-06 19:12:49 +00:00
|
|
|
// 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)
|
|
|
|
{
|
2023-04-10 08:27:25 +00:00
|
|
|
// 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%';
|
|
|
|
|
2023-04-06 19:12:49 +00:00
|
|
|
const editButton = document.createElement('button');
|
2023-04-09 21:40:44 +00:00
|
|
|
editButton.classList.add('my-1','mx-1','outline-none','px-4','bg-accent','text-black','rounded-md','hover:bg-[#7ba0ea]','active:bg-[#3d73e1]','transition-colors','ease-in-out');
|
|
|
|
editButton.style.float = 'right'; // set the float property to right
|
|
|
|
editButton.style.display='inline-block'
|
2023-04-06 19:12:49 +00:00
|
|
|
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;
|
2023-04-08 16:24:43 +00:00
|
|
|
|
2023-04-10 08:27:25 +00:00
|
|
|
buttonsContainer.style.display="none"
|
2023-04-06 19:12:49 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
});
|
2023-04-10 08:27:25 +00:00
|
|
|
buttonsContainer.style.display='inline-block'
|
|
|
|
messageElement.replaceChild(messageTextElement, inputField);
|
|
|
|
//messageElement.removeChild(inputField);
|
|
|
|
messageElement.removeChild(saveButton);
|
2023-04-06 19:12:49 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
messageElement.replaceChild(inputField, messageTextElement);
|
|
|
|
messageElement.appendChild(saveButton);
|
|
|
|
inputField.focus();
|
|
|
|
});
|
|
|
|
|
2023-04-10 08:27:25 +00:00
|
|
|
buttonsContainer.appendChild(editButton);
|
|
|
|
messageElement.appendChild(buttonsContainer);
|
2023-04-06 19:12:49 +00:00
|
|
|
}
|
|
|
|
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 = `
|
2023-04-08 21:30:32 +00:00
|
|
|
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.
|
|
|
|
- a=5, b=7, c is integer, c>a and c<b. what is the value of c
|
|
|
|
Welcome! I'm here to assist you with anything you need. What can I do for you today?
|
2023-04-06 19:12:49 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
addMessage("GPT4ALL",welcome_message,0);
|
|
|
|
|
|
|
|
// Code for collapsable text
|
|
|
|
const collapsibles = document.querySelectorAll('.collapsible');
|
|
|
|
function uncollapse(id){
|
|
|
|
console.log("uncollapsing")
|
|
|
|
const content = document.querySelector(`#${id}`);
|
|
|
|
content.classList.toggle('active');
|
|
|
|
}
|
2023-04-07 21:22:17 +00:00
|
|
|
|