v2.22.0
cloudflare/pingorav2.22.0Aug 1, 2026by dsfaccini
AI Summary
This release focuses on enhancing AI agent capabilities, specifically improving tool management, Temporal workflow durability, and model integration (Anthropic and Gemini). It includes numerous bug fixes for event loops, serialization, and tool validation.
Key Highlights
- Add `RunContext.is_tool_available` to check tool availability dynamically.
- Default Gemini `VALIDATED` tool mode on supported models.
- Send mid-conversation system prompts as native `system` messages on Anthropic.
- Improve Temporal workflow recovery and fix livelocks.
- Support requesting approval or deferring a call from a tool's `args_validator`.
New Features
- Allow `MCPToolset` clients to skip optional MCP tasks via `prefer_tasks`.
- Add configurable `max_retries` to `ToolSearchToolset`.
- Require `genai-prices>=0.1.0` for detailed usage tracking.
- Preserve `SystemPromptPart` semantics across caching and Temporal.
Full Release Notes
<!-- Release notes generated using configuration in .github/release.yml at main --> ## What's Changed ### 🚀 Features * Allow `MCPToolset` clients to skip optional MCP tasks via `prefer_tasks` by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/6851 * Default Gemini `VALIDATED` tool mode on supported models by @hramezani in https://github.com/pydantic/pydantic-ai/pull/6353 * Stop advertising tool search for capability-owned deferred tools on Anthropic by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6770 * Send mid-conversation system prompts as native `system` messages on Anthropic by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6765 * Add `RunContext.is_tool_available` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/7011 ### 🐛 Bug Fixes * Handle closed event loops in synchronous APIs by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/6850 * Compare full origin, not just hostname, when dropping credentials on `safe_download` redirects by @pydanty[bot] in https://github.com/pydantic/pydantic-ai/pull/6811 * Fix Temporal workflow livelock when anyio scope cancellation hits an in-flight activity await by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6892 * Copy `extra_headers` before `setdefault` in OpenAI chat and Groq models by @pydanty[bot] in https://github.com/pydantic/pydantic-ai/pull/6868 * Support requesting approval or deferring a call from a tool's `args_validator` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6897 * Use the workflow-prepared `tool_def` in Temporal function-tool activities instead of re-running `prepare` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6890 * Raise a `UserError` instead of hanging when `run_sync()` is called on an event loop it cannot drive by @DouweM in https://github.com/pydantic/pydantic-ai/pull/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 https://github.com/pydantic/pydantic-ai/pull/6944 * Run `after_tool_validate` when an `args_validator` defers the call by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6961 * Preserve the host's Logfire configuration in the Temporal `LogfirePlugin` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6962 * Fail the workflow instead of retrying forever when a Temporal activity argument can't be serialized by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6893 * Install the `EnqueueGuard` on the DBOS/Prefect model-request and `cancel_suspended_response` units by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6943 * Restore typed values in a dynamic tool's Temporal `ActivityConfig` after the activity round trip by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6947 * Reject unregistered `Model` instances in durable runs instead of re-inferring them from `model_id` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6898 * Heartbeat in tool, MCP, dynamic-toolset, and event-stream Temporal activities by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6965 * Rehydrate `set`s, carry `conversation_id`, and hard-error on omitted fields in `TemporalRunContext` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6891 * Allow `ApprovalRequired`/`CallDeferred` from post-validation tool hooks, `UserError` from pre-validation ones by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6951 * Raise a `UserError` when a history processor or `fallback_on` handler has unresolvable type annotations by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6958 * Raise `ModelAPIError` for OpenRouter responses with null choices and no error envelope by @ZacharyHampton in https://github.com/pydantic/pydantic-ai/pull/6901 * Inline every `$ref` to a union `$def`, not just the first one by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6960 * Reject unknown `ActivityConfig` keys in `TemporalDurability` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6964 * Honor per-tool `TaskConfig` on Prefect MCP tools and add `PydanticUserError` to its non-retryable set by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6952 * Pass the unprepared request to the wrapped model in `InstrumentedModel` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6982 * fix(mcp): inherit agent retries in `MCPToolset.tool_for_tool_def` by @hramezani in https://github.com/pydantic/pydantic-ai/pull/6449 * Fail the workflow on `HookTimeoutError` and `FallbackExceptionGroup` instead of retrying forever by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6978 * Keep thinking alive by not forcing `tool_choice` on OpenRouter `anthropic/` models by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6957 * Add configurable `max_retries` to `ToolSearchToolset` by @pydanty[bot] in https://github.com/pydantic/pydantic-ai/pull/6740 * Fix Temporal `ActivityConfig` validation on Python 3.10 and 3.11 by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6989 * Pass `pydantic_graph` through Temporal workflow sandboxes by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6990 * Memoize Temporal payload `TypeAdapter`s by @DouweM in https://github.com/pydantic/pydantic-ai/pull/7001 * Preserve `SystemPromptPart` semantics across caching and Temporal by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/6984 ### 📦 Dependencies * Require `genai-prices>=0.1.0` for detailed usage by @alexmojaki in https://github.com/pydantic/pydantic-ai/pull/6933 * Declare `anyio` as a direct dependency of `pydantic-ai-slim` and `pydantic-graph` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/7008 ## New Contributors * @ZacharyHampton made their first contribution in https://github.com/pydantic/pydantic-ai/pull/6901 * @vgrozdanic made their first contribution in https://github.com/pydantic/pydantic-ai/pull/6942 * @rscholz98 made their first contribution in https://github.com/pydantic/pydantic-ai/pull/6858 **Full Changelog**: https://github.com/pydantic/pydantic-ai/compare/v2.21.0...v2.22.0