pydantic_ai.capabilities
ToolSearchFunc
module-attribute
ToolSearchFunc = Callable[
[
RunContext[AgentDepsT],
Sequence[str],
Sequence["ToolDefinition"],
],
Sequence[str] | Awaitable[Sequence[str]],
]
Custom search function for
ToolSearch's strategy field.
Takes the run context, the list of search queries, and the deferred tool definitions, and returns the matching tool names ordered by relevance. Both sync and async implementations are accepted.
Usage ToolSearchFunc[AgentDepsT].
ToolSearchLocalStrategy
module-attribute
ToolSearchLocalStrategy = Literal['keywords']
Named local tool search strategy.
'keywords' opts into the built-in keyword-overlap algorithm explicitly — use this
to lock in the current local algorithm rather than the None default (which lets
Pydantic AI pick the best algorithm per provider and may change over time).
Future local strategies (e.g. local BM25, TF-IDF, regex) will join this Literal as they're added; the single-member shape today is forward-compat scaffolding.
ToolSearchNativeStrategy
module-attribute
ToolSearchNativeStrategy = Literal['bm25', 'regex']
Named provider-native tool search strategy.
'bm25' and 'regex' correspond to Anthropic's server-side tool search variants.
OpenAI's Responses API does not expose distinct named native strategies, so these values
are rejected by the OpenAI adapter.
ToolSearchStrategy
module-attribute
ToolSearchStrategy = Union[
ToolSearchFunc[AgentDepsT],
ToolSearchLocalStrategy,
ToolSearchNativeStrategy,
]
Strategy value accepted by ToolSearch.strategy.
'keywords': force the local keyword-overlap algorithm regardless of provider.'bm25'/'regex': force a specific provider-native strategy (Anthropic). The request fails on providers that can't honor the choice.- Callable
(ctx, queries, tools) -> names: custom search function. Used locally, and also by the native "client-executed" surface on providers that support it (Anthropic custom tool-reference blocks, OpenAIToolSearchToolParam(execution='client')).
None is not part of the union — it's accepted as the default on the
ToolSearch.strategy field and means
"let Pydantic AI pick"; see that field's docstring for details.
OutputContext
dataclass
Context about the output being processed, passed to output hooks.
Source code in pydantic_ai_slim/pydantic_ai/output.py
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | |
mode
instance-attribute
mode: OutputMode
The schema's output mode ('text', 'native', 'prompted', 'tool', 'image', 'auto').
This reflects the configured schema, not the format of this particular response. For
example, a ToolOutputSchema with a text_processor (hybrid mode) reports 'tool'
even if the model returned text — check tool_call
to distinguish.
output_type
instance-attribute
The resolved output type (e.g. MyModel, str). For output functions, the function's input type (what the model produces).
object_def
instance-attribute
object_def: OutputObjectDefinition | None
The output object definition (schema, name, description), if structured output.
has_function
instance-attribute
has_function: bool
Whether there's an output function to call in the execute step.
function_name
class-attribute
instance-attribute
function_name: str | None = None
Name of the output function that will run, when known. None for union processors that dispatch
by output subtype, or when the schema has no function.
tool_call
class-attribute
instance-attribute
tool_call: ToolCallPart | None = None
The tool call part, for tool-based output. None when the current output did not arrive via a tool call (text or image).
tool_def
class-attribute
instance-attribute
tool_def: ToolDefinition | None = None
The tool definition, for tool-based output. None when the current output did not arrive via a tool call.
allows_text
class-attribute
instance-attribute
allows_text: bool = False
Whether the schema accepts text output (including via a text_processor on a ToolOutputSchema).
allows_image
class-attribute
instance-attribute
allows_image: bool = False
Whether the schema accepts image output.
allows_deferred_tools
class-attribute
instance-attribute
allows_deferred_tools: bool = False
Whether the schema accepts deferred tool requests as output.
CapabilityFunc
module-attribute
CapabilityFunc: TypeAlias = Callable[
[RunContext[AgentDepsT]],
AbstractCapability[AgentDepsT]
| None
| Awaitable[AbstractCapability[AgentDepsT] | None],
]
A sync/async function which takes a run context and returns a capability.
DynamicCapability
dataclass
Bases: AbstractCapability[AgentDepsT]
A capability that builds another capability dynamically using a function that takes the run context.
The factory is called once per agent run from
for_run. The returned
capability replaces this wrapper for the rest of the run, so its
instructions, model settings, toolset, native tools, and hooks all flow
through normally.
Pass a CapabilityFunc directly
to Agent(capabilities=[...]) or agent.run(capabilities=[...]) and it
will be wrapped in a DynamicCapability automatically.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/_dynamic.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
capability_func
instance-attribute
capability_func: CapabilityFunc[AgentDepsT]
The function that takes the run context and returns a capability or None.
ToolSearch
dataclass
Bases: AbstractCapability[AgentDepsT]
Capability that provides tool discovery for large toolsets.
Tools marked with defer_loading=True are hidden from the model until discovered.
Auto-injected into every agent — zero overhead when no deferred tools exist.
When the model supports native tool search (Anthropic BM25/regex, OpenAI Responses),
discovery is handled by the provider: the deferred tools are sent with defer_loading
on the wire and the provider exposes them once they've been discovered. Otherwise,
discovery happens locally via a search_tools function that the model can call.
On providers that support a native "client-executed" surface (Anthropic, OpenAI), the discovery message is delivered append-only — prompt cache is preserved across discovery turns, so growing the message history with discovered-tool results does not invalidate the cached prefix.
from collections.abc import Sequence
from pydantic_ai import Agent, RunContext, Tool
from pydantic_ai.capabilities import ToolSearch
from pydantic_ai.tools import ToolDefinition
# Tools become deferred via `defer_loading=True`. They stay hidden from the model
# until tool search discovers them.
def get_weather(city: str) -> str:
...
weather_tool = Tool(get_weather, defer_loading=True)
# Default: native search on supporting providers, local keyword matching elsewhere.
agent = Agent('anthropic:claude-sonnet-4-6', tools=[weather_tool], capabilities=[ToolSearch()])
# Force a specific Anthropic native strategy; errors on providers that can't honor it.
agent = Agent(
'anthropic:claude-sonnet-4-6',
tools=[weather_tool],
capabilities=[ToolSearch(strategy='regex')],
)
# Always run the local keyword-overlap algorithm, regardless of provider.
agent = Agent(
'anthropic:claude-sonnet-4-6',
tools=[weather_tool],
capabilities=[ToolSearch(strategy='keywords')],
)
# Custom search function — used locally, and by provider-native "client-executed"
# modes when supported.
def my_search(
ctx: RunContext, queries: Sequence[str], tools: Sequence[ToolDefinition]
) -> list[str]:
return [
t.name
for t in tools
if any(q.lower() in (t.description or '').lower() for q in queries)
]
agent = Agent(
'anthropic:claude-sonnet-4-6',
tools=[weather_tool],
capabilities=[ToolSearch(strategy=my_search)],
)
Source code in pydantic_ai_slim/pydantic_ai/capabilities/_tool_search.py
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
strategy
class-attribute
instance-attribute
strategy: ToolSearchStrategy[AgentDepsT] | None = None
The search strategy to use.
None(default): let Pydantic AI pick the best strategy for the current provider — native on supporting models (Anthropic BM25, OpenAI server-executed tool search), local keyword matching elsewhere. The choice may change in future versions.'keywords': always use the local keyword-overlap algorithm. Still prompt-cache compatible on providers that expose a "client-executed" native surface (Anthropic, OpenAI): the algorithm rides the samedefer_loadingwire as a custom callable, so the tool list stays stable across discovery rounds and the cached prefix is preserved.'bm25'/'regex': force a specific Anthropic native strategy. Raises on providers that can't honor the choice (including OpenAI, which has no named native strategies).- Callable
(ctx, queries, tools) -> names: custom search function (sync or async). Used locally, and by the native "client-executed" surface on providers that support it (Anthropic custom tool-reference blocks, OpenAIexecution='client').
max_results
class-attribute
instance-attribute
max_results: int = 10
Maximum number of matches returned by the local search algorithm.
tool_description
class-attribute
instance-attribute
tool_description: str | None = None
Custom description for the local search_tools function shown to the model.
parameter_description
class-attribute
instance-attribute
parameter_description: str | None = None
Custom description for the queries parameter on the local search_tools function.
AbstractCapability
dataclass
Bases: ABC, Generic[AgentDepsT]
Abstract base class for agent capabilities.
A capability is a reusable, composable unit of agent behavior that can provide instructions, model settings, tools, and request/response hooks.
Lifecycle: capabilities are passed to an Agent at construction time, where
most get_* methods are called to collect static configuration (instructions, model
settings, toolsets, native tools). The exception is
get_wrapper_toolset,
which is called per-run during toolset assembly. Then, on each model request during a
run, the before_model_request
and after_model_request
hooks are called to allow dynamic adjustments.
See the capabilities documentation for built-in capabilities.
get_serialization_name
and from_spec support
YAML/JSON specs (via [Agent.from_spec][pydantic_ai.Agent.from_spec]); they have
sensible defaults and typically don't need to be overridden.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 | |
apply
apply(
visitor: Callable[
[AbstractCapability[AgentDepsT]], None
],
) -> None
Run a visitor function on all leaf capabilities in this tree.
For a single capability, calls the visitor on itself.
Overridden by CombinedCapability
to recursively visit all child capabilities, and by
WrapperCapability
to delegate to the wrapped capability.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
156 157 158 159 160 161 162 163 164 165 | |
has_wrap_node_run
property
has_wrap_node_run: bool
Whether this capability (or any sub-capability) overrides wrap_node_run.
has_wrap_run_event_stream
property
has_wrap_run_event_stream: bool
Whether this capability (or any sub-capability) overrides wrap_run_event_stream.
get_serialization_name
classmethod
get_serialization_name() -> str | None
Return the name used for spec serialization (CamelCase class name by default).
Return None to opt out of spec-based construction.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
177 178 179 180 181 182 183 | |
from_spec
classmethod
from_spec(
*args: Any, **kwargs: Any
) -> AbstractCapability[Any]
Create from spec arguments. Default: cls(*args, **kwargs).
Override when __init__ takes non-serializable types.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
185 186 187 188 189 190 191 | |
get_ordering
get_ordering() -> CapabilityOrdering | None
Return ordering constraints for this capability, or None for default behavior.
Override to declare a fixed position ('outermost' / 'innermost'),
relative ordering (wraps / wrapped_by other capability types or instances),
or dependency requirements (requires).
CombinedCapability uses
these to topologically sort its children at construction time.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
193 194 195 196 197 198 199 200 201 202 203 | |
for_run
async
for_run(
ctx: RunContext[AgentDepsT],
) -> AbstractCapability[AgentDepsT]
Return the capability instance to use for this agent run.
Called once per run, before get_*() re-extraction and before any hooks fire.
Override to return a fresh instance for per-run state isolation.
Default: return self (shared across runs).
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
205 206 207 208 209 210 211 212 | |
get_instructions
get_instructions() -> AgentInstructions[AgentDepsT] | None
Return instructions to include in the system prompt, or None.
This method is called once at agent construction time. To get dynamic
per-request behavior, return a callable that receives
RunContext or a
[TemplateStr][pydantic_ai.TemplateStr] — not a dynamic string.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
214 215 216 217 218 219 220 221 222 | |
get_model_settings
get_model_settings() -> (
AgentModelSettings[AgentDepsT] | None
)
Return model settings to merge into the agent's defaults, or None.
This method is called once at agent construction time. Return a static
ModelSettings dict when the settings don't change between requests.
Return a callable that receives RunContext
when settings need to vary per step (e.g. based on ctx.run_step or ctx.deps).
When the callable is invoked, ctx.model_settings contains the merged
result of all layers resolved before this capability (model defaults and
agent-level settings). The returned dict is merged on top of that.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
224 225 226 227 228 229 230 231 232 233 234 235 236 | |
get_toolset
get_toolset() -> AgentToolset[AgentDepsT] | None
Return a toolset to register with the agent, or None.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
238 239 240 | |
get_native_tools
get_native_tools() -> Sequence[AgentNativeTool[AgentDepsT]]
Return native tools to register with the agent.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
242 243 244 | |
get_wrapper_toolset
get_wrapper_toolset(
toolset: AbstractToolset[AgentDepsT],
) -> AbstractToolset[AgentDepsT] | None
Wrap the agent's assembled toolset, or return None to leave it unchanged.
Called per-run with the combined non-output toolset (after the
prepare_tools hook
has already wrapped it). Output tools are added separately and are not included.
Unlike the other get_* methods which are called once at agent construction,
this is called each run (after for_run).
When multiple capabilities provide wrappers, they follow middleware semantics:
the first capability in the list wraps outermost (matching wrap_* hooks).
Use this to apply cross-cutting toolset wrappers like
PreparedToolset,
FilteredToolset,
or custom WrapperToolset subclasses.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | |
prepare_tools
async
prepare_tools(
ctx: RunContext[AgentDepsT],
tool_defs: list[ToolDefinition],
) -> list[ToolDefinition]
Filter or modify function tool definitions for this step.
Receives function tools only. For output tools,
override
prepare_output_tools
— it runs separately, with ctx.retry/ctx.max_retries reflecting the output
retry budget instead of the function-tool budget.
Return a filtered or modified list. The result flows into both the model's request
parameters and ToolManager.tools, so filtering also blocks tool execution.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | |
prepare_output_tools
async
prepare_output_tools(
ctx: RunContext[AgentDepsT],
tool_defs: list[ToolDefinition],
) -> list[ToolDefinition]
Filter or modify output tool definitions for this step.
Receives only output tools. ctx.retry and
ctx.max_retries reflect the output retry budget (agent-level
max_output_retries), matching the output hook lifecycle.
Return a filtered or modified list. The result flows into both the model's request
parameters and ToolManager.tools, so filtering also blocks tool execution.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | |
before_run
async
before_run(ctx: RunContext[AgentDepsT]) -> None
Called before the agent run starts. Observe-only; use wrap_run for modification.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
303 304 305 306 307 | |
after_run
async
after_run(
ctx: RunContext[AgentDepsT],
*,
result: AgentRunResult[Any]
) -> AgentRunResult[Any]
Called after the agent run completes. Can modify the result.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
309 310 311 312 313 314 315 316 | |
wrap_run
async
wrap_run(
ctx: RunContext[AgentDepsT], *, handler: WrapRunHandler
) -> AgentRunResult[Any]
Wraps the entire agent run. handler() executes the run.
If handler() raises and this method catches the exception and
returns a result instead, the error is suppressed and the recovery
result is used.
If this method does not call handler() (short-circuit), the run
is skipped and the returned result is used directly.
Note: if the caller cancels the run (e.g. by breaking out of an
iter() loop), this method receives an asyncio.CancelledError.
Implementations that hold resources should handle cleanup accordingly.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | |
on_run_error
async
on_run_error(
ctx: RunContext[AgentDepsT], *, error: BaseException
) -> AgentRunResult[Any]
Called when the agent run fails with an exception.
This is the error counterpart to
after_run:
while after_run is called on success, on_run_error is called on
failure (after wrap_run
has had its chance to recover).
Raise the original error (or a different exception) to propagate it.
Return an AgentRunResult to suppress
the error and recover the run.
Not called for GeneratorExit or KeyboardInterrupt.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | |
before_node_run
async
before_node_run(
ctx: RunContext[AgentDepsT],
*,
node: AgentNode[AgentDepsT]
) -> AgentNode[AgentDepsT]
Called before each graph node executes. Can observe or replace the node.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
363 364 365 366 367 368 369 370 | |
after_node_run
async
after_node_run(
ctx: RunContext[AgentDepsT],
*,
node: AgentNode[AgentDepsT],
result: NodeResult[AgentDepsT]
) -> NodeResult[AgentDepsT]
Called after each graph node succeeds. Can modify the result (next node or End).
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
372 373 374 375 376 377 378 379 380 | |
wrap_node_run
async
wrap_node_run(
ctx: RunContext[AgentDepsT],
*,
node: AgentNode[AgentDepsT],
handler: WrapNodeRunHandler[AgentDepsT]
) -> NodeResult[AgentDepsT]
Wraps execution of each agent graph node (run step).
Called for every node in the agent graph (UserPromptNode,
ModelRequestNode, CallToolsNode). handler(node) executes
the node and returns the next node (or End).
Override to inspect or modify nodes before execution, inspect or modify
the returned next node, call handler multiple times (retry), or
return a different node to redirect graph progression.
Note: this hook fires when using [agent.run()][pydantic_ai.Agent.run],
[agent.run_stream()][pydantic_ai.Agent.run_stream], and when manually driving
an [agent.iter()][pydantic_ai.Agent.iter] run with
[next()][pydantic_ai.result.AgentRun.next], but it does not fire when
iterating over the run with bare async for (which yields stream events, not
node results).
When using agent.run() with event_stream_handler, the handler wraps both
streaming and graph advancement (i.e. the model call happens inside the wrapper).
When using agent.run_stream(), the handler wraps only graph advancement — streaming
happens before the wrapper because run_stream() must yield the stream to the caller
while the stream context is still open, which cannot happen from inside a callback.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | |
on_node_run_error
async
on_node_run_error(
ctx: RunContext[AgentDepsT],
*,
node: AgentNode[AgentDepsT],
error: Exception
) -> NodeResult[AgentDepsT]
Called when a graph node fails with an exception.
This is the error counterpart to
after_node_run.
Raise the original error (or a different exception) to propagate it.
Return a next node or End to recover and continue the graph.
Useful for recovering from
UnexpectedModelBehavior
by redirecting to a different node (e.g. retry with different model settings).
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | |
wrap_run_event_stream
async
wrap_run_event_stream(
ctx: RunContext[AgentDepsT],
*,
stream: AsyncIterable[AgentStreamEvent]
) -> AsyncIterable[AgentStreamEvent]
Wraps the event stream for a streamed node. Can observe or transform events.
Note: when this method is overridden (or Hooks.on.event
/ Hooks.on.run_event_stream are registered),
[agent.run()][pydantic_ai.Agent.run] automatically enables streaming mode so this hook
fires even without an explicit event_stream_handler.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | |
before_model_request
async
before_model_request(
ctx: RunContext[AgentDepsT],
request_context: ModelRequestContext,
) -> ModelRequestContext
Called before each model request. Can modify messages, settings, and parameters.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
455 456 457 458 459 460 461 | |
after_model_request
async
after_model_request(
ctx: RunContext[AgentDepsT],
*,
request_context: ModelRequestContext,
response: ModelResponse
) -> ModelResponse
Called after each model response. Can modify the response before further processing.
Raise ModelRetry to reject the response and
ask the model to try again. The original response is still appended to message history
so the model can see what it said. Retries count against the output side of the agent's retry budget.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
463 464 465 466 467 468 469 470 471 472 473 474 475 476 | |
wrap_model_request
async
wrap_model_request(
ctx: RunContext[AgentDepsT],
*,
request_context: ModelRequestContext,
handler: WrapModelRequestHandler
) -> ModelResponse
Wraps the model request. handler() calls the model.
Raise ModelRetry to skip on_model_request_error
and directly retry the model request with a retry prompt. If the handler was called,
the model response is preserved in history for context (same as after_model_request).
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
478 479 480 481 482 483 484 485 486 487 488 489 490 491 | |
on_model_request_error
async
on_model_request_error(
ctx: RunContext[AgentDepsT],
*,
request_context: ModelRequestContext,
error: Exception
) -> ModelResponse
Called when a model request fails with an exception.
This is the error counterpart to
after_model_request.
Raise the original error (or a different exception) to propagate it.
Return a ModelResponse to suppress
the error and use the response as if the model call succeeded.
Raise ModelRetry to retry the model request
with a retry prompt instead of recovering or propagating.
Not called for SkipModelRequest
or ModelRetry.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 | |
before_tool_validate
async
before_tool_validate(
ctx: RunContext[AgentDepsT],
*,
call: ToolCallPart,
tool_def: ToolDefinition,
args: RawToolArgs
) -> RawToolArgs
Modify raw args before validation.
Raise ModelRetry to skip validation and
ask the model to redo the tool call.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
518 519 520 521 522 523 524 525 526 527 528 529 530 531 | |
after_tool_validate
async
after_tool_validate(
ctx: RunContext[AgentDepsT],
*,
call: ToolCallPart,
tool_def: ToolDefinition,
args: ValidatedToolArgs
) -> ValidatedToolArgs
Modify validated args. Called only on successful validation.
Raise ModelRetry to reject the validated args
and ask the model to redo the tool call.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
533 534 535 536 537 538 539 540 541 542 543 544 545 546 | |
wrap_tool_validate
async
wrap_tool_validate(
ctx: RunContext[AgentDepsT],
*,
call: ToolCallPart,
tool_def: ToolDefinition,
args: RawToolArgs,
handler: WrapToolValidateHandler
) -> ValidatedToolArgs
Wraps tool argument validation. handler() runs the validation.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
548 549 550 551 552 553 554 555 556 557 558 | |
on_tool_validate_error
async
on_tool_validate_error(
ctx: RunContext[AgentDepsT],
*,
call: ToolCallPart,
tool_def: ToolDefinition,
args: RawToolArgs,
error: ValidationError | ModelRetry
) -> ValidatedToolArgs
Called when tool argument validation fails.
This is the error counterpart to
after_tool_validate.
Fires for [ValidationError][pydantic.ValidationError] (schema mismatch) and
ModelRetry (custom validator rejection).
Raise the original error (or a different exception) to propagate it.
Return validated args to suppress the error and continue as if validation passed.
Not called for SkipToolValidation.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 | |
before_tool_execute
async
before_tool_execute(
ctx: RunContext[AgentDepsT],
*,
call: ToolCallPart,
tool_def: ToolDefinition,
args: ValidatedToolArgs
) -> ValidatedToolArgs
Modify validated args before execution.
Raise ModelRetry to skip execution and
ask the model to redo the tool call.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
585 586 587 588 589 590 591 592 593 594 595 596 597 598 | |
after_tool_execute
async
after_tool_execute(
ctx: RunContext[AgentDepsT],
*,
call: ToolCallPart,
tool_def: ToolDefinition,
args: ValidatedToolArgs,
result: Any
) -> Any
Modify result after execution.
Raise ModelRetry to reject the tool result
and ask the model to redo the tool call.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | |
wrap_tool_execute
async
wrap_tool_execute(
ctx: RunContext[AgentDepsT],
*,
call: ToolCallPart,
tool_def: ToolDefinition,
args: ValidatedToolArgs,
handler: WrapToolExecuteHandler
) -> Any
Wraps tool execution. handler() runs the tool.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
616 617 618 619 620 621 622 623 624 625 626 | |
on_tool_execute_error
async
on_tool_execute_error(
ctx: RunContext[AgentDepsT],
*,
call: ToolCallPart,
tool_def: ToolDefinition,
args: ValidatedToolArgs,
error: Exception
) -> Any
Called when tool execution fails with an exception.
This is the error counterpart to
after_tool_execute.
Raise the original error (or a different exception) to propagate it.
Return any value to suppress the error and use it as the tool result.
Raise ModelRetry to ask the model to
redo the tool call instead of recovering or propagating.
Not called for control flow exceptions
(SkipToolExecution,
CallDeferred,
ApprovalRequired)
or retry signals (ToolRetryError
from ModelRetry).
Use wrap_tool_execute
to intercept retries.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | |
before_output_validate
async
before_output_validate(
ctx: RunContext[AgentDepsT],
*,
output_context: OutputContext,
output: RawOutput
) -> RawOutput
Modify raw model output before validation/parsing.
The primary hook for pre-parse repair and normalization of model output. Fires only for structured output that requires parsing: prompted, native, tool, and union output. Does not fire for plain text or image output.
For structured text output, output is the raw text string from the model.
For tool output, output is the raw tool arguments (string or dict).
Raise ModelRetry to skip validation and
ask the model to try again with a custom message.
During streaming, this hook fires on every partial validation attempt as well as
the final result. Check ctx.partial_output to distinguish and avoid expensive
work on partial results.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 | |
after_output_validate
async
after_output_validate(
ctx: RunContext[AgentDepsT],
*,
output_context: OutputContext,
output: Any
) -> Any
Modify validated output after successful parsing. Called only on success.
output is the semantic value the model was asked to produce — e.g., a
MyModel instance for output_type=MyModel, or 42 for output_type=int, or
the input to a single-arg output function. For multi-arg output functions, this
is the dict of arguments (the genuine multi-value input).
Note: this differs from tool hooks (after_tool_validate), which always see
dict[str, Any] — tool args follow the schema contract. Output hooks see the
semantic output value, regardless of how it's internally represented during
validation.
Raise ModelRetry to reject the validated
output and ask the model to try again.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 | |
wrap_output_validate
async
wrap_output_validate(
ctx: RunContext[AgentDepsT],
*,
output_context: OutputContext,
output: RawOutput,
handler: WrapOutputValidateHandler
) -> Any
Wraps output validation. handler(output) performs the validation.
ModelRetry from within the handler goes to
on_output_validate_error.
ModelRetry raised directly (not from the handler) bypasses the error hook.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 | |
on_output_validate_error
async
on_output_validate_error(
ctx: RunContext[AgentDepsT],
*,
output_context: OutputContext,
output: RawOutput,
error: ValidationError | ModelRetry
) -> Any
Called when output validation fails.
This is the error counterpart to
after_output_validate.
Raise the original error (or a different exception) to propagate it.
Return validated output to suppress the error and continue.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 | |
before_output_process
async
before_output_process(
ctx: RunContext[AgentDepsT],
*,
output_context: OutputContext,
output: Any
) -> Any
Modify validated output before processing (extraction, output function call).
output is the semantic value — e.g., a MyModel instance or 42, matching
after_output_validate. For multi-arg output functions, it's the dict of args.
See after_output_validate
for a full explanation of the semantic-value contract.
Raise ModelRetry to skip processing and
ask the model to try again.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 | |
after_output_process
async
after_output_process(
ctx: RunContext[AgentDepsT],
*,
output_context: OutputContext,
output: Any
) -> Any
Modify result after output processing.
Raise ModelRetry to reject the result
and ask the model to try again.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
764 765 766 767 768 769 770 771 772 773 774 775 776 | |
wrap_output_process
async
wrap_output_process(
ctx: RunContext[AgentDepsT],
*,
output_context: OutputContext,
output: Any,
handler: WrapOutputProcessHandler
) -> Any
Wraps output processing. handler(output) runs extraction + output function call.
ModelRetry bypasses
on_output_process_error
(treated as control flow, not an error).
During streaming, this fires only when partial validation succeeds, and on the
final result. Check ctx.partial_output to skip expensive work on partial results.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 | |
on_output_process_error
async
on_output_process_error(
ctx: RunContext[AgentDepsT],
*,
output_context: OutputContext,
output: Any,
error: Exception
) -> Any
Called when output processing fails with an exception.
This is the error counterpart to
after_output_process.
Raise the original error (or a different exception) to propagate it.
Return any value to suppress the error and use it as the output.
Not called for retry signals (ToolRetryError
from ModelRetry).
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 | |
handle_deferred_tool_calls
async
handle_deferred_tool_calls(
ctx: RunContext[AgentDepsT],
*,
requests: DeferredToolRequests
) -> DeferredToolResults | None
Handle deferred tool calls (approval-required or externally-executed) inline during an agent run.
Called by [ToolManager][pydantic_ai.tool_manager.ToolManager] when:
- a tool raises
ApprovalRequiredorCallDeferredduring execution, or - the model calls a tool registered with
requires_approval=True(see Human-in-the-Loop Tool Approval) or a tool backed by external execution.
Uses accumulation dispatch: each capability in the chain receives remaining unresolved requests and can resolve some or all of them. Results are merged and unresolved calls are passed to the next capability.
Return a DeferredToolResults to resolve
some or all calls.
Return None to leave all calls unresolved.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 | |
prefix_tools
prefix_tools(prefix: str) -> PrefixTools[AgentDepsT]
Returns a new capability that wraps this one and prefixes its tool names.
Only this capability's tools are prefixed; other agent tools are unaffected.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
848 849 850 851 852 853 854 855 | |
AgentNode
module-attribute
AgentNode: TypeAlias = (
"_agent_graph.AgentNode[AgentDepsT, Any]"
)
Type alias for an agent graph node (UserPromptNode, ModelRequestNode, CallToolsNode).
CapabilityOrdering
dataclass
Ordering constraints for a capability within a combined capability chain.
Capabilities follow middleware semantics: the first capability in the list is the
outermost layer, wrapping all others. Declare ordering constraints via
get_ordering
to control a capability's position in the chain regardless of how the user lists them.
When a CombinedCapability is
constructed, it topologically sorts its children to satisfy these constraints,
preserving user-provided order as a tiebreaker.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/abstract.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
position
class-attribute
instance-attribute
position: CapabilityPosition | None = None
Fixed position in the chain, or None for user-provided order.
wraps
class-attribute
instance-attribute
wraps: Sequence[CapabilityRef] = ()
This capability wraps around (is outside of) these capabilities in the middleware chain.
Each entry can be a capability type (matches all instances of that type via issubclass)
or a specific capability instance (matches by identity via is).
Note: instance refs use identity (is) matching, so if a capability's
for_run returns a
new instance, refs to the original will no longer match. Use type refs
when the target capability uses per-run state isolation.
wrapped_by
class-attribute
instance-attribute
wrapped_by: Sequence[CapabilityRef] = ()
This capability is wrapped by (is inside of) these capabilities in the middleware chain.
Each entry can be a capability type (matches all instances of that type via issubclass)
or a specific capability instance (matches by identity via is).
Note: instance refs use identity (is) matching, so if a capability's
for_run returns a
new instance, refs to the original will no longer match. Use type refs
when the target capability uses per-run state isolation.
requires
class-attribute
instance-attribute
requires: Sequence[type[AbstractCapability[Any]]] = ()
These types must be present in the chain (no ordering implied).
CapabilityPosition
module-attribute
CapabilityPosition = Literal['outermost', 'innermost']
Position tier for a capability in the middleware chain.
'outermost': in the outermost tier, before all non-outermost capabilities. Multiple capabilities can declare'outermost'; original list order breaks ties within the tier, andwraps/wrapped_byedges refine order further.'innermost': in the innermost tier, after all non-innermost capabilities. Same tie-breaking rules apply.
CapabilityRef
module-attribute
CapabilityRef: TypeAlias = (
"type[AbstractCapability[Any]] | AbstractCapability[Any]"
)
Reference to a capability — either a type (matches all instances of that type) or a specific instance (matches by identity).
NodeResult
module-attribute
NodeResult: TypeAlias = (
"_agent_graph.AgentNode[AgentDepsT, Any] | End[FinalResult[Any]]"
)
Type alias for the result of executing an agent graph node: either the next node or End.
RawOutput
module-attribute
Type alias for raw output data (text or tool args).
RawToolArgs
module-attribute
Type alias for raw (pre-validation) tool arguments.
ValidatedToolArgs
module-attribute
Type alias for validated tool arguments.
WrapModelRequestHandler
module-attribute
WrapModelRequestHandler: TypeAlias = (
"Callable[[ModelRequestContext], Awaitable[ModelResponse]]"
)
Handler type for wrap_model_request.
WrapNodeRunHandler
module-attribute
WrapNodeRunHandler: TypeAlias = (
"Callable[[_agent_graph.AgentNode[AgentDepsT, Any]], Awaitable[_agent_graph.AgentNode[AgentDepsT, Any] | End[FinalResult[Any]]]]"
)
Handler type for wrap_node_run.
WrapOutputProcessHandler
module-attribute
Handler type for wrap_output_process.
WrapOutputValidateHandler
module-attribute
Handler type for wrap_output_validate.
WrapRunHandler
module-attribute
WrapRunHandler: TypeAlias = (
"Callable[[], Awaitable[AgentRunResult[Any]]]"
)
Handler type for wrap_run.
WrapToolExecuteHandler
module-attribute
WrapToolExecuteHandler: TypeAlias = Callable[
[ValidatedToolArgs], Awaitable[Any]
]
Handler type for wrap_tool_execute.
WrapToolValidateHandler
module-attribute
WrapToolValidateHandler: TypeAlias = Callable[
[RawToolArgs], Awaitable[ValidatedToolArgs]
]
Handler type for wrap_tool_validate.
CombinedCapability
dataclass
Bases: AbstractCapability[AgentDepsT]
A capability that combines multiple capabilities.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/combined.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | |
HandleDeferredToolCalls
dataclass
Bases: AbstractCapability[AgentDepsT]
Resolves deferred tool calls inline during an agent run using a handler function.
When tools require approval or external execution, the agent normally pauses the run
and returns DeferredToolRequests as output.
This capability intercepts deferred tool calls, calls the provided handler to resolve
them, and continues the agent run automatically.
The handler receives the RunContext and the
DeferredToolRequests. It may return
DeferredToolResults with results for
some or all pending calls, or return None to decline handling (the next capability
in the chain gets a chance, otherwise the calls bubble up as DeferredToolRequests
output).
Example
from pydantic_ai import Agent
from pydantic_ai.capabilities import HandleDeferredToolCalls
from pydantic_ai.tools import DeferredToolRequests, DeferredToolResults, RunContext
async def handle_deferred(
ctx: RunContext, requests: DeferredToolRequests
) -> DeferredToolResults:
# Auto-approve all tools that need approval
return requests.build_results(approve_all=True)
agent = Agent(
'openai:gpt-5',
capabilities=[HandleDeferredToolCalls(handler=handle_deferred)],
)
Source code in pydantic_ai_slim/pydantic_ai/capabilities/deferred_tool_handler.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
handler
instance-attribute
handler: Callable[
[RunContext[AgentDepsT], DeferredToolRequests],
DeferredToolResults
| None
| Awaitable[DeferredToolResults | None],
]
The handler function that resolves deferred tool requests.
Receives the run context and the deferred tool requests, and returns
DeferredToolResults with results for some
or all pending calls, or None to decline handling. Can be sync or async.
Hooks
Bases: AbstractCapability[AgentDepsT]
Register hook functions via decorators or constructor kwargs.
For extension developers building reusable capabilities, subclass
AbstractCapability directly.
For application code that needs a few hooks without the ceremony of a subclass,
use Hooks.
Example using decorators:
hooks = Hooks()
@hooks.on.before_model_request
async def log_request(ctx, request_context):
print(f'Request: {request_context}')
return request_context
agent = Agent('openai:gpt-5', capabilities=[hooks])
Example using constructor kwargs:
agent = Agent('openai:gpt-5', capabilities=[
Hooks(before_model_request=log_request)
])
Source code in pydantic_ai_slim/pydantic_ai/capabilities/hooks.py
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 | |
on
cached
property
on: _HookRegistration[AgentDepsT]
Decorator namespace for registering hook functions.
HookTimeoutError
Bases: TimeoutError
Raised when a hook function exceeds its configured timeout.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/hooks.py
64 65 66 67 68 69 70 71 | |
ImageGeneration
dataclass
Bases: NativeOrLocalTool[AgentDepsT]
Image generation capability.
Uses the model's native image generation when available. When the model doesn't
support it and fallback_model is provided, falls back to a local tool that
delegates to a subagent running the specified image-capable model.
Image generation settings (quality, size, etc.) are forwarded to the
ImageGenerationTool used by
both the native and the local fallback subagent. When passing a custom native
instance, its settings are also used for the fallback subagent; capability-level
fields override any native instance settings.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/image_generation.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
fallback_model
instance-attribute
fallback_model: ImageGenerationFallbackModel = (
fallback_model
)
Model to use for image generation when the agent's model doesn't support it natively.
Must be a model that supports image generation via the
ImageGenerationTool native tool.
This requires a conversational model with image generation support, not a dedicated
image-only API. Examples:
'openai-responses:gpt-5.4'— OpenAI model with image generation support'google:gemini-3-pro-image-preview'— Google image generation model
Can be a model name string, Model instance, or a callable taking RunContext
that returns a Model instance.
action
instance-attribute
action: Literal['generate', 'edit', 'auto'] | None = action
Whether to generate a new image or edit an existing image.
Supported by: OpenAI Responses. Default: 'auto'.
background
instance-attribute
background: (
Literal["transparent", "opaque", "auto"] | None
) = background
Background type for the generated image.
Supported by: OpenAI Responses. 'transparent' only supported for 'png' and 'webp'.
input_fidelity
instance-attribute
input_fidelity: Literal["high", "low"] | None = (
input_fidelity
)
Input fidelity for matching style/features of input images.
Supported by: OpenAI Responses. Default: 'low'.
moderation
instance-attribute
moderation: Literal['auto', 'low'] | None = moderation
Moderation level for the generated image.
Supported by: OpenAI Responses.
image_model
instance-attribute
image_model: ImageGenerationModelName | None = image_model
The image generation model to use.
Supported by: OpenAI Responses.
output_compression
instance-attribute
output_compression: int | None = output_compression
Compression level for the output image.
Supported by: OpenAI Responses (jpeg/webp, default: 100), Google Cloud (jpeg, default: 75).
output_format
instance-attribute
output_format: Literal["png", "webp", "jpeg"] | None = (
output_format
)
Output format of the generated image.
Supported by: OpenAI Responses (default: 'png'), Google Cloud.
quality
instance-attribute
quality: Literal["low", "medium", "high", "auto"] | None = (
quality
)
Quality of the generated image.
Supported by: OpenAI Responses.
size
instance-attribute
size: (
Literal[
"auto",
"1024x1024",
"1024x1536",
"1536x1024",
"512",
"1K",
"2K",
"4K",
]
| None
) = size
Size of the generated image.
Supported by: OpenAI Responses ('auto', '1024x1024', '1024x1536', '1536x1024'),
Google ('512', '1K', '2K', '4K').
aspect_ratio
instance-attribute
aspect_ratio: ImageAspectRatio | None = aspect_ratio
Aspect ratio for generated images.
Supported by: Google (Gemini), OpenAI Responses (maps '1:1', '2:3', '3:2' to sizes).
IncludeToolReturnSchemas
dataclass
Bases: AbstractCapability[AgentDepsT]
Capability that includes return schemas for selected tools.
When added to an agent's capabilities, this sets
include_return_schema
to True on matching tool definitions, causing the model to receive
return type information for those tools.
For models that natively support return schemas (e.g. Google Gemini), the schema is passed as a structured field. For other models, it is injected into the tool description as JSON text.
Per-tool overrides (Tool(..., include_return_schema=False)) take
precedence — this capability only sets the flag on tools that haven't
explicitly opted out.
from pydantic_ai import Agent
from pydantic_ai.capabilities import IncludeToolReturnSchemas
agent = Agent('openai:gpt-5', capabilities=[IncludeToolReturnSchemas()])
Source code in pydantic_ai_slim/pydantic_ai/capabilities/include_return_schemas.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | |
tools
class-attribute
instance-attribute
tools: ToolSelector[AgentDepsT] = 'all'
Which tools should have their return schemas included.
'all'(default): every tool gets its return schema included.Sequence[str]: only tools whose names are listed.dict[str, Any]: matches tools whose metadata deeply includes the specified key-value pairs.- Callable
(ctx, tool_def) -> bool: custom sync or async predicate.
Instrumentation
dataclass
Bases: AbstractCapability[Any]
Capability that instruments agent runs with OpenTelemetry/Logfire tracing.
When added to an agent via capabilities=[Instrumentation(...)], this capability
creates OpenTelemetry spans for the agent run, model requests, and tool executions.
Other capabilities can add attributes to these spans using the OpenTelemetry API
(opentelemetry.trace.get_current_span().set_attribute(key, value)).
Source code in pydantic_ai_slim/pydantic_ai/capabilities/instrumentation.py
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | |
settings
class-attribute
instance-attribute
settings: InstrumentationSettings = field(
default_factory=lambda: _default_settings()
)
OTel/Logfire instrumentation settings. Defaults to InstrumentationSettings(),
which uses the global TracerProvider (typically configured by logfire.configure()).
from_spec
classmethod
from_spec(**kwargs: Any) -> Instrumentation
Build an Instrumentation capability from a YAML/JSON spec.
Accepts the serializable subset of InstrumentationSettings
kwargs (include_binary_content, include_content, version,
use_aggregated_usage_attribute_names). The OTel tracer_provider and meter_provider
fields can't be expressed in YAML and default to the global providers (typically configured
via logfire.configure()).
YAML form:
capabilities:
- Instrumentation: {} # default settings
- Instrumentation:
version: 2
include_content: false
Source code in pydantic_ai_slim/pydantic_ai/capabilities/instrumentation.py
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
for_run
async
for_run(ctx: RunContext[Any]) -> Instrumentation
Return a fresh copy for per-run state isolation.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/instrumentation.py
112 113 114 115 116 117 | |
wrap_output_process
async
wrap_output_process(
ctx: RunContext[AgentDepsT],
*,
output_context: OutputContext,
output: Any,
handler: WrapOutputProcessHandler
) -> Any
Emit a span for output-function execution.
Output processing for plain validation (no function) is not span-worthy — the validated value is the model's response itself, no user code ran. We open a span only when an output function will execute, regardless of whether the output arrived via a tool call. The span name reflects the function (or tool name when the function name is unavailable, e.g. union processors).
Source code in pydantic_ai_slim/pydantic_ai/capabilities/instrumentation.py
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | |
MCP
dataclass
Bases: NativeOrLocalTool[AgentDepsT]
MCP server capability.
The primary entry point for using MCP servers with Pydantic AI. Runs the MCP server
locally — keeps credentials, hooks, and tracing under your control — and accepts any
MCPToolset input (URL, fastmcp.Client, transport,
in-process FastMCP server, script path, etc.) directly via local=.
Pass url= for HTTP-based servers; the same URL can also be advertised to providers
that support native MCP via native=True. For non-URL local clients, omit url= and
pass the client/toolset as local=. Pass native=True, local=False for strict
native-only (no local at all — works without the mcp extra).
Source code in pydantic_ai_slim/pydantic_ai/capabilities/mcp.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
url
instance-attribute
url: str | None = url
The URL of the MCP server.
Required when using native MCP. Optional when using a local-only client via local=.
id
instance-attribute
id: str | None = id
Unique identifier for the MCP server. Defaults to a slug derived from the URL.
authorization_token
instance-attribute
authorization_token: str | None = authorization_token
Authorization header value for MCP server requests. Passed to both native and local.
headers
instance-attribute
HTTP headers for MCP server requests. Passed to both native and local.
allowed_tools
instance-attribute
Filter to only these tools. Applied to both native and local.
description
instance-attribute
description: str | None = description
Description of the MCP server. Native-only; ignored by local tools.
from_spec
classmethod
from_spec(
url: str,
*,
native: MCPServerTool | bool = False,
local: str | bool | None = None,
id: str | None = None,
authorization_token: str | None = None,
headers: dict[str, str] | None = None,
allowed_tools: list[str] | None = None,
description: str | None = None
) -> MCP[AgentDepsT]
Construct an MCP capability from spec-serializable args.
Restricts the runtime-wide local= union to the JSON/YAML-serializable subset
(str | bool | None) so AgentSpec schema generation works, and requires url= (which
is optional at runtime when local= is a concrete non-URL client). Non-serializable
runtime values like fastmcp.Client, ClientTransport, or pre-built MCPToolset
instances can still be passed to MCP(...) directly — they just can't roundtrip through
a spec file.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/mcp.py
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
NativeOrLocalTool
dataclass
Bases: AbstractCapability[AgentDepsT]
Capability that pairs a provider-native tool with a local fallback.
When the model supports the native tool, the local fallback is removed. When the model doesn't support the native tool, it is removed and the local tool stays.
Can be used directly:
from pydantic_ai.capabilities import NativeOrLocalTool
cap = NativeOrLocalTool(native=WebSearchTool(), local=my_search_func)
Or subclassed to set defaults by overriding _default_native, _default_local,
and _requires_native.
The built-in WebSearch,
WebFetch, and
ImageGeneration capabilities
are all subclasses.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/native_or_local.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | |
native
class-attribute
instance-attribute
native: AgentNativeTool[AgentDepsT] | bool = native
Configure the provider-native tool.
True(default): use the default native tool configuration (subclasses only).False: disable the native tool; always use the local tool.- An
AbstractNativeToolinstance: use this specific configuration. - A callable (
NativeToolFunc): dynamically create the native tool per-run viaRunContext.
local
class-attribute
instance-attribute
local: (
str
| Tool[AgentDepsT]
| Callable[..., Any]
| AbstractToolset[AgentDepsT]
| bool
| None
) = local
Configure the local fallback tool.
None(default): auto-detect a local fallback via_default_local.True: opt in to the default local fallback (resolved via_resolve_local_strategy).False: disable the local fallback; only use the native tool.- A named strategy (e.g.
'duckduckgo'): resolved via_resolve_local_strategyin subclasses. - A
ToolorAbstractToolsetinstance: use this specific local tool. - A bare callable: automatically wrapped in a
Tool.
NativeTool
dataclass
Bases: AbstractCapability[AgentDepsT]
A capability that registers a native tool with the agent.
Wraps a single AgentNativeTool — either a static
AbstractNativeTool instance or a callable
that dynamically produces one.
Equivalent to passing the tool through Agent(capabilities=[NativeTool(my_tool)]). For
provider-adaptive use (with a local fallback), see NativeOrLocalTool
or its subclasses like WebSearch.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/native_tool.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
from_spec
classmethod
from_spec(
tool: AbstractNativeTool | None = None, **kwargs: Any
) -> NativeTool[Any]
Create from spec.
Supports two YAML forms:
- Flat:
{NativeTool: {kind: web_search, search_context_size: high}} - Explicit:
{NativeTool: {tool: {kind: web_search}}}
Source code in pydantic_ai_slim/pydantic_ai/capabilities/native_tool.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
PrefixTools
dataclass
Bases: WrapperCapability[AgentDepsT]
A capability that wraps another capability and prefixes its tool names.
Only the wrapped capability's tools are prefixed; other agent tools are unaffected.
from pydantic_ai import Agent
from pydantic_ai.capabilities import PrefixTools, Toolset
from pydantic_ai.toolsets import FunctionToolset
toolset = FunctionToolset()
agent = Agent(
'openai:gpt-5',
capabilities=[
PrefixTools(
wrapped=Toolset(toolset),
prefix='ns',
),
],
)
Source code in pydantic_ai_slim/pydantic_ai/capabilities/prefix_tools.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | |
from_spec
classmethod
from_spec(
*, prefix: str, capability: CapabilitySpec
) -> PrefixTools[Any]
Create from spec with a nested capability specification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix
|
str
|
The prefix to add to tool names (e.g. |
required |
capability
|
CapabilitySpec
|
A capability spec (same format as entries in the |
required |
Source code in pydantic_ai_slim/pydantic_ai/capabilities/prefix_tools.py
46 47 48 49 50 51 52 53 54 55 56 57 | |
PrepareOutputTools
dataclass
Bases: AbstractCapability[AgentDepsT]
Capability that filters or modifies output tool definitions using a callable.
Mirrors PrepareTools for
output tools. ctx.retry/ctx.max_retries reflect
the output retry budget (max_output_retries), matching the output hook lifecycle.
from pydantic_ai import Agent, RunContext
from pydantic_ai.capabilities import PrepareOutputTools
from pydantic_ai.output import ToolOutput
from pydantic_ai.tools import ToolDefinition
async def only_after_first_step(
ctx: RunContext, tool_defs: list[ToolDefinition]
) -> list[ToolDefinition] | None:
return tool_defs if ctx.run_step > 0 else []
agent = Agent(
'openai:gpt-5',
output_type=ToolOutput(str),
capabilities=[PrepareOutputTools(only_after_first_step)],
)
Source code in pydantic_ai_slim/pydantic_ai/capabilities/prepare_tools.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | |
PrepareTools
dataclass
Bases: AbstractCapability[AgentDepsT]
Capability that filters or modifies function tool definitions using a callable.
Wraps a ToolsPrepareFunc as a capability.
Filters/modifies function tools only; for output tools use
PrepareOutputTools.
from pydantic_ai import Agent, RunContext
from pydantic_ai.capabilities import PrepareTools
from pydantic_ai.tools import ToolDefinition
async def hide_admin_tools(
ctx: RunContext, tool_defs: list[ToolDefinition]
) -> list[ToolDefinition] | None:
return [td for td in tool_defs if not td.name.startswith('admin_')]
agent = Agent('openai:gpt-5', capabilities=[PrepareTools(hide_admin_tools)])
Source code in pydantic_ai_slim/pydantic_ai/capabilities/prepare_tools.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
ProcessEventStream
dataclass
Bases: AbstractCapability[AgentDepsT]
A capability that forwards the agent's event stream to a user-provided async handler.
The handler receives the stream of AgentStreamEvents
emitted during model streaming and tool execution for each ModelRequestNode and
CallToolsNode. Two forms are supported:
- An
EventStreamHandler— anasync defreturningNone. Events are forwarded to the handler while also being passed through unchanged to the rest of the capability chain, so multiple handlers (and the top-levelevent_stream_handlerargument) can all see the same stream without changing each other's view. A handler that returns early stops receiving events but does not affect downstream consumers; a handler that raises propagates the exception to the rest of the run. Events are delivered synchronously, so a slow handler back-pressures the rest of the stream. - An [
EventStreamProcessor][pydantic_ai.agent.EventStreamProcessor] — an async generator yieldingAgentStreamEvents. The events it yields replace the inner stream for downstream wrappers and consumers, so it can modify, drop, or add events.
When this capability is registered, [agent.run()][pydantic_ai.Agent.run] automatically
enables streaming so the handler fires without requiring an explicit event_stream_handler
argument.
Durable execution
Under the current durable-execution integrations
(Temporal,
DBOS,
Prefect), model streaming happens
inside an activity/step rather than in the outer agent loop. This capability's
wrap_run_event_stream hook fires for tool-call events and the final post-streaming
batch, but it does not see individual model-response events live — the underlying
durable model consumes those inside the activity before returning. The in-flight
event_stream_handler parameter does still observe the live events; a future
refactor threading the capability chain through the activity boundary is being
explored in #4977.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/process_event_stream.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | |
ProcessHistory
dataclass
Bases: AbstractCapability[AgentDepsT]
A capability that processes message history before model requests.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/process_history.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
ReinjectSystemPrompt
dataclass
Bases: AbstractCapability[AgentDepsT]
Capability that reinjects the agent's configured system_prompt when missing from history.
Ensures the agent's configured system_prompt is present at the head of the first
ModelRequest on every model request.
Intended for callers that reconstruct a message_history from a source that doesn't
round-trip system prompts — UI frontends, database persistence layers, conversation
compaction pipelines. By default, if any SystemPromptPart is already present anywhere
in the history (for example, preserved from a prior run or handed off from another
agent), this capability leaves the messages untouched so that existing system prompts
remain authoritative. Set replace_existing=True to instead strip any existing
SystemPromptParts before prepending the agent's configured prompt — useful when the
history comes from an untrusted source (such as a UI frontend) and the server's prompt
must win.
The UI adapters automatically add this capability in manage_system_prompt='server' mode
with replace_existing=True. Add it explicitly with
Agent(..., capabilities=[ReinjectSystemPrompt()]) or per-run via the capabilities=
argument on Agent.run to get the same behavior
anywhere.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/reinject_system_prompt.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | |
replace_existing
class-attribute
instance-attribute
replace_existing: bool = False
If True, strip any existing SystemPromptParts from the history before prepending
the agent's configured prompt. If False (the default), the capability is a no-op when
any SystemPromptPart is already present.
SetToolMetadata
dataclass
Bases: AbstractCapability[AgentDepsT]
Capability that merges metadata key-value pairs onto selected tools.
from pydantic_ai import Agent
from pydantic_ai.capabilities import SetToolMetadata
agent = Agent('openai:gpt-5', capabilities=[SetToolMetadata(code_mode=True)])
Source code in pydantic_ai_slim/pydantic_ai/capabilities/set_tool_metadata.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
Thinking
dataclass
Bases: AbstractCapability[Any]
Enables and configures model thinking/reasoning.
Uses the unified thinking setting in
ModelSettings to work portably across providers.
Provider-specific thinking settings (e.g., anthropic_thinking,
openai_reasoning_effort) take precedence when both are set.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/thinking.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |
effort
class-attribute
instance-attribute
effort: ThinkingLevel = True
The thinking effort level.
True: Enable thinking with the provider's default effort.False: Disable thinking (silently ignored on always-on models).'minimal'/'low'/'medium'/'high'/'xhigh': Enable thinking at a specific effort level.
ThreadExecutor
dataclass
Bases: AbstractCapability[Any]
Use a custom executor for running sync functions in threads.
By default, sync tool functions and other sync callbacks are run in threads using
[anyio.to_thread.run_sync][], which creates ephemeral threads.
In long-running servers (e.g. FastAPI), this can lead to thread accumulation under sustained load.
This capability provides a bounded ThreadPoolExecutor
(or any Executor) to use instead, scoped to agent runs:
from concurrent.futures import ThreadPoolExecutor
from pydantic_ai import Agent
from pydantic_ai.capabilities import ThreadExecutor
executor = ThreadPoolExecutor(max_workers=16, thread_name_prefix='agent-worker')
agent = Agent('openai:gpt-5.2', capabilities=[ThreadExecutor(executor)])
To set an executor for all agents globally, use
Agent.using_thread_executor().
Source code in pydantic_ai_slim/pydantic_ai/capabilities/thread_executor.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | |
Toolset
dataclass
Bases: AbstractCapability[AgentDepsT]
A capability that provides a toolset.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/toolset.py
9 10 11 12 13 14 15 16 17 18 19 20 | |
WebFetch
dataclass
Bases: NativeOrLocalTool[AgentDepsT]
URL fetching capability.
Uses the model's native URL fetching and raises UserError on models that
don't support it natively. Pass local=True to opt into a local fallback
(requires the web-fetch optional group):
pip install "pydantic-ai-slim[web-fetch]"
Source code in pydantic_ai_slim/pydantic_ai/capabilities/web_fetch.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | |
allowed_domains
instance-attribute
Only fetch from these domains. Enforced locally when native is unavailable.
blocked_domains
instance-attribute
Never fetch from these domains. Enforced locally when native is unavailable.
max_uses
instance-attribute
max_uses: int | None = max_uses
Maximum number of fetches per run. Requires native support.
enable_citations
instance-attribute
enable_citations: bool | None = enable_citations
Enable citations for fetched content. Native-only; ignored by local tools.
max_content_tokens
instance-attribute
max_content_tokens: int | None = max_content_tokens
Maximum content length in tokens. Native-only; ignored by local tools.
WebSearch
dataclass
Bases: NativeOrLocalTool[AgentDepsT]
Web search capability.
Uses the model's native web search and raises UserError on models that
don't support it natively. Pass local='duckduckgo' (or local=True) to opt into a
local DuckDuckGo fallback — requires the duckduckgo optional group:
pip install "pydantic-ai-slim[duckduckgo]"
local= also accepts any callable, Tool, or AbstractToolset for a custom fallback.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/web_search.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
search_context_size
instance-attribute
search_context_size: (
Literal["low", "medium", "high"] | None
) = search_context_size
Controls how much context is retrieved from the web. Native-only; ignored by local tools.
user_location
instance-attribute
user_location: WebSearchUserLocation | None = user_location
Localize search results based on user location. Native-only; ignored by local tools.
blocked_domains
instance-attribute
Domains to exclude from results. Requires native support.
allowed_domains
instance-attribute
Only include results from these domains. Requires native support.
max_uses
instance-attribute
max_uses: int | None = max_uses
Maximum number of web searches per run. Requires native support.
WrapperCapability
dataclass
Bases: AbstractCapability[AgentDepsT]
A capability that wraps another capability and delegates all methods.
Analogous to WrapperToolset for toolsets.
Subclass and override specific methods to modify behavior while delegating the rest.
Source code in pydantic_ai_slim/pydantic_ai/capabilities/wrapper.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | |
AgentCapability
module-attribute
AgentCapability: TypeAlias = (
AbstractCapability[AgentDepsT]
| CapabilityFunc[AgentDepsT]
)
A capability or a CapabilityFunc that takes a run context and returns one.
Use as the item type for Agent(capabilities=[...]) and agent.run(capabilities=[...]).
Functions are wrapped in a DynamicCapability automatically.
CAPABILITY_TYPES
module-attribute
CAPABILITY_TYPES: dict[
str, type[AbstractCapability[Any]]
] = {
name: cls
for cls in (
NativeTool,
ImageGeneration,
IncludeToolReturnSchemas,
Instrumentation,
MCP,
PrefixTools,
PrepareTools,
ProcessHistory,
ReinjectSystemPrompt,
SetToolMetadata,
Thinking,
ToolSearch,
Toolset,
WebFetch,
WebSearch,
)
if (name := (get_serialization_name())) is not None
}
Registry of all capability types that have a serialization name, mapping name to class.