diff --git a/litellm/cost_calculator.py b/litellm/cost_calculator.py index 9cbbcafb569..6007ac70a54 100644 --- a/litellm/cost_calculator.py +++ b/litellm/cost_calculator.py @@ -1503,7 +1503,7 @@ def _response_time_ms_for_cost( def _model_is_none_error(completion_response_text: str, litellm_logging_obj: LitellmLoggingObject | None) -> ValueError: message: Final = "Model is None and does not exist in passed completion_response." model_call_details: Final = {} if litellm_logging_obj is None else litellm_logging_obj.model_call_details - if should_redact_message_logging(model_call_details): + if should_redact_message_logging(model_call_details) or model_call_details.get("query_image") is not None: return ValueError(message) return ValueError(f"{message} Passed completion_response={completion_response_text}, model=None") diff --git a/tests/unit/test_cost_calculator.py b/tests/unit/test_cost_calculator.py index 69fb81c6d3e..7a5ca1d7eb9 100644 --- a/tests/unit/test_cost_calculator.py +++ b/tests/unit/test_cost_calculator.py @@ -10270,14 +10270,37 @@ def test_bedrock_registered_cache_prices_preserve_dynamic_threshold_rates( assert entry[1][tier_field] == (tier_override if tier_override is not None else 0.007) -@pytest.mark.parametrize("message_logging_off", [True, False]) -def test_cost_failure_for_an_unpriced_response_echoes_the_response_only_with_message_logging_on( - message_logging_off: bool, monkeypatch: pytest.MonkeyPatch +@pytest.mark.parametrize( + ("message_logging_off", "query_image", "echoes_response"), + [ + (True, None, False), + (False, None, True), + (False, {"type": "base64", "media_type": "image/jpeg", "data": "cXVlcnk="}, False), + ], +) +def test_cost_failure_for_an_unpriced_response_echoes_only_a_text_search_response_with_message_logging_on( + message_logging_off: bool, + query_image: Mapping[str, str] | None, + echoes_response: bool, + monkeypatch: pytest.MonkeyPatch, ) -> None: monkeypatch.setattr(litellm, "turn_off_message_logging", message_logging_off) image_data: Final = "c2VjcmV0LWltYWdlLWJ5dGVz" + logging_obj: Final = Logging( + model="", + messages=[], + stream=False, + call_type="avector_store_search", + start_time=datetime.datetime.now(), + litellm_call_id="unpriced-search", + function_id="f", + ) + logging_obj.model_call_details["query_image"] = query_image with pytest.raises(ValueError, match="Model is None") as exc_info: - completion_cost(completion_response={"data": [{"content": [{"source": {"data": image_data}}]}]}) + completion_cost( + completion_response={"data": [{"content": [{"source": {"data": image_data}}]}]}, + litellm_logging_obj=logging_obj, + ) - assert (image_data in str(exc_info.value)) is not message_logging_off + assert (image_data in str(exc_info.value)) is echoes_response