@@ -8,7 +8,6 @@ import { Field as UiField } from '@ui/components/editor/panel/Field'
88import { Slider as UiSlider } from '@ui/components/editor/panel/Slider'
99import { Input as UiInput } from '@ui/components/editor/common/Input'
1010import { Textarea as UiTextarea } from '@ui/components/editor/common/Textarea'
11- import { Dropdown as UiDropdown } from '@ui/components/editor/common/Dropdown'
1211import { BackendMessage } from '@/views/panel/types/messages'
1312import { PresetOption as UiPresetOption } from '@ui/components/editor/panel/PresetOption'
1413import { Scrollable as UiScrollable } from '@ui/components/editor/panel/Scrollable'
@@ -19,6 +18,10 @@ type Props = {
1918 on_update : ( updated_preset : Preset ) => void
2019 pick_model : ( chatbot_name : string , current_model_id ?: string ) => void
2120 pick_chatbot : ( chatbot_id ?: keyof typeof CHATBOTS ) => void
21+ pick_reasoning_effort : (
22+ supported_efforts : string [ ] ,
23+ current_effort ?: string
24+ ) => void
2225 on_at_sign_in_affix : ( ) => void
2326}
2427
@@ -58,9 +61,11 @@ export const EditPresetForm: React.FC<Props> = (props) => {
5861 'prompt_prefix' | 'prompt_suffix' | null
5962 > ( null )
6063 const [ is_prompt_template_collapsed , set_is_prompt_template_collapsed ] =
61- useState ( true )
64+ useState ( ! ( props . preset . prompt_prefix || props . preset . prompt_suffix ) )
6265 const [ is_sampling_collapsed , set_is_sampling_collapsed ] = useState ( true )
63- const [ is_options_collapsed , set_is_options_collapsed ] = useState ( true )
66+ const [ is_options_collapsed , set_is_options_collapsed ] = useState (
67+ ! props . preset . options ?. length
68+ )
6469
6570 const chatbot_config = chatbot ? CHATBOTS [ chatbot ] : undefined
6671 const models = useMemo ( ( ) => chatbot_config ?. models || { } , [ chatbot_config ] )
@@ -183,6 +188,8 @@ export const EditPresetForm: React.FC<Props> = (props) => {
183188 set_model ( message . model_id )
184189 } else if ( message . command == 'NEWLY_PICKED_CHATBOT' ) {
185190 handle_chatbot_change ( message . chatbot_id as keyof typeof CHATBOTS )
191+ } else if ( message . command == 'NEWLY_PICKED_REASONING_EFFORT' ) {
192+ set_reasoning_effort ( message . effort )
186193 }
187194 }
188195 window . addEventListener ( 'message' , handle_message )
@@ -200,30 +207,21 @@ export const EditPresetForm: React.FC<Props> = (props) => {
200207 }
201208 }
202209
203- const reasoning_effort_options = useMemo ( ( ) => {
204- const supported_efforts =
210+ const supported_reasoning_efforts = useMemo ( ( ) => {
211+ return (
205212 chatbot_config ?. supported_reasoning_efforts ||
206- model_info ?. supported_reasoning_efforts
207-
208- if ( supported_efforts ) {
209- return [
210- { value : '—' , label : '—' } ,
211- ...supported_efforts . map ( ( effort : string ) => {
212- const capitalized = effort . charAt ( 0 ) . toUpperCase ( ) + effort . slice ( 1 )
213- return { value : effort , label : capitalized }
214- } )
215- ]
216- }
217- return [ { value : '—' , label : '—' } ]
213+ model_info ?. supported_reasoning_efforts ||
214+ [ ]
215+ )
218216 } , [ chatbot_config , model_info ] )
219217
220218 useEffect ( ( ) => {
221219 if (
222220 reasoning_effort &&
223- ! reasoning_effort_options . find ( ( o ) => o . value === reasoning_effort )
221+ ! supported_reasoning_efforts . includes ( reasoning_effort )
224222 )
225223 set_reasoning_effort ( undefined )
226- } , [ reasoning_effort , reasoning_effort_options ] )
224+ } , [ reasoning_effort , supported_reasoning_efforts ] )
227225
228226 return (
229227 < UiScrollable >
@@ -347,40 +345,55 @@ export const EditPresetForm: React.FC<Props> = (props) => {
347345 chatbot == 'OpenRouter' ? ' Requires a reasoning model.' : ''
348346 } `}
349347 >
350- < UiDropdown
351- options = { reasoning_effort_options }
352- value = { reasoning_effort || '—' }
353- onChange = { ( value ) => {
354- set_reasoning_effort ( value == '—' ? undefined : value )
348+ < button
349+ className = { dropdown_styles . button }
350+ onClick = { ( e ) => {
351+ e . stopPropagation ( )
352+ props . pick_reasoning_effort (
353+ supported_reasoning_efforts ,
354+ reasoning_effort
355+ )
355356 } }
356- />
357+ >
358+ < span >
359+ { reasoning_effort
360+ ? reasoning_effort . charAt ( 0 ) . toUpperCase ( ) +
361+ reasoning_effort . slice ( 1 )
362+ : '—' }
363+ </ span >
364+ < span
365+ className = { cn (
366+ 'codicon codicon-chevron-down' ,
367+ dropdown_styles . chevron
368+ ) }
369+ />
370+ </ button >
357371 </ UiField >
358372 ) }
359373
360- { supports_thinking_budget &&
361- ! supports_reasoning_effort && ( // Additional check for AI Studio
362- < UiField
363- label = "Thinking Budget"
364- html_for = "thinking-budget"
365- info = "Search for allowed min-max values."
366- >
367- < UiInput
368- id = "thinking-budget"
369- type = "text"
370- value = { String ( thinking_budget ?? '' ) }
371- on_change = { ( value ) => {
372- const num = parseInt ( value , 10 )
373- set_thinking_budget ( isNaN ( num ) ? undefined : num )
374- } }
375- placeholder = "e.g. 8000"
376- on_key_down = { ( e ) =>
377- ! / [ 0 - 9 ] / . test ( e . key ) &&
378- e . key != 'Backspace' &&
379- e . preventDefault ( )
380- }
381- />
382- </ UiField >
383- ) }
374+ { supports_thinking_budget && ! supports_reasoning_effort && (
375+ < UiField
376+ label = "Thinking Budget"
377+ html_for = "thinking-budget"
378+ info = "Search for allowed min-max values."
379+ >
380+ < UiInput
381+ id = "thinking-budget"
382+ type = "text"
383+ value = { String ( thinking_budget ?? '' ) }
384+ on_change = { ( value ) => {
385+ const num = parseInt ( value , 10 )
386+ set_thinking_budget ( isNaN ( num ) ? undefined : num )
387+ } }
388+ placeholder = "e.g. 8000"
389+ on_key_down = { ( e ) =>
390+ ! / [ 0 - 9 ] / . test ( e . key ) &&
391+ e . key != 'Backspace' &&
392+ e . preventDefault ( )
393+ }
394+ />
395+ </ UiField >
396+ ) }
384397
385398 { supports_system_instructions && (
386399 < UiField
@@ -455,9 +468,19 @@ export const EditPresetForm: React.FC<Props> = (props) => {
455468 < UiField
456469 label = "Temperature"
457470 info = "Influences response variety. Lower values are more predictable; higher values are more diverse."
471+ action = {
472+ temperature !== undefined && (
473+ < button
474+ className = { styles . clear }
475+ onClick = { ( ) => set_temperature ( undefined ) }
476+ >
477+ Clear
478+ </ button >
479+ )
480+ }
458481 >
459482 < UiSlider
460- value = { temperature ?? 1 }
483+ value = { temperature }
461484 onChange = { set_temperature }
462485 min = { 0 }
463486 max = { 2 }
@@ -469,13 +492,18 @@ export const EditPresetForm: React.FC<Props> = (props) => {
469492 < UiField
470493 label = "Top P"
471494 info = "Limits token choices to cumulative probability P. Lower values make responses more predictable."
495+ action = {
496+ top_p !== undefined && (
497+ < button
498+ className = { styles . clear }
499+ onClick = { ( ) => set_top_p ( undefined ) }
500+ >
501+ Clear
502+ </ button >
503+ )
504+ }
472505 >
473- < UiSlider
474- value = { top_p ?? 0.95 }
475- onChange = { set_top_p }
476- min = { 0 }
477- max = { 1 }
478- />
506+ < UiSlider value = { top_p } onChange = { set_top_p } min = { 0 } max = { 1 } />
479507 </ UiField >
480508 ) }
481509 </ UiFieldset >
0 commit comments