fix: map 'refusal' finish_reason to 'content_filter' (#24141)

Azure AI Foundry returns finish_reason='refusal' when content
filtering rejects a response (e.g. Claude Sonnet 4.6 on Azure).
This was unmapped and defaulted to 'stop', hiding the actual
content filter rejection from callers.

Add 'refusal' -> 'content_filter' to _FINISH_REASON_MAP.
This commit is contained in:
Imgyu Kim 2026-03-21 19:15:46 +09:00
parent d8e4fc4dd0
commit 28816ee95d
2 changed files with 8 additions and 0 deletions

View file

@ -98,6 +98,8 @@ _FINISH_REASON_MAP: dict[str, OpenAIChatCompletionFinishReason] = {
"content_filter": "content_filter",
# Anthropic Sonnet 4
"content_filtered": "content_filter",
# Azure AI Foundry content filtering
"refusal": "content_filter",
}

View file

@ -123,6 +123,12 @@ class TestMapFinishReasonBedrock:
assert map_finish_reason("guardrail_intervened") == "content_filter"
class TestMapFinishReasonAzureAIFoundry:
def test_refusal(self):
# GH#24141: Azure AI Foundry returns 'refusal' for content filtering
assert map_finish_reason("refusal") == "content_filter"
class TestMapFinishReasonOpenAIPassthrough:
@pytest.mark.parametrize(
"reason", ["stop", "length", "tool_calls", "function_call", "content_filter"]