Skip to content

Add screenshot option to Extract - #2149

Merged
miguelg719 merged 8 commits into
mainfrom
miguelgonzalez/stg-2065-add-screenshottruefalse-option-to-extract
May 20, 2026
Merged

Add screenshot option to Extract#2149
miguelg719 merged 8 commits into
mainfrom
miguelgonzalez/stg-2065-add-screenshottruefalse-option-to-extract

Conversation

@miguelg719

@miguelg719 miguelg719 commented May 20, 2026

Copy link
Copy Markdown
Collaborator

why

Some pages do not properly encapsulate the necessary information required to extract the content requested by the user, and can benefit from a hybrid approach with vision.

what changed

  • New extract({ options: { screenshot: true } }) flag. Captures the current viewport as PNG and sends it as an image_url part alongside the a11y tree text in the extraction LLM call.
  • Default is false — existing callers see no behavior change.
  • Gated to AI SDK clients; throws StagehandInvalidArgumentError otherwise (validated in both the handler and inference.extract, with the handler check running before the screenshot is taken).
  • Screenshot capture is bracketed by ensureTimeRemaining() so it respects the extract timeout.
  • Wired end-to-end: public ExtractOptions type, ExtractOptionsSchema, OpenAPI ExtractOptions, StagehandAPIClient.extract wire payload, V3.extractExtractHandlerinference.extractbuildExtract{System,User}Prompt.

test plan

  • extract-screenshot.test.ts (new) — multimodal message shape on happy path; rejection for non-AI SDK clients.
  • timeout-handlers.test.ts — handler captures viewport when enabled, skips capture by default, rejects screenshot + non-AI SDK client without touching page.screenshot or the snapshot pipeline.
  • api-client-serialization.test.ts (renamed from api-client-observe-variables.test.ts) — wire payload preserves options.screenshot.

Summary by cubic

Adds a screenshot option to extract() that sends the current viewport screenshot with the accessibility tree to improve results on visually-driven pages.

  • New Features
    • extract({ options: { screenshot: boolean } }) captures a PNG of the current viewport and includes it with the accessibility tree; defaults to false; only supported with aisdk clients (throws StagehandInvalidArgumentError otherwise).
    • Prompts are consolidated and multimodal when enabled: system and user prompts mention the screenshot and using it with the accessibility tree; attaches an image_url data URI; logs when a screenshot is used.
    • Public API, types, and OpenAPI updated (ExtractOptions.screenshot); the API client forwards the flag; tests cover prompt shape, viewport capture, default-off behavior, timeout guards, client-type validation, and serialization.

Written for commit d0c7500. Summary will update on new commits. Review in cubic

@changeset-bot

changeset-bot Bot commented May 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d0c7500

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

This PR includes changesets to release 5 packages
Name Type
@browserbasehq/stagehand Minor
@browserbasehq/browse-cli Patch
@browserbasehq/stagehand-evals Patch
@browserbasehq/stagehand-server-v3 Patch
@browserbasehq/stagehand-server-v4 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

@miguelg719
miguelg719 force-pushed the miguelgonzalez/stg-2065-add-screenshottruefalse-option-to-extract branch from 5241d31 to 2b4eca9 Compare May 20, 2026 15:22
@github-actions

github-actions Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

✱ Stainless preview builds for stagehand

This PR will update the stagehand SDKs with the following commit message.

feat: Add `screenshot` option to Extract
⚠️ stagehand-python studio · code

Your SDK build had at least one "warning" diagnostic.
generate ⚠️build ✅lint ✅test ✅

pip install https://pkg.stainless.com/s/stagehand-python/393ebbee487278360fc844e1fb5034651f37cce4/stagehand-3.20.0-py3-none-any.whl
stagehand-openapi studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅

⚠️ stagehand-csharp studio · code

Your SDK build had at least one "warning" diagnostic.
generate ⚠️build ✅lint ✅test ✅

stagehand-ruby studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅build ⏭️lint ✅test ✅

stagehand-kotlin studio · conflict

Your SDK build had at least one note diagnostic.

stagehand-java studio · conflict

Your SDK build had at least one note diagnostic.

⚠️ stagehand-php studio · code

Your SDK build had at least one "warning" diagnostic.
generate ⚠️lint ✅test ✅

⚠️ stagehand-typescript studio · conflict

Your SDK build had at least one warning diagnostic.

stagehand-go studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅build ⏭️lint ✅test ✅

go get github.com/stainless-sdks/stagehand-go@ba29e1e97d4744a504adf2990fa4cc1eeabf9bba

This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-05-20 21:02:43 UTC

Comment thread .changeset/extract-screenshot-option.md Outdated
Comment thread packages/core/tests/unit/api-client-observe-variables.test.ts Outdated
@miguelg719
miguelg719 marked this pull request as ready for review May 20, 2026 20:05
Comment thread packages/core/lib/prompt.ts Outdated

@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.

No issues found across 13 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.
Architecture diagram
sequenceDiagram
    participant Client as "Client (User Code)"
    participant V3 as "V3.extract()"
    participant ExtractHandler as "ExtractHandler"
    participant Page as "Page (Playwright)"
    participant Inference as "extract() (inference.ts)"
    participant LLM as "LLMClient (AI SDK)"
    participant Prompts as "Prompt Builders"

    Note over Client,Prompts: NEW: Screenshot extraction flow

    Client->>V3: extract(instruction, { screenshot: true })
    V3->>ExtractHandler: extract({ screenshot: true, ... })

    ExtractHandler->>ExtractHandler: resolveLlmClient(model)
    
    alt llmClient.type is NOT 'aisdk'
        ExtractHandler-->>Client: throw StagehandInvalidArgumentError
    end

    ExtractHandler->>Page: captureHybridSnapshot(...)
    Page-->>ExtractHandler: snapshot (combinedTree)

    ExtractHandler->>Page: page.screenshot({ fullPage: false, type: 'png' })
    Page-->>ExtractHandler: screenshotBuffer (Buffer)

    ExtractHandler->>Inference: extract({ screenshot: screenshotBuffer, ... })

    alt llmClient.type is NOT 'aisdk'
        Inference-->>ExtractHandler: throw StagehandInvalidArgumentError
    end

    Inference->>Prompts: buildExtractSystemPrompt(includeScreenshot=true)
    Prompts-->>Inference: system prompt referencing accessibility tree and screenshot

    Note over Inference: Builds multimodal user message

    Inference->>Prompts: buildExtractUserPrompt(instruction, domElements, screenshotDataUrl)
    Prompts->>Prompts: Convert screenshot buffer to data URL

    alt screenshotDataUrl present
        Prompts-->>Inference: Multimodal message (text + image_url)
    else no screenshot
        Prompts-->>Inference: Text-only message
    end

    Inference->>LLM: createChatCompletion(messages with image_url)
    LLM-->>Inference: LLM response + usage

    Inference-->>ExtractHandler: extracted data

    ExtractHandler-->>V3: results
    V3-->>Client: extracted content
Loading

Re-trigger cubic

@pirate pirate 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.

looks good, just make sure we dont emit full base64 to any DB/logs

@miguelg719
miguelg719 merged commit 6e75725 into main May 20, 2026
213 checks passed
Comment thread packages/core/tests/unit/extract-screenshot.test.ts
seanmcguire12 pushed a commit that referenced this pull request Jun 3, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @browserbasehq/stagehand@3.5.0

### Minor Changes

- [#2149](#2149)
[`6e75725`](6e75725)
Thanks [@miguelg719](https://github.com/miguelg719)! - Added a
`screenshot` option to `extract()` that sends the current viewport
screenshot with the a11y tree for extraction.

- [#2127](#2127)
[`78bcde8`](78bcde8)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - Add
`ignoreDefaultArgs` option to selectively remove chrome-launcher's
built-in default flags (e.g. `--disable-extensions`) when running
locally

- [#2160](#2160)
[`49575d6`](49575d6)
Thanks [@monadoid](https://github.com/monadoid)! - Forward constructor
and request model configuration when initializing API-backed sessions.

- [#2171](#2171)
[`dc1445d`](dc1445d)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - add native
clipboard API

### Patch Changes

- [#2146](#2146)
[`3a53ed4`](3a53ed4)
Thanks [@shriyatheunicorn](https://github.com/shriyatheunicorn)! - Pass
local browser launch options through when attaching over CDP so explicit
viewport settings are respected.

- [#2107](#2107)
[`8fc16d2`](8fc16d2)
Thanks [@miguelg719](https://github.com/miguelg719)! - Fix Anthropic CUA
`triple_click` action mapping.

- [#2118](#2118)
[`3e95a87`](3e95a87)
Thanks [@monadoid](https://github.com/monadoid)! - Add Vertex auth
parameters to the core and server API schemas.

- [#2126](#2126)
[`ebbdcd3`](ebbdcd3)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - fix(core):
import ToolSet from ai public export

- [#2120](#2120)
[`12703a6`](12703a6)
Thanks [@miguelg719](https://github.com/miguelg719)! - Fix
structuredOutputMode for newer Anthropic models

- [#2170](#2170)
[`1db5f1c`](1db5f1c)
Thanks [@Kylejeong2](https://github.com/Kylejeong2)! - Add Claude Opus
4.8 to the supported CUA model whitelist.

- [#2116](#2116)
[`cb586a1`](cb586a1)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - include
"[selected]" or "[checked]" state in snapshot

- [#2129](#2129)
[`765861c`](765861c)
Thanks [@miguelg719](https://github.com/miguelg719)! - Add a
backend-selectable v3 evaluator facade while preserving the legacy
evaluator path.

- [#2157](#2157)
[`2cd60a3`](2cd60a3)
Thanks [@miguelg719](https://github.com/miguelg719)! - Add verifier
trajectory, rubric, and evaluation-result types with normalized public
naming.

- [#2131](#2131)
[`e102a89`](e102a89)
Thanks [@miguelg719](https://github.com/miguelg719)! - Capture verifier
trajectory evidence from agent evidence callbacks for offline scoring.

## @browserbasehq/browse-cli@0.6.1

### Patch Changes

- Updated dependencies
\[[`3a53ed4`](3a53ed4),
[`6e75725`](6e75725),
[`8fc16d2`](8fc16d2),
[`78bcde8`](78bcde8),
[`3e95a87`](3e95a87),
[`ebbdcd3`](ebbdcd3),
[`12703a6`](12703a6),
[`1db5f1c`](1db5f1c),
[`cb586a1`](cb586a1),
[`765861c`](765861c),
[`2cd60a3`](2cd60a3),
[`e102a89`](e102a89),
[`49575d6`](49575d6),
[`dc1445d`](dc1445d)]:
    -   @browserbasehq/stagehand@3.5.0

## @browserbasehq/stagehand-server-v3@3.7.0

### Minor Changes

- [#2160](#2160)
[`49575d6`](49575d6)
Thanks [@monadoid](https://github.com/monadoid)! - Forward constructor
and request model configuration when initializing API-backed sessions.

### Patch Changes

- [#2118](#2118)
[`3e95a87`](3e95a87)
Thanks [@monadoid](https://github.com/monadoid)! - Add Vertex auth
parameters to the core and server API schemas.

- [#2167](#2167)
[`ce21468`](ce21468)
Thanks [@monadoid](https://github.com/monadoid)! - Add SEA binary
--version build metadata output.

- Updated dependencies
\[[`3a53ed4`](3a53ed4),
[`6e75725`](6e75725),
[`8fc16d2`](8fc16d2),
[`78bcde8`](78bcde8),
[`3e95a87`](3e95a87),
[`ebbdcd3`](ebbdcd3),
[`12703a6`](12703a6),
[`1db5f1c`](1db5f1c),
[`cb586a1`](cb586a1),
[`765861c`](765861c),
[`2cd60a3`](2cd60a3),
[`e102a89`](e102a89),
[`49575d6`](49575d6),
[`dc1445d`](dc1445d)]:
    -   @browserbasehq/stagehand@3.5.0

## @browserbasehq/stagehand-evals@2.0.2

### Patch Changes

- Updated dependencies
\[[`3a53ed4`](3a53ed4),
[`6e75725`](6e75725),
[`8fc16d2`](8fc16d2),
[`78bcde8`](78bcde8),
[`3e95a87`](3e95a87),
[`ebbdcd3`](ebbdcd3),
[`12703a6`](12703a6),
[`1db5f1c`](1db5f1c),
[`cb586a1`](cb586a1),
[`765861c`](765861c),
[`2cd60a3`](2cd60a3),
[`e102a89`](e102a89),
[`49575d6`](49575d6),
[`dc1445d`](dc1445d)]:
    -   @browserbasehq/stagehand@3.5.0

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
felipeofdev-ai pushed a commit to felipeofdev-ai/stagehand that referenced this pull request Aug 4, 2026
# why
Some pages do not properly encapsulate the necessary information
required to extract the content requested by the user, and can benefit
from a hybrid approach with vision.

# what changed
- New `extract({ options: { screenshot: true } })` flag. Captures the
current viewport as PNG and sends it as an `image_url` part alongside
the a11y tree text in the extraction LLM call.
- Default is `false` — existing callers see no behavior change.
- Gated to AI SDK clients; throws `StagehandInvalidArgumentError`
otherwise (validated in both the handler and `inference.extract`, with
the handler check running before the screenshot is taken).
- Screenshot capture is bracketed by `ensureTimeRemaining()` so it
respects the extract timeout.
- Wired end-to-end: public `ExtractOptions` type,
`ExtractOptionsSchema`, OpenAPI `ExtractOptions`,
`StagehandAPIClient.extract` wire payload, `V3.extract` →
`ExtractHandler` → `inference.extract` →
`buildExtract{System,User}Prompt`.

# test plan
- `extract-screenshot.test.ts` (new) — multimodal message shape on happy
path; rejection for non-AI SDK clients.
- `timeout-handlers.test.ts` — handler captures viewport when enabled,
skips capture by default, rejects screenshot + non-AI SDK client without
touching `page.screenshot` or the snapshot pipeline.
- `api-client-serialization.test.ts` (renamed from
`api-client-observe-variables.test.ts`) — wire payload preserves
`options.screenshot`.


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds a screenshot option to `extract()` that sends the current viewport
screenshot with the accessibility tree to improve results on
visually-driven pages.

- New Features
- `extract({ options: { screenshot: boolean } })` captures a PNG of the
current viewport and includes it with the accessibility tree; defaults
to false; only supported with `aisdk` clients (throws
`StagehandInvalidArgumentError` otherwise).
- Prompts are consolidated and multimodal when enabled: system and user
prompts mention the screenshot and using it with the accessibility tree;
attaches an `image_url` data URI; logs when a screenshot is used.
- Public API, types, and OpenAPI updated (`ExtractOptions.screenshot`);
the API client forwards the flag; tests cover prompt shape, viewport
capture, default-off behavior, timeout guards, client-type validation,
and serialization.

<sup>Written for commit d0c7500.
Summary will update on new commits. <a
href="https://cubic.dev/pr/browserbase/stagehand/pull/2149?utm_source=github">Review
in cubic</a></sup>

<!-- End of auto-generated description by cubic. -->
felipeofdev-ai pushed a commit to felipeofdev-ai/stagehand that referenced this pull request Aug 4, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @browserbasehq/stagehand@3.5.0

### Minor Changes

- [browserbase#2149](browserbase#2149)
[`6e75725`](browserbase@6e75725)
Thanks [@miguelg719](https://github.com/miguelg719)! - Added a
`screenshot` option to `extract()` that sends the current viewport
screenshot with the a11y tree for extraction.

- [browserbase#2127](browserbase#2127)
[`78bcde8`](browserbase@78bcde8)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - Add
`ignoreDefaultArgs` option to selectively remove chrome-launcher's
built-in default flags (e.g. `--disable-extensions`) when running
locally

- [browserbase#2160](browserbase#2160)
[`49575d6`](browserbase@49575d6)
Thanks [@monadoid](https://github.com/monadoid)! - Forward constructor
and request model configuration when initializing API-backed sessions.

- [browserbase#2171](browserbase#2171)
[`dc1445d`](browserbase@dc1445d)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - add native
clipboard API

### Patch Changes

- [browserbase#2146](browserbase#2146)
[`3a53ed4`](browserbase@3a53ed4)
Thanks [@shriyatheunicorn](https://github.com/shriyatheunicorn)! - Pass
local browser launch options through when attaching over CDP so explicit
viewport settings are respected.

- [browserbase#2107](browserbase#2107)
[`8fc16d2`](browserbase@8fc16d2)
Thanks [@miguelg719](https://github.com/miguelg719)! - Fix Anthropic CUA
`triple_click` action mapping.

- [browserbase#2118](browserbase#2118)
[`3e95a87`](browserbase@3e95a87)
Thanks [@monadoid](https://github.com/monadoid)! - Add Vertex auth
parameters to the core and server API schemas.

- [browserbase#2126](browserbase#2126)
[`ebbdcd3`](browserbase@ebbdcd3)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - fix(core):
import ToolSet from ai public export

- [browserbase#2120](browserbase#2120)
[`12703a6`](browserbase@12703a6)
Thanks [@miguelg719](https://github.com/miguelg719)! - Fix
structuredOutputMode for newer Anthropic models

- [browserbase#2170](browserbase#2170)
[`1db5f1c`](browserbase@1db5f1c)
Thanks [@Kylejeong2](https://github.com/Kylejeong2)! - Add Claude Opus
4.8 to the supported CUA model whitelist.

- [browserbase#2116](browserbase#2116)
[`cb586a1`](browserbase@cb586a1)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - include
"[selected]" or "[checked]" state in snapshot

- [browserbase#2129](browserbase#2129)
[`765861c`](browserbase@765861c)
Thanks [@miguelg719](https://github.com/miguelg719)! - Add a
backend-selectable v3 evaluator facade while preserving the legacy
evaluator path.

- [browserbase#2157](browserbase#2157)
[`2cd60a3`](browserbase@2cd60a3)
Thanks [@miguelg719](https://github.com/miguelg719)! - Add verifier
trajectory, rubric, and evaluation-result types with normalized public
naming.

- [browserbase#2131](browserbase#2131)
[`e102a89`](browserbase@e102a89)
Thanks [@miguelg719](https://github.com/miguelg719)! - Capture verifier
trajectory evidence from agent evidence callbacks for offline scoring.

## @browserbasehq/browse-cli@0.6.1

### Patch Changes

- Updated dependencies
\[[`3a53ed4`](browserbase@3a53ed4),
[`6e75725`](browserbase@6e75725),
[`8fc16d2`](browserbase@8fc16d2),
[`78bcde8`](browserbase@78bcde8),
[`3e95a87`](browserbase@3e95a87),
[`ebbdcd3`](browserbase@ebbdcd3),
[`12703a6`](browserbase@12703a6),
[`1db5f1c`](browserbase@1db5f1c),
[`cb586a1`](browserbase@cb586a1),
[`765861c`](browserbase@765861c),
[`2cd60a3`](browserbase@2cd60a3),
[`e102a89`](browserbase@e102a89),
[`49575d6`](browserbase@49575d6),
[`dc1445d`](browserbase@dc1445d)]:
    -   @browserbasehq/stagehand@3.5.0

## @browserbasehq/stagehand-server-v3@3.7.0

### Minor Changes

- [browserbase#2160](browserbase#2160)
[`49575d6`](browserbase@49575d6)
Thanks [@monadoid](https://github.com/monadoid)! - Forward constructor
and request model configuration when initializing API-backed sessions.

### Patch Changes

- [browserbase#2118](browserbase#2118)
[`3e95a87`](browserbase@3e95a87)
Thanks [@monadoid](https://github.com/monadoid)! - Add Vertex auth
parameters to the core and server API schemas.

- [browserbase#2167](browserbase#2167)
[`ce21468`](browserbase@ce21468)
Thanks [@monadoid](https://github.com/monadoid)! - Add SEA binary
--version build metadata output.

- Updated dependencies
\[[`3a53ed4`](browserbase@3a53ed4),
[`6e75725`](browserbase@6e75725),
[`8fc16d2`](browserbase@8fc16d2),
[`78bcde8`](browserbase@78bcde8),
[`3e95a87`](browserbase@3e95a87),
[`ebbdcd3`](browserbase@ebbdcd3),
[`12703a6`](browserbase@12703a6),
[`1db5f1c`](browserbase@1db5f1c),
[`cb586a1`](browserbase@cb586a1),
[`765861c`](browserbase@765861c),
[`2cd60a3`](browserbase@2cd60a3),
[`e102a89`](browserbase@e102a89),
[`49575d6`](browserbase@49575d6),
[`dc1445d`](browserbase@dc1445d)]:
    -   @browserbasehq/stagehand@3.5.0

## @browserbasehq/stagehand-evals@2.0.2

### Patch Changes

- Updated dependencies
\[[`3a53ed4`](browserbase@3a53ed4),
[`6e75725`](browserbase@6e75725),
[`8fc16d2`](browserbase@8fc16d2),
[`78bcde8`](browserbase@78bcde8),
[`3e95a87`](browserbase@3e95a87),
[`ebbdcd3`](browserbase@ebbdcd3),
[`12703a6`](browserbase@12703a6),
[`1db5f1c`](browserbase@1db5f1c),
[`cb586a1`](browserbase@cb586a1),
[`765861c`](browserbase@765861c),
[`2cd60a3`](browserbase@2cd60a3),
[`e102a89`](browserbase@e102a89),
[`49575d6`](browserbase@49575d6),
[`dc1445d`](browserbase@dc1445d)]:
    -   @browserbasehq/stagehand@3.5.0
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