Skip to content

feat: add private Agent Browser takeover - #189

Open
QueryPlanner wants to merge 35 commits into
mainfrom
feat/secure-browser-takeover
Open

QueryPlanner wants to merge 35 commits into
mainfrom
feat/secure-browser-takeover

Conversation

@QueryPlanner

@QueryPlanner QueryPlanner commented Sep 13, 2026

Copy link
Copy Markdown
Owner

What

Add a private, one-time Agent Browser takeover flow for sensitive human login steps in Telegram.

Why

Let the authenticated Telegram user enter passwords, OTPs, or CAPTCHA responses directly in the existing session browser without exposing those values to the model or ADK history.

How

  • Register start_browser_takeover only for the private Telegram root agent.
  • Send a protected, user-bound Telegram link with a single-use fragment token.
  • Redeem the token into an HttpOnly, SameSite cookie and proxy the browser stream same-origin.
  • Keep sandbox routing details server-side and clean up streams on completion, expiry, disconnect, and startup failure.
  • Validate token input and preserve the existing session-sandbox design.
  • Document HTTPS, Tailscale, reverse-proxy, and environment configuration.

Tests

  • uv run ruff format --check
  • uv run ruff check --output-format=github
  • uv run mypy .
  • uv run pytest --cov=src --cov-report=xml --cov-report=term-missing (2,144 passed, 1 skipped, 100% coverage)
  • uv run python -m compileall -q src
  • git diff --check
  • Manual disposable-account Telegram/OpenSandbox smoke test in the configured deployment environment

Related Issues

  • None identified.

@QueryPlanner QueryPlanner left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

I found one blocking correctness issue in the takeover lifecycle. CI is green, but the current tests explicitly encode the problematic behavior: a WebSocket disconnect or upstream connection failure is treated the same as the user clicking Done. That can resume the agent with a false success signal before authentication is complete. I’d fix that before merging.

Comment thread src/blacki/browser_takeover/routes.py Outdated
except Exception:
await websocket.close(code=1011)
finally:
await service.complete(token)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Blocking: this runs for every WebSocket termination, including the user closing the tab, losing network, or connect(...) failing. complete() sets the event that start_browser_takeover() interprets as successful human completion, so the model can resume with status=success even though the user never clicked Done or finished login. The new route tests currently assert this behavior for disconnect/upstream-error paths. Only /complete should mark the lease complete; WebSocket teardown should close the proxy and leave the lease waiting until explicit Done or expiry. Please add a regression test for disconnect/failure not completing the lease.

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