Symptom
Many sessions sit in the sidebar. The panel still does a full GET /sessions (and per-session get_session_state on the bridge) on every poll. When the active chat is working that poll is every 2.5s (SESSION_POLL_ACTIVE_MS in useSessionManager.ts). Idle chats should not keep the same request pattern.
This also shows up as bridge jank: the comment in useSessionManager.ts already says mass /transcript fetches starve WebSockets. Transcript sync was restricted to the active session; the list poll + liveness path was not fully tightened.
What already exists
- Fast vs idle poll interval is based on the active session only (
SESSION_POLL_ACTIVE_MS vs SESSION_POLL_IDLE_MS).
/transcript merge is active-session-only.
- WS keepalive:
collectWsKeepOpen in extension/src/shared/wsKeepalive.ts — active + turnRunning + persistent automation sessions.
What to change
Goal: only sessions that need it should trigger expensive work.
Concrete directions (pick one, measure, then the next):
- Cheap
GET /sessions — listing metadata for idle chats should not call get_session_state / liveness for every name. Example: ?live=1 or skip liveness unless active / turn_running / recently used. See list_sessions in devscope_bridge/session_http.py (loops all stored sessions today).
- Do not open WS for idle user chats (already partly true; audit automation + background workers).
- Do not
recoverPending / heal WS in a fan-out across every name on every poll.
- Document the invariant: active chat + in-flight turns (+ intentional automation) may poll/stream; everyone else is list-only until selected.
Done when
Good first slice: add a query flag or skip _liveness_fields for sessions that are not active and not is_turn_running, with a test that a large idle list stays cheap.
Symptom
Many sessions sit in the sidebar. The panel still does a full
GET /sessions(and per-sessionget_session_stateon the bridge) on every poll. When the active chat is working that poll is every 2.5s (SESSION_POLL_ACTIVE_MSinuseSessionManager.ts). Idle chats should not keep the same request pattern.This also shows up as bridge jank: the comment in
useSessionManager.tsalready says mass/transcriptfetches starve WebSockets. Transcript sync was restricted to the active session; the list poll + liveness path was not fully tightened.What already exists
SESSION_POLL_ACTIVE_MSvsSESSION_POLL_IDLE_MS)./transcriptmerge is active-session-only.collectWsKeepOpeninextension/src/shared/wsKeepalive.ts— active +turnRunning+ persistent automation sessions.What to change
Goal: only sessions that need it should trigger expensive work.
Concrete directions (pick one, measure, then the next):
GET /sessions— listing metadata for idle chats should not callget_session_state/ liveness for every name. Example:?live=1or skip liveness unlessactive/turn_running/ recently used. Seelist_sessionsindevscope_bridge/session_http.py(loops all stored sessions today).recoverPending/ heal WS in a fan-out across every name on every poll.Done when
get_session_statecall count).turn_running/ awaiting cards within one poll.Good first slice: add a query flag or skip
_liveness_fieldsfor sessions that are not active and notis_turn_running, with a test that a large idle list stays cheap.