Stack-2-9-finetuned / src /tools /registry.py
walidsobhie-code
fix: restore previous model card with tools showcase
b64b6b0
"""Tool registry for Stack 2.9 tools."""
from __future__ import annotations
from typing import Any
from .base import BaseTool
class ToolRegistry:
"""Singleton registry mapping tool names to tool instances."""
_instance: ToolRegistry | None = None
_tools: dict[str, BaseTool] = {}
def __new__(cls) -> ToolRegistry:
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._tools = {}
return cls._instance
def register(self, tool: BaseTool) -> None:
"""Register a tool instance by name."""
if not tool.name:
raise ValueError("Tool must have a non-empty name")
self._tools[tool.name] = tool
def get(self, name: str) -> BaseTool | None:
"""Retrieve a registered tool by name."""
return self._tools.get(name)
def list(self) -> list[str]:
"""List all registered tool names."""
return list(self._tools.keys())
def list_tools(self) -> dict[str, dict[str, Any]]:
"""List all registered tools with their info.
Returns a dict mapping tool name to info dict with keys:
- name: str
- description: str
- input_schema: dict
"""
result = {}
for name, tool in self._tools.items():
schema = tool.input_schema
if callable(schema):
schema = schema()
result[name] = {
"name": tool.name,
"description": tool.description,
"input_schema": schema,
}
return result
def call(self, name: str, input_data: dict[str, Any]) -> Any:
"""Convenience: get tool and call it in one step."""
tool = self.get(name)
if tool is None:
raise KeyError(f"Tool not found: {name}")
return tool.call(input_data)
def unregister(self, name: str) -> bool:
"""Remove a tool from the registry. Returns True if it existed."""
if name in self._tools:
del self._tools[name]
return True
return False
def get_registry() -> ToolRegistry:
"""Get the global ToolRegistry instance."""
return ToolRegistry()
# Global registry instance
tool_registry = ToolRegistry()