feat: add browser.disconnect() to the TypeScript and Python SDKs
Merged
MI
1h ago+1389+1389+0123456789012345678901234567890123456789-44-44-01234567890123456789
why
there's no public way to detach from a browser without closing it. browser.close() quits a browser attached with localBrowser.connect(), & stagehand.close() keeps the connection open, so callers attached to a long-lived browser (e.g. one holding signed-in profiles) can't cleanly let go
what changed
- added
browser.disconnect()(ts) /await browser.disconnect()(python): closes an attached stagehand instance (incl. the extension's loopback cdp connection), then stagehand's connection. a laterconnect()+Stagehand.create()on the same browser works; before, it failed with "A Stagehand instance is already initialized". stagehand never sendsBrowser.close, never closes a launched process or profile, & never releases a browserbase session - on browserbase,
keepAlivedecides whether the session survives: withkeepAlive: false(the default) browserbase ends the session when any cdp connection closes, includingdisconnect(). onlykeepAlive: truesessions keep running - the handle is finished after
disconnect():close()then throws ("connect() again to close it"); reconnect withlocalBrowser.connect({ cdpUrl })/browserbase.connect({ sessionId })& close that handle. repeateddisconnect()/close()calls are idempotent - if the connection drops without
disconnect(),close()still releases a browserbase session over its api & does nothing for local browsers close()on a launched local browser sendsBrowser.closebefore the launcher terminates it (temp profile removed unlesspreserveUserDataDir)- handles expose
cdpUrl(cdp_urlin python) for local browsers, andconnected:closedonly meansclose()/disconnect()was called, so callers stillclose()a handle whose connection dropped disconnect()waits at most 10s for the attached stagehand instance to close, then lets go anyway- docs: a disconnect section with a keepAlive warning & a per-case "to close it later" table, a disconnect column in the behavior-by-environment table split by keepAlive, & a corrected note about
close()on connected browsers - go is intentionally not included
test plan
- unit tests in both sdks across local & browserbase, launched & connected, keepAlive on & off: idempotency, close after disconnect (throws, releases nothing), close after a lost connection (browserbase released, local untouched),
Browser.closebefore termination,cdpUrl, & re-attach - real chrome tests in both sdks: attach to a separately launched chrome, disconnect, & check it still serves its pages (they fail if
close()is used instead); & connect → create → disconnect (nostagehand.close()) → connect → create → navigate (fails on the previous head) pnpm check,pnpm test:unit, sdk-ts unit tests, python tests, ruff, ty, docs tests, sdk parity rules