v2.55.0

pydantic/pydantic-aiv2.55.0Oct 9, 2026by dsfaccini

Upgrading?

AI Summary

This release enforces a Python 3.11+ requirement and introduces significant improvements to prompt caching, cross-provider support, and database backends. It adds a new `Conversation` object for state management across runs, support for the `claude-haiku-5-5` model, and new Postgres stores for messages and media.

Key Highlights

  • Requires Python 3.11 or newer, deprecating support for 3.10
  • Adds `PostgresStepStore` and `PostgresMediaStore` for database-backed execution
  • Enhances prompt caching with unified settings, diagnostics, and defaulting to the Coder harness
  • Adds support for the new `claude-haiku-5-5` model and `OpenAIDecisionsModel` backend
  • Optimizes import time by lazily loading the MCP module

Breaking Changes

  • Require Python 3.11 or newer in every package; Python 3.10 installs resolve to 2.54.0 and earlier

New Features

  • Add `Conversation` to carry and store a conversation between runs
  • Add `PostgresStepStore` and `PostgresMediaStore` backends
  • Add unified `cache` setting and `Caching` capability for cross-provider prompt caching
  • Add `hang_up()` to end a WebRTC call from the server
  • Add `openai_live_idle_audio` so text-only GPT-Live sessions work without a microphone
  • Add support for `claude-haiku-5-5`
  • Add `OpenAIDecisionsModel` backend with image input

Full Release Notes

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

## What's Changed
### ⚠️ Compatibility Notes
* Require Python 3.11 or newer in every package; Python 3.10 installs resolve to 2.54.0 and earlier by @Kludex in https://github.com/pydantic/pydantic-ai/pull/9526
* Record the tool requests of `ExaSearch`, `YouSearch`, `LocalStack` and other harness capabilities under durable execution by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9705
* Bound retained realtime audio like retained images with `retain_audio_max_seconds` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9702
* Prefix `LogfireMCP` tool names with `logfire_` by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/9868
* Serialize `FileUrl.media_type` as `null` for extensionless URLs instead of raising by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/8405
* Take realtime history, usage, and reply waits from the session core on OpenAI, Azure OpenAI, and xAI by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9612
* Keep default `run_id` and `conversation_id` stable when a durable run is re-executed by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9701
* Record each failed `FallbackModel` attempt with its model, timing, error and usage, and count rejected responses in `RunUsage` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8745
### 🚀 Features
* Add an `OpenAIDecisionsModel` backend with image input by @DenysMoskalenko in https://github.com/pydantic/pydantic-ai/pull/9634
* Halve `import pydantic_ai` time by loading `pydantic_ai.mcp` only when an `MCP` capability needs it by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10046
* Add `Conversation` to carry and store a conversation between runs, accepted as `conversation=` by every entry point by @DouweM in https://github.com/pydantic/pydantic-ai/pull/8337
* Record prompt cache diagnostics in `provider_details`: on by default for OpenAI Responses, `anthropic_cache_diagnostics` opt-in by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9406
* Report prompt-cache health per conversation via `pydantic_ai.cache.*` span attributes and collapse events by @DouweM in https://github.com/pydantic/pydantic-ai/pull/6534
* Default Azure AI Voice Live to API version `2026-07-15` and apply `parallel_tool_calls=False` there by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9409
* Raise Azure AI Voice Live `warning` events as Python warnings instead of dropping them by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9420
* Add `openai_cache_instructions` to place a prompt cache breakpoint on the instructions by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/7559
* Add `hang_up()` to end a WebRTC call from the server on gpt-realtime and GPT-Live by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9342
* Add `PostgresStepStore` and `PostgresMediaStore`, the hosted Postgres backends for messages and media by @rscholz98 in https://github.com/pydantic/pydantic-ai/pull/9899
* Add unified `cache` setting and `Caching` capability for cross-provider prompt caching by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/7560
* Add support for `claude-haiku-5-5` by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/9998
* Seed `message_history` into a WebRTC call through `answer_webrtc_offer` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9338
* Configure Azure AI Voice Live semantic VAD, end-of-utterance detection, noise suppression and echo cancellation by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9414
* Cache the instructions and tool definitions too when `cache=True` uses Anthropic's automatic caching by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10047
* Turn on prompt caching by default in harness `Coder` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10040
* Add `openai_live_idle_audio` so text-only GPT-Live sessions work without a microphone by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9295
### 🐛 Bug Fixes
* Read Codex CLI `auth.json` as UTF-8 regardless of platform locale by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/8254
* Avoid false `WarnOnCacheBusts` warnings after native tool calls by @aweis89 in https://github.com/pydantic/pydantic-ai/pull/9746
* Run a capability `durable_operation` inline when it is called from inside a durable unit by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9700
* End an xAI realtime session on a `max_duration` error instead of reconnecting into the same limit by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9415
* Attach a leading `CachePoint` to the previous message on OpenAI instead of raising by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9582
* Keep the run state recoverable when Ctrl-C interrupts `run_stream_sync()` mid-output by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9709
* Raise `BedrockEmbeddingModel` errors as `ModelHTTPError`/`ModelAPIError` instead of an `ExceptionGroup`, and map botocore transport errors by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9314
* Record GPT-Live's final usage on close by ending the session with `session.close` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9403
* Stop a numeric request timeout from lengthening the connect and pool timeouts of Pydantic AI-created HTTP clients by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9599
* Don't record an OpenAI realtime `idle_timeout_ms` follow-up as an empty user turn by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9396
* Close out interrupted tool calls when resuming a sub-agent with `delegate_task(resume=...)` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9783
* Publish `AgentRunResult`'s public shape in its validation JSON schema by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9791
* Record `Planning`'s plan store calls under durable execution, so recovery doesn't repeat its writes by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9789
* Report malformed GPT-Live events as recoverable errors instead of dropping them by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9393
* Record each `Memory` tool call under durable execution, so a forked DBOS workflow doesn't repeat its writes by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9832
* Replay a spoken realtime turn without a transcript as a marker on reconnect instead of dropping it by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9782
* Don't let `openai_prompt_cache_retention` widen the cache-health window on GPT-5.6+ by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9851
* Hide MCP Apps tools whose `_meta.ui.visibility` leaves out `"model"` from the model in `MCPToolset` by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/9862
* Drop the empty `moderation` stub from `SnowflakeModel` responses by @specterbuilds in https://github.com/pydantic/pydantic-ai/pull/9764
* Handle JSON-pointer `$ref`s and draft-07 `definitions` in MCP TypeScript SDK tool schemas by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/9643
* Populate `span_tree` and metrics for `run_on_errors` evaluators when a task raises by @Diwak4r in https://github.com/pydantic/pydantic-ai/pull/7070
* Send a generic question when a `SystemOneModel` question would have no `instructions` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9848
* Move `MCPReadOnlyNoToolsWarning` to `_warn` so harness submodule imports stay light by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9922
* Accrue `SpendLimits` continuation chains per segment boundary so a durable retry charges newly billed segments by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/10002
* Keep OpenAI's implicit prompt cache when `cache={'messages': False}` can't place an instruction breakpoint by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10007
* Cancel the streamed model request when a parallel `InputGuardrail` blocks by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/10003
* Ignore media-type parameters in `is_text_like_media_type` by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9948
* Decode percent-encoded Base64 payloads in `BinaryContent.from_data_uri` by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9950
* Add `gpt-6.1-sol` support on Bedrock Converse by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9817
* Fix history repair for a `tool_call_id` repeated within one response by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9819
* Preserve the current request when retained user turns exhaust the `SummarizingCompaction` tail budget by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9715
* Resume deferred Code Mode calls in dispatch order in global sequential modes by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9972
* Fix `Researcher` construction under `TemporalDurability` and `PrefectDurability` by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9564
* Fix `FallbackModel` ignoring handler functions in `fallback_on` tuples by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/10031
* Reject whitespace-only `SummarizingCompaction` summaries instead of replacing history with an empty summary by @aweis89 in https://github.com/pydantic/pydantic-ai/pull/9748
* Catch overflowing `Retry-After` HTTP dates by @ktz03 in https://github.com/pydantic/pydantic-ai/pull/10023
* Keep OpenAI Responses tool-call arguments that arrive only in `function_call_arguments.done` or `output_item.done` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10039
* Return a 422 instead of a 500 from `Agent.to_web()` for invalid chat requests by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10042
* Stop `EvaluationReport.render()` and `print()` from parsing case, task and evaluator text as Rich markup by @lets-order-some-fries in https://github.com/pydantic/pydantic-ai/pull/9544
* Rewrite `$ref`s under `propertyNames` and `patternProperties` when merging schema defs by @jayzuccarelli in https://github.com/pydantic/pydantic-ai/pull/8805
* Keep the current request when a `SlidingWindowCompaction` receipt would take the only kept slot by @aweis89 in https://github.com/pydantic/pydantic-ai/pull/9719
* Reconnect xAI realtime sessions by replaying local history, since xAI conversation resumption drops typed user turns and tool calls by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9421
* Keep completed tool returns under `parallel_ordered_events` when a sibling raises or the run is cancelled by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10049
* Fix retried Anthropic requests sending empty base64 image and PDF bytes by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/10014
* Keep the live workspace on a settled `StreamedRunResult.result` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10048
* Fix ID-only tool call deltas emitting a `null` args fragment in AG-UI and Vercel AI adapters by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9724
* Keep streamed OpenAI Responses tool-call arguments when the `done` snapshot disagrees, instead of starting the part again by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10044
* Stop dynamic system-prompt re-evaluation from mutating caller-owned message history by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9627
* Count a file in a tool return as its `See file` reference, not its `repr`, in harness compaction by @pepijn-m in https://github.com/pydantic/pydantic-ai/pull/9632
* List every module Monty can import in the `CodeMode` `run_code` description by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/9315
* Fix `merge_json_schema_defs` corrupting branch schemas on transitive def-name collisions by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9735
* Charge `SpendLimits` budgets for responses a `FallbackModel` rejected by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9792
* Fix `TextOutput` JSON schema to infer the wrapped function's return annotation by [@pydanty](https://github.com/apps/pydanty) in https://github.com/pydantic/pydantic-ai/pull/9652
* Charge `FallbackModel` attempts once in `SpendLimits` when a failed continuation chain is retried by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10059
* Raise `ModelAPIError` for transport errors that escaped Google, Mistral, Cohere, Hugging Face, Anthropic, Groq and Bedrock by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9336
* Raise earlier Anthropic cache breakpoints to a later, longer TTL so requests aren't rejected by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10057
### 📦 Dependencies
* Raise the `openai` floor to 3.26.0 for Decisions support in the `openai`, `openrouter`, `bedrock-mantle`, `zai`, `snowflake`, `crusoe` and `cerebras` extras by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/9968

## New Contributors
* @atharva-mashalkar made their first contribution in https://github.com/pydantic/pydantic-ai/pull/9567
* @pankajkoti made their first contribution in https://github.com/pydantic/pydantic-ai/pull/8785
* @specterbuilds made their first contribution in https://github.com/pydantic/pydantic-ai/pull/9764
* @ktz03 made their first contribution in https://github.com/pydantic/pydantic-ai/pull/10023
* @lets-order-some-fries made their first contribution in https://github.com/pydantic/pydantic-ai/pull/9544
* @jayzuccarelli made their first contribution in https://github.com/pydantic/pydantic-ai/pull/8805
* @pepijn-m made their first contribution in https://github.com/pydantic/pydantic-ai/pull/9632

**Full Changelog**: https://github.com/pydantic/pydantic-ai/compare/v2.54.0...v2.55.0

Related Repositories