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):
143class KilnTool(KilnToolInterface):
144    """
145    Base helper class that provides common functionality for tool implementations.
146    Subclasses only need to implement run() and provide tool configuration.
147    """
148
149    def __init__(
150        self,
151        tool_id: KilnBuiltInToolId,
152        name: str,
153        description: str,
154        parameters_schema: Dict[str, Any],
155    ):
156        self._id = tool_id
157        self._name = name
158        self._description = description
159        validate_schema_dict(parameters_schema)
160        self._parameters_schema = parameters_schema
161
162    async def id(self) -> KilnBuiltInToolId:
163        return self._id
164
165    async def name(self) -> str:
166        return self._name
167
168    async def description(self) -> str:
169        return self._description
170
171    async def toolcall_definition(self) -> ToolCallDefinition:
172        """Generate OpenAI-compatible tool definition."""
173        return {
174            "type": "function",
175            "function": {
176                "name": await self.name(),
177                "description": await self.description(),
178                "parameters": self._parameters_schema,
179            },
180        }
181
182    @abstractmethod
183    async def run(
184        self, context: ToolCallContext | None = None, **kwargs
185    ) -> ToolCallResult:
186        """Subclasses must implement the actual tool logic."""
187        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:
162    async def id(self) -> KilnBuiltInToolId:
163        return self._id

Return a unique identifier for this tool.

async def name(self) -> str:
165    async def name(self) -> str:
166        return self._name

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

async def description(self) -> str:
168    async def description(self) -> str:
169        return self._description

Return a description of what this tool does.

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

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:
182    @abstractmethod
183    async def run(
184        self, context: ToolCallContext | None = None, **kwargs
185    ) -> ToolCallResult:
186        """Subclasses must implement the actual tool logic."""
187        pass

Subclasses must implement the actual tool logic.

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

Return the OpenAI-compatible tool definition for this tool.

@abstractmethod
async def id( self) -> Annotated[str, AfterValidator(func=<function <lambda> at 0x7f5eb9365b20>)]:
76    @abstractmethod
77    async def id(self) -> ToolId:
78        """Return a unique identifier for this tool."""
79        pass

Return a unique identifier for this tool.

@abstractmethod
async def name(self) -> str:
81    @abstractmethod
82    async def name(self) -> str:
83        """Return the tool name (function name) of this tool."""
84        pass

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

@abstractmethod
async def description(self) -> str:
86    @abstractmethod
87    async def description(self) -> str:
88        """Return a description of what this tool does."""
89        pass

Return a description of what this tool does.

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

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])
102    def __init__(
103        self,
104        tool_id: ToolId,
105        name: str,
106        description: str,
107        parameters_schema: Dict[str, Any],
108    ):
109        validate_schema_dict(parameters_schema)
110        self._tool_id = tool_id
111        self._name = name
112        self._description = description
113        self._parameters_schema = parameters_schema
async def id( self) -> Annotated[str, AfterValidator(func=<function <lambda> at 0x7f5eb9365b20>)]:
115    async def id(self) -> ToolId:
116        return self._tool_id

Return a unique identifier for this tool.

async def name(self) -> str:
118    async def name(self) -> str:
119        return self._name

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

async def description(self) -> str:
121    async def description(self) -> str:
122        return self._description

Return a description of what this tool does.

async def toolcall_definition(self) -> kiln_ai.tools.base_tool.ToolCallDefinition:
124    async def toolcall_definition(self) -> ToolCallDefinition:
125        return {
126            "type": "function",
127            "function": {
128                "name": await self.name(),
129                "description": await self.description(),
130                "parameters": self._parameters_schema,
131            },
132        }

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:
134    async def run(
135        self, context: ToolCallContext | None = None, **kwargs
136    ) -> ToolCallResult:
137        raise RuntimeError(
138            "This tool is supplied as an unmanaged KilnTool for API tool definitions only; "
139            "the Kiln adapter does not execute it when return_on_tool_call is True."
140        )

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.