< Summary

Information
Class: UIBlazor.Components.Settings.SettingsDialog
Assembly: UIBlazor
File(s): /home/runner/work/InvAit/InvAit/UIBlazor/Components/Settings/SettingsDialog.razor
Tag: 71_26091983037
Line coverage
0%
Covered lines: 0
Uncovered lines: 67
Coverable lines: 67
Total lines: 256
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 19
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_ChatService()100%210%
get_NotificationService()100%210%
get_ToolManager()100%210%
get_ProfileManager()100%210%
get_CommonSettingsProvider()100%210%
get_DialogService()100%210%
.ctor()100%210%
OnAddProfile()100%210%
OnDeleteProfile()0%2040%
UpdateModelsAsync()100%210%
GetCategoryName(...)0%5670%
OnCategorySettingChanged()100%210%
OnToolSettingChanged()100%210%

File(s)

/home/runner/work/InvAit/InvAit/UIBlazor/Components/Settings/SettingsDialog.razor

#LineLine coverage
 1@inherits RadzenComponent
 2
 3<RadzenTabs RenderMode="TabRenderMode.Client" class="settings">
 4    <Tabs>
 5        <RadzenTabsItem Text="@SharedResource.SettingsGeneral">
 6            <RadzenStack Gap="1rem">
 7                <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem">
 08                    <RadzenText TextStyle="TextStyle.Subtitle1">@SharedResource.Profile:</RadzenText>
 9                    <RadzenDropDown Data="@ProfileManager.Current.Profiles" TextProperty="Name" ValueProperty="Id"
 10                                    @bind-Value="@ProfileManager.Current.ActiveProfileId"
 11                                    Style="flex: 1;" />
 12                    <RadzenButton Icon="add" ButtonStyle="ButtonStyle.Success" Size="ButtonSize.Small" Variant="Variant.
 13                    <RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Size="ButtonSize.Small" Variant="Varian
 14                                  Disabled="@(ProfileManager.Current.Profiles.Count <= 1)" />
 15                </RadzenStack>
 16
 17                <RadzenFormField Text="@SharedResource.ProfileName" Variant="Variant.Outlined" AllowFloatingLabel="false
 18                    <RadzenTextBox @bind-Value="@ProfileManager.ActiveProfile.Name" Immediate Style="width: 100%" />
 19                </RadzenFormField>
 20
 21                <RadzenFormField Text="@SharedResource.Provider" Variant="Variant.Outlined" AllowFloatingLabel="false">
 22                    <RadzenDropDown Disabled @bind-Value="@ProfileManager.ActiveProfile.Provider" Data="@_providers" Sty
 23                </RadzenFormField>
 24
 25                <RadzenFormField Text="@SharedResource.Endpoint" Variant="Variant.Outlined" AllowFloatingLabel="false">
 26                    <RadzenTextBox @bind-Value="@ProfileManager.ActiveProfile.Endpoint" Style="width: 100%" />
 27                </RadzenFormField>
 28
 29                <RadzenFormField Text="ApiKey" Variant="Variant.Outlined" AllowFloatingLabel="false">
 30                    <RadzenPassword @bind-Value="@ProfileManager.ActiveProfile.ApiKey" Style="width: 100%" />
 31                </RadzenFormField>
 32
 33                <RadzenFormField Text="@SharedResource.SelectModel" Variant="Variant.Outlined" AllowFloatingLabel="false
 34                    <ChildContent>
 35                        <ModelSelector />
 36                    </ChildContent>
 37                    <End>
 38                        <RadzenButton
 39                            Icon="autorenew" Click="UpdateModelsAsync"
 40                            class="@(_isModelUpdating ? "icon-spin" : "")"
 41                            Disabled="@_isModelUpdating"
 42                            ButtonStyle="ButtonStyle.Secondary" />
 43                    </End>
 44                </RadzenFormField>
 45
 46                <CheckBox Text="@SharedResource.UseStream" @bind-Value=@ProfileManager.ActiveProfile.Stream />
 47
 48                <RadzenStack Gap="0.2rem">
 49                    <RadzenLabel Text="@SharedResource.MaxTokens" />
 50                    <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem">
 51                        <RadzenSlider @bind-Value="@ProfileManager.ActiveProfile.MaxTokens" Min=0 Max=30000 Step="1000" 
 52                        <RadzenLabel Text="@($"{ProfileManager.ActiveProfile.MaxTokens}")" Style="text-align: right; wid
 53                    </RadzenStack>
 54                </RadzenStack>
 55
 56                <RadzenStack Gap="0.2rem">
 57                    <RadzenLabel Text="@SharedResource.ContextWindow" />
 58                    <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem">
 59                        <RadzenSlider @bind-Value="@ProfileManager.ActiveProfile.ContextWindow" Min=5000 Max=256000 Step
 60                        <RadzenLabel Text="@($"{ProfileManager.ActiveProfile.ContextWindow / 1000}K")" Style="text-align
 61                    </RadzenStack>
 62                </RadzenStack>
 63
 64                <RadzenStack Gap="0.2rem">
 65                    <RadzenLabel Text="@SharedResource.Temperature" />
 66                    <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem">
 67                        <RadzenSlider @bind-Value="@ProfileManager.ActiveProfile.Temperature" Min="0" Max="2" Step="0.1"
 68                        <RadzenLabel Text="@Math.Abs(ProfileManager.ActiveProfile.Temperature).ToString("0.0")" Style="t
 69                    </RadzenStack>
 70                </RadzenStack>
 71
 72                <RadzenStack Gap="0.2rem">
 73                    <RadzenLabel Text="@SharedResource.CompressionTokenThreshold" />
 74                    <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem">
 75                        <RadzenSlider @bind-Value="@ProfileManager.ActiveProfile.TokensToCompress" Min=0 Max=256000 Step
 76                        <RadzenLabel Text="@($"{ProfileManager.ActiveProfile.TokensToCompress / 1000}K")" Style="text-al
 77                    </RadzenStack>
 78                </RadzenStack>
 79
 80                <RadzenFormField Text="@SharedResource.SystemPrompt" Variant="Variant.Outlined" AllowFloatingLabel="fals
 81                    <RadzenTextArea @bind-Value="@ProfileManager.ActiveProfile.SystemPrompt" Style="min-height: 90px" />
 82                </RadzenFormField>
 83
 84                <ExtraHeaderPicker />
 85                <CheckBox Text="@SharedResource.SkipSSL" @bind-Value=@ProfileManager.ActiveProfile.SkipSSL />
 86            </RadzenStack>
 87        </RadzenTabsItem>
 88        <RadzenTabsItem Text="@SharedResource.SettingsTools">
 89            <RadzenStack Gap="1rem">
 090                @foreach (var category in _toolCategories)
 91                {
 092                    var state = ToolManager.Current.CategoryStates.ContainsKey(category)
 093                    ? ToolManager.Current.CategoryStates[category]
 094                    : new ToolCategorySettings();
 95
 96                    <RadzenStack Gap="0.5rem">
 97                        <RadzenStack Orientation="Orientation.Horizontal" Gap="1rem" AlignItems="AlignItems.Center" Just
 98                            <CheckBox Text="@GetCategoryName(category)" @bind-Value="@state.IsEnabled" @bind-Value:after
 99                            <ApprovalModeSelector Disabled="@(!state.IsEnabled)" @bind-Value="@state.ApprovalMode" @bind
 100                        </RadzenStack>
 101
 102                        <div class="@(state.IsEnabled ? "category-tools-visible" : "category-tools-hidden")">
 103                            @if (state.IsEnabled)
 104                            {
 0105                                var categoryTools = ToolManager.GetBuiltInTools().Where(t => t.Category == category).ToL
 106                                if (categoryTools.Count > 1)
 107                                {
 108                                    <RadzenAccordion>
 109                                        <Items>
 110                                            <RadzenAccordionItem Text="@SharedResource.Tools" Icon="build">
 111                                                <RadzenStack Gap="0.5rem">
 0112                                                    @foreach (var tool in categoryTools)
 113                                                    {
 114                                                        <RadzenStack Orientation="Orientation.Vertical" JustifyContent="
 0115                                                            <CheckBox Text="@tool.Name" @bind-Value="@tool.Enabled" @bin
 0116                                                            <RadzenText TextStyle="TextStyle.Caption" class="tool-descri
 117                                                        </RadzenStack>
 118                                                    }
 119                                                </RadzenStack>
 120                                            </RadzenAccordionItem>
 121                                        </Items>
 122                                    </RadzenAccordion>
 123                                }
 124                            }
 125                        </div>
 126                    </RadzenStack>
 127                }
 128
 129                <RadzenStack Gap="0.2rem">
 130                    <RadzenLabel Text="@SharedResource.ToolRequestTimeoutSec" />
 131                    <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem">
 132                        <RadzenSlider @bind-Value="@CommonSettingsProvider.Current.ToolTimeoutMs" Min="20000" Max="60000
 133                        <RadzenLabel Text="@($"{CommonSettingsProvider.Current.ToolTimeoutMs / 1000} s")" Style="text-al
 134                    </RadzenStack>
 135                </RadzenStack>
 136            </RadzenStack>
 137        </RadzenTabsItem>
 138
 139        <RadzenTabsItem Text="MCP">
 140            <MCPSettingsTab />
 141        </RadzenTabsItem>
 142        <RadzenTabsItem Text="@SharedResource.SettingsMisc">
 143            <RadzenStack Gap="1rem">
 144                <CheckBox Text="@SharedResource.SendCurrentFile" @bind-Value="@CommonSettingsProvider.Current.SendCurren
 145                <CheckBox Text="@SharedResource.SendSolutionsStricture" @bind-Value="@CommonSettingsProvider.Current.Sen
 146
 147                <RadzenStack Gap="0.2rem">
 148                    <RadzenLabel Text="@SharedResource.MaxRetries" />
 149                    <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem">
 150                        <RadzenSlider @bind-Value="@CommonSettingsProvider.Current.MaxRetries" Min="0" Max="50" Step="1"
 151                        <RadzenLabel Text="@CommonSettingsProvider.Current.MaxRetries.ToString()" Style="text-align: rig
 152                    </RadzenStack>
 153                </RadzenStack>
 154
 155                <CheckBox Text="@SharedResource.ShowMessageTimings" @bind-Value="@CommonSettingsProvider.Current.ShowMes
 156
 157                <LanguageSelector />
 158            </RadzenStack>
 159        </RadzenTabsItem>
 160    </Tabs>
 161</RadzenTabs>
 162
 163@code
 164{
 0165    [Inject] IChatService ChatService { get; set; } = null!;
 0166    [Inject] NotificationService NotificationService { get; set; } = null!;
 0167    [Inject] IToolManager ToolManager { get; set; } = null!;
 0168    [Inject] IProfileManager ProfileManager { get; set; } = null!;
 0169    [Inject] ICommonSettingsProvider CommonSettingsProvider { get; set; } = null!;
 0170    [Inject] DialogService DialogService { get; set; } = null!;
 171
 0172    private readonly ToolCategory[] _toolCategories = [
 0173        ToolCategory.ReadFiles,
 0174        ToolCategory.WriteFiles,
 0175        ToolCategory.DeleteFiles,
 0176        ToolCategory.ModeSwitch,
 0177        ToolCategory.Execution
 0178    ];
 0179    private readonly string[] _providers = ["OpenAI Compatible"];
 180    bool _isModelUpdating;
 181
 182    private async Task OnAddProfile()
 183    {
 0184        var newProfile = new ConnectionProfile();
 0185        ProfileManager.Current.Profiles.Add(newProfile);
 0186        await ProfileManager.ActivateProfileAsync(newProfile.Id, true);
 0187    }
 188
 189    private async Task OnDeleteProfile()
 190    {
 0191        if (string.IsNullOrEmpty(ProfileManager.Current.ActiveProfileId))
 192        {
 0193            return;
 194        }
 195
 0196        var confirm = await DialogService.Confirm($"{SharedResource.DeleteProfileQuestion} '{ProfileManager.ActiveProfil
 0197           new ConfirmOptions { OkButtonText = SharedResource.Yes, CancelButtonText = SharedResource.No });
 198
 0199        if (confirm == true)
 200        {
 0201            await ProfileManager.DeleteProfileAsync(ProfileManager.Current.ActiveProfileId);
 202        }
 0203    }
 204
 205    private async Task UpdateModelsAsync()
 206    {
 0207        _isModelUpdating = true;
 208        try
 209        {
 0210            var models = await ChatService.GetModelsAsync(CancellationToken.None);
 0211            var list = models.Data.Select(m => m.Id).ToList();
 0212            ProfileManager.ActiveProfile.AvailableModels = list;
 0213        }
 0214        catch (Exception ex)
 215        {
 0216            NotificationService.Notify(new NotificationMessage
 0217            {
 0218                Severity = NotificationSeverity.Error,
 0219                Summary = SharedResource.ErrorModelsNotFound,
 0220                Detail = ex.Message,
 0221                Duration = 10_000,
 0222                ShowProgress = true,
 0223            });
 0224        }
 225        finally
 226        {
 0227            _isModelUpdating = false;
 228        }
 0229        StateHasChanged();
 0230    }
 231
 232    private string GetCategoryName(ToolCategory category)
 233    {
 0234        return category switch
 0235        {
 0236            ToolCategory.ReadFiles => SharedResource.CategoryReadFiles,
 0237            ToolCategory.WriteFiles => SharedResource.CategoryWriteFiles,
 0238            ToolCategory.DeleteFiles => SharedResource.CategoryDeleteFiles,
 0239            ToolCategory.ModeSwitch => SharedResource.CategoryModeSwitch,
 0240            ToolCategory.Execution => SharedResource.CategoryExecution,
 0241            _ => category.ToString()
 0242        };
 243    }
 244
 245    private async Task OnCategorySettingChanged(ToolCategory category, ToolCategorySettings state)
 246    {
 0247        ToolManager.UpdateCategorySettings(category, state.IsEnabled, state.ApprovalMode);
 0248        await Task.CompletedTask;
 0249    }
 250
 251    private async Task OnToolSettingChanged(Tool tool)
 252    {
 0253        ToolManager.ToggleTool(tool.Name, tool.Enabled);
 0254        await Task.CompletedTask;
 0255    }
 256}