"""routing.cheapest_classifier_candidate -- backs classifier.cloud_primary_auto. Reuses select_candidates + estimated_cost rather than a second cost model, so these tests are mostly about the FILTER choices (tier 1, interactive, public, non-stale/deprecated) and the tie-break (cheapest wins), not about pricing arithmetic -- estimated_cost already has its own tests. """ from __future__ import annotations from routing import cheapest_classifier_candidate def _row(**overrides) -> dict: row = { "model_id": "m", "provider": "neuralwatt", "tier": 1, "effective_context_window": 100_000, "availability": "active", "deprecated": 0, "access_level": "public", "latency_class": "standard", "reasoning_mode": "default", "context_variant": "full", "supports_vision": 1, "supports_json_mode": 1, "cost_per_1m_prompt": 1.0, "cost_per_1m_completion": 1.0, } row.update(overrides) return row def test_picks_the_cheapest_of_several_candidates(): rows = [ _row(model_id="expensive", cost_per_1m_completion=10.0), _row(model_id="cheap", cost_per_1m_completion=0.5), _row(model_id="middle", cost_per_1m_completion=2.0), ] picked = cheapest_classifier_candidate(rows) assert picked["model_id"] == "cheap" def test_tier_is_a_floor_not_a_ceiling_so_a_frontier_model_can_still_win(): """required_tier=1 means "at least tier-1 capable", which every tier satisfies (tier is a capability floor -- see CLAUDE.md). It does not restrict candidates to cheap models; cost alone decides among them, and a tier-3 model can still be cheapest for a short classification call.""" rows = [ _row(model_id="tier1", tier=1, cost_per_1m_completion=5.0), _row(model_id="tier3-cheaper", tier=3, cost_per_1m_completion=0.1), ] picked = cheapest_classifier_candidate(rows) assert picked["model_id"] == "tier3-cheaper" def test_flex_rows_are_excluded(): """INTERACTIVE tolerance: a request already waiting on classification should not also wait out a flex capacity gap.""" rows = [ _row(model_id="standard", cost_per_1m_completion=5.0), _row(model_id="flex-cheaper", latency_class="flex", cost_per_1m_completion=0.1), ] picked = cheapest_classifier_candidate(rows) assert picked["model_id"] == "standard" def test_stale_and_deprecated_rows_are_excluded(): rows = [ _row(model_id="active", cost_per_1m_completion=5.0), _row(model_id="stale-cheaper", availability="stale", cost_per_1m_completion=0.1), _row(model_id="deprecated-cheaper", deprecated=1, cost_per_1m_completion=0.1), ] picked = cheapest_classifier_candidate(rows) assert picked["model_id"] == "active" def test_non_public_access_level_is_excluded_by_default(): rows = [ _row(model_id="public", cost_per_1m_completion=5.0), _row(model_id="preview-cheaper", access_level="preview", cost_per_1m_completion=0.1), ] picked = cheapest_classifier_candidate(rows) assert picked["model_id"] == "public" def test_allowed_access_levels_is_a_real_parameter_not_a_hardcoded_default(): """Pure function per this module's own rule: thresholds are arguments, not baked-in assumptions.""" rows = [_row(model_id="preview-only", access_level="preview")] assert cheapest_classifier_candidate(rows) is None picked = cheapest_classifier_candidate( rows, allowed_access_levels=["public", "preview"] ) assert picked["model_id"] == "preview-only" def test_rows_with_no_catalog_price_are_ignored(): rows = [ _row(model_id="unpriced", cost_per_1m_prompt=None, cost_per_1m_completion=None), _row(model_id="priced", cost_per_1m_completion=3.0), ] picked = cheapest_classifier_candidate(rows) assert picked["model_id"] == "priced" def test_empty_catalog_returns_none(): assert cheapest_classifier_candidate([]) is None def test_no_routable_candidates_returns_none(): rows = [_row(tier=None)] # unknown tier fails closed, per is_eligible assert cheapest_classifier_candidate(rows) is None def test_no_priced_candidates_returns_none(): rows = [_row(cost_per_1m_prompt=None, cost_per_1m_completion=None)] assert cheapest_classifier_candidate(rows) is None