3737 "too many total text bytes" ,
3838]
3939
40+ # Models that should include tool result status (include_tool_result_status = True)
41+ _MODELS_INCLUDE_STATUS = [
42+ "anthropic.claude" ,
43+ ]
44+
4045T = TypeVar ("T" , bound = BaseModel )
4146
4247
@@ -71,6 +76,8 @@ class BedrockConfig(TypedDict, total=False):
7176 guardrail_redact_output_message: If a Bedrock Output guardrail triggers, replace output with this message.
7277 max_tokens: Maximum number of tokens to generate in the response
7378 model_id: The Bedrock model ID (e.g., "us.anthropic.claude-sonnet-4-20250514-v1:0")
79+ include_tool_result_status: Flag to include status field in tool results.
80+ True includes status, False removes status, "auto" determines based on model_id. Defaults to "auto".
7481 stop_sequences: List of sequences that will stop generation when encountered
7582 streaming: Flag to enable/disable streaming. Defaults to True.
7683 temperature: Controls randomness in generation (higher = more random)
@@ -92,6 +99,7 @@ class BedrockConfig(TypedDict, total=False):
9299 guardrail_redact_output_message : Optional [str ]
93100 max_tokens : Optional [int ]
94101 model_id : str
102+ include_tool_result_status : Optional [Literal ["auto" ] | bool ]
95103 stop_sequences : Optional [list [str ]]
96104 streaming : Optional [bool ]
97105 temperature : Optional [float ]
@@ -119,7 +127,7 @@ def __init__(
119127 if region_name and boto_session :
120128 raise ValueError ("Cannot specify both `region_name` and `boto_session`." )
121129
122- self .config = BedrockModel .BedrockConfig (model_id = DEFAULT_BEDROCK_MODEL_ID )
130+ self .config = BedrockModel .BedrockConfig (model_id = DEFAULT_BEDROCK_MODEL_ID , include_tool_result_status = "auto" )
123131 self .update_config (** model_config )
124132
125133 logger .debug ("config=<%s> | initializing" , self .config )
@@ -169,6 +177,17 @@ def get_config(self) -> BedrockConfig:
169177 """
170178 return self .config
171179
180+ def _should_include_tool_result_status (self ) -> bool :
181+ """Determine whether to include tool result status based on current config."""
182+ include_status = self .config .get ("include_tool_result_status" , "auto" )
183+
184+ if include_status is True :
185+ return True
186+ elif include_status is False :
187+ return False
188+ else : # "auto"
189+ return any (model in self .config ["model_id" ] for model in _MODELS_INCLUDE_STATUS )
190+
172191 def format_request (
173192 self ,
174193 messages : Messages ,
@@ -256,6 +275,7 @@ def _format_bedrock_messages(self, messages: Messages) -> Messages:
256275 """Format messages for Bedrock API compatibility.
257276
258277 This function ensures messages conform to Bedrock's expected format by:
278+ - Filtering out SDK_UNKNOWN_MEMBER content blocks
259279 - Cleaning tool result content blocks by removing additional fields that may be
260280 useful for retaining information in hooks but would cause Bedrock validation
261281 exceptions when presented with unexpected fields
@@ -273,19 +293,33 @@ def _format_bedrock_messages(self, messages: Messages) -> Messages:
273293 https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ToolResultBlock.html
274294 """
275295 cleaned_messages = []
296+ filtered_unknown_members = False
276297
277298 for message in messages :
278299 cleaned_content : list [ContentBlock ] = []
279300
280301 for content_block in message ["content" ]:
302+ # Filter out SDK_UNKNOWN_MEMBER content blocks
303+ if "SDK_UNKNOWN_MEMBER" in content_block :
304+ filtered_unknown_members = True
305+ continue
306+
281307 if "toolResult" in content_block :
282308 # Create a new content block with only the cleaned toolResult
283309 tool_result : ToolResult = content_block ["toolResult" ]
284310
285- # Keep only the required fields for Bedrock
286- cleaned_tool_result = ToolResult (
287- content = tool_result ["content" ], toolUseId = tool_result ["toolUseId" ], status = tool_result ["status" ]
288- )
311+ if self ._should_include_tool_result_status ():
312+ # Include status field
313+ cleaned_tool_result = ToolResult (
314+ content = tool_result ["content" ],
315+ toolUseId = tool_result ["toolUseId" ],
316+ status = tool_result ["status" ],
317+ )
318+ else :
319+ # Remove status field
320+ cleaned_tool_result = ToolResult ( # type: ignore[typeddict-item]
321+ toolUseId = tool_result ["toolUseId" ], content = tool_result ["content" ]
322+ )
289323
290324 cleaned_block : ContentBlock = {"toolResult" : cleaned_tool_result }
291325 cleaned_content .append (cleaned_block )
@@ -297,6 +331,11 @@ def _format_bedrock_messages(self, messages: Messages) -> Messages:
297331 cleaned_message : Message = Message (content = cleaned_content , role = message ["role" ])
298332 cleaned_messages .append (cleaned_message )
299333
334+ if filtered_unknown_members :
335+ logger .warning (
336+ "Filtered out SDK_UNKNOWN_MEMBER content blocks from messages, consider upgrading boto3 version"
337+ )
338+
300339 return cleaned_messages
301340
302341 def _has_blocked_guardrail (self , guardrail_data : dict [str , Any ]) -> bool :
0 commit comments