The pi integration returned the raw accessibility tree from `snapshot`.
On real pages most of it is noise: anonymous layout containers (`div`,
`listitem`, `tbody`, `scrollable`, ...) that cannot be clicked or filled,
`StaticText` lines that are single-token fragments already aggregated into
an ancestor's name, and indentation that grows with nesting depth. In an agent
loop that payload is replayed on every later request, so it is paid for
repeatedly.
`snapshot` now keeps only semantic/actionable roles and re-indents by the
kept ancestors. `compact: false` returns the raw tree and `maxChars` hard-caps
the payload. Node IDs are copied verbatim and the facade keeps the full xpath
map, so `run` actions against compact IDs keep working.
Measured on real pages, the compact tree is 21-34% of the raw tree:
news.ycombinator.com 34027 -> 7314 chars, github.com/browserbase/stagehand
63080 -> 20274, books.toscrape.com 21553 -> 7436, example.com 316 -> 218.
What
snapshotin the pi integration returns a reduced accessibility tree by default, withcompact: falseto opt back into the raw tree andmaxCharsto hard-cap the payload.Why
The raw tree is dominated by nodes a caller cannot use:
div,listitem,tbody,scrollable,LayoutTable*, ...) that cannot be clicked or filled,StaticTextlines that are single-token fragments ({,,,=) already folded into an ancestor's accessible name,In an agent loop that payload is replayed on every later request, so it is paid for repeatedly. On
github.com/browserbase/stagehandthe raw tree was 63 080 characters, roughly 15.8k tokens, for a single look at the page.Change
extensions/snapshot-compaction.ts(new): the pure filter. Keeps semantic/actionable roles (link,button,textbox,heading,image,combobox, ...) plusStaticTextof 12+ characters, truncates names at 160 characters, and re-indents kept lines by their kept ancestors (two spaces per level). Lines that carry no node (continuation lines of a multi-line accessible name) are dropped.snapshotgainscompact(defaulttrue) andmaxChars.compact: falsereturns the byte-identical raw tree.maxCharsappends an explicit truncation marker.run/snapshotprompt guidelines now steer callers toward returning extracted values instead of dumping page content.IDs are copied verbatim and only whole lines are removed, so IDs stay valid for
runactions: the facade builds and stores the full xpath map regardless of what the tool returns, and filtering only changes the text handed back to the model.Measurements
snapshotresult size, raw vs compact, from real runs in the pi integration (local Chrome/Edge, no model in the loop for the sizes):Tool latency is unchanged (a warm
snapshotis 27-39 ms; the cold browser launch that dominates the first call is untouched).Verification
vitest runinpackages/integrations/pi: 16 tests pass, including the filter unit tests and an assertion that every ID in a compact tree exists in the raw tree.tsc --noEmit,oxlint, andoxfmt --checkare clean for the touched files.books.toscrape.com-> a category page), sorunactions are not broken by filtering.I ran the TypeScript checks scoped to
packages/integrations/pirather thanjust check/just test, becausejust, Go 1.26, anduvare not installed in my environment. No changeset:packages/integrations/piis private and this is not a public SDK, extension, or protocol change.Follow-up
The same filter would help every integration rather than only pi, so it may belong in the facade contract (
packages/integrations/core) once the behaviour is settled here. I kept it pi-local to keep the blast radius small.Developed and verified with an AI coding agent in a local checkout; the numbers and test results above come from that checkout.
Summary by cubic
Makes
snapshotin the pi integration return a compact accessibility tree by default, dropping anonymous layout containers and fragmented text so agent context costs far less. Passcompact: falseto get the raw tree, andmaxCharsto hard-cap the payload.New Features
extensions/snapshot-compaction.tsto keep semantic/actionable roles andStaticTextlines 12+ characters, truncating names at 160 characters.runactions still work.compact(defaulttrue) andmaxCharsparameters to thesnapshottool.runandsnapshotprompts to steer callers toward returning only needed values instead of dumping page content.github.com/browserbase/stagehand).Written for commit 346b3f8. Summary will update on new commits.