1# Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca2"""`av providers-check`: list the models each vendor exposes through /v1/models (official SDKs) and3verify that every id in configs/models.yaml exists. Keys are read from the environment only; nothing4is printed except model ids and booleans."""5from __future__ import annotations67import os8from typing import Any910from ..config import load_config111213def _anthropic_models() -> list[str] | str:14 if not os.environ.get("ANTHROPIC_API_KEY"):15 return "ANTHROPIC_API_KEY not set"16 try:17 import anthropic1819 client = anthropic.Anthropic()20 ids: list[str] = []21 page = client.models.list(limit=100)22 for m in page:23 ids.append(m.id)24 return sorted(ids)25 except Exception as e:26 return f"{type(e).__name__}: {str(e)[:200]}"272829def _openai_models() -> list[str] | str:30 if not os.environ.get("OPENAI_API_KEY"):31 return "OPENAI_API_KEY not set"32 try:33 from openai import OpenAI3435 client = OpenAI()36 return sorted(m.id for m in client.models.list())37 except Exception as e:38 return f"{type(e).__name__}: {str(e)[:200]}"394041def check() -> dict[str, Any]:42 cfg = load_config("models")43 listed = {"anthropic": _anthropic_models(), "openai": _openai_models()}44 report: dict[str, Any] = {"vendors": {}, "configured": {}, "all_configured_found": True}45 for vendor, res in listed.items():46 report["vendors"][vendor] = {"ok": isinstance(res, list), "n_models": (len(res) if isinstance(res, list) else 0), "error": (None if isinstance(res, list) else res)}47 for mid, info in cfg["models"].items():48 vendor = info["provider"]49 res = listed.get(vendor)50 found = (mid in res) if isinstance(res, list) else None51 report["configured"][mid] = {"provider": vendor, "tier": info.get("tier"), "found": found}52 if found is False:53 report["all_configured_found"] = False54 for tier, pair in cfg["cost_matched_pairs"].items():55 for vendor, mid in pair.items():56 if mid not in cfg["models"]:57 report["all_configured_found"] = False58 report["configured"][mid] = {"provider": vendor, "tier": tier, "found": None, "error": "pair model not registered in models:"}59 return report606162def print_report(report: dict[str, Any]) -> None:63 for vendor, v in report["vendors"].items():64 print(f"{vendor:10s} {'OK' if v['ok'] else 'UNAVAILABLE'} models listed: {v['n_models']}{(' (' + v['error'] + ')') if v['error'] else ''}")65 for mid, info in report["configured"].items():66 state = {True: "found", False: "MISSING", None: "unchecked"}[info["found"]]67 print(f" {mid:22s} {info['provider']:10s} {str(info.get('tier')):9s} {state}")68 print("all configured ids found:", report["all_configured_found"])69