Skip to content

Instantly share code, notes, and snippets.

@radu-matei
Created October 3, 2023 14:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save radu-matei/060056869104e98848387f28f95b4c0e to your computer and use it in GitHub Desktop.
Save radu-matei/060056869104e98848387f28f95b4c0e to your computer and use it in GitHub Desktop.
STREAM START HERE
<!DOCTYPE html>
<html>
<head>
<title>Spin and Large Language Models</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
</head>
<body>
<div class="chat-container">
<div class="chat-header">
<h1>Chat with Spin and Llama2!</h1>
</div>
<div class="chat-history"></div>
<div class="chat-input">
<input type="text" id="message-input" placeholder="Type your message here...">
<button id="send-button">Send</button>
<button id="clear-button">Clear</button>
</div>
<h3>Send messages in the chat area above, then clear all data from the server when you are done.</h3>
<script src="main.js"></script>
</body>
</html>
const chatHistory = document.querySelector('.chat-history');
const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');
const clearButton = document.getElementById('clear-button');
const conversationIdKey = "conversationId";
let conversationId = getOrSetConversationId();
(async () => {
let history = await fetch(`/api/${conversationId}`);
console.log(`Fetching conversation ID: ${conversationId}`);
if (history.ok) {
let chat = await history.json();
if (chat) {
chat.prompts.forEach(c => {
addMessageToChatHistory(c.role, c.content);
})
notify("Loaded conversation from history.");
}
} else {
notify("Created new conversation.");
}
})();
function getOrSetConversationId() {
let conversationId;
if (window.localStorage.getItem(conversationIdKey)) {
conversationId = window.localStorage.getItem(conversationIdKey);
} else {
conversationId = uuidv4();
console.log(`Conversation ID: ${conversationId}`);
window.localStorage.setItem(conversationIdKey, conversationId);
}
return conversationId;
}
// Function to add a new message to the chat history
function addMessageToChatHistory(role, content) {
if (role == "System") {
return;
}
const msg = content.replace(/^\s+|\s+$/g, '');
const newMessage = document.createElement('div');
if (role == "User") {
newMessage.className = "user-chat-message";
} else {
newMessage.className = "assistant-chat-message";
}
newMessage.innerText = `${role}: ${msg}`;
chatHistory.appendChild(newMessage);
chatHistory.scrollTop = chatHistory.scrollHeight;
}
// Function to add a new message to the chat history with typing animation
function typeMessage(role, content) {
const msg = content.replace(/^\s+|\s+$/g, '');
const newMessage = document.createElement('div');
if (role == "User") {
newMessage.className = "user-chat-message";
} else {
newMessage.className = "assistant-chat-message";
}
chatHistory.appendChild(newMessage);
let i = 0;
const typingAnimation = setInterval(() => {
newMessage.innerText = `${role}: ${msg.substring(0, i++)}_`;
if (i > msg.length) {
newMessage.innerText = `${role}: ${msg}`;
clearInterval(typingAnimation);
chatHistory.scrollTop = chatHistory.scrollHeight;
}
}, 30);
}
// Function to handle sending a message to the generation API
async function sendMessageToAPI(id, content) {
let response = await fetch("/api/generate", { method: "POST", body: JSON.stringify({ id: id, content: content }) });
typeMessage("Assistant", await response.text());
}
// Event listener for send button click
sendButton.addEventListener('click', () => {
const message = messageInput.value.trim();
if (message) {
addMessageToChatHistory('User', message);
messageInput.value = '';
sendMessageToAPI(conversationId, message);
}
});
// Event listener for enter key press
messageInput.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
const message = messageInput.value.trim();
if (message) {
addMessageToChatHistory('User', message);
messageInput.value = '';
sendMessageToAPI(conversationId, message);
}
}
});
clearButton.addEventListener('click', async () => {
window.localStorage.removeItem(conversationIdKey);
conversationId = getOrSetConversationId();
notify("Clearing history and starting new conversation.");
chatHistory.innerHTML = '';
// await fetch(`/api/${conversationId}`, { method: "DELETE" });
});
function uuidv4() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}
function notify(message) {
const notification = document.createElement('div');
notification.classList.add('notification');
notification.textContent = message;
// Add the notification to the body
document.body.appendChild(notification);
// Set a timeout to remove the notification after 3 seconds
setTimeout(() => {
notification.classList.add('hide');
}, 3000);
}
:root {
--rose-quartz: #433d4dff;
--periwinkle: #363147ff;
--nyanza: #2e3d2dff;
--russian-violet: #1a0b1fff;
--battleship-gray: #56575bff;
}
body {
font-family: 'Roboto', sans-serif;
background-color: var(--russian-violet);
color: white;
display: flex;
flex-direction: column;
min-height: 100vh;
}
.chat-container {
max-width: 1000px;
flex-grow: 10;
margin: 0 auto;
}
.chat-header {
background-color: var(--rose-quartz);
padding: 10px;
}
.chat-history {
height: 70vh;
min-height: max-content;
overflow-y: scroll;
border: 1px solid var(--battleship-gray);
padding: 10px;
}
.chat-history p {
margin: 0;
}
.chat-input {
display: flex;
align-items: center;
}
.chat-input input[type="text"] {
flex-grow: 1;
padding: 10px;
border-radius: 5px;
border: none;
margin-right: 10px;
background-color: var(--periwinkle);
border: 1px solid var(--battleship-gray);
color: white;
}
.chat-input button {
font-family: 'Roboto', sans-serif;
background-color: var(--nyanza);
color: white;
border: none;
padding: 10px;
border-radius: 5px;
cursor: pointer;
}
.chat-input button:hover {
opacity: 0.8;
}
.chat-input button#clear-button {
font-family: 'Roboto', sans-serif;
background-color: red;
margin-left: 5px;
}
.chat-input button#clear-button:hover {
opacity: 0.8;
}
.notification {
background-color: var(--periwinkle);
color: white;
padding: 10px;
position: fixed;
top: 10px;
right: 10px;
border-radius: 5px;
opacity: 1;
transition: opacity 0.5s ease-in-out;
}
.notification.hide {
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
/* show documentation section when .show-docs class is applied */
.show-docs .documentation {
display: block;
}
#toggle-docs {
font-family: 'Roboto', sans-serif;
background-color: var(--nyanza);
color: white;
border: none;
padding: 10px;
border-radius: 5px;
cursor: pointer;
}
#toggle-docs:hover {
opacity: 0.8;
}
.documentation {
display: none;
max-width: 800px;
margin: 20px auto;
padding: 20px;
background-color: var(--periwinkle);
color: white;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
.documentation h2 {
font-size: 24px;
margin-top: 0;
}
.documentation p {
font-size: 16px;
line-height: 1.5;
margin-bottom: 20px;
}
.documentation a {
color: white;
text-decoration: underline;
}
.documentation ul {
list-style: disc;
margin: 20px 0;
padding-left: 20px;
}
.documentation li {
font-size: 16px;
line-height: 1.5;
margin-bottom: 10px;
}
.documentation code {
font-family: Consolas, monospace;
font-size: 14px;
background-color: var(--rose-quartz);
padding: 2px 4px;
border-radius: 4px;
}
.documentation pre {
font-family: 'Roboto';
font-size: 14px;
background-color: var(--rose-quartz);
color: white;
padding: 10px;
border-radius: 4px;
overflow-x: auto;
}
footer {
background-color: var(--russian-violet);
color: white;
text-align: center;
padding: 20px;
font-size: 40px;
/* Increase font size */
position: fixed;
/* Anchor to bottom */
bottom: 0;
width: 100%;
}
.footer-links {
display: flex;
justify-content: center;
}
.footer-links a {
color: white;
text-decoration: none;
margin: 0 10px;
font-size: 18px;
}
.footer-links a:hover {
text-decoration: underline;
}
.user-chat-message {
background-color: var(--periwinkle);
padding: 10px;
border-radius: 10px;
margin: 5px 0;
color: white;
}
.assistant-chat-message {
background-color: var(--battleship-gray);
padding: 10px;
border-radius: 10px;
margin: 5px 0;
color: white;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment