Skip to content

Commit 6b4e02a

Browse files
committed
fix(models): restore Sol-exclusive 'max' reasoning value; fix Gemini 2.5 disable-thinking gap
Found during a final per-model audit round with independent 2-3 source verification on every changed model: - gpt-5.6-sol: restore 'max' reasoning-effort value. Multiple independent sources (OpenAI's own model-guidance docs page, launch announcement, and press coverage) confirm 'max' is a real, newly-launched value exclusive to Sol - not fabricated as originally assessed. Terra and Luna correctly do NOT get 'max' (confirmed Sol-exclusive), so they're unchanged. - gemini-2.5-flash / gemini-2.5-flash-lite (google + vertex): selecting 'none' for thinking level was sending no thinkingConfig at all, which falls back to the API's dynamic default (thinking stays ON for flash) - not actually disabling it, even though both models explicitly support thinkingBudget:0. Now sends an explicit budget of 0 for these two models specifically (gemini-2.5-pro is correctly excluded - it cannot disable thinking at all, floor is 128 not 0).
1 parent ec43215 commit 6b4e02a

4 files changed

Lines changed: 49 additions & 2 deletions

File tree

apps/sim/providers/gemini/core.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
extractTextContent,
2727
mapToThinkingBudget,
2828
mapToThinkingLevel,
29+
supportsDisablingGemini25Thinking,
2930
} from '@/providers/google/utils'
3031
import { enrichLastModelSegment } from '@/providers/trace-enrichment'
3132
import type {
@@ -953,7 +954,7 @@ export async function executeGeminiRequest(
953954
)
954955
}
955956

956-
// Configure thinking only when the user explicitly selects a thinking level.
957+
// Configure thinking based on the user's selected level.
957958
// Gemini 3.x accepts thinkingLevel directly; Gemini 2.5-series rejects thinkingLevel
958959
// entirely and requires a numeric thinkingBudget instead.
959960
if (request.thinkingLevel && request.thinkingLevel !== 'none') {
@@ -964,6 +965,14 @@ export async function executeGeminiRequest(
964965
thinkingConfig.thinkingBudget = mapToThinkingBudget(model, request.thinkingLevel)
965966
}
966967
geminiConfig.thinkingConfig = thinkingConfig
968+
} else if (
969+
request.thinkingLevel === 'none' &&
970+
!isGemini3Model(model) &&
971+
supportsDisablingGemini25Thinking(model)
972+
) {
973+
// Omitting thinkingConfig entirely falls back to the API's own dynamic default, which
974+
// is ON for gemini-2.5-flash — an explicit budget of 0 is required to actually disable it.
975+
geminiConfig.thinkingConfig = { includeThoughts: false, thinkingBudget: 0 }
967976
}
968977

969978
// Prepare tools

apps/sim/providers/google/utils.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
convertToGeminiFormat,
77
ensureStructResponse,
88
mapToThinkingBudget,
9+
supportsDisablingGemini25Thinking,
910
} from '@/providers/google/utils'
1011
import type { ProviderRequest } from '@/providers/types'
1112

@@ -42,6 +43,26 @@ describe('mapToThinkingBudget', () => {
4243
})
4344
})
4445

46+
describe('supportsDisablingGemini25Thinking', () => {
47+
it('returns true for gemini-2.5-flash and gemini-2.5-flash-lite', () => {
48+
expect(supportsDisablingGemini25Thinking('gemini-2.5-flash')).toBe(true)
49+
expect(supportsDisablingGemini25Thinking('gemini-2.5-flash-lite')).toBe(true)
50+
})
51+
52+
it('returns false for gemini-2.5-pro, which cannot disable thinking', () => {
53+
expect(supportsDisablingGemini25Thinking('gemini-2.5-pro')).toBe(false)
54+
})
55+
56+
it('strips the vertex/ prefix before checking', () => {
57+
expect(supportsDisablingGemini25Thinking('vertex/gemini-2.5-flash')).toBe(true)
58+
expect(supportsDisablingGemini25Thinking('vertex/gemini-2.5-pro')).toBe(false)
59+
})
60+
61+
it('returns false for models with no explicit mapping', () => {
62+
expect(supportsDisablingGemini25Thinking('gemini-3.5-flash')).toBe(false)
63+
})
64+
})
65+
4566
describe('ensureStructResponse', () => {
4667
describe('should return objects unchanged', () => {
4768
it('should return plain object unchanged', () => {

apps/sim/providers/google/utils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,23 @@ export function mapToThinkingBudget(model: string, level: string): number {
374374
return budgets[level.toLowerCase()] ?? budgets.high
375375
}
376376

377+
/**
378+
* Gemini 2.5-series models that accept `thinkingBudget: 0` to explicitly disable thinking.
379+
* gemini-2.5-pro cannot disable thinking at all (its documented budget floor is 128, not 0),
380+
* so it's deliberately excluded here.
381+
*/
382+
const GEMINI_25_MODELS_SUPPORTING_DISABLE = new Set(['gemini-2.5-flash', 'gemini-2.5-flash-lite'])
383+
384+
/**
385+
* Whether this Gemini 2.5-series model supports explicitly disabling thinking via budget=0.
386+
* Omitting thinkingConfig entirely (the 'none' no-op path) falls back to the API's own
387+
* dynamic default, which is ON for gemini-2.5-flash — not the same as actually disabling it.
388+
*/
389+
export function supportsDisablingGemini25Thinking(model: string): boolean {
390+
const normalized = model.toLowerCase().replace(/^vertex\//, '')
391+
return GEMINI_25_MODELS_SUPPORTING_DISABLE.has(normalized)
392+
}
393+
377394
/**
378395
* Result of checking forced tool usage
379396
*/

apps/sim/providers/models.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
294294
},
295295
capabilities: {
296296
reasoningEffort: {
297-
values: ['none', 'low', 'medium', 'high', 'xhigh'],
297+
values: ['none', 'low', 'medium', 'high', 'xhigh', 'max'],
298298
},
299299
verbosity: {
300300
values: ['low', 'medium', 'high'],

0 commit comments

Comments
 (0)