Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Chat with LLM</title> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/1.6.5/flowbite.min.css" rel="stylesheet"> | |
<script src="https://cdn.tailwindcss.com"></script> | |
</head> | |
<body class="bg-gray-100 p-5 pb-50 h-screen flex flex-col"> | |
<div class="chat-container max-w-5xl w-full h-full flex flex-col mx-auto bg-white shadow-lg rounded-lg p-4"> | |
<div class="chat-box w-full h-full overflow-y-auto mb-4 p-3 border border-gray-200 rounded-lg" id="chat-box"></div> | |
<div class="input-container flex flex-col flex-none space-x-y"> | |
<input type="file" id="image-input" | |
class="block w-96 px-4 py-2 text-sm text-gray-500 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 focus:outline-none mb-2" | |
accept="image/*"> | |
<div class="input-container flex space-x-2"> | |
<input type="text" id="chat-input" | |
class="block w-full px-4 py-4 text-sm text-gray-700 bg-gray-50 border border-gray-300 rounded-lg focus:ring-blue-500 focus:border-blue-500" | |
placeholder="Type your message here..."> | |
<button id="send-button" | |
class="bg-blue-600 text-white px-10 py-2 rounded-lg hover:bg-blue-700 focus:ring-4 focus:ring-blue-300"> | |
Send | |
</button> | |
</div> | |
</div> | |
</div> | |
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/2.1.0/showdown.min.js" | |
integrity="sha512-LhccdVNGe2QMEfI3x4DVV3ckMRe36TfydKss6mJpdHjNFiV07dFpS2xzeZedptKZrwxfICJpez09iNioiSZ3hA==" | |
crossorigin="anonymous" referrerpolicy="no-referrer"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/1.6.5/flowbite.min.js"></script> | |
<script> | |
const socket = io.connect(document.baseURI); | |
const chatBox = document.getElementById('chat-box'); | |
const chatInput = document.getElementById('chat-input'); | |
const imageInput = document.getElementById('image-input'); | |
const sendButton = document.getElementById('send-button'); | |
const converter = new showdown.Converter(); | |
let response = ""; | |
// Function to add a loader element | |
function addLoader() { | |
const loaderEle = document.createElement('div'); | |
loaderEle.classList.add('dot-loader'); | |
loaderEle.innerHTML = ` | |
<div></div> | |
<div></div> | |
<div></div> | |
`; | |
chatBox.appendChild(loaderEle); | |
} | |
// Function to append a message to the chat box | |
function appendMessage(message, sender) { | |
if (sender === 'bot') { | |
response += message; | |
const loaderEle = chatBox.lastElementChild; | |
if (loaderEle && loaderEle.classList.contains('dot-loader')) { | |
chatBox.removeChild(loaderEle); | |
const messageElement = document.createElement('div'); | |
messageElement.classList.add('chat-message', sender); | |
messageElement.innerHTML = `<span>${response}</span>`; | |
chatBox.append(messageElement); | |
chatBox.scrollTop = chatBox.scrollHeight; | |
} else { | |
const lastMessageEle = chatBox.lastElementChild; | |
if (lastMessageEle) { | |
lastMessageEle.innerHTML = response; | |
} | |
chatBox.scrollTop = chatBox.scrollHeight; | |
} | |
} else { | |
const messageElement = document.createElement('div'); | |
messageElement.classList.add('chat-message', sender); | |
messageElement.innerHTML = `<span>${message}</span>`; | |
chatBox.append(messageElement); | |
chatBox.scrollTop = chatBox.scrollHeight; | |
setTimeout(addLoader, 500); | |
} | |
} | |
// Function to handle image as Base64 and send with message | |
function readImageAsBase64(imageFile) { | |
return new Promise((resolve, reject) => { | |
const reader = new FileReader(); | |
reader.onload = () => resolve(reader.result); | |
reader.onerror = reject; | |
reader.readAsDataURL(imageFile); | |
}); | |
} | |
// Function to handle sending the message and image | |
sendButton.addEventListener('click', async () => { | |
const message = chatInput.value.trim(); | |
const imageFile = imageInput.files[0]; | |
// Prepare the message object | |
let messageData = { | |
message: message, | |
session_id: 'abc123' | |
}; | |
// If there is an image, read it as base64 and add to messageData | |
if (imageFile) { | |
try { | |
const imageBase64 = await readImageAsBase64(imageFile); | |
messageData.image = imageBase64; | |
} catch (error) { | |
console.error('Error reading image file:', error); | |
} | |
} | |
if (message || imageFile) { | |
// appendMessage(imageFile || 'Image sent', 'user'); | |
appendMessage(message || 'Image sent', 'user'); | |
// Send message and image (if available) to the server via socket | |
socket.emit('message', messageData); | |
// Clear inputs | |
chatInput.value = ''; | |
imageInput.value = ''; // Clear the image input | |
response = ""; | |
} else { | |
console.error("Message or image cannot be empty."); | |
} | |
}); | |
// Event listener for 'Enter' key press in the chat input | |
chatInput.addEventListener('keypress', (e) => { | |
if (e.key === 'Enter') { | |
sendButton.click(); | |
} | |
}); | |
// Handle incoming responses from the server | |
socket.on('response', (data) => { | |
if (data && typeof data === 'string') { | |
appendMessage(data, 'bot'); | |
} else { | |
console.error("Invalid response format received from the server."); | |
} | |
}); | |
// Handle connection errors | |
socket.on('connect_error', (error) => { | |
appendMessage("Sorry, there was a problem connecting to the server. Please try again later.", 'bot'); | |
}); | |
// Handle connection | |
socket.on('connect', (reason) => { | |
console.log("Connected to server."); | |
}); | |
// Handle disconnection | |
socket.on('disconnect', (reason) => { | |
appendMessage("You have been disconnected from the server. Please refresh the page to reconnect.", 'bot'); | |
}); | |
</script> | |
</body> | |
</html> | |