routing tests, launch.configs, redirect, stats and route statistics

This commit is contained in:
Dobromir Popov
2026-07-11 11:39:47 +03:00
parent f54ea100fb
commit 11bf460027
12 changed files with 546 additions and 80 deletions

View File

@@ -240,6 +240,7 @@
<section data-tab="overview"><h2>Nodes &amp; coverage</h2><div id="nodes" class="empty">loading…</div></section>
<section data-tab="overview"><h2>Model usage (RPM)</h2><div id="stats" class="empty">loading…</div></section>
<section data-tab="overview" class="wide"><h2>Routing (learned)</h2><div id="routing" class="empty">loading…</div></section>
<section data-tab="overview" class="wide"><h2>Model inference speed</h2><div id="model-speed-chart" class="empty">loading…</div></section>
<section data-tab="overview" class="wide"><h2>Call wall</h2><div id="call-wall" class="empty">loading...</div></section>
<section data-tab="chat" class="wide chat-section">
<h2 style="display:none">Chat / inference</h2>
@@ -752,6 +753,27 @@ function renderRouting(routing) {
el.innerHTML = html;
}
function renderModelSpeed(reports) {
const el = $("model-speed-chart");
if (!el) return;
const models = Object.entries(reports || {});
if (!models.length) { el.innerHTML = '<div class="empty">no observed route samples yet</div>'; return; }
let html = '';
for (const [model, report] of models) {
const routes = report.routes || [];
html += `<div style="margin:8px 0"><b>${esc(model)}</b>`;
html += table(["hops", "devices", "latency", "hop penalty", "speed", "samples", "route drill"], routes.map(route => [
`<span class="num">${esc(String(route.hop_count))}</span>`, esc(route.device_mix || "?"),
`<span class="num">${esc(route.latency_ms == null ? "—" : route.latency_ms.toFixed(2) + " ms")}</span>`,
`<span class="num">${esc(route.latency_penalty_ms == null ? "—" : route.latency_penalty_ms.toFixed(2) + " ms")}</span>`,
`<span class="num">${esc(tps(route.tps))}</span>`, `<span class="num">${esc(String(route.samples || 0))}</span>`,
`<details><summary>nodes</summary><span class="dim">${esc((route.node_ids || []).join(" → "))}</span></details>`,
]));
html += '</div>';
}
el.innerHTML = html;
}
function renderCallWall(consoleData, stats, map) {
const events = (consoleData && consoleData.events) || [];
const nowSec = Date.now() / 1000;
@@ -1954,6 +1976,11 @@ async function fetchOverviewTab() {
renderIfChanged("nodes", map, renderNodes);
renderIfChanged("stats", stats, renderStats);
renderIfChanged("routing", routing, renderRouting);
const speedModels = Object.keys((routing && routing.models) || {});
const reports = Object.fromEntries(await Promise.all(speedModels.map(async model => [
model, await fetchJson("/v1/model-speed?model=" + encodeURIComponent(model)),
])));
renderIfChanged("model-speed", reports, renderModelSpeed);
renderIfChanged("call-wall", { consoleData, stats, map }, data => renderCallWall(data.consoleData, data.stats, data.map));
}