github pydantic/pydantic-ai v2.22.0
v2.22.0 (2026-07-31)

4 hours ago

What's Changed

🚀 Features

  • Allow MCPToolset clients to skip optional MCP tasks via prefer_tasks by @adtyavrdhn in #6851
  • Default Gemini VALIDATED tool mode on supported models by @hramezani in #6353
  • Stop advertising tool search for capability-owned deferred tools on Anthropic by @DouweM in #6770
  • Send mid-conversation system prompts as native system messages on Anthropic by @DouweM in #6765
  • Add RunContext.is_tool_available by @DouweM in #7011

🐛 Bug Fixes

  • Handle closed event loops in synchronous APIs by @adtyavrdhn in #6850
  • Compare full origin, not just hostname, when dropping credentials on safe_download redirects by @pydanty[bot] in #6811
  • Fix Temporal workflow livelock when anyio scope cancellation hits an in-flight activity await by @DouweM in #6892
  • Copy extra_headers before setdefault in OpenAI chat and Groq models by @pydanty[bot] in #6868
  • Support requesting approval or deferring a call from a tool's args_validator by @DouweM in #6897
  • Use the workflow-prepared tool_def in Temporal function-tool activities instead of re-running prepare by @DouweM in #6890
  • Raise a UserError instead of hanging when run_sync() is called on an event loop it cannot drive by @DouweM in #6905
  • Fix Prefect tool-call cache keys: replay tool results on flow retry and stop colliding on RunContext fields a tool can read by @DouweM in #6944
  • Run after_tool_validate when an args_validator defers the call by @DouweM in #6961
  • Preserve the host's Logfire configuration in the Temporal LogfirePlugin by @DouweM in #6962
  • Fail the workflow instead of retrying forever when a Temporal activity argument can't be serialized by @DouweM in #6893
  • Install the EnqueueGuard on the DBOS/Prefect model-request and cancel_suspended_response units by @DouweM in #6943
  • Restore typed values in a dynamic tool's Temporal ActivityConfig after the activity round trip by @DouweM in #6947
  • Reject unregistered Model instances in durable runs instead of re-inferring them from model_id by @DouweM in #6898
  • Heartbeat in tool, MCP, dynamic-toolset, and event-stream Temporal activities by @DouweM in #6965
  • Rehydrate sets, carry conversation_id, and hard-error on omitted fields in TemporalRunContext by @DouweM in #6891
  • Allow ApprovalRequired/CallDeferred from post-validation tool hooks, UserError from pre-validation ones by @DouweM in #6951
  • Raise a UserError when a history processor or fallback_on handler has unresolvable type annotations by @DouweM in #6958
  • Raise ModelAPIError for OpenRouter responses with null choices and no error envelope by @ZacharyHampton in #6901
  • Inline every $ref to a union $def, not just the first one by @DouweM in #6960
  • Reject unknown ActivityConfig keys in TemporalDurability by @DouweM in #6964
  • Honor per-tool TaskConfig on Prefect MCP tools and add PydanticUserError to its non-retryable set by @DouweM in #6952
  • Pass the unprepared request to the wrapped model in InstrumentedModel by @DouweM in #6982
  • fix(mcp): inherit agent retries in MCPToolset.tool_for_tool_def by @hramezani in #6449
  • Fail the workflow on HookTimeoutError and FallbackExceptionGroup instead of retrying forever by @DouweM in #6978
  • Keep thinking alive by not forcing tool_choice on OpenRouter anthropic/ models by @DouweM in #6957
  • Add configurable max_retries to ToolSearchToolset by @pydanty[bot] in #6740
  • Fix Temporal ActivityConfig validation on Python 3.10 and 3.11 by @DouweM in #6989
  • Pass pydantic_graph through Temporal workflow sandboxes by @DouweM in #6990
  • Memoize Temporal payload TypeAdapters by @DouweM in #7001
  • Preserve SystemPromptPart semantics across caching and Temporal by @dsfaccini in #6984

📦 Dependencies

  • Require genai-prices>=0.1.0 for detailed usage by @alexmojaki in #6933
  • Declare anyio as a direct dependency of pydantic-ai-slim and pydantic-graph by @DouweM in #7008

New Contributors

Full Changelog: v2.21.0...v2.22.0

Don't miss a new pydantic-ai release

NewReleases is sending notifications on new releases.