Skip to content

fix(panel): stop live-dot flapping (coalesce frames) + show viewport size (v0.6.3)#17

Merged
mabry1985 merged 1 commit into
mainfrom
fix/panel-stability-and-dims
Jul 1, 2026
Merged

fix(panel): stop live-dot flapping (coalesce frames) + show viewport size (v0.6.3)#17
mabry1985 merged 1 commit into
mainfrom
fix/panel-stability-and-dims

Conversation

@mabry1985

Copy link
Copy Markdown
Contributor

Field report: "not navigating live, the live dot goes offline, buggy as hell," plus a narrow viewport that doesn't fill the dock.

Stability — the flapping

  • Coalescing frame delivery. on_frame now stashes only the newest frame and a sender task drains it. Under load it drops stale frames instead of letting ws.send_bytes block — the backpressure buildup was stalling the socket (frozen → the fleet proxy idle-closes it → the "live" dot flaps offline → reconnect loop). This is the standard "render latest, drop stale" pattern for live video.
  • Race input against CDP death. If Chrome's page target goes away (tab closed/replaced), the route breaks and lets the client reconnect to the live page (~1.2s) instead of freezing until an idle-close. Reconnect backoff 2.5s → 1.2s.

Diagnostics for the size issue

The default viewport is 1280×577 (wide), so a narrow strip means the panel-fit resize is landing small. To stop guessing:

  • The "live" pill now shows the real viewport dimslive · <w>×<h>. So we can see what the browser is rendering at.
  • Resize self-corrects — re-sent ~500ms after connect, in case the dock hadn't finished laying out when the socket opened.

Validation

47 host-free tests pass; nav re-arm + resize re-validated live against the real browser; ruff clean.

Next

Once this is in, the live · W×H readout tells us whether the fill is the real problem or the site's own layout — I'll target the fix from there.

🤖 Generated with Claude Code

…ast) + show viewport size (v0.6.3)

Field report: "not navigating live, live dot goes offline, buggy as hell" + a narrow
viewport that doesn't fill the dock.

Stability (the flapping):
- Coalescing frame delivery: on_frame stashes only the NEWEST frame and a sender task
  drains it. Under load this drops stale frames instead of letting ws.send_bytes block —
  the backpressure buildup was stalling the socket (frozen → proxy idle-closes → the
  "live" dot flaps offline → reconnect loop).
- Race operator input against the CDP reader task: if Chrome's page target dies (tab
  gone/replaced), break and let the client reconnect to the live page (~1.2s) instead of
  freezing until an idle-close. Reconnect backoff 2.5s → 1.2s.

Diagnostics for the size issue:
- The "live" pill now shows the real viewport dims (live · WxH), so we can see what size
  the browser is actually rendering at (the default is 1280x577; a narrow strip means the
  panel-fit resize is landing small).
- Resize self-corrects: re-sent ~500ms after connect in case the dock hadn't laid out yet.

47 host-free tests pass; nav re-arm + resize re-validated live; ruff clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@protoquinn

protoquinn Bot commented Jul 1, 2026

Copy link
Copy Markdown

👀 Quinn is reviewing — verdict (PASS / WARN / FAIL) + findings to follow.

@mabry1985 mabry1985 merged commit 24ca504 into main Jul 1, 2026
1 check passed

@protoquinn protoquinn Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA Audit — PR #17 | fix(panel): stop live-dot flapping (coalesce frames) + show viewport size (v0.6.3)

VERDICT: WARN (non-blocking — CI test still queued; re-evaluate once terminal)


CI Status

  • test: queued

Diff Review

  • Frame coalescing in browser_panel.py:97-123on_frame stashes newest frame into a shared latest dict, signals an asyncio.Event, and a sender() coroutine drains it. Stale frames are dropped when sender is blocked on ws.send_bytes — correct "render latest, drop stale" pattern. No data races (single event loop).
  • CDP death race in browser_panel.py:133-139asyncio.wait races ws.receive_json() against cdp.reader_task; breaks cleanly if the CDP socket dies first. recv.cancel() + finally cleanup of send_task is proper.
  • browser_stream.py:241-246 — new reader_task property exposes self._reader. Safe, no side effects.
  • JS: live() function replaces static "live" label with live · W×H viewport dims; sendResize() re-fired 500ms after connect; reconnect backoff 2.5s → 1.2s. All clean.

Observations

  • LOW: clawpatch structural review unavailable (HTTP 500 on checkout/mapping). Diff reviewed manually — no blocking issues found in the changed paths.
  • LOW: cdp.reader_task depends on _reader being set before __aenter__ returns — not in the diff but consistent with the class's async-context-manager pattern. Low risk.

Summary: The coalescing pipeline, CDP death race, and viewport diagnostics are all well-structured. No bugs spotted in the diff. 47 host-free tests pass per PR description. Hold for CI terminal-green before clearing for merge.

— Quinn, QA Engineer

@protoquinn

protoquinn Bot commented Jul 1, 2026

Copy link
Copy Markdown

Submitted COMMENT review on protoLabsAI/agent-browser-plugin#17.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant