Skip to content

fix: send think: false in Ollama API requests to prevent empty responses from thinking models (closes #46680)#46994

Closed
Br1an67 wants to merge 1 commit intoopenclaw:mainfrom
Br1an67:fix/46680
Closed

fix: send think: false in Ollama API requests to prevent empty responses from thinking models (closes #46680)#46994
Br1an67 wants to merge 1 commit intoopenclaw:mainfrom
Br1an67:fix/46680

Conversation

@Br1an67
Copy link
Copy Markdown
Contributor

@Br1an67 Br1an67 commented Mar 15, 2026

Summary

  • Problem: Ollama 0.18+ thinking-capable models (qwen3.5, kimi-k2.5, glm-5) produce empty responses because they spend their output budget on thinking tokens. OpenClaw only reads message.content, so when all output goes to the thinking field, the response appears empty.
  • Why it matters: All thinking-capable Ollama models silently produce empty responses in subagents, causing "failed to produce results" errors.
  • What changed: Added think field to OllamaChatRequest interface. The request body now explicitly sends think: false by default, and think: true when the user has requested reasoning via options.reasoning.
  • What did NOT change (scope boundary): No changes to response parsing, message conversion, or non-Ollama providers.

Change Type

  • Bug fix

Scope

  • Skills / tool execution

Linked Issue/PR

User-visible / Behavior Changes

Ollama thinking-capable models now produce actual text/tool_call responses instead of empty content. When reasoning is explicitly requested, thinking is enabled.

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No (same endpoint, additional body field)
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Steps

  1. Run Ollama 0.18 with a thinking-capable model (e.g. qwen3.5:35b)
  2. Spawn a subagent on ollama/qwen3.5:35b

Expected

  • Subagent returns actual content

Actual (before fix)

  • Subagent returns empty — all tokens spent on thinking field

Evidence

  • Failing test/log before + passing after
  • All 33 ollama-stream tests passing (including 2 new tests for think: false/true)

Human Verification

  • Verified scenarios: Default think: false, reasoning-enabled think: true; all existing tests still pass
  • Edge cases checked: Non-thinking models safely ignore the think field; empty reasoning option defaults to false
  • What you did NOT verify: runtime end-to-end testing with actual Ollama server

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery

  • How to disable/revert: revert this commit

Risks and Mitigations

None

@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: XS labels Mar 15, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 15, 2026

Greptile Summary

This PR fixes a silent empty-response bug with Ollama 0.18+ thinking-capable models (e.g. qwen3.5, kimi-k2.5) by adding a think boolean field to OllamaChatRequest and including it in every API request. The field defaults to false so thinking tokens don't consume the entire output budget, and is set to true when the caller explicitly requests reasoning via options.reasoning.

Key observations:

  • Correct default behaviour: think: false is always sent, suppressing thinking mode for models that enable it by default — this directly fixes the empty-response issue described in Ollama thinking models produce empty responses — think: false not sent in API requests #46680.
  • Reasoning path: !!options?.reasoning correctly evaluates to true for any active thinking level ("low", "medium", "high", "xhigh") because resolveSimpleThinkingLevel converts "off"undefined before reaching this code. However, the check is fragile: a caller passing reasoning: "off" directly would still send think: true since "off" is a truthy string.
  • Backward compatibility: Sending think: false to non-thinking models or older Ollama versions that don't recognise the field is expected to be safe (unknown fields are typically ignored). The PR author confirmed non-thinking models safely ignore the field.
  • Test coverage: Two new unit tests validate both the default-off and reasoning-enabled paths by inspecting the serialised request body.

Confidence Score: 4/5

  • This PR is safe to merge; it targets a narrow, well-tested bug with no changes outside the Ollama stream path.
  • The change is minimal and surgical: two lines of production code plus two new tests. The core logic is correct for all realistic call paths. The one edge case (a literal "off" string reaching the truthy check) is a low-risk latent issue, not a regression, and the existing test suite still fully passes.
  • No files require special attention; the single style concern is in src/agents/ollama-stream.ts line 465.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/ollama-stream.ts
Line: 465

Comment:
**Truthy check passes `think: true` when `reasoning` is `"off"`**

`!!options?.reasoning` is `true` for any non-empty string, including `"off"`. If a caller ever passes `options.reasoning = "off"` directly (bypassing `resolveSimpleThinkingLevel`), the request will incorrectly enable thinking mode.

In the current codebase this doesn't happen because `resolveSimpleThinkingLevel` converts `"off"``undefined`, but it's a fragile invariant. A more defensive guard would be explicit:

```suggestion
        const ollamaThink = typeof options?.reasoning === "string" && options.reasoning !== "off";
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: b2c9474

// Ollama 0.18+ thinking-capable models (qwen3.5, kimi-k2.5, etc.)
// default to producing thinking tokens which consumes the output budget.
// Explicitly send think: false unless the user requested reasoning.
const ollamaThink = !!options?.reasoning;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Truthy check passes think: true when reasoning is "off"

!!options?.reasoning is true for any non-empty string, including "off". If a caller ever passes options.reasoning = "off" directly (bypassing resolveSimpleThinkingLevel), the request will incorrectly enable thinking mode.

In the current codebase this doesn't happen because resolveSimpleThinkingLevel converts "off"undefined, but it's a fragile invariant. A more defensive guard would be explicit:

Suggested change
const ollamaThink = !!options?.reasoning;
const ollamaThink = typeof options?.reasoning === "string" && options.reasoning !== "off";
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/ollama-stream.ts
Line: 465

Comment:
**Truthy check passes `think: true` when `reasoning` is `"off"`**

`!!options?.reasoning` is `true` for any non-empty string, including `"off"`. If a caller ever passes `options.reasoning = "off"` directly (bypassing `resolveSimpleThinkingLevel`), the request will incorrectly enable thinking mode.

In the current codebase this doesn't happen because `resolveSimpleThinkingLevel` converts `"off"``undefined`, but it's a fragile invariant. A more defensive guard would be explicit:

```suggestion
        const ollamaThink = typeof options?.reasoning === "string" && options.reasoning !== "off";
```

How can I resolve this? If you propose a fix, please make it concise.

xuwei-xy pushed a commit to xuwei-xy/openclaw that referenced this pull request Mar 15, 2026
@Br1an67
Copy link
Copy Markdown
Contributor Author

Br1an67 commented Mar 17, 2026

Closing to manage active PR count. Will reopen when slot is available.

@Br1an67 Br1an67 closed this Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ollama thinking models produce empty responses — think: false not sent in API requests

1 participant