1from collections import Counter23from aiatlas.connectors.providers.openrouter import OpenRouterConnector, _display_name, _per_mtok4from aiatlas.sdk.facts import Target5from tests.conftest import claims_of, extract_from_fixture, fixture_path678async def test_catalogue():9 c = OpenRouterConnector()10 target = Target(url="https://openrouter.ai/api/v1/models", doc_type="catalogue", key="models")11 facts = await extract_from_fixture(c, target, fixture_path("openrouter", "models.json"), content_type="application/json")12 models = [e for e in facts.entities if e.entity_type == "model"]13 assert len(models) >= 300 and not any(e.identifiers.get("openrouter", "").startswith("~") for e in models) # alias rows skipped14 assert len(facts.prices) >= 15015 sonnet = next(p for p in facts.prices if p.provider_model_id == "anthropic/claude-sonnet-4.5")16 assert sonnet.model.name == "Claude Sonnet 4.5" and sonnet.model.organization.name == "Anthropic"17 assert sonnet.provider.name == "Anthropic API" and sonnet.features["via"] == "openrouter"18 assert (sonnet.input_per_mtok, sonnet.output_per_mtok, sonnet.cached_input_per_mtok) == (3.0, 15.0, 0.3) # per-token strings × 1e619 claims = claims_of(facts, "Claude Sonnet 4.5")20 assert claims["context_length"] == 1_000_000 and claims["max_output_tokens"] == 64000 and claims["release_date"] == "2025-09-29"21 assert claims["modalities_input"] == ["image", "text"] and claims["file_input"] is True # "file" is not in the modality vocabulary22 assert "tools" in claims["supported_parameters"] and claims["tool_calling"] is True23 by_provider = Counter(p.provider.name for p in facts.prices)24 assert by_provider["OpenAI API"] >= 50 and by_provider["OpenRouter"] >= 50 # unknown vendors → aggregator25 variant = next(p for p in facts.prices if ":" in (p.provider_model_id or ""))26 assert "variant" in variant.features and ":" not in variant.model.identifiers["openrouter"] # variants share the model identity27 assert not any(p.input_per_mtok is not None and p.input_per_mtok < 0 for p in facts.prices) # dynamic "-1" prices skipped28 assert any("hf_repo" in e.identifiers for e in models)293031def test_helpers():32 assert _display_name("Anthropic: Claude Sonnet 4.5", "anthropic") == "Claude Sonnet 4.5"33 assert _display_name("Sakana: Something", "sakana") == "Something"34 assert _per_mtok("0.000003") == 3.0 and _per_mtok("-1") == -1.0 and _per_mtok(None) is None35