Skip to content

Thinking not suppressed for Qwen3/Gemma via Ollama /v1 endpoint (think ignored, needs reasoning_effort) #5707

Description

@bernard-hossmoto

Prerequisites

  • I searched open issues and discussions and did not find an existing report of this bug.
  • This is not a security vulnerability. (Vulnerabilities go to GitHub Security Advisories — see SECURITY.md.)
  • I am running the latest code from the dev branch (the default branch you get on clone, where fixes land first) and the bug still reproduces there. Please git pull the latest dev before filing.

Install Method

macOS app (build-macos-app.sh / start-macos.sh)

Operating System

macOS

Steps to Reproduce

  1. Configure an Ollama endpoint as http://localhost:11434/v1 (correctly detected as Ollama OpenAI-compat).
  2. Select a Qwen3 model (e.g. qwen3.5:4b) and send any chat message. Odysseus injects its own prompt_security system prompt, which overrides any SYSTEM /no_think baked into the Modelfile — so the Modelfile switch can't be relied on.
  3. Observe: the model reasons without end; the reply never arrives, or arrives with empty content.

Expected Behaviour

Thinking is suppressed for Qwen3/Gemma over the Ollama /v1 endpoint (as intended by the existing payload["think"] = False), and a normal answer is returned promptly.

Actual Behaviour

Thinking is never disabled. Ollama's /v1 (OpenAI-compatible) endpoint ignores a top-level think field — it only honors the OpenAI-standard reasoning_effort. The model reasons endlessly (no answer), or returns the answer in reasoning_content with empty content.

Root cause — src/llm_core.py, both the streaming (stream_llm) and non-streaming (llm_call) OpenAI paths:

if _is_ollama_openai_compat_url(url) and _supports_thinking(model):
    payload["think"] = False

The inline comment ("Ollama /v1 accepts "think": false as a top-level param.") is no longer accurate for current Ollama.

Proposed fix — also send the OpenAI-standard field, in BOTH occurrences:

if _is_ollama_openai_compat_url(url) and _supports_thinking(model):
    payload["think"] = False
    payload["reasoning_effort"] = "none"

Optional: the native builder _build_ollama_payload never sets think, so the native /api/chat transport also leaves thinking on; adding think=False there for _supports_thinking(model) would align both transports.

Logs / Screenshots

Direct API calls against Ollama 0.32.1, identical model + prompt:

| Transport            | Param                             | Result                                        |
|----------------------|-----------------------------------|-----------------------------------------------|
| Native /api/chat     | think: false                      | thinking empty, content present (~1s) — OK    |
| /v1/chat/completions | think: false                      | reasons endlessly / hangs (param ignored)     |
| /v1/chat/completions | reasoning_effort: "none"          | reasoning_content empty, content present — OK |
| /v1/chat/completions | reasoning_effort: "low"/"minimal" | not honored / empty                           |

Model / Backend (if relevant)

Ollama 0.32.1 + qwen3.5:4b (and num_ctx variants), via OpenAI-compatible /v1 endpoint. Uses Ollama's newer RENDERER qwen3.5 / PARSER qwen3.5 format.

Are you willing to submit a fix?

No — I am only filing the report

Additional Information

Odysseus v1.0.2 (9844a2f). Tested on v1.0.2; confirmed the same code path is unchanged on dev at time of filing (still only sets think, no reasoning_effort).

Related upstream (root cause on the Ollama side): ollama/ollama #15288 and #15293 (OpenAI endpoint not forwarding think).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingready for reviewDescription complete — ready for maintainer review

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions