mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix(snowflake): transform string tool_choice to object format (#23318)
Snowflake's Cortex LLM API (like Anthropic) requires tool_choice as an
object with a "type" field, not as a bare string. Passing tool_choice="auto"
(or "required"/"none") results in error 390142 "invalid payload".
This fix transforms OpenAI string tool_choice values to the Snowflake
object format:
- "auto" -> {"type": "auto"}
- "required" -> {"type": "any"} (Snowflake/Anthropic convention)
- "none" -> {"type": "none"}
The dict-to-dict transformation for specific function tool choices
({"type": "function", "function": {"name": "..."}} -> {"type": "tool",
"name": [...]}) remains unchanged.
Fixes #23284
Co-authored-by: gambletan <tan@echooo.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
This commit is contained in:
parent
b0aa71ed9b
commit
2b7b7d3086
2 changed files with 36 additions and 12 deletions
|
|
@ -219,17 +219,32 @@ class SnowflakeConfig(SnowflakeBaseConfig, OpenAIGPTConfig):
|
|||
tool_choice: Tool choice in OpenAI format (str or dict)
|
||||
|
||||
Returns:
|
||||
Tool choice in Snowflake format (always an object)
|
||||
Tool choice in Snowflake format (always an object, never a string)
|
||||
|
||||
OpenAI format (string): "auto", "required", "none"
|
||||
OpenAI format (object): {"type": "function", "function": {"name": "get_weather"}}
|
||||
OpenAI format (string):
|
||||
"auto", "required", "none"
|
||||
|
||||
Snowflake format (string values become objects): {"type": "auto"}
|
||||
Snowflake format (specific tool): {"type": "tool", "name": ["get_weather"]}
|
||||
OpenAI format (dict):
|
||||
{"type": "function", "function": {"name": "get_weather"}}
|
||||
|
||||
Snowflake format:
|
||||
{"type": "auto"} / {"type": "any"} / {"type": "none"}
|
||||
{"type": "tool", "name": ["get_weather"]}
|
||||
|
||||
Snowflake's API (like Anthropic) requires tool_choice as an object
|
||||
with a "type" field, not as a bare string.
|
||||
"""
|
||||
if isinstance(tool_choice, str):
|
||||
# Snowflake requires object format: {"type": "auto"} not string "auto"
|
||||
return {"type": tool_choice}
|
||||
# Snowflake requires object format, not string.
|
||||
# Map OpenAI string values to Snowflake object format.
|
||||
# "required" maps to "any" (Snowflake/Anthropic convention).
|
||||
_type_map = {
|
||||
"auto": "auto",
|
||||
"required": "any",
|
||||
"none": "none",
|
||||
}
|
||||
mapped_type = _type_map.get(tool_choice, tool_choice)
|
||||
return {"type": mapped_type}
|
||||
|
||||
if isinstance(tool_choice, dict):
|
||||
if tool_choice.get("type") == "function":
|
||||
|
|
|
|||
|
|
@ -107,12 +107,19 @@ class TestSnowflakeToolTransformation:
|
|||
"""
|
||||
Test that string tool_choice values are transformed to Snowflake object format.
|
||||
|
||||
Snowflake requires tool_choice to be an object, not a string.
|
||||
Ref: https://docs.snowflake.com/en/developer-guide/snowflake-rest-api/reference/cortex-inference#post--api-v2-cortex-inference-complete-req-body-schema
|
||||
Snowflake's API (like Anthropic) requires tool_choice as an object
|
||||
with a "type" field, not as a bare string. OpenAI's "required" maps
|
||||
to Snowflake's "any".
|
||||
"""
|
||||
config = SnowflakeConfig()
|
||||
|
||||
for value in ["auto", "required", "none"]:
|
||||
expected_mappings = {
|
||||
"auto": {"type": "auto"},
|
||||
"required": {"type": "any"},
|
||||
"none": {"type": "none"},
|
||||
}
|
||||
|
||||
for value, expected in expected_mappings.items():
|
||||
optional_params = {"tool_choice": value}
|
||||
|
||||
transformed_request = config.transform_request(
|
||||
|
|
@ -123,8 +130,10 @@ class TestSnowflakeToolTransformation:
|
|||
headers={},
|
||||
)
|
||||
|
||||
# Snowflake requires object format: {"type": "auto"} not string "auto"
|
||||
assert transformed_request["tool_choice"] == {"type": value}
|
||||
assert transformed_request["tool_choice"] == expected, (
|
||||
f"tool_choice='{value}' should be transformed to {expected}, "
|
||||
f"got {transformed_request['tool_choice']}"
|
||||
)
|
||||
|
||||
def test_transform_response_with_tool_calls(self):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue