From 4d7efb7db0c2af735e152bc88b29628b9458152a Mon Sep 17 00:00:00 2001 From: codechrl Date: Fri, 14 Aug 2026 10:48:09 +0700 Subject: [PATCH] test(vertex_ai): cover multiple content-less candidates rescued independently Assert each content-less candidate keeps its index and maps its own finishReason (MAX_TOKENS -> length, SAFETY -> content_filter), so none is dropped when several arrive together. --- ...test_vertex_and_google_ai_studio_gemini.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_and_google_ai_studio_gemini.py b/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_and_google_ai_studio_gemini.py index 86b6ab33d61..6d71a2d3d3f 100644 --- a/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_and_google_ai_studio_gemini.py +++ b/tests/test_litellm/llms/vertex_ai/gemini/test_vertex_and_google_ai_studio_gemini.py @@ -5606,3 +5606,28 @@ def test_vertex_ai_content_less_candidate_without_finish_reason_not_stop(): assert model_response.choices[0].finish_reason == "length" assert model_response.choices[0].finish_reason != "stop" assert model_response.choices[0].message.content == "" + + +def test_vertex_ai_multiple_content_less_candidates_each_rescued(): + """Every content-less candidate is rescued independently, preserving each + candidate's index and mapping its own finishReason (MAX_TOKENS -> length, + SAFETY -> content_filter), rather than dropping any of them. + """ + v = VertexGeminiConfig() + model_response = ModelResponse() + model_response.choices = [] + + v._process_candidates( + _candidates=[ + {"finishReason": "MAX_TOKENS", "index": 0}, + {"finishReason": "SAFETY", "index": 1}, + ], + model_response=model_response, + standard_optional_params={}, + ) + + assert len(model_response.choices) == 2 + by_index = {c.index: c for c in model_response.choices} + assert by_index[0].finish_reason == "length" + assert by_index[1].finish_reason == "content_filter" + assert all(c.message.content == "" for c in model_response.choices)