From c3fda61b213ae0c8bd18664e6cc3651c689af3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller=20=28ChaoticByte=29?= Date: Thu, 18 May 2023 15:34:34 +0200 Subject: [PATCH] Made the frontend more flexible to also support other models than just Koala --- frontend-server.py | 24 ++++++++++- frontend/static/index.html | 4 ++ frontend/static/main.js | 84 +++++++++++++++++--------------------- profiles/koala.json | 7 ++++ 4 files changed, 71 insertions(+), 48 deletions(-) create mode 100644 profiles/koala.json diff --git a/frontend-server.py b/frontend-server.py index 2e1e7c3..a0fa3e6 100644 --- a/frontend-server.py +++ b/frontend-server.py @@ -2,18 +2,40 @@ # Copyright (c) 2023 Julian Müller (ChaoticByte) from argparse import ArgumentParser +from json import load +from pathlib import Path import uvicorn from frontend.app import app if __name__ == "__main__": + koala_profile_path = Path(__file__).parent / "profiles" / "koala.json" # CLI 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("--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") 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 - 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 uvicorn.run(app, host=args.host, port=args.port) diff --git a/frontend/static/index.html b/frontend/static/index.html index 34eae86..b13e19a 100644 --- a/frontend/static/index.html +++ b/frontend/static/index.html @@ -21,6 +21,10 @@
Settings
+
+
Assistant
+
+
max_tokens
diff --git a/frontend/static/main.js b/frontend/static/main.js index a3dc88a..f56cc78 100644 --- a/frontend/static/main.js +++ b/frontend/static/main.js @@ -1,27 +1,17 @@ // Copyright (c) 2023 Julian Müller (ChaoticByte) -(() => { +// Fetch configuration and initialize Eucalyptus Chat Frontend - // Koala specific keywords - const conversationBeginning = "BEGINNING OF CONVERSATION:"; - const userKeyword = " USER: "; - const assistantKeyword = " GPT:"; - const koalaStopSequence = ""; - - // Get frontend config - let frontend_config = null; - fetch("/config") - .then(r => { - return r.json(); - }) - .then(j => { - frontend_config = j; - }); +fetch("/config") +.then(r => { + return r.json(); +}).then(frontend_config => { // Message Context - let conversation = [conversationBeginning]; + let conversation = [frontend_config.profile.conversation_prefix]; // Elements - Sidebar + const settingsLabelAssistantNameElement = document.getElementById("settings-label-assistant"); const settingsMaxTokensElement = document.getElementById("settings-max-tokens"); const settingsTemperatureElement = document.getElementById("settings-temperature"); const settingsTopPElement = document.getElementById("settings-top-p"); @@ -32,6 +22,8 @@ const resetSettingsButtonElement = document.getElementById("reset-settings-btn"); const resetHistoryButtonElement = document.getElementById("reset-history-btn"); + settingsLabelAssistantNameElement.innerText = frontend_config.profile.name; + // Elements - Main const messageHistoryContainer = document.getElementById("messages"); const textInputElement = document.getElementById("text-input"); @@ -42,7 +34,7 @@ async function apiCompletion(prompt, settings) { const bodyData = JSON.stringify({ "prompt": prompt, - "stop": [koalaStopSequence], + "stop": [frontend_config.profile.stop_sequence], "max_tokens": settings.max_tokens, "temperature": settings.temperature, "top_p": settings.top_p, @@ -99,33 +91,36 @@ // Chat - const MessageType = { + // Message Roles + const Roles = { USER: { name: "User", class: "message-bg-user" }, ASSISTANT: { - name: "Koala", + name: frontend_config.profile.name, class: "message-bg-assistant" } } - function addMessage(message, type) { - if (type == MessageType.USER) { - conversation.push(userKeyword + message + assistantKeyword); + function addMessage(message, role) { + if (role == Roles.USER) { + conversation.push( + " " + frontend_config.profile.user_keyword + " " + + message + " " + frontend_config.profile.assistant_keyword); } else { conversation.push(message); } // UI - let messageTypeElem = document.createElement("div"); - messageTypeElem.classList.add("message-type"); - messageTypeElem.innerText = type.name; + let messageRoleElem = document.createElement("div"); + messageRoleElem.classList.add("message-type"); + messageRoleElem.innerText = role.name; let messageTextElem = document.createElement("div"); messageTextElem.classList.add("message-text"); messageTextElem.innerText = message; let messageElem = document.createElement("div"); messageElem.classList.add("message"); - messageElem.classList.add(type.class); - messageElem.appendChild(messageTypeElem); + messageElem.classList.add(role.class); + messageElem.appendChild(messageRoleElem); messageElem.appendChild(messageTextElem); messageHistoryContainer.appendChild(messageElem); messageHistoryContainer.scrollTo(0, messageHistoryContainer.scrollHeight); @@ -169,31 +164,26 @@ } async function chat() { - if (frontend_config == null) { - console.log("Couldn't fetch frontend configuration."); + disableInput(); + let input = textInputElement.value.trim(); + if (input == "") { + enableInput(); } else { - disableInput(); - let input = textInputElement.value.trim(); - if (input == "") { + textInputElement.value = ""; + resizeInputElement(); + addMessage(input, Roles.USER); + let prompt = conversation.join(""); + let settings = getSettings(); + apiCompletion(prompt, settings).then(r => { + addMessage(r, Roles.ASSISTANT); enableInput(); - } - else { - textInputElement.value = ""; - resizeInputElement(); - addMessage(input, MessageType.USER); - let prompt = conversation.join(""); - let settings = getSettings(); - apiCompletion(prompt, settings).then(r => { - addMessage(r, MessageType.ASSISTANT); - enableInput(); - }); - } + }); } } function resetHistory() { - conversation = [conversationBeginning]; + conversation = [frontend_config.profile.conversation_prefix]; messageHistoryContainer.innerText = ""; } @@ -213,4 +203,4 @@ textInputElement.addEventListener("input", resizeInputElement); resizeInputElement(); -})(); \ No newline at end of file +}); diff --git a/profiles/koala.json b/profiles/koala.json new file mode 100644 index 0000000..34b1c19 --- /dev/null +++ b/profiles/koala.json @@ -0,0 +1,7 @@ +{ + "name": "Koala", + "conversation_prefix": "BEGINNING OF CONVERSATION: ", + "user_keyword": "USER:", + "assistant_keyword": "GPT:", + "stop_sequence": "" +} \ No newline at end of file