mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-06 08:16:43 +00:00
feat(bedrock): pass strict and additionalProperties to Converse API toolSpec
Bedrock Converse API supports strict: true in toolSpec since 2026-02-04 (GA). Previously, both strict and additionalProperties were implicitly dropped during OpenAI-to-Bedrock tool conversion because ToolSpecBlock and ToolJsonSchemaBlock only whitelisted a subset of fields. This change: - Adds strict to ToolSpecBlock and passes it through when present - Adds additionalProperties to ToolJsonSchemaBlock and passes it through when present (required by Bedrock when strict: true is set) Without additionalProperties: false, Bedrock rejects strict: true requests with: "For 'object' type, 'additionalProperties' must be explicitly set to false" Fixes the gap where Anthropic direct API path already supports strict (PR #16725) but Bedrock Converse path does not.
This commit is contained in:
parent
62757ff48f
commit
c51fb46d85
3 changed files with 62 additions and 2 deletions
|
|
@ -5174,15 +5174,25 @@ def _bedrock_tools_pt(tools: List) -> List[BedrockToolBlock]:
|
|||
# with circular references (see issue #19098). unpack_defs handles nested
|
||||
# refs recursively and correctly detects/skips circular references.
|
||||
unpack_defs(parameters, defs_copy)
|
||||
_additional_properties = parameters.get("additionalProperties", None)
|
||||
tool_input_schema = BedrockToolInputSchemaBlock(
|
||||
json=BedrockToolJsonSchemaBlock(
|
||||
type=parameters.get("type", ""),
|
||||
properties=parameters.get("properties", {}),
|
||||
required=parameters.get("required", []),
|
||||
**(
|
||||
{"additionalProperties": _additional_properties}
|
||||
if _additional_properties is not None
|
||||
else {}
|
||||
),
|
||||
)
|
||||
)
|
||||
_strict = tool.get("function", {}).get("strict", None)
|
||||
tool_spec = BedrockToolSpecBlock(
|
||||
inputSchema=tool_input_schema, name=name, description=description
|
||||
inputSchema=tool_input_schema,
|
||||
name=name,
|
||||
description=description,
|
||||
**({"strict": _strict} if _strict is not None else {}),
|
||||
)
|
||||
tool_block = BedrockToolBlock(toolSpec=tool_spec)
|
||||
tool_block_list.append(tool_block)
|
||||
|
|
|
|||
|
|
@ -203,13 +203,16 @@ class ConverseResponseBlock(TypedDict, total=False):
|
|||
str
|
||||
] # end_turn | tool_use | max_tokens | stop_sequence | content_filtered
|
||||
usage: Required[ConverseTokenUsageBlock]
|
||||
serviceTier: ServiceTierBlock # Optional - only present when serviceTier was sent in request
|
||||
serviceTier: (
|
||||
ServiceTierBlock # Optional - only present when serviceTier was sent in request
|
||||
)
|
||||
|
||||
|
||||
class ToolJsonSchemaBlock(TypedDict, total=False):
|
||||
type: Literal["object"]
|
||||
properties: dict
|
||||
required: List[str]
|
||||
additionalProperties: bool
|
||||
|
||||
|
||||
class ToolInputSchemaBlock(TypedDict):
|
||||
|
|
@ -220,6 +223,7 @@ class ToolSpecBlock(TypedDict, total=False):
|
|||
inputSchema: Required[ToolInputSchemaBlock]
|
||||
name: Required[str]
|
||||
description: str
|
||||
strict: Optional[bool]
|
||||
|
||||
|
||||
class SystemToolBlock(TypedDict, total=False):
|
||||
|
|
|
|||
|
|
@ -1116,6 +1116,52 @@ def test_bedrock_tools_transformation_valid_params():
|
|||
assert "test" in result[0]["toolSpec"]["inputSchema"]["json"]["required"]
|
||||
|
||||
|
||||
def test_bedrock_tools_pt_strict_parameter():
|
||||
"""Test that strict and additionalProperties are passed through to Bedrock toolSpec."""
|
||||
tools_with_strict = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "generate_sql",
|
||||
"strict": True,
|
||||
"description": "Generate a SQL query",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": {"type": "string"},
|
||||
},
|
||||
"required": ["query"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
result = _bedrock_tools_pt(tools_with_strict)
|
||||
assert result[0]["toolSpec"]["strict"] is True
|
||||
assert result[0]["toolSpec"]["inputSchema"]["json"]["additionalProperties"] is False
|
||||
|
||||
# Test without strict - should not have strict key or additionalProperties
|
||||
tools_without_strict = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "generate_sql",
|
||||
"description": "Generate a SQL query",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": {"type": "string"},
|
||||
},
|
||||
"required": ["query"],
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
result = _bedrock_tools_pt(tools_without_strict)
|
||||
assert "strict" not in result[0]["toolSpec"]
|
||||
assert "additionalProperties" not in result[0]["toolSpec"]["inputSchema"]["json"]
|
||||
|
||||
|
||||
def test_not_found_error():
|
||||
with pytest.raises(litellm.NotFoundError):
|
||||
completion(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue