22Semantics for Reasoning Effort (ThinkingBudget)
33
44Capability surface:
5- - modelInfo.supportsReasoningEffort: boolean | Array<"disable" | "none" | "minimal" | "low" | "medium" | "high">
5+ - modelInfo.supportsReasoningEffort: boolean | Array<"disable" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" >
66 - true → UI shows ["low","medium","high"]
7- - array → UI shows exactly the provided values
7+ - array → UI shows exactly the provided values (e.g. GPT-5.5 includes "xhigh")
88
99Selection behavior:
1010- "disable":
@@ -17,7 +17,7 @@ Selection behavior:
1717 - set enableReasoningEffort = true
1818 - persist reasoningEffort = "none"
1919 - request builders include reasoning with value "none"
20- - "minimal" | "low" | "medium" | "high":
20+ - "minimal" | "low" | "medium" | "high" | "xhigh" | "max" :
2121 - set enableReasoningEffort = true
2222 - persist the selected value
2323 - request builders include reasoning with the selected effort
@@ -35,12 +35,7 @@ Notes:
3535import { useEffect } from "react"
3636import { Checkbox } from "vscrui"
3737
38- import {
39- type ProviderSettings ,
40- type ModelInfo ,
41- type ReasoningEffortWithMinimal ,
42- reasoningEfforts ,
43- } from "@roo-code/types"
38+ import { type ProviderSettings , type ModelInfo , type ReasoningEffortExtended , reasoningEfforts } from "@roo-code/types"
4439
4540import {
4641 DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS ,
@@ -81,44 +76,49 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
8176 // max-tokens control, so only surface this standalone slider when that branch is inactive.
8277 const isMaxTokensConfigurable = ! ! modelInfo && modelInfo . supportsMaxTokens && ! isReasoningBudgetSupported
8378
84- // Build available reasoning efforts list from capability
79+ // "disable" turns off reasoning entirely; "none" is a valid reasoning level.
80+ // Both display as "None" in the UI but behave differently.
81+ // Arrays from supportsReasoningEffort may include "disable" (e.g. Z.ai GLM), so type the
82+ // full option set as ReasoningEffortExtended | "disable" from the start to avoid casts.
83+ type ReasoningEffortOption = ReasoningEffortExtended | "disable"
8584 const supports = modelInfo ?. supportsReasoningEffort
86- const baseAvailableOptions : ReadonlyArray < ReasoningEffortWithMinimal > =
85+ const baseAvailableOptions : ReadonlyArray < ReasoningEffortOption > =
8786 supports === true
88- ? ( reasoningEfforts as readonly ReasoningEffortWithMinimal [ ] )
87+ ? ( reasoningEfforts as readonly ReasoningEffortOption [ ] )
8988 : Array . isArray ( supports )
90- ? ( supports as ReadonlyArray < ReasoningEffortWithMinimal > )
91- : ( reasoningEfforts as readonly ReasoningEffortWithMinimal [ ] )
89+ ? ( supports as ReadonlyArray < ReasoningEffortOption > )
90+ : ( reasoningEfforts as readonly ReasoningEffortOption [ ] )
9291
93- // "disable" turns off reasoning entirely; "none" is a valid reasoning level.
94- // Both display as "None" in the UI but behave differently.
9592 // Add "disable" option only when:
9693 // 1. requiredReasoningEffort is not true, AND
9794 // 2. supportsReasoningEffort is boolean true (not an explicit array)
9895 // When the model provides an explicit array, respect those exact values.
99- type ReasoningEffortOption = ReasoningEffortWithMinimal | "none" | "disable"
10096 const shouldAutoAddDisable =
101- ! modelInfo ?. requiredReasoningEffort && supports === true && ! baseAvailableOptions . includes ( "disable" as any )
97+ ! modelInfo ?. requiredReasoningEffort && supports === true && ! baseAvailableOptions . includes ( "disable" )
10298 const availableOptions : ReadonlyArray < ReasoningEffortOption > = shouldAutoAddDisable
103- ? ( [ "disable" , ...baseAvailableOptions ] as ReasoningEffortOption [ ] )
104- : ( baseAvailableOptions as ReadonlyArray < ReasoningEffortOption > )
99+ ? [ "disable" , ...baseAvailableOptions ]
100+ : baseAvailableOptions
105101
106102 // Default reasoning effort - use model's default if available
107103 // GPT-5 models have "medium" as their default in the model configuration
108- const modelDefaultReasoningEffort = modelInfo ?. reasoningEffort as ReasoningEffortWithMinimal | undefined
104+ const modelDefaultReasoningEffort = modelInfo ?. reasoningEffort as ReasoningEffortExtended | undefined
109105 const defaultReasoningEffort : ReasoningEffortOption = modelInfo ?. requiredReasoningEffort
110106 ? modelDefaultReasoningEffort || "medium"
111107 : "disable"
112- // Current reasoning effort from settings, or fall back to default
108+ // Current reasoning effort from settings, or fall back to default.
109+ // Clamp to availableOptions so the Select trigger always renders a valid option.
113110 const storedReasoningEffort = apiConfiguration . reasoningEffort as ReasoningEffortOption | undefined
114- const currentReasoningEffort : ReasoningEffortOption = storedReasoningEffort || defaultReasoningEffort
111+ const rawReasoningEffort : ReasoningEffortOption = storedReasoningEffort || defaultReasoningEffort
112+ const currentReasoningEffort : ReasoningEffortOption = availableOptions . includes ( rawReasoningEffort )
113+ ? rawReasoningEffort
114+ : ( availableOptions [ 0 ] ?? rawReasoningEffort )
115115
116116 // Set default reasoning effort when model supports it and no value is set
117117 useEffect ( ( ) => {
118118 if ( isReasoningEffortSupported && ! apiConfiguration . reasoningEffort ) {
119119 // Only set a default if reasoning is required, otherwise leave as undefined (which maps to "disable")
120120 if ( modelInfo ?. requiredReasoningEffort && defaultReasoningEffort !== "disable" ) {
121- setApiConfigurationField ( "reasoningEffort" , defaultReasoningEffort as ReasoningEffortWithMinimal , false )
121+ setApiConfigurationField ( "reasoningEffort" , defaultReasoningEffort as ReasoningEffortExtended , false )
122122 }
123123 }
124124 } , [
@@ -282,7 +282,7 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
282282 } else {
283283 // "none", "minimal", "low", "medium", "high" all enable reasoning
284284 setApiConfigurationField ( "enableReasoningEffort" , true )
285- setApiConfigurationField ( "reasoningEffort" , value as ReasoningEffortWithMinimal )
285+ setApiConfigurationField ( "reasoningEffort" , value as ReasoningEffortExtended )
286286 }
287287 } } >
288288 < SelectTrigger className = "w-full" >
0 commit comments