""" models_client.py — drop-in BESTIARY catalog reader for any PlinyOS app. Copy this single file into any repo that needs the model list. It reads the catalog BESTIARY produces and gives you filtered views, with zero third-party deps. No need to import the full bestiary engine. Resolution order for the catalog: 1. $BESTIARY_CATALOG (explicit path or http(s) URL) 2. a local catalog.json next to this file 3. the canonical monorepo path (…/03-PLINYOS/organs/bestiary/state/catalog.json) Usage ───── from models_client import models, model_ids, newest # frontier / hosted apps (godmode, tempest, libertarium): api_models = models(channel="api") # OpenRouter-reachable ids = model_ids(channel="api", vendor="anthropic") # ["anthropic/claude-opus-4.8", …] # open-weight apps (obliteratus, incanta, pandora): weights = models(open_weight=True) # downloadable, with hf_id coders = models(open_weight=True, capability="tools") # newest drops across everything: for m in newest(days=7): print(m["id"], m["released"]) """ from __future__ import annotations import json import os import urllib.request from datetime import datetime, timezone, timedelta from pathlib import Path from typing import List, Optional _HERE = Path(__file__).resolve().parent _CANONICAL = _HERE.parent / "bestiary" / "state" / "catalog.json" _LOCAL = _HERE / "catalog.json" _CHANNEL_ALIASES = {"api": "openrouter", "hosted": "openrouter", "frontier": "openrouter", "hf": "huggingface"} def _load() -> dict: src = os.environ.get("BESTIARY_CATALOG", "").strip() if src.startswith("http://") or src.startswith("https://"): with urllib.request.urlopen(src, timeout=15) as r: return json.loads(r.read().decode("utf-8")) for p in (Path(src) if src else None, _LOCAL, _CANONICAL, _HERE / "state" / "catalog.json"): if p and p.exists(): return json.loads(p.read_text()) raise FileNotFoundError( "BESTIARY catalog not found. Run `python3 bestiary.py update`, or set " "$BESTIARY_CATALOG to a catalog.json path or URL." ) def models(channel: Optional[str] = None, vendor: Optional[str] = None, open_weight: Optional[bool] = None, capability: Optional[str] = None) -> List[dict]: """Return catalog records filtered by channel / vendor / open_weight / capability.""" if channel in ("open-weight", "openweight", "weights"): open_weight, channel = True, None if channel: channel = _CHANNEL_ALIASES.get(channel, channel) out = [] for m in _load().get("models", []): if channel and channel not in m.get("channels", []): continue if vendor and m.get("vendor") != vendor.lower(): continue if open_weight is not None and bool(m.get("open_weight")) != open_weight: continue if capability and capability not in m.get("capabilities", []): continue out.append(m) return out def model_ids(**kw) -> List[str]: """Just the ids — the common case for populating a dropdown or a config.""" return [m["id"] for m in models(**kw)] def newest(days: int = 7, **kw) -> List[dict]: """Models first-seen (≈ released) within the last `days`, newest first.""" cutoff = datetime.now(timezone.utc) - timedelta(days=days) out = [] for m in models(**kw): fs = m.get("first_seen") or m.get("released") if not fs: continue try: t = datetime.strptime(fs, "%Y-%m-%d").replace(tzinfo=timezone.utc) except ValueError: continue if t >= cutoff: out.append(m) return sorted(out, key=lambda r: r.get("first_seen") or "", reverse=True) if __name__ == "__main__": cat = _load() print(f"catalog generated_at={cat.get('generated_at')} count={cat.get('count')}") print(f" api models : {len(models(channel='api'))}") print(f" open-weight : {len(models(open_weight=True))}") print(f" new (7d) : {len(newest(7))}")