fix: use string tool_choice for Groq and OpenRouter (#9267)
Some providers (Groq, OpenRouter proxied providers) only support string
values for tool_choice ("none", "auto", "required"), not the object
format {"type": "function", "name": "..."}.
When force_tool_call is set, convert to "required" instead of object
format for these providers.
🤖 Generated with [Letta Code](https://letta.com)
Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
@@ -34,6 +34,11 @@ class GroqClient(OpenAIClient):
|
||||
) -> dict:
|
||||
data = super().build_request_data(agent_type, messages, llm_config, tools, force_tool_call, requires_subsequent_tool_call)
|
||||
|
||||
# Groq only supports string values for tool_choice: "none", "auto", "required"
|
||||
# Convert object-format tool_choice (used for force_tool_call) to "required"
|
||||
if "tool_choice" in data and isinstance(data["tool_choice"], dict):
|
||||
data["tool_choice"] = "required"
|
||||
|
||||
# Groq validation - these fields are not supported and will cause 400 errors
|
||||
# https://console.groq.com/docs/openai
|
||||
if "top_logprobs" in data:
|
||||
|
||||
@@ -468,7 +468,12 @@ class OpenAIClient(LLMClientBase):
|
||||
tool_choice = None
|
||||
if tools: # only set tool_choice if tools exist
|
||||
if force_tool_call is not None:
|
||||
tool_choice = ToolFunctionChoice(type="function", function=ToolFunctionChoiceFunctionCall(name=force_tool_call))
|
||||
# OpenRouter proxies to providers that may not support object-format tool_choice
|
||||
# Use "required" instead which achieves similar effect
|
||||
if is_openrouter:
|
||||
tool_choice = "required"
|
||||
else:
|
||||
tool_choice = ToolFunctionChoice(type="function", function=ToolFunctionChoiceFunctionCall(name=force_tool_call))
|
||||
elif requires_subsequent_tool_call:
|
||||
tool_choice = "required"
|
||||
elif self.requires_auto_tool_choice(llm_config) or agent_type == AgentType.letta_v1_agent:
|
||||
|
||||
Reference in New Issue
Block a user