Made the frontend more flexible to also support other models than just Koala
This commit is contained in:
parent
02a142012b
commit
c3fda61b21
4 changed files with 71 additions and 48 deletions
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
7
profiles/koala.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"name": "Koala",
|
||||||
|
"conversation_prefix": "BEGINNING OF CONVERSATION: ",
|
||||||
|
"user_keyword": "USER:",
|
||||||
|
"assistant_keyword": "GPT:",
|
||||||
|
"stop_sequence": "</s>"
|
||||||
|
}
|
Reference in a new issue