diff --git a/app/package.json b/app/package.json index 39862c1..762aca5 100644 --- a/app/package.json +++ b/app/package.json @@ -2,7 +2,7 @@ "name": "church-translate-engine", "productName": "Church Translate", "version": "3.23.2", - "buildNumber": 113, + "buildNumber": 114, "private": true, "description": "Live sermon translation — self-contained: captures audio, transcribes, translates, and serves the congregation page itself", "main": "main.js", @@ -106,7 +106,7 @@ ] }, "asar": false, - "buildVersion": "113", + "buildVersion": "114", "win": { "target": [ { diff --git a/app/server/server.js b/app/server/server.js index e5e2e1c..2c51504 100644 --- a/app/server/server.js +++ b/app/server/server.js @@ -500,6 +500,23 @@ const ENGINE_STALE_MS = 12000; * with one plain sentence does. Computed here so every operator surface — * in-app pane, browser page — shows the same verdict. */ +/* + * WHEN IT IS BEHIND, SAY WHAT IS LOADING IT. + * + * Translation cost is roughly linear in the number of active languages, through + * ONE NLLB process — measured, five languages in 1.9 s. So the single most + * useful fact about a machine that is falling behind is how many languages it + * is carrying, and that number was computed one function away and never shown. + * A campus reported "constantly behind, in the red" and the cause took an + * afternoon to find; it was eight languages on hardware tuned against one. + */ +function loadNote() { + const n = activeLanguages().length; + if (n < 2) return ''; + return ' Carrying ' + n + ' languages' + + (config.allowAllLanguages ? ', and listeners may add more' : '') + '.'; +} + function healthVerdict(connected, stale) { const es = state.engineStatus || {}; if (!connected) return { level: 'red', detail: 'The translation app is not connected.' }; @@ -507,9 +524,11 @@ function healthVerdict(connected, stale) { if (!state.live) return { level: 'green', detail: 'Ready.' }; if (!es.modelsReady) return { level: 'amber', detail: 'Models are still loading.' }; if ((es.lagMs || 0) > 12000 || (es.captionOnlyFinals || 0) > 0) - return { level: 'red', detail: 'Falling badly behind — some sentences are captions only.' }; + return { level: 'red', + detail: 'Falling badly behind — some sentences are captions only.' + loadNote() }; if ((es.lagMs || 0) > 6000 || (es.queue || 0) >= 2 || (es.degradedFinals || 0) > 0) - return { level: 'amber', detail: 'Running behind — idle languages may be trimmed to catch up.' }; + return { level: 'amber', + detail: 'Running behind — idle languages may be trimmed to catch up.' + loadNote() }; if (es.cloud && es.cloud.parked) return { level: 'amber', detail: 'Natural voices are down — the built-in voices have taken over.' }; /* A fallback in the last minute means one language just changed voice