Rudder on a server that should run the engine says it is not running yet, not that it only runs on your computer

The dev backend reports expected=true while an engine the server is set up to
run is down (RUDDER_ENGINE=1 or RUDDER_AUDIO=browser). Rudder then reads "Not
running yet" and says the engine is starting or failed to set up; "Runs on
your computer" remains for a server with no engine at all.
This commit is contained in:
Doxa Maps 2026-09-27 22:35:00 +00:00
parent b347310ef4
commit 8e267b0ce5
2 changed files with 13 additions and 2 deletions

View file

@ -30,6 +30,9 @@ export const DEV_BACKENDS = [
route: '/api/rudder',
port: Number(process.env.RUDDER_PORT || 5193),
env: { RUDDER_PORT: String(process.env.RUDDER_PORT || 5193), RUDDER_NEMO_PORT: String(process.env.RUDDER_NEMO_PORT || 5194) },
// This server is SUPPOSED to run the engine (a server deployment with the engine switched on): while it
// is down, the plugin says "not running yet" instead of "runs on your own computer".
expected: () => process.env.RUDDER_ENGINE === '1' || process.env.RUDDER_AUDIO === 'browser',
},
]
@ -87,7 +90,8 @@ export function backendDevPlugin(root) {
if (isAlive(b.name)) return next()
if ((req.url || '').startsWith('/events')) {
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' })
res.write(`data: ${JSON.stringify({ type: 'status', status: { engine: 'offline', error: 'The desktop engine is not running.' } })}\n\n`)
const expected = !!(b.expected && b.expected())
res.write(`data: ${JSON.stringify({ type: 'status', status: { engine: 'offline', expected, error: 'The desktop engine is not running.' } })}\n\n`)
return // held open, so the EventSource does not reconnect in a loop
}
res.writeHead(200, { 'Content-Type': 'application/json' })

View file

@ -287,6 +287,7 @@ function applyStatus(s) {
if (s.runtime) runtime.value = s.runtime
if (s.model) model.value = s.model
if (s.audio) audioMode.value = s.audio
if (typeof s.expected === 'boolean') engineExpected.value = s.expected
// A browser session's state is this page's own; the server's shared status never reports it.
if (typeof s.recording === 'boolean' && audioMode.value !== 'browser') recording.value = s.recording
}
@ -377,6 +378,9 @@ const WORKLET = `class RudderPcm16k extends AudioWorkletProcessor {
}
registerProcessor('rudder-pcm16k', RudderPcm16k)`
const audioMode = ref('local')
// The server is set up to run the engine (it reports expected=true while the engine is down): an absent
// engine there means "starting or failed to set up", not "this only runs on your computer".
const engineExpected = ref(false)
let sock = null, media = null, actx = null
async function startBrowser() {
@ -577,7 +581,7 @@ const statusText = computed(() => ({
starting: 'Loading speech model… (about 20 s the first time)',
ready: recording.value ? 'Listening' : 'Ready',
error: 'Engine error',
offline: onOwnComputer.value ? 'Engine offline' : 'Runs on your computer',
offline: onOwnComputer.value ? 'Engine offline' : engineExpected.value ? 'Not running yet' : 'Runs on your computer',
}[engine.value] || engine.value))
</script>
@ -675,6 +679,9 @@ const statusText = computed(() => ({
<p v-if="offCards.length" class="hint">Also available but switched off in Sound settings: {{ offCards.join(', ') }}. Turn it on there to use it here.</p>
<p v-if="notice" class="notice" :data-kind="noticeKind">{{ notice }}</p>
<p v-else-if="engine === 'offline' && !onOwnComputer && engineExpected" class="notice" data-kind="warn">
The voice engine on this server isn't running yet (it is starting, or it failed to set up). Try again in a minute.
</p>
<p v-else-if="engine === 'offline' && !onOwnComputer" class="notice" data-kind="warn">
Voice to text runs on your own computer, not on this server: it listens to the microphone of the machine
the engine runs on. Open the Plugin Studio on your computer (<code>bun run dev</code>) or use the Rudder desktop app.