11import { useCallback , useState , useMemo } from "react"
22import { Checkbox } from "vscrui"
33import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
4+ import { Collapsible , CollapsibleContent , CollapsibleTrigger } from "@src/components/ui/collapsible"
45import { Slider } from "@src/components/ui"
6+ import { ChevronRight } from "lucide-react"
57
68import type { ProviderSettings } from "@roo-code/types"
79import { geminiModels , geminiDefaultModelId , type GeminiModelId } from "@roo-code/types"
@@ -23,6 +25,7 @@ export const Gemini = ({ apiConfiguration, setApiConfigurationField, currentMode
2325 const [ googleGeminiBaseUrlSelected , setGoogleGeminiBaseUrlSelected ] = useState (
2426 ! ! apiConfiguration ?. googleGeminiBaseUrl ,
2527 )
28+ const [ isModelParametersOpen , setIsModelParametersOpen ] = useState ( false )
2629
2730 const modelInfo = useMemo ( ( ) => {
2831 const modelId = (
@@ -84,84 +87,8 @@ export const Gemini = ({ apiConfiguration, setApiConfigurationField, currentMode
8487 ) }
8588 </ div >
8689
87- < div className = "mt-6 border-t border-vscode-widget-border pt-4" >
88- < h3 className = "font-semibold text-lg mb-4" > { t ( "settings:providers.geminiSections.modelParameters" ) } </ h3 >
89-
90- < div className = "mt-4" >
91- < label className = "block font-medium mb-1" >
92- { t ( "settings:providers.geminiParameters.topP.title" ) }
93- </ label >
94- < div className = "flex items-center space-x-2" >
95- < Slider
96- data-testid = "slider-top-p"
97- min = { 0 }
98- max = { 1 }
99- step = { 0.01 }
100- value = { [ apiConfiguration . topP ?? 0.95 ] }
101- onValueChange = { ( values : number [ ] ) => setApiConfigurationField ( "topP" , values [ 0 ] ) }
102- className = "flex-grow"
103- />
104- < span className = "w-10 text-right" > { ( apiConfiguration . topP ?? 0.95 ) . toFixed ( 2 ) } </ span >
105- </ div >
106- < div className = "text-sm text-vscode-descriptionForeground" >
107- { t ( "settings:providers.geminiParameters.topP.description" ) }
108- </ div >
109- </ div >
110-
111- < div className = "mt-4" >
112- < label className = "block font-medium mb-1" >
113- { t ( "settings:providers.geminiParameters.topK.title" ) }
114- </ label >
115- < div className = "flex items-center space-x-2" >
116- < Slider
117- data-testid = "slider-top-k"
118- min = { 0 }
119- max = { 100 }
120- step = { 1 }
121- value = { [ apiConfiguration . topK ?? 64 ] }
122- onValueChange = { ( values : number [ ] ) => setApiConfigurationField ( "topK" , values [ 0 ] ) }
123- className = "flex-grow"
124- />
125- < span className = "w-10 text-right" > { apiConfiguration . topK ?? 64 } </ span >
126- </ div >
127- < div className = "text-sm text-vscode-descriptionForeground" >
128- { t ( "settings:providers.geminiParameters.topK.description" ) }
129- </ div >
130- </ div >
131-
132- < div className = "mt-4" >
133- < label className = "block font-medium mb-1" >
134- { t ( "settings:providers.geminiParameters.maxOutputTokens.title" ) }
135- </ label >
136- < div className = "flex items-center space-x-2" >
137- < Slider
138- data-testid = "slider-max-output-tokens"
139- min = { 3000 }
140- max = { modelInfo . maxTokens }
141- step = { 1 }
142- value = { [ apiConfiguration . maxOutputTokens ?? modelInfo . maxTokens ] }
143- onValueChange = { ( values : number [ ] ) => setApiConfigurationField ( "maxOutputTokens" , values [ 0 ] ) }
144- className = "flex-grow"
145- />
146- < VSCodeTextField
147- value = { ( apiConfiguration . maxOutputTokens ?? modelInfo . maxTokens ) . toString ( ) }
148- type = "text"
149- inputMode = "numeric"
150- onInput = { handleInputChange ( "maxOutputTokens" , ( e ) => {
151- const val = parseInt ( ( e as any ) . target . value , 10 )
152- return Number . isNaN ( val ) ? 0 : Math . min ( val , modelInfo . maxTokens )
153- } ) }
154- className = "w-16"
155- />
156- </ div >
157- < div className = "text-sm text-vscode-descriptionForeground" >
158- { t ( "settings:providers.geminiParameters.maxOutputTokens.description" ) }
159- </ div >
160- </ div >
161- </ div >
162-
163- < div className = "mt-6 border-t border-vscode-widget-border pt-4" >
164- < h3 className = "font-semibold text-lg mb-4" > { t ( "settings:providers.geminiSections.tools" ) } </ h3 >
90+ < div >
91+ < h3 className = "font-semibold text-base mb-4" > { t ( "settings:providers.geminiSections.tools" ) } </ h3 >
16592
16693 < Checkbox
16794 data-testid = "checkbox-url-context"
@@ -183,6 +110,104 @@ export const Gemini = ({ apiConfiguration, setApiConfigurationField, currentMode
183110 { t ( "settings:providers.geminiParameters.groundingSearch.description" ) }
184111 </ div >
185112 </ div >
113+
114+ < div className = "mb-2" >
115+ < Collapsible onOpenChange = { setIsModelParametersOpen } >
116+ < CollapsibleTrigger className = "w-full text-left" >
117+ < div className = "flex items-center justify-between" >
118+ < div className = "flex flex-col" >
119+ < h3 className = "font-semibold text-base" >
120+ { t ( "settings:providers.geminiSections.modelParameters.title" ) }
121+ </ h3 >
122+ < p className = "text-sm text-vscode-descriptionForeground -mt-3" >
123+ { t ( "settings:providers.geminiSections.modelParameters.description" ) }
124+ </ p >
125+ </ div >
126+ < ChevronRight
127+ className = { `transform transition-transform duration-200 mr-2 ${
128+ isModelParametersOpen ? "rotate-90" : ""
129+ } `}
130+ size = { 20 }
131+ />
132+ </ div >
133+ </ CollapsibleTrigger >
134+ < CollapsibleContent >
135+ < div className = "mt-4" >
136+ < label className = "block font-medium mb-1" >
137+ { t ( "settings:providers.geminiParameters.topP.title" ) }
138+ </ label >
139+ < div className = "flex items-center space-x-2" >
140+ < Slider
141+ data-testid = "slider-top-p"
142+ min = { 0 }
143+ max = { 1 }
144+ step = { 0.01 }
145+ value = { [ apiConfiguration . topP ?? 0.95 ] }
146+ onValueChange = { ( values : number [ ] ) => setApiConfigurationField ( "topP" , values [ 0 ] ) }
147+ className = "flex-grow"
148+ />
149+ < span className = "w-10 text-right" > { ( apiConfiguration . topP ?? 0.95 ) . toFixed ( 2 ) } </ span >
150+ </ div >
151+ < div className = "text-sm text-vscode-descriptionForeground" >
152+ { t ( "settings:providers.geminiParameters.topP.description" ) }
153+ </ div >
154+ </ div >
155+
156+ < div className = "mt-4" >
157+ < label className = "block font-medium mb-1" >
158+ { t ( "settings:providers.geminiParameters.topK.title" ) }
159+ </ label >
160+ < div className = "flex items-center space-x-2" >
161+ < Slider
162+ data-testid = "slider-top-k"
163+ min = { 0 }
164+ max = { 100 }
165+ step = { 1 }
166+ value = { [ apiConfiguration . topK ?? 64 ] }
167+ onValueChange = { ( values : number [ ] ) => setApiConfigurationField ( "topK" , values [ 0 ] ) }
168+ className = "flex-grow"
169+ />
170+ < span className = "w-10 text-right" > { apiConfiguration . topK ?? 64 } </ span >
171+ </ div >
172+ < div className = "text-sm text-vscode-descriptionForeground" >
173+ { t ( "settings:providers.geminiParameters.topK.description" ) }
174+ </ div >
175+ </ div >
176+
177+ < div className = "mt-4" >
178+ < label className = "block font-medium mb-1" >
179+ { t ( "settings:providers.geminiParameters.maxOutputTokens.title" ) }
180+ </ label >
181+ < div className = "flex items-center space-x-2" >
182+ < Slider
183+ data-testid = "slider-max-output-tokens"
184+ min = { 3000 }
185+ max = { modelInfo . maxTokens }
186+ step = { 1 }
187+ value = { [ apiConfiguration . maxOutputTokens ?? modelInfo . maxTokens ] }
188+ onValueChange = { ( values : number [ ] ) =>
189+ setApiConfigurationField ( "maxOutputTokens" , values [ 0 ] )
190+ }
191+ className = "flex-grow"
192+ />
193+ < VSCodeTextField
194+ value = { ( apiConfiguration . maxOutputTokens ?? modelInfo . maxTokens ) . toString ( ) }
195+ type = "text"
196+ inputMode = "numeric"
197+ onInput = { handleInputChange ( "maxOutputTokens" , ( e ) => {
198+ const val = parseInt ( ( e as any ) . target . value , 10 )
199+ return Number . isNaN ( val ) ? 0 : Math . min ( val , modelInfo . maxTokens )
200+ } ) }
201+ className = "w-16"
202+ />
203+ </ div >
204+ < div className = "text-sm text-vscode-descriptionForeground" >
205+ { t ( "settings:providers.geminiParameters.maxOutputTokens.description" ) } _{ " " }
206+ </ div >
207+ </ div >
208+ </ CollapsibleContent >
209+ </ Collapsible >
210+ </ div >
186211 </ >
187212 )
188213}
0 commit comments