fix(cost): apply vertex regional uplift to cost breakdown line items

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Devin AI 2026-08-13 23:14:26 +00:00
parent 41afb13fc6
commit f5ba4afefb
4 changed files with 49 additions and 18 deletions

View file

@ -1661,6 +1661,7 @@ def completion_cost(
usage=cost_per_token_usage_object,
service_tier=service_tier,
data_residency=data_residency,
vertex_location=vertex_location,
)
_reasoning_cost = _token_type_breakdown.reasoning_cost
_cache_read_cost = _token_type_breakdown.cache_read_cost

View file

@ -694,6 +694,23 @@ def _get_regional_uplift_multiplier(model_info: ModelInfo, data_residency: str |
return 1.0
GLOBAL_VERTEX_LOCATION: Final = "global"
def get_vertex_regional_endpoint_uplift(model_info: ModelInfo, vertex_location: str | None) -> float:
"""
Vertex bills a flat premium (currently +10%) on every token type when a request is served
from a regional or multi-region endpoint instead of the global one, so the location the
request was routed to decides the rate, not just the model.
"""
if vertex_location is None or vertex_location.lower() == GLOBAL_VERTEX_LOCATION:
return 1.0
multiplier: Final = model_info.get("regional_endpoint_uplift_multiplier")
if multiplier is None:
return 1.0
return float(multiplier)
def _resolve_reasoning_token_cost(
model_info: ModelInfo,
service_tier: str | None,
@ -903,6 +920,7 @@ def get_token_type_cost_breakdown(
usage: Usage,
service_tier: str | None = None,
data_residency: str | None = None,
vertex_location: str | None = None,
) -> TokenTypeCostBreakdown:
"""
Provider-agnostic cost of reasoning and cache tokens, derived from the usage
@ -975,7 +993,9 @@ def get_token_type_cost_breakdown(
# Apply the same flat regional-processing uplift the totals get, so per-type
# costs stay reconciled with input_cost/output_cost for regionalized OpenAI hosts.
uplift: Final = _get_regional_uplift_multiplier(model_info, data_residency)
uplift: Final = _get_regional_uplift_multiplier(model_info, data_residency) * get_vertex_regional_endpoint_uplift(
model_info, vertex_location
)
if uplift != 1.0:
reasoning_cost *= uplift
cache_read_cost *= uplift

View file

@ -7,6 +7,7 @@ from litellm import verbose_logger
from litellm.litellm_core_utils.llm_cost_calc.utils import (
_is_above_128k,
generic_cost_per_token,
get_vertex_regional_endpoint_uplift,
)
from litellm.types.utils import ModelInfo, Usage
@ -26,22 +27,6 @@ Google AI Studio -> token based pricing
models_without_dynamic_pricing: Final = ["gemini-1.0-pro", "gemini-pro", "gemini-2"]
GLOBAL_VERTEX_LOCATION: Final = "global"
def _regional_endpoint_uplift(model_info: ModelInfo, vertex_location: str | None) -> float:
"""
Vertex bills a flat premium (currently +10%) on every token type when a request is served
from a regional or multi-region endpoint instead of the global one, so the location the
request was routed to decides the rate, not just the model.
"""
if vertex_location is None or vertex_location.lower() == GLOBAL_VERTEX_LOCATION:
return 1.0
multiplier: Final = model_info.get("regional_endpoint_uplift_multiplier")
if multiplier is None:
return 1.0
return float(multiplier)
def cost_router(
model: str,
@ -253,5 +238,5 @@ def cost_per_token(
service_tier=service_tier,
)
uplift: Final = _regional_endpoint_uplift(model_info=model_info, vertex_location=vertex_location)
uplift: Final = get_vertex_regional_endpoint_uplift(model_info, vertex_location)
return prompt_cost * uplift, completion_cost * uplift

View file

@ -2207,6 +2207,31 @@ def test_token_type_cost_breakdown_matches_real_gemini_numbers():
assert breakdown.cache_creation_cost == 0.0
@pytest.mark.parametrize("vertex_location, uplift", [("global", 1.0), ("us-east5", 1.1)])
def test_token_type_cost_breakdown_applies_vertex_regional_uplift(vertex_location, uplift):
"""Component costs must carry the same regional uplift as the total, or spend logs stop adding up."""
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
litellm.model_cost = litellm.get_model_cost_map(url="")
usage = Usage(
prompt_tokens=2500,
completion_tokens=200,
total_tokens=2700,
cache_creation_input_tokens=500,
cache_read_input_tokens=2000,
)
breakdown = get_token_type_cost_breakdown(
model="claude-sonnet-4-6",
custom_llm_provider="vertex_ai",
usage=usage,
vertex_location=vertex_location,
)
assert breakdown.cache_read_cost == pytest.approx(2000 * 3e-07 * uplift)
assert breakdown.cache_creation_cost == pytest.approx(500 * 3.75e-06 * uplift)
def test_token_type_cost_breakdown_xai_at_exactly_200k_uses_higher_tier_rates():
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
litellm.model_cost = litellm.get_model_cost_map(url="")