From bbe7aeafdb4db0a7513716a2265dba471b89e006 Mon Sep 17 00:00:00 2001 From: Anuj7411 Date: Thu, 20 Aug 2026 23:14:13 +0530 Subject: [PATCH] fix(cost): stop double-billing the Azure AI Model Router flat fee --- litellm/cost_calculator.py | 7 +++++- .../azure_ai/test_azure_ai_cost_calculator.py | 24 ++++--------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/litellm/cost_calculator.py b/litellm/cost_calculator.py index 8f7cd09d364..63bb6b93cc1 100644 --- a/litellm/cost_calculator.py +++ b/litellm/cost_calculator.py @@ -39,6 +39,7 @@ from litellm.llms.anthropic.cost_calculation import ( from litellm.llms.azure.cost_calculation import ( cost_per_token as azure_openai_cost_per_token, ) +from litellm.llms.azure_ai.cost_calculator import _is_azure_model_router from litellm.llms.azure_ai.cost_calculator import ( cost_per_token as azure_ai_cost_per_token, ) @@ -1592,7 +1593,11 @@ def completion_cost( ) # Get additional costs from provider (e.g., routing fees, infrastructure costs) - if custom_llm_provider == "azure_ai": + token_path_billed_router: Final = custom_llm_provider == "azure_ai" and ( + _is_azure_model_router(model) + or (request_model_for_cost is not None and _is_azure_model_router(request_model_for_cost)) + ) + if custom_llm_provider == "azure_ai" and not token_path_billed_router: model_for_additional_costs = request_model_for_cost if completion_response is not None: hidden_params = getattr(completion_response, "_hidden_params", None) or {} diff --git a/tests/test_litellm/llms/azure_ai/test_azure_ai_cost_calculator.py b/tests/test_litellm/llms/azure_ai/test_azure_ai_cost_calculator.py index 20260c744f8..9316102c900 100644 --- a/tests/test_litellm/llms/azure_ai/test_azure_ai_cost_calculator.py +++ b/tests/test_litellm/llms/azure_ai/test_azure_ai_cost_calculator.py @@ -377,25 +377,11 @@ class TestAzureModelRouterCostBreakdown: litellm_logging_obj=logging_obj, ) - # Check that cost breakdown contains additional_costs - assert hasattr(logging_obj, "cost_breakdown") - assert logging_obj.cost_breakdown is not None - assert "additional_costs" in logging_obj.cost_breakdown - assert isinstance(logging_obj.cost_breakdown["additional_costs"], dict) - - # Check that the Azure Model Router flat cost is in additional_costs - additional_costs = logging_obj.cost_breakdown["additional_costs"] - assert "Azure Model Router Flat Cost" in additional_costs - - # Verify the flat cost value - expected_flat_cost = ( - 5000 * AZURE_MODEL_ROUTER_FLAT_COST_PER_M_INPUT_TOKENS / 1_000_000 - ) - actual_flat_cost = additional_costs["Azure Model Router Flat Cost"] - assert actual_flat_cost == pytest.approx(expected_flat_cost, rel=1e-9) - - print(f"Additional costs in breakdown: {additional_costs}") - print(f"Azure Model Router Flat Cost: ${actual_flat_cost:.6f}") + # For a pure model-router response (no underlying model pricing) the flat fee is + # billed once, through the token-cost path, so the total equals a single flat fee. + # It must not also be summed via additional_costs, which would double-bill it. + expected_flat_cost = 5000 * AZURE_MODEL_ROUTER_FLAT_COST_PER_M_INPUT_TOKENS / 1_000_000 + assert cost == pytest.approx(expected_flat_cost, rel=1e-9) def test_additional_costs_when_response_has_actual_model_via_hidden_params(self): """additional_costs populated when response has actual model but request was via model router (hidden_params)."""