Skip to content

v2.5.0 — Real Dashboard Backend Adapters (#444)

Choose a tag to compare

@shanewas shanewas released this 07 Jun 02:21
· 23 commits to master since this release
Immutable release. Only release title and notes can be modified.
784edd7

v2.5.0 — Real Dashboard Backend Adapters (#444)

Closes #444. Replaces the three thin dashboard backend aliases with genuinely distinct adapter implementations (M0–M4), and fixes the v2.4.1 status subcommand crash on a fresh install (the subparser was missing --headless/--session).

What ships

  • BackendAdapter Protocol + Capability enum (production/adapters/base.py:84): runtime-checkable protocol surface; new AdapterLaunchError / AdapterCapabilityError exception types; register_adapter enforces non-empty string names. M0.
  • CDPBridgeAdapter (production/adapters/cdp_bridge.py): Playwright connect_over_cdp over WebSocket for adopted-context / WSL-host workflows. M1.
  • PlaywrightMCPAdapter (production/adapters/playwright_mcp.py): stdio subprocess + MCP JSON-RPC. Env allowlist (PATH, HOME), 16 MB frame cap, stderr drain. M2.
  • AgenticStealthMCPAdapter (production/adapters/agentic_stealth_mcp.py): stdio subprocess + MCP JSON-RPC round-tripping the bundled MCP server. Same env/frame/stderr guarantees. M3.
  • Dashboard backend wiring (M4): BrowserRuntimeManager resolves through the adapter registry, records an audit event on backend switch, surfaces negotiated capabilities in status, rejects unsupported actions with a backend-specific error. production/dashboard_adapter_bridge.py is now a thin shim.

Pre-release review fixes (#444 M0 review)

  • S1 capability gating: M2/M3 actions now call self.supports() and raise AdapterCapabilityError if the capability isn't declared. Enforces the base.py:84 contract.
  • S2 stderr drain: M2/M3 stderr=PIPE is drained by a background task started right after spawn and cancelled in close(). A noisy child no longer fills the ~64 KB kernel pipe buffer and hangs the handshake.
  • F1 stale state on retry: after MCP handshake failure, terminate_subprocess() is called and self._proc / self._client are cleared.
  • F2 frame cap: _jsonrpc_stdio.readline() enforces MAX_FRAME_BYTES = 16 MB and raises ConnectionError on overflow. A misbehaving server emitting a multi-GB line no longer OOMs the client.
  • F3 env allowlist: both stdio adapters pass an explicit env={PATH, HOME} instead of inheriting the operator's full environment (OPENAI_API_KEY, AWS_*, DATABASE_URL, ...).
  • A3 dead tautology: cdp_bridge.screenshot() defensive branch removed; M0 contract is the only contract that matters.
  • M0 code-quality review (17abc50): exception types narrowed, isinstance coverage tightened, defensive tautology branches removed, transport teardown symmetric with launch.

Packaging & docs

  • MANIFEST.in ships assets/*.{gif,png,jpg,svg} (demo GIF), docs/, CODE_OF_CONDUCT.md, CONTRIBUTING.md, SECURITY.md.
  • README: "What is this / When to use / When NOT to use" block, honest comparison table (region client-hello profiles, not full uTLS), install-from-source section, full doc index. Dropped unverified test-count badge and Buy Me A Coffee. 177 → 238 lines.
  • New docs/README.md operator/reference/planning index. Examples rewritten for honesty and reproducibility (01_cloudflare_bypass.py, 02_linkedin_search.py, 03_amazon_product.py).

Tests

  • tests/test_backend_adapter_contract.py — M0 contract (Protocol surface, Capability enum, register_adapter enforcement).
  • tests/test_adapter_cdp_bridge.py, tests/test_adapter_playwright_mcp.py, tests/test_adapter_agentic_stealth_mcp.py — per-adapter launch/capability/stderr-drain/env-allowlist/close tests.
  • tests/test_dashboard_protocol_bridge.py — M4 audit event + capability surface + unsupported-action rejection.
  • 1025 collected, 1023 passed, 2 e2e skipped, 0 failed.
  • ruff check + ruff format --check clean across 159 Python files.
  • M+2.5 wheel smoke test on a fresh venv: every CLI subcommand --help works, real status invocation completes with the v2.4.0 Namespace.headless regression confirmed fixed.

Install

pip install --upgrade agentic-stealth-browser==2.5.0

Known non-blocking diagnostics

On a real status run, one HEALTH ERROR: 'str' object has no attribute 'get' line may be logged. Caught and surfaced; status report completes successfully with exit 0. Tracked as a follow-up.

Closes #444.