Bug
When using Ollama models with native thinking support (e.g. qwen3.5:9b), OpenClaw does not send think: false in the Ollama API request even when thinking: "off" is configured. Without think: false, the model puts its response in the thinking field instead of content. OpenClaw drops thinking blocks and users see empty responses.
Version
- OpenClaw: 2026.3.13
- Ollama: latest (March 2026)
- Model: qwen3.5:9b (any thinking-capable model)
Root Cause Analysis
Location: src/agents/ollama-stream.ts — createOllamaStreamFn()
The root cause is in the run() async function where the Ollama API request body is constructed. Around lines 300-310, the ollamaOptions object is built but the think parameter is never included:
const ollamaOptions: Record<string, unknown> = { num_ctx: model.contextWindow ?? 65536 };
if (typeof options?.temperature === "number") {
ollamaOptions.temperature = options.temperature;
}
if (typeof options?.maxTokens === "number") {
ollamaOptions.num_predict = options.maxTokens;
}
const body: OllamaChatRequest = {
model: model.id,
messages: ollamaMessages,
stream: true,
...(ollamaTools.length > 0 ? { tools: ollamaTools } : {}),
options: ollamaOptions,
};
The problem: The think parameter is never added to ollamaOptions. Ollama thinking models interpret the absence of think as "use default behavior" — which means think=true (thinking enabled). When the user sets thinking: "off", this preference is never transmitted to the Ollama API.
The fallback in buildAssistantMessage() (which tries response.message.content || response.message.thinking || response.message.reasoning) is insufficient in streaming mode because Ollama sends intermediate chunks with thinking content that may not be properly accumulated.
Reproduction Steps
- Configure OpenClaw with Ollama provider using a thinking model (qwen3.5:9b) with
thinking: "off"
- Send a message that does not trigger tool use
- Observe: response is empty
- Verify with curl that without
think:false, Ollama returns content:"" and thinking:"actual answer"
Proposed Fix
In createOllamaStreamFn(), add think to ollamaOptions based on thinkingLevel:
// Determine if thinking should be disabled
const isThinkingModel = /qwen3|thinking|r1|reasoning/i.test(model.id);
const thinkingLevel = options?.thinkingLevel;
const shouldDisableThinking = !isThinkingModel || thinkingLevel === "off";
if (shouldDisableThinking) {
ollamaOptions.think = false;
}
Note: The options parameter should include thinkingLevel from agent configuration.
Environment
- OS: Linux/macOS/Windows
- OpenClaw: 2026.3.13
- Ollama: latest
- Node.js: 22.x
Bug
When using Ollama models with native thinking support (e.g. qwen3.5:9b), OpenClaw does not send
think: falsein the Ollama API request even whenthinking: "off"is configured. Withoutthink: false, the model puts its response in thethinkingfield instead ofcontent. OpenClaw drops thinking blocks and users see empty responses.Version
Root Cause Analysis
Location:
src/agents/ollama-stream.ts—createOllamaStreamFn()The root cause is in the
run()async function where the Ollama API request body is constructed. Around lines 300-310, theollamaOptionsobject is built but thethinkparameter is never included:The problem: The
thinkparameter is never added toollamaOptions. Ollama thinking models interpret the absence ofthinkas "use default behavior" — which meansthink=true(thinking enabled). When the user setsthinking: "off", this preference is never transmitted to the Ollama API.The fallback in
buildAssistantMessage()(which triesresponse.message.content || response.message.thinking || response.message.reasoning) is insufficient in streaming mode because Ollama sends intermediate chunks withthinkingcontent that may not be properly accumulated.Reproduction Steps
thinking: "off"think:false, Ollama returnscontent:""andthinking:"actual answer"Proposed Fix
In
createOllamaStreamFn(), addthinktoollamaOptionsbased onthinkingLevel:Note: The
optionsparameter should includethinkingLevelfrom agent configuration.Environment