Skip to content

fix: Tighten required shape of frameOrdinal/backendNodeID [stacked]#1963

Closed
monadoid wants to merge 11 commits intoSTG-1758from
stg-1555_2
Closed

fix: Tighten required shape of frameOrdinal/backendNodeID [stacked]#1963
monadoid wants to merge 11 commits intoSTG-1758from
stg-1555_2

Conversation

@monadoid
Copy link
Copy Markdown
Contributor

@monadoid monadoid commented Apr 6, 2026

Why

We were asking the LLM to return a single elementId: string field, where the model was expected to return an encoded value like "0-76" or "16-21" that packed both the frame ordinal and backend node id into one string. That made it possible for the LLM to return structurally invalid data for that field, like "9786" or empty strings.

Several tickets were seeing this error:
No object generated: response did not match schema
STG-1486, STG-1555, STG-1634, STG-1690

What Changed

Stacked on top of #1949.

This PR fixes this by tightening up the required shape of the data returned by the LLM:
target: { frameOrdinal: number, backendNodeId: number }

This PR does not change anything user facing. We intentionally stop at the inference boundary. I also kept using the old encoded snapshot maps and legacy elementId shape upstream for now to keep the PR focused.

  • Replaced model-generated elementId strings with typed target refs in the internal act/observe schemas.
  • Switched the internal model action shape to a method-specific union.
  • Encoded typed refs back into the existing snapshot key format at the inference boundary so the upstream/public-facing shape stays unchanged.
  • Removed explicit strict flags at the Stagehand-owned call sites and rely on strict structured outputs by default in the AI SDK v6 path.
  • Updated the evals AI SDK wrapper to use the same AI SDK v6 structured-output path.
  • Added focused regression coverage for structured act, observe, and dragAndDrop element refs.

Summary by cubic

Require typed element refs target: { frameOrdinal, backendNodeId } for act/observe, canonicalize twoStep as a top‑level boolean, and convert back to legacy encoded IDs at the inference boundary. Also enable structured outputs across AI SDK providers, harden local CDP connect with transient retries, and route legacy model names through the AI SDK. This closes schema holes that caused “No object generated: response did not match schema” in STG-1486, STG-1555, STG-1634, and STG-1690, with no public API changes.

  • Bug Fixes

    • Enforce typed element refs and method-specific validation; accept click without a button.
    • Canonicalize twoStep as a top-level field; reject twoStep nested inside action.
    • Propagate NoObjectGeneratedError from act, extract, and fillForm; keep V3AgentHandler.execute() returning a failed result instead of throwing.
    • Add transient-retry to CDP connect and enable a short retry window in LOCAL env to reduce flakiness.
  • Refactors

    • Introduce modelActions schemas (elementRef, ModelAction, ModelActResponse) and use them internally; convert typed refs to legacy IDs/args at the inference boundary.
    • Default to strict structured outputs in the AI SDK v6 path; enable structured outputs for openai, azure, google/vertex, anthropic, groq, cerebras, and mistral via provider options; update AISdkClientWrapped to use Output.object with generateText.
    • Route legacy bare model names through the AI SDK with a deprecation warning; remove OpenAIClient and consolidate provider handling.

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

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 6, 2026

⚠️ No Changeset found

Latest commit: 1fad611

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

@monadoid monadoid closed this Apr 7, 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.

1 participant