fix(reasoning): apply reasoningDefault independently of thinking level

The reasoningDefault was incorrectly skipped when thinking was active.
Thinking controls reasoning depth while reasoning controls visibility -
they should be independent settings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
fishking
2026-03-23 16:03:52 +08:00
committed by Ayaan Zaidi
parent f48571bec6
commit b91374eb0d
3 changed files with 24 additions and 20 deletions

View File

@@ -94,8 +94,8 @@ describe("resolveCurrentDirectiveLevels", () => {
expect(result.currentReasoningLevel).toBe("stream");
});
it("skips agent reasoningDefault when thinking is active", async () => {
const resolveDefaultThinkingLevel = vi.fn().mockResolvedValue("low");
it("applies agent reasoningDefault even when thinking is active", async () => {
const resolveDefaultThinkingLevel = vi.fn().mockResolvedValue("high");
const result = await resolveCurrentDirectiveLevels({
sessionEntry: {},
@@ -105,6 +105,20 @@ describe("resolveCurrentDirectiveLevels", () => {
resolveDefaultThinkingLevel,
});
// reasoningDefault should work independently of thinking level
expect(result.currentThinkLevel).toBe("high");
expect(result.currentReasoningLevel).toBe("stream");
});
it("defaults reasoning to off when no agent default is set", async () => {
const resolveDefaultThinkingLevel = vi.fn().mockResolvedValue("low");
const result = await resolveCurrentDirectiveLevels({
sessionEntry: {},
agentEntry: {},
resolveDefaultThinkingLevel,
});
expect(result.currentReasoningLevel).toBe("off");
});
});

View File

@@ -39,12 +39,10 @@ export async function resolveCurrentDirectiveLevels(params: {
const currentVerboseLevel =
(params.sessionEntry?.verboseLevel as VerboseLevel | undefined) ??
(params.agentCfg?.verboseDefault as VerboseLevel | undefined);
const sessionReasoningLevel = params.sessionEntry?.reasoningLevel as ReasoningLevel | undefined;
const currentReasoningLevel =
sessionReasoningLevel ??
(currentThinkLevel === "off"
? ((params.agentEntry?.reasoningDefault as ReasoningLevel | undefined) ?? "off")
: "off");
(params.sessionEntry?.reasoningLevel as ReasoningLevel | undefined) ??
(params.agentEntry?.reasoningDefault as ReasoningLevel | undefined) ??
"off";
const currentElevatedLevel =
(params.sessionEntry?.elevatedLevel as ElevatedLevel | undefined) ??
(params.agentCfg?.elevatedDefault as ElevatedLevel | undefined);

View File

@@ -386,9 +386,8 @@ export async function resolveReplyDirectives(params: {
let resolvedReasoningLevel: ReasoningLevel =
directives.reasoningLevel ??
(sessionEntry?.reasoningLevel as ReasoningLevel | undefined) ??
(agentEntry?.reasoningDefault as ReasoningLevel | undefined) ??
"off";
const agentReasoningDefault = agentEntry?.reasoningDefault as ReasoningLevel | undefined;
const hasAgentReasoningDefault = agentReasoningDefault !== undefined;
const resolvedElevatedLevel = elevatedAllowed
? (directives.elevatedLevel ??
(sessionEntry?.elevatedLevel as ElevatedLevel | undefined) ??
@@ -434,20 +433,13 @@ export async function resolveReplyDirectives(params: {
(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
// active, including model-inferred defaults, or internal thinking blocks can
// be emitted as visible "Reasoning:" messages.
// When neither directive nor session nor agent set reasoning, default to model capability
// (e.g. OpenRouter with reasoning: true).
const reasoningExplicitlySet =
directives.reasoningLevel !== undefined ||
(sessionEntry?.reasoningLevel !== undefined && sessionEntry?.reasoningLevel !== null);
const thinkingActive = resolvedThinkLevelWithDefault !== "off";
if (!reasoningExplicitlySet && resolvedReasoningLevel === "off" && !thinkingActive) {
if (hasAgentReasoningDefault) {
resolvedReasoningLevel = agentReasoningDefault;
} else {
resolvedReasoningLevel = await modelState.resolveDefaultReasoningLevel();
}
if (!reasoningExplicitlySet && resolvedReasoningLevel === "off") {
resolvedReasoningLevel = await modelState.resolveDefaultReasoningLevel();
}
let contextTokens = resolveContextTokens({