fix(agents): prioritize per-model thinking defaults (#30439)

* fix(agents): honor per-model thinking defaults

* fix(agents): preserve thinking fallback with model defaults

---------

Co-authored-by: Mark L <73659136+markliuyuxiang@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
Mark L
2026-03-02 12:00:02 +08:00
committed by GitHub
parent 3fc19ed7d7
commit 0f2dce0483
9 changed files with 123 additions and 31 deletions

View File

@@ -0,0 +1,36 @@
import { describe, expect, it, vi } from "vitest";
import { resolveCurrentDirectiveLevels } from "./directive-handling.levels.js";
describe("resolveCurrentDirectiveLevels", () => {
it("prefers resolved model default over agent thinkingDefault", async () => {
const resolveDefaultThinkingLevel = vi.fn().mockResolvedValue("high");
const result = await resolveCurrentDirectiveLevels({
sessionEntry: {},
agentCfg: {
thinkingDefault: "low",
},
resolveDefaultThinkingLevel,
});
expect(result.currentThinkLevel).toBe("high");
expect(resolveDefaultThinkingLevel).toHaveBeenCalledTimes(1);
});
it("keeps session thinking override without consulting defaults", async () => {
const resolveDefaultThinkingLevel = vi.fn().mockResolvedValue("high");
const result = await resolveCurrentDirectiveLevels({
sessionEntry: {
thinkingLevel: "minimal",
},
agentCfg: {
thinkingDefault: "low",
},
resolveDefaultThinkingLevel,
});
expect(result.currentThinkLevel).toBe("minimal");
expect(resolveDefaultThinkingLevel).not.toHaveBeenCalled();
});
});

View File

@@ -21,8 +21,8 @@ export async function resolveCurrentDirectiveLevels(params: {
}> {
const resolvedDefaultThinkLevel =
(params.sessionEntry?.thinkingLevel as ThinkLevel | undefined) ??
(params.agentCfg?.thinkingDefault as ThinkLevel | undefined) ??
(await params.resolveDefaultThinkingLevel());
(await params.resolveDefaultThinkingLevel()) ??
(params.agentCfg?.thinkingDefault as ThinkLevel | undefined);
const currentThinkLevel = resolvedDefaultThinkLevel;
const currentVerboseLevel =
(params.sessionEntry?.verboseLevel as VerboseLevel | undefined) ??

View File

@@ -339,9 +339,7 @@ export async function resolveReplyDirectives(params: {
});
const defaultActivation = defaultGroupActivation(requireMention);
const resolvedThinkLevel =
directives.thinkLevel ??
(sessionEntry?.thinkingLevel as ThinkLevel | undefined) ??
(agentCfg?.thinkingDefault as ThinkLevel | undefined);
directives.thinkLevel ?? (sessionEntry?.thinkingLevel as ThinkLevel | undefined);
const resolvedVerboseLevel =
directives.verboseLevel ??
@@ -390,6 +388,10 @@ export async function resolveReplyDirectives(params: {
});
provider = modelState.provider;
model = modelState.model;
const resolvedThinkLevelWithDefault =
resolvedThinkLevel ??
(await modelState.resolveDefaultThinkingLevel()) ??
(agentCfg?.thinkingDefault as ThinkLevel | undefined);
// When neither directive nor session set reasoning, default to model capability
// (e.g. OpenRouter with reasoning: true). Skip auto-enabling when thinking is
@@ -398,9 +400,7 @@ export async function resolveReplyDirectives(params: {
const reasoningExplicitlySet =
directives.reasoningLevel !== undefined ||
(sessionEntry?.reasoningLevel !== undefined && sessionEntry?.reasoningLevel !== null);
const effectiveThinkingForReasoning =
resolvedThinkLevel ?? (await modelState.resolveDefaultThinkingLevel());
const thinkingActive = effectiveThinkingForReasoning !== "off";
const thinkingActive = resolvedThinkLevelWithDefault !== "off";
if (!reasoningExplicitlySet && resolvedReasoningLevel === "off" && !thinkingActive) {
resolvedReasoningLevel = await modelState.resolveDefaultReasoningLevel();
}
@@ -477,7 +477,7 @@ export async function resolveReplyDirectives(params: {
elevatedAllowed,
elevatedFailures,
defaultActivation,
resolvedThinkLevel,
resolvedThinkLevel: resolvedThinkLevelWithDefault,
resolvedVerboseLevel,
resolvedReasoningLevel,
resolvedElevatedLevel,