11using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
24using Avalonia . Controls ;
35using Avalonia . Interactivity ;
46
@@ -14,20 +16,206 @@ public class CliSettings
1416 public bool AllowNetworkAccess { get ; set ; } = true ;
1517 public bool ShowMcpResultsInLog { get ; set ; } = true ;
1618 public bool ShowMcpResultsOnlyWhenNoEdits { get ; set ; } = true ;
17- public System . Collections . Generic . List < string > Profiles { get ; set ; } = new ( ) ;
1819 public string SelectedProfile { get ; set ; } = string . Empty ;
1920 public bool UseWsl { get ; set ; } = false ;
2021 public bool CanUseWsl { get ; set ; } = OperatingSystem . IsWindows ( ) ;
22+ public List < CliModelOption > Models { get ; set ; } = new ( ) ;
23+ public string SelectedModelId { get ; set ; } = string . Empty ;
24+ public string SelectedReasoningEffort { get ; set ; } = string . Empty ;
25+ }
26+
27+ public class CliModelOption
28+ {
29+ public string Id { get ; set ; } = string . Empty ;
30+ public string Model { get ; set ; } = string . Empty ;
31+ public string DisplayName { get ; set ; } = string . Empty ;
32+ public string Description { get ; set ; } = string . Empty ;
33+ public string DefaultReasoningEffort { get ; set ; } = string . Empty ;
34+ public List < CliReasoningOption > ReasoningOptions { get ; set ; } = new ( ) ;
35+ public bool IsProfile { get ; set ; }
36+ public string ProfileName { get ; set ; } = string . Empty ;
37+
38+ public override string ToString ( ) => DisplayName ;
39+ }
40+
41+ public class CliReasoningOption
42+ {
43+ public string Effort { get ; set ; } = string . Empty ;
44+ public string DisplayLabel { get ; set ; } = string . Empty ;
45+ public string Description { get ; set ; } = string . Empty ;
46+
47+ public override string ToString ( ) => DisplayLabel ;
2148}
2249
2350public partial class CliSettingsDialog : Window
2451{
52+ private bool _initializingModelSelection ;
53+
2554 public CliSettingsDialog ( )
2655 {
2756 InitializeComponent ( ) ;
2857 }
2958
30- private CliSettings ViewModel => ( DataContext as CliSettings ) ?? new CliSettings ( ) ;
59+ private CliSettings ? ViewModel => DataContext as CliSettings ;
60+
61+ private ComboBox ? ModelComboControl => this . FindControl < ComboBox > ( "ModelComboBox" ) ;
62+ private ComboBox ? ReasoningComboControl => this . FindControl < ComboBox > ( "ReasoningComboBox" ) ;
63+
64+ protected override void OnOpened ( EventArgs e )
65+ {
66+ base . OnOpened ( e ) ;
67+ PopulateModelControls ( ) ;
68+ }
69+
70+ private void PopulateModelControls ( )
71+ {
72+ var vm = ViewModel ;
73+ var modelCombo = ModelComboControl ;
74+ if ( vm is null || modelCombo is null )
75+ return ;
76+
77+ _initializingModelSelection = true ;
78+ try
79+ {
80+ modelCombo . ItemsSource = vm . Models ;
81+
82+ CliModelOption ? selection = null ;
83+ if ( ! string . IsNullOrWhiteSpace ( vm . SelectedProfile ) )
84+ {
85+ selection = vm . Models . FirstOrDefault ( m => m . IsProfile && string . Equals ( m . ProfileName , vm . SelectedProfile , StringComparison . OrdinalIgnoreCase ) ) ;
86+ }
87+
88+ if ( selection is null && ! string . IsNullOrWhiteSpace ( vm . SelectedModelId ) )
89+ {
90+ selection = vm . Models . FirstOrDefault ( m => ! m . IsProfile && string . Equals ( m . Id , vm . SelectedModelId , StringComparison . OrdinalIgnoreCase ) ) ;
91+ }
92+
93+ if ( selection is null && vm . Models . Count > 0 )
94+ {
95+ selection = vm . Models [ 0 ] ;
96+ if ( selection . IsProfile )
97+ {
98+ vm . SelectedProfile = selection . ProfileName ;
99+ vm . SelectedModelId = string . Empty ;
100+ }
101+ else
102+ {
103+ vm . SelectedModelId = selection . Id ;
104+ vm . SelectedProfile = string . Empty ;
105+ }
106+ }
107+
108+ modelCombo . SelectedItem = selection ;
109+ if ( selection != null )
110+ {
111+ if ( selection . IsProfile )
112+ {
113+ vm . SelectedProfile = selection . ProfileName ;
114+ vm . SelectedModelId = string . Empty ;
115+ }
116+ else
117+ {
118+ vm . SelectedProfile = string . Empty ;
119+ vm . SelectedModelId = selection . Id ;
120+ }
121+ }
122+ UpdateReasoningOptionsForModel ( selection , vm . SelectedReasoningEffort ) ;
123+ }
124+ finally
125+ {
126+ _initializingModelSelection = false ;
127+ }
128+ }
129+
130+ private void UpdateReasoningOptionsForModel ( CliModelOption ? model , string ? desiredEffort )
131+ {
132+ var vm = ViewModel ;
133+ var effortCombo = ReasoningComboControl ;
134+ if ( vm is null || effortCombo is null )
135+ return ;
136+
137+ effortCombo . ItemsSource = null ;
138+ if ( model is null )
139+ {
140+ effortCombo . ItemsSource = null ;
141+ effortCombo . IsEnabled = false ;
142+ vm . SelectedReasoningEffort = string . Empty ;
143+ return ;
144+ }
145+
146+ if ( model . IsProfile )
147+ {
148+ effortCombo . ItemsSource = null ;
149+ effortCombo . IsEnabled = false ;
150+ vm . SelectedReasoningEffort = string . Empty ;
151+ return ;
152+ }
153+
154+ effortCombo . IsEnabled = true ;
155+ effortCombo . ItemsSource = model . ReasoningOptions ;
156+
157+ var targetEffort = desiredEffort ;
158+ if ( string . IsNullOrWhiteSpace ( targetEffort ) ||
159+ ! model . ReasoningOptions . Any ( o => string . Equals ( o . Effort , targetEffort , StringComparison . OrdinalIgnoreCase ) ) )
160+ {
161+ targetEffort = model . DefaultReasoningEffort ?? model . ReasoningOptions . FirstOrDefault ( ) ? . Effort ?? string . Empty ;
162+ }
163+
164+ CliReasoningOption ? selectedOption = null ;
165+ if ( ! string . IsNullOrWhiteSpace ( targetEffort ) )
166+ {
167+ selectedOption = model . ReasoningOptions . FirstOrDefault ( o => string . Equals ( o . Effort , targetEffort , StringComparison . OrdinalIgnoreCase ) ) ;
168+ }
169+
170+ if ( selectedOption is null && model . ReasoningOptions . Count > 0 )
171+ {
172+ selectedOption = model . ReasoningOptions [ 0 ] ;
173+ }
174+
175+ effortCombo . SelectedItem = selectedOption ;
176+ vm . SelectedReasoningEffort = selectedOption ? . Effort ?? string . Empty ;
177+ }
178+
179+ private void OnModelSelectionChanged ( object ? sender , SelectionChangedEventArgs e )
180+ {
181+ if ( _initializingModelSelection )
182+ return ;
183+
184+ var vm = ViewModel ;
185+ var selected = ModelComboControl ? . SelectedItem as CliModelOption ;
186+ if ( vm is null || selected is null )
187+ return ;
188+
189+ if ( selected . IsProfile )
190+ {
191+ vm . SelectedProfile = selected . ProfileName ;
192+ vm . SelectedModelId = string . Empty ;
193+ UpdateReasoningOptionsForModel ( selected , null ) ;
194+ }
195+ else
196+ {
197+ vm . SelectedProfile = string . Empty ;
198+ vm . SelectedModelId = selected . Id ;
199+ UpdateReasoningOptionsForModel ( selected , vm . SelectedReasoningEffort ) ;
200+ }
201+ }
202+
203+ private void OnReasoningSelectionChanged ( object ? sender , SelectionChangedEventArgs e )
204+ {
205+ if ( _initializingModelSelection )
206+ return ;
207+
208+ var vm = ViewModel ;
209+ var effortCombo = ReasoningComboControl ;
210+ if ( vm is null || effortCombo is null || effortCombo . IsEnabled == false )
211+ return ;
212+
213+ var option = effortCombo . SelectedItem as CliReasoningOption ;
214+ if ( option is null )
215+ return ;
216+
217+ vm . SelectedReasoningEffort = option . Effort ;
218+ }
31219
32220 private void OnSave ( object ? sender , RoutedEventArgs e )
33221 => Close ( ViewModel ) ;
0 commit comments