"""Meter catalogue integrity.""" from __future__ import annotations import pytest from tokencalc.defaults import DEFAULT_METERS, DEFAULT_PRICING from tokencalc.meters import Confidence, MeterType, TokenMeter, TokenPricing def test_all_spec_meters_present(): expected = { # Voice / Bot "Voice Bot", "Digital Bot", # Virtual Agent "Virtual Agent (legacy)", "Agentic Virtual Agent", # Agent Copilot (named + concurrent) "Agent Copilot [named]", "Agent Copilot [concurrent]", # AI Quality / Analytics "AI Scoring", "AI Summary & Insights", # Speech & Text Analytics (named + concurrent) "Speech & Text Analytics [named]", "Speech & Text Analytics [concurrent]", # Routing "Predictive Routing", # Messaging "Direct Messaging", "Social Listening", "Social Responses", # Language "AI Translate", # Genesys Cloud Copilot "Genesys Cloud Copilot", # Email AI (rates TBD) "Email AI (Auto-Suggest)", "Email AI (Auto-Respond)", } assert expected == set(DEFAULT_METERS) def test_confirmed_rates(): m = DEFAULT_METERS assert m["Voice Bot"].units_per_token == 17 assert m["Voice Bot"].tokens_per_unit == pytest.approx(0.0588, abs=1e-3) assert m["Digital Bot"].units_per_token == 51 assert m["Agentic Virtual Agent"].tokens_per_unit == 1.2 assert m["AI Summary & Insights"].tokens_per_unit == 0.02 assert m["Direct Messaging"].units_per_token == 400 # Named variants assert m["Speech & Text Analytics [named]"].tokens_per_unit == 30 assert m["Speech & Text Analytics [concurrent]"].tokens_per_unit == 45 assert m["Agent Copilot [named]"].tokens_per_unit == 40 assert m["Agent Copilot [concurrent]"].tokens_per_unit == 60 # AI Translate is now a confirmed consumption meter assert m["AI Translate"].tokens_per_unit == 0.5 assert m["AI Translate"].units_per_token == 2 assert m["AI Translate"].confidence is Confidence.CONFIRMED # New meters assert m["AI Scoring"].units_per_token == 20 assert m["Predictive Routing"].units_per_token == 17 assert m["Genesys Cloud Copilot"].units_per_token == 20 def test_unknown_meters_flagged(): unknown = {f for f, m in DEFAULT_METERS.items() if m.confidence is Confidence.UNKNOWN} assert unknown == { "Email AI (Auto-Suggest)", "Email AI (Auto-Respond)", } assert Confidence.UNKNOWN.icon == "🔴" assert Confidence.CONFIRMED.icon == "🟢" def test_inverse_consistency_validated(): with pytest.raises(ValueError, match="not inverses"): TokenMeter( feature="Bad", meter_type=MeterType.PER_MINUTE, units_per_token=10, tokens_per_unit=0.5, confidence=Confidence.ESTIMATED, notes="", ) def test_every_confirmed_meter_has_source_url(): for m in DEFAULT_METERS.values(): if m.confidence is Confidence.CONFIRMED: assert m.source_url, f"{m.feature} missing source URL" def test_pricing_effective_rate(): p = TokenPricing(region="US", list_rate_per_token=1.0, contracted_rate_per_token=0.85) assert p.effective_rate(use_contracted=False) == 1.0 assert p.effective_rate(use_contracted=True) == 0.85 # no contracted rate → falls back to list assert DEFAULT_PRICING["US"].effective_rate(use_contracted=True) == 1.0 def test_all_regions_priced(): assert set(DEFAULT_PRICING) == {"US", "EU", "AU", "APAC"}