Newer
Older
navi-1 / navi / tools / reload_tools.py
"""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))