v2.52.0
pydantic/pydantic-aiv2.52.0Sep 30, 2026by dsfaccini
Upgrading?
AI Summary
This release introduces the concept of 'Workspaces' for unified file and command execution, bundles `pydantic-ai-harness` into the main repository, and adds support for new sandbox environments and AI models.
Key Highlights
- Fixed moderate security vulnerability in `web_fetch` (GHSA-v36g-jcw9-x7cw).
- `pydantic-ai-harness` now lives in this repository and ships with every release.
- Introduced `ctx.workspace` for tools to access files and commands locally or in a sandbox.
- Added `SpritesSandbox` and `E2BSandbox` for running harness capabilities.
- Added `SSHWorkspace` and `BubblewrapSandbox` harness capabilities.
Breaking Changes
- `pydantic-ai-harness` version jumps from 0.36.0 to 0.52.0 (bundled).
- `ModalSandbox`'s tools replaced by a Modal workspace.
- `SubAgents` no longer loads agent files by default.
- `inherit_tools` is deprecated.
- `AnthropicModel` default `max_tokens` raised from 4096 to 16384 for newer models.
New Features
- Workspaces (`ctx.workspace`)
- `SpritesSandbox` and `E2BSandbox`
- `SSHWorkspace` and `BubblewrapSandbox`
- Azure AI Voice Live support
- OpenAI `gpt-6.1-sol` model support
- Browser WebRTC support on OpenAI GPT-Live
Full Release Notes
### 🛡️ Security This release fixes one security issue in `web_fetch`. See the advisory for full details and affected versions. - **[GHSA-v36g-jcw9-x7cw](https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-v36g-jcw9-x7cw)** (moderate): converting attacker-controlled HTML with deeply nested elements in the local `web_fetch` tool could consume excessive CPU and memory. Provider-native web fetching is not affected. Reported by @SounLabs. (#8984) Patched in `2.52.0` (v2) and `1.107.7` (v1). ### 📦 Harness `pydantic-ai-harness` now lives in this repository and ships with every Pydantic AI release, so it jumps from `0.36.0` to `0.52.0`. ## What's Changed ### ⚠️ Compatibility Notes * Run harness capabilities in any workspace: `Coder`, `FileSystem`, `Shell` and the rest work through `ctx.workspace`, locally or in a sandbox by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/8866 * Replace `ModalSandbox`'s own tools with a Modal workspace, so `Coder`, `Shell` and `FileSystem` run in the sandbox; `ModalSandboxBackend` replaces `ModalSandboxSession` by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/8867 * Raise `AnthropicModel`'s default `max_tokens` from 4096 to 16384 on Claude Sonnet 4.5 and later by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9025 * Keep the prompt as a `DecisionModel`'s judged `text` after a retry by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/8967 * Stop `SubAgents` loading agent files by default, and deprecate `inherit_tools` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9023 * Default `AnthropicModel`'s `max_tokens` to the model's maximum output, streaming such requests behind the scenes by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9298 ### 🚀 Features * Add workspaces: `ctx.workspace` gives tools one API for files and commands, on your machine or in a sandbox, with durable execution support by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/6492 * Add `SpritesSandbox`: a workspace that runs `Coder`, `Shell`, `FileSystem` and every other harness capability in a Fly.io Sprite by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/8869 * Add `E2BSandbox`: a workspace that runs `Coder`, `Shell`, `FileSystem` and every other harness capability in an E2B sandbox by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/8868 * Give `Coder` file tools a retry budget of 5 and keep scratch files out of the project by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/8970 * Add Claude Sonnet 5.5 (`claude-sonnet-5-5`) support by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/8974 * Model realtime async tool calls as a profile `async_tool_call_mode` with a shared `async_tool_calls` setting by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8813 * Add `_process_provider_details` hook to `OpenAIResponsesModel` by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9094 * Seed retained user audio on Gemini `gemini-3.1-flash-live-preview` and `gemini-3.8-live` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9047 * Support browser WebRTC on OpenAI GPT-Live with `answer_webrtc_offer` and a sideband session by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9059 * Add `SSHWorkspace` and `BubblewrapSandbox` harness capabilities by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/8956 * Add `azure_voice_live_voice` to choose an Azure voice for Azure AI Voice Live sessions by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9044 * Apply `thinking`, `openai_turn_detection`, `openai_input_noise_reduction` and a new `azure_voice_live_temperature` on Azure AI Voice Live by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9051 * Seed tool calls and results as native function parts on Gemini `gemini-3.8-live` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9058 * Emit identified response, turn, and input lifecycle events from the OpenAI-protocol realtime connection by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9064 * Warn on unexpected `RequestUsage.extract()` failures by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/8564 * feat(profiles): `default_cache_retention` + `prompt_cache_outlook()` cold-window helper; rename `resolve_prompt_cache_retention()` to `resolve_cache_retention()` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6337 * Deliver images and text files returned from tools on Gemini 3.x Live by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9065 * Map the shared `thinking` and `parallel_tool_calls` settings to the GPT-Live backend model by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9040 * Accept `mxfp4`, `nvfp4`, and `mxfp8` OpenRouter `quantizations` and the `exacto` `sort` value by @harimaruthachalam in https://github.com/pydantic/pydantic-ai/pull/8888 * Add OpenAI `gpt-6.1-sol` model support and allow image output on `gpt-6-astra` by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/9305 ### 🐛 Bug Fixes * Record realtime user turns in speaking order under push-to-talk, barge-in, and with input transcription off by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8764 * Stop tool docstring parsing from changing the root logger level by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/8872 * Treat `application/toml` as text-like for inline model inputs by @JoeyTan21 in https://github.com/pydantic/pydantic-ai/pull/8848 * Ask for one answer per batch of parallel realtime tool results, and stop `wait_for_reply()` hanging on merged or failed replies by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8765 * Move tool-forcing and thinking-default profile flags to `ModelProfile` so they apply on every provider route by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8808 * Stop Gemini Live tool rounds reporting `RealtimeTurnCompleteEvent` before the spoken answer by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8766 * Don't force output tools on Anthropic requests that think, so Claude keeps thinking with a structured `output_type` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8812 * Truncate the provider's copy of a realtime reply the user cut off after it finished generating by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8757 * Leave room for the extended thinking budget in Anthropic's default `max_tokens` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8986 * Settle Gemini tool calls and 2.5 typed turns a resumed realtime session lost, and stop OpenAI-protocol reconnects re-requesting a failed `response.create` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8763 * Keep a realtime microphone task alive across a reconnect by dropping audio sent while the link is re-dialed by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8806 * Raise `UserError` instead of `ModelRetry` for `Macroscope` setup failures by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8999 * Give the first stage of a Playwright operation its full configured budget by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9029 * Make workspace concurrency deadlines robust under load by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9043 * Report OpenAI native web searches in `RequestUsage.details` and price them in `cost` by @dltsum in https://github.com/pydantic/pydantic-ai/pull/8310 * Apply model concurrency limits to `compact_messages()` by @yang0228 in https://github.com/pydantic/pydantic-ai/pull/8241 * Allow `azure_voice_live=True` for `gpt-realtime-2` models on `AzureRealtimeModel` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9050 * Bound the Gemini Live handshake with `handshake_timeout` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9042 * Allow text output on Vertex `gemini-live-2.5-flash` and remove a stale Gemini Live docs claim by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9069 * Emit `DeferredToolRequestsEvent` in realtime sessions before the `HandleDeferredToolCalls` handler runs by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9057 * Map OpenAI response JSON decode errors to `ModelAPIError` by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/8846 * Map in-stream error objects to `ModelAPIError` in `OpenAIChatModel`, `GroqModel` and `HuggingFaceModel` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9313 * Raise `ModelAPIError` instead of `ValidationError` when an `OpenRouterModel` stream drops mid-response by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9312 * Read the `capabilities` docs topic from `capabilities/overview.md` in `PydanticAIDocs` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9011 * Apply `FileSystem` default `read_only_patterns` to nested `.env` and `.git/` paths by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9021 * Restore `CodeMode` discovery announcements after compaction or history loss by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9045 * Keep the original request in the `TrajectoryJudge` window when the transcript is clamped by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9012 * Raise `ContentFilterError` for a thinking-only response refused by the content filter, instead of retrying by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9355 * Sandbox file methods and block sockets without network in `BubblewrapSandbox` by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/9349 * Give the current time to the hour in `LogfireMCP` instructions so they stop busting the prompt cache by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/9319 * Raise `ModelAPIError` when the OpenAI Responses API reports a failed response or an `error` stream event by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9321 * Map every `MistralError` from the Mistral SDK to `ModelHTTPError` or `ModelAPIError` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9307 * Map provider errors from `GoogleModel.count_tokens` and `XaiModel` file uploads by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9308 * Fix capability audit findings in `ClampOversizedMessages`, `SubAgents`, and `StepPersistence` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9026 * Root union output member `data` validation errors under `result.data` so retry feedback keeps the failing input by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/8669 * Read a `shell` job log deleted mid-read as empty instead of failing the call by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/9322 * Record Gemini Live `turn_complete_reason` as the realtime response's `finish_reason` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9390 * Remove the default ACP `request_limit` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9380 * Report a realtime session's own usage on its span, not a carried total by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9389 * Count separately budgeted `SubAgent` usage toward parent budgets by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9374 ### 📦 Dependencies * Bump the python-packages group across 1 directory with 14 updates by @dependabot[bot] in https://github.com/pydantic/pydantic-ai/pull/9076 ## New Contributors * @JoeyTan21 made their first contribution in https://github.com/pydantic/pydantic-ai/pull/8848 * @dltsum made their first contribution in https://github.com/pydantic/pydantic-ai/pull/8310 * @Jinzhengxu made their first contribution in https://github.com/pydantic/pydantic-ai/pull/8567 * @dafyy321-pixel made their first contribution in https://github.com/pydantic/pydantic-ai/pull/9092 * @yang0228 made their first contribution in https://github.com/pydantic/pydantic-ai/pull/8241 * @harimaruthachalam made their first contribution in https://github.com/pydantic/pydantic-ai/pull/8888 **Full Changelog**: https://github.com/pydantic/pydantic-ai/compare/v2.51.0...v2.52.0
Related Repositories
public-apis/public-apis★ 491,312
A collective list of free APIs
NousResearch/hermes-agent★ 256,157
The agent that grows with you
yt-dlp/yt-dlp★ 200,362
A feature-rich command-line audio/video downloader
microsoft/markitdown★ 191,618
Python tool for converting files and office documents to Markdown.
Significant-Gravitas/AutoGPT★ 187,708
AutoGPT is the vision of accessible AI for everyone, to use and to build on. Our mission is to provide the tools, so that you can focus on what matters.