Skip to content

Commit 8f8572e

Browse files
Python: map Vertex AI RECITATION/BLOCKLIST/PROHIBITED_CONTENT/SPII finish reasons to CONTENT_FILTER
The Vertex AI connector only mapped SAFETY to CONTENT_FILTER, so responses Gemini stopped for recitation, blocklist, prohibited content or SPII came back with finish_reason=None. Map them the same way the Google AI connector already does.
1 parent d41312f commit 8f8572e

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

‎python/semantic_kernel/connectors/ai/google/vertex_ai/services/utils.py‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@
3232
logger: logging.Logger = logging.getLogger(__name__)
3333

3434

35+
# Finish reasons where Gemini stopped the response for the content, not for length or a natural end.
36+
_VERTEX_AI_CONTENT_FILTER_REASONS = frozenset({
37+
Candidate.FinishReason.SAFETY,
38+
Candidate.FinishReason.RECITATION,
39+
Candidate.FinishReason.BLOCKLIST,
40+
Candidate.FinishReason.PROHIBITED_CONTENT,
41+
Candidate.FinishReason.SPII,
42+
})
43+
44+
3545
def finish_reason_from_vertex_ai_to_semantic_kernel(
3646
finish_reason: Candidate.FinishReason,
3747
) -> SemanticKernelFinishReason | None:
@@ -45,7 +55,7 @@ def finish_reason_from_vertex_ai_to_semantic_kernel(
4555
if finish_reason == Candidate.FinishReason.MAX_TOKENS:
4656
return SemanticKernelFinishReason.LENGTH
4757

48-
if finish_reason == Candidate.FinishReason.SAFETY:
58+
if finish_reason in _VERTEX_AI_CONTENT_FILTER_REASONS:
4959
return SemanticKernelFinishReason.CONTENT_FILTER
5060

5161
return None

‎python/tests/unit/connectors/ai/google/vertex_ai/services/test_vertex_ai_utils.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ def test_finish_reason_from_vertex_ai_to_semantic_kernel():
3030
assert finish_reason_from_vertex_ai_to_semantic_kernel(Candidate.FinishReason.OTHER) is None
3131

3232

33+
@pytest.mark.parametrize(
34+
"vertex_reason",
35+
[
36+
Candidate.FinishReason.SAFETY,
37+
Candidate.FinishReason.RECITATION,
38+
Candidate.FinishReason.BLOCKLIST,
39+
Candidate.FinishReason.PROHIBITED_CONTENT,
40+
Candidate.FinishReason.SPII,
41+
],
42+
)
43+
def test_finish_reason_from_vertex_ai_content_filter_reasons(vertex_reason):
44+
"""Responses Gemini stopped for their content map to CONTENT_FILTER."""
45+
assert finish_reason_from_vertex_ai_to_semantic_kernel(vertex_reason) == FinishReason.CONTENT_FILTER
46+
47+
3348
def test_format_user_message():
3449
"""Test format_user_message."""
3550
user_message = ChatMessageContent(role=AuthorRole.USER, content="User message")

0 commit comments

Comments
 (0)