Skip to content

Commit c9b184b

Browse files
author
Jack Yuan
committed
fix: fix stop reason for bedrock model when stop_reason is end_turn in tool use response.
1 parent b008cf5 commit c9b184b

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

src/strands/models/bedrock.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ def _stream(
432432
logger.debug("got response from model")
433433
if streaming:
434434
response = self.client.converse_stream(**request)
435+
# Track tool use events to fix stopReason for streaming responses
436+
has_tool_use = False
435437
for chunk in response["stream"]:
436438
if (
437439
"metadata" in chunk
@@ -443,7 +445,24 @@ def _stream(
443445
for event in self._generate_redaction_events():
444446
callback(event)
445447

446-
callback(chunk)
448+
# Track if we see tool use events
449+
if "contentBlockStart" in chunk and chunk["contentBlockStart"].get("start", {}).get("toolUse"):
450+
has_tool_use = True
451+
452+
# Fix stopReason for streaming responses that contain tool use
453+
if "messageStop" in chunk and has_tool_use:
454+
message_stop = chunk["messageStop"]
455+
if message_stop.get("stopReason") == "end_turn":
456+
# Create corrected chunk with tool_use stopReason
457+
modified_chunk = chunk.copy()
458+
modified_chunk["messageStop"] = message_stop.copy()
459+
modified_chunk["messageStop"]["stopReason"] = "tool_use"
460+
logger.info("Override stop reason from end_turn to tool_use")
461+
callback(modified_chunk)
462+
else:
463+
callback(chunk)
464+
else:
465+
callback(chunk)
447466

448467
else:
449468
response = self.client.converse(**request)
@@ -579,9 +598,17 @@ def _convert_non_streaming_to_streaming(self, response: dict[str, Any]) -> Itera
579598
yield {"contentBlockStop": {}}
580599

581600
# Yield messageStop event
601+
# Fix stopReason for models that return end_turn when they should return tool_use on non-streaming side
602+
current_stop_reason = response["stopReason"]
603+
if current_stop_reason == "end_turn":
604+
message_content = response["output"]["message"]["content"]
605+
if any("toolUse" in content for content in message_content):
606+
current_stop_reason = "tool_use"
607+
logger.info("Override stop reason from end_turn to tool_use")
608+
582609
yield {
583610
"messageStop": {
584-
"stopReason": response["stopReason"],
611+
"stopReason": current_stop_reason,
585612
"additionalModelResponseFields": response.get("additionalModelResponseFields"),
586613
}
587614
}

0 commit comments

Comments
 (0)