Get started with Predicate SDK in 5 minutes. This guide walks you through a complete login automation example.
Install the Predicate SDK for your preferred language:
# Install the Python SDK
pip install predicatelabs
# Install Chromium browser (required for automation)
playwright install chromiumAPI key enables smarter filtering and saves LLM token usage
Sign up at www.predicatelabs.dev to get your API key. You can also test locally without an API key.
export PREDICATE_API_KEY="sk_..."
If you already have an AI web agent (LangChain, browser-use, your own loop), you can keep it — and attach Predicate Debugger as a verification + tracing sidecar.
Notes:
page is the Playwright Page owned by your agent/framework.Tracer writes a JSONL trace you can inspect in Predicate Studio later.use_api: false in snapshot() options.import asyncio
from predicate import PredicateDebugger
from predicate.tracing import Tracer, JsonlTraceSink
from predicate.verification import exists, url_contains
class MyAgent:
"""
Your existing agent/framework.
It owns the browser and returns a Playwright Page.
"""
def __init__(self, page):
self.page = page # playwright.async_api.Page
async def step(self) -> None:
# Example "action" - replace with your real agent step
await self.page.click("text=Checkout")
async def main() -> None:
# 1) Your agent/framework provides the Playwright page
page = agent.get_page() # playwright.async_api.Page
# 2) Create tracer (writes trace.jsonl)
tracer = Tracer(run_id="quickstart-run", sink=JsonlTraceSink("trace.jsonl"))
# 3) Attach PredicateDebugger to your existing page (sidecar mode)
dbg = PredicateDebugger.attach(page, tracer=tracer)
# 4) Your agent loop runs as usual…
await agent.step()
# 5) …and you verify outcomes with Predicate (deterministic)
# Local-only snapshot (no API key required):
await dbg.snapshot(use_api=False, goal="verify:after-step", limit=120)
# Checks can be added dynamically (LLM can decide what to verify):
dbg.check(url_contains("checkout"), label="navigated_to_checkout", required=True).once()
dbg.check(exists("role=heading text~'Checkout'"), label="checkout_heading_visible").once()
# Optional: group checks into a step boundary (creates a clean trace segment)
async with dbg.step("verify:checkout"):
await dbg.snapshot(use_api=False)
await dbg.check(exists("role=button text~'Place Order'"), label="place_order_visible", required=True).eventually()
if __name__ == "__main__":
asyncio.run(main())python your_script.pyRun the script that contains your agent loop. If you used the examples above, this will open a browser, execute your agent step(s), and then run Predicate verification.
If you don't already have an agent framework, you can also use the Predicate SDK directly to drive the browser with snapshots + actions.
from predicate import PredicateBrowser, snapshot, find, type_text, click, wait_for
# Create browser instance
with PredicateBrowser(api_key="sk_...") as browser:
# Navigate to login page
browser.page.goto("https://example.com/login")
# PERCEPTION: Take snapshot and find elements
snap = snapshot(browser)
email_input = find(snap, "role=textbox text~'email'")
password_input = find(snap, "role=textbox text~'password'")
submit_btn = find(snap, "role=button text~'sign in'")
# ACTION: Interact with the page
type_text(browser, email_input.id, "user@example.com")
type_text(browser, password_input.id, "password123")
click(browser, submit_btn.id)
# VERIFICATION: Wait for success
result = wait_for(browser, "role=heading text~'Dashboard'", timeout=5.0)
if result.found:
print("✓ Login successful!")
else:
print("✗ Login failed")trace.jsonl)use_api: false (no API key required).once() and .eventually() to make outcomes deterministicNo! You can use use_api=False to process everything locally. This won't charge credits but also won't include importance ranking.
Queries use operators like role=button, text~"Submit" (contains), importance>500. See the full reference for all operators.
Use wait_for() to wait for elements to appear. Check element visibility with element.in_viewport and element.is_occluded.