kiln_ai.tools

1from kiln_ai.tools.base_tool import KilnTool, KilnToolInterface, UnmanagedKilnTool
2from kiln_ai.tools.tool_registry import tool_from_id
3
4__all__ = [
5    "KilnTool",
6    "KilnToolInterface",
7    "UnmanagedKilnTool",
8    "tool_from_id",
9]
class KilnTool(kiln_ai.tools.KilnToolInterface):
139class KilnTool(KilnToolInterface):
140    """
141    Base helper class that provides common functionality for tool implementations.
142    Subclasses only need to implement run() and provide tool configuration.
143    """
144
145    def __init__(
146        self,
147        tool_id: KilnBuiltInToolId,
148        name: str,
149        description: str,
150        parameters_schema: Dict[str, Any],
151    ):
152        self._id = tool_id
153        self._name = name
154        self._description = description
155        validate_schema_dict(parameters_schema)
156        self._parameters_schema = parameters_schema
157
158    async def id(self) -> KilnBuiltInToolId:
159        return self._id
160
161    async def name(self) -> str:
162        return self._name
163
164    async def description(self) -> str:
165        return self._description
166
167    async def toolcall_definition(self) -> ToolCallDefinition:
168        """Generate OpenAI-compatible tool definition."""
169        return {
170            "type": "function",
171            "function": {
172                "name": await self.name(),
173                "description": await self.description(),
174                "parameters": self._parameters_schema,
175            },
176        }
177
178    @abstractmethod
179    async def run(
180        self, context: ToolCallContext | None = None, **kwargs
181    ) -> ToolCallResult:
182        """Subclasses must implement the actual tool logic."""
183        pass

Base helper class that provides common functionality for tool implementations. Subclasses only need to implement run() and provide tool configuration.

async def id(self) -> kiln_ai.datamodel.tool_id.KilnBuiltInToolId:
158    async def id(self) -> KilnBuiltInToolId:
159        return self._id

Return a unique identifier for this tool.

async def name(self) -> str:
161    async def name(self) -> str:
162        return self._name

Return the tool name (function name) of this tool.

async def description(self) -> str:
164    async def description(self) -> str:
165        return self._description

Return a description of what this tool does.

async def toolcall_definition(self) -> kiln_ai.tools.base_tool.ToolCallDefinition:
167    async def toolcall_definition(self) -> ToolCallDefinition:
168        """Generate OpenAI-compatible tool definition."""
169        return {
170            "type": "function",
171            "function": {
172                "name": await self.name(),
173                "description": await self.description(),
174                "parameters": self._parameters_schema,
175            },
176        }

Generate OpenAI-compatible tool definition.

@abstractmethod
async def run( self, context: kiln_ai.tools.base_tool.ToolCallContext | None = None, **kwargs) -> kiln_ai.tools.base_tool.ToolCallResult:
178    @abstractmethod
179    async def run(
180        self, context: ToolCallContext | None = None, **kwargs
181    ) -> ToolCallResult:
182        """Subclasses must implement the actual tool logic."""
183        pass

Subclasses must implement the actual tool logic.

class KilnToolInterface(abc.ABC):
54class KilnToolInterface(ABC):
55    """
56    Abstract interface defining the core API that all Kiln tools must implement.
57    This ensures consistency across all tool implementations.
58    """
59
60    @abstractmethod
61    async def run(
62        self, context: ToolCallContext | None = None, **kwargs
63    ) -> ToolCallResult:
64        """Execute the tool with the given parameters and calling context if provided."""
65        pass
66
67    @abstractmethod
68    async def toolcall_definition(self) -> ToolCallDefinition:
69        """Return the OpenAI-compatible tool definition for this tool."""
70        pass
71
72    @abstractmethod
73    async def id(self) -> ToolId:
74        """Return a unique identifier for this tool."""
75        pass
76
77    @abstractmethod
78    async def name(self) -> str:
79        """Return the tool name (function name) of this tool."""
80        pass
81
82    @abstractmethod
83    async def description(self) -> str:
84        """Return a description of what this tool does."""
85        pass

Abstract interface defining the core API that all Kiln tools must implement. This ensures consistency across all tool implementations.

@abstractmethod
async def run( self, context: kiln_ai.tools.base_tool.ToolCallContext | None = None, **kwargs) -> kiln_ai.tools.base_tool.ToolCallResult:
60    @abstractmethod
61    async def run(
62        self, context: ToolCallContext | None = None, **kwargs
63    ) -> ToolCallResult:
64        """Execute the tool with the given parameters and calling context if provided."""
65        pass

Execute the tool with the given parameters and calling context if provided.

@abstractmethod
async def toolcall_definition(self) -> kiln_ai.tools.base_tool.ToolCallDefinition:
67    @abstractmethod
68    async def toolcall_definition(self) -> ToolCallDefinition:
69        """Return the OpenAI-compatible tool definition for this tool."""
70        pass

Return the OpenAI-compatible tool definition for this tool.

@abstractmethod
async def id( self) -> Annotated[str, AfterValidator(func=<function <lambda> at 0x7fc4f7aa4400>)]:
72    @abstractmethod
73    async def id(self) -> ToolId:
74        """Return a unique identifier for this tool."""
75        pass

Return a unique identifier for this tool.

@abstractmethod
async def name(self) -> str:
77    @abstractmethod
78    async def name(self) -> str:
79        """Return the tool name (function name) of this tool."""
80        pass

Return the tool name (function name) of this tool.

@abstractmethod
async def description(self) -> str:
82    @abstractmethod
83    async def description(self) -> str:
84        """Return a description of what this tool does."""
85        pass

Return a description of what this tool does.

class UnmanagedKilnTool(kiln_ai.tools.KilnToolInterface):
 88class UnmanagedKilnTool(KilnToolInterface):
 89    """
 90    Helper for tools passed via ``AdapterConfig.unmanaged_tools`` (SDK-injected, not from the
 91    Kiln tool registry). Use a :class:`~kiln_ai.datamodel.tool_id.ToolId` with prefix
 92    ``kiln_unmanaged::<id>`` (see :func:`~kiln_ai.datamodel.tool_id.build_kiln_unmanaged_tool_id`).
 93    Subclass and override :meth:`run` for in-adapter execution when ``return_on_tool_call`` is
 94    False; default :meth:`run` raises (use ``return_on_tool_call`` and resume with tool results
 95    in ``prior_trace``, or provide a subclass that implements :meth:`run`).
 96    """
 97
 98    def __init__(
 99        self,
100        tool_id: ToolId,
101        name: str,
102        description: str,
103        parameters_schema: Dict[str, Any],
104    ):
105        validate_schema_dict(parameters_schema)
106        self._tool_id = tool_id
107        self._name = name
108        self._description = description
109        self._parameters_schema = parameters_schema
110
111    async def id(self) -> ToolId:
112        return self._tool_id
113
114    async def name(self) -> str:
115        return self._name
116
117    async def description(self) -> str:
118        return self._description
119
120    async def toolcall_definition(self) -> ToolCallDefinition:
121        return {
122            "type": "function",
123            "function": {
124                "name": await self.name(),
125                "description": await self.description(),
126                "parameters": self._parameters_schema,
127            },
128        }
129
130    async def run(
131        self, context: ToolCallContext | None = None, **kwargs
132    ) -> ToolCallResult:
133        raise RuntimeError(
134            "This tool is supplied as an unmanaged KilnTool for API tool definitions only; "
135            "the Kiln adapter does not execute it when return_on_tool_call is True."
136        )

Helper for tools passed via AdapterConfig.unmanaged_tools (SDK-injected, not from the Kiln tool registry). Use a ~kiln_ai.datamodel.tool_id.ToolId with prefix kiln_unmanaged::<id> (see ~kiln_ai.datamodel.tool_id.build_kiln_unmanaged_tool_id()). Subclass and override run() for in-adapter execution when return_on_tool_call is False; default run() raises (use return_on_tool_call and resume with tool results in prior_trace, or provide a subclass that implements run()).

UnmanagedKilnTool( tool_id: Annotated[str, AfterValidator(func=<function <lambda>>)], name: str, description: str, parameters_schema: Dict[str, Any])
 98    def __init__(
 99        self,
100        tool_id: ToolId,
101        name: str,
102        description: str,
103        parameters_schema: Dict[str, Any],
104    ):
105        validate_schema_dict(parameters_schema)
106        self._tool_id = tool_id
107        self._name = name
108        self._description = description
109        self._parameters_schema = parameters_schema
async def id( self) -> Annotated[str, AfterValidator(func=<function <lambda> at 0x7fc4f7aa4400>)]:
111    async def id(self) -> ToolId:
112        return self._tool_id

Return a unique identifier for this tool.

async def name(self) -> str:
114    async def name(self) -> str:
115        return self._name

Return the tool name (function name) of this tool.

async def description(self) -> str:
117    async def description(self) -> str:
118        return self._description

Return a description of what this tool does.

async def toolcall_definition(self) -> kiln_ai.tools.base_tool.ToolCallDefinition:
120    async def toolcall_definition(self) -> ToolCallDefinition:
121        return {
122            "type": "function",
123            "function": {
124                "name": await self.name(),
125                "description": await self.description(),
126                "parameters": self._parameters_schema,
127            },
128        }

Return the OpenAI-compatible tool definition for this tool.

async def run( self, context: kiln_ai.tools.base_tool.ToolCallContext | None = None, **kwargs) -> kiln_ai.tools.base_tool.ToolCallResult:
130    async def run(
131        self, context: ToolCallContext | None = None, **kwargs
132    ) -> ToolCallResult:
133        raise RuntimeError(
134            "This tool is supplied as an unmanaged KilnTool for API tool definitions only; "
135            "the Kiln adapter does not execute it when return_on_tool_call is True."
136        )

Execute the tool with the given parameters and calling context if provided.

def tool_from_id( tool_id: str, task: kiln_ai.datamodel.Task | None = None) -> KilnToolInterface:
174def tool_from_id(tool_id: str, task: Task | None = None) -> KilnToolInterface:
175    """Get a tool from its ID.
176
177    Thin wrapper around ``tool_from_id_and_project`` that derives
178    the project from *task*.
179    """
180    project = task.parent_project() if task is not None else None
181    return tool_from_id_and_project(tool_id, project=project, task=task)

Get a tool from its ID.

Thin wrapper around tool_from_id_and_project that derives the project from task.