From 024a5de501fbf56ec5ce29d72a4a207b0cec0a3e Mon Sep 17 00:00:00 2001 From: Jah-yee Date: Thu, 12 Mar 2026 22:23:21 +0800 Subject: [PATCH] fix: preserve non-OpenAI attributes in final streaming chunk When an upstream server injects custom attributes into SSE streaming chunks, preserve_upstream_non_openai_attributes() correctly copies them to the ModelResponseStream for content-bearing chunks - but NOT for the final chunk (the one with finish_reason set and empty/null content). This fix adds the preserve_upstream_non_openai_attributes() call in the received_finish_reason branch, ensuring custom metadata attached to the last SSE chunk is preserved and passed to the client. Fixes #23444 --- litellm/litellm_core_utils/streaming_handler.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/litellm/litellm_core_utils/streaming_handler.py b/litellm/litellm_core_utils/streaming_handler.py index 317f1037686..4b759eeb7da 100644 --- a/litellm/litellm_core_utils/streaming_handler.py +++ b/litellm/litellm_core_utils/streaming_handler.py @@ -1026,6 +1026,14 @@ class CustomStreamWrapper: self.sent_last_chunk = True + # Preserve custom attributes from original chunk to final chunk + _original_chunk = response_obj.get("original_chunk") + if _original_chunk: + preserve_upstream_non_openai_attributes( + model_response=model_response, + original_chunk=_original_chunk, + ) + return model_response elif self._has_special_delta_content(model_response): return self._handle_special_delta_content(model_response)