Skip to content

API Reference

Complete API documentation for PyAgentic's public interfaces.

Core Classes

BaseAgent

Base agent class to be extended to define new LLM-powered agents.

Agent definition requires the use of special decorators and class attributes
  • @tool: Declares a method as a tool callable by the LLM
  • system_message: Required class attribute defining the agent's system prompt
  • description: Optional description used when agent is linked to another agent
  • input_template: Optional template for formatting user input
  • response_format: Optional Pydantic model for structured output

Parameters:

Name Type Description Default
model str

Model used for inference in format <provider>::<model>. For example: openai::gpt-4o. Requires api_key to also be provided.

required
api_key str

API key matching the model provider

required
provider LLMProvider

Pre-configured provider instance. Overrides model and api_key if provided.

required
tracer AgentTracer

Tracer instance for observability. Defaults to BasicTracer if not provided.

required
max_call_depth int

Maximum number of tool calling loops per run. Defaults to 1.

required

Examples:

With a model string:

agent = MyAgent(
    model="openai::gpt-4o",
    api_key=MY_API_KEY
)

With a provider:

from pyagentic.llm import OpenAIProvider

agent = MyAgent(
    provider=OpenAIProvider(
        model="gpt-4o",
        api_key=MY_API_KEY,
        base_url="http://localhost:8000",
        max_retries=5
    )
)

run(input_: str) -> AgentResponse async

Executes the agent with a message string and returns the final result.

This method consumes the entire step() generator and returns only the final AgentResponse. Use this when you don't need intermediate streaming responses and just want the final output.

Parameters:

Name Type Description Default
input_ str

The user input/query for the agent to process

required

Returns:

Name Type Description
AgentResponse AgentResponse

Structured response containing: - final_output: The final text or structured output from the LLM - state: Current agent state after execution - tool_responses: List of all tool calls and their outputs - agent_responses: List of linked agent calls (if any) - provider_info: Information about the LLM provider used

Example
agent = MyAgent(model="openai::gpt-4o", api_key=API_KEY)
response = await agent.run("What's the weather in San Francisco?")
print(response.final_output)  # LLM's final answer
print(response.tool_responses)  # Tools that were called
Source code in pyagentic/_base/_agent/_agent.py
async def run(self, input_: str) -> AgentResponse:
    """
    Executes the agent with a message string and returns the final result.

    This method consumes the entire step() generator and returns only the final
    AgentResponse. Use this when you don't need intermediate streaming responses
    and just want the final output.

    Args:
        input_ (str): The user input/query for the agent to process

    Returns:
        AgentResponse: Structured response containing:
            - final_output: The final text or structured output from the LLM
            - state: Current agent state after execution
            - tool_responses: List of all tool calls and their outputs
            - agent_responses: List of linked agent calls (if any)
            - provider_info: Information about the LLM provider used

    Example:
        ```python
        agent = MyAgent(model="openai::gpt-4o", api_key=API_KEY)
        response = await agent.run("What's the weather in San Francisco?")
        print(response.final_output)  # LLM's final answer
        print(response.tool_responses)  # Tools that were called
        ```
    """
    final_response = None
    async for res in self.step(input_):
        final_response = res
    return final_response

get_tool_definition(name: str) -> _ToolDefinition classmethod

Creates a tool definition for this agent class to be used as a linked agent.

When an agent is linked to another agent, it appears as a tool that can be called by the LLM. This method generates the tool definition with the agent's description as the tool description and the agent's call signature as the tool parameters.

Parameters:

Name Type Description Default
name str

The name to use for this agent when it appears as a tool

required

Returns:

Name Type Description
_ToolDefinition _ToolDefinition

A tool definition that can be sent to the LLM

Source code in pyagentic/_base/_agent/_agent.py
@classmethod
def get_tool_definition(cls, name: str) -> _ToolDefinition:
    """
    Creates a tool definition for this agent class to be used as a linked agent.

    When an agent is linked to another agent, it appears as a tool that can be
    called by the LLM. This method generates the tool definition with the agent's
    __description__ as the tool description and the agent's __call__ signature
    as the tool parameters.

    Args:
        name (str): The name to use for this agent when it appears as a tool

    Returns:
        _ToolDefinition: A tool definition that can be sent to the LLM
    """
    desc = getattr(cls, "__description__", "") or ""

    # Create a fresh async wrapper function for this agent class
    # Each class needs its own function object for the @tool decorator
    @wraps(cls.__call__)
    async def _invoke(self, *args, **kwargs):
        return await cls.__call__(self, *args, **kwargs)

    # Apply @tool decorator to extract parameter info and create definition
    td = tool(desc)(_invoke).__tool_def__
    td.name = name
    return td

AgentExtension

Base class for creating reusable agent mixins that add tools, state, and behaviors.

AgentExtension allows you to package common functionality (tools, state fields, linked agents) into reusable components that can be mixed into multiple agent classes. This promotes code reuse and modular agent design.

Example
class LoggingMixin(AgentExtension):
    logs: State[list[str]] = spec.State(default_factory=list)

    @tool("Record a log message")
    def log(self, message: str) -> str:
        self.state.logs.append(message)
        return f"Logged: {message}"

class MyAgent(BaseAgent, LoggingMixin):
    __system_message__ = "You are a helpful agent with logging"

__annotations__: dict[str, Any] = {} class-attribute instance-attribute

__init_subclass__(**kwargs)

Merges annotations from all AgentExtension bases in MRO order. Subclass annotations override parent annotations on conflicts.

Parameters:

Name Type Description Default
**kwargs

Additional keyword arguments passed to parent init_subclass

{}
Source code in pyagentic/_base/_agent/_agent.py
def __init_subclass__(cls, **kwargs):
    """
    Merges annotations from all AgentExtension bases in MRO order.
    Subclass annotations override parent annotations on conflicts.

    Args:
        **kwargs: Additional keyword arguments passed to parent __init_subclass__
    """
    super().__init_subclass__(**kwargs)

    # Merge annotations from all AgentExtension bases (oldest first),
    # then let the subclass' own annotations win on key conflicts.
    merged: dict[str, Any] = {}
    for base in reversed(cls.__mro__[1:]):  # Skip cls itself, walk up towards object
        if issubclass(base, AgentExtension):
            ann = getattr(base, "__annotations__", None)
            if ann:
                merged.update(ann)

    merged.update(getattr(cls, "__annotations__", {}))
    # Assign a fresh dict so we don't mutate a base class' annotations
    cls.__annotations__ = dict(merged)

Decorators

@tool

Decorator to mark an agent method as a tool that the LLM can call.

Tools are functions the LLM can invoke to perform actions or retrieve information. The tool description helps the LLM understand when and how to use the tool. All tool methods must return an object that can be casted as a string (to show the LLM).

Parameters:

Name Type Description Default
description str

Clear description of what the tool does. The LLM uses this to decide when to call the tool. Be specific and action-oriented.

required
condition Callable[[Any], bool]

Function that returns True/False to conditionally enable/disable the tool. Receives the agent instance (self).

None

Returns:

Name Type Description
Callable

Decorated method that can be called by the LLM

Raises:

Type Description
InvalidToolDefinition

If the method does not have a return type annotation of str

Example
class FileAgent(BaseAgent):
    __system_message__ = "You help manage files"

    @tool("Read the contents of a file given its path")
    def read_file(self, path: str) -> str:
        with open(path, 'r') as f:
            return f.read()

    @tool("Write content to a file", condition=lambda self: self.state.write_enabled)
    def write_file(self, path: str, content: str) -> str:
        with open(path, 'w') as f:
            f.write(content)
        return f"Wrote {len(content)} characters to {path}"
Source code in pyagentic/_base/_tool.py
def tool(description: str, condition: Callable[[Any], bool] = None, phases: list[str] = None):
    """
    Decorator to mark an agent method as a tool that the LLM can call.

    Tools are functions the LLM can invoke to perform actions or retrieve information.
    The tool description helps the LLM understand when and how to use the tool.
    All tool methods must return an object that can be casted as a string (to show the LLM).

    Args:
        description (str): Clear description of what the tool does. The LLM uses this
            to decide when to call the tool. Be specific and action-oriented.
        condition (Callable[[Any], bool], optional): Function that returns True/False to
            conditionally enable/disable the tool. Receives the agent instance (self).

    Returns:
        Callable: Decorated method that can be called by the LLM

    Raises:
        InvalidToolDefinition: If the method does not have a return type annotation of `str`

    Example:
        ```python
        class FileAgent(BaseAgent):
            __system_message__ = "You help manage files"

            @tool("Read the contents of a file given its path")
            def read_file(self, path: str) -> str:
                with open(path, 'r') as f:
                    return f.read()

            @tool("Write content to a file", condition=lambda self: self.state.write_enabled)
            def write_file(self, path: str, content: str) -> str:
                with open(path, 'w') as f:
                    f.write(content)
                return f"Wrote {len(content)} characters to {path}"
        ```
    """

    def decorator(fn: Callable):
        # Check return type
        types = get_type_hints(fn)
        return_type = types.pop("return", None)

        # 2) grab default values
        sig = inspect.signature(fn)
        defaults = {
            param_name: param.default
            for param_name, param in sig.parameters.items()
            if param.default is not inspect._empty
        }

        params = {}

        for name, type_ in types.items():
            default = defaults.get(name, None)
            if isinstance(default, ParamInfo):
                params[name] = (type_, default)
            elif default is not None:
                params[name] = (type_, ParamInfo(default=default))
            else:
                params[name] = (type_, ParamInfo(required=True))

        fn.__tool_def__ = _ToolDefinition(
            name=fn.__name__,
            description=description or fn.__doc__ or "",
            parameters=params,
            condition=condition,
            return_type=return_type,
            phases=phases,
        )
        return fn

    return decorator

Type Annotations

State

Bases: Generic[T]

Type annotation for defining persistent state fields in agents.

State fields hold data that persists across tool calls and LLM interactions. Use Pydantic models as the state type to ensure type safety and validation.

Parameters:

Name Type Description Default
T

A Pydantic BaseModel class defining the structure of the state

required
Example
from pydantic import BaseModel

class ConversationState(BaseModel):
    user_name: str
    message_count: int = 0

class ChatAgent(BaseAgent):
    __system_message__ = "You are a chatbot"

    # Simple state field
    conversation: State[ConversationState]

    # State field with default value
    logs: State[list] = spec.State(default_factory=list)

__class_getitem__(item)

Creates a generic State type for a given model class.

Parameters:

Name Type Description Default
item

The model class to wrap as a state field

required

Returns:

Name Type Description
type

Special marker type that the metaclass can detect and process

Source code in pyagentic/_base/_state.py
def __class_getitem__(cls, item):
    """
    Creates a generic State type for a given model class.

    Args:
        item: The model class to wrap as a state field

    Returns:
        type: Special marker type that the metaclass can detect and process
    """
    # Return a special marker type that metaclass can detect
    return type(
        f"State[{item.__name__}]",
        (),
        {"__origin__": State, "__args__": (item,), "__state_model__": item},
    )

Bases: Generic[T]

Type annotation for linking other agents as callable tools.

Linked agents appear as tools to the parent agent, allowing complex multi-agent workflows. When the LLM calls a linked agent, that agent runs its full execution cycle and returns results to the parent.

Parameters:

Name Type Description Default
T

An agent class (subclass of BaseAgent) to link

required
Example
class ResearchAgent(BaseAgent):
    __system_message__ = "You research topics deeply"
    __description__ = "Research agent for gathering detailed information"

class OrchestratorAgent(BaseAgent):
    __system_message__ = "You coordinate research tasks"

    # Link research agent as a tool
    researcher: Link[ResearchAgent]

    # Conditional linking (agent only available when condition is true)
    expert: Link[ExpertAgent] = spec.AgentLink(
        condition=lambda self: self.state.needs_expert
    )

__class_getitem__(item)

Creates a generic Link type for a given agent class.

Parameters:

Name Type Description Default
item

The agent class to link

required

Returns:

Name Type Description
type

Special marker type that the metaclass can detect and process

Source code in pyagentic/_base/_agent/_agent_linking.py
def __class_getitem__(cls, item):
    """
    Creates a generic Link type for a given agent class.

    Args:
        item: The agent class to link

    Returns:
        type: Special marker type that the metaclass can detect and process
    """
    # Return a special marker type that metaclass can detect
    return type(
        f"Link[{item.__name__}]",
        (),
        {"__origin__": Link, "__args__": (item,), "__linked_agent__": item},
    )

Configuration

spec

Factory class for creating configuration descriptors for agent fields.

The spec object provides methods to configure state fields, tool parameters, and linked agents with advanced options like defaults, policies, and conditions.

Methods:

Name Description
- spec.State

Configure agent state fields

- spec.Param

Configure tool parameters with validation

- spec.AgentLink

Configure linked agent fields

Example
from pyagentic import BaseAgent, State, spec, tool
from pydantic import BaseModel

class UserProfile(BaseModel):
    name: str
    email: str

class MyAgent(BaseAgent):
    __system_message__ = "You are a helpful assistant"

    # State with default factory
    profile: State[UserProfile] = spec.State(
        default_factory=lambda: UserProfile(name="Guest", email="")
    )

    # State with policies
    logs: State[list] = spec.State(
        default_factory=list,
        policies=[LoggingPolicy()]
    )

    @tool("Update user profile")
    def update_profile(
        self,
        name: str = spec.Param(description="User's full name", required=True),
        email: str = spec.Param(description="User's email address")
    ) -> str:
        self.state.profile.name = name
        if email:
            self.state.profile.email = email
        return f"Updated profile for {name}"

State(default: Any = None, default_factory: Callable = None, policies: list[Policy] = None, access: Literal['read', 'write', 'readwrite', 'hidden'] = 'read', description: str | None = None, get_description: str | None = None, set_description: str | None = None, **kwargs) -> StateInfo staticmethod

Creates a StateInfo descriptor for configuring agent state fields.

Parameters:

Name Type Description Default
default Any

The default value for the state field

None
default_factory Callable

A factory function to generate the default value

None
policies list[Policy]

List of policies to apply to this state field

None
**kwargs

Additional keyword arguments passed to StateInfo

{}

Returns:

Name Type Description
StateInfo StateInfo

A configured StateInfo descriptor

Source code in pyagentic/_base/_spec.py
@staticmethod
def State(
    default: Any = None,
    default_factory: Callable = None,
    policies: list[Policy] = None,
    access: Literal["read", "write", "readwrite", "hidden"] = "read",
    description: str | None = None,
    get_description: str | None = None,
    set_description: str | None = None,
    **kwargs,
) -> StateInfo:
    """
    Creates a StateInfo descriptor for configuring agent state fields.

    Args:
        default (Any, optional): The default value for the state field
        default_factory (Callable, optional): A factory function to generate the default value
        policies (list[Policy], optional): List of policies to apply to this state field
        **kwargs: Additional keyword arguments passed to StateInfo

    Returns:
        StateInfo: A configured StateInfo descriptor
    """
    return StateInfo(
        default=default,
        default_factory=default_factory,
        policies=policies,
        access=access,
        description=description,
        get_description=get_description,
        set_description=set_description,
        **kwargs,
    )

Param(description: str = None, required: bool = False, default: Any = None, default_factory: Callable = None, values: Any = None) -> ParamInfo staticmethod

Creates a ParamInfo descriptor for configuring tool parameters.

Parameters:

Name Type Description Default
description str

A human-readable description of the parameter

None
required bool

Whether this parameter must be provided. Defaults to False

False
default Any

The default value for the parameter

None
default_factory Callable

A factory function to generate the default value

None
values Any

List of valid values to constrain the parameter

None

Returns:

Name Type Description
ParamInfo ParamInfo

A configured ParamInfo descriptor

Source code in pyagentic/_base/_spec.py
@staticmethod
def Param(
    description: str = None,
    required: bool = False,
    default: Any = None,
    default_factory: Callable = None,
    values: Any = None,
) -> ParamInfo:
    """
    Creates a ParamInfo descriptor for configuring tool parameters.

    Args:
        description (str, optional): A human-readable description of the parameter
        required (bool): Whether this parameter must be provided. Defaults to False
        default (Any, optional): The default value for the parameter
        default_factory (Callable, optional): A factory function to generate the default value
        values (Any, optional): List of valid values to constrain the parameter

    Returns:
        ParamInfo: A configured ParamInfo descriptor
    """
    return ParamInfo(
        description=description,
        required=required,
        default=default,
        default_factory=default_factory,
        values=values,
    )

Creates an AgentInfo descriptor for configuring linked agent fields.

Parameters:

Name Type Description Default
default Any

The default agent instance

None
default_factory Callable

A factory function to generate the default agent

None
condition Callable

A callable determining when this agent link is active

None
phases list[str]

A list of phases of when this agent will be available. When None, will show for all phases. Defaults to None.

None

Returns:

Name Type Description
AgentInfo AgentInfo

A configured AgentInfo descriptor

Source code in pyagentic/_base/_spec.py
@staticmethod
def AgentLink(
    default: Any = None,
    default_factory: Callable = None,
    condition: Callable = None,
    phases: list[str] | None = None,
) -> AgentInfo:
    """
    Creates an AgentInfo descriptor for configuring linked agent fields.

    Args:
        default (Any, optional): The default agent instance
        default_factory (Callable, optional): A factory function to generate the default agent
        condition (Callable, optional): A callable determining when this agent link is active
        phases (list[str], optional): A list of phases of when this agent will be available.
            When None, will show for all phases. Defaults to None.

    Returns:
        AgentInfo: A configured AgentInfo descriptor
    """
    return AgentInfo(
        default=default, default_factory=default_factory, condition=condition, phases=phases
    )

State References

ref