fix(redaction): redact Responses refusal parts under turn_off_message_logging

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yucheng 2026-09-19 19:35:08 +00:00
parent 7d93821e41
commit e8f2ee8200
2 changed files with 33 additions and 0 deletions

View file

@ -128,6 +128,8 @@ def _redact_responses_api_output(output_items):
for content_part in output_item.content:
if getattr(content_part, "text", None) is not None:
content_part.text = REDACTED_BY_LITELLM
if getattr(content_part, "refusal", None) is not None:
content_part.refusal = REDACTED_BY_LITELLM
# Redact reasoning items in output array
if hasattr(output_item, "type") and output_item.type == "reasoning":
@ -155,6 +157,8 @@ def _redact_responses_api_output_dict(output_items, redacted_str: str):
for content_item in output_item["content"]:
if isinstance(content_item, dict) and content_item.get("text") is not None:
content_item["text"] = redacted_str
if isinstance(content_item, dict) and content_item.get("refusal") is not None:
content_item["refusal"] = redacted_str
if output_item.get("type") == "reasoning" and isinstance(output_item.get("summary"), list):
for summary_item in output_item["summary"]:

View file

@ -507,6 +507,26 @@ class TestPerformRedaction:
assert redacted["output"][0]["name"] == "grep"
assert redacted["output"][1]["input"] == "not-a-custom-input"
def test_redacts_responses_api_refusal_parts_dict(self):
result = {
"output": [
{
"type": "message",
"role": "assistant",
"content": [
{"type": "refusal", "refusal": "I cannot share the secret"},
{"type": "output_text", "text": "ok"},
],
}
]
}
redacted = perform_redaction({}, result)
assert redacted["output"][0]["content"][0]["refusal"] == "redacted-by-litellm"
assert redacted["output"][0]["content"][0]["type"] == "refusal"
assert redacted["output"][0]["content"][1]["text"] == "redacted-by-litellm"
def test_redacts_every_tool_call_in_multi_element_list(self):
result = litellm.ModelResponse(
id="resp-multi",
@ -585,6 +605,15 @@ class TestPerformRedaction:
assert output_item.input == "redacted-by-litellm"
assert output_item.name == "grep"
def test_redacts_responses_api_refusal_parts_object(self):
refusal = SimpleNamespace(type="refusal", refusal="I cannot share the secret")
output_item = SimpleNamespace(type="message", role="assistant", content=[refusal])
_redact_responses_api_output([output_item])
assert refusal.refusal == "redacted-by-litellm"
assert refusal.type == "refusal"
def test_redacts_response_output_objects_with_top_level_text(self):
output_items = [
SimpleNamespace(text="top-level output"),