Spaces:
Sleeping
Sleeping
File size: 1,819 Bytes
e787a71 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | """Backend factory — centralized creation of LLM backends.
Replaces scattered if/elif backend selection across mcp.py, routes.py, web.py.
"""
from __future__ import annotations
import logging
from core.types import LLMBackend
logger = logging.getLogger(__name__)
class BackendFactory:
"""Registry and factory for LLM backends."""
_registry: dict[str, type[LLMBackend]] = {}
@classmethod
def register(cls, name: str, backend_cls: type[LLMBackend]) -> None:
cls._registry[name] = backend_cls
@classmethod
def create(cls, name: str, **kwargs) -> LLMBackend:
if name not in cls._registry:
raise ValueError(f"Unknown backend: {name!r}. Available: {list(cls._registry.keys())}")
return cls._registry[name](**kwargs)
@classmethod
def create_safe(cls, name: str, **kwargs) -> LLMBackend:
"""Create backend, falling back to mock on failure."""
try:
return cls.create(name, **kwargs)
except Exception as exc:
logger.warning("Backend %r unavailable (%s), falling back to mock", name, exc)
return cls.create("mock")
def _register_defaults() -> None:
"""Register all built-in backends. Called at module load."""
from core.backends import MockBackend
BackendFactory.register("mock", MockBackend)
try:
from core.backends import AnthropicBackend
BackendFactory.register("anthropic", AnthropicBackend)
except Exception:
pass
try:
from core.backends import OpenAIBackend
BackendFactory.register("openai", OpenAIBackend)
except Exception:
pass
try:
from core.backends import GeminiBackend
BackendFactory.register("gemini", GeminiBackend)
except Exception:
pass
_register_defaults()
|