v2.58.0

pydantic/pydantic-aiv2.58.0Oct 20, 2026by dsfaccini

Upgrading?

AI Summary

This release brings a wide array of new features including support for ChatGPT sign-in, ElevenLabs Agents, and message storage optimizations. It also resolves a security vulnerability in UI adapters and updates compatibility notes for DBOS workflows and RealtimeConnection.

Key Highlights

  • New `openai-chatgpt` provider for ChatGPT sign-in
  • New `ElevenLabsAgentsRealtimeModel` for realtime sessions
  • Security fix for UI adapter history allowing unauthorized tool execution (GHSA-5pfm-2g3g-gh85)
  • Message storage optimizations in `SqliteStepStore` and `PostgresStepStore`
  • New `DelegationTasks.steer` method for controlling delegated tasks

Breaking Changes

  • Existing DBOS workflows using `Planning` with an `event_stream_handler` may not recover after upgrading; let in-flight workflows finish first or deploy a new DBOS application version

New Features

  • Add `openai-chatgpt` provider
  • Add `ElevenLabsAgentsRealtimeModel`
  • Store each message once in `SqliteStepStore` and `PostgresStepStore`
  • Steer delegated tasks with `DelegationTasks.steer`
  • Add `ModelSettings['max_retries']`

Full Release Notes

> This comment was posted by codex-tui using gpt-6.1-sol on behalf of David.

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

## What's Changed
### 🛡️ Security
* **Medium — MCP request telemetry:** [GHSA-xv4x-g8mx-ch56](https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-xv4x-g8mx-ch56). Provider-native MCP configuration could expose server URLs, authorization tokens and custom header values in OpenTelemetry request traces, even with `include_content=False`. URL-based `MCP` capabilities could also expose a credential embedded in the URL-derived identifier. Fixed in v2.58.0 and v1.107.8. Restrict access to historical traces and rotate exposed credentials.
  **Temporal mitigation:** URL-based `MCP` activity names remain unchanged to preserve in-flight workflows. With Temporal tracing enabled, also pass an explicit `id=` to `MCP` once in-flight workflows complete; changing it renames the activities.
* **Medium — UI adapter history:** [GHSA-5pfm-2g3g-gh85](https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-5pfm-2g3g-gh85). With non-empty server-side `message_history` and `manage_system_prompt='server'` (the default), Vercel AI and AG-UI adapters could execute an available tool with client-chosen arguments without a model request. Approval-required tools are not executed by this path. Fixed in v2.58.0; v1 is unaffected.
### ⚠️ Compatibility Notes
* Count a resumed `'suspended'` response's usage only in the run that produced it, in `RunUsage`, `UsageLimits` and `SpendLimits` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10078
* Make `RealtimeConnection` yield lifecycle events through a public `pydantic_ai.realtime.lifecycle` module by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10353
* Let `read_file` return images and PDFs, and describe other binary files by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9596
* Record a realtime reply the user cut off after it finished generating as interrupted, and mark interrupted speech when seeding by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10466
* Treat a native tool as unsupported when the model can't apply its `allowed_domains`, `blocked_domains`, `max_uses` or `external_web_access` setting by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10451
* Add request-scoped `SystemPromptPart(scope='request')` sent natively as Anthropic `clear_at` system messages by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9711
* Send Harness `WarnNearLimits` warnings as request-scoped system prompts by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10561
* Escape `RepoContext` `<context-file>` blocks and send the nested-directory pointer as a `SystemPromptPart` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10558
* Make the profile's `supports_auto_cache` decide `anthropic_cache`, and use automatic caching on legacy `AsyncAnthropicBedrock` for Claude Opus 4.7 and later by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10551
* Let any module define a `ToolKind` with typed tool parts, and keep unknown kinds loadable by @DouweM in https://github.com/pydantic/pydantic-ai/pull/9710
* Emit `Planning` status-tool events after their store reads, so DBOS recovery with an `event_stream_handler` replays in order by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/10343
  Existing DBOS workflows using `Planning` with an `event_stream_handler` may not recover after upgrading; let in-flight workflows finish first or deploy a new DBOS application version.
* Align `RealtimeTurnCompleteEvent` with the exchange boundary that `wait_for_reply()` waits for by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10517
  To react when a particular response ends, use its `PartEndEvent`s. Caption UIs should keep user parts open until their `PartEndEvent`, which can arrive after the reply completes.
### 🚀 Features
* Steer a running delegated task with `DelegationTasks.steer` by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/10359
* Store each message once in `SqliteStepStore` instead of repeating the history in every snapshot by @aweis89 in https://github.com/pydantic/pydantic-ai/pull/9982
* Add `ModelSettings['max_retries']` to set how many times the provider SDK retries a request by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10068
* Bound a whole agent run with `timeout=` and `RunContext.deadline` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10070
* Stream `ctx.enqueue` messages to Vercel AI and AG-UI frontends as history they send back but don't render by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10405
* Add `ModelSettings['request_timeout']` covering all attempts and stream consumption of one model request by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10072
* Store each message once in `PostgresStepStore` and `MongoStepStore` instead of repeating the history in every snapshot by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10452
* Let harness `Skills` ignore `include` and `exclude` names no library has with `unknown_names='skip'` by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/10506
* Add the `openai-chatgpt` provider so app users can sign in with ChatGPT and use their plan by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/10539
* Accept `timeout=` on UI adapter `run_stream()`, `run_stream_native()` and `dispatch_request()` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10553
* Add `reasoning_summary` to `OpenAILiveResponsesDelegation` to request the GPT-Live backend's reasoning summaries by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10514
* Warn with `UnsupportedSettingWarning` when a model ignores a setting like `timeout`, `max_retries` or `stop_sequences` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10508
* Add `openai_prune_tool_items` to delete answered tool rounds from the OpenAI Realtime conversation by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10556
* Add `ElevenLabsAgentsRealtimeModel` to run realtime sessions on ElevenLabs Agents by @rscholz98 in https://github.com/pydantic/pydantic-ai/pull/7964
### 🐛 Bug Fixes
* Stop `wait_for_reply()` waiting forever when a realtime tool batch receives no reply after a call is cancelled by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10503
* Label a symlinked `RepoContext` instruction file with its target's name, so `CLAUDE.md -> AGENTS.md` reads `AGENTS.md` by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/10438
* Keep mid-run system prompts when `ReinjectSystemPrompt(replace_existing=True)` replaces the client's by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10389
* Keep parallel tool calls in one `ModelResponse` when `VercelAIAdapter` loads messages by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10404
* Stream the returns of tool calls skipped after a final result to AG-UI and Vercel AI frontends by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10409
* Fix `tool_choice='none'` on `BedrockConverseModel` failing after a tool call by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10395
* Resolve the default output mode once per run so toggling `thinking` per step keeps `tools` stable by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10398
* Clear tool results in batches under `ClearToolResults(max_messages=...)` instead of on every request past the threshold by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10390
* Force a single tool natively on `MistralModel` instead of filtering `tools` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10394
* Don't crash on a `CachePoint` after a replayed Anthropic MCP tool result by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10369
* Fall back on stream errors raised before the first event in `FallbackModel` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10386
* Raise in `run_stream()` instead of returning a response that a model request hook rejected with `ModelRetry` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10400
* Give a model's provider a new HTTP client on a new event loop, and keep `Model` instances a selector returns open inside `async with agent:` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10377
* Carry non-native `ThinkingPart`s in a user turn for models that imitate assistant formatting by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/6692
* Send tool-call args as compact JSON from `ToolCallPart.args_as_json_str()` so UI round trips keep the prompt cache by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10410
* Send tool results in call order from `Model.prepare_messages` so UI round trips keep the prompt cache by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10411
* Close the `AsyncInferenceClient` that `HuggingFaceProvider` builds when the provider or agent exits by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10393
* Keep `ToolReturn(tools=...)` reveals when a Vercel AI frontend rebuilds history from the event stream by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10401
* Skip the gh-aw `pydantic-ai` engine when an earlier step wrote a `noop` to `GH_AW_SAFE_OUTPUTS` by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/10450
* Restore the files #10457 accidentally reverted, including `request_timeout` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10483
* Update `RealtimeSession.context_window_used` together with the usage it reports by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10467
* Don't load the tokenizer to replay an empty GPT-Live history on a redial by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10474
* End an OpenAI realtime response created without an id when a malformed `response.done` closes it by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10511
* Call `OpenAIResponsesModel._process_provider_details` on streamed responses too by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10515
* Let shielded model-stream cleanup finish when an outer `anyio` cancel ends a debounced `stream_text()`, `stream_output()` or `stream_response()` by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/10448
* Add `ModelProfile.tool_call_id_length` and rewrite tool call IDs that Mistral models reject by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10519
* Use automatic prompt caching (`anthropic_cache`) on `AsyncAnthropicVertex` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10513
* Inline GLM-5.3 tool schemas on Z.AI, Mistral, and OpenRouter by @2Zest in https://github.com/pydantic/pydantic-ai/pull/10607
* Walk `propertyNames` and `contains` when inlining JSON Schema definitions by @jukebox in https://github.com/pydantic/pydantic-ai/pull/10588
* Keep an unsaved `openai-codex` or `openai-chatgpt` token refresh instead of reverting to the stored credentials it spent by @mpfaffenberger in https://github.com/pydantic/pydantic-ai/pull/10615
* Keep a request's separate `UserPromptPart`s through a `VercelAIAdapter` round trip by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10532
* Escape tool names in `CodeMode` discovery announcements and stop recognizing announcements by their text by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10559
* Keep every usage counter in `RunUsage.__sub__`, so durable runs keep one-hour cache writes and reasoning tokens, and declare `cache_write_1h_tokens` and `output_reasoning_tokens` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10516
* Don't ask again for a realtime tool batch's reply when the caller's `send()` of its last result failed by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10512
* Keep a request's separate `UserPromptPart`s through an `AGUIAdapter` round trip by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10563
* Stop continuing an OpenAI response with `openai_previous_response_id` once the history before it has changed by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10509
* Stop harness sub-agents from returning `DeferredToolRequests` to a parent that cannot resolve them by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10497
* Stop continuing an OpenAI response with `openai_previous_response_id` once the response itself has changed by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10656
* Raise `RealtimeError` instead of a raw `websockets` exception when a GPT-Live connection drops without a reconnect policy by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10645
* Ignore deeply nested `ReasoningMessage.encrypted_value` JSON in `AGUIAdapter.load_messages` by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10650
* Write `format_as_xml` mapping keys that aren't valid XML names to a `key` attribute by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10651
* Fix `UseEnumMemberDocstrings` enums, `Choices` and `BoolCriteria` failing in Anthropic strict schemas by @DouweM in https://github.com/pydantic/pydantic-ai/pull/10659
* Rewrite nested `$ref`s when merging JSON schema definitions by @limadog9 in https://github.com/pydantic/pydantic-ai/pull/10601

## New Contributors
* @2Zest made their first contribution in https://github.com/pydantic/pydantic-ai/pull/10607
* @jukebox made their first contribution in https://github.com/pydantic/pydantic-ai/pull/10588
* @limadog9 made their first contribution in https://github.com/pydantic/pydantic-ai/pull/10601

**Full Changelog**: https://github.com/pydantic/pydantic-ai/compare/v2.57.0...v2.58.0

Related Repositories