pydantic_ai.tools
Tool calls that require approval or external execution.
This can be used as an agent’s output_type and will be used as the output of the agent run if the model called any deferred tools.
Results can be passed to the next agent run using a DeferredToolResults object with the same tool call IDs.
See deferred tools docs for more information.
Tool calls that require human-in-the-loop approval.
Type: list[ToolCallPart] Default: field(default_factory=(list[ToolCallPart]))
Tool calls that require external execution.
Type: list[ToolCallPart] Default: field(default_factory=(list[ToolCallPart]))
Metadata for deferred tool calls, keyed by tool_call_id.
Type: dict[str, dict[str, Any]] Default: field(default_factory=(dict[str, dict[str, Any]]))
def build_results(
*,
approvals: dict[str, bool | DeferredToolApprovalResult] | None = None,
calls: dict[str, DeferredToolCallResult | Any] | None = None,
metadata: dict[str, dict[str, Any]] | None = None,
approve_all: bool = False,
) -> DeferredToolResults
Create a DeferredToolResults for these requests.
Results for tool calls that required approval. Keys must match
tool_call_ids in self.approvals.
Results for tool calls that required external execution. Keys must
match tool_call_ids in self.calls.
Per-call metadata, keyed by tool_call_id.
approve_all : bool Default: False
If True, every approval-requesting call not already listed in
approvals is approved (with default ToolApproved()).
ValueError— If a key inapprovals/callsdoesn’t match a pending request of the appropriate kind.
def remaining(results: DeferredToolResults) -> DeferredToolRequests | None
Return unresolved requests after applying results, or None if all resolved.
Results for deferred tool calls from a previous run that required approval or external execution.
The tool call IDs need to match those from the DeferredToolRequests output object from the previous run.
See deferred tools docs for more information.
Map of tool call IDs to results for tool calls that required human-in-the-loop approval.
Type: dict[str, bool | DeferredToolApprovalResult] Default: field(default_factory=(dict[str, bool | DeferredToolApprovalResult]))
Map of tool call IDs to results for tool calls that required external execution.
Type: dict[str, DeferredToolCallResult | Any] Default: field(default_factory=(dict[str, DeferredToolCallResult | Any]))
Metadata for deferred tool calls, keyed by tool_call_id. Each value will be available in the tool’s RunContext as tool_call_metadata.
Type: dict[str, dict[str, Any]] Default: field(default_factory=(dict[str, dict[str, Any]]))
def to_tool_call_results() -> dict[str, DeferredToolResult]
Convert results into the internal per-call format used by the tool-execution pipeline.
Normalizes True/False approvals to ToolApproved/ToolDenied, and wraps
plain external-call values in ToolReturn.
def update(other: DeferredToolResults) -> None
Update this DeferredToolResults with entries from another, in-place.
Bases: Generic[RunContextAgentDepsT]
Information about the current call.
The agent running this context, or None if not set.
Type: Agent[RunContextAgentDepsT, Any] | None Default: field(default=None, repr=False)
IDs of the capabilities whose contributions are live to the model right now.
The capability-side mirror of available_tool_names: available = auto/always ∪ runtime-revealed. Here that’s the non-deferred capabilities (defer_loading not
True) plus the deferred ones the model has loaded (loaded_capability_ids), so
available_capability_ids - loaded_capability_ids is the auto/always-on subset.
Distinct from capabilities, the full registry (including deferred ones not yet
loaded). See loaded_capability_ids for the runtime-revealed subset.
Reliable from before_run onwards: the capabilities registry is seeded once at
run start, and loaded_capability_ids is refreshed from history before each model
request, so the loaded subset grows across steps as the model loads capabilities.
Because it grows step by step, where you read it in the
hook order determines what you see — e.g. a capability
loaded during one step is not reflected until the next step’s hooks.
Names of function tools the model can call on the current turn.
The visible subset of tools: always-visible
tools, tools revealed via tool search, and tools
owned by loaded deferred capabilities.
Only fully populated once the turn’s tools have been resolved during model-request
preparation, so it is reliable in model-request hooks (before_model_request,
wrap_model_request, after_model_request) and tool hooks. In earlier hooks like
before_run it falls back to discovered_tool_names (reconstructed from history).
See hook ordering for how timing affects what you see.
All capabilities registered for the current run, including deferred ones.
Type: dict[str, AbstractCapability[RunContextAgentDepsT]] Default: field(default_factory=(lambda: {}))
Whether the capability whose hook or callback is currently running is loaded.
This is None outside capability dispatch, where there is no current capability.
Type: bool | None Default: None
Unique identifier for the conversation this run belongs to.
A conversation spans potentially multiple agent runs that share message history.
Resolved at the start of Agent.run (etc.) from the explicit conversation_id
argument, the most recent conversation_id on message_history, or a fresh UUID7.
Type: str | None Default: None
Dependencies for the agent.
Type: RunContextAgentDepsT
Names of deferred function tools named by durable message history.
Raw evidence, not a verdict: it collects every name tool-search returns and
ToolAvailabilityDeltaParts mention — including deltas from any tool’s ToolReturn.tools and
from load_capability — without checking that the tool still exists or that its owner is
loaded. Read by is_tool_available and the reveal builders, which apply those checks.
Populated during run preparation from message history. Use available_tool_names for the full
set of currently-callable tools (always-visible plus these).
Managed by the framework: safe to read, but don’t mutate it directly.
Type: set[str] Default: field(default_factory=(set[str]))
Instrumentation settings version, if instrumentation is enabled.
Type: int Default: DEFAULT_INSTRUMENTATION_VERSION
Whether this is the last attempt at running this tool before an error is raised.
Type: bool
IDs of the deferred capabilities the model has explicitly loaded via the load_capability tool.
The capability-side mirror of discovered_tool_names: the runtime-revealed subset.
Derived from message history (parse_loaded_capabilities) before each request, so a capability
loaded during a step appears from the next one — the same step that first carries its
instructions to the model, and therefore the first on which its tools can be called. Use
available_capability_ids for the full set of currently-active capabilities (auto/always-on
plus these). Managed by the framework: safe to read, but don’t mutate it directly.
Type: set[str] Default: field(default_factory=(set[str]))
The maximum number of retries allowed.
For tool calls, this is the maximum retries for the specific tool. For output validation, this is the maximum output validation retries.
Type: int Default: 0
Messages exchanged in the conversation so far.
Type: list[_messages.ModelMessage] Default: field(default_factory=(list[_messages.ModelMessage]))
Metadata associated with this agent run, if configured.
Type: dict[str, Any] | None Default: None
The active model, which is a RealtimeModel during a realtime session.
Type: AbstractModel
The resolved model settings for the current run step.
Populated before each model request, after all model settings layers
(model defaults, agent-level, capability, and run-level) have been merged.
Available in model request hooks (before_model_request, wrap_model_request,
after_model_request). Currently None in tool hooks, output validators,
and during agent construction.
During a realtime session this holds the merged
RealtimeModelSettings the session was opened
with, for the whole session (realtime settings are fixed at connect time).
Type: ModelSettings | RealtimeModelSettings | None Default: None
Whether the output passed to an output validator is partial.
Type: bool Default: False
Queue read and mutated by the internal PendingMessageDrainCapability.
Set to the run’s live queue during an agent run; None in synthetic contexts that aren’t
backed by a running agent (e.g. the RunContext built by Agent.system_prompt_parts), where
enqueue would have nowhere to drain to and so raises.
Managed by the framework: read it if useful, but use enqueue
to add messages rather than mutating it directly.
Type: list[PendingMessage] | None Default: field(default=None, repr=False)
The original user prompt passed to the run.
Type: str | Sequence[_messages.UserContent] | None Default: None
Whether this run is a realtime session, i.e. model is the connected RealtimeModel.
Reliable from before_run through session close, including instruction resolution — unlike
realtime_session, which is only set once
the session is connected. The class is looked up through sys.modules rather than imported:
if the realtime package was never imported, no realtime model can exist, and a classic run
should not pay for (or cycle into) that import.
Type: bool
The RealtimeSession this run is, once it is connected.
None in classic runs, and during the parts of a realtime run that precede the connection:
before_run, wrap_run before handler() starts the session, and instruction resolution.
Use realtime to detect a realtime run in those
stages. Tools and hooks that run during the live session can use it to e.g.
interrupt() playback or
send() follow-up content.
Type: RealtimeSession | None Default: field(default=None, repr=False)
Number of retries for each tool so far.
Type: dict[str, int] Default: field(default_factory=(dict[str, int]))
Number of retries so far.
For tool calls, this is the number of retries of the specific tool. For output validation, this is the number of output validation retries.
Type: int Default: 0
The effective root capability for this run.
Reflects the merged capability chain (agent-level + per-run extras) that is driving model requests, hooks, and toolsets for the current run. Capability implementations can use this to validate per-run additions (e.g. detect runtime-added capabilities that require worker registration).
Not part of the Temporal activity-boundary serialization (capabilities
don’t round-trip), but populated on the activity side from the bound
agent’s root_capability.
Type: AbstractCapability[RunContextAgentDepsT] | None Default: None
“Unique identifier for the agent run.
Type: str | None Default: None
The current step in the run.
Type: int Default: 0
Whether a tool call that required approval has now been approved.
Type: bool Default: False
The ID of the tool call.
Type: str | None Default: None
Metadata from DeferredToolResults.metadata[tool_call_id], available when tool_call_approved=True.
Type: Any Default: None
The tool manager for the current run step.
Provides access to tool validation and execution, including tracing and capability hooks. Useful for toolsets that need to dispatch tool calls programmatically (e.g. code execution sandboxes).
Not available in TemporalRunContext — it is not serializable across
Temporal activity boundaries.
Type: ToolManager[RunContextAgentDepsT] | None Default: None
Name of the tool being called.
Type: str | None Default: None
All tool definitions present this turn, keyed by name (includes still-deferred ones). Index available_tool_names into this for the callable subset.
Type: dict[str, ToolDefinition]
Whether to include the content of the messages in the trace.
Type: bool Default: False
The tracer to use for tracing the run.
Type: Tracer Default: field(default_factory=NoOpTracer)
LLM usage associated with the run.
Type: RunUsage
The UsageLimits enforced for this run.
During a run this is always set: if no limits were passed, the run enforces the default
UsageLimits() (e.g. request_limit=50). It is only None on a
bare/synthetic RunContext that isn’t backed by a run.
This reflects the limits the run is already enforcing, so tools and capabilities can disclose or
adapt to the run’s budget (e.g. a budget-disclosure capability) without having to be configured
with a duplicate copy. Combine it with usage to compute
how much budget remains. Treat it as read-only: it is the live object the run enforces against, so
mutating a field here would change what the run enforces on subsequent requests.
Type: UsageLimits | None Default: None
Pydantic validation context for tool args and run outputs.
Type: Any Default: None
def cancel() -> None
Cancel the agent run this context belongs to.
Safe to call from anywhere a RunContext is available — tools, event_stream_handlers,
and capability hooks. This requests cancellation: it returns normally, and the calling
code keeps running until its next await, where the cancellation is delivered — so the
caller can still do cleanup, but its return value (e.g. a tool’s result) is discarded. The
run then stops what it is doing (the in-flight model request is torn down, sibling tool
tasks are cancelled and drained, a suspended server-side job is best-effort cancelled) and
ends with RunCancelled, preserving everything that
completed before the cancellation took effect in message history. Idempotent; a no-op once
the run has finished. Cancellation is terminal: capability hooks may observe it and clean
up, but cannot recover the run to success.
UserError— If thisRunContextisn’t backed by a running agent (e.g. the synthetic context fromAgent.system_prompt_parts, or across a durable-execution serialization boundary such as a Temporal activity).
def enqueue(
*content: EnqueueContent,
priority: PendingMessagePriority = 'asap',
) -> str | None
Enqueue content to be injected into the conversation.
Safe to call from anywhere a RunContext is available — async tools,
sync tools (auto-wrapped in a thread executor by Pydantic AI), and
capability hooks. The drain only iterates the queue between graph nodes
(in before_model_request and after_node_run), never concurrently
with the tool body, so list.append from a worker thread doesn’t race
the drain.
str | None — The enqueue_id of the queued message, echoed on the
str | None — EnqueuedMessagesEvent emitted when it’s
str | None — delivered, or None when there was nothing to enqueue (an empty call).
One or more EnqueueContent items.
Adjacent UserContent (a str or multi-modal
content like an ImageUrl) is gathered into one
UserPromptPart, and each
ModelRequestPart (e.g. a
SystemPromptPart) is coalesced with adjacent
part-style items into one ModelRequest; a complete
ModelRequest or
ModelResponse is kept as its own message. The
assembled sequence must end in a request. Calling with no positional args is a no-op.
When to deliver:
'asap' (default) — at the earliest opportunity (next model request,
or a redirect if the agent would otherwise end). In a realtime session, an active
assistant response is allowed to finish before the content is sent; otherwise it
is sent immediately.
'when_idle' — only when the agent would otherwise end, after 'asap' messages.
In a realtime session, this means after the next response completes.
UserError— If thisRunContextisn’t backed by a running agent’s queue (e.g. the synthetic context fromAgent.system_prompt_parts), since there’d be nowhere to deliver the message.
def is_tool_available(tool: str | ToolDefinition) -> bool
Whether a function tool is currently available to the model.
Pass a ToolDefinition when checking a definition
held by a toolset, especially inside get_tools. This form evaluates the definition’s
own fields against the reveal state recorded in history, so it remains
reliable when a wrapping toolset has removed the definition from the resolved tool set.
Pass a tool name where tools is reliable, such as
model-request hooks or ordinary tool execution. The name form looks up the current definition
in tools; when live tool state is unavailable (including inside a Temporal activity), it
falls back to available_tool_names. An unknown name returns False. See
available_tool_names for the timing
caveat, and ModelRequestParameters.revealed_tool_names
for the reveal state sent through the model-request pipeline.
Bases: Generic[ToolAgentDepsT]
A tool function for an agent.
The base JSON schema for the tool’s parameters.
This schema may be modified by the prepare function or by the Model class prior to including it in an API request.
Type: _function_schema.FunctionSchema Default: function_schema or _function_schema.function_schema(function, schema_generator, tool_name=(self.name), takes_ctx=takes_ctx, docstring_format=docstring_format, require_parameter_descriptions=require_parameter_descriptions)
def __init__(
function: ToolFuncEither[ToolAgentDepsT, ToolParams],
*,
takes_ctx: bool | None = None,
max_retries: int | None = None,
name: str | None = None,
description: str | None = None,
prepare: ToolPrepareFunc[ToolAgentDepsT] | None = None,
args_validator: ArgsValidatorFunc[ToolAgentDepsT, ToolParams] | None = None,
docstring_format: DocstringFormat = 'auto',
require_parameter_descriptions: bool = False,
schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
strict: bool | None = None,
sequential: bool = False,
requires_approval: bool = False,
metadata: dict[str, Any] | None = None,
timeout: float | None = None,
defer_loading: bool = False,
include_return_schema: bool | None = None,
function_schema: _function_schema.FunctionSchema | None = None,
)
Create a new tool instance.
Example usage:
from pydantic_ai import Agent, RunContext, Tool
async def my_tool(ctx: RunContext[int], x: int, y: int) -> str:
return f'{ctx.deps} {x} {y}'
agent = Agent('test', tools=[Tool(my_tool)])
or with a custom prepare method:
from pydantic_ai import Agent, RunContext, Tool
from pydantic_ai.tools import ToolDefinition
async def my_tool(ctx: RunContext[int], x: int, y: int) -> str:
return f'{ctx.deps} {x} {y}'
async def prep_my_tool(
ctx: RunContext[int], tool_def: ToolDefinition
) -> ToolDefinition | None:
# only register the tool if `deps == 42`
if ctx.deps == 42:
return tool_def
agent = Agent('test', tools=[Tool(my_tool, prepare=prep_my_tool)])
The Python function to call as the tool.
Whether the function takes a RunContext first argument,
this is inferred if unset.
Maximum number of retries allowed for this tool, set to the agent default if None.
Name of the tool, inferred from the function if None.
Description of the tool, inferred from the function if None.
prepare : ToolPrepareFunc[ToolAgentDepsT] | None Default: None
custom method to prepare the tool definition for each step, return None to omit this
tool from a given step. This is useful if you want to customise a tool at call time,
or omit it completely from a step. See ToolPrepareFunc.
args_validator : ArgsValidatorFunc[ToolAgentDepsT, ToolParams] | None Default: None
custom method to validate tool arguments after schema validation has passed,
before execution. The validator receives the already-validated and type-converted parameters,
with RunContext as the first argument.
Raise ModelRetry to ask the model to correct the
arguments and try again, or ToolFailed to report a
terminal failure the model should adapt to instead of retrying. Return None on success.
See ArgsValidatorFunc.
The format of the docstring, see DocstringFormat.
Defaults to 'auto', such that the format is inferred from the structure of the docstring.
require_parameter_descriptions : bool Default: False
If True, raise an error if a parameter description is missing. Defaults to False.
schema_generator : type[GenerateJsonSchema] Default: GenerateToolJsonSchema
The JSON schema generator class to use. Defaults to GenerateToolJsonSchema.
Whether to enforce (vendor-specific) strict schema adherence for tool calls (supported by OpenAI, Anthropic, Google, and Bedrock).
See ToolDefinition for more info.
sequential : bool Default: False
Whether this tool acts as a barrier that runs alone, not overlapping with other tool calls.
See ToolDefinition for more info. Defaults to False.
requires_approval : bool Default: False
Whether this tool requires human-in-the-loop approval. Defaults to False. See the tools documentation for more info.
Optional metadata for the tool. This is not sent to the model but can be used for filtering and tool behavior customization.
Timeout in seconds for tool execution. If the tool takes longer, a retry prompt is returned to the model. Defaults to None (no timeout).
defer_loading : bool Default: False
Whether to hide this tool until it’s discovered via tool search. Defaults to False. See Tool Search for more info.
Whether to include the return schema in the tool definition sent to the model.
If None, defaults to False unless the IncludeToolReturnSchemas capability is used.
function_schema : _function_schema.FunctionSchema | None Default: None
The function schema to use for the tool. If not provided, it will be generated.
@classmethod
def from_schema(
cls,
function: Callable[..., Any],
name: str,
description: str | None,
json_schema: JsonSchemaValue,
takes_ctx: bool = False,
sequential: bool = False,
args_validator: ArgsValidatorFunc[Any, ...] | None = None,
) -> Self
Creates a Pydantic tool from a function and a JSON schema.
Self — A Pydantic tool that calls the function
The function to call.
This will be called with keywords only. Schema validation of
the arguments is skipped, but a custom args_validator will
still run if provided.
name : str
The unique name of the tool that clearly communicates its purpose
Used to tell the model how/when/why to use the tool. You can provide few-shot examples as a part of the description.
The schema for the function arguments
takes_ctx : bool Default: False
An optional boolean parameter indicating whether the function accepts the context object as an argument.
sequential : bool Default: False
Whether this tool acts as a barrier that runs alone, not overlapping with other tool calls.
See ToolDefinition for more info. Defaults to False.
custom method to validate tool arguments after schema validation has passed,
before execution. The validator receives the already-validated and type-converted parameters,
with RunContext as the first argument.
Raise ModelRetry to ask the model to correct the
arguments and try again, or ToolFailed to report a
terminal failure the model should adapt to instead of retrying. Return None on success.
See ArgsValidatorFunc.
@async
def prepare_tool_def(ctx: RunContext[ToolAgentDepsT]) -> ToolDefinition | None
Get the tool definition.
By default, this method creates a tool definition, then either returns it, or calls self.prepare
if it’s set.
ToolDefinition | None — return a ToolDefinition or None if the tools should not be registered for this run.
Indicates that a tool call has been approved and that the tool function should be executed.
Optional tool call arguments to use instead of the original arguments.
Type: dict[str, Any] | None Default: None
Definition of a tool passed to a model.
This is used for both function tools and output tools.
The id of the capability that contributed this tool, or None if the tool is not owned by a capability.
Assigned once when the run’s capabilities are set up and then carried on the ToolDefinition
for the rest of that run — it does not change or reset between steps. For a tool owned by a
deferred capability it gates visibility: the tool is revealed once that capability’s id appears
in RunContext.loaded_capability_ids.
Type: str | None Default: None
Whether calls to this tool will be deferred.
See the tools documentation for more info.
Type: bool
Whether this tool should be hidden from the model until something explicitly surfaces it.
Set on Tool(defer_loading=True) (or via a custom toolset) to opt this tool into
deferred loading. This author intent remains stable after the tool is revealed;
current wire placement is tracked separately by
ModelRequestParameters.tool_visibility.
See Tool Search for more info.
Type: bool Default: False
The description of the tool.
Type: str | None Default: None
The function signature shape for this tool.
Lazily computed from parameters_json_schema and return_schema on first access.
Name and description are not stored on the signature — pass them at render time
via sig.render(body, name=td.name, description=td.description).
Type: FunctionSignature
Whether to include the return schema in the tool definition sent to the model.
When True, the return_schema will be preserved and sent to the model.
When False, the return_schema will be cleared before sending.
When None (default), defaults to False unless the
IncludeToolReturnSchemas capability is used.
Type: bool | None Default: None
The kind of tool:
'function': a tool that will be executed by Pydantic AI during an agent run and has its result returned to the model'output': a tool that passes through an output value that ends the run'external': a tool whose result will be produced outside of the Pydantic AI agent run in which it was called, because it depends on an upstream service (or user) or could take longer to generate than it’s reasonable to keep the agent process running. See the tools documentation for more info.'unapproved': a tool that requires human-in-the-loop approval. See the tools documentation for more info.
Type: ToolKind Default: field(default='function')
Tool metadata that can be set by the toolset this tool came from. It is not sent to the model, but can be used for filtering and tool behavior customization.
For MCP tools, this contains the meta and annotations fields from the tool definition, as well as a task flag indicating whether the toolset will use task-augmented execution for the tool.
Type: dict[str, Any] | None Default: None
The name of the tool.
Type: str
The key in the outer [TypedDict] that wraps an output tool.
This will only be set for output tools which don’t have an object JSON schema.
Type: str | None Default: None
The JSON schema for the tool’s parameters.
Type: ObjectJsonSchema Default: field(default_factory=(lambda: {'type': 'object', 'properties': {}}))
The JSON schema for the tool’s return value.
For models that natively support return schemas (e.g. Google Gemini), this is passed as a
structured field in the API request. For other models, it is injected into the tool’s
description as JSON text. Only included when include_return_schema resolves to True.
Type: ObjectJsonSchema | None Default: None
Whether this tool acts as a barrier that runs alone, not overlapping with other tool calls.
A sequential=True tool acts as a barrier: it runs alone, with tools the model emitted before it
completing first and tools emitted after it starting only once it finishes. Other tools still run
in parallel around it. To run an entire run’s tools serially, use
ToolManager.parallel_execution_mode('sequential')
instead.
Type: bool Default: False
Whether to enforce (vendor-specific) strict schema adherence for tool calls.
Setting this to True while using a supported model requests the provider’s native schema-enforcement
feature. On some providers that imposes restrictions on the tool’s JSON schema (e.g. every property
required, additionalProperties: false) in exchange for constrained generation; on Google it maps to
Gemini’s VALIDATED function-calling mode, which needs no schema rewrites.
When False, never use strict mode for the tool. On Google, any function or output tool with
strict=False keeps the whole request on AUTO (Gemini’s mode is request-wide, not per-tool).
When None (the default), the value is inferred per provider: OpenAI enables strict mode when the
parameters_json_schema is strict-compatible; Google defaults to VALIDATED on supported models
(Gemini 2.5+); Anthropic and Bedrock leave it off unless you explicitly set strict=True.
Note: this is currently supported by OpenAI, Anthropic, Google, and Bedrock models. See Strict Mode for the full per-provider table.
Type: bool | None Default: None
Timeout in seconds for tool execution.
If the tool takes longer than this, a retry prompt is returned to the model. Defaults to None (no timeout).
Type: float | None Default: None
Discriminator for a cross-provider typed call/return shape (e.g. 'tool-search').
Set by the framework when a tool emits parts that should be promoted to a typed
subclass (such as ToolSearchCallPart
and ToolSearchReturnPart). Leave as
None for user-defined function tools — they go through the standard
ToolCallPart /
ToolReturnPart shapes.
To detect a tool-search part regardless of execution path (native server-side vs.
local fallback), check part.tool_kind == 'tool-search' — this works across both
call/return and both server/local variants.
Distinct from kind, which is about invocation
semantics ('function' / 'output' / 'external' / 'unapproved').
Type: ToolPartKind | None Default: None
The ID of the toolset that this tool belongs to.
Set automatically when tools are collected from toolsets. Can be used by capabilities (e.g. durable execution) to apply per-toolset configuration to tool operations.
Type: str | None Default: None
If set, this tool is dropped from the wire when the named native tool is supported by the model.
Generic version of the old prefer_builtin flag: a function tool carrying
unless_native='web_search' is treated as a local fallback for the
WebSearchTool native tool and silently
removed from the request whenever the model handles WebSearchTool natively. It
stays in the request when the native tool isn’t supported.
Type: Annotated[str | None, Field(validation_alias=(AliasChoices(unless_native, prefer_native, prefer_builtin)))] Default: None
If set, this tool is a member of a corpus the named native tool manages.
Symmetric pair with unless_native:
unless_native='X'— drop me from the wire when X is supported (local fallback).with_native='X'— I belong to X’s corpus, so X’s adapter decides my wire format.
Set by ToolSearchToolset on the deferred tools the model may search for, and only those: a
tool an on-demand capability gates is deferred without being searchable, and carries
defer_loading alone. When the named native tool isn’t supported by the model, this is cleared
— a corpus with no manager is not a corpus — which is independent of whether the tool stays on
the wire; that’s defer_loading’s question.
Type: str | None Default: None
def render_signature(body: str, **kwargs: Any) -> str
Render the function signature with this tool’s name and description.
Convenience wrapper around self.function_signature.render() that
supplies name and description from this tool definition.
Indicates that a tool call has been denied and that a denial message should be returned to the model.
The message to return to the model.
Type: str Default: 'The tool call was denied.'
@async
def matches_tool_selector(
selector: ToolSelector[AgentDepsT],
ctx: RunContext[AgentDepsT],
tool_def: ToolDefinition,
) -> bool
Check whether a tool definition matches a ToolSelector.
bool — True if the tool matches the selector.
The selector to check against.
ctx : RunContext[AgentDepsT]
The current run context.
tool_def : ToolDefinition
The tool definition to test.
Type variable for agent dependencies.
Default: TypeVar('AgentDepsT', default=object, contravariant=True)
A native tool or a function that dynamically produces one.
This is a convenience alias for AbstractNativeTool | NativeToolFunc[AgentDepsT].
Type: TypeAlias Default: AbstractNativeTool | NativeToolFunc[AgentDepsT]
A function that validates tool arguments before execution.
The validator receives the same typed parameters as the tool function,
with RunContext as the first argument for dependency access.
Raise ModelRetry to ask the model to correct the arguments and try
again, or ToolFailed to report a terminal failure the model should
adapt to instead of retrying. Return None on success.
Type: TypeAlias Default: Callable[Concatenate[RunContext[AgentDepsT], ToolParams], Awaitable[None]] | Callable[Concatenate[RunContext[AgentDepsT], ToolParams], None]
Supported docstring formats.
'google'— Google-style docstrings.'numpy'— Numpy-style docstrings.'sphinx'— Sphinx-style docstrings.'auto'— Automatically infer the format based on the structure of the docstring.
Type: TypeAlias Default: Literal['google', 'numpy', 'sphinx', 'auto']
Definition of a function that can prepare a native tool at call time.
This is useful if you want to customize the native tool based on the run context (e.g. user dependencies), or omit it completely from a step.
Type: TypeAlias Default: Callable[[RunContext[AgentDepsT]], Awaitable[AbstractNativeTool | None] | AbstractNativeTool | None]
Type representing JSON schema of an object, e.g. where "type": "object".
This type is used to define tools parameters (aka arguments) in ToolDefinition.
With PEP-728 this should be a TypedDict with type: Literal['object'], and extra_parts=Any
Type: TypeAlias Default: dict[str, Any]
A function that may or may not take RunContext as an argument, and may or may not be async.
Functions which return None are excluded from model requests.
Usage SystemPromptFunc[AgentDepsT].
Type: TypeAlias Default: Callable[[RunContext[AgentDepsT]], str | None] | Callable[[RunContext[AgentDepsT]], Awaitable[str | None]] | Callable[[], str | None] | Callable[[], Awaitable[str | None]]
Type variable for agent dependencies for a tool.
Default: TypeVar('ToolAgentDepsT', default=object, contravariant=True)
A tool function that takes RunContext as the first argument.
Usage ToolContextFunc[AgentDepsT, ToolParams].
Type: TypeAlias Default: Callable[Concatenate[RunContext[AgentDepsT], ToolParams], Any]
Either kind of tool function.
This is just a union of ToolFuncContext and
ToolFuncPlain.
Usage ToolFuncEither[AgentDepsT, ToolParams].
Type: TypeAlias Default: ToolFuncContext[AgentDepsT, ToolParams] | ToolFuncPlain[ToolParams]
A tool function that does not take RunContext as the first argument.
Usage ToolPlainFunc[ToolParams].
Type: TypeAlias Default: Callable[ToolParams, Any]
Kind of tool.
Type: TypeAlias Default: Literal['function', 'output', 'external', 'unapproved']
Retrieval function param spec.
Default: ParamSpec('ToolParams', default=...)
Definition of a function that can prepare a tool definition at call time. Both sync and async functions are accepted.
See tool docs for more information.
Example — here only_if_42 is valid as a ToolPrepareFunc:
from pydantic_ai import RunContext, Tool
from pydantic_ai.tools import ToolDefinition
def only_if_42(
ctx: RunContext[int], tool_def: ToolDefinition
) -> ToolDefinition | None:
if ctx.deps == 42:
return tool_def
def hitchhiker(ctx: RunContext[int], answer: str) -> str:
return f'{ctx.deps} {answer}'
hitchhiker = Tool(hitchhiker, prepare=only_if_42)
Usage ToolPrepareFunc[AgentDepsT].
Type: TypeAlias Default: Callable[[RunContext[AgentDepsT], 'ToolDefinition'], Union[Awaitable['ToolDefinition | None'], 'ToolDefinition', None]]
Specifies which tools a capability or toolset wrapper should apply to.
'all': matches every tool (default for most capabilities).Sequence[str]: matches tools whose names are in the sequence.dict[str, Any]: matches tools whosemetadatacontains all the specified key-value pairs (deep inclusion check — nested dicts are compared recursively, and the tool’s metadata may have additional keys).Callable[[RunContext, ToolDefinition], bool | Awaitable[bool]]: custom sync or async predicate.
The first three forms are serializable for use in agent specs (YAML/JSON).
Usage ToolSelector[AgentDepsT].
Type: TypeAlias Default: Literal['all'] | Sequence[str] | dict[str, Any] | ToolSelectorFunc[AgentDepsT]
A callable that decides whether a tool matches a selection criterion.
Receives the run context and a tool definition, returns True if the tool is selected.
Both sync and async functions are accepted.
Usage ToolSelectorFunc[AgentDepsT].
Type: TypeAlias Default: Callable[[RunContext[AgentDepsT], 'ToolDefinition'], bool | Awaitable[bool]]
Definition of a function that can prepare the tool definition of all tools for each step. This is useful if you want to customize the definition of multiple tools or you want to register a subset of tools for a given step. Both sync and async functions are accepted.
Example — here turn_on_strict_if_openai is valid as a ToolsPrepareFunc:
from dataclasses import replace
from pydantic_ai import Agent, RunContext
from pydantic_ai.capabilities import PrepareTools
from pydantic_ai.tools import ToolDefinition
def turn_on_strict_if_openai(
ctx: RunContext, tool_defs: list[ToolDefinition]
) -> list[ToolDefinition]:
if ctx.model.system == 'openai':
return [replace(tool_def, strict=True) for tool_def in tool_defs]
return tool_defs
agent = Agent('openai:gpt-5.2', capabilities=[PrepareTools(turn_on_strict_if_openai)])
Usage ToolsPrepareFunc[AgentDepsT].
Type: TypeAlias Default: Callable[[RunContext[AgentDepsT], list['ToolDefinition']], Awaitable[list['ToolDefinition']] | list['ToolDefinition']]
How tool calls from a single model response are executed — see
ToolManager.parallel_execution_mode.
Default: Literal['parallel', 'sequential', 'parallel_ordered_events']
Bases: Generic[AgentDepsT]
Manages tools for an agent run step. It caches the agent run’s toolset’s tool definitions and handles calling tools and retries.
@classmethod
def parallel_execution_mode(
cls,
mode: ParallelExecutionMode = 'parallel',
) -> Generator[None]
Set the parallel execution mode during the context.
The execution mode for tool calls:
- ‘parallel’: Run tool calls in parallel, yielding events as they complete (default).
- ‘sequential’: Run tool calls one at a time in order.
- ‘parallel_ordered_events’: Run tool calls in parallel, but events are emitted in order, after all calls complete.