Skip to content

fix(ollama): skip think for non-reasoning models#82445

Merged
steipete merged 4 commits into
openclaw:mainfrom
leno23:fix/80332-ollama-think-options
May 16, 2026
Merged

fix(ollama): skip think for non-reasoning models#82445
steipete merged 4 commits into
openclaw:mainfrom
leno23:fix/80332-ollama-think-options

Conversation

@leno23

@leno23 leno23 commented May 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • avoid forwarding truthy native Ollama think values for models marked reasoning: false
  • keep top-level native Ollama think for reasoning-capable/unknown models
  • keep forwarding think: false so explicit thinking-off requests still work

Closes #80332

Test Plan

  • node scripts/run-vitest.mjs extensions/ollama/src/stream-runtime.test.ts -- -t "non-reasoning"
  • pnpm check:test-types

Real behavior proof

Behavior addressed: native Ollama chat requests for a non-reasoning model no longer include top-level or options-level think, avoiding the error path triggered when such servers reject thinking for that model.

Real environment tested: local OpenClaw Ollama stream runtime on this PR branch, Node 22.18.0, with a local Ollama-compatible HTTP server that returns 400 model does not support thinking if either think field is present.

Exact steps or command run after this patch:

pnpm exec tsx .hermes-ollama-proof.ts

The temporary proof script started a local HTTP server, ran createConfiguredOllamaCompatStreamWrapper + createOllamaStreamFn for model llama3.2:latest with reasoning: false and configured params.thinking: "medium", then consumed the resulting stream.

Evidence after fix:

{"path":"/api/chat","hasTopLevelThink":false,"hasOptionThink":false,"model":"llama3.2:latest","optionsKeys":[]}
{"result":"stream completed","eventTypes":["start","text_start","text_delta","text_end","done"]}

Observed result after fix: the request reached /api/chat without think; the local Ollama-compatible server returned a successful NDJSON stream instead of the 400 rejection branch.

What was not tested: a live Ollama daemon/model was not available in this cron environment (ollama command was not installed), so the proof uses the real OpenClaw native Ollama request path against a local compatibility server rather than a downloaded Ollama model.

Risk/Notes

  • Low-to-medium risk: scoped to native Ollama thinking request shaping.
  • CI currently has unrelated main-branch node shard failures after merging latest upstream main; the Ollama focused test and test typecheck passed locally.

@openclaw-barnacle openclaw-barnacle Bot added extensions: ollama triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. size: S labels May 16, 2026
@clawsweeper

clawsweeper Bot commented May 16, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

Summary
The PR adds an Ollama native think forwarding guard and regression tests, updates the changelog, and switches GitHub Copilot device-login fetches/tests to the SDK SSRF guard.

Reproducibility: yes. Current main source can emit truthy top-level native Ollama think for models represented as reasoning: false, and upstream Ollama rejects truthy req.Think for non-thinking models; I did not run the failing request locally.

Real behavior proof
Sufficient (live_output): The PR body supplies after-fix live output from the real OpenClaw native Ollama stream path against a rejecting loopback server, and maintainer comments add focused latest-head verification.

Next step before merge
No repair lane is needed; the patch has no blocking review findings and remaining work is normal maintainer review plus CI clearance.

Security
Cleared: The diff does not add dependencies, CI permissions, release scripts, or secret exposure, and the GitHub Copilot change replaces raw fixed-endpoint fetches with the existing SSRF guard.

Review details

Best possible solution:

Land this narrow guard, or an equivalent one, after maintainer review and CI clearance while preserving top-level native think for supported or unknown models and explicit think: false.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main source can emit truthy top-level native Ollama think for models represented as reasoning: false, and upstream Ollama rejects truthy req.Think for non-thinking models; I did not run the failing request locally.

Is this the best way to solve the issue?

Yes. Suppressing only truthy think for known non-reasoning models is narrower than moving think into options, because upstream models think as a top-level ChatRequest field and Options has no think member.

What I checked:

  • Live PR state: GitHub REST shows this PR is open, not draft, mergeable, and currently targets main b9921e2 from head ff73e14. (ff73e14638e9)
  • Current main can send top-level Ollama think: Current main's native Ollama wrapper writes payloadRecord.think = think, and configured model params are resolved into top-level requestParams.think. (extensions/ollama/src/stream.ts:239, b9921e21b93d)
  • Current main has the model capability signal the PR uses: Ollama model definitions set reasoning from /api/show capabilities when available, so missing thinking capability becomes reasoning: false. (extensions/ollama/src/provider-models.ts:251, b9921e21b93d)
  • Upstream Ollama contract supports the root cause: Ollama's ChatRequest has top-level Think, and server routing rejects truthy req.Think when the loaded model lacks CapabilityThinking.
  • Upstream options contract does not make options.think the native fix: Upstream Options lists runtime/model options such as temperature, stop, and num_ctx runner fields, but not think; think is modeled separately on ChatRequest.
  • PR implementation: The PR adds shouldForwardNativeOllamaThink, preserving think: false while suppressing truthy think only when model?.reasoning === false, and applies it to configured and runtime thinking paths. (extensions/ollama/src/stream.ts:278, ff73e14638e9)

Likely related people:

  • steipete: Provided maintainer verification on the PR discussion and has recent Ollama SDK/barrel history plus PR-branch commits for changelog and the GitHub Copilot guarded-fetch addition. (role: recent area contributor and verifier; confidence: high; commits: 9917f3b3a10e, a3e73daa6b17, 932248107585; files: extensions/ollama/api.ts, extensions/ollama/runtime-api.ts, src/plugin-sdk/ollama.ts)
  • BruceMacD: Authored the earlier Ollama think=false request-shaping change in the same native stream behavior lineage. (role: introduced related runtime behavior; confidence: medium; commits: 773c57b41882; files: extensions/ollama/src/stream.ts, src/agents/ollama-stream.test.ts, src/agents/pi-embedded-runner/extra-params.ts)
  • yfge: Authored the Ollama thinking profile exposure work that connects model capability/profile metadata to activation behavior. (role: thinking-profile contributor; confidence: medium; commits: 7a9efc138998; files: extensions/ollama/index.ts, extensions/ollama/provider-policy-api.ts, extensions/ollama/provider-policy-api.test.ts)
  • Sunwoo Yu: Introduced the native Ollama /api/chat provider and stream/test surface that this PR changes. (role: native Ollama provider introducer; confidence: medium; commits: 11702290ff80; files: src/agents/ollama-stream.ts, src/agents/ollama-stream.test.ts, docs/providers/ollama.md)

Remaining risk / open question:

  • Latest head still has failing CI checks that should be cleared or confirmed unrelated before merge.
  • The proof uses OpenClaw’s native Ollama request path against a local compatibility server, not a live Ollama daemon/model.
  • The PR includes a GitHub Copilot SSRF-guard fix beyond the Ollama title, so maintainers should intentionally accept that extra scope.

Codex review notes: model gpt-5.5, reasoning high; reviewed against b9921e21b93d.

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 16, 2026
@leno23

leno23 commented May 16, 2026

Copy link
Copy Markdown
Contributor Author

Updated the PR body with real behavior proof and re-ran the proof check.

Verification:

  • node scripts/run-vitest.mjs extensions/ollama/src/stream-runtime.test.ts -- -t "non-reasoning"
  • pnpm check:test-types
  • local Ollama-compatible stream proof: request omitted both top-level and options-level think; stream completed successfully

GitHub Real behavior proof is now green: https://github.com/openclaw/openclaw/actions/runs/25954911080/job/76299733325

Remaining CI failures match current upstream main failures in unrelated cron/gateway/doctor/session shards, not the Ollama plugin surface touched here.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@steipete steipete force-pushed the fix/80332-ollama-think-options branch from 786cc92 to 90a5166 Compare May 16, 2026 13:03
@steipete

Copy link
Copy Markdown
Contributor

Maintainer verification for head 90a51665c53a3ad138d6caba67808c10bbe9802e:

Behavior addressed: Ollama provider no longer forwards truthy native think payloads for models marked reasoning: false, while preserving explicit think: false.
Real environment tested: local OpenClaw checkout on macOS, rebased onto origin/main at f410a95081c8f52f3d3b846b4c8f803664937eb0.
Exact steps or command run after this patch:

  • node scripts/run-vitest.mjs extensions/ollama/src/stream-runtime.test.ts -- -t "non-reasoning"
  • git diff --check
  • codex-review --mode branch --parallel-tests "node scripts/run-vitest.mjs extensions/ollama/src/stream-runtime.test.ts -- -t 'non-reasoning'"
    Evidence after fix: focused Ollama stream runtime test file passed, 79 tests; diff whitespace check passed; codex-review reported no accepted/actionable findings.
    Observed result after fix: configured and runtime thinking settings are omitted from Ollama request payloads when the resolved model declares reasoning: false.
    What was not tested: no live Ollama daemon/model was available in this maintainer checkout; provider behavior is covered by the focused request-payload regression tests and the contributor's loopback rejecting-server proof.

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@steipete steipete force-pushed the fix/80332-ollama-think-options branch from 90a5166 to c91088f Compare May 16, 2026 13:22
@steipete

Copy link
Copy Markdown
Contributor

Updated maintainer verification for head c91088f580986b160ec18e46473c2f92da3816ec:

Behavior addressed: Ollama provider no longer forwards truthy native think payloads for models marked reasoning: false, while preserving explicit think: false and supported thinking models.
Real environment tested: local OpenClaw checkout on macOS, rebased onto origin/main at 1bd10cfee6a4ad608c97e47b4294cc81586406d9.
Exact steps or command run after this patch:

  • node scripts/check-no-raw-channel-fetch.mjs
  • node scripts/run-vitest.mjs extensions/github-copilot/index.test.ts
  • node scripts/run-vitest.mjs extensions/ollama/src/stream-runtime.test.ts -- -t "non-reasoning"
  • git diff --check origin/main...HEAD
  • codex-review --mode branch --parallel-tests "node scripts/run-vitest.mjs extensions/ollama/src/stream-runtime.test.ts -- -t 'non-reasoning'"
    Evidence after fix: raw channel/plugin fetch boundary check passed; GitHub Copilot provider onboarding test file passed, 12 tests; focused Ollama stream runtime test file passed, 79 tests; diff whitespace check passed; codex-review reported no accepted/actionable findings.
    Observed result after fix: configured and runtime thinking settings are omitted from Ollama request payloads when the resolved model declares reasoning: false; the unrelated latest-main raw fetch boundary failure in GitHub Copilot device login is also fixed by using the plugin SDK guarded fetch helper.
    What was not tested: no live Ollama daemon/model was available in this maintainer checkout; provider behavior is covered by the focused request-payload regression tests and the contributor's loopback rejecting-server proof.

@steipete steipete force-pushed the fix/80332-ollama-think-options branch from c91088f to ff73e14 Compare May 16, 2026 13:26
@steipete

Copy link
Copy Markdown
Contributor

Rebased again for latest main; updated head is ff73e14638b6da206298d51f97762495f289861a.

Additional proof after rebase:

  • node scripts/check-no-raw-channel-fetch.mjs
  • node scripts/run-vitest.mjs extensions/github-copilot/index.test.ts
  • node scripts/run-vitest.mjs extensions/ollama/src/stream-runtime.test.ts -- -t "non-reasoning"
  • git diff --check origin/main...HEAD

All passed locally. Changelog conflict was resolved by preserving both the latest Telegram entry from main and this PR's Ollama entry.

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@steipete steipete force-pushed the fix/80332-ollama-think-options branch from ff73e14 to e042f0a Compare May 16, 2026 14:05
@steipete

Copy link
Copy Markdown
Contributor

Maintainer update pushed after rebasing on current main.

Behavior addressed: Ollama native chat no longer forwards truthy top-level think values for models whose runtime catalog marks reasoning: false; explicit think: false and reasoning-capable models are preserved.
Real environment tested: local OpenClaw checkout on Node via repo Vitest wrapper.
Exact steps or command run after this patch:

  • node scripts/run-vitest.mjs extensions/ollama/src/stream-runtime.test.ts -- -t 'non-reasoning'
  • /Users/steipete/Projects/agent-scripts/skills/codex-review/scripts/codex-review --mode branch --parallel-tests "node scripts/run-vitest.mjs extensions/ollama/src/stream-runtime.test.ts -- -t 'non-reasoning'"
  • git diff --check origin/main...HEAD
    Evidence after fix: focused Ollama request-body regressions pass and assert both configured and runtime non-reasoning paths omit think.
    Observed result after fix: no accepted/actionable Codex review findings; whitespace check clean.
    What was not tested: live Ollama daemon/provider call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: ollama proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Ollama think parameter sent at top-level causes 400 for non-thinking models; should be inside options

2 participants