Files
oai-web/server/tools/base.py
2026-04-08 12:43:24 +02:00

72 lines
2.1 KiB
Python

"""
tools/base.py — BaseTool abstract class.
All tools inherit from this. The tool registry discovers them and builds
the schema list sent to the AI provider on every agent call.
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass
@dataclass
class ToolResult:
"""Normalised return value from every tool execution."""
success: bool
data: dict | list | str | None = None
error: str | None = None
def to_dict(self) -> dict:
if self.success:
return {"success": True, "data": self.data}
result: dict = {"success": False, "error": self.error}
if self.data is not None:
result["data"] = self.data
return result
class BaseTool(ABC):
"""
Abstract base for all aide tools.
Subclasses must set class-level attributes:
name — used in tool schema and audit log
description — what the AI sees
input_schema — JSON Schema for parameters (Anthropic-native format)
Optional overrides:
requires_confirmation — default False
allowed_in_scheduled_tasks — default True
"""
name: str
description: str
input_schema: dict
requires_confirmation: bool = False
allowed_in_scheduled_tasks: bool = True
@abstractmethod
async def execute(self, **kwargs) -> ToolResult:
"""
Run the tool. Never raises — always returns a ToolResult.
The dispatcher catches any unexpected exceptions as a safety net.
"""
def get_schema(self) -> dict:
"""Return the tool schema in aide-internal / Anthropic-native format."""
return {
"name": self.name,
"description": self.description,
"input_schema": self.input_schema,
}
def confirmation_description(self, **kwargs) -> str:
"""
Human-readable description of the action shown to the user
when confirmation is required. Override for better messages.
"""
args_str = ", ".join(f"{k}={v!r}" for k, v in kwargs.items())
return f"{self.name}({args_str})"