fix(agents): recognize params.thinking=false and "disabled"/"none" as thinking=off#74418
Conversation
Greptile SummaryThis PR fixes Confidence Score: 5/5This PR is safe to merge — the change is small, well-scoped, and fully tested. The fix is minimal (8 lines) and directly addresses the documented root cause. All three new aliases are covered by unit tests, and there are no side effects on the existing code paths. No P0/P1 issues found. No files require special attention. Reviews (1): Last reviewed commit: "fix(agents): recognize boolean false and..." | Re-trigger Greptile |
|
Codex review: needs real behavior proof before merge. Reviewed May 31, 2026, 9:42 AM ET / 13:42 UTC. Summary PR surface: Source +16, Tests +103. Total +119 across 4 files. Reproducibility: yes. Current-main source inspection shows the disabled aliases are not recognized before fallback, and the PR adds focused tests that exercise the expected Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the narrow alias handling after current-head proof and maintainer acceptance of the config compatibility change; keep the broader Do we have a high-confidence way to reproduce the issue? Yes. Current-main source inspection shows the disabled aliases are not recognized before fallback, and the PR adds focused tests that exercise the expected Is this the best way to solve the issue? Yes for this PR's bug boundary. Updating the two existing thinking-default resolution paths is narrower than changing provider request wrappers, while the broader AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 75e0053cf969. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +16, Tests +103. Total +119 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
8074f98 to
fbace74
Compare
16646c6 to
676e44b
Compare
|
After-fix real behavior proof from the PR head, redacted to resolver inputs and outputs only. Behavior addressed: DeepSeek V4 has provider default thinking Evidence after fix: {
"branch": "fork/fix/deepseek-v4-thinking-false-74374",
"head": "676e44b3db5b73dbd564221a2b023e708ea419a5",
"command": "node --import tsx resolveThinkingDefault proof",
"providerDefault": "high",
"cases": [
{
"input": false,
"resolved": "off"
},
{
"input": "disabled",
"resolved": "off"
},
{
"input": "none",
"resolved": "off"
}
]
}Observed result after fix: all three disabled aliases resolve to @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
ClawSweeper PR egg ✨ Hatched: 🥚 common Clockwork Test Hopper Hatch commandComment Hatchability rules:
Rarity: 🥚 common. What is this egg doing here?
|
|
@clawsweeper re-review |
676e44b to
d0a19d2
Compare
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
d0a19d2 to
0599a3a
Compare
|
Behavior addressed: params.thinking now treats false, disabled, and none as the existing off state in both normal agent model selection and auto-reply duplicate-precheck model selection. Real environment tested: local targeted Vitest in this checkout plus GitHub Actions on PR head 0599a3a. Exact steps or command run after this patch:
Evidence after fix:
Observed result after fix: disabled model params keep thinking off ahead of any global thinkingDefault, including auto-reply precheck routing. What was not tested: full local suite. Known CI proof gap: build-artifacts job 78731190189 fails in the unrelated core-support-boundary lane at scripts/plugin-prerelease-test-plan.test.ts:163 and :185 because that test still expects docker_e2e_docker_cmd stats --no-stream while the current scripts use docker_e2e_sample_stats_until_exit. This failure is outside the touched agent and auto-reply model-selection paths and reproduced after a failed-job rerun. |
Summary
Fixes #74374
resolveThinkingDefaultonly recognized string values like"off","low","high", etc. for per-modelparams.thinking. When a user configuredparams.thinking: false(boolean) orparams.thinking: "disabled"— both common ways to express "no thinking" — the value fell through to the model/provider default (e.g."high"for DeepSeek v4-pro).This caused the DeepSeek thinking stream wrapper to inject
reasoning_contentinto assistant messages and setthinking: { type: "enabled" }. If the user also configuredextra_body: { thinking: { type: "disabled" } }, theextra_bodywrapper then overwrotethinkingtodisabled— butreasoning_contentwas already in the messages. DeepSeek's API rejects this inconsistent state with:Changes
resolveThinkingDefaultnow treatsfalse,"disabled", and"none"as"off"Root Cause
src/agents/model-thinking-default.ts:42-52only matched string values against the known thinking levels. Booleanfalseand aliases like"disabled"/"none"were not handled, causing them to fall through to the provider default. The DeepSeek V4 wrapper (createDeepSeekV4OpenAICompatibleThinkingWrapper) already handles"none"correctly at the stream level, but it was never reached becausethinkingLevelwas resolved to the wrong value upstream.Real behavior proof
Behavior addressed: DeepSeek V4 has provider default thinking
high, but model-level disabled aliases must resolve to OpenClaw thinkingoffbefore request payload shaping.Real environment tested: local OpenClaw source checkout using fork PR head
676e44b3db5b73dbd564221a2b023e708ea419a5.Exact steps or command run after this patch:
Evidence after fix:
{ "branch": "fork/fix/deepseek-v4-thinking-false-74374", "head": "676e44b3db5b73dbd564221a2b023e708ea419a5", "command": "node --import tsx resolveThinkingDefault proof", "providerDefault": "high", "cases": [ { "input": false, "resolved": "off" }, { "input": "disabled", "resolved": "off" }, { "input": "none", "resolved": "off" } ] }Observed result after fix: all three disabled aliases resolve to
offinstead of falling through to the provider defaulthigh.What was not tested: No live DeepSeek HTTP request was sent; this proof exercises the production thinking resolver locally and avoids printing prompts, credentials, or provider responses.