fix: treat reasoning_effort="none" as thinking disabled and route gemma to Gemini provider
- Do not send reasoning_effort="none" to APIs (prevents 400 on gemma/Gemini) - Treat "none" as thinking disabled in thinking_style, Kimi, and reasoning_content backfill paths - Fix Anthropic extended thinking not respecting "none" - Fix Azure OpenAI temperature suppression and reasoning body for "none" - Fix Codex reasoning body for "none" - Add "gemma" keyword to Gemini ProviderSpec for correct auto routing
This commit is contained in:
@@ -434,7 +434,7 @@ class AnthropicProvider(LLMProvider):
|
|||||||
)
|
)
|
||||||
|
|
||||||
max_tokens = max(1, max_tokens)
|
max_tokens = max(1, max_tokens)
|
||||||
thinking_enabled = bool(reasoning_effort)
|
thinking_enabled = bool(reasoning_effort) and reasoning_effort.lower() != "none"
|
||||||
|
|
||||||
# claude-opus-4-7 deprecated the `temperature` parameter entirely — the
|
# claude-opus-4-7 deprecated the `temperature` parameter entirely — the
|
||||||
# API returns 400 if it is present, on any code path.
|
# API returns 400 if it is present, on any code path.
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class AzureOpenAIProvider(LLMProvider):
|
|||||||
reasoning_effort: str | None = None,
|
reasoning_effort: str | None = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Return True when temperature is likely supported for this deployment."""
|
"""Return True when temperature is likely supported for this deployment."""
|
||||||
if reasoning_effort:
|
if reasoning_effort and reasoning_effort.lower() != "none":
|
||||||
return False
|
return False
|
||||||
name = deployment_name.lower()
|
name = deployment_name.lower()
|
||||||
return not any(token in name for token in ("gpt-5", "o1", "o3", "o4"))
|
return not any(token in name for token in ("gpt-5", "o1", "o3", "o4"))
|
||||||
@@ -102,7 +102,7 @@ class AzureOpenAIProvider(LLMProvider):
|
|||||||
if self._supports_temperature(deployment, reasoning_effort):
|
if self._supports_temperature(deployment, reasoning_effort):
|
||||||
body["temperature"] = temperature
|
body["temperature"] = temperature
|
||||||
|
|
||||||
if reasoning_effort:
|
if reasoning_effort and reasoning_effort.lower() != "none":
|
||||||
body["reasoning"] = {"effort": reasoning_effort}
|
body["reasoning"] = {"effort": reasoning_effort}
|
||||||
body["include"] = ["reasoning.encrypted_content"]
|
body["include"] = ["reasoning.encrypted_content"]
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class OpenAICodexProvider(LLMProvider):
|
|||||||
"tool_choice": tool_choice or "auto",
|
"tool_choice": tool_choice or "auto",
|
||||||
"parallel_tool_calls": True,
|
"parallel_tool_calls": True,
|
||||||
}
|
}
|
||||||
if reasoning_effort:
|
if reasoning_effort and reasoning_effort.lower() != "none":
|
||||||
body["reasoning"] = {"effort": reasoning_effort}
|
body["reasoning"] = {"effort": reasoning_effort}
|
||||||
if tools:
|
if tools:
|
||||||
body["tools"] = convert_tools(tools)
|
body["tools"] = convert_tools(tools)
|
||||||
|
|||||||
@@ -570,7 +570,7 @@ class OpenAICompatProvider(LLMProvider):
|
|||||||
# DashScope accepts none/minimum/low/medium/high/xhigh; "minimal" 400s.
|
# DashScope accepts none/minimum/low/medium/high/xhigh; "minimal" 400s.
|
||||||
wire_effort = "minimum"
|
wire_effort = "minimum"
|
||||||
|
|
||||||
if wire_effort:
|
if wire_effort and semantic_effort != "none":
|
||||||
kwargs["reasoning_effort"] = wire_effort
|
kwargs["reasoning_effort"] = wire_effort
|
||||||
|
|
||||||
# Provider-specific thinking parameters.
|
# Provider-specific thinking parameters.
|
||||||
@@ -579,7 +579,7 @@ class OpenAICompatProvider(LLMProvider):
|
|||||||
# The mapping is driven by ProviderSpec.thinking_style so that adding
|
# The mapping is driven by ProviderSpec.thinking_style so that adding
|
||||||
# a new provider never requires touching this function.
|
# a new provider never requires touching this function.
|
||||||
if spec and spec.thinking_style and reasoning_effort is not None:
|
if spec and spec.thinking_style and reasoning_effort is not None:
|
||||||
thinking_enabled = semantic_effort != "minimal"
|
thinking_enabled = semantic_effort not in ("none", "minimal")
|
||||||
extra = _THINKING_STYLE_MAP.get(spec.thinking_style, lambda _: None)(thinking_enabled)
|
extra = _THINKING_STYLE_MAP.get(spec.thinking_style, lambda _: None)(thinking_enabled)
|
||||||
if extra:
|
if extra:
|
||||||
kwargs.setdefault("extra_body", {}).update(extra)
|
kwargs.setdefault("extra_body", {}).update(extra)
|
||||||
@@ -589,7 +589,7 @@ class OpenAICompatProvider(LLMProvider):
|
|||||||
# so that OpenRouter-style names like "moonshotai/kimi-k2.5" are handled
|
# so that OpenRouter-style names like "moonshotai/kimi-k2.5" are handled
|
||||||
# identically to bare names like "kimi-k2.5".
|
# identically to bare names like "kimi-k2.5".
|
||||||
if reasoning_effort is not None and _is_kimi_thinking_model(model_name):
|
if reasoning_effort is not None and _is_kimi_thinking_model(model_name):
|
||||||
thinking_enabled = semantic_effort != "minimal"
|
thinking_enabled = semantic_effort not in ("none", "minimal")
|
||||||
kwargs.setdefault("extra_body", {}).update(
|
kwargs.setdefault("extra_body", {}).update(
|
||||||
{"thinking": {"type": "enabled" if thinking_enabled else "disabled"}}
|
{"thinking": {"type": "enabled" if thinking_enabled else "disabled"}}
|
||||||
)
|
)
|
||||||
@@ -609,9 +609,9 @@ class OpenAICompatProvider(LLMProvider):
|
|||||||
# thinking happened on that turn").
|
# thinking happened on that turn").
|
||||||
thinking_active = (
|
thinking_active = (
|
||||||
(spec and spec.thinking_style and reasoning_effort is not None
|
(spec and spec.thinking_style and reasoning_effort is not None
|
||||||
and semantic_effort != "minimal")
|
and semantic_effort not in ("none", "minimal"))
|
||||||
or (reasoning_effort is not None and _is_kimi_thinking_model(model_name)
|
or (reasoning_effort is not None and _is_kimi_thinking_model(model_name)
|
||||||
and semantic_effort != "minimal")
|
and semantic_effort not in ("none", "minimal"))
|
||||||
)
|
)
|
||||||
if thinking_active:
|
if thinking_active:
|
||||||
for msg in kwargs["messages"]:
|
for msg in kwargs["messages"]:
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ PROVIDERS: tuple[ProviderSpec, ...] = (
|
|||||||
# Gemini: Google's OpenAI-compatible endpoint
|
# Gemini: Google's OpenAI-compatible endpoint
|
||||||
ProviderSpec(
|
ProviderSpec(
|
||||||
name="gemini",
|
name="gemini",
|
||||||
keywords=("gemini",),
|
keywords=("gemini", "gemma"),
|
||||||
env_key="GEMINI_API_KEY",
|
env_key="GEMINI_API_KEY",
|
||||||
display_name="Gemini",
|
display_name="Gemini",
|
||||||
backend="openai_compat",
|
backend="openai_compat",
|
||||||
|
|||||||
Reference in New Issue
Block a user