Skip to content

add ignoreLocators to act - #2655

Merged
seanmcguire12 merged 12 commits into
locator-inputsfrom
act-ignore-locators
Aug 10, 2026
Merged

add ignoreLocators to act#2655
seanmcguire12 merged 12 commits into
locator-inputsfrom
act-ignore-locators

Conversation

@seanmcguire12

@seanmcguire12 seanmcguire12 commented Aug 9, 2026

Copy link
Copy Markdown
Member

why

  • for consistency across act/extract/observe

what changed

this PR extends locator-based scoping to instruction-based/nondeterministic act

  • adds ignoreLocators to the act protocol options
  • passes locator and ignoreLocators through act snapshot capture so the model only sees the intended page context
  • includes act locator descriptors in cache keys
  • updates TS, Python, & Go SDK public APIs to accept page-bound locator wrapper objects for act
  • validates that supplied act locators belong to the resolved target page before sending RPC requests

SDK Shape

TypeScript:

await stagehand.act("Click the checkout button", {
  page,
  locator: page.locator("main"),
  ignoreLocators: [page.locator("nav"), page.locator(".promo-modal")],
});

Python:

await stagehand.act(
    "Click the checkout button",
    page=page,
    locator=page.locator("main"),
    ignore_locators=[page.locator("nav"), page.locator(".promo-modal")],
)

Go:

_, err := client.Act(ctx, stagehand.ActInstruction("Click the checkout button"), &stagehand.StagehandClientActOptions{
	Page:    page,
	Locator: page.Locator("main"),
	IgnoreLocators: []*stagehand.PageLocator{
		page.Locator("nav"),
		page.Locator(".promo-modal"),
	},
})

behavioural notes:

  • observed actions still execute against their Action.selector data directly. Locator scoping only affects instruction-based/nondeterministic act
  • page remains optional. If omitted, Stagehand resolves the active page & validates locators against that page
  • locator descriptors include selector & optional nth internally
  • ignoreLocators removes matched nodes & descendants from the act planning snapshot
  • act cache data now includes locator and ignoreLocators, so scoped planning does not reuse incompatible cached actions
  • TS batch callbacks now extend the existing locator option serialization path to act
  • Go StagehandClientActOptions now uses explicit client fields instead of embedding generated protocol ActOptions

test plan

  • added protocol tests to cover the new act wire shape for locator and ignoreLocators
  • extension act tests cover focused locator scope, ignored locator subtrees, and locator-filtered planning prompts
  • extension cache tests cover act, observe, and extract locator descriptors in cache data
  • TS SDK tests cover act locator serialization, batch callback locator serialization, and cross-page validation
  • Python SDK tests cover public act Locator inputs, descriptor serialization, and cross-page validation
  • Go SDK tests cover act *PageLocator conversion, cross-page validation, and generated model compatibility for the SDK/internal packages
  • docs tests cover the updated v4 act reference and examples

Summary by cubic

Adds locator scoping to instruction-based act() with a new ignoreLocators option so the model plans within a focused DOM and excludes ignored regions. Scoped act() bypasses server-side caching and sends locators to snapshot capture for both planning and verification.

  • New Features

    • Add ignoreLocators to act options; pass locator and ignoreLocators to snapshot capture for planning and the verification step.
    • Locator-scoped instruction-based act() bypasses server-side result caching and reports metadata.cache.status: DISABLED.
    • Protocol: add ignore_locators to ActOptions in the v4 schema.
    • Locator scoping applies to instruction-based act() only; replays of recorded Actions use their own selectors.
  • SDKs

    • sdk-ts: act accepts locator wrappers and serializes them in direct calls and callback batches (page resolution + locator serialization for act, observe, extract); cross-page validation added.
    • sdk-python: act accepts locator and ignore_locators as page-bound locators with cross-page validation.
    • sdk-go: StagehandClientActOptions uses flattened fields (Page, Locator, IgnoreLocators, Timeout, Variables, Model, Cache); act serializes PageLocators with cross-page validation.
    • Docs updated with act() scoping examples, cache bypass behavior, and Go option shape; speed and caching guides show scoped act() usage.

Written for commit 6e038da. Summary will update on new commits.

Review in cubic

@changeset-bot

changeset-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 6e038da

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@seanmcguire12
seanmcguire12 force-pushed the act-ignore-locators branch 2 times, most recently from 5a7e4f2 to 34695fc Compare August 9, 2026 20:54
@seanmcguire12
seanmcguire12 marked this pull request as ready for review August 9, 2026 21:30
@seanmcguire12
seanmcguire12 requested a review from a team as a code owner August 9, 2026 21:30
@seanmcguire12
seanmcguire12 removed the request for review from a team August 9, 2026 21:30

@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 25 files

Architecture diagram
sequenceDiagram
    participant SDK as Client SDK (TS/Py/Go)
    participant RPC as Stagehand RPC
    participant Svc as Act Service
    participant Page as Page Snapshot
    participant Cache as Cache Service
    participant LLM as LLM Provider

    Note over SDK,LLM: NEW: Locator-scoped act flow

    SDK->>SDK: Resolve target page (explicit or active)
    alt Locator not owned by target page
        SDK-->>SDK: Throw "locator must belong to page"
    else Valid locators
        SDK->>SDK: Serialize locator & ignoreLocators to descriptors
        SDK->>RPC: NEW: stagehand.act(pageId, instruction, options {locator, ignoreLocators})
        RPC->>Svc: Dispatch act request
        Svc->>Svc: Build snapshotOptions {focusLocator, ignoreLocators}
        Svc->>Cache: NEW: Build cache key with locator + ignoreLocators
        alt Cache hit
            Cache-->>Svc: Cached action result
            Svc-->>RPC: Cached result
        else Cache miss
            Svc->>Page: NEW: captureSnapshot(snapshotOptions)
            Page-->>Svc: Locator-scoped DOM tree
            Svc->>LLM: Generate act plan (instruction + scoped DOM)
            LLM-->>Svc: Plan result (elementId, method, args)
            Svc->>Page: NEW: captureSnapshot(snapshotOptions) for change verification
            Page-->>Svc: Diff tree
            Svc->>Cache: NEW: Store result with locator-aware key
            Svc-->>RPC: Result
        end
        RPC-->>SDK: ActResult
    end

    Note over Svc: Recorded Action replays use its own selector,<br/>ignoring locator scoping
Loading

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

Re-trigger cubic

Comment thread packages/sdk-ts/src/stagehand.ts
Comment thread packages/docs/v4/reference/stagehand.mdx Outdated
Comment thread packages/docs/v4/reference/stagehand.mdx Outdated
Comment thread packages/extension/services/cacheService.ts Outdated
Comment thread packages/sdk-ts/tests/objectWrapper.test.ts
Comment thread packages/docs/v4/basics/act.mdx Outdated
Comment thread packages/docs/v4/basics/act.mdx Outdated
Comment thread packages/docs/v4/basics/act.mdx Outdated
Comment thread packages/docs/v4/best-practices/speed-optimization.mdx
Comment thread packages/sdk-go/stagehand.go

@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 27 files

Architecture diagram
sequenceDiagram
    participant User as SDK User Code
    participant SDK as SDK Client (TS/Py/Go)
    participant Batch as Callback Batch (TS)
    participant RPC as JSON-RPC Protocol
    participant ActSvc as Extension actService
    participant CacheSvc as Cache Service
    participant Page as Page.captureSnapshot
    participant LLM as Model (LLM)

    Note over User,LLM: Locator-scoped instruction-based act() flow

    User->>SDK: act(instruction, { page, locator, ignoreLocators })
    SDK->>SDK: Resolve target page (explicit or active page)
    alt Locator from a different page
        SDK-->>User: Error: locator must belong to target page
    end
    alt Instruction is an Action (recorded observe result)
        SDK->>RPC: stagehand.act (no locator options)
        Note over ActSvc,LLM: Action.selector replayed directly - scoping not applied
    else Instruction is a string
        SDK->>SDK: Serialize locator descriptors ({selector, nth})
        SDK->>RPC: stagehand.act(pageId, instruction, options with locator/ignoreLocators)
        alt User composes callback batch
            User->>Batch: act(instruction, { locator, ignoreLocators })
            Batch->>Batch: resolveOperationPage + serializeClientLocatorOptions("act", ...)
            Batch->>RPC: stagehand.act (same wire shape)
        end

        RPC->>ActSvc: act(params)
        ActSvc->>CacheSvc: shouldBypassCacheForLocatorScope(options)
        CacheSvc-->>ActSvc: locator or ignoreLocators present?
        alt Locator scope set
            Note over ActSvc,CacheSvc: Cache reads/writes skipped (status DISABLED)
        end

        ActSvc->>ActSvc: buildActCacheData(params) - omits locator keys
        ActSvc->>Page: captureSnapshot({ focusLocator, ignoreLocators })
        Page-->>ActSvc: Combined tree scoped to focus, excludes ignored subtrees
        ActSvc->>LLM: Build act prompt from filtered snapshot
        LLM-->>ActSvc: Action plan (elementId within scope)

        ActSvc->>Page: captureSnapshot({ focusLocator, ignoreLocators }) for verification
        Page-->>ActSvc: Next scoped tree
        ActSvc->>ActSvc: diffTrees + build step-two prompt
        LLM-->>ActSvc: Verify action result
        ActSvc-->>RPC: ActResult (metadata.cache.status: DISABLED)
        RPC-->>SDK: ActResult
        SDK-->>User: ActResult
    end
Loading

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

Re-trigger cubic

Comment thread packages/docs/v4/best-practices/speed-optimization.mdx
Comment thread packages/docs/v4/reference/stagehand.mdx
Comment thread packages/docs/v4/basics/act.mdx
Comment thread packages/sdk-go/behavior_regression_test.go
@seanmcguire12
seanmcguire12 merged commit d9355af into locator-inputs Aug 10, 2026
54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants