feat: implement skeleton phase

This commit is contained in:
hh
2026-05-19 14:19:15 +02:00
parent 75a23d231e
commit 221e660c5c
21 changed files with 586 additions and 3 deletions
+83
View File
@@ -0,0 +1,83 @@
"""Agent / MCP registries + the user-facing ``Gateway`` collector.
The user's ``/config/config.py`` ends with::
gateway = Gateway(agents=[...], mcps=[...], frontends=[...])
``cli.main`` picks that object up and builds the registries.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Iterable, Iterator
from beaver_gateway.agents.base import BaseAgent
from beaver_gateway.frontends.base import Frontend
from beaver_gateway.mcp.types import McpServerT
class AgentRegistry:
"""Name → agent lookup with duplicate detection."""
def __init__(self, agents: Iterable[BaseAgent]) -> None:
self._agents: dict[str, BaseAgent] = {}
for a in agents:
if a.name in self._agents:
msg = f"duplicate agent name: {a.name!r}"
raise ValueError(msg)
self._agents[a.name] = a
def __getitem__(self, name: str) -> BaseAgent:
return self._agents[name]
def get(self, name: str) -> BaseAgent | None:
return self._agents.get(name)
def __iter__(self) -> Iterator[BaseAgent]:
return iter(self._agents.values())
def __len__(self) -> int:
return len(self._agents)
def __contains__(self, name: object) -> bool:
return name in self._agents
class McpRegistry:
"""Name → MCP server lookup with duplicate detection."""
def __init__(self, mcps: Iterable[McpServerT]) -> None:
self._mcps: dict[str, McpServerT] = {}
for m in mcps:
if m.name in self._mcps:
msg = f"duplicate mcp name: {m.name!r}"
raise ValueError(msg)
self._mcps[m.name] = m
def __getitem__(self, name: str) -> McpServerT:
return self._mcps[name]
def get(self, name: str) -> McpServerT | None:
return self._mcps.get(name)
def __iter__(self) -> Iterator[McpServerT]:
return iter(self._mcps.values())
def __len__(self) -> int:
return len(self._mcps)
def __contains__(self, name: object) -> bool:
return name in self._mcps
@dataclass(slots=True)
class Gateway:
"""Top-level object the user assembles in ``/config/config.py``."""
agents: list[BaseAgent] = field(default_factory=list)
mcps: list[McpServerT] = field(default_factory=list)
frontends: list[Frontend] = field(default_factory=list)