mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-06 08:16:43 +00:00
Merge pull request #5138 from BerriAI/litellm_bedrock_tool_calling
Feat - Translate openai function names to bedrock converse schema
This commit is contained in:
commit
2fa73acf32
2 changed files with 156 additions and 1 deletions
|
|
@ -2293,6 +2293,34 @@ def _bedrock_converse_messages_pt(
|
|||
return contents
|
||||
|
||||
|
||||
def make_valid_bedrock_tool_name(input_tool_name: str) -> str:
|
||||
"""
|
||||
Replaces any invalid characters in the input tool name with underscores
|
||||
and ensures the resulting string is a valid identifier for Bedrock tools
|
||||
"""
|
||||
|
||||
def replace_invalid(char):
|
||||
"""
|
||||
Bedrock tool names only supports alpha-numeric characters and underscores
|
||||
"""
|
||||
if char.isalnum() or char == "_":
|
||||
return char
|
||||
return "_"
|
||||
|
||||
# If the string is empty, return a default valid identifier
|
||||
if input_tool_name is None or len(input_tool_name) == 0:
|
||||
return input_tool_name
|
||||
|
||||
# If it doesn't start with a letter, prepend 'a'
|
||||
if not input_tool_name[0].isalpha():
|
||||
input_tool_name = "a" + input_tool_name
|
||||
|
||||
# Replace any invalid characters with underscores
|
||||
valid_string = "".join(replace_invalid(char) for char in input_tool_name)
|
||||
|
||||
return valid_string
|
||||
|
||||
|
||||
def _bedrock_tools_pt(tools: List) -> List[BedrockToolBlock]:
|
||||
"""
|
||||
OpenAI tools looks like:
|
||||
|
|
@ -2346,6 +2374,10 @@ def _bedrock_tools_pt(tools: List) -> List[BedrockToolBlock]:
|
|||
for tool in tools:
|
||||
parameters = tool.get("function", {}).get("parameters", None)
|
||||
name = tool.get("function", {}).get("name", "")
|
||||
|
||||
# related issue: https://github.com/BerriAI/litellm/issues/5007
|
||||
# Bedrock tool names must satisfy regular expression pattern: [a-zA-Z][a-zA-Z0-9_]* ensure this is true
|
||||
name = make_valid_bedrock_tool_name(input_tool_name=name)
|
||||
description = tool.get("function", {}).get(
|
||||
"description", name
|
||||
) # converse api requires a description
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@ from litellm import (
|
|||
completion_cost,
|
||||
embedding,
|
||||
)
|
||||
from litellm.llms.bedrock_httpx import BedrockLLM
|
||||
from litellm.llms.bedrock_httpx import BedrockLLM, ToolBlock
|
||||
from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler, HTTPHandler
|
||||
from litellm.llms.prompt_templates.factory import _bedrock_tools_pt
|
||||
|
||||
# litellm.num_retries = 3
|
||||
litellm.cache = None
|
||||
|
|
@ -983,3 +984,125 @@ def test_completion_bedrock_external_client_region():
|
|||
pass
|
||||
except Exception as e:
|
||||
pytest.fail(f"Error occurred: {e}")
|
||||
|
||||
|
||||
def test_bedrock_tool_calling():
|
||||
"""
|
||||
# related issue: https://github.com/BerriAI/litellm/issues/5007
|
||||
# Bedrock tool names must satisfy regular expression pattern: [a-zA-Z][a-zA-Z0-9_]* ensure this is true
|
||||
"""
|
||||
litellm.set_verbose = True
|
||||
response = litellm.completion(
|
||||
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0",
|
||||
fallbacks=["bedrock/meta.llama3-1-8b-instruct-v1:0"],
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What's the weather like in Boston today in Fahrenheit?",
|
||||
}
|
||||
],
|
||||
tools=[
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "-DoSomethingVeryCool-forLitellm_Testin999229291-0293993",
|
||||
"description": "do something very cool",
|
||||
"parameters": {"type": "object", "properties": {}},
|
||||
},
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
print("bedrock response")
|
||||
print(response)
|
||||
|
||||
|
||||
def test_bedrock_tools_pt_valid_names():
|
||||
"""
|
||||
# related issue: https://github.com/BerriAI/litellm/issues/5007
|
||||
# Bedrock tool names must satisfy regular expression pattern: [a-zA-Z][a-zA-Z0-9_]* ensure this is true
|
||||
|
||||
"""
|
||||
tools = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "get_current_weather",
|
||||
"description": "Get the current weather",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"location": {"type": "string"},
|
||||
},
|
||||
"required": ["location"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "search_restaurants",
|
||||
"description": "Search for restaurants",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cuisine": {"type": "string"},
|
||||
},
|
||||
"required": ["cuisine"],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
result = _bedrock_tools_pt(tools)
|
||||
|
||||
assert len(result) == 2
|
||||
assert result[0]["toolSpec"]["name"] == "get_current_weather"
|
||||
assert result[1]["toolSpec"]["name"] == "search_restaurants"
|
||||
|
||||
|
||||
def test_bedrock_tools_pt_invalid_names():
|
||||
"""
|
||||
# related issue: https://github.com/BerriAI/litellm/issues/5007
|
||||
# Bedrock tool names must satisfy regular expression pattern: [a-zA-Z][a-zA-Z0-9_]* ensure this is true
|
||||
|
||||
"""
|
||||
|
||||
tools = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "123-invalid@name",
|
||||
"description": "Invalid name test",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"test": {"type": "string"},
|
||||
},
|
||||
"required": ["test"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "another@invalid#name",
|
||||
"description": "Another invalid name test",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"test": {"type": "string"},
|
||||
},
|
||||
"required": ["test"],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
result = _bedrock_tools_pt(tools)
|
||||
|
||||
print("bedrock tools after prompt formatting=", result)
|
||||
|
||||
assert len(result) == 2
|
||||
assert result[0]["toolSpec"]["name"] == "a123_invalid_name"
|
||||
assert result[1]["toolSpec"]["name"] == "another_invalid_name"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue