Pydantic AI
Build provider-agnostic, typed Python browser agents with dependency injection.
Pydantic AI is the Pydantic team's agent framework. It's provider-agnostic and reuses the Pydantic models you'd already validate API I/O with for tool arguments and final outputs, so adding an agent to a typed Python codebase doesn't introduce a parallel schema layer. The Steel integration passes a Playwright Page through RunContext.deps, so every tool in an agent run sees the same cloud browser without module globals.
Requirements
- Steel API Key: Active Steel subscription
- Model provider key: OpenAI, Anthropic, Google, or any other Pydantic AI-supported provider
- Python: 3.10+
Connect Steel to Pydantic AI
Define a BrowserDeps dataclass holding the Steel-backed Playwright Page, register tools that read ctx.deps.page, and pass deps= to agent.run:
Python
from dataclasses import dataclassfrom playwright.async_api import Page, async_playwrightfrom pydantic_ai import Agent, RunContextfrom steel import Steel@dataclassclass BrowserDeps:page: Pageasync def navigate(ctx: RunContext[BrowserDeps], url: str) -> dict:"""Navigate to a URL and wait for the page to load."""await ctx.deps.page.goto(url, wait_until="domcontentloaded")return {"url": ctx.deps.page.url, "title": await ctx.deps.page.title()}agent = Agent("openai:gpt-5-mini",deps_type=BrowserDeps,tools=[navigate],)steel = Steel(steel_api_key=STEEL_API_KEY)session = steel.sessions.create()playwright = await async_playwright().start()browser = await playwright.chromium.connect_over_cdp(f"{session.websocket_url}&apiKey={STEEL_API_KEY}")page = browser.contexts[0].pages[0]result = await agent.run("Open example.com and report the title.", deps=BrowserDeps(page=page))
Full runnable starter: Steel + Pydantic AI recipe →
Resources
- Pydantic AI documentation – Agents, tools, output validators, retries, and Logfire integration
- Steel Sessions API reference – Programmatic session control for Steel browsers
- Steel Discord – Get help and share what you build