Skip to content

rigging.tool

This module defines handles tool interaction with rigging generation.

SUPPORTED_TOOL_ARGUMENT_TYPES = t.Union[int, float, str, bool] module-attribute #

Supported types for tool arguments.

SUPPORTED_TOOL_ARGUMENT_TYPES_LIST = [int, float, str, bool] module-attribute #

Supported types for tool arguments as a list.

Tool #

Base class for implementing tools in the Rigging system.

You should subclass this to define your own tools:

def Hammer(Tool):
    name = "Hammer"
    description = "A tool for hitting things."

    def hit(self, target: Annotated[str, "Target of the hit") -> str:
        return f"Hit {target} with a hammer."

chat = await generator.chat(...).using(Hammer()).run()
Note

The name and description attributes are required and can be defined as class attributes or properties. If you define them as properties, you must also define a getter for them.

Note

All functions on the tool must have type hints for their parameters and use the Annotated type hint to provide a description for each parameter.

description: str instance-attribute #

Description of the tool

name: str instance-attribute #

Name of the tool

execute(call: ToolCall) -> ToolResult #

Executes a function call on the tool.

Source code in rigging/tool.py
def execute(self, call: ToolCall) -> ToolResult:
    """Executes a function call on the tool."""
    try:
        content = self._execute(call)
        return ToolResult(tool=call.tool, function=call.function, error=False, content=content)
    except Exception as e:
        return ToolResult(tool=call.tool, function=call.function, error=True, content=str(e))

get_description() -> ToolDescription #

Creates a full description of the tool for use in prompting

Source code in rigging/tool.py
def get_description(self) -> ToolDescription:
    """Creates a full description of the tool for use in prompting"""
    functions: list[ToolFunction] = []
    for method_name, method in inspect.getmembers(self.__class__, predicate=inspect.isfunction):
        if not method.__qualname__.startswith(self.__class__.__name__):
            continue

        if method_name.startswith("_"):
            continue

        signature = inspect.signature(method)

        if signature.return_annotation is inspect.Signature.empty:
            raise TypeError(f"Functions must have return type hints ({method_name})")

        if signature.return_annotation != str:
            raise TypeError(f"Functions must return strings ({method_name})")

        parameters: list[ToolParameter] = []
        for param_name, param in signature.parameters.items():
            if param_name == "self":
                continue

            formatted_name = f"{method.__name__}#{param_name}"

            if param.kind not in (
                inspect.Parameter.POSITIONAL_OR_KEYWORD,
                inspect.Parameter.KEYWORD_ONLY,
            ):
                raise TypeError(f"Parameters must be positional or keyword ({formatted_name})")

            if param.annotation is inspect.Parameter.empty:
                raise TypeError(f"Parameters must have type hints ({formatted_name})")

            if t.get_origin(param.annotation) != t.Annotated:
                raise TypeError(
                    f'Parameters must be annotated like Annotated[<type>, "<description>"] ({formatted_name})'
                )

            annotation_args = t.get_args(param.annotation)

            if len(annotation_args) != 2 or not isinstance(annotation_args[1], str):
                raise TypeError(
                    f'Parameters must be annotated like Annotated[<type>, "<description>"] ({formatted_name})'
                )

            if annotation_args[0] not in SUPPORTED_TOOL_ARGUMENT_TYPES_LIST:
                raise TypeError(
                    f"Parameters must be annotated with one of these types: {SUPPORTED_TOOL_ARGUMENT_TYPES_LIST} ({formatted_name})"
                )

            type_name = annotation_args[0].__name__
            description = annotation_args[1]

            parameters.append(ToolParameter(name=param_name, type=type_name, description=description))

        functions.append(
            ToolFunction(
                name=method_name,
                description=method.__doc__ if method.__doc__ else "",
                parameters=parameters,
            )
        )

    return ToolDescription(name=self.name, description=self.description, functions=functions)