Newer
Older
navi-1 / navi / core / registry.py
"""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,
    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())

    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