Skip to content

feat(providers): a sandbox provider declares WEBSOCKETS, and a computer with a website browser refuses one without it - #506

Merged
earakely-scale merged 2 commits into
mainfrom
edgararakelyan/fd-4950-websockets-capability
Nov 5, 2026
Merged

earakely-scale merged 2 commits into
mainfrom
edgararakelyan/fd-4950-websockets-capability

Conversation

@earakely-scale

@earakely-scale earakely-scale commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

What and why

Sandbox providers now declare whether their sandboxes' exposed ports carry WebSockets, and a computer with a website browser among its apps refuses a provider that doesn't. A website browser's CDP address is a WebSocket. On a provider whose tunnel doesn't carry one, the deploy succeeded, and then every CDP client failed to connect. This is FD-4950 (M8.3). Its outcome and two decisions are recorded there.

The declaration (decision 2): WEBSOCKETS: ClassVar[bool] = False in SandboxProvider's "what it declares" block, beside PRIVATE_NETWORK.

Where it's on (decision 1), wherever there's evidence, by one rule:

Provider Evidence
local our own WebSocket tests (M8.6, #500)
smol_vm, lume VMs on this machine, their ports reached with no tunnel
modal, modal_vm Modal's tunnels; modal_vm uses the same ones
boxd, sail_vm, tenki, agent37 their READMEs say their tunnels carry WebSocket

It stays off for e2b, tensorlake, vercel, coreweave, daytona and boat until M8.25 tests each live. agent37 isn't in M8.25's list, probably because it was added after the Nov 1 plan.

The checks. A computer env serves a website browser when one of its composed apps has browser = true in its stored declaration. That's chromium today, alone as a browser computer or as an app in a desktop. ComputerEnv.serves_website_browser() reads it, and two places check it:

  • Preflight: ComputerEnv.deploy_refusal, beside the native-arch and network-policy checks, refuses when no link that runs the env natively carries WebSockets, and names them. The network policy is checked against the same links, so a chain where one link carries WebSockets and another enforces the network is refused too. That check runs when a task is saved. At deploy, as for the native-arch and network checks, the per-link check below refuses before anything boots.
  • Deploy: the computer provider's _boot raises on a link without WebSockets, so a chain moves on to the next link, the same way it moves past a link that runs none of the env's builds natively.

Docs: the root AGENTS.md and the providers' AGENTS.md list the new declaration.

Not in this PR:

  • the live per-provider checks (M8.25);
  • multi envs with a browser (M8.13);
  • the playwright-mcp website browser, which agents reach through MCP, never CDP.

How it was tested

  • ruff check: clean.

  • Unit tests:

    • Declarations: the provider capabilities table gains a WEBSOCKETS column, and a provider that declares nothing doesn't carry WebSockets.
    • Preflight: a computer env with chromium among its apps passes preflight on the local provider. With its WEBSOCKETS off, saving the task is refused: "LocalSandboxProvider carries no WebSockets, which its website browser's CDP address needs".
    • Deploy: on a real ChainedSandboxProvider whose first link is the local provider with WEBSOCKETS off, the deploy skips that link and boots on the second.
    • Mixed chain: a chain where one link carries WebSockets and another enforces the network is refused at save (Greptile's case).

    The computer, app, disk, sandbox provider and bundle preflight tests: 1997 passed, 7 skipped. CI runs the full unit tier.

  • Dry run: agent-env run agents --task browser-use-smoke --dry-run on local, e2b, and a chain of e2b then local. The run writes chromium itself, so its deploy_env isn't preflighted in a dry run, and the refusal fires at deploy instead, before anything boots.

  • E2e on agent-environments-admin VMs, amd64 and arm64, at e515b611:

    • Setup: agentenv's real chromium, composed and stored as a browser computer, and a provider registered through a config file ([sandbox.providers.nows] impl = …): the local provider with WEBSOCKETS off.
    • Save: a task deploying it on nows is refused: "computer env '…/chromium': NoWebSocketsProvider carries no WebSockets, which its website browser's CDP address needs".
    • Deploy on nows alone: refused before any container starts. The container count was the same before and after.
    • Deploy on nows,local: the nows attempt is logged as failed for that reason, the deploy boots on local, and a CDP client answers Browser.getVersion (Chrome/156) over the WebSocket.
    • Regression on local: browser_computer_test.py and browser_gateway_test.py 11/11 on amd64, and 8/8 on arm64 without the 3 echo-agent tests, which need qemu there.
    • The harness is a scratch script, not committed.
  • Not tested live: a chain that skips a real remote provider without WebSockets. That needs one that also runs the browser natively, which means credentials. M8.25's live checks are where each remote provider gets tested.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the previous preflight gap is fixed.

Summary

Adds WEBSOCKETS declarations and refuses browser computers on providers without that support.

  • Browser computers use only providers that declare WebSocket support.

Reviews (2) · Last reviewed commit: "fix(computer): a deploy's network is che..." · Reviewed by Greptile

…er with a website browser refuses one without it

A website browser's CDP address is a WebSocket, so on a provider whose tunnel doesn't carry one the deploy succeeded and
every CDP client then failed. Providers now declare WEBSOCKETS: on for local, smol_vm, lume, modal, modal_vm, boxd,
sail_vm, tenki and agent37, where our tests or their tunnels' docs say so, and off for the six M8.25 checks live. A
computer env with a website browser among its apps refuses at preflight when no link that runs it natively carries
WebSockets, naming them, and a chain's deploy skips such a link for the next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale requested a review from a team as a code owner November 5, 2026 18:03
Comment thread src/agent_env/env/envs/computer/env.py Resolved
…lso run it natively and carry its WebSockets

The WebSocket and network checks could each pass on a different link, so a task every link would fail to deploy passed
preflight. The network policy is now checked against the native links that carry WebSockets when a website browser is
among the env's apps, the conditions a deploy needs of the one link it boots on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale merged commit bff6821 into main Nov 5, 2026
35 checks passed
@earakely-scale
earakely-scale deleted the edgararakelyan/fd-4950-websockets-capability branch November 5, 2026 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant