NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #293 most downloaded on PyPI
AI Agent Framework, the Pydantic way, slim package
Last release today
19 Sep 2026
Ships on a steady schedule
a new release about every 9 days
Nearly every release is documented
notes for 59 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
2 years old
329 releases · first in 2024
One column per month.
<!-- Release notes generated using configuration in .github/release.yml at v2-main -->
<!-- Release notes generated using configuration in .github/release.yml at v2-main -->
For more information on Pydantic AI V2, see the release notes for v2.0.0b1 and the Upgrade Guide.
Beta 3 adds no new breaking or v2-specific changes, but pulls in these changes from v1.102.0:
FileUrl into force_download='allow-local' on a URL that is, or could be, influenced by untrusted input, AND runs on a NAT64- or ISATAP-configured network (e.g. some IPv6-only or dual-stack-with-NAT64 Kubernetes setups).Agent.to_web / clai web; VercelAIAdapter; AGUIAdapter / Agent.to_ag_uistrict=None tools to strict mode with Bedrock, and skip strict field when botocore is too old by @shailendher in https://github.com/pydantic/pydantic-ai/pull/5580variable_instructions span attribute by @madanlalit in https://github.com/pydantic/pydantic-ai/pull/5487VercelAIAdapter now accepts providerExecuted / title on dynamic-tool message parts by @he-yufeng in https://github.com/pydantic/pydantic-ai/pull/5474WebFetchTool domain matching by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5592Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v2.0.0b2...v2.0.0b3
The third V2 beta, forked from v1.102.0. There are no new V2 breaking changes since v2.0.0b1 below — everything in that entry applies unchanged — but this beta picks up the latest V1 release on top, which is a bug-fix release; see the v1.102.0 release notes for the full list.
Install it the same way, pinning the exact pre-release version:
pip/uv-add "pydantic-ai==2.0.0b3"
For the full breaking-change list and the recommended upgrade path, see the v2.0.0b1 entry below; the only difference is that the latest V1 to upgrade through first is now v1.102.0.
<!-- Release notes generated using configuration in .github/release.yml at v2-main -->
<!-- Release notes generated using configuration in .github/release.yml at v2-main -->
For more information on Pydantic AI V2, see the release notes for yesterday's v2.0.0b1 and the Upgrade Guide.
Beta 2 adds no new breaking or v2-specific changes, but pulls in these changes from v1.101.0:
ctx.enqueue / agent_run.enqueue) by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4980XSearch capability model-agnostic via subagent fallback by @colesmcintosh in https://github.com/pydantic/pydantic-ai/pull/5120top_k model setting in GoogleModel, AnthropicModel, and CohereModel by @madanlalit in https://github.com/pydantic/pydantic-ai/pull/5558AnthropicModel dropping code execution tool results when continuing a conversation by @2830500285 in https://github.com/pydantic/pydantic-ai/pull/5568BaseModel tool arguments sent in wrapped form when the model uses default extra='ignore' by @macayu17 in https://github.com/pydantic/pydantic-ai/pull/5560xai-sdk 1.6.0 by @FU-max-boop in https://github.com/pydantic/pydantic-ai/pull/5355genai-prices minimum version by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/5565Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v2.0.0b1...v2.0.0b2
The second V2 beta, forked from v1.101.0. There are no new V2 breaking changes since v2.0.0b1 below — everything in that entry applies unchanged — but this beta picks up the latest V1 release on top, which adds the pending message queue (ctx.enqueue / agent_run.enqueue).
Install it the same way, pinning the exact pre-release version:
pip/uv-add "pydantic-ai==2.0.0b2"
For the full breaking-change list and the recommended upgrade path, see the v2.0.0b1 entry below; the only difference is that the latest V1 to upgrade through first is now v1.101.0.
V2.0.0b1 is forked from v1.100.0 (out today), which (along with other recent versions) deprecates most of what V2 removes. The recommended path (full…
V2 leans into a harness-first design, with capabilities as a core primitive. A capability is a single, composable unit that bundles an agent's tools, lifecycle hooks, instructions, and model settings — so a whole extension (a memory system, a guardrail, a coding toolkit) can reach every layer of the agent through one concept you pass via capabilities=[...]. Pydantic AI stays a small core: some capabilities ship with it, more come from the first-party Pydantic AI Harness, and others are third-party or your own.
Many of V2's changes move configuration that used to be spread across Agent arguments onto that primitive, alongside the behavior changes V1's stability guarantee didn't allow.
V2.0.0b1 is forked from v1.100.0 (out today), which (along with other recent versions) deprecates most of what V2 removes. The recommended path (full before → after in the Upgrade Guide):
uv add 'pydantic-ai==2.0.0b1'
pydantic-ai install now ships fewer extras — add providers like bedrock, groq, mistral explicitly.openai: model names now use the OpenAI Responses API; use openai-chat: to stay on Chat Completions.WebSearch/WebFetch are native-only by default, and MCP(url=...) runs locally by default.capture_run_messages() now also captures partial messages from interrupted runs.end_strategy='graceful') instead of being skipped.Most other removals were deprecated by v1.100.0; the Upgrade Guide has the complete list, split into changes covered vs. not covered by deprecation warnings.
It's a pre-release — stable V2.0 is expected within roughly two weeks — so pin the exact b version and expect occasional changes before then.
File issues or chat in Slack.
Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.100.0...v2.0.0b1
The first V2 beta, forked from v1.100.0, which deprecates most of what V2 removes. V2 leans into a harness-first design with capabilities as a core primitive: a single, composable unit that bundles an agent's tools, hooks, instructions, and model settings, reaching every layer of the agent through one concept. Many of V2's changes move configuration that used to be spread across Agent arguments onto that primitive, alongside the behavior changes that V1's stability guarantee didn't allow. Pydantic AI stays a small core: some capabilities ship with it, more come from the first-party Pydantic AI Harness, and others are third-party or your own.
The breaking changes below are split into two groups:
Recommended upgrade path. To make the jump as smooth as possible:
You can also upgrade straight to V2 and work through the list below directly — it's organized so a coding agent can apply the code changes mechanically. Resolving deprecation warnings on the latest V1 first is still the smoother path, since it spreads the work out and leaves you only the behavior changes to reason about consciously at the end.
Message history serialized with V1 (via [ModelMessagesTypeAdapter][pydantic_ai.messages.ModelMessagesTypeAdapter]) continues to deserialize in V2.
These removals and behavior changes could not be announced via a V1 deprecation warning, so review them even if you've resolved every deprecation warning on the latest V1.
Code changes:
None to object: an un-parameterized Agent(...) now infers Agent[object, str] instead of Agent[None, str], and the pydantic_graph StateT/RunEndT/DepsT defaults changed to match. Update explicit Agent[None, ...], RunContext[None], and Tool[None] annotations that don't actually require None dependencies to use object. This is a type-checking-only change; runtime behavior is unchanged. See #5307.pydantic_graph.persistence package and the pydantic_graph.mermaid module are removed, with no V2 equivalent for standalone Mermaid generation (render diagrams with Graph.render()). The builder API deliberately does not snapshot graph state, so there is no pydantic_graph replacement for the persistence package; to save, resume, and fork agent run state, Pydantic AI Harness ships the StepPersistence capability. The move of the [GraphBuilder][pydantic_graph.GraphBuilder] API out of pydantic_graph.beta to the top-level pydantic_graph was deprecation-announced; see below. See #5470.ModelProfile][pydantic_ai.profiles.ModelProfile] and its subclasses are now TypedDicts instead of dataclasses. Passing profile=OpenAIModelProfile(field=value) into a model still works unchanged; the migration only matters if you read or mutate profile fields, or call .update()/.from_profile(). See ModelProfile is now a TypedDict below. (#5481)Default behavior changes — same API, different runtime behavior (roughly ordered by how many users they affect):
uv add pydantic-ai / pip install pydantic-ai now installs a slimmer set of extras (frontier providers plus minimal integrations); providers like bedrock, groq, and mistral are no longer included by default, so you'll need to add the extras you use. See Slimmer default extras below. (#5467)end_strategy changed from 'early' to 'graceful': when a model calls function tools in the same response as a successful output tool, those function tools now run (and their side effects happen) instead of being skipped, and tool calls run in the order the model emitted them. See Parallel tool-call execution order below. (#5339)gen_ai.aggregated_usage.*. See Instrumentation defaults below. (#5523)capture_run_messages()][pydantic_ai.capture_run_messages] now also captures the partial ModelRequest/ModelResponse from an interrupted run, marked with state='interrupted' (a new ModelRequest.state field is added). Code that asserts on exact captured-message counts on error paths may need updating. See #5364.OutputToolCallEvent/OutputToolResultEvent instead of FunctionToolCallEvent/FunctionToolResultEvent. Separately, native tool calls and returns no longer emit dedicated events at all — the BuiltinToolCallEvent/BuiltinToolResultEvent classes are removed and they surface only via the standard PartStartEvent/PartDeltaEvent. See #5332 and #5476.ModelProfile][pydantic_ai.profiles.ModelProfile] is now a TypedDict {#modelprofile-is-now-a-typeddict}See the Model Profile guide for an overview of what a model profile is and how to configure one.
[ModelProfile][pydantic_ai.profiles.ModelProfile] and all its subclasses ([OpenAIModelProfile][pydantic_ai.profiles.openai.OpenAIModelProfile], [AnthropicModelProfile][pydantic_ai.profiles.anthropic.AnthropicModelProfile], [GoogleModelProfile][pydantic_ai.profiles.google.GoogleModelProfile], BedrockModelProfile, etc.) are now TypedDict(total=False) instead of @dataclass. This unifies the mental model with [ModelSettings][pydantic_ai.settings.ModelSettings] (also a TypedDict) and enables direct dict-spread for cross-class merging.
ModelProfile.update() and ModelProfile.from_profile() are removed; use the module-level [merge_profile][pydantic_ai.profiles.merge_profile] (later argument wins per key).
Migration recipes:
| v1 (dataclass) | v2 (TypedDict) |
|---|---|
OpenAIModelProfile(field=value) |
Same syntax; returns a partial dict instead of a fully-defaulted instance. |
profile.field (attribute read) |
profile.get('field', <default>) — non-trivial defaults are exported from [pydantic_ai.profiles][pydantic_ai.profiles] (e.g. [DEFAULT_THINKING_TAGS][pydantic_ai.profiles.DEFAULT_THINKING_TAGS], [DEFAULT_PROMPTED_OUTPUT_TEMPLATE][pydantic_ai.profiles.DEFAULT_PROMPTED_OUTPUT_TEMPLATE]); the fully-merged base is [DEFAULT_PROFILE][pydantic_ai.profiles.DEFAULT_PROFILE]. |
profile.field = value (attribute write) |
profile['field'] = value |
dataclasses.replace(profile, field=value) |
{**profile, 'field': value} or merge_profile(profile, ModelProfile(field=value)) |
profile.update(other) |
merge_profile(profile, other) |
OpenAIModelProfile.from_profile(p) |
Just p — no upcasting needed |
Model(name, profile=full_profile) (full replace) |
Now merges on top of the provider's default profile — usually what you want. For a hard replace use Model(name, profile=lambda _default: full_profile). |
Model(name, profile=fn) where fn: Callable[[str], ModelProfile | None] |
Removed — the user-passed callable is now Callable[[ModelProfile], ModelProfile], receiving the resolved default and returning the final profile. The (model_name: str) -> ModelProfile | None shape is still accepted internally by Provider.model_profile. |
isinstance(profile, OpenAIModelProfile) |
Not supported by TypedDict at runtime — raises TypeError. Use isinstance(profile, dict) or check key presence ('openai_chat_supports_web_search' in profile). Pyright still narrows correctly via the TypedDict subclass annotation. |
Model.profile is now the single source of truth for the resolved profile. It is composed by [merge_profile][pydantic_ai.profiles.merge_profile] in this order (later wins):
DEFAULT_PROFILE][pydantic_ai.profiles.DEFAULT_PROFILE] — base defaults for every documented key.Provider.model_profile(model_name) — provider/model-specific resolution.profile= argument — either a partial dict (merged on top) or a Callable[[ModelProfile], ModelProfile] (full control: receives the resolved default, returns the final profile).In v1, ModelProfile.update() silently filtered out fields not declared on the target class. In v2, dict-spread preserves every key.
This means e.g. a Bedrock-hosted Anthropic model's resolved profile now carries the upstream anthropic_* fields alongside the bedrock_* fields, where v1 dropped them. No in-tree model class reads cross-class fields, so behavior is unchanged in the standard providers; but custom model classes that do profile.get('anthropic_supports_adaptive_thinking', False) on a non-Anthropic route will now see the value the upstream Anthropic profile set, where v1 always returned the default.
See the Model Profile guide for how to configure a profile, and PR #5481 for the full ModelProfile redesign.
The default [end_strategy][pydantic_ai.agent.EndStrategy] changed from 'early' to 'graceful'. This only affects responses where a model calls function tools in the same response as an output tool (the call that ends the run). When that output tool succeeds, the function tools requested alongside it now run by default instead of being skipped, so their side effects happen and their results reach the model if the run continues; and a function tool's [ModelRetry][pydantic_ai.exceptions.ModelRetry] now suppresses the output result so the model can correct itself on the next round. The case where every output tool fails is unchanged: function tools run and the run continues either way. Most agents don't need any change. If you relied on the run ending the instant an output tool succeeds — skipping any function tools requested in the same response — set end_strategy='early' explicitly.
The sequential=True flag on a tool is now a per-tool barrier rather than a batch-wide serial switch: a sequential tool runs alone, but other tools in the same response still run in parallel around it. The barrier now also applies to output tools via [ToolOutput(sequential=True)][pydantic_ai.output.ToolOutput], not just function tools. To run all of a run's tools serially, wrap the run in [agent.parallel_tool_call_execution_mode('sequential')][pydantic_ai.agent.AbstractAgent.parallel_tool_call_execution_mode] or set parallel_tool_calls=False on the [model settings][pydantic_ai.settings.ModelSettings].
See Parallel Output Tool Calls for the full behavior of all three strategies, and #5339.
pydantic-ai extrasA bare uv add pydantic-ai / pip install pydantic-ai now installs pydantic-ai-slim[openai,anthropic,google,cli,mcp,evals,web,retries,logfire] — frontier providers plus minimal integrations. Providers and integrations that were previously bundled are no longer installed by default; add the ones you use explicitly, e.g. uv add 'pydantic-ai[bedrock,groq]': bedrock, groq, mistral, cohere, xai, huggingface, temporal, ag-ui, ui, and spec. See the installation guide for the full list of extras.
Some pydantic-ai-slim extras were also removed outright (not just dropped from the default bundle): the outlines-* extras (the Outlines integration is removed), vertexai (Vertex AI is now served by the google extra), fastmcp (the FastMCP back-compat shim is removed), and a2a (A2A now lives in the upstream fasta2a package). See #5467.
The default instrumentation format is now version 5 (versions 2–4 still work but emit a deprecation warning; version 1 and its event_mode=/logger_provider= arguments are removed). In version 5, deferred tool calls (CallDeferred/ApprovalRequired) are no longer recorded as span errors.
Separately, [InstrumentationSettings][pydantic_ai.models.instrumented.InstrumentationSettings]'s use_aggregated_usage_attribute_names now defaults to True: agent run spans report token usage under gen_ai.aggregated_usage.* while model request spans keep gen_ai.usage.*, which avoids double-counting in backends that sum parent and child usage. Dashboards and alerts that read token usage from run spans must be updated, or set use_aggregated_usage_attribute_names=False to keep the V1 attribute names.
See #5523.
These changes were announced in the latest V1 releases via deprecation warnings that name the replacement API. If you upgraded to the latest V1 and resolved every warning, you've already made them. The V1 → V2 migration map carries the full before → after for every symbol; this section records the behavior that changes with them and the PRs each one landed in.
Behavior changes that flip silently if the V1 deprecation warning was not addressed — even though these were announced, an unaddressed warning means the behavior changes without raising an error, so confirm you've handled them:
openai: model prefix now uses the OpenAI Responses API ([OpenAIResponsesModel][pydantic_ai.models.openai.OpenAIResponsesModel]) instead of the Chat Completions API ([OpenAIChatModel][pydantic_ai.models.openai.OpenAIChatModel]). Use openai-chat: to keep Chat Completions, or openai-responses: to opt into the new default explicitly. Announced via #5334; flipped in #5469.WebSearch and WebFetch capabilities are now native-only and raise on models that don't support them, and MCP(url=...) runs the server locally by default. Restore the V1 fallbacks with WebSearch(local='duckduckgo'), WebFetch(local=True), and MCP(url=..., native=True). Announced via #5331; changed in #5333.API removals and renames — look each old name up in the migration map; the PRs that announced and landed each group are:
| Group | PRs |
|---|---|
Providers: Grok → xAI (grok: prefix → xai:) |
#5460 |
Providers: Google GLA/Vertex → GoogleProvider/GoogleCloudProvider, GeminiModel → GoogleModel |
#5336, #5543, #5479 |
Models: OpenAIModel → OpenAIChatModel, system_prompt_role and sampling-settings move into the profile |
#5468 |
Models: StreamedResponse.usage() becomes a property (affects custom Model subclasses) |
#5546 |
Models: bare provider-prefix-less names (Agent('gpt-5')) now raise UserError |
#5464 |
Native tools: builtin_tools → native_tools throughout |
#5338, #5396 |
Native tools: UrlContextTool → WebFetchTool |
#5458 |
MCP: per-transport server classes → MCPToolset |
#5325, #5337 |
Agent config → capabilities: instrument= |
#5434 |
Agent config → capabilities: event_stream_handler=, prepare_tools= |
#5335, #5475 |
Agent config → capabilities: history_processors= |
#5425 |
Agent config: mcp_servers= → toolsets=, sequential_tool_calls() → parallel_tool_call_execution_mode() |
#5466 |
Tools: DeferredToolCalls → DeferredToolRequests, DeferredToolset → ExternalToolset |
#5459 |
Tools: FunctionToolset.tool() now requires a RunContext first parameter |
#5462 |
Tools: pydantic_ai.ext.aci removed (wrap with Tool.from_schema) |
#5510, #5467 |
Usage and response-field renames (request_tokens → input_tokens, vendor_details → provider_details, …) |
#5476 |
Events: dedicated OutputToolCallEvent/OutputToolResultEvent, FunctionToolResultEvent.result → .part |
#5332 |
Streaming: StreamedRunResult accessor renames, stream_responses() → stream_response() |
#5296, #5463 |
Streaming: Agent.run_stream_events() is an async context manager only |
#5440 |
Results: result.usage()/result.timestamp()/stream.get() become properties |
#5263 |
Integrations: Agent.to_a2a() and the bundled fasta2a move upstream |
#5426, #5502 |
Integrations: Agent.to_ag_ui()/AGUIApp → AGUIAdapter, cached_async_http_client → create_async_http_client() |
#5345, #5464 |
Graph: pydantic_graph.beta imports move to top-level pydantic_graph |
#5306, #5470 |
Instrumentation: version=1 and its event_mode=/logger_provider= arguments removed |
#5523 |
Pydantic Evals: keyword-only arguments, required Dataset(name=...), Evaluator.name → get_serialization_name() |
#5547, #5548 |
Pydantic Evals: evaluation_name/evaluator_version class attributes → get_default_evaluation_name()/get_evaluator_version() |
#5554, #5556 |
Four of these carry a caveat the name mapping alone doesn't convey:
Agent.set_mcp_sampling_model() is not removed — it still sets the sampling model on every registered MCPToolset, while MCPToolset(sampling_model=...) sets it on one toolset at construction.version=2/3/4 still work but now emit a deprecation warning, and the default is version=5 — see Instrumentation defaults above for the behavior changes that ship with it.Agent(instrument=...): only the constructor arguments are removed. The Agent.instrument property, Agent.instrument_all(), and InstrumentedModel are unchanged.A maintenance release for the v1 line, carrying the v1 backports of the four security fixes released in 2.44.0 . See each advisory for full details an…
A maintenance release for the v1 line, carrying the v1 backports of the four security fixes released in 2.44.0. See each advisory for full details and affected versions.
web_fetch, in both the HTML conversion and the charset decode, blocking the event loop. Reported by @BrianWillows. (#8399, #8434)web_fetch_tool domain lists compared as written rather than in the form the resolver uses. (#8409)include_content=False. Reported by @BrianWillows. (#8404, #8422, #8429)Also carried over: credentials are now dropped on a safe_download redirect whenever the full origin changes, not only the hostname (#8410). This was fixed on the v2 line some time ago and had never been backported.
Patched in 1.107.6; all four are also patched on the v2 line in 2.44.0.
Every code change in this release is one of the security fixes above. Maintenance alongside them:
v1 CI and its mcp, anthropic, and duckduckgo extras (v1 backport) by @DouweM in #8406a2a extra (v1) by @DouweM in #8412Full Changelog: v1.107.5...v1.107.6
GHSA-q2xc-rrxj-58x9 : the local dev web chat UI ( Agent.to_web() , clai web ) didn't validate the Host header, so DNS rebinding from a website you vis
Agent.to_web(), clai web) didn't validate the Host header, so DNS rebinding from a website you visit could reach it and run the served agent with your local process's tools and credentials. Fixed in pydantic-ai/pydantic-ai-slim 1.107.5 by validating Host against localhost/loopback/LAN addresses by default; deployments reached under a real hostname must opt in with the new allowed_hosts setting. Backport of allowed_hosts by @DouweM in #7438Full Changelog: v1.107.4...v1.107.5
This release backports two security fixes to the v1 line:
Note: an earlier
v1.107.3tag/release was cut and deleted tonight — a build-tooling issue (#7394:hatchling1.32.0 emitted a package-metadata version PyPI's publish validator didn't yet accept) blocked its publish before anything reached PyPI, so nothing under that version number was ever installable. This release (1.107.4) carries the same fixes with the build issue resolved.
This release backports two security fixes to the v1 line:
Agent.to_web(), clai web) chat endpoint didn't check the request's content type, so a plain cross-origin request from a website open in the developer's browser could reach it without a CORS preflight and trigger the served agent to run and execute its tools with the local process's privileges and credentials. The endpoint now requires Content-Type: application/json.InstrumentationSettings(include_content=False) when the retry wasn't tied to a tool call.Patched in 1.107.4; both are also patched on the v2 line (2.28.0 and 2.27.1 respectively).
v1 by @DouweM in #7381Full Changelog: v1.107.2...v1.107.4
Fixes an availability vulnerability: unbounded memory use when downloading remote content via the local web_fetch tool or FileUrl media downloads, whi…
Fixes an availability vulnerability: unbounded memory use when downloading remote content via the local web_fetch tool or FileUrl media downloads, which could exhaust process memory and crash the worker. Patched versions enforce a default 50 MiB download cap. See GHSA-v2xh-2vp8-57h8. Patched in 1.107.2 (v1) and 2.24.0 (v2).
web_fetch and media URL downloads by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/7308Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.107.1...v1.107.2
This release patches [GHSA-jpr8-2v3g-wgf9](https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-jpr8-2v3g-wgf9) (moderate, CWE-863) on the
This release patches GHSA-jpr8-2v3g-wgf9 (moderate, CWE-863) on the v1 line. On the AG-UI serving path (Agent.to_ag_ui() / AGUIAdapter), UIAdapter.sanitize_messages anchored its dangling-tool-call strip to an index computed before sanitization. When a trailing client message was dropped during sanitization (for example a client system message under the default manage_system_prompt='server'), a preceding assistant response carrying an unresolved tool call could be re-exposed as the new tail and executed with client-chosen arguments.
pydantic-ai / pydantic-ai-slim >= 1.88.0, < 1.107.1 (v1) and >= 2.0.0, < 2.5.0 (v2)1.107.1 (v1) and 2.5.0 (v2)requires_approval=True / ApprovalRequiredToolset, or if your tool handlers validate their arguments and enforce authorization themselves.See the advisory for details and workarounds.
sanitize_messages tail handling when a trailing client message is dropped by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/6407Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.107.0...v1.107.1
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
UploadedFile consistently with FileUrl in UI adapters by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5772
VercelAIAdapter trusts client-controlled provider metadata to construct UploadedFile references (confused-deputy file read) https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-h7p7-w5gc-xj3wVercelAIAdapter), AND your model-provider or cloud-storage account holds files referenceable by an attacker-guessable UploadedFile id or storage URI (e.g. s3://…, gs://…).UploadedFile parts before running it.AGUIAdapter / Agent.to_ag_ui on defaults — the preserve_file_data flag that re-enables this path is off by default.known_model_names() to enumerate KnownModelName members by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5803CachePoint and prompt caching support by @Adversarian in https://github.com/pydantic/pydantic-ai/pull/4604claude-fable-5) and Claude Mythos 5 (claude-mythos-5) support by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5849message=None Bedrock start events in stream path by @Bartok9 in https://github.com/pydantic/pydantic-ai/pull/5818AnthropicModel.count_tokens with native tools by @kazmer97 in https://github.com/pydantic/pydantic-ai/pull/5704Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.106.0...v1.107.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
UploadedFile consistently with FileUrl in UI adapters by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5772
VercelAIAdapter trusts client-controlled provider metadata to construct UploadedFile references (confused-deputy file read) https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-h7p7-w5gc-xj3wVercelAIAdapter), AND your model-provider or cloud-storage account holds files referenceable by an attacker-guessable UploadedFile id or storage URI (e.g. s3://…, gs://…).UploadedFile parts before running it.AGUIAdapter / Agent.to_ag_ui on defaults — the preserve_file_data flag that re-enables this path is off by default.seed setting to xAI by @colesmcintosh in https://github.com/pydantic/pydantic-ai/pull/5741api_host and timeout to XaiProvider by @colesmcintosh in https://github.com/pydantic/pydantic-ai/pull/5742event_stream_handler doesn't consume the stream by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/5771Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.105.0...v1.106.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
reasoning_effort support and current xAI model names by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/5454gateway/ model construction inside a Temporal workflow by passing provider SDKs through the sandbox by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/5733GoogleModelSettings.google_cached_content so request omits system_instruction, tools, and tool_config by @gaurav0107 in https://github.com/pydantic/pydantic-ai/pull/5681Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.104.0...v1.105.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
thinking=False on hybrid OpenRouter/xAI/Bedrock routes, aligning silent-drop with direct routes by @sarth6 in https://github.com/pydantic/pydantic-ai/pull/5433tool_choice cache preservation by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5674Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.103.0...v1.104.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
list_prompts and get_prompt functionality to McpServer by @bdore in https://github.com/pydantic/pydantic-ai/pull/3889VercelAIAdapter's UIMessage.metadata by @Genmin in https://github.com/pydantic/pydantic-ai/pull/5279anthropic_eager_input_streaming in OpenRouterModel by @Alex-Resch in https://github.com/pydantic/pydantic-ai/pull/5656malformed_model_output and malformed_tool_use to FinishReason.error by @kuishou68 in https://github.com/pydantic/pydantic-ai/pull/5640type='adaptive' in _is_thinking_enabled by @sevakva in https://github.com/pydantic/pydantic-ai/pull/5651force_download flag from client-submitted FileUrl parts in UIAdapter.sanitize_messages by @colesmcintosh in https://github.com/pydantic/pydantic-ai/pull/5571None by @dfm88 in https://github.com/pydantic/pydantic-ai/pull/5188Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.102.0...v1.103.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
FileUrl into force_download='allow-local' on a URL that is, or could be, influenced by untrusted input, AND runs on a NAT64- or ISATAP-configured network (e.g. some IPv6-only or dual-stack-with-NAT64 Kubernetes setups).Agent.to_web / clai web; VercelAIAdapter; AGUIAdapter / Agent.to_ag_uistrict=None tools to strict mode with Bedrock, and skip strict field when botocore is too old by @shailendher in https://github.com/pydantic/pydantic-ai/pull/5580variable_instructions span attribute by @madanlalit in https://github.com/pydantic/pydantic-ai/pull/5487VercelAIAdapter now accepts providerExecuted / title on dynamic-tool message parts by @he-yufeng in https://github.com/pydantic/pydantic-ai/pull/5474WebFetchTool domain matching by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5592Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.101.0...v1.102.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
ctx.enqueue / agent_run.enqueue) by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4980XSearch capability model-agnostic via subagent fallback by @colesmcintosh in https://github.com/pydantic/pydantic-ai/pull/5120top_k model setting in GoogleModel, AnthropicModel, and CohereModel by @madanlalit in https://github.com/pydantic/pydantic-ai/pull/5558AnthropicModel dropping code execution tool results when continuing a conversation by @2830500285 in https://github.com/pydantic/pydantic-ai/pull/5568BaseModel tool arguments sent in wrapped form when the model uses default extra='ignore' by @macayu17 in https://github.com/pydantic/pydantic-ai/pull/5560xai-sdk 1.6.0 by @FU-max-boop in https://github.com/pydantic/pydantic-ai/pull/5355genai-prices minimum version by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/5565Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.100.0...v1.101.0
Deprecate gateway/gemini: prefix in favor of gateway/google-cloud: by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5543
<!-- Release notes generated using configuration in .github/release.yml at main -->
FileUrl into force_download='allow-local' on a URL that is, or could be, influenced by untrusted input.Agent.to_web / clai web; VercelAIAdapter; AGUIAdapter / Agent.to_ag_uigateway/gemini: prefix in favor of gateway/google-cloud: by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5543StreamedResponse.usage(); raise on region-less Gateway API keys by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5546evaluation_name / evaluator_version attribute pattern in favor of explicit accessor methods by @dmontagu in https://github.com/pydantic/pydantic-ai/pull/5554Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.99.0...v1.100.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
FileUrl into force_download='allow-local' on a URL that is, or could be, influenced by untrusted input.Agent.to_web / clai web; VercelAIAdapter; AGUIAdapter / Agent.to_ag_uigemini-3.5-flash model by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5527Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.98.0...v1.99.0
Deprecate pydantic_ai.ext.aci (tool_from_aci and ACIToolset) by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5510
<!-- Release notes generated using configuration in .github/release.yml at v1.98.0 -->
OpenAIResponsesModel.count_tokens) by @colesmcintosh in https://github.com/pydantic/pydantic-ai/pull/3951Agent tool_retries=/output_retries= with retries: int | AgentRetries by @Kludex in https://github.com/pydantic/pydantic-ai/pull/5500fastmcp.server at runtime by @Kymi808 in https://github.com/pydantic/pydantic-ai/pull/5514pydantic_ai.ext.aci (tool_from_aci and ACIToolset) by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5510Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.97.0...v1.98.0
…to google:, google-vertex: to google-cloud:; deprecate old names by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5336
<!-- Release notes generated using configuration in .github/release.yml at main -->
OnlineEvaluator.run_on_errors to opt into evaluating failed calls by @dmontagu in https://github.com/pydantic/pydantic-ai/pull/5456GoogleProvider(vertexai=True|False) into GoogleProvider + GoogleCloudProvider; rename provider ID google-gla: to google:, google-vertex: to google-cloud:; deprecate old names by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5336MCPToolset that uses fastmcp-slim[client], deprecate MCPServer* and FastMCPToolset by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5325ModelResponse.state to incomplete while response is still streaming by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/5455pydantic_graph.beta API out of beta, deprecate old API by @dmontagu in https://github.com/pydantic/pydantic-ai/pull/5306stream_responses() for stream_response(); new singular yields ModelResponse instead of (ModelResponse, is_last) tuple by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5296Agent.to_a2a() and bundled fasta2a integration; fasta2a has been adopted by DataLayer and users can use fasta2a.pydantic_ai (requires fasta2a v0.6.1) instead by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5426Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.96.1...v1.97.0
Deprecate Agent constructor prepare_tools=, prepare_output_tools=, event_stream_handler= in favor of PrepareTools, PrepareOutputTools, ProcessEventStr…
<!-- Release notes generated using configuration in .github/release.yml at main -->
Agent constructor prepare_tools=, prepare_output_tools=, event_stream_handler= in favor of PrepareTools, PrepareOutputTools, ProcessEventStream capabilities by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5335input_fidelity when None in image generation tool by @pydanty[bot] in https://github.com/pydantic/pydantic-ai/pull/5415openai_system_prompt_role in OpenAIResponsesModel by @navalprakhar in https://github.com/pydantic/pydantic-ai/pull/5430Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.96.0...v1.96.1
Deprecate Agent(history_processors=) in favor of capabilities=[ProcessHistory(...)] by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5425
<!-- Release notes generated using configuration in .github/release.yml at main -->
openai-chat: prefix and warn on bare openai: which will switch to use the Responses API in v2 by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5334Agent(history_processors=) in favor of capabilities=[ProcessHistory(...)] by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5425result.usage(), result.timestamp(), stream.get() in favor of property-style result.usage, result.timestamp, stream.response by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5263AGUIApp, Agent.to_ag_ui(), and pydantic_ai.ag_ui shim in favor of AGUIAdapter by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5345OutlinesModel and OutlinesProvider by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5432Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.95.1...v1.96.0
fix: un-deprecate Agent.instrument setter and InstrumentedModel by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5427
<!-- Release notes generated using configuration in .github/release.yml at main -->
current_otel_traceparent imports eager (unbreak agent runs in Temporal workflows) by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5422Agent.instrument setter and InstrumentedModel by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5427Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.95.0...v1.95.1
Add Instrumentation capability; deprecate Agent(instrument=...) by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4967
<!-- Release notes generated using configuration in .github/release.yml at main -->
Instrumentation capability; deprecate Agent(instrument=...) by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4967capabilities=[NativeTool(...)] by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5338local= opt-in for provider-adaptive capability fallback; deprecate auto-fallback by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5331tool-input-(available|error) on FunctionToolCallEvent by @sadra-barikbin in https://github.com/pydantic/pydantic-ai/pull/5292mistral as default dependency, exclude compromised 2.4.6 by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5393Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.94.0...v1.95.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
openai_chat_supports_multiple_system_messages profile flag by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5375mistralai as dependency from pydantic-ai by @Kludex in https://github.com/pydantic/pydantic-ai/pull/5384Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.93.0...v1.94.0
Yield OutputToolCallEvent/OutputToolResultEvent for output tool calls; deprecate function-tool events for failing output tool calls by @DouweM in http…
<!-- Release notes generated using configuration in .github/release.yml at main -->
tool_choice setting by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/3611OutputToolCallEvent/OutputToolResultEvent for output tool calls; deprecate function-tool events for failing output tool calls by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5320Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.92.0...v1.93.0
Add runtime output_retries override + deprecate retries + internal retry-field rename by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/50…
<!-- Release notes generated using configuration in .github/release.yml at main -->
output_retries override + deprecate retries + internal retry-field rename by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/5075attempted exit cancel scope in different task by running MCP session in a dedicated task by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4514for_run RunContext with run_id, conversation_id, and metadata by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5330CaseLifecycle.teardown() by @voorhs in https://github.com/pydantic/pydantic-ai/pull/5322Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.91.0...v1.92.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
gpt-image-2 options by @banteg in https://github.com/pydantic/pydantic-ai/pull/5234deepseek-v4-flash anddeepseek-v4-pro by @SuperMarioYL in https://github.com/pydantic/pydantic-ai/pull/5195ModelResponse in OpenAI Chat assistant message mapping by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5300Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.90.0...v1.91.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
OpenAIResponsesModelSettings.openai_conversation_id by @corytomlinson in https://github.com/pydantic/pydantic-ai/pull/5224pydantic/ai-chat-ui 1.2.0 by @johnthagen in https://github.com/pydantic/pydantic-ai/pull/5246Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.89.1...v1.90.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
wrap_validation_errors on ToolManager function-tool methods by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5275anyio.Lock creation via cached_property to bind to running loop by @Kludex in https://github.com/pydantic/pydantic-ai/pull/5265Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.89.0...v1.89.1
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
conversation_id for cross-run correlation by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5251builtin_tools to agent.override by @mplemay in https://github.com/pydantic/pydantic-ai/pull/5248Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.88.0...v1.89.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
prepare_tools to function tools, add prepare_output_tools by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4859service_tier model setting; Anthropic + Gemini API + Vertex Priority PayGo support by @markmcd in https://github.com/pydantic/pydantic-ai/pull/4926fast mode for opus 4.6 by @bohdanhr in https://github.com/pydantic/pydantic-ai/pull/4300phase on assistant messages by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5229UIAdapter.sanitize_messages and allowed_file_url_schemes by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5228cache_control for anthropic_cache_messages by @Wh1isper in https://github.com/pydantic/pydantic-ai/pull/5227CallToolsNode stream fails by @thejens in https://github.com/pydantic/pydantic-ai/pull/4799Agent(retries=...) to user-provided toolsets by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4745Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.87.0...v1.88.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
HandleDeferredToolCalls capability and handle_deferred_tool_calls hook by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5142ProcessEventStream capability by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5141Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.86.1...v1.87.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
choices=None in streamed chunks (#5165) by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/5170container_id as string on reuse; unwrap broken {id: x} shape by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/5168input on tool-call retries by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5181MCPServer.__aexit__ called more times than __aenter__ in DynamicToolset by @anishesg in https://github.com/pydantic/pydantic-ai/pull/5171dict fields with Anthropic strict mode by @rahulmansharamani14 in https://github.com/pydantic/pydantic-ai/pull/4321gen_ai.operation.name=execute_tool on tool-execution spans by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5182Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.86.0...v1.86.1
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
UIAdapter.manage_system_prompt + ReinjectSystemPrompt capability by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4087messageId by @MukundaKatta in https://github.com/pydantic/pydantic-ai/pull/5156reasoning_content from Gemini 2.5 models by @JulieLiu99 in https://github.com/pydantic/pydantic-ai/pull/5155Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.85.1...v1.86.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
input from retry messages by @navalprakhar in https://github.com/pydantic/pydantic-ai/pull/4947dump_messages() by @tijmenhammer in https://github.com/pydantic/pydantic-ai/pull/4831Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.85.0...v1.85.1
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.84.1...v1.85.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
dict-shaped validated args to hooks for single-BaseModel tools by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5137Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.84.0...v1.84.1
…treating it as a hardening fix rather than a vulnerability.
<!-- Release notes generated using configuration in .github/release.yml at main -->
FileSearchTool response parsing by @DouweM in #5106. This was first released in yesterday's v1.83.0. The pattern was reachable in principle from Gemini streaming responses but could not be triggered via real Gemini output in testing, so we're treating it as a hardening fix rather than a vulnerability.OpenAICompaction by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5108OllamaModel subclass and correct Ollama capability flags to fix structured output on Ollama Cloud by @Goldokpa in https://github.com/pydantic/pydantic-ai/pull/4160openai_logprobs for streamed responses by @iAmir97 in https://github.com/pydantic/pydantic-ai/pull/5091openai_previous_response_id seeds by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5126new_messages() even with current run_id by @madanlalit in https://github.com/pydantic/pydantic-ai/pull/4731Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.83.0...v1.84.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
XSearchTool and FileSearch support for xAI by @colesmcintosh in https://github.com/pydantic/pydantic-ai/pull/4165FastMCPToolset by @Boryotto in https://github.com/pydantic/pydantic-ai/pull/4929Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.82.0...v1.83.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
openai_previous_response_id='auto' by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5086CombinedToolset and CombinedCapability by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5085ToolDefinition.function_signature by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5087Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.81.0...v1.82.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
run_id from cache key computation in PrefectAgentInputs by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/3890JsonSchemaTransformer by @Dharit13 in https://github.com/pydantic/pydantic-ai/pull/4989Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.80.0...v1.81.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
CapabilityOrdering (innermost, outermost, wraps, wrapped_by, requires`) by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5036Hooks ordering parameter and instance refs in wraps/wrapped_by by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5048OpenAICompaction and AnthropicCompaction capabilities by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4943get_wrapper_toolset iteration for consistency with wrap_ hooks by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5036mcp optional for DBOS module import by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5050Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.79.0...v1.80.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
dump_messages by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/3971create_async_http_client and context manager by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4421apply() to AbstractCapability, CombinedCapability, and WrapperCapability by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5022$refs in renamed schema defs, handle missing keywords, and detect semantically different defs by @Ricardo-M-L in https://github.com/pydantic/pydantic-ai/pull/5020run() when capability/hook overrides wrap_run_event_stream by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5028on_node_run_error and after_node_run hook recovery by @DouweM in https://github.com/pydantic/pydantic-ai/pull/5023UserError messages by @graydeon in https://github.com/pydantic/pydantic-ai/pull/4976Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.78.0...v1.79.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
return_schema and function_signature to ToolDefinition by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/4964SetToolMetadata capability by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4964Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.77.0...v1.78.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
WebFetch tool and have WebFetch capability use it when provider lacks builtin support by @DEENUU1 in https://github.com/pydantic/pydantic-ai/pull/4906defer_loading to tools and toolsets to enable tool search by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4090ThreadExecutor capability and Agent.using_thread_executor() by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4942server_message_id in VercelAIEventStream by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4579ModelHTTPError/ModelAPIError by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4889Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.76.0...v1.77.0
Have ImageGeneration capability auto-fallback to subagent with imagegen model if main model lacks imagegen by @DouweM in https://github.com/pydantic/p
ImageGeneration capability auto-fallback to subagent with imagegen model if main model lacks imagegen by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4910agent to RunContext by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4922gen_ai.operation.name span attribute in agent runs by @adriangb in https://github.com/pydantic/pydantic-ai/pull/4936Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.75.0...v1.76.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
DataUIPart in Vercel AI adapter user message processing (#4704) by @sudo-nick in https://github.com/pydantic/pydantic-ai/pull/4712run_sync and run_stream for invalid output tool calls by @Spectual in https://github.com/pydantic/pydantic-ai/pull/4860Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.74.0...v1.75.0
deprecate: Dataset without name parameter by @Kludex in https://github.com/pydantic/pydantic-ai/pull/4862
<!-- Release notes generated using configuration in .github/release.yml at main -->
TextContent for user prompts with metadata not sent to model by @thisisarko in https://github.com/pydantic/pydantic-ai/pull/4432AbstractToolset.get_instructions method and include_instructions arg to MCP Servers by @DougTrajano in https://github.com/pydantic/pydantic-ai/pull/4123Dataset without name parameter by @Kludex in https://github.com/pydantic/pydantic-ai/pull/4862CallDeferred/ApprovalRequired from marking tool spans as errors by @jaiwinshah3 in https://github.com/pydantic/pydantic-ai/pull/4661service_tier validation failure for OpenAI-compatible providers by @majdalsado in https://github.com/pydantic/pydantic-ai/pull/4911gemini-embedding-2-preview by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4913ToolOutput.max_retries parameter by @JasonCZMeng in https://github.com/pydantic/pydantic-ai/pull/4687Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.73.0...v1.74.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
CaseLifecycle hooks to Dataset.evaluate by @dmontagu in https://github.com/pydantic/pydantic-ai/pull/4854ModelRetry for retry control flow by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4858ModelRequestContext by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4855x-ai matching genai-prices by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/4789>=1.24.0 by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/4863Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.72.0...v1.73.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
anthropic_eager_input_streaming to AnthropicModelSettings by @moe9195 in https://github.com/pydantic/pydantic-ai/pull/4842url= on MCP capability, in Python or AgentSpec by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4846Thinking capability type inference by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4846OpenRouterReasoning effort values by @majdalsado in https://github.com/pydantic/pydantic-ai/pull/4709ToolReturn metadata through Temporal serialization by @alvinttang in https://github.com/pydantic/pydantic-ai/pull/4684Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.71.0...v1.72.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
AgentSpec and Agent.from_file for loading agents from YAML/JSON, with support for templated instructions referencing deps (via TemplateStr) by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4640Hooks capability for defining hooks using decorators by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4640Thinking capability and cross-provider thinking model setting by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4640WebSearch, WebFetch, MCP, ImageGeneration that automatically fall back from builtin (provider) tools to local tools by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4640AbstractToolset.for_run and for_run_step for state isolation by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4640openai:gpt-5.4-mini and openai:gpt-5.4-nano by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/4787Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.70.0...v1.71.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
bedrock_inference_profile to BedrockModelSettings and BedrockEmbeddingSettings by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4697embedding_types to Cohere embed() to prevent SDK TypeError by @adityasingh2400 in https://github.com/pydantic/pydantic-ai/pull/4524Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.69.0...v1.70.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
description parameter to Agent and set gen_ai.agent.description on span by @Kludex in https://github.com/pydantic/pydantic-ai/pull/4677FallbackModel by @sarth6 in https://github.com/pydantic/pydantic-ai/pull/3786FunctionToolset.tool via tool/tool_plain split by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/4626details dict in Usage.__add__ to prevent mutation of or… by @sksvineeth in https://github.com/pydantic/pydantic-ai/pull/4606Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.68.0...v1.69.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
running tools parent span by @Kludex in #4560gpt-5.3-chat-latest by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4567Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.67.0...v1.68.0
<!-- Release notes generated using configuration in .github/release.yml at v1.68.0 -->
running tools parent span by @Kludex in https://github.com/pydantic/pydantic-ai/pull/4560gpt-5.3-chat-latest by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4567Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.67.0...v1.68.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
WebSearchTool for OpenRouterModel through OpenRouter plugins by @mochow13 in https://github.com/pydantic/pydantic-ai/pull/4022Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.66.0...v1.67.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
gemini-3.1-flash-image-preview) by @adtyavrdhn in https://github.com/pydantic/pydantic-ai/pull/4525TemporalAgent with multiple models by @mattbrandman in https://github.com/pydantic/pydantic-ai/pull/4100HasMatchingSpan YAML export/import round-trip for SpanQuery arguments by @debu-sinha in https://github.com/pydantic/pydantic-ai/pull/4454Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.65.0...v1.66.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
UploadedFile object by @mattbrandman in https://github.com/pydantic/pydantic-ai/pull/3942gemini-3.1-flash-lite-preview model by @rian-dolphin in https://github.com/pydantic/pydantic-ai/pull/4517__reduce__ to exception classes for pickle support by @OiPunk in https://github.com/pydantic/pydantic-ai/pull/4504Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.64.0...v1.65.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
template=False on PromptedOutput and NativeOutput to disable schema prompt by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4497run_id on ModelRequest in UI adapter runs by @madanlalit in https://github.com/pydantic/pydantic-ai/pull/4419ModelHTTPError/ModelAPIError by @saakshigupta2002 in https://github.com/pydantic/pydantic-ai/pull/4437__aexit__ guard inside lock to prevent TOCTOU race by @jameslcowan in https://github.com/pydantic/pydantic-ai/pull/4435BaseToolCallPart.has_content() incorrectly returns False for falsy arg values by @bsherifi in https://github.com/pydantic/pydantic-ai/pull/4442max_tokens by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4496dump_messages output with Vercel spec by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4196Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.63.0...v1.64.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
args_validator parameter to tools for pre-execution validation by @jerry-reevo in https://github.com/pydantic/pydantic-ai/pull/4016TracerProviders without add_span_processor by @AtharvaJaiswal005 in https://github.com/pydantic/pydantic-ai/pull/4328strip_markdown_fences to stop at closing fence by @sksvineeth in https://github.com/pydantic/pydantic-ai/pull/4398BuiltinToolCallPart.id for OpenAI Responses WebSearch/FileSearch by @yipstar in https://github.com/pydantic/pydantic-ai/pull/4391run_id instead of index by @madanlalit in https://github.com/pydantic/pydantic-ai/pull/4086Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.62.0...v1.63.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
tool_use_failed errors without tool name/args by retrying by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4354prompt_feedback and OpenAI refusals by @DouweM in https://github.com/pydantic/pydantic-ai/pull/4315huggingface to 1.3.4 by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4119griffelib instead of griffe by @dsfaccini in https://github.com/pydantic/pydantic-ai/pull/4313Full Changelog: https://github.com/pydantic/pydantic-ai/compare/v1.61.0...v1.62.0
Your coding agent can read these notes before it upgrades. Set up the MCP server →