|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8" /> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|
<title>TinyLlama Chat UI</title> |
|
<style> |
|
@import url("https://fonts.googleapis.com/css2?family=Lato&family=Montserrat&family=Roboto:wght@300&display=swap"); |
|
|
|
:root { |
|
--dark1: #121212; |
|
--dark2: #242424; |
|
--dark3: #363636; |
|
--dark4: #484848; |
|
--textDark: #cac4c4; |
|
--lingrad: linear-gradient( |
|
90deg, |
|
rgba(255, 240, 82, 1) 0%, |
|
rgba(255, 155, 34, 1) 39%, |
|
rgba(255, 59, 236, 1) 75% |
|
); |
|
} |
|
* { |
|
font-family: "Lato", sans-serif; |
|
font-family: "Montserrat", sans-serif; |
|
font-family: "Roboto", sans-serif; |
|
box-sizing: border-box; |
|
font-family: sans-serif; |
|
} |
|
body { |
|
margin: 0; |
|
padding: 0; |
|
} |
|
h1 { |
|
background: rgb(255, 240, 82); |
|
background: var(--lingrad); |
|
-webkit-background-clip: text; |
|
-webkit-text-fill-color: transparent; |
|
} |
|
a { |
|
color: var(--textDark); |
|
} |
|
#sidebar { |
|
position: absolute; |
|
top: 0; |
|
left: 0; |
|
width: 20%; |
|
height: 100%; |
|
background-color: var(--dark1); |
|
color: var(--textDark); |
|
padding: 10px; |
|
display: flex; |
|
flex-direction: column; |
|
} |
|
#chatarea { |
|
position: absolute; |
|
top: 0; |
|
left: 20%; |
|
width: 80%; |
|
height: 85%; |
|
background-color: var(--dark2); |
|
color: var(--textDark); |
|
padding: 10px; |
|
overflow: auto; |
|
} |
|
#prompting { |
|
position: absolute; |
|
top: 85%; |
|
left: 20%; |
|
width: 80%; |
|
height: 15%; |
|
background-color: var(--dark2); |
|
color: var(--textDark); |
|
padding: 10px; |
|
} |
|
#top { |
|
flex-basis: 70%; |
|
margin-bottom: 10px; |
|
padding: 5px; |
|
} |
|
|
|
#bottom { |
|
flex-basis: 30%; |
|
margin-top: 10px; |
|
padding: 5px; |
|
} |
|
|
|
#prompt { |
|
width: 80%; |
|
height: 50px; |
|
background-color: var(--dark3); |
|
border-radius: 10px; |
|
border: none; |
|
padding: 10px; |
|
margin: 5px; |
|
color: var(--textDark); |
|
font-size: 16px; |
|
} |
|
|
|
.sqbutton { |
|
width: 50px; |
|
height: 50px; |
|
background-color: var(--dark3); |
|
border-radius: 10px; |
|
border: none; |
|
padding: 5px; |
|
margin: 5px; |
|
color: var(--textDark); |
|
} |
|
|
|
#modal { |
|
display: none; |
|
position: absolute; |
|
width: 75%; |
|
height: 75%; |
|
left: 12.5%; |
|
top: 12.5%; |
|
background-color: var(--dark4); |
|
color: var(--textDark); |
|
z-index: 9; |
|
padding: 10px; |
|
border-radius: 10px; |
|
} |
|
</style> |
|
<link |
|
rel="stylesheet" |
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" |
|
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" |
|
crossorigin="anonymous" |
|
referrerpolicy="no-referrer" |
|
/> |
|
</head> |
|
<body> |
|
<div id="modal"> |
|
<div style="float: right;" id="close"><i class="fa-solid fa-xmark" style="font-size: 30px;"></i></div> |
|
<h2>Advanced Settings</h2> |
|
<div> |
|
<p style="display: inline; font-family: monospace;">Max Tokens</p> |
|
<input |
|
type="range" |
|
id="maxTok" |
|
min="0" |
|
max="500" |
|
step="5" |
|
value="100" |
|
style="display: inline" |
|
/> |
|
<label for="maxTok" style="display: inline; font-family: monospace;">100</label> |
|
</div> |
|
<p style="font-family: monospace; margin-top: 29%;">None of the Data you chat about in this UI is collected.</p> |
|
</div> |
|
<div id="sidebar"> |
|
<div id="top"> |
|
<h1>TinyLlama</h1> |
|
<p>Chat UI</p> |
|
</div> |
|
<div id="bottom"> |
|
<hr style="border-color: #131313" /> |
|
<p></p> |
|
<p> |
|
<button |
|
onclick="changeMode()" |
|
style=" |
|
border: none; |
|
background: none; |
|
padding: 0; |
|
font-size: 16px; |
|
color: var(--textDark); |
|
" |
|
> |
|
Theme |
|
</button> |
|
</p> |
|
<p> |
|
<a |
|
href="https://github.com/jzhang38/TinyLlama" |
|
style="text-decoration: none" |
|
>Github</a |
|
> |
|
</p> |
|
<p> |
|
<a |
|
href="https://github.com/jzhang38/TinyLlama/issues" |
|
style="text-decoration: none" |
|
>FeedBack</a |
|
> |
|
</p> |
|
<button |
|
id="open" |
|
style=" |
|
border: none; |
|
background: none; |
|
padding: 0; |
|
font-size: 16px; |
|
color: var(--textDark); |
|
" |
|
> |
|
Advanced Settings |
|
</button> |
|
</div> |
|
</div> |
|
<div id="chatarea"></div> |
|
<div id="prompting"> |
|
<button |
|
id="plugins" |
|
onclick="alert('we currently have no plugins!')" |
|
class="sqbutton" |
|
> |
|
<i class="fa-solid fa-bolt"></i> |
|
</button> |
|
<input |
|
type="text" |
|
id="prompt" |
|
placeholder="Type a message to start chatting" |
|
/> |
|
<button |
|
id="send" |
|
onclick="enterInput(document.getElementById('prompt').value)" |
|
class="sqbutton" |
|
> |
|
<i class="fa-solid fa-paper-plane"></i> |
|
</button> |
|
</div> |
|
<script> |
|
let chatArray = []; |
|
let context = ""; |
|
let mode = "dark"; |
|
|
|
const input = document.getElementById("prompt"); |
|
|
|
input.addEventListener("keydown", function (event) { |
|
if (event.keyCode === 13) { |
|
enterInput(document.getElementById("prompt").value); |
|
} |
|
}); |
|
|
|
function enterInput(val) { |
|
context = context + String.raw`<|im_start|>user\n${val}<|im_end|><|im_start|>assistant\n`; |
|
chatArray.push(val); |
|
callBot(); |
|
updateChatView(); |
|
document.getElementById("prompt").value = ""; |
|
} |
|
|
|
function callBot() { |
|
console.log(context); |
|
const url = new URL("/respond", window.location.origin); |
|
url.searchParams.set("input", context); |
|
url.searchParams.set("maxTok", document.getElementById("maxTok").value); |
|
console.log(url); |
|
|
|
fetch(url, { |
|
method: "GET", |
|
headers: { |
|
"ngrok-skip-browser-warning": "69420", |
|
}, |
|
}) |
|
.then(async (response) => { |
|
const data = await response.text(); |
|
updateContext(data); |
|
updateChatView(); |
|
}) |
|
.catch((error) => { |
|
console.log(error); |
|
updateContext("ERROR"); |
|
updateChatView(); |
|
}); |
|
} |
|
|
|
function updateContext(text) { |
|
let newContext = text.replace(context, '') + "<|im_end|>"; |
|
console.log(newContext) |
|
context = context+newContext; |
|
newContext=newContext.replace("<|im_end|>","") |
|
chatArray.push(newContext); |
|
} |
|
|
|
function updateChatView() { |
|
document.getElementById("chatarea").innerHTML = ""; |
|
loopA(chatArray); |
|
} |
|
|
|
function loopA(array) { |
|
for (let i = 0; i < array.length; i++) { |
|
let color = "var(--dark3)"; |
|
let margin = "40%"; |
|
if (i % 2 !== 0) { |
|
color = "var(--dark1)"; |
|
margin = "0%"; |
|
} |
|
|
|
document.getElementById( |
|
"chatarea" |
|
).innerHTML += `<div style="background-color: ${color}; width: 60%; margin: 10px; padding: 10px; border-radius:10px; margin-left:${margin}">${array[i]}</div>`; |
|
} |
|
} |
|
|
|
function changeMode() { |
|
if (mode == "dark") { |
|
document.documentElement.style.setProperty("--dark1", "#ebebeb"); |
|
document.documentElement.style.setProperty("--dark2", "#f0f0f0"); |
|
document.documentElement.style.setProperty("--dark3", "#f8f8f8"); |
|
document.documentElement.style.setProperty("--dark4", "#fff"); |
|
document.documentElement.style.setProperty("--textDark", "#000000"); |
|
document.documentElement.style.setProperty( |
|
"--lingrad", |
|
"linear-gradient(90deg,rgba(0, 0, 0, 1) 0%,rgba(0, 0, 0, 1) 39%,rgba(0, 0, 0, 1) 75%);" |
|
); |
|
mode = "light"; |
|
return; |
|
} |
|
if (mode == "light") { |
|
document.documentElement.style.setProperty("--dark1", "#121212"); |
|
document.documentElement.style.setProperty("--dark2", "#242424"); |
|
document.documentElement.style.setProperty("--dark3", "#363636"); |
|
document.documentElement.style.setProperty("--dark4", "#484848"); |
|
document.documentElement.style.setProperty("--textDark", "#cac4c4"); |
|
document.documentElement.style.setProperty( |
|
"--lingrad", |
|
"linear-gradient(90deg,rgba(255, 240, 82, 1) 0%,rgba(255, 155, 34, 1) 39%,rgba(255, 59, 236, 1) 75%);" |
|
); |
|
mode = "dark"; |
|
return; |
|
} |
|
} |
|
|
|
|
|
const maxTokInput = document.getElementById('maxTok'); |
|
const maxTokLabel = document.querySelector('label[for="maxTok"]'); |
|
|
|
maxTokInput.addEventListener('input', function() { |
|
maxTokLabel.textContent = maxTokInput.value; |
|
}); |
|
|
|
|
|
document.querySelector("#close").addEventListener("click", function() { |
|
document.querySelector("#modal").style.display = "none"; |
|
}); |
|
document.querySelector("#open").addEventListener("click", function() { |
|
document.querySelector("#modal").style.display = "block"; |
|
}); |
|
</script> |
|
</body> |
|
</html> |
|
|