v2.50.0

pydantic/pydantic-aiv2.50.0Sep 25, 2026by DouweM

Upgrading?

AI Summary

The release introduces the `DecisionModel` protocol for routing and expands real-time support for Gemini 3.8, while also exposing OpenAI service tiers and adding durable context detection.

Key Highlights

  • Introduced `DecisionModel` base class and `TypeSafeModel` as a decision model.
  • Added support for `gemini-3.8-live` and `gemini-3.8-live-extended-thinking`.
  • Added `RunContext.in_durable_context` to detect durable workflow execution.
  • Exposed `OpenAI service_tier` in provider details.

Breaking Changes

  • Ask a `DecisionModel` which route to take by name, with one label per route.
  • Replace the decision model's tool-call lean with an opt-in `decision_route_threshold`.

New Features

  • Added `DecisionModel` base class for Decisions-protocol models.
  • Added `RunContext.in_durable_context` for hooks.
  • Added `gemini-3.8-live` and `gemini-3.8-live-extended-thinking` support.
  • Added `RequestUsage.audio_seconds` for pricing voice models.

Full Release Notes

<!-- Release notes generated using configuration in .github/release.yml at main -->

## What's Changed
### ⚠️ Compatibility Notes
* Ask a `DecisionModel` which route to take by name, with one label per route by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8733
* Make `ModelSelectionContext.messages` end with the request being routed, and add `ModelSelectionContext.prompt` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8737
* Replace the decision model's tool-call lean with an opt-in `decision_route_threshold` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8739
### 🚀 Features
* Expose OpenAI `service_tier` in provider details by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/7945
* Add `DecisionModel`, a base for Decisions-protocol models, and make `TypeSafeModel` one by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8696
* Add `RunContext.in_durable_context` so hooks can tell they run in durable workflow code by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/8723
* Add `gemini-3.8-live` and `gemini-3.8-live-extended-thinking` realtime support by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8393
* Ask a `DecisionModel`'s route fields with the route question under a route premise, with nested-field `context` and a `done` state after tool calls by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8749
* Emit a `decide` span for every request a `DecisionModel` sends by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8698
### 🐛 Bug Fixes
* Keep the type variable of a generic `OutputSpec[T]` passed to `Agent.run` under mypy by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8730
* Send `ThinkingPart`s in the history decision models judge by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8738
* Price Anthropic one-hour cache writes at the one-hour rate instead of the five-minute rate by @kazmer97 in https://github.com/pydantic/pydantic-ai/pull/8666
* Price realtime image input at the image rate by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8741
* Add `RequestUsage.audio_seconds` so duration-billed voice models are priced by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8427
* Offer a decision model's unfillable `output_type` as a route beside other routes, and rename `ToolCallProposed` to `UnfillableRoute` under a `DecisionHandOff` base by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8744
* Keep realtime user turns whole when the microphone streams continuously on providers without input item IDs by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8746
* Roll back a realtime send the provider refuses, so `wait_for_reply()` no longer hangs on it by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8747
* Turn reasoning off for `thinking=False` on OpenAI Realtime by sending `reasoning.effort: 'none'` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8753
* Take Jev's `context_window` from genai-prices and document compacting a Jev conversation by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8740
* Buffer five minutes of audio per `stream_audio()` view so speaker-paced playback gets whole replies by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8750
* Stop Google Search from crashing Gemini 2.5 native-audio realtime sessions by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8751
* Keep user speech out of Gemini 3.x realtime history when input transcription is off by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8754
* Surface a failed OpenAI realtime response's error as a `RealtimeSessionErrorEvent` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8752


**Full Changelog**: https://github.com/pydantic/pydantic-ai/compare/v2.49.0...v2.50.0

Related Repositories