github pydantic/pydantic-ai v2.61.0
v2.61.0 (2026-10-23)

latest release: clai2-bleeding
4 hours ago

What's Changed

⚠️ Compatibility Notes

  • Warn when a provider-specific thinking setting from a broader scope overrides thinking by @dsfaccini in #10231
  • Send the least thinking a model accepts for thinking=False on models that can't turn thinking off by @DouweM in #11036
  • Raise NotImplementedError for a file in a CohereModel tool return instead of dropping it by @dsfaccini in #11114
  • Keep concurrent workspace runs attached to their own Prefect environments by @dsfaccini in #11160
  • Keep bool and int inputs on separate Literal decision branches in pydantic_graph by @dafyy321-pixel in #9091
  • Deprecate google_multi_speaker on GoogleRealtimeModel, which no Gemini Live model supports by @DouweM in #11064
  • Accept async auth functions in the hosted MCP capabilities by @mpfaffenberger in #10835
  • Run the authoring checks in CapabilityStore.load_active and stop overwriting unreadable manifests by @mpfaffenberger in #10731
  • Keep the last valid authored capability on a failed re-author, share the CapabilityStore lock per directory, and let runs cancel authoring by @mpfaffenberger in #10767
  • Reject BrowserUse prohibited lists browser-use would match by exact hostname, and retry when redacted schema keys collide by @mpfaffenberger in #10775
  • Share one LocalStack container inside async with agent:, stop service-list bypasses and aws configure writes to ~/.aws, and cap aws_cli output by @mpfaffenberger in #10828
  • Make InputGuardrail redact the user's own prompt and close fail-open paths in guardrails by @mpfaffenberger in #10841
  • Keep CodeMode(dynamic_catalog=True) discoveries from rewriting the cached prompt by @DouweM in #10906

🚀 Features

  • Accept async auth functions in the hosted MCP capabilities by @mpfaffenberger in #10835
  • Add structured citations to TextPart by @adtyavrdhn in #7434
  • Normalize citations from Bedrock, OpenRouter, and xAI by @adtyavrdhn in #7750
  • Bound background and shell job logs with Shell.max_log_bytes by @mpfaffenberger in #10712
  • Replay citations in message history to the provider that produced them by @adtyavrdhn in #7752
  • Keep citations in the Vercel AI adapter by @adtyavrdhn in #9639
  • Add kimi-k3.1-pro and kimi-k3.1-pro-highspeed model names by @dsfaccini in #11173
  • Accept transport= in create_async_httpx2_client() and give the httpx2 retry transports its pool limits by @DouweM in #11073
  • Add RealtimeClientSecret.webrtc_url, which carries webrtcfilter=on on Azure OpenAI by @DouweM in #11076
  • Warn when a realtime session has capabilities that implement hooks it never calls by @DouweM in #11094
  • Add RealtimeModelProfile.supports_audio_output so text-only realtime models like Gemini's robotics streaming models default to text output by @DouweM in #11102
  • Make the durable engine extension surface public: operation types, ParameterTransports, DurableRunContext and run identity hooks by @DouweM in #11088

🐛 Bug Fixes

  • Keep streamed OpenRouter reasoning that arrives without reasoning_details by @dsfaccini in #11104
  • Raise a UserError instead of an AssertionError for an unconverted response SpeechPart in BedrockConverseModel by @dsfaccini in #11107
  • Raise NotImplementedError for a file in a CohereModel tool return instead of dropping it by @dsfaccini in #11114
  • Detect pydantic-ai-minted Gemini tool-call ids with TOOL_CALL_ID_PREFIX instead of a hardcoded 'pyd_ai_' by @dsfaccini in #11109
  • Keep bool and int inputs on separate Literal decision branches in pydantic_graph by @dafyy321-pixel in #9091
  • Support NativeOutput on every FireworksProvider model by @pydanty in #10157
  • Warn when a provider-specific thinking setting from a broader scope overrides thinking by @dsfaccini in #10231
  • Record the failed status on streamed XaiModel native tool return parts by @dsfaccini in #11105
  • Keep an OpenAIChatModel response with a non-standard finish_reason instead of raising UnexpectedModelBehavior by @dsfaccini in #11119
  • Make InputGuardrail redact the user's own prompt and close fail-open paths in guardrails by @mpfaffenberger in #10841
  • Run the authoring checks in CapabilityStore.load_active and stop overwriting unreadable manifests by @mpfaffenberger in #10731
  • Keep Linear(id=None) uncombined like GitHub(id=None) by @mpfaffenberger in #10813
  • Cancel the Exa runs a cancelled ExaAgent poll leaves behind, and stop retrying Exa errors the model can't fix by @mpfaffenberger in #10840
  • Keep dict key order in histories the step stores reload, so resumed runs keep the prompt cache by @rscholz98 in #11137
  • Start long quote-heavy Shell commands over SSHWorkspaceBackend, and return a command too long to start to the model by @mpfaffenberger in #11004
  • Name the operation in E2BSandbox probe timeouts and validate env and sandbox_timeout at construction by @mpfaffenberger in #10811
  • Rebuild the default ExaSearch and ExaAgent client on a new event loop, and build ExaAgent's once by @mpfaffenberger in #10848
  • Keep the last valid authored capability on a failed re-author, share the CapabilityStore lock per directory, and let runs cancel authoring by @mpfaffenberger in #10767
  • Stop ConversationSearch returning inherited history once per run, and clip excerpts around the matched term by @mpfaffenberger in #10749
  • Reject BrowserUse prohibited lists browser-use would match by exact hostname, and retry when redacted schema keys collide by @mpfaffenberger in #10775
  • Share one LocalStack container inside async with agent:, stop service-list bypasses and aws configure writes to ~/.aws, and cap aws_cli output by @mpfaffenberger in #10828
  • Make InputGuardrail redaction also rewrite the history prompt when the model was sent a copy, and tighten the guardrails docs by @mpfaffenberger in #10852
  • Redact URL-encoded forms of BrowserUse secrets in browse_web results by @mpfaffenberger in #10827
  • Send tool call arguments in HuggingFaceModel message history by @canblmz1 in #11139
  • Carry a sub-agent's RunCancelled across the durable tool-call boundary as a failed tool result by @dsfaccini in #11163
  • Keep concurrent workspace runs attached to their own Prefect environments by @dsfaccini in #11160
  • Store a failed non-streamed XaiModel native tool call as a call part and one return part by @dsfaccini in #11164
  • Stop sending a thinking config to gemini-2.5-flash-image, which rejects it by @DouweM in #11099
  • Point the first-run banner at logfire-cli wizard --task pydantic-ai by @DouweM in #11069
  • Let OpenAIResponsesModel force a tool revealed mid-run on models before GPT-5.6 by @dsfaccini in #10273
  • Keep CodeMode(dynamic_catalog=True) discoveries from rewriting the cached prompt by @DouweM in #10906
  • Leave GPT-Live audio split from its words by a tool call out of history instead of recording an empty SpeechPart by @DouweM in #11159
  • Keep deferred tool entries in place when a defer_loading=True capability is loaded on Anthropic by @DouweM in #11091
  • Send the least thinking a model accepts for thinking=False on models that can't turn thinking off by @DouweM in #11036
  • Deprecate google_multi_speaker on GoogleRealtimeModel, which no Gemini Live model supports by @DouweM in #11064
  • Support hang_up() for Azure OpenAI WebRTC calls by @DouweM in #11075
  • Attach a late GPT-Live WebRTC sideband that is no longer sent session.started by @DouweM in #11115
  • Leave framework-owned __pydantic_ai__ metadata out of sanitize_messages output, as the UI adapters do by @DouweM in #11089

New Contributors

Full Changelog: v2.60.0...v2.61.0

Don't miss a new pydantic-ai release

NewReleases is sending notifications on new releases.