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
  • instructions: Class attribute defining the agent's instructions, either as a string or a PromptRef from a PromptEngine. Rendered with state into the system message sent to the LLM. Inherited from the nearest ancestor when not declared; an overriding declaration can embed the parent's rendered instructions with {{ super }}. Required somewhere in the hierarchy. (system_message is the deprecated spelling.)
  • 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):
    __instructions__ = "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):
    __instructions__ = "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):
            __instructions__ = "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):
    __instructions__ = "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):
    __instructions__ = "You research topics deeply"
    __description__ = "Research agent for gathering detailed information"

class OrchestratorAgent(BaseAgent):
    __instructions__ = "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):
    __instructions__ = "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
shared bool

If False (default), each call to the linked agent runs on a fresh, isolated fork (its own conversation state, reset to construction time), so concurrent or repeated calls neither race nor pollute each other. If True, all calls share one persistent instance whose state accumulates across calls — use this when the parent needs to read the linked agent's state via ref.

False

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,
    shared: bool = False,
) -> 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.
        shared (bool): If False (default), each call to the linked agent runs on a fresh,
            isolated fork (its own conversation state, reset to construction time), so
            concurrent or repeated calls neither race nor pollute each other. If True, all
            calls share one persistent instance whose state accumulates across calls — use
            this when the parent needs to read the linked agent's state via ``ref``.

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

State References

ref

Prompt Management

PromptEngine

Bases: ABC

Base class for prompt engines, designed to be extended to support multiple different source types (local files, databases, managed prompt services, ...).

load(key: str, version: str | None = None) -> PromptSource abstractmethod

Load a prompt by key.

Parameters:

Name Type Description Default
key str

Engine-specific identifier for the prompt.

required
version str | None

Specific version to load; the engine's latest when omitted.

None

Returns:

Name Type Description
PromptSource PromptSource

The loaded prompt text plus metadata.

Raises:

Type Description
PromptNotFound

If no prompt exists for the key (or version).

Source code in pyagentic/_base/_prompts.py
@abstractmethod
def load(self, key: str, version: str | None = None) -> PromptSource:
    """
    Load a prompt by key.

    Args:
        key (str): Engine-specific identifier for the prompt.
        version (str | None): Specific version to load; the engine's latest
            when omitted.

    Returns:
        PromptSource: The loaded prompt text plus metadata.

    Raises:
        PromptNotFound: If no prompt exists for the key (or version).
    """

ref(key: str, version: str | None = None) -> PromptRef

Create a deferred reference to a prompt, resolved at agent instantiation.

Parameters:

Name Type Description Default
key str

Engine-specific identifier for the prompt.

required
version str | None

Pin a specific version; the engine's latest when omitted.

None

Returns:

Name Type Description
PromptRef PromptRef

A reference that loads the prompt when resolved.

Source code in pyagentic/_base/_prompts.py
def ref(self, key: str, version: str | None = None) -> PromptRef:
    """
    Create a deferred reference to a prompt, resolved at agent instantiation.

    Args:
        key (str): Engine-specific identifier for the prompt.
        version (str | None): Pin a specific version; the engine's latest
            when omitted.

    Returns:
        PromptRef: A reference that loads the prompt when resolved.
    """
    return PromptRef(self, key, version=version)

LocalPromptEngine

Bases: PromptEngine

Prompt engine backed by the local file system.

A pattern defines how prompt files are laid out under the root directory (default .prompts/ in the current working directory). The pattern is a template with a required {key} placeholder and an optional {version} placeholder:

  • Without {version} (default "{key}.md"): the key maps to a single file and the prompt is versioned by content hash.
  • With {version} (e.g. "{key}/{version}.md"): the directory structure holds the versions. load(key) picks the latest version (natural sort, so v10 > v2); load(key, version="v1") pins one. The path's version segment becomes PromptSource.version.
Example
# .prompts/researcher/v1.md, .prompts/researcher/v2.md, ...
prompts = LocalPromptEngine(".prompts", pattern="{key}/{version}.md")

class ResearchAgent(BaseAgent):
    __instructions__ = prompts.ref("researcher")  # latest version

Parameters:

Name Type Description Default
path str | Path | None

Root directory holding prompt files. Defaults to .prompts/ under the current working directory.

None
pattern str

File layout template relative to the root. Must contain {key}; may contain {version} to derive versions from the file structure. Defaults to "{key}.md".

'{key}.md'

Raises:

Type Description
ValueError

If the pattern does not contain a {key} placeholder.

Source code in pyagentic/_base/_prompts.py
def __init__(self, path: str | Path | None = None, pattern: str = "{key}.md"):
    """
    Args:
        path (str | Path | None): Root directory holding prompt files. Defaults
            to `.prompts/` under the current working directory.
        pattern (str): File layout template relative to the root. Must contain
            `{key}`; may contain `{version}` to derive versions from the file
            structure. Defaults to `"{key}.md"`.

    Raises:
        ValueError: If the pattern does not contain a `{key}` placeholder.
    """
    if "{key}" not in pattern:
        raise ValueError(
            f"LocalPromptEngine pattern {pattern!r} must contain a '{{key}}' placeholder"
        )
    self.root = Path(path) if path else Path.cwd() / ".prompts"
    self.pattern = pattern
    self.versioned = "{version}" in pattern

pattern = pattern instance-attribute

root = Path(path) if path else Path.cwd() / '.prompts' instance-attribute

versioned = '{version}' in pattern instance-attribute

__repr__() -> str

Source code in pyagentic/_base/_prompts.py
def __repr__(self) -> str:
    return f"LocalPromptEngine(root={str(self.root)!r}, pattern={self.pattern!r})"

_resolve_versioned(key: str, version: str | None) -> tuple[Path, str]

Resolve path and version for a versioned pattern; latest version when unpinned.

Source code in pyagentic/_base/_prompts.py
def _resolve_versioned(self, key: str, version: str | None) -> tuple[Path, str]:
    """Resolve path and version for a versioned pattern; latest version when unpinned."""
    if version is not None:
        path = self.root / self.pattern.format(key=key, version=version)
        if not path.is_file():
            raise PromptNotFound(key=f"{key} (version {version})", source=str(self.root))
        return path, version

    # Glob for every version of the key, then parse the version segment back
    # out of each path with a regex built from the pattern
    regex = re.compile(
        re.escape(self.pattern)
        .replace(re.escape("{key}"), re.escape(key))
        .replace(re.escape("{version}"), r"(?P<version>[^/]+)")
    )
    found: dict[str, Path] = {}
    for path in self.root.glob(self.pattern.format(key=key, version="*")):
        match = regex.fullmatch(path.relative_to(self.root).as_posix())
        if match:
            found[match.group("version")] = path

    if not found:
        raise PromptNotFound(key=key, source=str(self.root))
    latest = max(found, key=_natural_sort_key)
    return found[latest], latest

load(key: str, version: str | None = None) -> PromptSource

Load a prompt from a file laid out per the engine's pattern.

Parameters:

Name Type Description Default
key str

Prompt identifier substituted into the pattern's {key}.

required
version str | None

Specific version to load. Only valid for versioned patterns; the latest version is used when omitted.

None

Returns:

Name Type Description
PromptSource PromptSource

The file contents. Versioned patterns take the version from the file structure; unversioned patterns use a content hash.

Raises:

Type Description
PromptNotFound

If no matching file exists under the root.

ValueError

If a version is requested but the pattern has no {version} placeholder.

Source code in pyagentic/_base/_prompts.py
def load(self, key: str, version: str | None = None) -> PromptSource:
    """
    Load a prompt from a file laid out per the engine's pattern.

    Args:
        key (str): Prompt identifier substituted into the pattern's `{key}`.
        version (str | None): Specific version to load. Only valid for
            versioned patterns; the latest version is used when omitted.

    Returns:
        PromptSource: The file contents. Versioned patterns take the version
            from the file structure; unversioned patterns use a content hash.

    Raises:
        PromptNotFound: If no matching file exists under the root.
        ValueError: If a version is requested but the pattern has no
            `{version}` placeholder.
    """
    if self.versioned:
        path, resolved_version = self._resolve_versioned(key, version)
    else:
        if version is not None:
            raise ValueError(
                f"Engine pattern {self.pattern!r} has no '{{version}}' placeholder; "
                "a specific version cannot be requested"
            )
        path = self.root / self.pattern.format(key=key)
        if not path.is_file():
            raise PromptNotFound(key=key, source=str(self.root))
        resolved_version = None

    text = path.read_text()
    return PromptSource(
        text=text,
        source=str(path),
        source_type="local",
        version=resolved_version or _version_hash(text),
        loaded_at=datetime.now(timezone.utc),
    )

PromptRef

A deferred pointer to a prompt in a PromptEngine.

Created via PromptEngine.ref(key) and assigned to __instructions__; resolved at agent instantiation, so each new instance (and each fork) reloads the prompt.

Source code in pyagentic/_base/_prompts.py
def __init__(self, engine: "PromptEngine", key: str, version: str | None = None):
    self.engine = engine
    self.key = key
    self.version = version

engine = engine instance-attribute

key = key instance-attribute

version = version instance-attribute

__repr__() -> str

Source code in pyagentic/_base/_prompts.py
def __repr__(self) -> str:
    return f"PromptRef(engine={self.engine!r}, key={self.key!r}, version={self.version!r})"

resolve() -> PromptSource

Load the referenced prompt from its engine.

Returns:

Name Type Description
PromptSource PromptSource

The loaded prompt text plus metadata.

Raises:

Type Description
PromptNotFound

If the engine has no prompt for the key.

Source code in pyagentic/_base/_prompts.py
def resolve(self) -> PromptSource:
    """
    Load the referenced prompt from its engine.

    Returns:
        PromptSource: The loaded prompt text plus metadata.

    Raises:
        PromptNotFound: If the engine has no prompt for the key.
    """
    return self.engine.load(self.key, version=self.version)

PromptSource

Bases: BaseModel

A loaded prompt along with metadata about where and when it was loaded.

Attributes:

Name Type Description
text str

The prompt text itself.

source str

Identifier of where the prompt came from (e.g. a file path).

source_type str

The kind of engine that loaded it (e.g. "local").

version str

Version identifier for the loaded text (e.g. a content hash).

loaded_at datetime

When the prompt was loaded.

loaded_at: datetime instance-attribute

source: str instance-attribute

source_type: str instance-attribute

text: str instance-attribute

version: str instance-attribute