fix(guardrails): stop labelling image-only input as a not_run scoping skip

Images without text were never dispatched to guardrails before this change, so that gap is not a message scoping skip and must not get a not_run entry

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yucheng 2026-09-14 23:49:03 +00:00
parent 0d0b96ed06
commit 0519d86346
2 changed files with 22 additions and 1 deletions

View file

@ -210,7 +210,7 @@ class OpenAIChatCompletionsHandler(BaseTranslation):
task_mappings=tool_call_task_mappings,
)
elif not guardrail_to_apply.records_own_guardrail_information:
elif not images_to_check and not guardrail_to_apply.records_own_guardrail_information:
guardrail_to_apply.add_standard_logging_guardrail_information_to_request_data(
guardrail_json_response="no scannable content after message scoping",
request_data=data,

View file

@ -1942,6 +1942,27 @@ class TestNoScannableContentRecordsNotRun:
assert guardrail.last_inputs is not None
assert all(e.get("guardrail_status") != "not_run" for e in self._recorded_entries(data))
@pytest.mark.asyncio
async def test_image_only_content_is_not_reported_as_not_run(self):
"""Images are only scanned alongside text, so an image-only request is a
pre-existing scan gap, not a message-scoping skip, and must not be labelled one"""
handler = OpenAIChatCompletionsHandler()
guardrail = MockGuardrail(guardrail_name="image-guardrail")
guardrail.skip_system_message_in_guardrail = True
data = {
"messages": [
{"role": "system", "content": "SYSTEM-PROMPT"},
{
"role": "user",
"content": [{"type": "image_url", "image_url": {"url": "https://example.com/cat.png"}}],
},
]
}
await handler.process_input_messages(data=data, guardrail_to_apply=guardrail)
assert self._recorded_entries(data) == []
class TestBuildBlockSseChunks:
"""build_block_sse_chunks turns a streaming ModifyResponseException into 200 SSE chunks"""