fix(agent): also send chat_template_kwargs.enable_thinking=false for llama.cpp/vLLM - #12427
Conversation
…llama.cpp/vLLM The custom-provider thinking opt-out at run_agent.py only sets extra_body.think=false, which is Ollama's field. llama.cpp and vLLM ignore `think` and look for `chat_template_kwargs.enable_thinking`. As a result, setting `agent.reasoning_effort: none` on a custom provider pointed at llama.cpp or vLLM has no effect: thinking-capable models (Qwen3, etc.) still emit <think> blocks, and any subsequent assistant- prefill turn (e.g. Hermes' thinking-only continuation path) hits llama.cpp's prefill-incompatibility 400. Send both fields. Backends ignore unknown body fields by convention, so this is additive for Ollama. Tests added alongside the existing custom-provider think tests.
Also add test coverage for reasoning_config.effort="none" path, which upstream PR NousResearch#12427 handles but we missed in the initial implementation.
|
Confirming this bug still bites on current 1. The target moved — this PR is now stale against The # plugins/model-providers/custom/__init__.py (build_api_kwargs_extras)
if _effort == "none" or _enabled is False:
extra_body["think"] = False # ← Ollama-only flag; vLLM/llama.cpp ignore it
elif _effort:
top_level["reasoning_effort"] = _effortSo the exact bug this PR describes is intact — a 2. Suggest making it backend-aware, to resolve the tension with The Sending A backend-aware split satisfies both camps: server_type = detect_local_server_type(base_url) if base_url else None
if _effort == "none" or _enabled is False:
extra_body["think"] = False # Ollama
if server_type in ("vllm", "llamacpp"):
extra_body["chat_template_kwargs"] = {"enable_thinking": False} # vLLM/llama.cpp
elif _effort:
top_level["reasoning_effort"] = _effort # GLM/ARK etc. unchangedScope: this addresses the disable path ( Good news on feasibility: no plumbing change is needed. The transport already passes One caveat worth a test: vLLM issues #35574 and #17357 show 3. How this sits next to the There's a parallel line of work making a
So this belongs in the profile regardless of where the passthrough lands. The enable-path piece I scoped out above (effort clamping + One adjacent gotcha to flag, not block on: #34027 (closed not_planned) documents that Happy to help with the rebase to the profile method + a |
|
Thanks for identifying the vLLM/llama.cpp reasoning-disable gap. The issue remains on current main, but the implementation has moved. Problems
Suggested changes
Automated hermes-sweeper review. |
What does this PR do?
The custom-provider thinking opt-out in
_build_api_kwargsonly setsextra_body.think=false, which is Ollama's field.llama-serverand vLLM ignorethinkand look forchat_template_kwargs.enable_thinkinginstead.Net effect: setting
agent.reasoning_effort: noneon a custom provider pointed at llama.cpp / vLLM has no effect. Thinking-capable models (Qwen3, etc.) still emit<think>blocks, and any subsequent assistant-prefill turn (including Hermes' own thinking-only continuation path inrun_agent.py) hits llama.cpp's prefill-incompatibility 400:The fix sends both fields. Different OpenAI-compat backends use different keys and ignore unknown body fields by convention, so adding
chat_template_kwargs.enable_thinkingis additive for Ollama.Related Issue
No issue filed; this is a small, surgical fix to behaviour added in the same block.
Type of Change
Changes Made
run_agent.py: also setextra_body["chat_template_kwargs"]["enable_thinking"] = Falsewhen the existing custom-provider opt-out fires. Updated the surrounding comment.tests/run_agent/test_run_agent.py: 3 new tests next to the existingtest_ollama_think_*cluster covering both the on-paths and the negative case.How to Test
Reproduction against llama.cpp
b8808-408225bb1with Qwen3-14B (Bartowski GGUF):Test suite:
Checklist
Code
fix(agent):)b8808-408225bb1(remote) + Qwen3-14B Q4_K_MDocumentation & Housekeeping
Notes for reviewers
chat_template_kwargs).chat_template_kwargsco-present, but it's an unknown OpenAI-extension field so should be ignored. Happy to gate by base URL if you'd prefer a more conservative landing.