From 263a1d43bb9d6b296fac6d7cef02897949269b75 Mon Sep 17 00:00:00 2001 From: yucheng Date: Wed, 30 Sep 2026 01:32:35 +0000 Subject: [PATCH] fix(responses): treat an empty guardrail texts answer as no rewrite like chat completions Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../guardrail_translation/handler.py | 2 +- ...test_openai_responses_guardrail_handler.py | 26 +++---------------- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/litellm/llms/openai/responses/guardrail_translation/handler.py b/litellm/llms/openai/responses/guardrail_translation/handler.py index 57f0bbb927a..620d0554bb1 100644 --- a/litellm/llms/openai/responses/guardrail_translation/handler.py +++ b/litellm/llms/openai/responses/guardrail_translation/handler.py @@ -568,7 +568,7 @@ class OpenAIResponsesHandler(BaseTranslation): guardrailed_inputs: GenericGuardrailAPIInputs, ) -> None: returned_texts: Final = guardrailed_inputs.get("texts") - if returned_texts is None: + if not returned_texts: return rewritten_texts: Final = tuple(returned_texts) offset: Final = 0 if extracted.instructions is None else 1 diff --git a/tests/unit/llms/openai/responses/test_openai_responses_guardrail_handler.py b/tests/unit/llms/openai/responses/test_openai_responses_guardrail_handler.py index 21ae6d62262..946450115af 100644 --- a/tests/unit/llms/openai/responses/test_openai_responses_guardrail_handler.py +++ b/tests/unit/llms/openai/responses/test_openai_responses_guardrail_handler.py @@ -356,31 +356,13 @@ class TestOpenAIResponsesHandlerInputProcessing: assert data["input"] == original["input"] @pytest.mark.asyncio + @pytest.mark.parametrize("answered_texts", [None, ()], ids=["no_texts_key", "empty_texts"]) @pytest.mark.parametrize("data_input", ["Hello", [{"role": "user", "content": "Hello"}]]) - async def test_empty_texts_answer_is_rejected_instead_of_forwarding_the_raw_request( - self, data_input: str | list[dict[str, str]] - ) -> None: - from litellm.llms.base_llm.guardrail_translation.utils import UnappliableRequestRewrite - - handler = OpenAIResponsesHandler() - guardrail = TextsReplacingGuardrail(guardrail_name="emptier", texts=()) - data = {"model": "gpt-4", "instructions": "Be terse", "input": data_input} - original = copy.deepcopy(data) - - with pytest.raises(UnappliableRequestRewrite) as excinfo: - await handler.process_input_messages(data, guardrail) - - assert excinfo.value.guardrail_name == "emptier" - assert data["instructions"] == original["instructions"] - assert data["input"] == original["input"] - - @pytest.mark.asyncio - @pytest.mark.parametrize("data_input", ["Hello", [{"role": "user", "content": "Hello"}]]) - async def test_answer_without_texts_key_leaves_instructions_and_input_untouched( - self, data_input: str | list[dict[str, str]] + async def test_answer_without_texts_leaves_instructions_and_input_untouched_like_chat_completions( + self, answered_texts: tuple[str, ...] | None, data_input: str | list[dict[str, str]] ) -> None: handler = OpenAIResponsesHandler() - guardrail = TextsReplacingGuardrail(guardrail_name="silent", texts=None) + guardrail = TextsReplacingGuardrail(guardrail_name="silent", texts=answered_texts) data = {"model": "gpt-4", "instructions": "Be terse", "input": data_input} original = copy.deepcopy(data)