| name | agent-browser |
| description | Use when a task needs the real browser — harvesting the logged-in Learn session, rendering SPA pages (course outlines), capturing quiz pages, or any authenticated web automation. (Assignment submission is NOT here — it uses the raw D2L API; see learn.py submit.) This project standardizes on Vercel agent-browser (CDP CLI); it reuses a logged-in browser session, so no second login. |
agent-browser — the single browser engine for agentic-learn
This project standardizes on Vercel agent-browser (Apache-2.0 CDP CLI) for ALL browser work,
wrapped by .learn/agent_browser.py. It keeps a persistent logged-in browser per session, so we
log in once (WatIAM + Duo) and reuse it. Verified: it harvests the HttpOnly d2lSessionVal +
XSRF.Token and those cookies authenticate the D2L API.
Install: npm install -g agent-browser && agent-browser install.
Use the project wrapper (.learn/agent_browser.py)
PY=.learn/.venv/bin/python
$PY .learn/agent_browser.py auth
$PY .learn/agent_browser.py outlines
$PY .learn/agent_browser.py render <url> [--pdf p]
$PY .learn/agent_browser.py snapshot <url>
Python API: harvest_session(base_url, session_path), render(url, pdf_path=), outlines(),
snapshot(url), available(). All use one persistent session (SESSION="learn").
Raw CLI (when the wrapper doesn't cover it)
agent-browser --session-name learn open --headed <url>
agent-browser --session-name learn get url
agent-browser --session-name learn cookies get
agent-browser --session-name learn storage local get XSRF.Token
agent-browser --session-name learn snapshot
agent-browser --session-name learn find role button "Submit"
agent-browser --session-name learn upload <sel> <file>
agent-browser --session-name learn click @e7
agent-browser --session-name learn pdf out.pdf
agent-browser skills get core --full
What actually works
- Session harvest: open Learn →
cookies get (HttpOnly d2lSessionVal/d2lSecureSessionVal) +
storage local get XSRF.Token. Feed those to requests; the D2L JSON API authenticates. This is
the foundation — the rest of ingestion is the API, not the browser.
- Render session-gated pages (outlines): they render in the same logged-in
learn session.
- Quiz capture / general UI:
snapshot to get refs → find role|text → click. Low context
(compact refs, not screenshots). NOTE: assignment submission is not done here — it's the raw
D2L API in .learn/submit.py (a dropbox submission is one atomic mypost call).
- The persistent session survives across CLI calls (a Rust daemon) — log in once, reuse.
Common mistakes
- Forgetting
--session-name learn: you'd drive a different browser without the login. Always use it.
- Expecting
eval document.cookie to see d2lSessionVal: it's HttpOnly — use cookies get.
- Running
render/outlines before auth: session-gated pages need the logged-in session first.
- Auth wall (ADFS/Duo): the harvest opens
--headed so the user can sign in — never type credentials yourself.
- A failed render returns empty:
agent_browser.render() RAISES on empty output — surface it, don't ignore.