Skip to content

tools

View module diagram

Declared tool validation and agent guidance.

Graphs declare required tools (e.g., pixi) so the orchestrator can validate availability before launch and inject usage guidance into agent instructions.

Classes:

Name Description
ToolSpec

Validation command and agent guidance for a single tool.

Functions:

Name Description
validate_tools

Check that all declared tools are available.

tool_guidance

Return agent guidance text for a list of tools.

TOOL_REGISTRY = {'pixi': ToolSpec(binary='pixi', agent_guidance='Use `pixi run` to execute all Python commands, tests, and scripts. Do not use bare `python`, `pytest`, or `pip` — always prefix with `pixi run`.')} module-attribute

Registry of known tools. Keyed by the name used in graph YAML.

ToolSpec dataclass

Validation and guidance metadata for a declared tool.

Attributes:

Name Type Description
binary str

Name of the binary to check (via shutil.which).

agent_guidance str

Markdown text telling agents how to use the tool.

Source code in src/agentrelay/tools.py
21
22
23
24
25
26
27
28
29
30
31
@dataclass(frozen=True)
class ToolSpec:
    """Validation and guidance metadata for a declared tool.

    Attributes:
        binary: Name of the binary to check (via ``shutil.which``).
        agent_guidance: Markdown text telling agents how to use the tool.
    """

    binary: str
    agent_guidance: str

ToolValidationError

Bases: RuntimeError

Raised when a declared tool fails validation.

Source code in src/agentrelay/tools.py
46
47
class ToolValidationError(RuntimeError):
    """Raised when a declared tool fails validation."""

validate_tools(tools)

Validate that all declared tools are available.

For each tool name, looks up the registry entry and checks that the binary is on PATH via :func:shutil.which.

Parameters:

Name Type Description Default
tools tuple[str, ...]

Tool names declared in the graph YAML.

required

Raises:

Type Description
ToolValidationError

If a tool is unknown or its binary is not found.

Source code in src/agentrelay/tools.py
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
def validate_tools(tools: tuple[str, ...]) -> None:
    """Validate that all declared tools are available.

    For each tool name, looks up the registry entry and checks that the
    binary is on PATH via :func:`shutil.which`.

    Args:
        tools: Tool names declared in the graph YAML.

    Raises:
        ToolValidationError: If a tool is unknown or its binary is not found.
    """
    for name in tools:
        spec = TOOL_REGISTRY.get(name)
        if spec is None:
            known = ", ".join(sorted(TOOL_REGISTRY))
            raise ToolValidationError(
                f"Unknown tool '{name}' declared in graph YAML. "
                f"Known tools: {known}"
            )
        if shutil.which(spec.binary) is None:
            raise ToolValidationError(
                f"Tool '{name}' is declared but '{spec.binary}' was not found on PATH.\n"
                f"Install it or remove '{name}' from the graph's tools list."
            )

tool_guidance(tools)

Build agent guidance text for the declared tools.

Parameters:

Name Type Description Default
tools tuple[str, ...]

Tool names declared in the graph YAML.

required

Returns:

Type Description
str

Markdown text with guidance for each tool, or empty string if no

str

tools are declared.

Source code in src/agentrelay/tools.py
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
def tool_guidance(tools: tuple[str, ...]) -> str:
    """Build agent guidance text for the declared tools.

    Args:
        tools: Tool names declared in the graph YAML.

    Returns:
        Markdown text with guidance for each tool, or empty string if no
        tools are declared.
    """
    if not tools:
        return ""
    lines: list[str] = []
    for name in tools:
        spec = TOOL_REGISTRY.get(name)
        if spec is not None:
            lines.append(f"- **{name}**: {spec.agent_guidance}")
    lines.append("")
    return "\n".join(lines)