"""Tool registration and schema export.""" import logging from pathlib import Path from typing import Any from app.models.config import AppConfig from app.tools.base import BaseTool logger = logging.getLogger(__name__) class ToolRegistry: """Registry of available tools, keyed by name.""" def __init__(self) -> None: self._tools: dict[str, BaseTool] = {} def register(self, tool: BaseTool) -> None: """Register a tool instance. Raises ValueError on duplicate name.""" if tool.name in self._tools: raise ValueError(f"Duplicate tool name: '{tool.name}'") self._tools[tool.name] = tool logger.debug("Registered tool: %s", tool.name) def get(self, name: str) -> BaseTool | None: """Look up a tool by name.""" return self._tools.get(name) def get_all(self) -> dict[str, BaseTool]: """Return all registered tools.""" return dict(self._tools) def get_openai_tools_schema(self) -> list[dict[str, Any]]: """Return OpenAI function-calling schemas for all registered tools.""" return [tool.get_openai_schema() for tool in self._tools.values()] def create_default_registry(workspace_root: Path, config: AppConfig) -> ToolRegistry: """Create a ToolRegistry populated with all built-in tools.""" # Read tools from app.tools.filesystem import ListDirTool, ReadFileTool # Write tools from app.tools.filesystem import DeleteFileTool, MakeDirTool, WriteFileTool # Edit tools from app.tools.edit import PatchApplyTool, StrReplaceTool # Shell tools from app.tools.shell import RunCommandTool # Control flow from app.tools.finish import FinishTool # Search tools from app.tools.search import FindFilesTool, GrepFilesTool registry = ToolRegistry() # Read registry.register(ReadFileTool(workspace_root, config)) registry.register(ListDirTool(workspace_root, config)) # Search registry.register(GrepFilesTool(workspace_root, config)) registry.register(FindFilesTool(workspace_root, config)) # Write registry.register(WriteFileTool(workspace_root, config)) registry.register(MakeDirTool(workspace_root, config)) registry.register(DeleteFileTool(workspace_root, config)) # Edit registry.register(StrReplaceTool(workspace_root, config)) registry.register(PatchApplyTool(workspace_root, config)) # Shell registry.register(RunCommandTool(workspace_root, config)) # Control flow registry.register(FinishTool(workspace_root, config)) return registry