Newer
Older
navi-1 / navi / core / registry.py
@Eugene Sukhodolskiy Eugene Sukhodolskiy on 8 Apr 2 KB Unrestricted terminal mode and SSH tool
"""Registries for tools, profiles, and LLM backends."""

from navi.config import settings
from navi.exceptions import ProfileNotFound, ToolNotFound
from navi.llm.base import LLMBackend
from navi.llm.ollama import OllamaBackend
from navi.profiles import ALL_PROFILES
from navi.profiles.base import AgentProfile
from navi.tools import (
    CodeExecTool,
    FilesystemTool,
    HttpRequestTool,
    SshExecTool,
    TerminalTool,
    Tool,
    WebSearchTool,
)


class ToolRegistry:
    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:
        if name not in self._tools:
            raise ToolNotFound(name)
        return self._tools[name]

    def resolve(self, names: list[str]) -> list[Tool]:
        return [self.get(n) for n in names]

    def all(self) -> list[Tool]:
        return list(self._tools.values())


class ProfileRegistry:
    def __init__(self) -> None:
        self._profiles: dict[str, AgentProfile] = {}

    def register(self, profile: AgentProfile) -> None:
        self._profiles[profile.id] = profile

    def get(self, profile_id: str) -> AgentProfile:
        if profile_id not in self._profiles:
            raise ProfileNotFound(profile_id)
        return self._profiles[profile_id]

    def all(self) -> list[AgentProfile]:
        return list(self._profiles.values())


class BackendRegistry:
    def __init__(self) -> None:
        self._backends: dict[str, LLMBackend] = {}

    def register(self, key: str, backend: LLMBackend) -> None:
        self._backends[key] = backend

    def get(self, key: str, model: str | None = None) -> LLMBackend:
        backend = self._backends.get(key)
        if backend is None:
            raise KeyError(f"LLM backend '{key}' not registered")
        return backend

    def all_keys(self) -> list[str]:
        return list(self._backends.keys())


def build_default_registries() -> tuple[ToolRegistry, ProfileRegistry, BackendRegistry]:
    """Build and populate registries with all built-in components."""

    tools = ToolRegistry()
    tools.register(WebSearchTool())
    tools.register(FilesystemTool())
    tools.register(HttpRequestTool())
    tools.register(CodeExecTool())
    tools.register(TerminalTool())
    tools.register(SshExecTool())

    profiles = ProfileRegistry()
    for p in ALL_PROFILES:
        profiles.register(p)

    backends = BackendRegistry()
    backends.register(
        "ollama",
        OllamaBackend(
            model=settings.ollama_default_model,
            host=settings.ollama_host,
        ),
    )

    return tools, profiles, backends