diff --git a/litellm/llms/vertex_ai/agent_engine/sse_iterator.py b/litellm/llms/vertex_ai/agent_engine/sse_iterator.py index ba93336e75a..b731827fcf5 100644 --- a/litellm/llms/vertex_ai/agent_engine/sse_iterator.py +++ b/litellm/llms/vertex_ai/agent_engine/sse_iterator.py @@ -90,21 +90,19 @@ class VertexAgentEngineResponseIterator(BaseModelResponseIterator): end-of-response signal. We therefore only surface ``finish_reason`` when the chunk has - user-facing content (text or tool_calls). Otherwise downstream stream - handling closes the stream after the first inner action and the actual - response is dropped (see issue #19121). + user-facing text content. Function-call and thought-only chunks must + keep ``finish_reason=None`` so the downstream stream wrapper does not + close the stream after the first inner action and drop the actual + response (see issue #19121). """ text, tool_calls = self._extract_parts_from_chunk(chunk) finish_reason: Optional[str] = None raw_finish_reason = chunk.get("finish_reason") - if raw_finish_reason: - if tool_calls: - finish_reason = "tool_calls" - elif text is not None: - finish_reason = ( - "stop" if raw_finish_reason == "STOP" else raw_finish_reason.lower() - ) + if raw_finish_reason and text is not None: + finish_reason = ( + "stop" if raw_finish_reason == "STOP" else raw_finish_reason.lower() + ) usage = None usage_metadata = chunk.get("usage_metadata") or {} diff --git a/tests/litellm/llms/vertex_ai/agent_engine/test_transformation.py b/tests/litellm/llms/vertex_ai/agent_engine/test_transformation.py index 26a6d28c4a3..2b8ef9cb569 100644 --- a/tests/litellm/llms/vertex_ai/agent_engine/test_transformation.py +++ b/tests/litellm/llms/vertex_ai/agent_engine/test_transformation.py @@ -155,7 +155,7 @@ class TestVertexAgentEngineChunkParser: result = self._iterator().chunk_parser(chunk) - assert result.choices[0].finish_reason == "tool_calls" + assert result.choices[0].finish_reason is None tool_calls = result.choices[0].delta.tool_calls assert tool_calls is not None and len(tool_calls) == 1 assert tool_calls[0]["function"]["name"] == "transfer_to_agent" @@ -207,7 +207,7 @@ class TestVertexAgentEngineChunkParser: result = self._iterator().chunk_parser(chunk) - assert result.choices[0].finish_reason == "tool_calls" + assert result.choices[0].finish_reason is None tool_calls = result.choices[0].delta.tool_calls assert tool_calls is not None and len(tool_calls) == 1 assert tool_calls[0]["function"]["name"] == "list_cases"