@@ -82,6 +82,8 @@ class BedrockConfig(TypedDict, total=False):
8282 guardrail_redact_input_message: If a Bedrock Input guardrail triggers, replace the input with this message.
8383 guardrail_redact_output: Flag to redact output if guardrail is triggered. Defaults to False.
8484 guardrail_redact_output_message: If a Bedrock Output guardrail triggers, replace output with this message.
85+ guardrail_last_turn_only: Flag to send only the last turn to guardrails instead of full conversation.
86+ Defaults to False.
8587 max_tokens: Maximum number of tokens to generate in the response
8688 model_id: The Bedrock model ID (e.g., "us.anthropic.claude-sonnet-4-20250514-v1:0")
8789 include_tool_result_status: Flag to include status field in tool results.
@@ -105,6 +107,7 @@ class BedrockConfig(TypedDict, total=False):
105107 guardrail_redact_input_message : Optional [str ]
106108 guardrail_redact_output : Optional [bool ]
107109 guardrail_redact_output_message : Optional [str ]
110+ guardrail_last_turn_only : Optional [bool ]
108111 max_tokens : Optional [int ]
109112 model_id : str
110113 include_tool_result_status : Optional [Literal ["auto" ] | bool ]
@@ -206,9 +209,19 @@ def _format_request(
206209 Returns:
207210 A Bedrock converse stream request.
208211 """
212+ # Filter messages for guardrails if guardrail_last_turn_only is enabled
213+ messages_for_request = messages
214+ if (
215+ self .config .get ("guardrail_last_turn_only" , False )
216+ and self .config .get ("guardrail_id" )
217+ and self .config .get ("guardrail_version" )
218+ ):
219+ messages_for_request = self ._get_last_turn_messages (messages )
220+
209221 if not tool_specs :
210222 has_tool_content = any (
211- any ("toolUse" in block or "toolResult" in block for block in msg .get ("content" , [])) for msg in messages
223+ any ("toolUse" in block or "toolResult" in block for block in msg .get ("content" , []))
224+ for msg in messages_for_request
212225 )
213226 if has_tool_content :
214227 tool_specs = [noop_tool .tool_spec ]
@@ -224,7 +237,7 @@ def _format_request(
224237
225238 return {
226239 "modelId" : self .config ["model_id" ],
227- "messages" : self ._format_bedrock_messages (messages ),
240+ "messages" : self ._format_bedrock_messages (messages_for_request ),
228241 "system" : system_blocks ,
229242 ** (
230243 {
@@ -295,6 +308,42 @@ def _format_request(
295308 ),
296309 }
297310
311+ def _get_last_turn_messages (self , messages : Messages ) -> Messages :
312+ """Get the last turn messages for guardrail evaluation.
313+
314+ Returns the latest user message and the previous assistant message (if it exists).
315+ This reduces the conversation context sent to guardrails when guardrail_last_turn_only is True.
316+
317+ Args:
318+ messages: Full conversation messages.
319+
320+ Returns:
321+ Messages containing only the last turn (user + previous assistant if exists).
322+ """
323+ if not messages :
324+ return []
325+
326+ # Find the last user message
327+ last_user_index = - 1
328+ for i in range (len (messages ) - 1 , - 1 , - 1 ):
329+ if messages [i ]["role" ] == "user" :
330+ last_user_index = i
331+ break
332+
333+ if last_user_index == - 1 :
334+ # No user message found, return empty
335+ return []
336+
337+ # Include the previous assistant message if it exists
338+ result_messages : Messages = []
339+ if last_user_index > 0 and messages [last_user_index - 1 ]["role" ] == "assistant" :
340+ result_messages .append (messages [last_user_index - 1 ])
341+
342+ # Add the last user message
343+ result_messages .append (messages [last_user_index ])
344+
345+ return result_messages
346+
298347 def _format_bedrock_messages (self , messages : Messages ) -> list [dict [str , Any ]]:
299348 """Format messages for Bedrock API compatibility.
300349
0 commit comments