fix(agents): accept disabled thinking params

Fixes #74374.

Normalizes params.thinking false, disabled, and none to the existing off state for agent and auto-reply model selection. Thanks @yelog.

Known proof gap: build-artifacts is failing in an unrelated plugin prerelease plan assertion that expects an old Docker stats helper string; targeted tests, diff check, autoreview, and all touched-path checks pass.
This commit is contained in:
Logan Ye
2026-05-31 22:07:18 +08:00
committed by GitHub
parent f8f52592c5
commit fdf6092494
4 changed files with 119 additions and 0 deletions

View File

@@ -2529,6 +2529,72 @@ describe("model-selection", () => {
expect(resolveAnthropicOpusThinking(cfg)).toBe("adaptive");
});
it("treats params.thinking=false as off (#74374)", () => {
const cfg = {
agents: {
defaults: {
models: {
"deepseek/deepseek-v4-pro": {
params: { thinking: false },
},
},
},
},
} as OpenClawConfig;
expect(
resolveThinkingDefault({
cfg,
provider: "deepseek",
model: "deepseek-v4-pro",
}),
).toBe("off");
});
it('treats params.thinking="disabled" as off (#74374)', () => {
const cfg = {
agents: {
defaults: {
models: {
"deepseek/deepseek-v4-pro": {
params: { thinking: "disabled" },
},
},
},
},
} as OpenClawConfig;
expect(
resolveThinkingDefault({
cfg,
provider: "deepseek",
model: "deepseek-v4-pro",
}),
).toBe("off");
});
it('treats params.thinking="none" as off', () => {
const cfg = {
agents: {
defaults: {
models: {
"deepseek/deepseek-v4-pro": {
params: { thinking: "none" },
},
},
},
},
} as OpenClawConfig;
expect(
resolveThinkingDefault({
cfg,
provider: "deepseek",
model: "deepseek-v4-pro",
}),
).toBe("off");
});
it("keeps thinking off by default for explicitly configured Anthropic Opus 4.7", () => {
const cfg = {
agents: {

View File

@@ -41,6 +41,14 @@ export function resolveThinkingDefault(params: {
const perModelThinking =
configuredModels?.[canonicalKey]?.params?.thinking ??
(legacyKey ? configuredModels?.[legacyKey]?.params?.thinking : undefined);
// Accept boolean false and common disable aliases as "off".
if (
perModelThinking === false ||
perModelThinking === "disabled" ||
perModelThinking === "none"
) {
return "off";
}
if (
perModelThinking === "off" ||
perModelThinking === "minimal" ||

View File

@@ -145,6 +145,43 @@ describe("createModelSelectionState catalog loading", () => {
expect(loadModelCatalog).not.toHaveBeenCalled();
});
it("keeps per-model disabled params.thinking ahead of global thinkingDefault", async () => {
vi.mocked(loadModelCatalog).mockClear();
const cfg = {
agents: {
defaults: {
thinkingDefault: "low",
models: {
"deepseek/deepseek-v4-pro": {
params: { thinking: false },
},
},
},
},
models: {
providers: {
deepseek: {
baseUrl: "https://api.deepseek.com/v1",
models: [makeConfiguredModel({ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro" })],
},
},
},
} as OpenClawConfig;
const state = await createModelSelectionState({
cfg,
agentCfg: cfg.agents?.defaults,
defaultProvider: "deepseek",
defaultModel: "deepseek-v4-pro",
provider: "deepseek",
model: "deepseek-v4-pro",
hasModelDirective: false,
});
await expect(state.resolveDefaultThinkingLevel()).resolves.toBe("off");
expect(loadModelCatalog).not.toHaveBeenCalled();
});
it("uses the implicit model default when no global thinking default is configured", async () => {
vi.mocked(loadModelCatalog).mockClear();
const cfg = {

View File

@@ -469,6 +469,14 @@ export async function createModelSelectionState(params: {
const configuredModelThinkingDefault =
configuredModels?.[canonicalKey]?.params?.thinking ??
(legacyKey ? configuredModels?.[legacyKey]?.params?.thinking : undefined);
if (
configuredModelThinkingDefault === false ||
configuredModelThinkingDefault === "disabled" ||
configuredModelThinkingDefault === "none"
) {
defaultThinkingLevel = "off";
return defaultThinkingLevel;
}
if (
configuredModelThinkingDefault === "off" ||
configuredModelThinkingDefault === "minimal" ||