"""Curated registries (YAML under /registry) and their loaders.""" from __future__ import annotations from functools import lru_cache from pathlib import Path from typing import Any import yaml REGISTRY_DIR = Path(__file__).resolve().parents[3] / "registry" @lru_cache def load(name: str) -> list[dict[str, Any]]: """`registry/.yaml` merged with fragment files `registry/.d/*.yaml` (same top-level key). Later fragments may not redefine a key — duplicates are an error.""" paths = [REGISTRY_DIR / f"{name}.yaml", *sorted((REGISTRY_DIR / f"{name}.d").glob("*.yaml"))] items: list[dict[str, Any]] = [] for path in paths: if not path.exists(): continue with path.open("r", encoding="utf-8") as fh: data = yaml.safe_load(fh) or {} items.extend(data.get(name) or []) keys = [i["key"] for i in items] dupes = {k for k in keys if keys.count(k) > 1} if dupes: raise ValueError(f"duplicate keys in {name}.yaml: {sorted(dupes)}") return items @lru_cache def organizations() -> dict[str, dict[str, Any]]: return {o["key"]: o for o in load("organizations")} @lru_cache def providers() -> dict[str, dict[str, Any]]: return {p["key"]: p for p in load("providers")} @lru_cache def org_by_hf(hf_org: str) -> dict[str, Any] | None: for o in organizations().values(): if o.get("hf_org", "").lower() == hf_org.lower(): return o return None @lru_cache def org_by_github(gh_org: str) -> dict[str, Any] | None: for o in organizations().values(): if o.get("github_org", "").lower() == gh_org.lower(): return o return None @lru_cache def org_by_domain(domain: str) -> dict[str, Any] | None: d = domain.lower() d = d.removeprefix("www.") for o in organizations().values(): for od in o.get("domains", []): if d == od or d.endswith("." + od): return o return None def org_ref(key: str): # type: ignore[no-untyped-def] """EntityRef for a registry organization (identifiers make resolution deterministic).""" from aiatlas.sdk.facts import EntityRef o = organizations()[key] ids: dict[str, str] = {"registry_org": key} if o.get("domains"): ids["domain"] = o["domains"][0] if o.get("hf_org"): ids["hf_org"] = o["hf_org"] if o.get("github_org"): ids["github_org"] = o["github_org"] return EntityRef(entity_type=o.get("type", "company") if o.get("type") in ("company", "lab", "organization", "university") else "company", name=o["name"], identifiers=ids, aliases=list(o.get("aliases", [])), slug_hint=key) def provider_ref(key: str): # type: ignore[no-untyped-def] from aiatlas.sdk.facts import EntityRef p = providers()[key] ids = {"registry_provider": key} if p.get("openrouter_slug"): ids["openrouter_provider"] = p["openrouter_slug"] org = org_ref(p["organization"]) if p.get("organization") in organizations() else None # providers share names with their companies ("Anthropic" the company vs "Anthropic API" the provider): keep slugs distinct and readable slug = key if key not in organizations() else f"{key}-api" return EntityRef(entity_type="provider", name=p["name"], identifiers=ids, aliases=list(p.get("aliases", [])), slug_hint=slug, organization=org) def provider_by_openrouter(slug: str) -> str | None: for k, p in providers().items(): if p.get("openrouter_slug") == slug: return k return None __all__ = ["REGISTRY_DIR", "load", "org_by_domain", "org_by_github", "org_by_hf", "org_ref", "organizations", "provider_by_openrouter", "provider_ref", "providers"]