Repository navigation
Description
Summary
Relay-mesh (Buzz shared compute) agents silently stop replying if the mesh runtime drops at any point after app launch. No error surfaces to the user and nothing re-arms the runtime until an agent is manually (re)started.
Repro
- Launch desktop with a relay-mesh agent; mesh runtime comes up, ingress on
127.0.0.1:9337, bot replies fine. - Leave the app running for an extended period (overnight), or otherwise have the embedded mesh runtime exit/wedge.
- Send the bot a message → no reply, no error.
- Manually start/create an agent →
ensure_relay_mesh_for_recordruns again, re-arms9337, replies resume.
Observed live: 9337/3131 NOT listening while goose acp agent subprocesses were still running and healthy; curl 127.0.0.1:9337/v1/models → connection refused. A remote peer (M4) was serving the model the whole time, so compute availability was never the issue.
Root cause
ensure_relay_mesh_for_record (which brings up the local mesh client node / OpenAI ingress) is only invoked:
- at launch —
managed_agents/restore.rs(restore_managed_agents_on_launch) - on agent create/start —
commands/agents.rs(start_local_agent_with_preflight)
There is no periodic re-arm and no liveness check tying the mesh runtime to agent message dispatch. If state.mesh_llm_runtime becomes None (runtime exited, or a bad restart left a zombie — cf. "timed out after 5s waiting for embedded mesh runtime thread to exit"), relay-mesh agents keep running but point at a dead ingress. The failure is invisible.
Impact
Any long-lived desktop session using shared-compute agents will eventually see bots go quiet with no indication why. This is the dominant "shared compute is broken" user-facing symptom even though discovery, transport, and remote serving are all healthy.
Suggested fix (options)
- On-demand re-arm: before dispatching a message to a relay-mesh agent (or in the agent reconcile loop), if
mesh_llm_runtime.is_none()or the ingress is unreachable, callensure_relay_mesh_for_record/ensure_client_node_for_modelto bring it back. - Liveness + surfaced error: health-check the runtime periodically; if it's down and can't be restored (e.g. no live serving member), surface a visible "shared compute offline" state on the agent instead of silent non-reply.
- Zombie guard: the
mesh runtime thread to exit5s timeout can leave a half-dead runtime — ensure a failed restart doesn't leavemesh_llm_runtimein a state that blocks re-arm.
Fix (1) alone resolves the reported symptom; (2) makes it debuggable; (3) prevents the wedge that motivated it.
Not this
- Not a transport/discovery bug (those were fixed in fix(desktop): keep mesh allowlist on transient roster query failure #2024, present in main).
- Not remote-serving availability (peer was serving throughout).
Activity
Orland00 commentedon Jul 21, 2026
I'd like to contribute the fix for this and want maintainer input on the design before writing code, since it changes a desktop daemon's runtime behavior.
Root cause, verified on current
main:ensure_relay_mesh_for_record(desktop/src-tauri/src/commands/mesh_llm.rs) trustsmesh_llm_runtime.is_some()— if the slot holds a wedged runtime whose127.0.0.1:9337ingress is dead, it never evicts/rebuilds; it just falls intowait_for_mesh_inferenceand times out. And its only two callers are launch (restore_managed_agents_on_launch) and agent create/start — nothing on the dispatch path, no periodic check. So a runtime that dies after launch stays dead until a manual agent (re)start, exactly as reported. Meanwhile the machine keeps serving/reserving compute for nobody.Proposed fix — a mesh ingress liveness watchdog, following the existing coordinator pattern:
start_coordinator(mesh_llm/coordinator.rs) already runs two periodic loops (status_publisher ~45s, roster_watcher ~60s). Add a third:mesh_llm_runtime.is_some(), probe the ingress (cheapGET /v1/modelson 9337, orwait_for_mesh_inferencewith a short deadline).take()+stop(), same patternreconcile_rosteralready uses, including its anti-flapping hysteresis) and re-runensure_relay_mesh_for_recordfor each running relay-mesh agent (load_managed_agentsfiltered byrelay_mesh_model_id).persist_restore_errorpath instead of failing silently.Complementary one-line hardening: inside
ensure_relay_mesh_for_recorditself, treat "runtime present but probe fails" as evict-and-rebuild rather than wait-and-error — that fixes the zombie case even on the explicit-start path, independent of the watchdog.Questions before I write it:
start_coordinator, or would you rather fold the probe intoroster_watcher?All behind
#[cfg(feature = "mesh-llm")], eviction/hysteresis logic extracted into pure testable functions, manual repro (kill the runtime process, observe recovery) included in the PR.— Orlando (Olive One)
Bartok9 commentedon Jul 21, 2026
Took a focused pass at Option 1 + the zombie guard.
Root cause confirmed as described:
ensure_relay_mesh_for_recordtakes the "already running" fast path whenevermesh_llm_runtime.is_some(), thenwait_for_mesh_inferencejust times out against the dead:9337ingress — so the agent stays silent.Fix: added a fast liveness probe (
mesh_ingress_is_live— single 3sGET /v1/models, the exact call this issue used to confirm the ingress was down). When a runtime handle exists but the ingress is unreachable, drop the stale runtime (best-effort stop — never block re-arm on a wedged runtime, per your zombie-guard note) and fall through to the normal re-arm/bootstrap path. Healthy fast path (live ingress) is unchanged.This resolves the reported symptom on the next dispatch instead of requiring a manual restart. I scoped it to the on-demand re-arm; the periodic liveness/health-surfacing (Option 2) can layer on top separately. PR incoming.
fix(desktop): re-arm relay-mesh runtime when ingress is dead
fix(desktop): re-arm relay-mesh runtime when ingress is dead
fix(desktop): post-launch mesh ingress watchdog re-arm (block#2062)
fix(desktop): re-arm relay-mesh runtime when ingress is dead
fix(desktop): post-launch mesh ingress watchdog re-arm (block#2062)
micspiral commentedon Jul 24, 2026
could this also be related? #2448 ? thanks
fix(desktop): re-arm relay-mesh runtime when ingress is dead
fix(desktop): post-launch mesh ingress watchdog re-arm (block#2062)
fix(desktop): re-arm relay-mesh runtime when ingress is dead
fix(desktop): post-launch mesh ingress watchdog re-arm (block#2062)
fix(desktop): re-arm relay-mesh runtime when ingress is dead
fix(desktop): post-launch mesh ingress watchdog re-arm (block#2062)
fix(desktop): re-arm relay-mesh runtime when ingress is dead
fix(desktop): post-launch mesh ingress watchdog re-arm (block#2062)
fix(desktop): supervise and re-arm relay-mesh runtime (#2823)
fix(desktop): supervise and re-arm relay-mesh runtime (block#2823)
fix(desktop): supervise and re-arm relay-mesh runtime (block#2823)