"""Backend selection: local llama-server > API > scripted, by availability. Environment knobs: SCRYPT_BACKEND auto|local|api|scripted (default auto) SCRYPT_API_BASE OpenAI-compatible base URL (default OpenRouter) SCRYPT_API_KEY bearer token for the API SCRYPT_MODEL model id for the API """ from __future__ import annotations import os from .api import DEFAULT_MODEL, OpenAIChatBackend from .backend import Backend, ScriptedBackend, complete from .local import LlamaServer, preflight OPENROUTER = "https://openrouter.ai/api/v1" def build_backend() -> tuple[Backend, LlamaServer | None, str]: """Returns (backend, server-or-None, mode-name).""" mode = os.environ.get("SCRYPT_BACKEND", "auto") api_key = os.environ.get("SCRYPT_API_KEY", "") api_base = os.environ.get("SCRYPT_API_BASE", OPENROUTER) model = os.environ.get("SCRYPT_MODEL", DEFAULT_MODEL) if mode in ("auto", "local") and not preflight(): server = LlamaServer() server.start() return server.backend(), server, "local" if mode == "local": raise RuntimeError("SCRYPT_BACKEND=local but: " + "; ".join(preflight())) if mode in ("auto", "api") and api_key: return OpenAIChatBackend(api_base, model=model, api_key=api_key), None, "api" if mode == "api": raise RuntimeError("SCRYPT_BACKEND=api requires SCRYPT_API_KEY") return ScriptedBackend(), None, "scripted" __all__ = [ "Backend", "OpenAIChatBackend", "ScriptedBackend", "build_backend", "complete", ]