v2.53.0
pydantic/pydantic-aiv2.53.0Oct 2, 2026by dsfaccini
Upgrading?
AI Summary
This release prioritizes security by fixing a critical concurrency issue in `ConcurrencyLimitedModel`. It adds new capabilities like `ToolCallJudge` and `SystemOneModel`, extends harness durability options, and improves JSON schema support.
Key Highlights
- Fixed high-severity concurrency security vulnerability (GHSA-6fqq-452j-qhrp).
- Added `ToolCallJudge` to assess tool calls before execution.
- Added `SystemOneModel` for running decision models over the `/v1/systemone` API.
- Added `AbsurdDurability` to the harness as a replacement for `pydantic-ai-absurd`.
- Added `oneOf` schema support to `TestModel`'s generated data.
Breaking Changes
- `ConcurrencyLimiter.acquire()` now takes a slot on every call, even on the same task.
- `ConcurrencyLimiter` now raises `UserError` when sharing a limiter with the agent or enclosing wrapper.
New Features
- `ToolCallJudge`
- `SystemOneModel`
- `AbsurdDurability`
- `AskUser` deferral to host and timeout support
- Exposed message-history repair pipeline as `repair_messages`
Full Release Notes
<!-- Release notes generated using configuration in .github/release.yml at main --> ### 🛡️ Security This release fixes one security issue in `ConcurrencyLimitedModel`. See the advisory for full details and affected versions. - **[GHSA-6fqq-452j-qhrp](https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-6fqq-452j-qhrp)** (high): a streamed request through `ConcurrencyLimitedModel` or `limit_model_concurrency` could keep its concurrency slot when the slot was released on a different task than the one that acquired it: after an early exit (the consumer stopped iterating, raised, or was cancelled), and also after fully consuming `stream_text()` with its default debouncing. Repeated streams could then block every request sharing the limiter. Agent-level `max_concurrency` and non-streaming requests are not affected. Reported by @lche511. (#9478) The fix also changes how limiters are shared: a model wrapper now raises `UserError` when it shares a limiter with the agent making the request or with an enclosing model wrapper, `ConcurrencyLimiter.acquire()` takes a slot on every call, even on the same task, and a custom `AbstractConcurrencyLimiter` must allow `release()` from another task. Patched in `2.53.0`. v1 is not affected. ## What's Changed ### ⚠️ Compatibility Notes * Add `oneOf` schema support to `TestModel`'s generated data by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/8783 * Deprecate `pydantic_ai_harness.step_persistence.naming` by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/9499 ### 🚀 Features * Count Google grounding web search queries in `usage` by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/8891 * Add `AbsurdDurability` to the harness as a replacement for `pydantic-ai-absurd` by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/8946 * Let `AskUser` defer questions to the host and time out a slow answerer by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/9509 * Add `SystemOneModel` to run decision models such as CLM and Laya over the `/v1/systemone` API by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/8942 * Add `ToolCallJudge` to assess tool calls before execution by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9041 * Send images and documents from GPT-Live tool results to the delegated backend by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9048 * Expose the message-history repair pipeline as `repair_messages` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8370 ### 🐛 Bug Fixes * Kill the process group when a `LocalWorkspaceBackend.run` timeout fires during process startup by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/9358 * Avoid invalid-escape warning floods during `CodeMode` analysis by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/9475 * Keep the registered `Memory` toolset across runs so durable execution accepts it by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/9489 * Keep the registered `Planning` toolset across runs so durable execution accepts it by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/9507 * Keep planted files from escaping `BubblewrapSandbox` on the next launch by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/9457 * Render non-finite eval metrics as `inf`/`-inf`/`nan` by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/8852 * Snap `gemini-3.1-flash-image` thinking efforts to `minimal` and `high` on the Gemini API by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/9515 * Raise `UnexpectedModelBehavior` instead of running the wrong tool when function tool calls share a `tool_call_id` by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/8782 * Build one streamed `XaiModel` thinking part per output, matching the non-streamed response by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9416 * Leave image generation calls out of the `OpenAIResponsesModel` replay when `openai_store=False` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9388 * Build the same `ModelResponse` from streamed and complete `OpenAIChatModel` and `OpenRouterModel` responses by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9418 * Make `OpenAIResponsesModel` build the same `ModelResponse` from a stream as from a complete response by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9417 * Make xAI push-to-talk reply only when asked: `commit_audio()` alone no longer triggers a reply, and `create_response()` is always answered by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9070 * Tolerate OpenAI realtime `status`, `status_details` and session values the SDK does not know yet by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9392 * Stop `SubAgents` from forcing `thinking` on disk agents by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9384 * Restore `DynamicWorkflow` reveal announcements after compaction or history loss by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9371 * Make Logfire Temporal spans replay-safe by @DouweM in https://github.com/pydantic/pydantic-ai/pull/7006 * Allow unschemable types in the derived Temporal `ActivityConfig` schema by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9577 * Let `GoogleRealtimeModel` declare tools whose `dict` values are recursive models by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/9607 ## New Contributors * @Poojita060926 made their first contribution in https://github.com/pydantic/pydantic-ai/pull/8900 **Full Changelog**: https://github.com/pydantic/pydantic-ai/compare/v2.52.0...v2.53.0
Related Repositories
public-apis/public-apis★ 491,192
A collective list of free APIs
NousResearch/hermes-agent★ 256,049
The agent that grows with you
yt-dlp/yt-dlp★ 200,221
A feature-rich command-line audio/video downloader
microsoft/markitdown★ 191,544
Python tool for converting files and office documents to Markdown.
Significant-Gravitas/AutoGPT★ 187,700
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.