CR
Code Review Helper
๐Ÿ”—

fix(guardrail): pass request_data to output response handlers

ishaan-jaffโ€ข14 filesโ€ข+87โˆ’52โ€ข4 chunks
Critical2
High2
Medium0
#1high+4โˆ’3

Add request_data to A2A output handler

๐Ÿ“„ litellm/llms/a2a/chat/guardrail_translation/handler.py
Adds the request_data parameter to process_output_response and merges it into local_request_data via dict unpacking, preserving any input-phase context.
RELATED
111111 guardrail_to_apply: "CustomGuardrail",
112112 litellm_logging_obj: Optional["LiteLLMLoggingObj"] = None,
113113 user_api_key_dict: Optional["UserAPIKeyAuth"] = None,
114+ request_data: Optional[dict] = None,
114115 ) -> Any:
115116 """
116117 Process A2A output response by applying guardrails to text content.
โ‹ฏ 50 lines hidden
167168 # Step 2: Apply guardrail to all texts in batch
168169 # Create a local_request_data dict with response info
169โˆ’ request_data: dict = {"response": response_dict}
170+ local_request_data: dict = {**(request_data or {}), "response": response_dict}
๐Ÿ’ฌConversation ยท 2 messagesโ–ผ
Y
You2 min ago
Why use dict unpacking instead of dict.update()?
AI
AI Assistant1 min ago
The `{(request_data or {}), "response": response_dict}` pattern creates a new dict rather than mutating `request_data`. This matters because `request_data` is shared across multiple handler invocations โ€” mutating it would cause cross-contamination between guardrail handlers.
Y
171172 # Add user API key metadata with prefixed keys
172173 user_metadata = self.transform_user_api_key_dict_to_metadata(user_api_key_dict)
173174 if user_metadata:
174175 local_request_data["litellm_metadata"] = user_metadata
Hover a line and click + to ask about specific lines
#5critical+8โˆ’3

Update base class abstract signatures

๐Ÿ“„ litellm/llms/base_llm/guardrail_translation/base_translation.py
Updates the abstract BaseTranslation to declare request_data on both process_output_response and process_output_streaming_response, defining the interface contract all subclasses must follow.
RELATED
7373 guardrail_to_apply: "CustomGuardrail",
7474 litellm_logging_obj: Optional["LiteLLMLoggingObj"] = None,
7575 user_api_key_dict: Optional["UserAPIKeyAuth"] = None,
76+ request_data: Optional[dict] = None,
7677 ) -> Any:
7778 """
7879 Process output response with guardrails.
8283 litellm_logging_obj: Optional logging object
8384 user_api_key_dict: User API key metadata
8485 request_data: Optional original request data dict from the proxy
86+ """
8587 pass
Hover a line and click + to ask about specific lines
AI
Ask about Chunk #5
AI Summary
Updates the abstract BaseTranslation to declare request_data on both process_output_response and process_output_streaming_response, defining the interface contract all subclasses must follow.
RELATED โ†’#1#2#3#8#20
Y
You3 min ago
Why is this chunk marked as critical?
AI
AI Assistant2 min ago
This chunk modifies the abstract base class `BaseTranslation`, which defines the interface contract for all guardrail handlers. Every concrete handler must conform to this signature. Changing the abstract interface is critical because: 1. Any subclass missing `request_data` breaks Liskov substitution 2. It affects 10+ handler implementations 3. A missing parameter means silent loss of input context
Y
#8high+6โˆ’4

Update OpenAI handler + use local_request_data

๐Ÿ“„ litellm/llms/openai/chat/guardrail_translation/handler.py
Adds request_data to the OpenAI chat handler and fixes the streaming path to pass local_request_data instead of the raw parameter, ensuring enriched context reaches the guardrail.
RELATED
260260 guardrail_to_apply: "CustomGuardrail",
261261 litellm_logging_obj: Optional[Any] = None,
262262 user_api_key_dict: Optional[Any] = None,
263+ request_data: Optional[dict] = None,
263264 ) -> Any:
264265 """
265266 Process output response by applying guardrails to text content.
โ‹ฏ 43 lines hidden
308309 # Step 2: Apply guardrail to all texts and tool calls in batch
309310 if texts_to_check or tool_calls_to_check:
310311 # Create a local_request_data dict
311โˆ’ request_data: dict = {"response": response}
312+ local_request_data: dict = {**(request_data or {}), "response": response}
313314 # Add user API key metadata with prefixed keys
314315 user_metadata = self.transform_user_api_key_dict_to_metadata(
315316 user_api_key_dict
316317 )
Hover a line and click + to ask about specific lines
#20critical+4โˆ’0

Forward request_data from unified guardrail

๐Ÿ“„ litellm/proxy/guardrails/guardrail_hooks/unified_guardrail/unified_guardrail.py
The entry point: passes the full request `data` dict into process_output_response and streaming hooks, making it available to all downstream handlers.
RELATED
247247 guardrail_to_apply=guardrail_to_apply,
248248 litellm_logging_obj=data.get("litellm_logging_obj"),
249249 user_api_key_dict=user_api_key_dict,
250+ request_data=data,๐Ÿ’ฌ 4
๐Ÿ’ฌ4 commentsโ€” click to expandโ–ถ
250251 )
251252 # Add guardrail to applied guardrails header
Hover a line and click + to ask about specific lines