Browser Automation + /improve: AI Agents That Browse the Web and Fix Themselves
Table of Contents
For three months my AI agent searched GitHub for the wrong query every single session.
Search “pydantic”, zero results. Search “pydantic-ai”, forty-seven results. Click the right repo. Every session, same wasted first query, because the agent forgot the lesson at session end.
This week I shipped the fix in pydantic-deep v0.3.4, along with browser automation in v0.3.5. Combined with StuckLoopDetection, context window warnings, curl install, and Docker sandbox shipped earlier this week, the two together changed what an AI agent actually is for me.
pydantic-deep is the modular agent runtime for Python. An agent that can’t see the web is limited to what it already knows and what’s in your codebase. An agent that doesn’t learn from its sessions resets to zero every run. Both limitations are solvable, and in pydantic-deep v0.3.5 and v0.3.4, we solved them.
Part 1: BrowserCapability
Installation
pip install 'pydantic-deep[browser]'playwright install chromiumThe 9 Tools
from pydantic_deep.capabilities import BrowserCapability
agent = create_deep_agent( model="anthropic:claude-opus-4-6", extra_capabilities=[BrowserCapability( allowed_domains=["github.com", "docs.python.org"], auto_screenshot=True, headless=False, # visible window by default )])| Tool | What it does |
|---|---|
navigate(url) | Navigate to URL, returns content + optional screenshot |
click(selector) | Click element by CSS selector |
type_text(selector, text) | Type into input field |
get_text(selector) | Extract text from element |
screenshot() | Capture current page state |
scroll(direction, amount) | Scroll page up/down |
go_back() | Browser back |
go_forward() | Browser forward |
execute_js(script) | Run arbitrary JavaScript |
Every tool returns a BrowseResult: url, title, content, screenshot, error.
Safety Design
Single-tab. One tab at a time, deliberate, not a limitation. Multiple tabs would require the agent to track tab context, adding state complexity and failure modes.
Domain allowlist. The agent can only navigate to explicitly allowed domains. Attempts to navigate elsewhere return an error.
Automatic popup interception. Cookie banners, login dialogs, subscription prompts, intercepted automatically.
Content truncation. Page content is truncated before being passed to the model, preventing context overflow from large pages.
Browser Lifecycle
The browser doesn’t start lazily on first navigate, it starts before the agent run and is guaranteed to close after it ends:
# Lifecycle via wrap_run pattern:# Chromium starts → agent runs → Chromium stops# Guaranteed on: success / exception / cancellationNo orphaned browser processes regardless of how the run ends.
CLI flags:
pydantic-deep tui --browser # enable browser (disabled by default)pydantic-deep tui --browser --browser-headless # no window (for CI)pydantic-deep tui --browser --browser-headed # visible window (default)
# Combine with Docker sandboxpydantic-deep run "research competitors on GitHub" \ --browser \ --sandbox dockerBug Fix: No Approval Dialogs
Browser tools now force kind='function' in prepare_tools, they’re always treated as regular tool calls, never as actions requiring human confirmation. An approval dialog on a screenshot() call mid-task breaks automation entirely.
Use Cases
Research tasks: Navigate, read, extract, without pre-fetching anything manually.
Competitor monitoring: Check pricing pages, changelogs, star counts. Combine with /improve and the agent builds memory of what it found last time.
Documentation lookups: Read the actual current docs, not training data. Especially useful when working with libraries that change frequently.
UI testing: Interact with your app like a user. click, type_text, screenshot, the basics of any E2E flow.
JS-dependent scraping: execute_js("document.querySelectorAll('.price').map(e => e.textContent)"), for data that only exists after JavaScript renders it.
Part 2: /improve, The Self-Improvement Loop
What /improve Does
After an agent session, run /improve in the TUI. It analyzes the full session and extracts two categories of insights:
UserFactInsight, what the agent learned about you and your preferences:
- Code style preferences
- Preferred output formats
- Domain-specific terminology
- Patterns in the kinds of tasks you give it
AgentLearningInsight, patterns and strategies the agent discovered:
- Approaches that worked for your codebase
- Effective tool call sequences
- Failure modes encountered and how they were recovered
- Constraints or peculiarities of your project setup
Both types write to MEMORY.md, loaded at the start of every subsequent session.
The Meta-Harness Finding: Raw Traces >> Summaries
This was the key insight from our internal evaluation:
When building the /improve pipeline, we compared two inputs to the synthesis step:
- Human-readable summaries of what happened
- Raw tool traces, the actual sequence of tool calls and responses
Raw traces performed significantly better. Summaries lose the failure/recovery patterns that contain the actual learning signal. “The agent tried X, failed, then tried Y, which worked” becomes “the agent solved the problem” in a summary, but the learning is in the failure/recovery.
The tool_log.jsonl file (written per session) captures the full tool trace. /improve reads this directly.
The /improve Pipeline
Session runs ↓tool_log.jsonl written (raw tool traces) ↓/improve triggered ↓LLM analyzes raw traces ↓Extracts UserFactInsight + AgentLearningInsight ↓Writes to MEMORY.md ↓Next session loads MEMORY.md ↓Agent starts with accumulated contextWhat Was Fixed in v0.3.4
- Crash on
{}in prompt templates - Silent failures (appeared to run, wrote nothing)
- Wrong model being used
- MEMORY.md path mismatch (writing to different location than where agent loaded from)
Also: /config TUI command, view and edit config.toml without leaving the interface.
The Complete Loop
After this week, the full capability stack:
- Agent detects stuck loops (StuckLoopDetection)
- Agent knows when context is running out (LimitWarnerCapability)
- Agent installs in 30 seconds (curl install)
- Agent runs in isolated Docker (Docker sandbox)
- Agent can browse the web (BrowserCapability)
- Agent learns from every session (/improve)
An agent that browses the web and accumulates session insights is qualitatively different from one that doesn’t. Not because the model changed, because the context of how it works with your specific codebase and preferences is growing.
Want This in a Full-Stack App?
If you want to embed pydantic-deep’s capabilities into a production application, API, frontend, auth, deployment, check the full-stack-ai-agent-template. Zero to production AI app in 30 minutes: FastAPI + Next.js + 75+ configuration options.
Key Takeaways
- BrowserCapability: 9 Playwright tools,
pip install 'pydantic-deep[browser]' - Safety: single-tab, domain allowlist, popup interception, content truncation
- Browser lifecycle via
wrap_run, guaranteed cleanup on success/failure/cancel - /improve extracts
UserFactInsight+AgentLearningInsight→ MEMORY.md - Raw tool traces (not summaries) are the right input for session synthesis, clearer, more specific, more actionable
- Combine browser + /improve: agent researches and remembers what it found
GitHub: https://github.com/vstorm-co/pydantic-deep Full-stack template: https://github.com/vstorm-co/full-stack-fastapi-nextjs-llm-template OSS Portal: https://oss.vstorm.co