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

total cost tracker

This commit is contained in:
Laura
2025-08-23 18:07:53 +02:00
parent 9bf526fd01
commit 480e955910
5 changed files with 60 additions and 17 deletions

View File

@@ -73,29 +73,26 @@ body.resizing * {
cursor: grabbing !important;
}
#total,
#version {
position: absolute;
font-size: 12px;
font-style: italic;
top: 3px;
right: 6px;
right: 4px;
color: #a5adcb;
}
#total {
right: unset;
left: 4px;
}
#version a {
color: #a5adcb;
text-decoration: none;
}
body.loading #version {
font-size: 0;
animation: rotating 1.2s linear infinite;
background-image: url(icons/spinner.svg);
width: 16px;
height: 16px;
top: 6px;
}
#loading {
position: absolute;
top: 0;

View File

@@ -16,6 +16,7 @@
<title>whiskr</title>
</head>
<body class="loading">
<div id="total" title="Accumulated total cost, middle-click to reset"></div>
<div id="version"></div>
<div id="loading">

View File

@@ -1,5 +1,6 @@
(() => {
const $version = document.getElementById("version"),
$total = document.getElementById("total"),
$messages = document.getElementById("messages"),
$chat = document.getElementById("chat"),
$message = document.getElementById("message"),
@@ -41,7 +42,14 @@
let searchAvailable = false,
activeMessage = null,
isResizing = false,
scrollResize = false;
scrollResize = false,
totalCost = 0;
function updateTotalCost() {
storeValue("total-cost", totalCost);
$total.textContent = formatMoney(totalCost);
}
function updateScrollButton() {
const bottom = $messages.scrollHeight - ($messages.scrollTop + $messages.offsetHeight);
@@ -448,8 +456,7 @@
if (this.#statistics) {
const { provider, model, ttft, time, input, output, cost } = this.#statistics;
const tps = output / (time / 1000),
price = cost < 1 ? `${fixed(cost * 100, 1)}ct` : `$${fixed(cost, 2)}`;
const tps = output / (time / 1000);
html = [
provider ? `<div class="provider">${provider} (${model.split("/").pop()})</div>` : "",
@@ -462,7 +469,7 @@
=
<div class="total">${input + output}t</div>
</div>`,
`<div class="cost">${price}</div>`,
`<div class="cost">${formatMoney(cost)}</div>`,
].join("");
}
@@ -587,6 +594,10 @@
}
this.setStatistics(data);
totalCost += data.cost;
updateTotalCost();
} catch (err) {
console.error(err);
@@ -1030,6 +1041,11 @@
// start icon preload
preloadIcons(data.icons);
// render total cost
totalCost = loadValue("total-cost", 0);
updateTotalCost();
// render version
if (data.version === "dev") {
$version.remove();
@@ -1223,6 +1239,16 @@
return message;
}
$total.addEventListener("auxclick", (event) => {
if (event.button !== 1) {
return;
}
totalCost = 0;
updateTotalCost();
});
$messages.addEventListener("scroll", () => {
updateScrollButton();
});
@@ -1244,7 +1270,7 @@
$resizeBar.addEventListener("mousedown", event => {
const isAtBottom = $messages.scrollHeight - ($messages.scrollTop + $messages.offsetHeight) <= 10;
if (event.buttons === 4) {
if (event.button === 1) {
$chat.style.height = "";
storeValue("resized", false);
@@ -1252,7 +1278,7 @@
scroll(isAtBottom, true);
return;
} else if (event.buttons !== 1) {
} else if (event.button !== 0) {
return;
}

View File

@@ -84,6 +84,26 @@ function fixed(num, decimals = 0) {
return num.toFixed(decimals).replace(/\.?0+$/m, "");
}
function formatMoney(num) {
if (num === 0) {
return "0ct";
}
if (num < 1) {
let decimals = 1;
if (num < 0.0001) {
decimals = 3;
} else if (num < 0.001) {
decimals = 2;
}
return `${fixed(num * 100, decimals)}ct`;
}
return `$${fixed(num, 2)}`;
}
function clamp(num, min, max) {
return Math.min(Math.max(num, min), max);
}