From 7446e026907de8c0126008f43cdcefde93ae0fdc Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Wed, 7 Oct 2026 21:20:56 -0700 Subject: [PATCH] fix(decisions): return guardrail_information on OpenAI-format decisions when requested Backport of the #45184 and #45214 guardrail fix. Cherry-picked from 855f0bb765 (litellm_systemone_endpoint) as merged into #45214 at c19ada66ed (litellm_openai_decisions_provider). --- litellm/types/decisions.py | 2 +- .../decisions_endpoints/test_endpoints.py | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/litellm/types/decisions.py b/litellm/types/decisions.py index c81f1d76a3a..6488ef45308 100644 --- a/litellm/types/decisions.py +++ b/litellm/types/decisions.py @@ -313,7 +313,7 @@ class OpenAIDecisionResponse(_HiddenParamsResponse): answers: tuple[OpenAIDecisionAnswer, ...] usage: OpenAIDecisionUsage - model_config = ConfigDict(frozen=True) + model_config = ConfigDict(extra="allow", frozen=True) _NO_EXTRA: Final[Mapping[str, object]] = MappingProxyType({}) diff --git a/tests/unit/proxy/decisions_endpoints/test_endpoints.py b/tests/unit/proxy/decisions_endpoints/test_endpoints.py index 812f4556b85..7d965af56b1 100644 --- a/tests/unit/proxy/decisions_endpoints/test_endpoints.py +++ b/tests/unit/proxy/decisions_endpoints/test_endpoints.py @@ -386,6 +386,29 @@ def test_openai_format_decisions_translate_through_systemone( assert float(response.headers["x-litellm-response-cost"]) > 0 +@pytest.mark.parametrize( + ("endpoint", "request_body", "upstream_response"), + ( + ("/v1/systemone", _REQUEST, _RESPONSE), + ("/v1/decisions", _OPENAI_FORMAT_REQUEST, _SYSTEMONE_ANSWERS_FOR_OPENAI_REQUEST), + ), + ids=("systemone", "openai_format"), +) +def test_decisions_return_guardrail_information_when_requested( + client: TestClient, + respx_mock: respx.MockRouter, + endpoint: str, + request_body: Mapping[str, object], + upstream_response: Mapping[str, object], +) -> None: + respx_mock.post("https://api.perplexity.ai/v1/decisions").respond(json=upstream_response) + + response: Final = client.post(endpoint, json={**request_body, "include_guardrail_response": True}) + + assert response.status_code == 200, response.text + assert response.json()["guardrail_information"] == [] + + @pytest.mark.parametrize( "request_body", (