Problem
The SimpleStreamOptions interface allows users to configure model reasoning using
easoning: boolean | ModelThinkingLevel. When a user explicitly disables reasoning by setting
easoning: "off", the string "off" evaluates to truthy, bypassing the intended falsy checks in the Anthropic and Google provider adapters.
In src/llm/providers/google-shared.ts (�uildGoogleSimpleThinking):
` ypescript
if (!options?.reasoning) { // "off" is truthy, so this check is skipped
return { enabled: false };
}
const clampedReasoning = clampThinkingLevel(model, options.reasoning);
// "off" maps to "off"
const effort = (
clampedReasoning === "off" || clampedReasoning === "max" ? "high" : clampedReasoning
) as ClampedGoogleThinkingLevel;
// "off" is transformed into "high", and enabled=true is returned!
`
In src/llm/providers/anthropic.ts (streamSimpleAnthropic):
` ypescript
if (!options?.reasoning) { // "off" is truthy, so this check is skipped
// ...
}
// For Opus 4.6 and Sonnet 4.6: use adaptive thinking with effort level
if (supportsAdaptiveThinking(model)) {
// "off" maps to "low" effort
const effort = mapThinkingLevelToEffort(model, options.reasoning);
return streamAnthropic(model, context, {
...base,
thinkingEnabled: true, // Incorrectly enables thinking!
effort,
});
}
`
As a result, specifying
easoning: "off" actually enables high-effort thinking in Gemini and low-effort thinking in Claude.
Expected Behavior
Setting
easoning: "off" in SimpleStreamOptions should completely disable thinking in all provider adapters, just as
easoning: false does. The adapters must explicitly check for === "off" (or use a helper that handles it correctly like Mistral's clampedReasoning === "off" ? undefined : clampedReasoning).
Solution
- Update �uildGoogleSimpleThinking in google-shared.ts to return { enabled: false } if options?.reasoning === "off" or clampThinkingLevel returns "off".
- Update streamSimpleAnthropic in �nthropic.ts to return hinkingEnabled: false when options?.reasoning === "off" or when clampThinkingLevel returns "off" (for models where thinking is not mandatory).
Problem
The SimpleStreamOptions interface allows users to configure model reasoning using
easoning: boolean | ModelThinkingLevel. When a user explicitly disables reasoning by setting
easoning: "off", the string "off" evaluates to truthy, bypassing the intended falsy checks in the Anthropic and Google provider adapters.
In src/llm/providers/google-shared.ts (�uildGoogleSimpleThinking):
` ypescript
if (!options?.reasoning) { // "off" is truthy, so this check is skipped
return { enabled: false };
}
const clampedReasoning = clampThinkingLevel(model, options.reasoning);
// "off" maps to "off"
const effort = (
clampedReasoning === "off" || clampedReasoning === "max" ? "high" : clampedReasoning
) as ClampedGoogleThinkingLevel;
// "off" is transformed into "high", and enabled=true is returned!
`
In src/llm/providers/anthropic.ts (streamSimpleAnthropic):
` ypescript
if (!options?.reasoning) { // "off" is truthy, so this check is skipped
// ...
}
// For Opus 4.6 and Sonnet 4.6: use adaptive thinking with effort level
if (supportsAdaptiveThinking(model)) {
// "off" maps to "low" effort
const effort = mapThinkingLevelToEffort(model, options.reasoning);
return streamAnthropic(model, context, {
...base,
thinkingEnabled: true, // Incorrectly enables thinking!
effort,
});
}
`
As a result, specifying
easoning: "off" actually enables high-effort thinking in Gemini and low-effort thinking in Claude.
Expected Behavior
Setting
easoning: "off" in SimpleStreamOptions should completely disable thinking in all provider adapters, just as
easoning: false does. The adapters must explicitly check for === "off" (or use a helper that handles it correctly like Mistral's clampedReasoning === "off" ? undefined : clampedReasoning).
Solution