Updated 2026-02-14 — Expanded .eventually() verifications (adaptive resnapshotting) and a first-class scroll verification primitive.
Predicate is a verification layer: the agent acts, and Predicate asserts with evidence.
In browser agents, it’s common to see:
Predicate’s approach is to make progress provable:
.eventually())If you’re new to the assertion APIs, start here:
When you use .eventually() for deterministic checks, you can now grow the snapshot element limit across retries. This helps on long / virtualized pages where a small snapshot can miss the target element, causing a false failure.
from predicate.verification import exists
# Grow snapshot limit on each retry until the element appears.
ok = await runtime.check(
exists("text~'Checkout'"),
label="checkout_visible",
required=True,
).eventually(
timeout_s=12,
snapshot_limit_growth={
"start_limit": 60,
"step": 40,
"max_limit": 220,
"apply_on": "only_on_fail", # default; or "all"
},
)A common failure mode is: the agent “scrolls” but the UI doesn’t move (overlay blocks input, nested scroller, focus issues). This causes silent drift / loops.
Use the runtime scroll helper to scroll and verify the scroll had real effect using a bounded before/after scroll position (scrollTop).
runtime.begin_step("Scroll and verify it moved")
ok = await runtime.scroll_by(
600,
verify=True,
min_delta_px=50,
label="scroll_effective",
required=True,
timeout_s=5.0,
)
if not ok:
raise RuntimeError("Scroll had no effect (likely blocked by overlay or nested scroller).")