mirror of
https://github.com/coalaura/whiskr.git
synced 2025-12-02 20:22:52 +00:00
track actual time to first token
This commit is contained in:
@@ -455,6 +455,8 @@ body:not(.loading) #loading {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.message .time {
|
.message .time {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
line-height: 10px;
|
line-height: 10px;
|
||||||
@@ -464,6 +466,11 @@ body:not(.loading) #loading {
|
|||||||
color: var(--c-subtext);
|
color: var(--c-subtext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message .time .ttft-real::after {
|
||||||
|
content: "/";
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.tool .call,
|
.tool .call,
|
||||||
.reasoning .toggle {
|
.reasoning .toggle {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -175,6 +175,7 @@
|
|||||||
#tool;
|
#tool;
|
||||||
#tags = [];
|
#tags = [];
|
||||||
#time = 0;
|
#time = 0;
|
||||||
|
#ttft = 0;
|
||||||
#statistics;
|
#statistics;
|
||||||
#error = false;
|
#error = false;
|
||||||
|
|
||||||
@@ -206,6 +207,7 @@
|
|||||||
this.#text = data.text || "";
|
this.#text = data.text || "";
|
||||||
|
|
||||||
this.#time = data.time;
|
this.#time = data.time;
|
||||||
|
this.#ttft = data.ttft;
|
||||||
|
|
||||||
this.#_diff = document.createElement("div");
|
this.#_diff = document.createElement("div");
|
||||||
|
|
||||||
@@ -278,10 +280,6 @@
|
|||||||
// time
|
// time
|
||||||
this.#_time = make("div", "time");
|
this.#_time = make("div", "time");
|
||||||
|
|
||||||
if (this.#time) {
|
|
||||||
this.#_time.textContent = formatMilliseconds(this.#time * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
_body.appendChild(this.#_time);
|
_body.appendChild(this.#_time);
|
||||||
|
|
||||||
// loader
|
// loader
|
||||||
@@ -767,6 +765,28 @@
|
|||||||
this.#_message.classList.toggle("has-statistics", !!html);
|
this.#_message.classList.toggle("has-statistics", !!html);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!only || only === "time") {
|
||||||
|
this.#_time.innerHTML = "";
|
||||||
|
|
||||||
|
if (this.#time) {
|
||||||
|
if (this.#ttft) {
|
||||||
|
const ttft = make("span", "ttft-real");
|
||||||
|
|
||||||
|
ttft.title = "Real time to first token";
|
||||||
|
ttft.textContent = `${formatMilliseconds(this.#ttft * 1000)}`;
|
||||||
|
|
||||||
|
this.#_time.appendChild(ttft);
|
||||||
|
}
|
||||||
|
|
||||||
|
const time = make("span");
|
||||||
|
|
||||||
|
time.title = "Total time taken";
|
||||||
|
time.textContent = formatMilliseconds(this.#time * 1000);
|
||||||
|
|
||||||
|
this.#_time.appendChild(time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.#error) {
|
if (this.#error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -874,6 +894,10 @@
|
|||||||
|
|
||||||
if (this.#time && full) {
|
if (this.#time && full) {
|
||||||
data.time = this.#time;
|
data.time = this.#time;
|
||||||
|
|
||||||
|
if (this.#ttft) {
|
||||||
|
data.ttft = this.#ttft;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.#_message.classList.contains("collapsed") && full) {
|
if (this.#_message.classList.contains("collapsed") && full) {
|
||||||
@@ -894,11 +918,17 @@
|
|||||||
this.#save();
|
this.#save();
|
||||||
}
|
}
|
||||||
|
|
||||||
setTime(time) {
|
setTime(time, ttft, final = false) {
|
||||||
this.#time = time;
|
this.#time = time;
|
||||||
|
|
||||||
if (this.#time) {
|
if (ttft && !this.#ttft) {
|
||||||
this.#_time.textContent = formatMilliseconds(this.#time * 1000);
|
this.#ttft = ttft;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#render("time");
|
||||||
|
|
||||||
|
if (final) {
|
||||||
|
this.#save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1321,7 +1351,7 @@
|
|||||||
|
|
||||||
$chat.classList.add("completing");
|
$chat.classList.add("completing");
|
||||||
|
|
||||||
let message, generationID, stopTimeout, timeInterval, started;
|
let message, generationID, stopTimeout, timeInterval, started, receivedToken;
|
||||||
|
|
||||||
function startLoadingTimeout() {
|
function startLoadingTimeout() {
|
||||||
stopTimeout?.();
|
stopTimeout?.();
|
||||||
@@ -1354,7 +1384,9 @@
|
|||||||
|
|
||||||
clearInterval(timeInterval);
|
clearInterval(timeInterval);
|
||||||
|
|
||||||
msg.setTime(Math.round((Date.now() - started) / 100) / 10);
|
const took = Math.round((Date.now() - started) / 100) / 10;
|
||||||
|
|
||||||
|
msg.setTime(took, false);
|
||||||
|
|
||||||
msg.setState(false);
|
msg.setState(false);
|
||||||
|
|
||||||
@@ -1362,6 +1394,8 @@
|
|||||||
msg.loadGenerationData(genID);
|
msg.loadGenerationData(genID);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
receivedToken = false;
|
||||||
|
|
||||||
message = null;
|
message = null;
|
||||||
generationID = null;
|
generationID = null;
|
||||||
}
|
}
|
||||||
@@ -1388,7 +1422,9 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
message.setTime(Math.round((Date.now() - started) / 100) / 10);
|
const took = Math.round((Date.now() - started) / 100) / 10;
|
||||||
|
|
||||||
|
message.setTime(took, receivedToken ? took : false);
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1454,6 +1490,8 @@
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case "tool":
|
case "tool":
|
||||||
|
receivedToken = true;
|
||||||
|
|
||||||
message.setState("tooling");
|
message.setState("tooling");
|
||||||
message.setTool(chunk.data);
|
message.setTool(chunk.data);
|
||||||
|
|
||||||
@@ -1467,19 +1505,27 @@
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case "image":
|
case "image":
|
||||||
|
receivedToken = true;
|
||||||
|
|
||||||
message.addImage(chunk.data);
|
message.addImage(chunk.data);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "reason":
|
case "reason":
|
||||||
|
receivedToken = true;
|
||||||
|
|
||||||
message.setState("reasoning");
|
message.setState("reasoning");
|
||||||
message.addReasoning(chunk.data);
|
message.addReasoning(chunk.data);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "reason_type":
|
case "reason_type":
|
||||||
|
receivedToken = true;
|
||||||
|
|
||||||
message.setReasoningType(chunk.data);
|
message.setReasoningType(chunk.data);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "text":
|
case "text":
|
||||||
|
receivedToken = true;
|
||||||
|
|
||||||
message.setState("receiving");
|
message.setState("receiving");
|
||||||
message.addText(chunk.data);
|
message.addText(chunk.data);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user