What's Changed
⚠️ Compatibility Notes
- Warn when a provider-specific thinking setting from a broader scope overrides
thinkingby @dsfaccini in #10231 - Send the least thinking a model accepts for
thinking=Falseon models that can't turn thinking off by @DouweM in #11036 - Raise
NotImplementedErrorfor a file in aCohereModeltool return instead of dropping it by @dsfaccini in #11114 - Keep concurrent workspace runs attached to their own Prefect environments by @dsfaccini in #11160
- Keep
boolandintinputs on separateLiteraldecision branches inpydantic_graphby @dafyy321-pixel in #9091 - Deprecate
google_multi_speakeronGoogleRealtimeModel, which no Gemini Live model supports by @DouweM in #11064 - Accept async
authfunctions in the hosted MCP capabilities by @mpfaffenberger in #10835 - Run the authoring checks in
CapabilityStore.load_activeand stop overwriting unreadable manifests by @mpfaffenberger in #10731 - Keep the last valid authored capability on a failed re-author, share the
CapabilityStorelock per directory, and let runs cancel authoring by @mpfaffenberger in #10767 - Reject
BrowserUseprohibited lists browser-use would match by exact hostname, and retry when redacted schema keys collide by @mpfaffenberger in #10775 - Share one
LocalStackcontainer insideasync with agent:, stop service-list bypasses andaws configurewrites to~/.aws, and capaws_clioutput by @mpfaffenberger in #10828 - Make
InputGuardrailredact 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
authfunctions in the hosted MCP capabilities by @mpfaffenberger in #10835 - Add structured citations to
TextPartby @adtyavrdhn in #7434 - Normalize citations from Bedrock, OpenRouter, and xAI by @adtyavrdhn in #7750
- Bound background and
shelljob logs withShell.max_log_bytesby @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-proandkimi-k3.1-pro-highspeedmodel names by @dsfaccini in #11173 - Accept
transport=increate_async_httpx2_client()and give thehttpx2retry transports its pool limits by @DouweM in #11073 - Add
RealtimeClientSecret.webrtc_url, which carrieswebrtcfilter=onon 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_outputso 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,DurableRunContextand run identity hooks by @DouweM in #11088
🐛 Bug Fixes
- Keep streamed OpenRouter
reasoningthat arrives withoutreasoning_detailsby @dsfaccini in #11104 - Raise a
UserErrorinstead of anAssertionErrorfor an unconverted responseSpeechPartinBedrockConverseModelby @dsfaccini in #11107 - Raise
NotImplementedErrorfor a file in aCohereModeltool return instead of dropping it by @dsfaccini in #11114 - Detect pydantic-ai-minted Gemini tool-call ids with
TOOL_CALL_ID_PREFIXinstead of a hardcoded'pyd_ai_'by @dsfaccini in #11109 - Keep
boolandintinputs on separateLiteraldecision branches inpydantic_graphby @dafyy321-pixel in #9091 - Support
NativeOutputon everyFireworksProvidermodel by @pydanty in #10157 - Warn when a provider-specific thinking setting from a broader scope overrides
thinkingby @dsfaccini in #10231 - Record the failed status on streamed
XaiModelnative tool return parts by @dsfaccini in #11105 - Keep an
OpenAIChatModelresponse with a non-standardfinish_reasoninstead of raisingUnexpectedModelBehaviorby @dsfaccini in #11119 - Make
InputGuardrailredact the user's own prompt and close fail-open paths in guardrails by @mpfaffenberger in #10841 - Run the authoring checks in
CapabilityStore.load_activeand stop overwriting unreadable manifests by @mpfaffenberger in #10731 - Keep
Linear(id=None)uncombined likeGitHub(id=None)by @mpfaffenberger in #10813 - Cancel the Exa runs a cancelled
ExaAgentpoll 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
Shellcommands overSSHWorkspaceBackend, and return a command too long to start to the model by @mpfaffenberger in #11004 - Name the operation in
E2BSandboxprobe timeouts and validateenvandsandbox_timeoutat construction by @mpfaffenberger in #10811 - Rebuild the default
ExaSearchandExaAgentclient on a new event loop, and buildExaAgent's once by @mpfaffenberger in #10848 - Keep the last valid authored capability on a failed re-author, share the
CapabilityStorelock per directory, and let runs cancel authoring by @mpfaffenberger in #10767 - Stop
ConversationSearchreturning inherited history once per run, and clip excerpts around the matched term by @mpfaffenberger in #10749 - Reject
BrowserUseprohibited lists browser-use would match by exact hostname, and retry when redacted schema keys collide by @mpfaffenberger in #10775 - Share one
LocalStackcontainer insideasync with agent:, stop service-list bypasses andaws configurewrites to~/.aws, and capaws_clioutput by @mpfaffenberger in #10828 - Make
InputGuardrailredaction 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
BrowserUsesecrets inbrowse_webresults by @mpfaffenberger in #10827 - Send tool call
argumentsinHuggingFaceModelmessage history by @canblmz1 in #11139 - Carry a sub-agent's
RunCancelledacross 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
XaiModelnative 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-aiby @DouweM in #11069 - Let
OpenAIResponsesModelforce 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
SpeechPartby @DouweM in #11159 - Keep deferred tool entries in place when a
defer_loading=Truecapability is loaded on Anthropic by @DouweM in #11091 - Send the least thinking a model accepts for
thinking=Falseon models that can't turn thinking off by @DouweM in #11036 - Deprecate
google_multi_speakeronGoogleRealtimeModel, 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.startedby @DouweM in #11115 - Leave framework-owned
__pydantic_ai__metadata out ofsanitize_messagesoutput, as the UI adapters do by @DouweM in #11089
New Contributors
Full Changelog: v2.60.0...v2.61.0