A structured trace schema for AI-agent browser sessions. Built for two things existing tools don't do well:
- Replay an agent run step-by-step without re-running it.
- Classify failures — distinguish "agent made wrong decision" from "site changed" from "antibot blocked us" from "credentials wrong."
Playwright trace shows you what the browser did. browser-use logs show you what the agent said. Neither tells you, in aggregate across 10,000 runs, what fraction failed because of Cloudflare Turnstile vs. because of stale selectors vs. because of bad credentials. This schema does.
Status: v0.1 — schema is unstable until v1. API is small and unlikely to change much, but breaking changes allowed.
pip install agent-traceOr from source:
git clone https://github.com/gotcs108/agent-trace.git
cd agent-trace && pip install -e .from agent_trace import Tracer
with Tracer(task="Log in and fetch invoice",
model="claude-opus-4-7",
browser="playwright") as t:
t.step("Navigate to login page")
t.nav("about:blank", "https://example.com/login", trigger="user")
t.step("Fill credentials")
t.type("input#email", "user@example.com")
t.type("input#password", "***", redact=True)
t.step("Submit form")
t.login_attempt(provider="form")
t.submit("form#login")
t.login_failed(reason="invalid_credentials",
evidence="Page contains 'Invalid email or password'")
t.end(status="failed", reason="login_failed_invalid_credentials")Replay it:
agent-trace traces/<session-id>.jsonlOutput:
Session a3f1...
Task: Log in and fetch invoice
Agent: claude / claude-opus-4-7
Browser: playwright
Status: failed (login_failed_invalid_credentials)
Steps:
[0] Navigate to login page
· nav: about:blank → https://example.com/login (user)
→ ok in 142ms
[1] Fill credentials
· type: input#email = 'user@example.com'
· type: input#password = <redacted>
→ ok in 53ms
[2] Submit form
· login_attempt: form
· submit: form#login
· LOGIN_FAILED: invalid_credentials — Page contains 'Invalid email...'
→ error in 1240ms
Totals:
steps=3 errors=0 antibot_events=0
Production agent runs fail in maybe a dozen distinct ways. If you only have free-text logs you can't tell, after the fact, which way this run failed — let alone what the failure mix looks like across the last 10k runs. Without that, your bug bash is undirected.
This schema enforces an enum on the failure mode at the session level (session_end.reason), with first-class events for the specific signals that drive each mode (antibot detection vendor, MFA prompt type, login failure reason, etc.). Tail the JSONL, group-by, and you have observability.
It's not a replacement for playwright trace or OpenTelemetry — it sits above both. A trace can reference a playwright-trace.zip as an artifact; an OTel exporter is a v1 candidate.
See SPEC.md for full event taxonomy. Highlights:
- Agent reasoning —
step_start,step_end,llm_call(with cached-token accounting) - Browser actions —
nav,click,type(withredact=Truefor passwords),submit,extract,screenshot,dom_snapshot - Failure-mode events —
antibot_detected(with vendor enum),login_attempt/success/failed,mfa_prompt/submitted - Errors — typed (
timeout/selector_not_found/agent_decision/ etc.) with recoverable flag
examples/01_invalid_credentials.py — login rejected on bad password.
examples/02_antibot_block.py — Cloudflare Turnstile blocks page load.
python examples/01_invalid_credentials.py
agent-trace traces/<the-printed-session-id>.jsonlCurrently Tracer is manually wired into your agent loop. Adapters for browser-use, Playwright, and Stagehand are queued — see ROADMAP.md. PRs welcome.
MIT.
Issues and PRs welcome. If you're hitting a failure mode the schema can't represent, that's the most useful thing to file — schema gaps are the whole point of v0.
See ROADMAP.md for what's queued.