{t("maint. pending")}
// AI-MONITOR · Page sections — Nodes, Models, Telemetry
const { NODES: _NODES, MODELS: _MODELS, live: _live, totals: _totals } = window.AIData;
// ── NODES ──────────────────────────────────────────────────────────────
function NodesSection() {
useLive();
const { t } = useLang();
const [active, setActive] = useState(null);
const [nfilter, setNfilter] = useState("All");
return (
{t("Each host runs the LiteLLM gateway, an inference engine, or both. Click a node for the full forensic view.")}
{t("{n} machines. ", { n: _NODES.length })}{t("Each a citizen.")}
{t("maint. pending")}
{t("All inference is routed through LiteLLM on ")}{(_live.cluster && _live.cluster.gatewayHost) || "127.0.0.1:4000"}{t(" — OpenAI-compatible API, smart routing, fallbacks, cost & token accounting. Cold models spin up on demand to fit the VRAM budget.")}
{t("Every request that lands at the gateway, every anomaly the rules engine catches — surfaced as a quiet, structured stream. No paging unless something actually needs you.")}
{haAny && (| {t("Device")} | {t("Type")} | {t("Power")} | {t("24h")} | {t("30d")} | {t("Plug °C")} | {t("State")} |
|---|---|---|---|---|---|---|
| {n.name} {n.ip} | {n.class || t("Compute node")} | {has ? w.toFixed(0) + " W" : "—"} | {k24 != null ? k24.toFixed(2) + " kWh" : "—"} | {k30 != null ? k30.toFixed(2) + " kWh" : "—"} | {ptemp != null ? ptemp.toFixed(0) + " °C" : "—"} | {has ? ( <>{t("on")}> ) : ( {t("no smart plug")} )} |
| {t("Rack AC")} — | {t("Cabinet HVAC")} | {en.acW != null ? en.acW.toFixed(0) + " W" : "—"} | {en.acKwh24h != null ? en.acKwh24h.toFixed(2) + " kWh" : "—"} | {en.acKwh30d != null ? en.acKwh30d.toFixed(2) + " kWh" : "—"} | — | {en.acOn == null ? t("unknown") : en.acOn ? t("on") : t("off")} |
| {t("Metric")} | {t("24h")} | {t("7d")} | {t("30d")} |
|---|---|---|---|
| {t("AC energy")} | {_trendCell(_live.energyTrends.ac?.last24h?.kwh, " kWh", 2)} | {_trendCell(_live.energyTrends.ac?.last7d?.kwh, " kWh", 2)} | {_trendCell(_live.energyTrends.ac?.last30d?.kwh, " kWh", 2)} |
| {t("avg power")} | {_trendCell(_live.energyTrends.ac?.last24h?.avgW, " W", 0)} | {_trendCell(_live.energyTrends.ac?.last7d?.avgW, " W", 0)} | {_trendCell(_live.energyTrends.ac?.last30d?.avgW, " W", 0)} |
| ↳ {t("day")} (06-18) | {_trendCell(_live.energyTrends.ac?.last24h?.dayAvgW, " W", 0)} | {_trendCell(_live.energyTrends.ac?.last7d?.dayAvgW, " W", 0)} | {_trendCell(_live.energyTrends.ac?.last30d?.dayAvgW, " W", 0)} |
| ↳ {t("night")} (18-06) | {_trendCell(_live.energyTrends.ac?.last24h?.nightAvgW, " W", 0)} | {_trendCell(_live.energyTrends.ac?.last7d?.nightAvgW, " W", 0)} | {_trendCell(_live.energyTrends.ac?.last30d?.nightAvgW, " W", 0)} |
| {t("Wall avg")} | {_trendCell(_live.energyTrends.wall?.last24h?.avgW, " W", 0)} | {_trendCell(_live.energyTrends.wall?.last7d?.avgW, " W", 0)} | {_trendCell(_live.energyTrends.wall?.last30d?.avgW, " W", 0)} |
| {t("Cabinet mean")} | {_trendCell(_live.energyTrends.cabinet?.last24h?.meanC, " °C", 1)} | {_trendCell(_live.energyTrends.cabinet?.last7d?.meanC, " °C", 1)} | {_trendCell(_live.energyTrends.cabinet?.last30d?.meanC, " °C", 1)} |
| {t("min / max")} | {_trendCell(_live.energyTrends.cabinet?.last24h?.minC, "", 1)} / {_trendCell(_live.energyTrends.cabinet?.last24h?.maxC, " °C", 1)} | {_trendCell(_live.energyTrends.cabinet?.last7d?.minC, "", 1)} / {_trendCell(_live.energyTrends.cabinet?.last7d?.maxC, " °C", 1)} | {_trendCell(_live.energyTrends.cabinet?.last30d?.minC, "", 1)} / {_trendCell(_live.energyTrends.cabinet?.last30d?.maxC, " °C", 1)} |
| {t("samples")} | {_live.energyTrends.ac?.last24h?.samples || 0} / 96 | {_live.energyTrends.ac?.last7d?.samples || 0} / 672 | {_live.energyTrends.ac?.last30d?.samples || 0} / 2880 |
{t("The gateway host peers with every inference node — link intensity & pulse are driven by real node-exporter throughput. Inter-node fabric (RDMA/InfiniBand) is physical topology only (throughput not instrumented by default).")}