diff --git a/litellm/litellm_core_utils/model_response_utils.py b/litellm/litellm_core_utils/model_response_utils.py index dc4f375daa7..77d85c52404 100644 --- a/litellm/litellm_core_utils/model_response_utils.py +++ b/litellm/litellm_core_utils/model_response_utils.py @@ -158,8 +158,8 @@ def _is_choice_non_empty(choice: StreamingChoices) -> bool: # Skip private attributes, methods, and known empty fields if ( attr_name.startswith("_") - or callable(_attribute_of(choice, attr_name)) or attr_name.startswith("model_") + or callable(_attribute_of(choice, attr_name)) or attr_name in { "finish_reason", @@ -197,7 +197,7 @@ def _is_delta_non_empty(delta: Delta) -> bool: # Check all regular attributes of the delta object for attr_name in dir(delta): # Skip private attributes, methods, and Pydantic-specific fields - if attr_name.startswith("_") or callable(_attribute_of(delta, attr_name)) or attr_name.startswith("model_"): + if attr_name.startswith("_") or attr_name.startswith("model_") or callable(_attribute_of(delta, attr_name)): continue delta_attr_value: object = getattr(delta, attr_name, None) diff --git a/tests/unit/litellm_core_utils/test_model_response_utils.py b/tests/unit/litellm_core_utils/test_model_response_utils.py index 2ffe5853c4d..aff7c81ee07 100644 --- a/tests/unit/litellm_core_utils/test_model_response_utils.py +++ b/tests/unit/litellm_core_utils/test_model_response_utils.py @@ -1,3 +1,4 @@ +import warnings from litellm.litellm_core_utils.model_response_utils import ( is_model_response_stream_empty, ) @@ -58,3 +59,37 @@ def test_is_model_response_stream_empty_with_custom_value(): setattr(chunk.choices[0].delta, "custom_field", "test") assert is_model_response_stream_empty(chunk) is False + + + +def test_is_model_response_stream_empty_does_not_access_deprecated_pydantic_instance_attributes(): + chunk = ModelResponseStream( + id="chatcmpl-C3sWKN2RWbn6CZ1IGU2QCpRh4RhYf", + created=1755040596, + model="gpt-4o-mini", + object="chat.completion.chunk", + system_fingerprint="fp_34a54ae93c", + choices=[ + StreamingChoices( + finish_reason=None, + index=0, + delta=Delta( + provider_specific_fields=None, + content=None, + role=None, + function_call=None, + tool_calls=None, + audio=None, + ), + logprobs=None, + ) + ], + provider_specific_fields=None, + ) + + with warnings.catch_warnings(): + warnings.filterwarnings( + "error", + message=r".*'model_(computed_)?fields' attribute on the instance is deprecated", + ) + assert is_model_response_stream_empty(chunk) is True