fix(auto-reply): honor per-model thinking params

Auto-reply now uses the existing per-model model params thinking value before falling back to the global thinkingDefault, matching gateway/shared model selection behavior.\n\nVerified with targeted auto-reply and agents Vitest coverage plus formatting and diff checks.\n\nThanks @tynamite for the fix.
This commit is contained in:
tynamite
2026-05-31 14:01:25 +01:00
committed by GitHub
parent b222b5f6fa
commit 2f7e6ec196
2 changed files with 63 additions and 3 deletions

View File

@@ -108,6 +108,43 @@ describe("createModelSelectionState catalog loading", () => {
expect(loadModelCatalog).not.toHaveBeenCalled();
});
it("prefers per-model params.thinking over global thinkingDefault", async () => {
vi.mocked(loadModelCatalog).mockClear();
const cfg = {
agents: {
defaults: {
thinkingDefault: "low",
models: {
"openai-codex/gpt-5.4": {
params: { thinking: "high" },
},
},
},
},
models: {
providers: {
"openai-codex": {
baseUrl: "https://api.openai.com/v1",
models: [makeConfiguredModel()],
},
},
},
} as OpenClawConfig;
const state = await createModelSelectionState({
cfg,
agentCfg: cfg.agents?.defaults,
defaultProvider: "openai-codex",
defaultModel: "gpt-5.4",
provider: "openai-codex",
model: "gpt-5.4",
hasModelDirective: false,
});
await expect(state.resolveDefaultThinkingLevel()).resolves.toBe("high");
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

@@ -7,6 +7,7 @@ import type { ModelCatalogEntry } from "../../agents/model-catalog.js";
import { parseConfiguredModelVisibilityEntries } from "../../agents/model-selection-shared.js";
import {
buildConfiguredModelCatalog,
legacyModelKey,
modelKey,
normalizeModelRef,
normalizeProviderId,
@@ -458,10 +459,32 @@ export async function createModelSelectionState(params: {
return defaultThinkingLevel;
}
const agentThinkingDefault = agentEntry?.thinkingDefault as ThinkLevel | undefined;
if (agentThinkingDefault) {
defaultThinkingLevel = agentThinkingDefault;
return defaultThinkingLevel;
}
const configuredModels = cfg.agents?.defaults?.models;
const canonicalKey = modelKey(provider, model);
const legacyKey = legacyModelKey(provider, model);
const configuredModelThinkingDefault =
configuredModels?.[canonicalKey]?.params?.thinking ??
(legacyKey ? configuredModels?.[legacyKey]?.params?.thinking : undefined);
if (
configuredModelThinkingDefault === "off" ||
configuredModelThinkingDefault === "minimal" ||
configuredModelThinkingDefault === "low" ||
configuredModelThinkingDefault === "medium" ||
configuredModelThinkingDefault === "high" ||
configuredModelThinkingDefault === "xhigh" ||
configuredModelThinkingDefault === "adaptive" ||
configuredModelThinkingDefault === "max"
) {
defaultThinkingLevel = configuredModelThinkingDefault;
return defaultThinkingLevel;
}
const configuredThinkingDefault = agentCfg?.thinkingDefault as ThinkLevel | undefined;
const explicitThinkingDefault = agentThinkingDefault ?? configuredThinkingDefault;
if (explicitThinkingDefault) {
defaultThinkingLevel = explicitThinkingDefault;
if (configuredThinkingDefault) {
defaultThinkingLevel = configuredThinkingDefault;
return defaultThinkingLevel;
}
const catalogForThinking = await resolveThinkingCatalog();