pypi pydantic-ai 2.60.0
v2.60.0 (2026-10-22)

5 hours ago

What's Changed

⚠️ Compatibility Notes

  • Raise model error categories like ModelRateLimitError from embedding models by @DouweM in #10804
  • Add usage_limits, deadline, run_id and conversation_id to ModelSelectionContext by @DouweM in #10856
  • Default BedrockConverseModel's maxTokens to Claude's maximum output, streaming such requests behind the scenes by @DouweM in #10845
  • Deprecate RetryPromptPart in favor of ToolReturnPart(outcome='retried') and RetryFeedbackPart by @dsfaccini in #8094
  • Summarize harness-added user-channel content as <harness_data> instead of user messages in SummarizingCompaction by @DouweM in #10833
  • Give AskUser, ConversationSearch, Macroscope, ManagedPrompt, PlaywrightBrowser and PydanticAIDocs a stable default id, and append ManagedPrompt version changes by @DouweM in #10904
  • Derive the MCP capability's default id from the server URL's hostname only, and reject two servers on one host without explicit ids by @DouweM in #10807
  • Record who wrote a memory file with an opt-in MetadataMemoryStore and Memory(write_metadata=...) by @mpfaffenberger in #10892
  • Let a named InstructionPart passed to a run's instructions opt into on_change='append', keyed run:<name> by @DouweM in #10789
  • Keep SummarizingCompaction(keep_user_messages=True) copies recognized after their request is merged by @DouweM in #10914
  • Strip request-level instructions from untrusted history in sanitize_messages and server-managed UI adapters by @DouweM in #10897
  • Send tool returns whose JSON form is a string, like datetime and UUID, to the model unquoted so restored histories match the first run by @dsfaccini in #10488
  • Keep the ids of instructions a wrapper toolset passes on from the toolsets it wraps by @DouweM in #10909
  • Include settings and profile in model equality and Model repr by @dsfaccini in #9474
  • Deprecate OpenAIDecisionsProvider and let OpenAIDecisionsModel take OpenAIProvider by @DouweM in #10951
  • Record every mid-run tool population change as a ToolAvailabilityDeltaPart by @DouweM in #9405
  • Send typed text to the GPT-Live backend as a user turn, so send(text) runs the agent's tools by @DouweM in #10960
  • Keep tool returns shaped like media markers from breaking StepPersistence snapshots, and fix SqliteMediaStore, DiskMediaStore, MongoMediaStore and S3MediaStore edge cases by @mpfaffenberger in #10834
  • Send settings stated by either of two merged Advisor capabilities by @mpfaffenberger in #10726
  • Drop client-supplied TextContent.metadata from user prompts in sanitize_messages by @DouweM in #10943
  • Raise ModelConnectionError and ModelTimeoutError for xAI gRPC connection failures and client timeouts by @DouweM in #11080
  • Send the agent's system_prompt and seeded history's system prompts to realtime sessions by @DouweM in #11055
  • Deliver SubAgents background task output as framed <task_output> data instead of in a SystemPromptPart by @DouweM in #10550
  • Keep BrowserUse secrets on allowlisted sites and out of tool results, and fix allowlist and file:// gaps by @mpfaffenberger in #10771
  • Match FileSystem denied and read-only patterns case-insensitively, protect .git files, and bound reads and Python regex searches by @mpfaffenberger in #10825
  • Filter GitHub tools on readOnlyHint under read_only=True, reject 'oauth', and deprecate plain http:// URLs by @mpfaffenberger in #10815
  • Add 'max' to unified thinking effort levels by @dsfaccini in #10920

🚀 Features

  • Add DockerSandbox harness capability that runs the workspace in a local Docker or Podman container by @mpfaffenberger in #9341
  • Add BoxLiteSandbox: a local BoxLite micro-VM workspace by @adtyavrdhn in #10740
  • Let SmolSandboxBackend use a VM the application already has by @adtyavrdhn in #10882
  • Attribute ElevenLabs Agents replies to the text turns they answer by in_response_to_ids by @DouweM in #10792
  • Add the run's output retry count and budget to ModelSelectionContext by @DouweM in #10836
  • Add ToolDefinition.unless_tool_kind and RunContext.tool_name_for_kind, and give instructions the current step's tools by @DouweM in #10673
  • Send a file a tool returns as a note when the model can't read it, with supports_audio_file_input and supported_document_media_types profile flags by @DouweM in #10476
  • Run gh-aw copilot/ models on the github-copilot: model and declare detection-engine: copilot by @mpfaffenberger in #9318
  • Add base_url and MOONSHOTAI_BASE_URL support to MoonshotAIProvider by @yanlinf in #10177
  • Drop capability reader tools duplicated by FileSystem by @DouweM in #9410
  • Add Bedrock model profile for xAI Grok 4.6 and 4.7 by @ahmed-moubtahij in #8639
  • Add RelevanceCompaction, which keeps, reduces or drops each older history step by a judge model's ranking by @mpfaffenberger in #11026
  • Add SmartSearch harness capability for plain-English code search with a pluggable judge model by @mpfaffenberger in #8977
  • Keep streamed model deltas out of durable execution histories by replaying the final response by @DouweM in #10958
  • Send OpenAIDecisionsModel message history as native Responses input items by @DouweM in #11028
  • Add the FileUnderstanding capability by @DouweM in #8453
  • Let MCPToolset take auth and headers as functions of the run context, so each run connects as its own user by @DouweM in #10846
  • Support Temporal continue-as-new in TemporalDurability via continue_as_new by @YHallouard in #7312
  • Add lockdown to GitHub to ask GitHub's server to withhold public content from users without push access by @mpfaffenberger in #10822

🐛 Bug Fixes

  • Fix SetToolMetadata(background=...) having no effect on BackgroundTools by @adtyavrdhn in #10613
  • Stop a GPT-Live session hanging when a tool in a delegated round raises by @DouweM in #10794
  • Raise ContentFilterError when Azure blocks a Responses API prompt without content_filter_result by @DouweM in #10805
  • Record what a Gemini Live model says during an asynchronous tool call before the tool's result by @DouweM in #10802
  • Send a raised tool's failure to the GPT-Live backend so the delegated round continues by @DouweM in #10868
  • Keep an xAI spoken turn going when its server VAD takes back a stop, and end the reply it drops by @DouweM in #10798
  • Keep a GPT-Live reply that called tools open until its delegated backend answers, so what Live says meanwhile stays with it by @DouweM in #10847
  • Use only the agent's instructions for realtime sessions, never instructions recorded in seeded message_history by @dsfaccini in #10896
  • Close the Bedrock event stream when a BedrockConverseModel.request_stream() context exits, including on cancellation by @DouweM in #10900
  • Keep BedrockConverseModel message caching readable after a Claude message ending in a document by @DouweM in #10907
  • Use explicit output_type overloads for Agent.from_spec and Agent.from_file by @tjkuson in #10886
  • Use native structured output on Bedrock for Claude Haiku 5.5, Sonnet 5 and later, and Opus 4.7 and later by @DouweM in #10901
  • Tell CodeMode models to import asyncio before calling asyncio.gather by @adtyavrdhn in #10913
  • Keep continuing an OpenAI response with openai_previous_response_id after a call to a tool with a tool_kind by @DouweM in #10931
  • Leave out a request-scoped SystemPromptPart that no user message clears, as after a no_output retry on Anthropic by @DouweM in #10938
  • Stop recording an empty system message in traces for requests with an InstructionBaselinePart by @DouweM in #10911
  • Leave retried tool returns out of ClearToolResults and DeduplicateFileReads by @DouweM in #10932
  • Keep a retried tool return's validation errors structured through a VercelAIAdapter round-trip by @DouweM in #10933
  • Record pydantic_ai.tool.retry.* attributes on argument-validation failure spans by @DouweM in #10934
  • Hold eager and speculative CodeMode tool calls, and a first model request that raises, until a parallel InputGuardrail decides by @dsfaccini in #10365
  • Fix cancelled steps, tool metadata key validation, and handler typing in AWSLambdaDurability by @mpfaffenberger in #10730
  • Describe Grain's write tools and treat Grain(id=None) as the default grain id by @mpfaffenberger in #10801
  • Emit AskUserAnsweredEvent with failed=True when the AskUser answerer raises by @mpfaffenberger in #10725
  • Raise the realtime connection failure from played_audio_bytes and wait_for_playback() instead of a UserError once it ended the audio stream by @DouweM in #10940
  • Route every core framework tag through _framing.wrap, so a </system> in an instruction or tool name can't end its block by @DouweM in #10547
  • Report ModelRetry and ToolFailed from execute hooks on BackgroundTools calls to the model by @mpfaffenberger in #10830
  • Accept Unicode spaces in AskUser questions and document its timeout, concurrency and tracing behavior by @mpfaffenberger in #10755
  • Surface an invalid AG-UI resume payload as a RunError instead of denying silently by @dsfaccini in #7038
  • Allow ToolSearch(strategy='bm25') on the legacy Bedrock AsyncAnthropicBedrock client by @dsfaccini in #10340
  • Send an empty reasoning_content on DeepSeekProvider tool calls whenever the request thinks by @dsfaccini in #10350
  • Reject TemplateVariable and fall back to the code default on invalid templates in ManagedPrompt, and correct its docs by @mpfaffenberger in #10821
  • Refuse non-regular file reads in ModalSandboxBackend and log a sandbox created after every caller was cancelled by @mpfaffenberger in #10816
  • Keep Eleven Realtime turn tracking intact when the model makes parallel tool calls by @DouweM in #10944
  • Report Azure Voice Live session_output_overflow as non-recoverable without a reconnect policy by @DouweM in #10947
  • Read the context size of an Anthropic server-side tool loop from its last usage.iterations pass by @dsfaccini in #10363
  • Wait for GPT-Live's answer to a raised tool's failure before ending the turn by @DouweM in #10941
  • Record an xAI realtime reply the user barged in on after it finished generating as interrupted by @DouweM in #10948
  • Emit RealtimeTurnCompleteEvent once for a realtime turn that ends because a tool raised by @DouweM in #10965
  • Honor retry-after-ms in wait_retry_after by @DouweM in #11065
  • Send a failure result to Gemini Live when a realtime tool raises, so the session keeps answering by @DouweM in #10942
  • Stop OpenAI GPT-Live answer_webrtc_offer from rejecting the profile's audio sample rates by @DouweM in #11049
  • Keep an in-flight Anthropic tool_search call so the model gets its result instead of searching again by @DouweM in #11058
  • Accept an explicit input_transcription_model='auto' on OpenAI GPT-Live by @DouweM in #11047
  • Make Macroscope work under durable execution and return the findings of a review the CLI stopped early by @mpfaffenberger in #10817
  • Treat LogfireMCP(id=None) as the default id, accept client with auth='', and flag untrusted telemetry in its docs by @mpfaffenberger in #10818
  • Support anthropic 2.x: build message params as dicts and keep Bedrock's anthropic_version by @DouweM in #11077
  • Require prefect>=3.9.0 so the prefect extra imports on current FastAPI by @DouweM in #11071
  • Keep ModelRequest fields when WarnNearLimits strips legacy warnings by @mpfaffenberger in #10776
  • Show ApprovalReviewer and ToolCallJudge the arguments as written, and correct the approval reviewer docs by @mpfaffenberger in #10727
  • Fix command cleanup and first-use races in BubblewrapWorkspace by @mpfaffenberger in #10746
  • Apply FallbackModel response handlers when continuing a suspended response by @DouweM in #11085
  • Let a Temporal worker register an agent listed on several workflows or also passed to AgentPlugin by @DouweM in #11082
  • Map unified thinking to reasoning.effort for OpenAI GPT-5.6 and GPT-6 on Bedrock Converse by @rscholz98 in #10993
  • Accept unrounded float probabilities and scores from SystemOneModel backends like vLLM by @mpfaffenberger in #11092
  • Keep SlidingWindowCompaction and SummarizingCompaction histories sendable after tool retries and keep_messages=0, and warn on an invalid summary_prompt by @mpfaffenberger in #10759
  • Stop timed-out E2BSandbox commands on templates without ps by @mpfaffenberger in #10809
  • Reject auth='oauth' and describe only the selected products in GoogleWorkspace by @mpfaffenberger in #10800
  • Handle prefixItems and string length bounds in OpenAI strict mode by @adtyavrdhn in #7333
  • Make E2BSandbox raise a clear UserError on Trio before any E2B request by @mpfaffenberger in #10810
  • Stop CodeMode speculation adopting reads that predate a write, scan eager streams that split \n, and reject out-of-range resource_limits by @mpfaffenberger in #10764

New Contributors

Full Changelog: v2.59.0...v2.60.0

Don't miss a new pydantic-ai release

NewReleases is sending notifications on new releases.