feat(ollama): pass think=false to custom providers when reasoning_effort is none
When a custom/Ollama provider is used and reasoning_effort is set to 'none' (or enabled: false), inject 'think': false into the request extra_body. Ollama does not recognise the OpenRouter-style 'reasoning' extra_body field, so thinking-capable models (Qwen3, etc.) generate <think> blocks regardless of the reasoning_effort setting. This produces empty-response errors that corrupt session state. The fix adds a provider-specific block in _build_api_kwargs() that sets think=false in extra_body whenever self.provider == 'custom' and reasoning is explicitly disabled. Closes #3191
This commit is contained in:
parent
8011aa31ba
commit
3522a7aa13
12
run_agent.py
12
run_agent.py
@ -6688,6 +6688,18 @@ class AIAgent:
|
|||||||
options["num_ctx"] = self._ollama_num_ctx
|
options["num_ctx"] = self._ollama_num_ctx
|
||||||
extra_body["options"] = options
|
extra_body["options"] = options
|
||||||
|
|
||||||
|
# Ollama / custom provider: pass think=false when reasoning is disabled.
|
||||||
|
# Ollama does not recognise the OpenRouter-style `reasoning` extra_body
|
||||||
|
# field, so we use its native `think` parameter instead.
|
||||||
|
# This prevents thinking-capable models (Qwen3, etc.) from generating
|
||||||
|
# <think> blocks and producing empty-response errors when the user has
|
||||||
|
# set reasoning_effort: none.
|
||||||
|
if self.provider == "custom" and self.reasoning_config and isinstance(self.reasoning_config, dict):
|
||||||
|
_effort = (self.reasoning_config.get("effort") or "").strip().lower()
|
||||||
|
_enabled = self.reasoning_config.get("enabled", True)
|
||||||
|
if _effort == "none" or _enabled is False:
|
||||||
|
extra_body["think"] = False
|
||||||
|
|
||||||
if self._is_qwen_portal():
|
if self._is_qwen_portal():
|
||||||
extra_body["vl_high_resolution_images"] = True
|
extra_body["vl_high_resolution_images"] = True
|
||||||
|
|
||||||
|
|||||||
@ -928,6 +928,7 @@ class TestBuildApiKwargs:
|
|||||||
kwargs = agent._build_api_kwargs(messages)
|
kwargs = agent._build_api_kwargs(messages)
|
||||||
assert kwargs["max_tokens"] == 4096
|
assert kwargs["max_tokens"] == 4096
|
||||||
|
|
||||||
|
|
||||||
def test_qwen_portal_formats_messages_and_metadata(self, agent):
|
def test_qwen_portal_formats_messages_and_metadata(self, agent):
|
||||||
agent.base_url = "https://portal.qwen.ai/v1"
|
agent.base_url = "https://portal.qwen.ai/v1"
|
||||||
agent._base_url_lower = agent.base_url.lower()
|
agent._base_url_lower = agent.base_url.lower()
|
||||||
@ -983,6 +984,46 @@ class TestBuildApiKwargs:
|
|||||||
messages = [{"role": "system", "content": "sys"}, {"role": "user", "content": "hi"}]
|
messages = [{"role": "system", "content": "sys"}, {"role": "user", "content": "hi"}]
|
||||||
kwargs = agent._build_api_kwargs(messages)
|
kwargs = agent._build_api_kwargs(messages)
|
||||||
assert kwargs["max_tokens"] == 65536
|
assert kwargs["max_tokens"] == 65536
|
||||||
|
=======
|
||||||
|
def test_ollama_think_false_on_effort_none(self, agent):
|
||||||
|
"""Custom (Ollama) provider with effort=none should inject think=false."""
|
||||||
|
agent.provider = "custom"
|
||||||
|
agent.base_url = "http://localhost:11434/v1"
|
||||||
|
agent._base_url_lower = agent.base_url.lower()
|
||||||
|
agent.reasoning_config = {"effort": "none"}
|
||||||
|
messages = [{"role": "user", "content": "hi"}]
|
||||||
|
kwargs = agent._build_api_kwargs(messages)
|
||||||
|
assert kwargs.get("extra_body", {}).get("think") is False
|
||||||
|
|
||||||
|
def test_ollama_think_false_on_enabled_false(self, agent):
|
||||||
|
"""Custom (Ollama) provider with enabled=false should inject think=false."""
|
||||||
|
agent.provider = "custom"
|
||||||
|
agent.base_url = "http://localhost:11434/v1"
|
||||||
|
agent._base_url_lower = agent.base_url.lower()
|
||||||
|
agent.reasoning_config = {"enabled": False}
|
||||||
|
messages = [{"role": "user", "content": "hi"}]
|
||||||
|
kwargs = agent._build_api_kwargs(messages)
|
||||||
|
assert kwargs.get("extra_body", {}).get("think") is False
|
||||||
|
|
||||||
|
def test_ollama_no_think_param_when_reasoning_enabled(self, agent):
|
||||||
|
"""Custom provider with reasoning enabled should NOT inject think=false."""
|
||||||
|
agent.provider = "custom"
|
||||||
|
agent.base_url = "http://localhost:11434/v1"
|
||||||
|
agent._base_url_lower = agent.base_url.lower()
|
||||||
|
agent.reasoning_config = {"enabled": True, "effort": "medium"}
|
||||||
|
messages = [{"role": "user", "content": "hi"}]
|
||||||
|
kwargs = agent._build_api_kwargs(messages)
|
||||||
|
assert kwargs.get("extra_body", {}).get("think") is None
|
||||||
|
|
||||||
|
def test_non_custom_provider_unaffected(self, agent):
|
||||||
|
"""OpenRouter provider with effort=none should NOT inject think=false."""
|
||||||
|
agent.provider = "openrouter"
|
||||||
|
agent.model = "qwen/qwen3.5-plus-02-15"
|
||||||
|
agent.reasoning_config = {"effort": "none"}
|
||||||
|
messages = [{"role": "user", "content": "hi"}]
|
||||||
|
kwargs = agent._build_api_kwargs(messages)
|
||||||
|
assert kwargs.get("extra_body", {}).get("think") is None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestBuildAssistantMessage:
|
class TestBuildAssistantMessage:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user