mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
fix(bedrock/realtime): mint response/item ids so toolUse is not dropped
Nova Sonic starts tool turns with contentStart role=TOOL, so ASSISTANT-only id init never runs and transform_tool_use_event used to return empty events even after parsing content. Mint resp_/item_ ids when missing so function_call_arguments.done reaches the client with non-empty args
This commit is contained in:
parent
95239b9c68
commit
06cbbbb79a
2 changed files with 26 additions and 14 deletions
|
|
@ -1026,11 +1026,9 @@ class BedrockRealtimeConfig(BaseRealtimeConfig):
|
|||
verbose_logger.debug("Handling toolUse")
|
||||
tool_use = event["toolUse"]
|
||||
|
||||
if not current_output_item_id or not current_response_id:
|
||||
return [], "", ""
|
||||
response_id = current_response_id or f"resp_{uuid.uuid4()}"
|
||||
item_id = current_output_item_id or f"item_{uuid.uuid4()}"
|
||||
|
||||
# Parse the tool input. Nova 2 Sonic sends arguments in `content`;
|
||||
# fall back to `input` for backward compatibility.
|
||||
tool_input = {}
|
||||
raw_input = tool_use["content"] if "content" in tool_use else tool_use.get("input")
|
||||
if raw_input:
|
||||
|
|
@ -1042,15 +1040,13 @@ class BedrockRealtimeConfig(BaseRealtimeConfig):
|
|||
tool_call_id = tool_use.get("toolUseId", "")
|
||||
tool_name = tool_use.get("toolName", "")
|
||||
|
||||
# Create a function call arguments done event
|
||||
# This is a custom event format that matches what clients expect
|
||||
from typing import cast
|
||||
|
||||
function_call_event: dict[str, Any] = {
|
||||
"type": "response.function_call_arguments.done",
|
||||
"event_id": f"event_{uuid.uuid4()}",
|
||||
"response_id": current_response_id,
|
||||
"item_id": current_output_item_id,
|
||||
"response_id": response_id,
|
||||
"item_id": item_id,
|
||||
"output_index": 0,
|
||||
"call_id": tool_call_id,
|
||||
"name": tool_name,
|
||||
|
|
|
|||
|
|
@ -614,16 +614,30 @@ class TestBedrockRealtimeResponseTransformation:
|
|||
assert args["location"] == "San Francisco"
|
||||
|
||||
def test_transform_tool_use_event_directly(self):
|
||||
"""Test transform_tool_use_event directly for guard clause and input parsing"""
|
||||
"""Test transform_tool_use_event directly for input parsing and missing IDs"""
|
||||
config = BedrockRealtimeConfig()
|
||||
|
||||
# Guard clause: missing IDs returns empty result
|
||||
# Missing IDs still emit a function call (Nova Sonic starts tools with role=TOOL)
|
||||
events, tool_call_id, tool_name = config.transform_tool_use_event(
|
||||
{"toolUse": {}}, None, "resp_123"
|
||||
{
|
||||
"toolUse": {
|
||||
"toolUseId": "tool_call_no_ids",
|
||||
"toolName": "get_weather",
|
||||
"content": json.dumps({"location": "Seattle"}),
|
||||
}
|
||||
},
|
||||
None,
|
||||
None,
|
||||
)
|
||||
assert events == []
|
||||
assert tool_call_id == ""
|
||||
assert tool_name == ""
|
||||
assert len(events) == 1
|
||||
assert events[0]["type"] == "response.function_call_arguments.done"
|
||||
assert events[0]["call_id"] == "tool_call_no_ids"
|
||||
assert events[0]["name"] == "get_weather"
|
||||
assert events[0]["response_id"].startswith("resp_")
|
||||
assert events[0]["item_id"].startswith("item_")
|
||||
assert json.loads(events[0]["arguments"]) == {"location": "Seattle"}
|
||||
assert tool_call_id == "tool_call_no_ids"
|
||||
assert tool_name == "get_weather"
|
||||
|
||||
# JSON string content is parsed and converted to a function call event
|
||||
events, tool_call_id, tool_name = config.transform_tool_use_event(
|
||||
|
|
@ -641,6 +655,8 @@ class TestBedrockRealtimeResponseTransformation:
|
|||
assert events[0]["type"] == "response.function_call_arguments.done"
|
||||
assert events[0]["call_id"] == "tool_call_123"
|
||||
assert events[0]["name"] == "get_weather"
|
||||
assert events[0]["response_id"] == "resp_123"
|
||||
assert events[0]["item_id"] == "item_123"
|
||||
assert json.loads(events[0]["arguments"]) == {"location": "San Francisco"}
|
||||
|
||||
# Invalid JSON content falls back to empty arguments
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue