🛡️ Security
This release fixes one security issue in web_fetch. See the advisory for full details and affected versions.
- GHSA-v36g-jcw9-x7cw (moderate): converting attacker-controlled HTML with deeply nested elements in the local
web_fetchtool 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 and CLAI 2
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. pydantic-clai2 0.52.0 is its first release: uvx pydantic-clai2.
What's Changed
⚠️ Compatibility Notes
- Run harness capabilities in any workspace:
Coder,FileSystem,Shelland the rest work throughctx.workspace, locally or in a sandbox by @adtyavrdhn in #8866 - Replace
ModalSandbox's own tools with a Modal workspace, soCoder,ShellandFileSystemrun in the sandbox;ModalSandboxBackendreplacesModalSandboxSessionby @adtyavrdhn in #8867 - Raise
AnthropicModel's defaultmax_tokensfrom 4096 to 16384 on Claude Sonnet 4.5 and later by @DouweM in #9025 - Keep the prompt as a
DecisionModel's judgedtextafter a retry by @dsfaccini in #8967 - Stop
SubAgentsloading agent files by default, and deprecateinherit_toolsby @DouweM in #9023 - Default
AnthropicModel'smax_tokensto the model's maximum output, streaming such requests behind the scenes by @DouweM in #9298
🚀 Features
- Add workspaces:
ctx.workspacegives tools one API for files and commands, on your machine or in a sandbox, with durable execution support by @adtyavrdhn in #6492 - Add
SpritesSandbox: a workspace that runsCoder,Shell,FileSystemand every other harness capability in a Fly.io Sprite by @adtyavrdhn in #8869 - Add
E2BSandbox: a workspace that runsCoder,Shell,FileSystemand every other harness capability in an E2B sandbox by @adtyavrdhn in #8868 - Give
Coderfile tools a retry budget of 5 and keep scratch files out of the project by @mpfaffenberger in #8970 - Add a
typesafeextra topydantic-clai2and reject models with a missing provider SDK at/modeltime by @mpfaffenberger in #8962 - Add Claude Sonnet 5.5 (
claude-sonnet-5-5) support by @dsfaccini in #8974 - Model realtime async tool calls as a profile
async_tool_call_modewith a sharedasync_tool_callssetting by @DouweM in #8813 - Show tool-call arguments in
pydantic-clai2tool headers, clipped bydisplay.tool_arg_charsby @mpfaffenberger in #9100 - Open a
clai2plugin's settings menu when it is turned on, and end every settings menu with Save & close by @mpfaffenberger in #9102 - Add
_process_provider_detailshook toOpenAIResponsesModelby @pydanty in #9094 - Add
clai2 --agent MODULE:ATTRto chat with an existingAgentwith plugins off by @mpfaffenberger in #9291 - Add a built-in
githubplugin toclai2with a settings menu and its token in/keysby @mpfaffenberger in #8904 - Add a built-in
pylonplugin to CLAI2 with a settings menu and a named/keysentry by @mpfaffenberger in #8953 - Seed retained user audio on Gemini
gemini-3.1-flash-live-previewandgemini-3.8-liveby @DouweM in #9047 - Support browser WebRTC on OpenAI GPT-Live with
answer_webrtc_offerand a sideband session by @DouweM in #9059 - Add
SSHWorkspaceandBubblewrapSandboxharness capabilities by @mpfaffenberger in #8956 - Add a
pydantic-clai2console script souvx pydantic-clai2runs CLAI by @mpfaffenberger in #9304 - Add
azure_voice_live_voiceto choose an Azure voice for Azure AI Voice Live sessions by @DouweM in #9044 - Add
google_workspaceas a built-inclai2plugin backed by harnessGoogleWorkspaceby @mpfaffenberger in #8907 - Apply
thinking,openai_turn_detection,openai_input_noise_reductionand a newazure_voice_live_temperatureon Azure AI Voice Live by @DouweM in #9051 - Seed tool calls and results as native function parts on Gemini
gemini-3.8-liveby @DouweM in #9058 - Emit identified response, turn, and input lifecycle events from the OpenAI-protocol realtime connection by @DouweM in #9064
- Add a built-in
day_aiplugin toclai2with a settings menu and/keysor browser sign-in by @mpfaffenberger in #8940 - Warn on unexpected
RequestUsage.extract()failures by @adtyavrdhn in #8564 - Add a built-in
ordinalplugin toclai2with token or keyring-backed browser sign-in by @mpfaffenberger in #8941 - feat(profiles):
default_cache_retention+prompt_cache_outlook()cold-window helper; renameresolve_prompt_cache_retention()toresolve_cache_retention()by @DouweM in #6337 - Add a built-in
notionplugin toclai2with a settings menu and its key in/keysby @mpfaffenberger in #8944 - Deliver images and text files returned from tools on Gemini 3.x Live by @DouweM in #9065
- Map the shared
thinkingandparallel_tool_callssettings to the GPT-Live backend model by @DouweM in #9040 - Accept
mxfp4,nvfp4, andmxfp8OpenRouterquantizationsand theexactosortvalue by @harimaruthachalam in #8888 - Add a built-in
slackplugin topydantic-clai2with a settings menu,/keysuser token, or browser sign-in by @mpfaffenberger in #8908 - Add a
logfire_mcpbuilt-in plugin toclai2with/keys,LOGFIRE_API_KEY, and keyring-backed OAuth by @mpfaffenberger in #8903 - Add OpenAI
gpt-6.1-solmodel support and allow image output ongpt-6-astraby @dsfaccini in #9305
🐛 Bug Fixes
- Record realtime user turns in speaking order under push-to-talk, barge-in, and with input transcription off by @DouweM in #8764
- Stop tool docstring parsing from changing the root logger level by @adtyavrdhn in #8872
- Treat
application/tomlas text-like for inline model inputs by @JoeyTan21 in #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 #8765 - Move tool-forcing and thinking-default profile flags to
ModelProfileso they apply on every provider route by @DouweM in #8808 - Stop Gemini Live tool rounds reporting
RealtimeTurnCompleteEventbefore the spoken answer by @DouweM in #8766 - Don't force output tools on Anthropic requests that think, so Claude keeps thinking with a structured
output_typeby @DouweM in #8812 - Truncate the provider's copy of a realtime reply the user cut off after it finished generating by @DouweM in #8757
- Leave room for the extended thinking budget in Anthropic's default
max_tokensby @DouweM in #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.createby @DouweM in #8763 - Keep a realtime microphone task alive across a reconnect by dropping audio sent while the link is re-dialed by @DouweM in #8806
- Raise
UserErrorinstead ofModelRetryforMacroscopesetup failures by @DouweM in #8999 - Give the first stage of a Playwright operation its full configured budget by @DouweM in #9029
- Make workspace concurrency deadlines robust under load by @DouweM in #9043
- Report OpenAI native web searches in
RequestUsage.detailsand price them incostby @dltsum in #8310 - Stop blank lines and "settings unchanged" notices after closing
clai2menus by @mpfaffenberger in #9101 - Terminate
!commandshell descendants on cancellation inclai2by @dafyy321-pixel in #9092 - Quiet missing plugin modules and
UserWarnings inclai2, and groupCodeModemissing-return-schema warnings by @mpfaffenberger in #9099 - Handle Ctrl-C during
clai2shell process startup by @DouweM in #9104 - Apply model concurrency limits to
compact_messages()by @yang0228 in #8241 - Keep Up/Down on prompt history when
clai2recalls a slash command by @mpfaffenberger in #9297 - Allow
azure_voice_live=Trueforgpt-realtime-2models onAzureRealtimeModelby @DouweM in #9050 - Bound the Gemini Live handshake with
handshake_timeoutby @DouweM in #9042 - Allow text output on Vertex
gemini-live-2.5-flashand remove a stale Gemini Live docs claim by @DouweM in #9069 - Emit
DeferredToolRequestsEventin realtime sessions before theHandleDeferredToolCallshandler runs by @DouweM in #9057 - Map OpenAI response JSON decode errors to
ModelAPIErrorby @pydanty in #8846 - Map in-stream error objects to
ModelAPIErrorinOpenAIChatModel,GroqModelandHuggingFaceModelby @DouweM in #9313 - Raise
ModelAPIErrorinstead ofValidationErrorwhen anOpenRouterModelstream drops mid-response by @DouweM in #9312 - Read the
capabilitiesdocs topic fromcapabilities/overview.mdinPydanticAIDocsby @DouweM in #9011 - Apply
FileSystemdefaultread_only_patternsto nested.envand.git/paths by @DouweM in #9021 - Restore
CodeModediscovery announcements after compaction or history loss by @DouweM in #9045 - Keep the original request in the
TrajectoryJudgewindow when the transcript is clamped by @DouweM in #9012 - Raise
ContentFilterErrorfor a thinking-only response refused by the content filter, instead of retrying by @DouweM in #9355 - Sandbox file methods and block sockets without network in
BubblewrapSandboxby @mpfaffenberger in #9349 - Give the current time to the hour in
LogfireMCPinstructions so they stop busting the prompt cache by @mpfaffenberger in #9319 - Raise
ModelAPIErrorwhen the OpenAI Responses API reports a failed response or anerrorstream event by @DouweM in #9321 - Map every
MistralErrorfrom the Mistral SDK toModelHTTPErrororModelAPIErrorby @DouweM in #9307 - Map provider errors from
GoogleModel.count_tokensandXaiModelfile uploads by @DouweM in #9308 - Fix capability audit findings in
ClampOversizedMessages,SubAgents, andStepPersistenceby @DouweM in #9026 - Root union output member
datavalidation errors underresult.dataso retry feedback keeps the failing input by @pydanty in #8669 - Read a
shelljob log deleted mid-read as empty instead of failing the call by @dsfaccini in #9322 - Record Gemini Live
turn_complete_reasonas the realtime response'sfinish_reasonby @DouweM in #9390 - Remove the default ACP
request_limitby @DouweM in #9380 - Report a realtime session's own usage on its span, not a carried total by @DouweM in #9389
- Count separately budgeted
SubAgentusage toward parent budgets by @DouweM in #9374
📦 Dependencies
- Bump the python-packages group across 1 directory with 14 updates by @dependabot[bot] in #9076
New Contributors
- @JoeyTan21 made their first contribution in #8848
- @dltsum made their first contribution in #8310
- @Jinzhengxu made their first contribution in #8567
- @dafyy321-pixel made their first contribution in #9092
- @yang0228 made their first contribution in #8241
- @harimaruthachalam made their first contribution in #8888
Full Changelog: v2.51.0...v2.52.0