test: fix remaining cost-map pin and leaked logging event races

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
kerry 2026-09-17 22:17:27 +00:00
parent 6858663fd2
commit 26addc5b39
3 changed files with 20 additions and 10 deletions

View file

@ -1218,17 +1218,25 @@ async def test_async_success_handler_truncates_large_base64_off_the_event_loop(m
original_scan = logging_utils._truncate_base64_in_string
def recording_scan(value: str) -> str:
scan_threads.append(threading.get_ident())
if payload in value:
scan_threads.append(threading.get_ident())
return original_scan(value)
monkeypatch.setattr(logging_utils, "_truncate_base64_in_string", recording_scan)
monkeypatch.setattr(logging_utils, "BASE64_TRUNCATION_OFFLOAD_THRESHOLD_CHARS", 1_000)
import json
logged = asyncio.Event()
captured: dict = {}
class CaptureLogger(CustomLogger):
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
logged_messages: Final = json.dumps(
kwargs.get("standard_logging_object", {}).get("messages", "")
)
if "describe" not in logged_messages or "image/png" not in logged_messages:
return
captured["standard_logging_object"] = kwargs["standard_logging_object"]
logged.set()
@ -1249,9 +1257,9 @@ async def test_async_success_handler_truncates_large_base64_off_the_event_loop(m
)
await asyncio.wait_for(logged.wait(), timeout=10)
logged_url = captured["standard_logging_object"]["messages"][0]["content"][1]["image_url"]["url"]
assert "base64_data truncated" in logged_url
assert payload not in logged_url
serialized: Final = json.dumps(captured["standard_logging_object"]["messages"])
assert "base64_data truncated" in serialized
assert payload not in serialized
assert scan_threads
assert loop_thread not in scan_threads
@ -3190,7 +3198,8 @@ async def test_non_streaming_computes_standard_logging_object_once():
mock_response="Hello, world!",
)
await asyncio.sleep(1)
assert mock_payload.call_count == 1
own_calls: Final = [call for call in mock_payload.call_args_list if "codex-mini-latest" in str(call)]
assert len(own_calls) == 1
@pytest.mark.asyncio

View file

@ -11,8 +11,8 @@ from litellm.types.management_endpoints.prompt_cache_prediction import CacheToke
def _tiered_rate(entry: Mapping[str, float], field: str, total: int) -> float:
above_field: Final = f"{field}_above_200k_tokens"
if total > 200_000 and above_field in entry:
return entry[above_field]
return entry[field]
return entry.get(above_field) or 0.0
return entry.get(field) or 0.0
def _expected_cache_cost(model: str, tokens: CacheTokenBuckets) -> float:
@ -28,7 +28,7 @@ def _expected_cache_cost(model: str, tokens: CacheTokenBuckets) -> float:
tokens.uncached_input_tokens * _tiered_rate(entry, "input_cost_per_token", total)
+ tokens.cache_read_input_tokens * _tiered_rate(entry, "cache_read_input_token_cost", total)
+ tokens.cache_creation_5m_input_tokens * _tiered_rate(entry, "cache_creation_input_token_cost", total)
+ tokens.cache_creation_1h_input_tokens * entry[one_hour_field]
+ tokens.cache_creation_1h_input_tokens * (entry.get(one_hour_field) or 0.0)
)

View file

@ -2239,8 +2239,9 @@ def test_create_model_info_response_falls_back_to_alias_for_opaque_deployment_na
litellm.model_cost.clear()
litellm.model_cost.update(saved_model_cost)
assert response["max_input_tokens"] == 128000
assert response["max_output_tokens"] == 16384
entry = litellm.model_cost["gpt-4o"]
assert response["max_input_tokens"] == entry["max_input_tokens"]
assert response["max_output_tokens"] == entry["max_output_tokens"]
def test_create_model_info_response_resolves_mode_through_deployment_model():