1
0
mirror of https://github.com/coalaura/whiskr.git synced 2025-09-09 09:19:54 +00:00

title generation

This commit is contained in:
Laura
2025-08-25 22:45:03 +02:00
parent 3eac1a0795
commit 82e91cfc3e
14 changed files with 392 additions and 31 deletions

View File

@@ -1,6 +1,9 @@
(() => {
const $version = document.getElementById("version"),
$total = document.getElementById("total"),
$title = document.getElementById("title"),
$titleRefresh = document.getElementById("title-refresh"),
$titleText = document.getElementById("title-text"),
$messages = document.getElementById("messages"),
$chat = document.getElementById("chat"),
$message = document.getElementById("message"),
@@ -37,7 +40,8 @@
let autoScrolling = false,
jsonMode = false,
searchTool = false;
searchTool = false,
chatTitle = false;
let searchAvailable = false,
activeMessage = null,
@@ -51,6 +55,14 @@
$total.textContent = formatMoney(totalCost);
}
function updateTitle() {
$title.classList.toggle("hidden", !messages.length);
$titleText.textContent = chatTitle || (messages.length ? "New Chat" : "");
storeValue("title", chatTitle);
}
function updateScrollButton() {
const bottom = $messages.scrollHeight - ($messages.scrollTop + $messages.offsetHeight);
@@ -266,6 +278,8 @@
let timeout;
_optCopy.addEventListener("click", () => {
this.stopEdit();
clearTimeout(timeout);
navigator.clipboard.writeText(this.#text);
@@ -304,6 +318,8 @@
return;
}
this.stopEdit();
while (messages.length > index) {
messages[messages.length - 1].delete();
}
@@ -759,8 +775,6 @@
}
}
let controller;
async function json(url) {
try {
const response = await fetch(url);
@@ -778,6 +792,8 @@
}
async function stream(url, options, callback) {
let aborted;
try {
const response = await fetch(url, options);
@@ -834,29 +850,32 @@
}
}
} catch (err) {
if (err.name !== "AbortError") {
callback({
type: "error",
text: err.message,
});
if (err.name === "AbortError") {
aborted = true;
return;
}
callback({
type: "error",
text: err.message,
});
} finally {
callback(false);
callback(aborted ? "aborted" : "done");
}
}
let chatController;
function generate(cancel = false) {
if (controller) {
controller.abort();
if (chatController) {
chatController.abort();
if (cancel) {
return;
}
}
if (!$temperature.value) {
}
let temperature = parseFloat($temperature.value);
if (Number.isNaN(temperature) || temperature < 0 || temperature > 2) {
@@ -888,7 +907,7 @@
pushMessage();
controller = new AbortController();
chatController = new AbortController();
$chat.classList.add("completing");
@@ -908,14 +927,16 @@
let message, generationID;
function finish() {
function finish(aborted = false) {
if (!message) {
return;
}
message.setState(false);
setTimeout(message.loadGenerationData.bind(message), 750, generationID);
if (!aborted) {
setTimeout(message.loadGenerationData.bind(message), 750, generationID);
}
message = null;
generationID = null;
@@ -945,16 +966,24 @@
"Content-Type": "application/json",
},
body: JSON.stringify(body),
signal: controller.signal,
signal: chatController.signal,
},
chunk => {
if (!chunk) {
controller = null;
if (chunk === "aborted") {
finish(true);
return;
} else if (chunk === "done") {
chatController = null;
finish();
$chat.classList.remove("completing");
if (!chatTitle && !titleController) {
refreshTitle();
}
return;
}
@@ -999,6 +1028,65 @@
);
}
let titleController;
async function refreshTitle() {
if (titleController) {
titleController.abort();
}
titleController = new AbortController();
const body = {
title: chatTitle || null,
messages: messages.map(message => message.getData()).filter(Boolean),
};
if (!body.messages.length) {
updateTitle();
return;
}
$title.classList.add("refreshing");
try {
const response = await fetch("/-/title", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
signal: titleController.signal,
}),
result = await response.json();
if (result.cost) {
totalCost += result.cost;
updateTotalCost();
}
if (!response.ok || !result?.title) {
throw new Error(result?.error || response.statusText);
}
chatTitle = result.title;
} catch (err) {
if (err.name === "AbortError") {
return;
}
alert(err.message);
}
titleController = null;
updateTitle();
$title.classList.remove("refreshing");
}
async function login() {
const username = $username.value.trim(),
password = $password.value.trim();
@@ -1147,6 +1235,10 @@
}
});
chatTitle = loadValue("title");
updateTitle();
scroll();
// small fix, sometimes when hard reloading we don't scroll all the way
@@ -1235,11 +1327,12 @@
const message = new Message($role.value, "", text, attachments);
clearAttachments();
updateTitle();
return message;
}
$total.addEventListener("auxclick", (event) => {
$total.addEventListener("auxclick", event => {
if (event.button !== 1) {
return;
}
@@ -1249,6 +1342,10 @@
updateTotalCost();
});
$titleRefresh.addEventListener("click", () => {
refreshTitle();
});
$messages.addEventListener("scroll", () => {
updateScrollButton();
});
@@ -1417,6 +1514,10 @@
}
clearMessages();
chatTitle = false;
updateTitle();
});
$export.addEventListener("click", () => {