What's Changed
⚠️ Compatibility Notes
- Change thinking effort mid-conversation via OpenAI
configuration_updateand Anthropic per-messageoutput_config, recorded asModelSettingsDeltaPartby @DouweM in #11111 - Add
ModelRequestRejectedError,ModelAuthenticationErrorandModelNotFoundErrormodel error categories by @DouweM in #11081 - State loaded deferred capabilities' instructions in the system voice, append their changes, and show them to
before_model_requestby @DouweM in #11103 - Prefix hosted MCP capabilities' tool names with the service by default, configurable with
tool_prefixby @DouweM in #10376 - Store the
SummarizingCompactionsummary as aCompactionPartinstead of a system prompt, and send provider-lessCompactionParts to every model by @DouweM in #10573 - Deliver realtime
SystemPromptParts on each provider's operator channel withsession.send()by @DouweM in #11379 - Preserve run identity when replaying Prefect capability operations by @dsfaccini in #11196
- Append changed MCP server instructions with
on_change='append', and give an id-less URLMCPToolsetits hostname asidby @DouweM in #10791 - Record Harness
Memorysnapshots in history once per changed run, so requests stay append-only by @DouweM in #10903 - Tell the realtime model a tool call failed on every provider, so it answers instead of going silent by @DouweM in #11086
- Reserve DBOS handler step positions during tool
ctx.emit()by @dsfaccini in #11157 - Record GPT-Live speech as one
SpeechPartinstead of splitting it at each delegated tool call by @DouweM in #11187 - Deliver
ctx.emit()events into the realtime session event stream by @DouweM in #11369 - Make realtime shared settings warn, raise or ignore like standard
ModelSettings: forcedtool_choiceraises on Gemini Live,parallel_tool_calls=Falsewarns by @DouweM in #11066 - Keep the prompt cache when changing thinking effort mid-conversation on OpenRouter, via its
configuration_updatesystem message by @DouweM in #11426 - Start
GraphBuilderbroadcast branches in.to()order instead of reversed, which can break replay of durable workflows paused across the upgrade by @DouweM in #11408 - Cache
on_change='append'instruction blocks behind a second cache point after the static instructions by @DouweM in #11351 - Build Harness
SystemReminderson request-scoped system prompts and deprecatecache_ttlby @DouweM in #9712 - Add
CodeMode(monty_sandbox=...), which takes a remote Monty URL or a function that builds the pool, and deprecatemonty_sandbox_urlby @adtyavrdhn in #11141
🚀 Features
- Change thinking effort mid-conversation via OpenAI
configuration_updateand Anthropic per-messageoutput_config, recorded asModelSettingsDeltaPartby @DouweM in #11111 - Add
ModelRequestRejectedError,ModelAuthenticationErrorandModelNotFoundErrormodel error categories by @DouweM in #11081 - Export
conversation_id_from_run_idfrompydantic_ai.durable_execfor third-party durability engines by @DouweM in #11338 - Run tool calls as Temporal child workflows via
child_workflowtool metadata inTemporalDurabilityby @YHallouard in #7329 - Restrict
tool_choicesubsets withallowed_toolson OpenAI Chat Completions to preserve the prompt cache by @DouweM in #10396 - State loaded deferred capabilities' instructions in the system voice, append their changes, and show them to
before_model_requestby @DouweM in #11103 - Prefix hosted MCP capabilities' tool names with the service by default, configurable with
tool_prefixby @DouweM in #10376 - Store the
SummarizingCompactionsummary as aCompactionPartinstead of a system prompt, and send provider-lessCompactionParts to every model by @DouweM in #10573 - Add
tool_prefixto theMCPcapability by @DouweM in #11364 - Let
SubAgentsrun delegations as tasks the model can background, steer, answer and cancel, behindtask_controlby @mpfaffenberger in #10893 - Add
Coder(task_control=)to turn onSubAgentstask control by @mpfaffenberger in #11007 - Add
StructuredContentuser content, sent as its value to decision models by @DouweM in #10529 - Use the Pydantic AI Gateway's reported cost for
RequestUsage.costby @adtyavrdhn in #7337 - Let the model request a harness compaction at a natural break in the task with
CompactOnRequestby @mpfaffenberger in #11422 - Deliver realtime
SystemPromptParts on each provider's operator channel withsession.send()by @DouweM in #11379 - Add
AnthropicModel.compact_messages()for on-demand native compaction by @DouweM in #11432 - Add provider batch API support with a
BatchModelRequestscapability and aget_wrapper_modelcapability hook by @DouweM in #10672
🐛 Bug Fixes
- Break
GraphRuniterator andToolManagercontext reference cycles by @dsfaccini in #11158 - Preserve run identity when replaying Prefect capability operations by @dsfaccini in #11196
- Stop
Agent.run_streamname inference from keepingdepsalive until garbage collection by @dsfaccini in #11219 - Preserve Cohere response IDs in
ModelResponse.provider_response_idby @dsfaccini in #11223 - Recognize
deepseek-flashinDeepSeekProviderby @dsfaccini in #11249 - Close the whole
AgentStreamevent stream when a consumer leavesnode.stream()early by @adtyavrdhn in #11009 - Close inner event streams so a raising listener cancels in-flight tool calls by @Kludex in #8822
- Fix
thinking=Falseon OpenRouter'santhropic/claude-sonnet-5.5, which can't turn reasoning off by @dsfaccini in #11261 - Append changed MCP server instructions with
on_change='append', and give an id-less URLMCPToolsetits hostname asidby @DouweM in #10791 - Keep a system prompt after the tool result it followed in AG-UI
dump_messages()by @DouweM in #11188 - Cancel a suspended background job only once when a streamed continuation request fails by @DouweM in #11090
- Keep billed usage when a run stops before a continued response completes by @DouweM in #11068
- Classify Azure
too_many_requestsstream errors forFallbackModelby @pydanty in #11253 - Make
google_proactive_audiowork on the default Gemini provider with a separatev1alphaLive client by @DouweM in #11067 - Keep an empty response in place when AG-UI
load_messages()reloads a dumped history by @DouweM in #11192 - Keep
openai_previous_response_idchaining when a rewrite-mode instruction changes beside anon_change='append'block by @DouweM in #11331 - Record Harness
Memorysnapshots in history once per changed run, so requests stay append-only by @DouweM in #10903 - Tell the realtime model a tool call failed on every provider, so it answers instead of going silent by @DouweM in #11086
- Send the lowest effort for
thinking=Falseon OpenRouter routes that make reasoning mandatory by @DouweM in #11347 - Reserve DBOS handler step positions during tool
ctx.emit()by @dsfaccini in #11157 - Record GPT-Live speech as one
SpeechPartinstead of splitting it at each delegated tool call by @DouweM in #11187 - Keep history before a
CompactionPartwith an empty summary instead of treating it as a compaction boundary by @DouweM in #11368 - Replay local history into a fresh Gemini Live session when a reconnect has no resumption handle by @DouweM in #11074
- Inline tool schema definitions for Azure Grok deployments by @dsfaccini in #11155
- Fix
AGUIAdapter.dump_messagesinjecting newlines between adjacentTextParts by @pydanty in #8660 - Keep a loaded deferred capability's instructions in a realtime session seeded with a standard run's history by @DouweM in #11387
- Split streamed AG-UI assistant messages at reasoning, compaction and preserved file parts, as
AGUIAdapter.dump_messagesdoes by @DouweM in #11391 - Give each
UIMessageof a split request its own id in Vercel AIdump_messages()by @DouweM in #11193 - Let an explicit
FileUrlmedia_typewin over the downloadedContent-Type, and treatbinary/octet-streamas unknown by @DouweM in #11407 - Deliver
ctx.emit()events into the realtime session event stream by @DouweM in #11369 - Stop replaying a non-empty
search_toolsresult as "No matching tools found" on Anthropic when its matches are no longer declared by @DouweM in #11411 - Show retry feedback in the
SummarizingCompactionandRelevanceCompactiontranscript by @DouweM in #11370 - Carry non-native thinking in a user turn for Claude on OpenAI-compatible providers via
OpenAIChatModelandOpenAIResponsesModelby @DouweM in #11410 - Re-attach a dropped GPT-Live WebRTC sideband under the
reconnectpolicy by @DouweM in #11070 - Make realtime shared settings warn, raise or ignore like standard
ModelSettings: forcedtool_choiceraises on Gemini Live,parallel_tool_calls=Falsewarns by @DouweM in #11066 - Preserve initial code in streamed
code_interpreter_callevents by @dsfaccini in #11166 - Keep
ToolOutputLimitsfrom reducingload_capabilityandsearch_toolsreturns, so loaded capabilities' tools unlock by @mpfaffenberger in #11446 - Keep the prompt cache when changing thinking effort mid-conversation on OpenRouter, via its
configuration_updatesystem message by @DouweM in #11426 - Start
GraphBuilderbroadcast branches in.to()order instead of reversed, which can break replay of durable workflows paused across the upgrade by @DouweM in #11408 - Keep the response that crosses a token or cost limit in
capture_run_messagesby @DouweM in #11413 - Cache
on_change='append'instruction blocks behind a second cache point after the static instructions by @DouweM in #11351 - Keep
ToolOutputLimitsbands largest-first aftercombine, with the later band winning a shared threshold by @mpfaffenberger in #11453 - Forward nested
ToolReturn.contentfromCodeModerun_codeto the model instead of silently dropping it by @mpfaffenberger in #11456 - Preserve Gateway costs in Groq streams by @dsfaccini in #11473
- Count a
ModelRetryraised after aBackgroundToolstool's step has ended towardmax_retriesby @mpfaffenberger in #11458 - Build Harness
SystemReminderson request-scoped system prompts and deprecatecache_ttlby @DouweM in #9712 - Keep deferred capabilities loaded when
SummarizingCompaction,SlidingWindowCompactionandRelevanceCompactionremove theirload_capabilityexchange by @DouweM in #11394 - Strip the internal end-of-command marker from
SSHWorkspaceBackendtimeout and output-limit errors by @DouweM in #11479 - Report the same job from the harness
Shellpersistentshelltool after a durable (DBOS) replay by @mpfaffenberger in #11457
Full Changelog: v2.61.0...v2.62.0