You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: make browser verification model-independent (#250)
## Summary
- replace provider-backed browser observation with Stagehand native
accessibility snapshots
- keep XPath mappings inside the sandbox driver and expose only
page-bound, single-use refs
- return the post-action page tree so functional verification needs no
second inference call
- align web/mobile prompts, tool descriptions, capabilities, skills, and
architecture docs
## Architecture
The driver snapshots the active page locally, exposes bounded hyphenated
refs, and retains the ref-to-XPath map in memory. browser_act accepts
one ref plus a validated method/value, enforces URL and origin binding,
consumes the observation, executes deterministically with self-healing
disabled, and returns a fresh state tree.
## Decisions
- Native snapshot instead of changing observation models: removes
provider-specific structured-output failure and latency for every agent
model.
- Server-held selectors instead of returning XPath: prevents selector
invention and keeps the trust boundary inside the driver.
- Post-action tree in the act response instead of a second extract:
makes the acceptance flow bounded and deterministic.
## Verification
- pnpm lint
- pnpm typecheck
- pnpm turbo build --force
- pnpm deadcode
- pnpm architecture:check
- pnpm turbo skills:build
- node --check infra/containers/sandbox/browser-driver/server.js
Production browser QA follows after the sandbox image is built and
promoted.
Copy file name to clipboardExpand all lines: packages/agent-core/src/mastra/system-prompt.ts
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -206,7 +206,7 @@ Beyond these you also have browser, document-generation, data-analysis, web-rese
206
206
constWEB_MODULE=`## Building web apps
207
207
208
208
Make the app real and complete: working features, real data flow, considered design. Default to a clean modern stack — React / Next.js. Ship something polished: sensible colour and type, responsive, mobile-first, no lorem ipsum, no dead buttons, no placeholder images. Write the files, add or update dependencies only when the app actually needs them, and start the dev server early with code_start_dev_server (request port 5173) so you're always working against the running app. The managed server restores an unchanged project's existing dependencies itself. Never substitute a shell process for the managed preview, even for a static server or when restarting an existing project.
209
-
Verify it in the browser: open the app's INTERNAL address in the sandbox's headed Chromium — http://localhost:<port> (e.g. http://localhost:5173), NOT the external preview link (your sandbox browser can't reach that). Take one screenshot with the exact visual acceptance criterion; its result includes a visual PASS/FAIL assessment, so do not take another screenshot unless you changed the rendered output. To exercise one representative interaction, call browser_observe once for that exact interaction, pass one returned action unchanged to browser_act, then read the resulting state once. Never send prose directly to browser_act, invent selectors, write a separate Playwright/Python test, or install another browser. If either check fails, fix the concrete defect and repeat only that changed check once; never loop on equivalent screenshots or interactions. If the browser can't load it at all, note you couldn't visually verify and go straight to your closing summary. The running app is shown to the user automatically in the Computer panel's Browser tab — never paste the preview URL.`;
209
+
Verify it in the browser: open the app's INTERNAL address in the sandbox's headed Chromium — http://localhost:<port> (e.g. http://localhost:5173), NOT the external preview link (your sandbox browser can't reach that). Take one screenshot with the exact visual acceptance criterion; its result includes a visual PASS/FAIL assessment, so do not take another screenshot unless you changed the rendered output. To exercise one representative interaction, call browser_observe once, choose one exact hyphenated element ref from its accessibility tree, and call browser_act with that ref plus the required method/value. browser_act returns the post-action page tree, so use that result to verify the interaction without another observation or extraction. Never invent a ref or selector, write a separate Playwright/Python test, or install another browser. If either check fails, fix the concrete defect and repeat only that changed check once; never loop on equivalent screenshots or interactions. If the browser can't load it at all, note you couldn't visually verify and go straight to your closing summary. The running app is shown to the user automatically in the Computer panel's Browser tab — never paste the preview URL.`;
210
210
211
211
constMOBILE_MODULE=`## Building the mobile app
212
212
@@ -219,7 +219,7 @@ Build the Expo Router screens for a polished, native-feeling app: real screens,
219
219
// keeps WEB_MODULE's "start the dev server yourself" guidance; this note only applies here.
220
220
constAPP_BUILDER_PREVIEW_NOTE=`## Your preview is already running — do not start your own
221
221
222
-
This project is scaffolded at the workspace root and its dev server + live preview are ALREADY running and managed for you before your turn begins (for a mobile app that's Metro serving the app on web plus the Expo Go QR). Do NOT initialize, scaffold, or create another app or nested project. Do NOT start, restart, or reconfigure the server yourself — no code_start_dev_server, \`expo start\`, \`npm run dev\`/\`web\`, or \`npx expo …\`: a second server fights the managed one for the project's port and breaks the preview. Use pnpm, never npm/npx, only when dependency changes are necessary. Inspect and edit the existing root files; the preview hot-reloads on save. Verify by opening the running app in the sandbox's headed Chromium at its INTERNAL localhost address; it's shown to the user automatically in the Computer/App panel — never paste the preview URL. Metro may briefly show an empty document while rebuilding the first web bundle after edits: wait for page content once and reload at most once before treating it as a defect. Take one screenshot with the exact visual acceptance criterion and use its returned PASS/FAIL assessment; never judge screenshot byte size. Exercise one representative interaction by calling browser_observe once, passing one returned action unchanged to browser_act, and reading the resulting state once. Never write a separate Playwright/Python test or install another browser. If a check fails, fix the concrete defect and repeat only that changed check once. Once the requested content renders, that interaction passes, and no blocking browser error remains, finish.`;
222
+
This project is scaffolded at the workspace root and its dev server + live preview are ALREADY running and managed for you before your turn begins (for a mobile app that's Metro serving the app on web plus the Expo Go QR). Do NOT initialize, scaffold, or create another app or nested project. Do NOT start, restart, or reconfigure the server yourself — no code_start_dev_server, \`expo start\`, \`npm run dev\`/\`web\`, or \`npx expo …\`: a second server fights the managed one for the project's port and breaks the preview. Use pnpm, never npm/npx, only when dependency changes are necessary. Inspect and edit the existing root files; the preview hot-reloads on save. Verify by opening the running app in the sandbox's headed Chromium at its INTERNAL localhost address; it's shown to the user automatically in the Computer/App panel — never paste the preview URL. Metro may briefly show an empty document while rebuilding the first web bundle after edits: wait for page content once and reload at most once before treating it as a defect. Take one screenshot with the exact visual acceptance criterion and use its returned PASS/FAIL assessment; never judge screenshot byte size. Exercise one representative interaction by calling browser_observe once, choosing one exact hyphenated element ref from its accessibility tree, and calling browser_act with that ref plus the required method/value. Use browser_act's post-action tree as the result check; do not observe or extract again. Never invent a ref or selector, write a separate Playwright/Python test, or install another browser. If a check fails, fix the concrete defect and repeat only that changed check once. Once the requested content renders, that interaction passes, and no blocking browser error remains, finish.`;
"Execute one exact action returned by the immediately preceding browser_observe call. Pass the returned action object unchanged; invented or stale actions are rejected.",
31
+
"Execute one deterministic action against an exact element ref from the immediately preceding browser_observe tree. The ref is page-bound and single-use; the result includes the post-action page tree.",
"Find executable actions for one explicit interaction in the current sandbox browser page. Select one returned action and pass it unchanged to browser_act.",
52
+
"Read the current sandbox page as a deterministic accessibility tree with page-bound element refs. Choose an exact hyphenated ref from the tree for browser_act; no secondary model is invoked.",
0 commit comments