Skip to content

fix(v3): honor CAPTCHA awareness options for local attachments - #3114

Merged
miguelg719 merged 7 commits into
v3from
miguelgonzalez/ap-3038-v3-local-captcha
Oct 14, 2026
Merged

miguelg719 merged 7 commits into
v3from
miguelgonzalez/ap-3038-v3-local-captcha

Conversation

@miguelg719

@miguelg719 miguelg719 commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Honor browserbaseSessionCreateParams.browserSettings.solveCaptchas and waitForCaptchaSolves for local attachments. An explicit false for either option disables awareness; absent options retain Browserbase-on/local-off defaults.
  • Resolve awareness from constructor options so it is available before CDP initialization, then forward it through the SDK session-start request and standalone v3 server.
  • Reuse the existing waiting, solved-notice, and computer-use widget-avoidance behavior without changing CDP routing, session ownership, or shutdown behavior. No subclass or customer-specific flag.
  • Update option/schema documentation, add a patch changeset, and cover the option matrix and SDK bootstrap forwarding.

Validation

  • 68 focused compiled tests passed across eight suites: CAPTCHA options, agent CAPTCHA hooks, solver timing, Browserbase accessors, API default model config, API serialization, optional model API keys, and agent prompt variables.
  • ESM and CommonJS builds passed.
  • Package and standalone v3 server typechecks passed.
  • Targeted ESLint, Prettier, and diff whitespace checks passed.
  • No live hosted CAPTCHA session was tested.

Summary by cubic

Fixes CAPTCHA awareness for local attachments in Stagehand v3 so agents no longer interfere with Browserbase solves or stop at already-solved widgets.

Previously the waitForCaptchaSolves and browserSettings.solveCaptchas options only took effect when env: "BROWSERBASE", since awareness was gated on the environment. Now isCaptchaAutoSolveEnabled resolves from constructor options before CDP initialization, with waitForCaptchaSolves ?? solveCaptchas ?? env === "BROWSERBASE" as the default and solveCaptchas: false always disabling awareness. The resolved value is forwarded through the SDK session-start request and the standalone v3 server.

  • Reuses existing waiting, solved-notice, and widget-avoidance behavior; CDP routing, session ownership, and shutdown are unchanged.
  • Adds a patch changeset, updates option/schema documentation, and covers the option matrix plus API forwarding in tests.
  • Targeting v3 only; the Browserbase API dependency update and package publication remain required for the hosted fix.

Rollout

  • Publish the package, update the API's Orca dependency, and deploy the API forwarding change.
  • This does not add a CAPTCHA solver for ordinary local attachments; solve events emitted before listeners attach remain unhandled.

Written for commit 90d5767. Summary will update on new commits.

Review in cubic

@changeset-bot

changeset-bot Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7d60cac

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@browserbasehq/stagehand Patch
@browserbasehq/stagehand-evals Patch
@browserbasehq/stagehand-server-v3 Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 8 files

Architecture diagram
sequenceDiagram
    participant Client as V3 Client Code
    participant V3 as V3 Class
    participant API as StagehandAPIClient
    participant Server as Standalone V3 Server
    participant Store as InMemorySessionStore
    participant Browser as Browserbase Session

    Note over Client,Browser: CAPTCHA Awareness Resolution Flow

    Client->>V3: Create instance(env, waitForCaptchaSolves, solveCaptchas)
    V3->>V3: Resolve isCaptchaAutoSolveEnabled
    Note over V3: waitForCaptchaSolves ?? solveCaptchas ?? (env === "BROWSERBASE")
    Note over V3: Explicit solveCaptchas: false always wins

    Client->>V3: init()
    V3->>V3: Read isCaptchaAutoSolveEnabled (before CDP init)
    V3->>API: init(waitForCaptchaSolves=resolvedValue)
    API-->>V3: sessionId, available

    V3->>Browser: Attach via CDP (env LOCAL or BROWSERBASE)

    alt Local attachment (env: "LOCAL")
        Note over V3,Browser: Same CAPTCHA awareness now applies
        Browser-->>V3: Captcha solve event
        V3->>V3: Wait for solve (if enabled)
        V3-->>Client: Continue action
    else Browserbase attachment (env: "BROWSERBASE")
        Browser-->>V3: Captcha solve event
        V3->>V3: Wait for solve (if enabled)
    end

    Note over V3,Store: Server-side forwarding (standalone)

    V3->>Server: Session start request (includes waitForCaptchaSolves)
    Server->>Store: Persist session params
    Store-->>Server: Stored session
    Server-->>V3: Session established
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 2 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 5 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 8 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

@AzamAbdul AzamAbdul left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

not sure how much this is an actual issue, but the code looks fine to me. just a question about if this is actually a problem:

from claude

found one real bug. On plain local Chrome, setting solveCaptchas: true now turns captcha waiting on. The agent is then told not to solve captchas, but there's no solver locally, so it gets stuck. The bug is in two places: the core library check (v3.ts:203) and the server, which now passes Browserbase settings to local sessions (InMemorySessionStore.ts:251).

miguelg719 added a commit that referenced this pull request Oct 13, 2026
…#3150)

## Why

`act` fails on OpenAI models routed through the AI SDK client (for
example `openai/gpt-4.1-nano`) with:

```
Invalid schema for response_format 'response': In context=('properties', 'action', 'anyOf', '0'),
'additionalProperties' is required to be supplied and to be false.
```

`AISdkClient` sends OpenAI requests with `strictJsonSchema: true`, and
OpenAI strict mode requires `additionalProperties: false` on every
object. `generateObject` converts the Zod schema with the AI SDK's own
converter, which leaves that field off the object inside the nullable
`action`'s `anyOf`. The direct provider clients use `toJsonSchema` and
already emit it.

This is what fails `server/v3/integration/v3/act` and
`server/v3/integration/v3/agentExecute` (the variables tests return an
empty field because the agent's `act` tool call 400s). See #3114.

## What changed

- Mark the action object with `.meta({ additionalProperties: false })`
when running on Zod 4. `zod` is a peer dependency (`^3.25 || ^4`) and
Zod 3 has no `.meta()`; its converter already emits the field, so the
call is skipped there. This changes only the generated JSON schema.
Parsing still strips unknown keys, so clients that validate locally
(Google, AI SDK providers without strict mode, custom clients) keep
accepting responses with extra fields. `.strict()` was considered and
rejected because it would make those responses fail validation.
- Unit tests check both converters, that parsing still strips unknown
keys, and that `act()` builds its schema under a Zod 3 peer.

## Test plan

- [x] New `act-response-schema` unit tests pass; the AI SDK converter
test fails without the fix.
- [x] `act-response-schema-zod3` (mocks `zod` with `zod/v3`) passes;
without the guard it fails with `actionSchema.meta is not a function`.
- [x] `inference-temperature` unit tests pass.
- [x] Live `generateObject` call with `@ai-sdk/openai` `gpt-4.1-nano`
and `strictJsonSchema: true`: without the fix it returns the 400 above;
with the fix it returns a valid action.
- [x] ESLint and Prettier clean.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes `act` calls failing on OpenAI models routed through the AI SDK
client. OpenAI strict mode requires `additionalProperties: false` on
every object, and the AI SDK schema converter omitted it inside the
nullable `action`'s `anyOf`, producing an `invalid_json_schema` 400.

- Sets `additionalProperties: false` via `.meta()` so only the generated
JSON schema changes; parsing still strips unknown keys, so clients that
validate locally keep accepting responses with extra fields.
- Calls `.meta()` only under Zod 4 since `zod` is a peer dependency
(^3.25 || ^4) and its Zod 3 import lacks the method; the Zod 3 converter
already emits the field.
- Adds unit tests for the AI SDK and `toJsonSchema` converters,
including the Zod 3 path.

<sup>Written for commit 8c3658a.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/browserbase/stagehand/pull/3150?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="View guided diff"
src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a>
<a
href="https://www.cubic.dev/action/auto-fix/pr/browserbase/stagehand/3150?returnTo=https%3A%2F%2Fgithub.com%2Fbrowserbase%2Fstagehand%2Fpull%2F3150&source=description"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img
alt="Turn on auto-fix"
src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->
@miguelg719

Copy link
Copy Markdown
Collaborator Author

@AzamAbdul not an issue this fix is going out for the hosted version mainly

@miguelg719
miguelg719 merged commit f6b3d85 into v3 Oct 14, 2026
249 checks passed
@miguelg719
miguelg719 deleted the miguelgonzalez/ap-3038-v3-local-captcha branch October 14, 2026 00:02
@github-actions github-actions Bot mentioned this pull request Oct 14, 2026
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.

2 participants