Skip to content

Conversation

@monadoid
Copy link
Contributor

@monadoid monadoid commented Jan 10, 2026

why

Better DX if frameId doesn't need to be passed in.

what changed

  • Made frameId optional - passes empty string to server internally, and server just uses the default frameId instead of an empty string.
  • Also updated readme + examples to reflect this + added in link to local_example.py in readme as well while I was at it.

test plan


Summary by cubic

Make frameId optional on session actions. If not provided, the client sends an empty string and the server uses the default main frame.

  • New Features
    • frame_id is now optional for navigate, act, observe, extract, and execute (sync and async).
    • Added a helper to inject frame_id="" when missing; server behavior remains the same.
    • Updated README and examples to omit frame_id; tests assert frameId "" is sent when omitted.
    • Added a Playwright bring-your-own-browser example and README guidance for local mode.

Written for commit fc15135. Summary will update on new commits.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 6 files

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="examples/byob_example.py">

<violation number="1" location="examples/byob_example.py:37">
P1: This example doesn't achieve the stated BYOB (Bring Your Own Browser) goal. The `AsyncStagehand` client uses the default `server="remote"` mode, creating a browser session on Browserbase that is completely independent from the local Playwright browser. These two browsers never share the same page - they're just navigating to the same URLs independently.

To actually demonstrate BYOB, consider using `server="local"` mode, or clarify the example's purpose to show how to coordinate between two separate browser sessions.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

browserbase_project_id=os.environ.get("BROWSERBASE_PROJECT_ID"),
model_api_key=os.environ.get("MODEL_API_KEY"),
) as client, async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=True)
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 11, 2026

Choose a reason for hiding this comment

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

P1: This example doesn't achieve the stated BYOB (Bring Your Own Browser) goal. The AsyncStagehand client uses the default server="remote" mode, creating a browser session on Browserbase that is completely independent from the local Playwright browser. These two browsers never share the same page - they're just navigating to the same URLs independently.

To actually demonstrate BYOB, consider using server="local" mode, or clarify the example's purpose to show how to coordinate between two separate browser sessions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/byob_example.py, line 37:

<comment>This example doesn't achieve the stated BYOB (Bring Your Own Browser) goal. The `AsyncStagehand` client uses the default `server="remote"` mode, creating a browser session on Browserbase that is completely independent from the local Playwright browser. These two browsers never share the same page - they're just navigating to the same URLs independently.

To actually demonstrate BYOB, consider using `server="local"` mode, or clarify the example's purpose to show how to coordinate between two separate browser sessions.</comment>

<file context>
@@ -0,0 +1,74 @@
+        browserbase_project_id=os.environ.get("BROWSERBASE_PROJECT_ID"),
+        model_api_key=os.environ.get("MODEL_API_KEY"),
+    ) as client, async_playwright() as playwright:
+        browser = await playwright.chromium.launch(headless=True)
+        page = await browser.new_page()
+        session = await client.sessions.create(model_name="openai/gpt-5-nano")
</file context>
Fix with Cubic

@monadoid monadoid merged commit c9fefcc into stainless Jan 11, 2026
7 of 8 checks passed
miguelg719 added a commit that referenced this pull request Jan 13, 2026
* Initial commit

* initial commit

* codegen metadata

* codegen metadata

* codegen metadata

* codegen metadata

* codegen metadata

* codegen metadata

* codegen metadata

* codegen metadata

* chore(internal): add missing files argument to base client

* codegen metadata

* feat(api): tweak branding and fix some config fields

* release: 0.1.0 (#250)

* feat(api): manual updates

* feat(api): manual updates

* codegen metadata

* codegen metadata

* feat(api): manual updates

* codegen metadata

* feat(api): manual updates

* feat(api): manual updates

* codegen metadata

* feat(api): manual updates

* codegen metadata

* feat(api): manual updates

* feat(api): manual updates

* feat(api): manual updates

* codegen metadata

* feat(api): manual updates

* chore: speedup initial import

* refactor(internal): switch from rye to uv

* feat(api): manual updates

* feat(api): manual updates

* feat(api): manual updates

* feat(api): manual updates

* feat(api): manual updates

* feat(api): manual updates

* codegen metadata

* feat(api): manual updates

* feat(api): manual updates

* fix: use async_to_httpx_files in patch method

* chore(internal): add `--fix` argument to lint script

* feat(api): manual updates

* docs: add more examples

* feat: [STG-1053] [server] Use fastify-zod-openapi + zod v4 for openapi generation

* chore: update SDK settings

* chore: update SDK settings

* release: 0.1.0

---------

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>

* release: 0.2.0 (#258)

* feat(api): manual updates

* codegen metadata

* docs: prominently feature MCP server setup in root SDK readmes

* feat: Added optional param to force empty object

* release: 0.2.0

* Added x-language and minimal agent example

* lint fix

* Added full example + updated readme

* Added local binary logic

* Added empty body logic for /end endpoint

* lint fix

* Added bundling logic for wheels

* lint fix

---------

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
Co-authored-by: monadoid <[email protected]>

* release: 0.2.1 (#259)

* fix: specify pnpm version 9 in publish workflow

* release: 0.2.1

---------

Co-authored-by: monadoid <[email protected]>
Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>

* release: 0.2.2 (#260)

* fix: specify pnpm version 9 in publish workflow

* fix: correct binary names and update macOS runner in publish workflow

* release: 0.2.2

---------

Co-authored-by: monadoid <[email protected]>
Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>

* release: 0.2.3 (#261)

* fix: use macos-15-intel runner for darwin-x64 builds

* release: 0.2.3

---------

Co-authored-by: monadoid <[email protected]>
Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>

* release: 0.2.4 (#262)

* codegen metadata

* Added x_sdk_version headers + resolved api path

* docs: update README with SDK version headers

* release: 0.2.4

---------

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
Co-authored-by: monadoid <[email protected]>

* Addressing (some) stainless notion doc comments (#264)

* Added session create helper

* Using existing types

* Showing only async python examples

* docs show using uv

* Added local example

* lint fix

* Made frameId optional (#266)

* Made frameId optional

* Added link to local_example in readme.

* Minimal working byob example

* Working bring-your-own-browser-driver example interleaving playwright with stagehand.

* Added logging example (#267)

* Add back in x-sent-at so that start_time and end_time work again (#268)

* Updated readme to mention installing chrome / providing CHROME_PATH (#269)

* release: 0.3.0 (#265)

* feat: Removed requiring x-language and x-sdk-version from openapi spec

* feat: Using provider/model syntax in modelName examples within openapi spec

* release: 0.3.0

---------

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>

* Fix download-binary script to pull latest version of stagehand-server

* Using proper x-sent-at timestamp

* make AsyncSession and Session subclass SessionStartResponse for compat with autogen sdk docs (#271)

* remove x-language and x-sdk-version (#272)

* remove x-language and x-sdk-version

* linting

* browserbase headers not required when server=local and browser=local

* release: 0.3.1 (#270)

* codegen metadata

* release: 0.3.1

---------

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>

* Renamed local_binary_path to _local_stagehand_binary_path, making it internal and clarifying the name

* MODEL_API_KEY is the public facing env, but either MODEL_API_KEY or OPENAI_API_KEY can be used - one is required to be set.

* Removed frame_id empty string passing

* allow passing chrome path as init param not only env var

* Standardize README with Stagehand branding (#275)

- Replace README header with standardized Stagehand branding
- Update docs URL to /v3/sdk/python
- Add 'What is Stagehand?' and 'Why Stagehand?' sections

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Sonnet 4.5 <[email protected]>

* Fix media URLs to use absolute GitHub paths (#276)

* Standardize README with Stagehand branding

- Replace README header with standardized Stagehand branding
- Update docs URL to /v3/sdk/python
- Add 'What is Stagehand?' and 'Why Stagehand?' sections

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>

* Fix media URLs to use absolute GitHub paths

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>

---------

Co-authored-by: Claude Sonnet 4.5 <[email protected]>

* fix install command

* Added a minimal playwright Page helper (#274)

* Update README.md (#278)

* release doctor main

---------

Co-authored-by: stainless-sdks[bot] <167585319+stainless-sdks[bot]@users.noreply.github.com>
Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
Co-authored-by: monadoid <[email protected]>
Co-authored-by: Sam F <[email protected]>
Co-authored-by: Nick Sweeting <[email protected]>
Co-authored-by: Claude Sonnet 4.5 <[email protected]>
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.

3 participants