@@ -78,26 +78,62 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
7878
7979 // Build available reasoning efforts list from capability
8080 const supports = modelInfo ?. supportsReasoningEffort
81- const availableOptions : ReadonlyArray < ReasoningEffortWithMinimal > =
81+ const baseAvailableOptions : ReadonlyArray < ReasoningEffortWithMinimal > =
8282 supports === true
8383 ? ( reasoningEfforts as readonly ReasoningEffortWithMinimal [ ] )
8484 : Array . isArray ( supports )
8585 ? ( supports as ReadonlyArray < ReasoningEffortWithMinimal > )
8686 : ( reasoningEfforts as readonly ReasoningEffortWithMinimal [ ] )
8787
88+ // "disable" turns off reasoning entirely; "none" is a valid reasoning level.
89+ // Both display as "None" in the UI but behave differently.
90+ // Add "disable" option if reasoning effort is not required.
91+ type ReasoningEffortOption = ReasoningEffortWithMinimal | "none" | "disable"
92+ const availableOptions : ReadonlyArray < ReasoningEffortOption > = modelInfo ?. requiredReasoningEffort
93+ ? ( baseAvailableOptions as ReadonlyArray < ReasoningEffortOption > )
94+ : ( [ "disable" , ...baseAvailableOptions ] as ReasoningEffortOption [ ] )
95+
8896 // Default reasoning effort - use model's default if available
8997 // GPT-5 models have "medium" as their default in the model configuration
9098 const modelDefaultReasoningEffort = modelInfo ?. reasoningEffort as ReasoningEffortWithMinimal | undefined
91- const defaultReasoningEffort : ReasoningEffortWithMinimal = modelDefaultReasoningEffort || "medium"
92- const currentReasoningEffort : ReasoningEffortWithMinimal =
93- ( apiConfiguration . reasoningEffort as ReasoningEffortWithMinimal | undefined ) || defaultReasoningEffort
99+ const defaultReasoningEffort : ReasoningEffortOption = modelInfo ?. requiredReasoningEffort
100+ ? modelDefaultReasoningEffort || "medium"
101+ : "disable"
102+ // Current reasoning effort from settings, or fall back to default
103+ const storedReasoningEffort = apiConfiguration . reasoningEffort as ReasoningEffortOption | undefined
104+ const currentReasoningEffort : ReasoningEffortOption = storedReasoningEffort || defaultReasoningEffort
94105
95106 // Set default reasoning effort when model supports it and no value is set
96107 useEffect ( ( ) => {
97- if ( isReasoningEffortSupported && ! apiConfiguration . reasoningEffort && defaultReasoningEffort ) {
98- setApiConfigurationField ( "reasoningEffort" , defaultReasoningEffort , false )
108+ if ( isReasoningEffortSupported && ! apiConfiguration . reasoningEffort ) {
109+ // Only set a default if reasoning is required, otherwise leave as undefined (which maps to "disable")
110+ if ( modelInfo ?. requiredReasoningEffort && defaultReasoningEffort !== "disable" ) {
111+ setApiConfigurationField ( "reasoningEffort" , defaultReasoningEffort as ReasoningEffortWithMinimal , false )
112+ }
113+ }
114+ } , [
115+ isReasoningEffortSupported ,
116+ apiConfiguration . reasoningEffort ,
117+ defaultReasoningEffort ,
118+ modelInfo ?. requiredReasoningEffort ,
119+ setApiConfigurationField ,
120+ ] )
121+
122+ // Sync enableReasoningEffort based on selection
123+ // "disable" turns off reasoning; "none" is a valid level (reasoning enabled)
124+ useEffect ( ( ) => {
125+ if ( ! isReasoningEffortSupported ) return
126+ const shouldEnable = modelInfo ?. requiredReasoningEffort || currentReasoningEffort !== "disable"
127+ if ( shouldEnable && apiConfiguration . enableReasoningEffort !== true ) {
128+ setApiConfigurationField ( "enableReasoningEffort" , true , false )
99129 }
100- } , [ isReasoningEffortSupported , apiConfiguration . reasoningEffort , defaultReasoningEffort , setApiConfigurationField ] )
130+ } , [
131+ isReasoningEffortSupported ,
132+ modelInfo ?. requiredReasoningEffort ,
133+ currentReasoningEffort ,
134+ apiConfiguration . enableReasoningEffort ,
135+ setApiConfigurationField ,
136+ ] )
101137
102138 const enableReasoningEffort = apiConfiguration . enableReasoningEffort
103139 const customMaxOutputTokens = apiConfiguration . modelMaxTokens || DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS
@@ -193,22 +229,34 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
193229 </ div >
194230 < Select
195231 value = { currentReasoningEffort }
196- onValueChange = { ( value : ReasoningEffortWithMinimal ) => {
197- setApiConfigurationField ( "reasoningEffort" , value )
232+ onValueChange = { ( value : ReasoningEffortOption ) => {
233+ // "disable" turns off reasoning entirely; "none" is a valid reasoning level
234+ if ( value === "disable" ) {
235+ setApiConfigurationField ( "enableReasoningEffort" , false )
236+ setApiConfigurationField ( "reasoningEffort" , "disable" )
237+ } else {
238+ // "none", "minimal", "low", "medium", "high" all enable reasoning
239+ setApiConfigurationField ( "enableReasoningEffort" , true )
240+ setApiConfigurationField ( "reasoningEffort" , value as ReasoningEffortWithMinimal )
241+ }
198242 } } >
199243 < SelectTrigger className = "w-full" >
200244 < SelectValue
201245 placeholder = {
202246 currentReasoningEffort
203- ? t ( `settings:providers.reasoningEffort.${ currentReasoningEffort } ` )
247+ ? currentReasoningEffort === "none" || currentReasoningEffort === "disable"
248+ ? t ( "settings:providers.reasoningEffort.none" )
249+ : t ( `settings:providers.reasoningEffort.${ currentReasoningEffort } ` )
204250 : t ( "settings:common.select" )
205251 }
206252 />
207253 </ SelectTrigger >
208254 < SelectContent >
209255 { availableOptions . map ( ( value ) => (
210256 < SelectItem key = { value } value = { value } >
211- { t ( `settings:providers.reasoningEffort.${ value } ` ) }
257+ { value === "none" || value === "disable"
258+ ? t ( "settings:providers.reasoningEffort.none" )
259+ : t ( `settings:providers.reasoningEffort.${ value } ` ) }
212260 </ SelectItem >
213261 ) ) }
214262 </ SelectContent >
0 commit comments