Skip to content

[FEATURE]: web: connection health surface — stream status, reconnect progress, client/server version mismatch #51860

Description

@afonsoft

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

A visible connection-health surface in the web UI: stream status, reconnect progress, and client/server version mismatch.

Today, when the event stream is degraded, the UI gives no signal: the stream either works or the app silently goes stale (#39030 family). The client implementation that was merged in #47571 already tracked a connected | connecting | reconnecting status internally — it was just never surfaced, and the code has since been lost in the v2 refactor. The server already sends server.heartbeat every 10s, so the data needed to drive this UI exists on the wire today.

Proposal

A small, persistent status affordance (e.g. header or sidebar footer) showing:

  • Stream state: connected / reconnecting (attempt n, retrying in Xs) / offline, driven by heartbeat age — e.g. degraded if no event (heartbeat counts) within ~3× the 10s heartbeat interval, and a lastEventAt timestamp.
  • Reconnect progress: attempt count, next retry delay, last disconnect reason.
  • Version health: the app knows the server version at bootstrap; if the embedded/proxied UI asset version differs from the server's (or the server version changes under an open tab — deploy mid-session), show "client outdated — reload" with a safe reload that preserves the draft prompt.
  • Queue feedback: pending/queued prompts while offline, instead of silent loss or apparent hanging.
// state sketch driven by the existing stream
type StreamHealth = {
  state: "connected" | "reconnecting" | "offline"
  lastEventAt: number        // updated on ANY event, incl. server.heartbeat
  attempt: number
  nextRetryAt?: number
  serverVersion?: string     // from server.connected or a /health endpoint
  clientVersion: string      // build-time constant
}

Acceptance ideas

Benefits

Users currently cannot distinguish "session is thinking" from "connection is dead" — which is why stale-UI bug reports keep recurring. An honest status surface turns a whole class of silent failures into observable, self-healing ones.

Related work

Ref State What it reports / fixes
PR #47571 merged (lost) Already tracked connected | connecting | reconnecting internally — the status model this UI would surface.
#21716 closed SSE stale after laptop sleep/wake with no detection or recovery — the symptom this surface makes visible.
#36582 open issue TUI: make API failures explicit and actionable — same principle, TUI side.
#51291 open issue Provider stream can disappear while a tool call stays "running" forever — server-side analogue of invisible liveness.
#48622 open issue Background auto-update — pairs with the version-mismatch affordance.
#41280 open issue Concrete instance of bundled UI version mismatch this surface would catch.
#47563 open issue Heartbeat floods opencode.log at INFO (95GB/34d reported) — if health UI consumes heartbeats, consider demoting their log level too.
#51857 / #51858 open issues Companion fixes: stall watchdog (live-update staleness) and cache directives (deploy staleness). This surface is what lets users see both working.

Triage note for maintainers

Recurring stale-UI reports (#39030, #47258, #45860, #21716, #46733) share one property: the failure is invisible. Even after the watchdog lands (#51857), users need to distinguish "thinking" from "disconnected". The data already exists on the wire (server.connected, 10s server.heartbeat) — this is a client-only feature with no server contract change, so it is cheap to ship alongside the watchdog work.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions