From e7a94984ea3abc2912627d0b0f91c8c854c423c4 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Fri, 30 Jan 2026 20:48:41 +1100 Subject: [PATCH] fix: respect supportsReasoningEffort compat flag for reasoning models --- CHANGELOG.md | 3 ++ src/agents/pi-embedded-runner/compact.ts | 2 +- src/agents/pi-embedded-runner/run/attempt.ts | 2 +- src/agents/pi-embedded-runner/utils.test.ts | 37 ++++++++++++++++++++ src/agents/pi-embedded-runner/utils.ts | 12 ++++++- 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 src/agents/pi-embedded-runner/utils.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c0549c16..c0dd93d60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ Docs: https://docs.openclaw.ai ## 2026.1.29 Status: stable. +### Fixed +- Fixed reasoning models that don't support the `reasoning_effort` parameter (like XAI's `grok-4-1-fast-reasoning`) by respecting the `supportsReasoningEffort` compat flag in model configurations + ### Changes - Rebrand: rename the npm package/CLI to `openclaw`, add a `openclaw` compatibility shim, and move extensions to the `@openclaw/*` scope. - Onboarding: strengthen security warning copy for beta + access control expectations. diff --git a/src/agents/pi-embedded-runner/compact.ts b/src/agents/pi-embedded-runner/compact.ts index 2dc4c5325..a70cc0e87 100644 --- a/src/agents/pi-embedded-runner/compact.ts +++ b/src/agents/pi-embedded-runner/compact.ts @@ -390,7 +390,7 @@ export async function compactEmbeddedPiSessionDirect( authStorage, modelRegistry, model, - thinkingLevel: mapThinkingLevel(params.thinkLevel), + thinkingLevel: mapThinkingLevel(params.thinkLevel, model.compat), systemPrompt, tools: builtInTools, customTools, diff --git a/src/agents/pi-embedded-runner/run/attempt.ts b/src/agents/pi-embedded-runner/run/attempt.ts index e83c3ae4a..1bab121e6 100644 --- a/src/agents/pi-embedded-runner/run/attempt.ts +++ b/src/agents/pi-embedded-runner/run/attempt.ts @@ -453,7 +453,7 @@ export async function runEmbeddedAttempt( authStorage: params.authStorage, modelRegistry: params.modelRegistry, model: params.model, - thinkingLevel: mapThinkingLevel(params.thinkLevel), + thinkingLevel: mapThinkingLevel(params.thinkLevel, params.model.compat), systemPrompt, tools: builtInTools, customTools: allCustomTools, diff --git a/src/agents/pi-embedded-runner/utils.test.ts b/src/agents/pi-embedded-runner/utils.test.ts new file mode 100644 index 000000000..e4e89bc94 --- /dev/null +++ b/src/agents/pi-embedded-runner/utils.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, it } from "vitest"; +import type { ModelCompatConfig } from "../../config/types.models.js"; +import { mapThinkingLevel } from "./utils.js"; + +describe("mapThinkingLevel", () => { + it("returns undefined when model doesn't support reasoning_effort", () => { + const compat: ModelCompatConfig = { supportsReasoningEffort: false }; + expect(mapThinkingLevel("low", compat)).toBeUndefined(); + expect(mapThinkingLevel("high", compat)).toBeUndefined(); + expect(mapThinkingLevel("off", compat)).toBeUndefined(); + expect(mapThinkingLevel(undefined, compat)).toBeUndefined(); + }); + + it("returns level when model supports reasoning_effort", () => { + const compat: ModelCompatConfig = { supportsReasoningEffort: true }; + expect(mapThinkingLevel("low", compat)).toBe("low"); + expect(mapThinkingLevel("high", compat)).toBe("high"); + expect(mapThinkingLevel("off", compat)).toBe("off"); + }); + + it("returns level when compat is empty object", () => { + const compat: ModelCompatConfig = {}; + expect(mapThinkingLevel("low", compat)).toBe("low"); + expect(mapThinkingLevel("high", compat)).toBe("high"); + }); + + it("returns level when compat is undefined", () => { + expect(mapThinkingLevel("low")).toBe("low"); + expect(mapThinkingLevel("high")).toBe("high"); + }); + + it("handles undefined level with no compat restrictions", () => { + expect(mapThinkingLevel(undefined)).toBe("off"); + expect(mapThinkingLevel(undefined, {})).toBe("off"); + expect(mapThinkingLevel(undefined, { supportsReasoningEffort: true })).toBe("off"); + }); +}); diff --git a/src/agents/pi-embedded-runner/utils.ts b/src/agents/pi-embedded-runner/utils.ts index a95c18330..e4ac10a44 100644 --- a/src/agents/pi-embedded-runner/utils.ts +++ b/src/agents/pi-embedded-runner/utils.ts @@ -1,9 +1,19 @@ import type { ThinkingLevel } from "@mariozechner/pi-agent-core"; import type { ReasoningLevel, ThinkLevel } from "../../auto-reply/thinking.js"; import type { OpenClawConfig } from "../../config/config.js"; +import type { ModelCompatConfig } from "../../config/types.models.js"; import type { ExecToolDefaults } from "../bash-tools.js"; -export function mapThinkingLevel(level?: ThinkLevel): ThinkingLevel { +export function mapThinkingLevel( + level: ThinkLevel | undefined, + modelCompat?: ModelCompatConfig, +): ThinkingLevel | undefined { + // If model doesn't support reasoning_effort parameter, return undefined + // so the SDK doesn't pass it to the API + if (modelCompat?.supportsReasoningEffort === false) { + return undefined; + } + // pi-agent-core supports "xhigh"; OpenClaw enables it for specific models. if (!level) return "off"; return level;