"""Built-in tool to hot-reload user tools and context providers without restarting."""
from navi.config import settings
from .base import Tool, ToolResult
class ReloadToolsTool(Tool):
name = "reload_tools"
description = (
"Hot-reload all tools from the tools/ directory and context providers from "
"context_providers/ without restarting the server. "
"Call this after writing or editing a tool or context provider file. "
"Returns a report of what was loaded and any errors per file."
)
parameters = {
"type": "object",
"properties": {},
"required": [],
}
def __init__(self, registry=None, cp_registry=None) -> None:
self._registry = registry
self._cp_registry = cp_registry
async def execute(self, params: dict) -> ToolResult:
if self._registry is None:
return ToolResult(success=False, output="Tool registry not available.", error="no_registry")
lines = []
has_errors = False
tool_result = self._registry.reload_user_tools(settings.tools_dir)
if tool_result.loaded:
lines.append(f"Tools ({len(tool_result.loaded)}): {', '.join(t.name for t in tool_result.loaded)}")
else:
lines.append("Tools: none.")
if tool_result.errors:
has_errors = True
lines.append(f"Tool errors ({len(tool_result.errors)}):")
for filename, error in tool_result.errors.items():
lines.append(f" {filename}: {error}")
if self._cp_registry is not None:
cp_result = self._cp_registry.reload_user_providers(settings.context_providers_dir)
if cp_result.loaded:
lines.append(f"Context providers ({len(cp_result.loaded)}): {', '.join(cp_result.loaded)}")
else:
lines.append("Context providers: none.")
if cp_result.errors:
has_errors = True
lines.append(f"Context provider errors ({len(cp_result.errors)}):")
for filename, error in cp_result.errors.items():
lines.append(f" {filename}: {error}")
return ToolResult(success=not has_errors, output="\n".join(lines))