Made the frontend more flexible to also support other models than just Koala

This commit is contained in:
Julian Müller (ChaoticByte) 2023-05-18 15:34:34 +02:00
parent 02a142012b
commit c3fda61b21
4 changed files with 71 additions and 48 deletions

View file

@ -2,18 +2,40 @@
# Copyright (c) 2023 Julian Müller (ChaoticByte) # Copyright (c) 2023 Julian Müller (ChaoticByte)
from argparse import ArgumentParser from argparse import ArgumentParser
from json import load
from pathlib import Path
import uvicorn import uvicorn
from frontend.app import app from frontend.app import app
if __name__ == "__main__": if __name__ == "__main__":
koala_profile_path = Path(__file__).parent / "profiles" / "koala.json"
# CLI # CLI
ap = ArgumentParser() ap = ArgumentParser()
ap.add_argument("--profile", help="Path to a profile file that includes settings for a specific model (default: ./profiles/koala.json)", type=Path, default=koala_profile_path)
ap.add_argument("--host", help="Address to listen on (default: localhost)", type=str, default="localhost") ap.add_argument("--host", help="Address to listen on (default: localhost)", type=str, default="localhost")
ap.add_argument("--port", help="Port to listen on (default: 8080)", type=int, default=8080) ap.add_argument("--port", help="Port to listen on (default: 8080)", type=int, default=8080)
ap.add_argument("--api", help="URL of the API Server (default: 'http://localhost:7331')", type=str, default="http://localhost:7331") ap.add_argument("--api", help="URL of the API Server (default: 'http://localhost:7331')", type=str, default="http://localhost:7331")
args = ap.parse_args() args = ap.parse_args()
# Read profile
with args.profile.open("r") as pf:
profile = load(pf)
# Check profile
assert "name" in profile
assert "conversation_prefix" in profile
assert "user_keyword" in profile
assert "assistant_keyword" in profile
assert "stop_sequence" in profile
# Pass frontend config to the app # Pass frontend config to the app
app.config.frontend_config = {"api_url": args.api.rstrip("/")} app.config.frontend_config = {
"api_url": args.api.rstrip("/"),
"profile": {
"name": profile["name"],
"conversation_prefix": profile["conversation_prefix"],
"user_keyword": profile["user_keyword"],
"assistant_keyword": profile["assistant_keyword"],
"stop_sequence": profile["stop_sequence"]
}
}
# Run # Run
uvicorn.run(app, host=args.host, port=args.port) uvicorn.run(app, host=args.host, port=args.port)

View file

@ -21,6 +21,10 @@
<div class="sidepanel flex flex-column"> <div class="sidepanel flex flex-column">
<div class="max-width">Settings</div> <div class="max-width">Settings</div>
<div class="settings flex flex-column"> <div class="settings flex flex-column">
<div class="setting flex">
<div>Assistant</div>
<div id="settings-label-assistant"></div>
</div>
<div class="setting flex"> <div class="setting flex">
<div>max_tokens</div> <div>max_tokens</div>
<div><input type="number" id="settings-max-tokens" min="16" value="100"></div> <div><input type="number" id="settings-max-tokens" min="16" value="100"></div>

View file

@ -1,27 +1,17 @@
// Copyright (c) 2023 Julian Müller (ChaoticByte) // Copyright (c) 2023 Julian Müller (ChaoticByte)
(() => { // Fetch configuration and initialize Eucalyptus Chat Frontend
// Koala specific keywords fetch("/config")
const conversationBeginning = "BEGINNING OF CONVERSATION:"; .then(r => {
const userKeyword = " USER: ";
const assistantKeyword = " GPT:";
const koalaStopSequence = "</s>";
// Get frontend config
let frontend_config = null;
fetch("/config")
.then(r => {
return r.json(); return r.json();
}) }).then(frontend_config => {
.then(j => {
frontend_config = j;
});
// Message Context // Message Context
let conversation = [conversationBeginning]; let conversation = [frontend_config.profile.conversation_prefix];
// Elements - Sidebar // Elements - Sidebar
const settingsLabelAssistantNameElement = document.getElementById("settings-label-assistant");
const settingsMaxTokensElement = document.getElementById("settings-max-tokens"); const settingsMaxTokensElement = document.getElementById("settings-max-tokens");
const settingsTemperatureElement = document.getElementById("settings-temperature"); const settingsTemperatureElement = document.getElementById("settings-temperature");
const settingsTopPElement = document.getElementById("settings-top-p"); const settingsTopPElement = document.getElementById("settings-top-p");
@ -32,6 +22,8 @@
const resetSettingsButtonElement = document.getElementById("reset-settings-btn"); const resetSettingsButtonElement = document.getElementById("reset-settings-btn");
const resetHistoryButtonElement = document.getElementById("reset-history-btn"); const resetHistoryButtonElement = document.getElementById("reset-history-btn");
settingsLabelAssistantNameElement.innerText = frontend_config.profile.name;
// Elements - Main // Elements - Main
const messageHistoryContainer = document.getElementById("messages"); const messageHistoryContainer = document.getElementById("messages");
const textInputElement = document.getElementById("text-input"); const textInputElement = document.getElementById("text-input");
@ -42,7 +34,7 @@
async function apiCompletion(prompt, settings) { async function apiCompletion(prompt, settings) {
const bodyData = JSON.stringify({ const bodyData = JSON.stringify({
"prompt": prompt, "prompt": prompt,
"stop": [koalaStopSequence], "stop": [frontend_config.profile.stop_sequence],
"max_tokens": settings.max_tokens, "max_tokens": settings.max_tokens,
"temperature": settings.temperature, "temperature": settings.temperature,
"top_p": settings.top_p, "top_p": settings.top_p,
@ -99,33 +91,36 @@
// Chat // Chat
const MessageType = { // Message Roles
const Roles = {
USER: { USER: {
name: "User", name: "User",
class: "message-bg-user" class: "message-bg-user"
}, },
ASSISTANT: { ASSISTANT: {
name: "Koala", name: frontend_config.profile.name,
class: "message-bg-assistant" class: "message-bg-assistant"
} }
} }
function addMessage(message, type) { function addMessage(message, role) {
if (type == MessageType.USER) { if (role == Roles.USER) {
conversation.push(userKeyword + message + assistantKeyword); conversation.push(
" " + frontend_config.profile.user_keyword + " "
+ message + " " + frontend_config.profile.assistant_keyword);
} }
else { conversation.push(message); } else { conversation.push(message); }
// UI // UI
let messageTypeElem = document.createElement("div"); let messageRoleElem = document.createElement("div");
messageTypeElem.classList.add("message-type"); messageRoleElem.classList.add("message-type");
messageTypeElem.innerText = type.name; messageRoleElem.innerText = role.name;
let messageTextElem = document.createElement("div"); let messageTextElem = document.createElement("div");
messageTextElem.classList.add("message-text"); messageTextElem.classList.add("message-text");
messageTextElem.innerText = message; messageTextElem.innerText = message;
let messageElem = document.createElement("div"); let messageElem = document.createElement("div");
messageElem.classList.add("message"); messageElem.classList.add("message");
messageElem.classList.add(type.class); messageElem.classList.add(role.class);
messageElem.appendChild(messageTypeElem); messageElem.appendChild(messageRoleElem);
messageElem.appendChild(messageTextElem); messageElem.appendChild(messageTextElem);
messageHistoryContainer.appendChild(messageElem); messageHistoryContainer.appendChild(messageElem);
messageHistoryContainer.scrollTo(0, messageHistoryContainer.scrollHeight); messageHistoryContainer.scrollTo(0, messageHistoryContainer.scrollHeight);
@ -169,10 +164,6 @@
} }
async function chat() { async function chat() {
if (frontend_config == null) {
console.log("Couldn't fetch frontend configuration.");
}
else {
disableInput(); disableInput();
let input = textInputElement.value.trim(); let input = textInputElement.value.trim();
if (input == "") { if (input == "") {
@ -181,19 +172,18 @@
else { else {
textInputElement.value = ""; textInputElement.value = "";
resizeInputElement(); resizeInputElement();
addMessage(input, MessageType.USER); addMessage(input, Roles.USER);
let prompt = conversation.join(""); let prompt = conversation.join("");
let settings = getSettings(); let settings = getSettings();
apiCompletion(prompt, settings).then(r => { apiCompletion(prompt, settings).then(r => {
addMessage(r, MessageType.ASSISTANT); addMessage(r, Roles.ASSISTANT);
enableInput(); enableInput();
}); });
} }
} }
}
function resetHistory() { function resetHistory() {
conversation = [conversationBeginning]; conversation = [frontend_config.profile.conversation_prefix];
messageHistoryContainer.innerText = ""; messageHistoryContainer.innerText = "";
} }
@ -213,4 +203,4 @@
textInputElement.addEventListener("input", resizeInputElement); textInputElement.addEventListener("input", resizeInputElement);
resizeInputElement(); resizeInputElement();
})(); });

7
profiles/koala.json Normal file
View file

@ -0,0 +1,7 @@
{
"name": "Koala",
"conversation_prefix": "BEGINNING OF CONVERSATION: ",
"user_keyword": "USER:",
"assistant_keyword": "GPT:",
"stop_sequence": "</s>"
}