Files
xtrm-agent/xtrm_agent/tools/registry.py
Kaloyan Danchev 378d599125 Initial implementation of xtrm-agent multi-agent system
Multi-agent AI automation system with shared message bus, specialized
roles (coder/researcher/reviewer), and deny-by-default security.

- Config system with Pydantic validation and YAML loading
- Async message bus with inter-agent delegation
- LLM providers: Anthropic (Claude) and LiteLLM (DeepSeek/Kimi/MiniMax)
- Tool system: registry, builtins (file/bash/web), approval engine, MCP client
- Agent engine with tool-calling loop and orchestrator for multi-agent management
- CLI channel (REPL) and Discord channel
- Docker + Dockge deployment config
- Typer CLI: chat, serve, status, agents commands

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:21:42 +02:00

81 lines
2.2 KiB
Python

"""Tool registry — ABC and dynamic registration."""
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any
from loguru import logger
class Tool(ABC):
"""Abstract base for all tools."""
@property
@abstractmethod
def name(self) -> str: ...
@property
@abstractmethod
def description(self) -> str: ...
@property
@abstractmethod
def parameters(self) -> dict[str, Any]:
"""JSON Schema for tool parameters."""
@abstractmethod
async def execute(self, **kwargs: Any) -> str:
"""Execute the tool and return a string result."""
def to_openai_schema(self) -> dict[str, Any]:
"""Convert to OpenAI function-calling format."""
return {
"type": "function",
"function": {
"name": self.name,
"description": self.description,
"parameters": self.parameters,
},
}
class ToolRegistry:
"""Manages registered tools and dispatches execution."""
def __init__(self) -> None:
self._tools: dict[str, Tool] = {}
def register(self, tool: Tool) -> None:
self._tools[tool.name] = tool
def get(self, name: str) -> Tool | None:
return self._tools.get(name)
def names(self) -> list[str]:
return list(self._tools.keys())
def get_definitions(self) -> list[dict[str, Any]]:
"""Get all tool schemas for the LLM."""
return [t.to_openai_schema() for t in self._tools.values()]
def filtered(self, allowed: list[str]) -> ToolRegistry:
"""Return a new registry containing only the specified tools."""
filtered_reg = ToolRegistry()
for name in allowed:
tool = self._tools.get(name)
if tool:
filtered_reg.register(tool)
return filtered_reg
async def execute(self, name: str, arguments: dict[str, Any]) -> str:
"""Execute a tool by name."""
tool = self._tools.get(name)
if not tool:
return f"Error: Unknown tool '{name}'"
try:
return await tool.execute(**arguments)
except Exception as e:
logger.error(f"Tool '{name}' failed: {e}")
return f"Error executing '{name}': {e}"