Spaces:
Running
Running
Update metrics display and calculations: Rename and add new metrics for EOU Delay, STT Finalization, LLM TTFT, LLM→TTS Handoff, and TTS TTFB. Adjust layout for better responsiveness and improve average calculations in the metrics collector.
Browse files- src/ui/index.html +20 -7
- src/ui/main.js +64 -27
src/ui/index.html
CHANGED
|
@@ -247,8 +247,9 @@
|
|
| 247 |
.averages-row {
|
| 248 |
flex-shrink: 0;
|
| 249 |
display: flex;
|
|
|
|
| 250 |
align-items: center;
|
| 251 |
-
gap: 24px;
|
| 252 |
padding: 8px 24px;
|
| 253 |
border-top: 1px solid var(--border);
|
| 254 |
border-bottom: 1px solid var(--border);
|
|
@@ -390,16 +391,28 @@
|
|
| 390 |
<!-- Averages compact row -->
|
| 391 |
<div class="averages-row">
|
| 392 |
<div class="avg-item">
|
| 393 |
-
<span class="avg-item-label">Avg
|
| 394 |
-
<span class="avg-item-value" id="avg-
|
| 395 |
</div>
|
| 396 |
<div class="avg-item">
|
| 397 |
-
<span class="avg-item-label">Avg
|
| 398 |
-
<span class="avg-item-value" id="avg-
|
| 399 |
</div>
|
| 400 |
<div class="avg-item">
|
| 401 |
-
<span class="avg-item-label">Avg
|
| 402 |
-
<span class="avg-item-value" id="avg-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 403 |
</div>
|
| 404 |
</div>
|
| 405 |
|
|
|
|
| 247 |
.averages-row {
|
| 248 |
flex-shrink: 0;
|
| 249 |
display: flex;
|
| 250 |
+
flex-wrap: wrap;
|
| 251 |
align-items: center;
|
| 252 |
+
gap: 10px 24px;
|
| 253 |
padding: 8px 24px;
|
| 254 |
border-top: 1px solid var(--border);
|
| 255 |
border-bottom: 1px solid var(--border);
|
|
|
|
| 391 |
<!-- Averages compact row -->
|
| 392 |
<div class="averages-row">
|
| 393 |
<div class="avg-item">
|
| 394 |
+
<span class="avg-item-label">Avg EOU:</span>
|
| 395 |
+
<span class="avg-item-value" id="avg-eou">-- <span class="unit">s</span></span>
|
| 396 |
</div>
|
| 397 |
<div class="avg-item">
|
| 398 |
+
<span class="avg-item-label">Avg STT Finalization:</span>
|
| 399 |
+
<span class="avg-item-value" id="avg-stt-finalization">-- <span class="unit">s</span></span>
|
| 400 |
</div>
|
| 401 |
<div class="avg-item">
|
| 402 |
+
<span class="avg-item-label">Avg LLM TTFT:</span>
|
| 403 |
+
<span class="avg-item-value" id="avg-llm-ttft">-- <span class="unit">s</span></span>
|
| 404 |
+
</div>
|
| 405 |
+
<div class="avg-item">
|
| 406 |
+
<span class="avg-item-label">Avg LLM→TTS Handoff:</span>
|
| 407 |
+
<span class="avg-item-value" id="avg-llm-handoff">-- <span class="unit">s</span></span>
|
| 408 |
+
</div>
|
| 409 |
+
<div class="avg-item">
|
| 410 |
+
<span class="avg-item-label">Avg TTS TTFB:</span>
|
| 411 |
+
<span class="avg-item-value" id="avg-tts-ttfb">-- <span class="unit">s</span></span>
|
| 412 |
+
</div>
|
| 413 |
+
<div class="avg-item">
|
| 414 |
+
<span class="avg-item-label">Avg Total:</span>
|
| 415 |
+
<span class="avg-item-value" id="avg-total">-- <span class="unit">s</span></span>
|
| 416 |
</div>
|
| 417 |
</div>
|
| 418 |
|
src/ui/main.js
CHANGED
|
@@ -21,10 +21,12 @@ let currentSessionId = null;
|
|
| 21 |
let metricsHistory = [];
|
| 22 |
let turnCount = 0;
|
| 23 |
let averages = {
|
| 24 |
-
|
| 25 |
-
|
| 26 |
llmTtft: [],
|
| 27 |
-
|
|
|
|
|
|
|
| 28 |
};
|
| 29 |
const LIVE_METRIC_IDS = [
|
| 30 |
"eou",
|
|
@@ -277,17 +279,26 @@ function resetMetrics() {
|
|
| 277 |
turnCount = 0;
|
| 278 |
activeLiveSpeechId = null;
|
| 279 |
averages = {
|
| 280 |
-
|
| 281 |
-
|
| 282 |
llmTtft: [],
|
| 283 |
-
|
|
|
|
|
|
|
| 284 |
};
|
| 285 |
|
| 286 |
clearAllLiveMetrics();
|
| 287 |
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 291 |
}
|
| 292 |
|
| 293 |
function handleLiveTurnBoundary(metricsData) {
|
|
@@ -424,29 +435,55 @@ function updateLiveMetrics(turn) {
|
|
| 424 |
function updateAverages() {
|
| 425 |
const avg = (arr) => arr.length ? arr.reduce((a, b) => a + b, 0) / arr.length : null;
|
| 426 |
|
| 427 |
-
const
|
| 428 |
-
const
|
| 429 |
-
const
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 440 |
}
|
| 441 |
|
| 442 |
function renderTurn(turn) {
|
| 443 |
metricsHistory.push(turn);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 444 |
|
| 445 |
-
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 450 |
|
| 451 |
updateAverages();
|
| 452 |
}
|
|
|
|
| 21 |
let metricsHistory = [];
|
| 22 |
let turnCount = 0;
|
| 23 |
let averages = {
|
| 24 |
+
eouDelay: [],
|
| 25 |
+
sttFinalization: [],
|
| 26 |
llmTtft: [],
|
| 27 |
+
llmToTtsHandoff: [],
|
| 28 |
+
ttsTtfb: [],
|
| 29 |
+
totalLatency: [],
|
| 30 |
};
|
| 31 |
const LIVE_METRIC_IDS = [
|
| 32 |
"eou",
|
|
|
|
| 279 |
turnCount = 0;
|
| 280 |
activeLiveSpeechId = null;
|
| 281 |
averages = {
|
| 282 |
+
eouDelay: [],
|
| 283 |
+
sttFinalization: [],
|
| 284 |
llmTtft: [],
|
| 285 |
+
llmToTtsHandoff: [],
|
| 286 |
+
ttsTtfb: [],
|
| 287 |
+
totalLatency: [],
|
| 288 |
};
|
| 289 |
|
| 290 |
clearAllLiveMetrics();
|
| 291 |
|
| 292 |
+
[
|
| 293 |
+
"avg-eou",
|
| 294 |
+
"avg-stt-finalization",
|
| 295 |
+
"avg-llm-ttft",
|
| 296 |
+
"avg-llm-handoff",
|
| 297 |
+
"avg-tts-ttfb",
|
| 298 |
+
"avg-total",
|
| 299 |
+
].forEach((id) => {
|
| 300 |
+
document.getElementById(id).innerHTML = '-- <span class="unit">s</span>';
|
| 301 |
+
});
|
| 302 |
}
|
| 303 |
|
| 304 |
function handleLiveTurnBoundary(metricsData) {
|
|
|
|
| 435 |
function updateAverages() {
|
| 436 |
const avg = (arr) => arr.length ? arr.reduce((a, b) => a + b, 0) / arr.length : null;
|
| 437 |
|
| 438 |
+
const avgEou = avg(averages.eouDelay);
|
| 439 |
+
const avgSttFinalization = avg(averages.sttFinalization);
|
| 440 |
+
const avgLlmTtft = avg(averages.llmTtft);
|
| 441 |
+
const avgLlmToTtsHandoff = avg(averages.llmToTtsHandoff);
|
| 442 |
+
const avgTtsTtfb = avg(averages.ttsTtfb);
|
| 443 |
+
const avgTotalLatency = avg(averages.totalLatency);
|
| 444 |
+
|
| 445 |
+
const setAverageValue = (id, value) => {
|
| 446 |
+
document.getElementById(id).innerHTML = value !== null
|
| 447 |
+
? `${value.toFixed(2)} <span class="unit">s</span>`
|
| 448 |
+
: '-- <span class="unit">s</span>';
|
| 449 |
+
};
|
| 450 |
+
|
| 451 |
+
setAverageValue("avg-eou", avgEou);
|
| 452 |
+
setAverageValue("avg-stt-finalization", avgSttFinalization);
|
| 453 |
+
setAverageValue("avg-llm-ttft", avgLlmTtft);
|
| 454 |
+
setAverageValue("avg-llm-handoff", avgLlmToTtsHandoff);
|
| 455 |
+
setAverageValue("avg-tts-ttfb", avgTtsTtfb);
|
| 456 |
+
setAverageValue("avg-total", avgTotalLatency);
|
| 457 |
}
|
| 458 |
|
| 459 |
function renderTurn(turn) {
|
| 460 |
metricsHistory.push(turn);
|
| 461 |
+
const latencies = turn.latencies || {};
|
| 462 |
+
const metrics = turn.metrics || {};
|
| 463 |
+
|
| 464 |
+
const eouDelay = latencies.eou_delay ?? latencies.vad_detection_delay;
|
| 465 |
+
if (isFiniteNumber(eouDelay) && eouDelay > 0) averages.eouDelay.push(eouDelay);
|
| 466 |
|
| 467 |
+
const sttFinalization = latencies.stt_finalization_delay;
|
| 468 |
+
if (isFiniteNumber(sttFinalization) && sttFinalization > 0) {
|
| 469 |
+
averages.sttFinalization.push(sttFinalization);
|
| 470 |
+
}
|
| 471 |
+
|
| 472 |
+
const llmTtft = metrics.llm?.ttft;
|
| 473 |
+
if (isFiniteNumber(llmTtft) && llmTtft > 0) averages.llmTtft.push(llmTtft);
|
| 474 |
+
|
| 475 |
+
const llmToTtsHandoff = latencies.llm_to_tts_handoff_latency;
|
| 476 |
+
if (isFiniteNumber(llmToTtsHandoff) && llmToTtsHandoff > 0) {
|
| 477 |
+
averages.llmToTtsHandoff.push(llmToTtsHandoff);
|
| 478 |
+
}
|
| 479 |
+
|
| 480 |
+
const ttsTtfb = metrics.tts?.ttfb;
|
| 481 |
+
if (isFiniteNumber(ttsTtfb) && ttsTtfb > 0) averages.ttsTtfb.push(ttsTtfb);
|
| 482 |
+
|
| 483 |
+
const totalLatency = latencies.total_latency;
|
| 484 |
+
if (isFiniteNumber(totalLatency) && totalLatency > 0) {
|
| 485 |
+
averages.totalLatency.push(totalLatency);
|
| 486 |
+
}
|
| 487 |
|
| 488 |
updateAverages();
|
| 489 |
}
|