Skip to content

feat(browser): browser_sign_in, and browser steps reach a multi env's computers (FD-4944) - #556

Merged
earakely-scale merged 5 commits into
mainfrom
edgararakelyan/fd-4944-browser-sign-in
Nov 9, 2026
Merged

earakely-scale merged 5 commits into
mainfrom
edgararakelyan/fd-4944-browser-sign-in

Conversation

@earakely-scale

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

Copy link
Copy Markdown
Collaborator

Summary

M5.15 (FD-4944): a task signs the browser in to a site as a chosen user. Design: Signing the browser in (M5.15). Its four decisions were proposed on Nov 8 while you were away, and this PR is built on their recommendations. They're settled once you review them.

browser_sign_in {site, user, browser?}. It signs an env's website browser in to site, a website env deployed in the run, on its own or in a multi env, named by its env id as site_routing does.

  1. The site's website/v1 session {user} gives the cookies and local storage, through the record that serves it.
  2. Each cookie is set for every name the site is reached by. session leaves the domain unset, so an exact name is placed by its URL and a *. name becomes a domain cookie.
  3. The browser's data/add loads them, which opens its start tabs again while no agent has acted.

A task runs it after the load that seeds the site, and again after reset_env, since a reset now starts the browser afresh and empties the sites (#542). This revises the earlier design, in which the multi env signed in by itself at deploy and after each reset (decision 1).

Browser steps reach a multi env's computers. The gateway lists a computer but not its apps, and the computer isn't in context.deployed_envs. find_browser now also looks through the multi env record's child_envs, and calls a browser in a computer with that computer's own record and control token, as backing_servers has since #542. browser_connect_cdp refuses such a browser for now: its agents reach it through the gateway, whose CDP address it doesn't hand out yet.

Finding the site. The step finds the site by the name it's served as, the <name> of its /svc/<name>/ route, as deployed_sites does, not by its card's name: a WebsiteEnvironment's card is named after its class (Shop), and the test site is served as shop. sites._served_as is public as served_as for this (Greptile round 1). Since #557 (FD-5376) merged, the helper reads the gateway's stated environment_name first, and falls back to the route for older gateways; 1b40fb5 merges main and keeps that body under the public name.

Test plan

  • Unit (tst/unit/task_step/test_browser_sign_in.py):

    • sign-in in a multi env, with the site's card named as it's served and named otherwise (the second fails without the fix): the session is asked through the gateway with the multi env's token, and data/add goes to the computer's browser with the computer's token;
    • cookies are scoped to exact, *. and .localhost names;
    • a site without session, or not deployed, fails before the browser is touched;
    • browser_set_cookies reaches a multi env's computer;
    • browser_connect_cdp refuses one;
    • the step round-trips, preflight works, and a multi env's browsers are listed.
  • Integration (website_browser_test.py): a multi env with the website-browser test desktop (site_routing) and a small WebsiteEnvironment site, tst/data/session_website. The browser has no session for shop.test before the step, and the site says Alex is signed in after it. After reset_env the browser has none again, and after the step again the site says Alex.

  • Unit suites: tst/unit/task_step, test_computer_sites.py, test_env.py, 2,576 passed.

  • VM e2e (c6i.4xlarge, amd64, Nov 9): the integration test above passed. The first runs caught two bugs in the test itself, both fixed in f469be6: MultiEnv.put needs mcp_server_envs, and the site image needs curl for the website health check.

  • VM chaos, one multi env deploy, all in 20 minutes:

    Phase Result
    Sign in as alex, then as bea alex, then bea: the second replaces the first
    Two sign-ins at once (alex, bea) both succeed; the last write (alex) is signed in
    docker restart the site still alex: the deploy's WEBSITE_SESSION_SECRET outlives the process
    Sign in with the site stopped fails at once with ExtensionCallError: 502 Bad Gateway; the browser is untouched
    Site started again, sign in as dana dana
    Chromium killed in the computer, then sign in fails at once and named: data/add failed: no browser is connected over its debugging pipe (the load had applied nothing)
    Teardown clean

    A browser killed mid-run stays down until a reset, which is the browser app's behavior, not this PR's. The 502 error doesn't name the site; the failing step's id does.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no new actionable issues remain.

Summary

Adds browser_sign_in and lets browser steps reach computers inside a multi env.

  • Tasks can sign a browser into a deployed website as a chosen user.
  • Browser steps can find browsers in a multi environment’s computers.

Diagram

sequenceDiagram
    participant Step as browser_sign_in
    participant Site as Website
    participant Browser as Computer browser
    Step->>Site: Request session for user
    Site-->>Step: Cookies and local storage
    Note over Step: Scope cookies to the site's names
    Step->>Browser: data/add with computer's control token
    Browser-->>Step: Loaded
Loading

Reviews (11) · Last reviewed commit: "fix(browser): a website deployed alone i..." · Reviewed by Greptile

… computers (FD-4944)

browser_sign_in {site, user} signs an env's website browser in to a site as a
user: the site's website/v1 session gives the cookies and local storage, each
cookie is set for every name the site is reached by (an exact name by its URL,
a *. name as a domain cookie), and the browser's data/add loads them, which
opens its start tabs again while no agent has acted. The site is a website env
deployed in the run on its own or in a multi env, by its env id. A task runs
the step after the load that seeds the site and again after reset_env.

Every browser step now reaches a browser app inside a multi env's computer,
through the computer's own record and control token kept in the multi env's
record, since the gateway lists a computer but not its apps.
browser_connect_cdp refuses one for now: its agents reach it through the
gateway, whose address it doesn't hand out yet.

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 9, 2026 06:55
earakely-scale and others added 2 commits November 8, 2026 23:04
…as, not its card's name

A website's card name needn't be its environment_name (a card named Notes served as notes), so look the site up
by its /svc/<name>/ route, as deployed_sites does; sites.served_as is public for that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, and its site image keeps curl for the health check

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale

Copy link
Copy Markdown
Collaborator Author

🤖 Automated Claude routine — Env Pod PR Context Review. This is a bot, not Edgar Arakelyan; not a human review.

Context from another open PR rather than from this diff: #447 also adds a browser sign-in task step, under a different name and a different mechanism, and neither PR references the other.

  • This PR: src/agent_env/task_step/task_steps/browser/sign_in.py → BrowserSignInTaskStep, type = "browser_sign_in". It reads the site's website/v1 session {user} and applies the state through the browser's data/add.
  • feat(website): live sites, browser/v1 sign-in and WARC replay (FD-4683) #447: src/agent_env/task_step/task_steps/sign_in_browser.py → SignInBrowserTaskStep, type = "sign_in_browser" (that file's line 293; registered at its registry.py:110). It reads the same website/v1 session and applies it through browser/v1 cookies/delete → cookies/set → local_storage/set.

Both register into the same src/agent_env/task_step/registry.py, and neither name exists on main today (main's task_steps/browser/ has only connect_cdp, cookies, local_storage, tabs), so if both land, a task author gets two near-synonymous step types for one job, plus two ~340-line test files covering it.

They also differ on what happens after a reset, which is worth settling deliberately rather than by merge order: #447 modifies task_steps/reset_env.py so that reset_env signs the browser back in by itself ("reset_env signs the browser in again after a reset, as the last sign-in did", its module docstring), while this PR's design has the task run the step again after reset_env. #447 is stacked on #446, so it reaches main behind that one.


Generated by Claude Code

…4-browser-sign-in

# Conflicts:
#	src/agent_env/env/envs/computer/utils/sites.py
…tores, else those its card declares

deployed_sites routes a website by a composed card's child or a frontend, so a website a plugin deploys alone,
with a card of its own and no frontend, had no names and the sign-in failed before asking for a session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale merged commit 462ca0d into main Nov 9, 2026
55 of 60 checks passed
@earakely-scale
earakely-scale deleted the edgararakelyan/fd-4944-browser-sign-in branch November 9, 2026 19:45
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