Centralize custom code
Merged
PI
7mo ago+1324+1324+0123456789012345678901234567890123456789-967-967-012345678901234567890123456789
Summary by cubic
Centralizes all handwritten SDK logic under stagehand/_custom and patches the generated client at import time to simplify local server mode and bound session handling. Also ensures Playwright CDP sessions are detached after frame ID extraction to prevent leaks.
-
Refactors
- Moved SEA binary/server and session patches to
stagehand/_custom;_clientnow usesconfigure_client_base_url,prepare_*,close_*, andcopy_local_mode_kwargsand lazily starts/stops the SEA server. - Runtime patches install on import:
sessions.start()returns a boundSession/AsyncSession;Session.extractsupports Pydantic schema validation; generatedresources/sessions.startis type-hinted to return bound sessions. - Exported
SessionandAsyncSessionfromstagehand;_client.sessionsnow exposes the generatedresources/sessions(helper wrappers removed). - Local mode behavior: when
server="local"and no browser is passed, default to a local browser if Browserbase creds are set; if creds are missing, require an explicit local browser. - Consolidated scripts:
scripts/download_binary.py(renamed) andscripts/test_local_mode.py(new); docs updated.
- Moved SEA binary/server and session patches to
-
Bug Fixes
- Always detach Playwright CDP sessions after reading
Page.getFrameTreewhen injectingframe_idfrom apageparam (sync/async) to avoid leaked CDP sessions and flaky tests.
- Always detach Playwright CDP sessions after reading
-
Migration
- Update imports to
stagehand._custom(e.g.,from stagehand._custom import sea_server, sea_binary). - Use
scripts/download_binary.pyandscripts/test_local_mode.py; type-checker excludes updated. - Code using
sessions.start()can use the returnedSession/AsyncSessiondirectly; raw/streaming responses are unchanged.
- Update imports to