From 57e6f298f9cd913dcf4b9380f1f105b250c04d85 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 23:13:43 +0000 Subject: [PATCH] fix(cost): price cached GLM 5.2 tokens for OpenAI-compatible routes --- model_prices_and_context_window.json | 14 +++++ .../test_router_model_cost_isolation.py | 61 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index e79ddbe35d2..18198660677 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -39398,6 +39398,20 @@ "litellm_provider": "vertex_ai", "mode": "vector_store" }, + "openai/z-ai/glm-5.2": { + "cache_read_input_token_cost": 2.6e-07, + "input_cost_per_token": 1.4e-06, + "litellm_provider": "openai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 4.4e-06, + "source": "https://docs.z.ai/guides/overview/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true + }, "openai/container": { "code_interpreter_cost_per_session": 0.03, "litellm_provider": "openai", diff --git a/tests/test_litellm/test_router_model_cost_isolation.py b/tests/test_litellm/test_router_model_cost_isolation.py index 6db7b04b3b7..3baa2f00d98 100644 --- a/tests/test_litellm/test_router_model_cost_isolation.py +++ b/tests/test_litellm/test_router_model_cost_isolation.py @@ -8,6 +8,7 @@ should still use the built-in pricing. """ import copy +import json import os import sys from unittest.mock import patch @@ -21,6 +22,7 @@ sys.path.insert( import litellm from litellm import Router from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo +from litellm.types.utils import ModelResponse, PromptTokensDetailsWrapper, Usage from litellm.utils import _invalidate_model_cost_lowercase_map @@ -451,6 +453,65 @@ def test_partial_custom_pricing_inherits_builtin_cache_pricing(): _restore_model_cost_entries(model_keys) +def test_openai_compatible_glm_partial_pricing_inherits_cache_rate(): + backend_model = "openai/z-ai/glm-5.2" + deploy_id = "glm-5-2-partial-pricing" + model_keys = { + deploy_id: litellm.model_cost.get(deploy_id), + backend_model: copy.deepcopy(litellm.model_cost.get(backend_model)), + } + + try: + with open("model_prices_and_context_window.json", "r") as model_prices_file: + model_cost = json.load(model_prices_file) + litellm.register_model({backend_model: model_cost[backend_model]}) + + Router( + model_list=[ + { + "model_name": "glm-5.2", + "litellm_params": { + "model": backend_model, + "api_base": "https://api.example.com/v1", + "api_key": "fake-key", + "custom_llm_provider": "openai", + }, + "model_info": { + "id": deploy_id, + "input_cost_per_token": 7.8e-07, + "output_cost_per_token": 2.42e-06, + }, + } + ], + ) + + entry = litellm.model_cost[deploy_id] + assert entry["input_cost_per_token"] == 7.8e-07 + assert entry["output_cost_per_token"] == 2.42e-06 + assert entry["cache_read_input_token_cost"] == 2.6e-07 + + response = ModelResponse( + model=backend_model, + choices=[], + usage=Usage( + prompt_tokens=1000, + completion_tokens=100, + total_tokens=1100, + prompt_tokens_details=PromptTokensDetailsWrapper(cached_tokens=800), + ), + ) + cost = litellm.completion_cost( + completion_response=response, + model=backend_model, + custom_llm_provider="openai", + custom_pricing=True, + router_model_id=deploy_id, + ) + assert cost == pytest.approx(200 * 7.8e-07 + 800 * 2.6e-07 + 100 * 2.42e-06) + finally: + _restore_model_cost_entries(model_keys) + + def test_partial_pricing_does_not_overwrite_explicit_cache_fields(): """When the user explicitly sets cache_*_input_token_cost on a deployment, those values must not be replaced by the built-in fallback.