@@ -205,12 +205,15 @@ def test_guardrail_output_intervention_redact_output(bedrock_guardrail, processi
205205
206206@pytest .mark .parametrize ("processing_mode" , ["sync" , "async" ])
207207def test_guardrail_intervention_properly_redacts_tool_result (bedrock_guardrail , processing_mode ):
208- REDACT_MESSAGE = "Input redacted."
208+ INPUT_REDACT_MESSAGE = "Input redacted."
209+ OUTPUT_REDACT_MESSAGE = "Output redacted."
209210 bedrock_model = BedrockModel (
210211 guardrail_id = bedrock_guardrail ,
211212 guardrail_version = "DRAFT" ,
212213 guardrail_stream_processing_mode = processing_mode ,
213- guardrail_redact_input_message = REDACT_MESSAGE ,
214+ guardrail_redact_output = True ,
215+ guardrail_redact_input_message = INPUT_REDACT_MESSAGE ,
216+ guardrail_redact_output_message = OUTPUT_REDACT_MESSAGE ,
214217 region_name = "us-east-1" ,
215218 )
216219
@@ -230,51 +233,44 @@ def list_users() -> str:
230233 response1 = agent ("List my users." )
231234 response2 = agent ("Thank you!" )
232235
233- assert response1 .stop_reason == "guardrail_intervened"
234-
235- """
236- In async streaming: The buffering is non-blocking.
237- Tokens are streamed while Guardrails processes the buffered content in the background.
238- This means the response may be returned before Guardrails has finished processing.
239- As a result, we cannot guarantee that the BLOCKED_OUTPUT is in the response
240- However, response2 should not be blocked anyway.
236+ """ Message sequence:
237+ 0 (user): request1
238+ 1 (assistant): reasoning + tool call
239+ 2 (user): tool result
240+ 3 (assistant): response1 -> output guardrail intervenes
241+ 4 (user): request2
242+ 5 (assistant): response2
243+
244+ Guardrail intervened on output in message 3 will cause
245+ the redaction of the preceding input (message 2) and message 3.
241246 """
247+
242248 if processing_mode == "sync" :
243- assert response1 . stop_reason == "guardrail_intervened"
244- assert BLOCKED_OUTPUT in str ( response1 )
249+ """ In sync mode the guardrail processing is blocking.
250+ The response is already blocked and redacted. """
245251
246- assert response2 .stop_reason != "guardrail_intervened"
247- assert BLOCKED_OUTPUT not in str (response2 )
252+ assert OUTPUT_REDACT_MESSAGE in str (response1 )
253+ assert OUTPUT_REDACT_MESSAGE not in str (response2 )
254+
255+ """
256+ In async streaming, the buffering is non-blocking,
257+ so the response may be returned before Guardrails has finished processing.
258+
259+ However, in both sync and async, with guardrail_redact_output=True:
260+ 1. the content should be properly redacted in memory allowing the
261+ conversation to continue;
262+ """
263+ assert response1 .stop_reason == "guardrail_intervened"
264+ assert response2 .stop_reason != "guardrail_intervened"
248265
249- """ Message sequence:
250- 0 (user): request1
251- 1 (assistant): reasoning + tool call
252- 2 (user): tool result
253- 3 (assistant): response1 (blocked)
254- 4 (user): request2
255- 5 (assistant): response2
256-
257- Guardrail intervened on output in message 3 will cause
258- the redaction of the preceding input (message 2).
259- We want the tool result block to be preserved.
260- """
261-
262- tool_call = [b for b in agent .messages [1 ]["content" ] if "toolUse" in b ][0 ]
263- tool_result = [b for b in agent .messages [2 ]["content" ] if "toolResult" in b ][0 ]
264- assert tool_result ["tool_id" ] == tool_call ["tool_id" ]
265- assert tool_result ["content" ][0 ]["text" ] == REDACT_MESSAGE
266+ """
267+ 2. the tool result block should be redacted properly.
268+ """
266269
267- else :
268- # TODO
269- cactus_returned_in_response1_blocked_by_input_guardrail = BLOCKED_INPUT in str (response2 )
270- cactus_blocked_in_response1_allows_next_response = (
271- REDACT_MESSAGE not in str (response2 ) and response2 .stop_reason != "guardrail_intervened"
272- )
273- assert (
274- cactus_returned_in_response1_blocked_by_input_guardrail or cactus_blocked_in_response1_allows_next_response
275- )
276- # Output correctly redacted
277- assert agent .messages [3 ]["content" ][0 ]["text" ] == REDACT_MESSAGE
270+ tool_call = [b for b in agent .messages [1 ]["content" ] if "toolUse" in b ][0 ]["toolUse" ]
271+ tool_result = [b for b in agent .messages [2 ]["content" ] if "toolResult" in b ][0 ]["toolResult" ]
272+ assert tool_result ["toolUseId" ] == tool_call ["toolUseId" ]
273+ assert tool_result ["content" ][0 ]["text" ] == INPUT_REDACT_MESSAGE
278274
279275
280276def test_guardrail_input_intervention_properly_redacts_in_session (boto_session , bedrock_guardrail , temp_dir ):
0 commit comments