diff --git a/app/MindWork AI Studio/Components/Settings/SettingsPanelProviders.razor b/app/MindWork AI Studio/Components/Settings/SettingsPanelProviders.razor new file mode 100644 index 00000000..cd1b4ffb --- /dev/null +++ b/app/MindWork AI Studio/Components/Settings/SettingsPanelProviders.razor @@ -0,0 +1,124 @@ +@using AIStudio.Provider +@using AIStudio.Settings +@using AIStudio.Provider.SelfHosted +@inherits SettingsPanelBase + + + Configured Providers + + What we call a provider is the combination of an LLM provider such as OpenAI and a model like GPT-4o. + You can configure as many providers as you want. This way, you can use the appropriate model for each + task. As an LLM provider, you can also choose local providers. However, to use this app, you must + configure at least one provider. + + + + + + + + + + + # + Instance Name + Provider + Model + Actions + + + @context.Num + @context.InstanceName + @context.UsedLLMProvider + + @if (context.UsedLLMProvider is not LLMProviders.SELF_HOSTED) + { + @this.GetLLMProviderModelName(context) + } + else if (context.UsedLLMProvider is LLMProviders.SELF_HOSTED && context.Host is not Host.LLAMACPP) + { + @this.GetLLMProviderModelName(context) + } + else + { + @("as selected by provider") + } + + + + Open Dashboard + + + Edit + + + Delete + + + + + + @if(this.SettingsManager.ConfigurationData.Providers.Count == 0) + { + No providers configured yet. + } + + + Add Provider + + + LLM Provider Confidence + + Do you want to always be able to recognize how trustworthy your LLM providers are? This way, + you keep control over which provider you send your data to. You have two options for this: + Either you choose a common schema, or you configure the trust levels for each LLM provider yourself. + + + + @if(this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence) + { + + } + + + @if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence) + { + + @if (this.SettingsManager.ConfigurationData.LLMProviders.ConfidenceScheme is ConfidenceSchemes.CUSTOM) + { + + + + + + + + LLM Provider + Description + Confidence Level + + + + @context.ToName() + + + + + + + @foreach (var confidenceLevel in Enum.GetValues().OrderBy(n => n)) + { + if(confidenceLevel is ConfidenceLevel.NONE or ConfidenceLevel.UNKNOWN) + continue; + + + @confidenceLevel.GetName() + + } + + + + + } + } + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Settings/SettingsPanelProviders.razor.cs b/app/MindWork AI Studio/Components/Settings/SettingsPanelProviders.razor.cs new file mode 100644 index 00000000..e2c434fe --- /dev/null +++ b/app/MindWork AI Studio/Components/Settings/SettingsPanelProviders.razor.cs @@ -0,0 +1,145 @@ +using AIStudio.Dialogs; +using AIStudio.Provider; +using AIStudio.Settings; + +using Microsoft.AspNetCore.Components; + +using DialogOptions = AIStudio.Dialogs.DialogOptions; + +namespace AIStudio.Components.Settings; + +public partial class SettingsPanelProviders : SettingsPanelBase +{ + [Parameter] + public List> AvailableLLMProviders { get; set; } = new(); + + [Parameter] + public EventCallback>> AvailableLLMProvidersChanged { get; set; } + + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + await this.UpdateProviders(); + await base.OnInitializedAsync(); + } + + #endregion + + private async Task AddLLMProvider() + { + var dialogParameters = new DialogParameters + { + { x => x.IsEditing, false }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Add LLM Provider", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var addedProvider = (AIStudio.Settings.Provider)dialogResult.Data!; + addedProvider = addedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; + + this.SettingsManager.ConfigurationData.Providers.Add(addedProvider); + await this.UpdateProviders(); + + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private async Task EditLLMProvider(AIStudio.Settings.Provider provider) + { + var dialogParameters = new DialogParameters + { + { x => x.DataNum, provider.Num }, + { x => x.DataId, provider.Id }, + { x => x.DataInstanceName, provider.InstanceName }, + { x => x.DataLLMProvider, provider.UsedLLMProvider }, + { x => x.DataModel, provider.Model }, + { x => x.DataHostname, provider.Hostname }, + { x => x.IsSelfHosted, provider.IsSelfHosted }, + { x => x.IsEditing, true }, + { x => x.DataHost, provider.Host }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Edit LLM Provider", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var editedProvider = (AIStudio.Settings.Provider)dialogResult.Data!; + + // Set the provider number if it's not set. This is important for providers + // added before we started saving the provider number. + if(editedProvider.Num == 0) + editedProvider = editedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; + + this.SettingsManager.ConfigurationData.Providers[this.SettingsManager.ConfigurationData.Providers.IndexOf(provider)] = editedProvider; + await this.UpdateProviders(); + + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private async Task DeleteLLMProvider(AIStudio.Settings.Provider provider) + { + var dialogParameters = new DialogParameters + { + { "Message", $"Are you sure you want to delete the provider '{provider.InstanceName}'?" }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Delete LLM Provider", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var deleteSecretResponse = await this.RustService.DeleteAPIKey(provider); + if(deleteSecretResponse.Success) + { + this.SettingsManager.ConfigurationData.Providers.Remove(provider); + await this.SettingsManager.StoreSettings(); + } + + await this.UpdateProviders(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private string GetLLMProviderModelName(AIStudio.Settings.Provider provider) + { + const int MAX_LENGTH = 36; + var modelName = provider.Model.ToString(); + return modelName.Length > MAX_LENGTH ? "[...] " + modelName[^Math.Min(MAX_LENGTH, modelName.Length)..] : modelName; + } + + private async Task UpdateProviders() + { + this.AvailableLLMProviders.Clear(); + foreach (var provider in this.SettingsManager.ConfigurationData.Providers) + this.AvailableLLMProviders.Add(new (provider.InstanceName, provider.Id)); + + await this.AvailableLLMProvidersChanged.InvokeAsync(this.AvailableLLMProviders); + } + + private string GetCurrentConfidenceLevelName(LLMProviders llmProvider) + { + if (this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme.TryGetValue(llmProvider, out var level)) + return level.GetName(); + + return "Not yet configured"; + } + + private string SetCurrentConfidenceLevelColorStyle(LLMProviders llmProvider) + { + if (this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme.TryGetValue(llmProvider, out var level)) + return $"background-color: {level.GetColor(this.SettingsManager)};"; + + return $"background-color: {ConfidenceLevel.UNKNOWN.GetColor(this.SettingsManager)};"; + } + + private async Task ChangeCustomConfidenceLevel(LLMProviders llmProvider, ConfidenceLevel level) + { + this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme[llmProvider] = level; + await this.SettingsManager.StoreSettings(); + } +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Pages/Settings.razor b/app/MindWork AI Studio/Pages/Settings.razor index f55be829..4a004734 100644 --- a/app/MindWork AI Studio/Pages/Settings.razor +++ b/app/MindWork AI Studio/Pages/Settings.razor @@ -1,134 +1,11 @@ @attribute [Route(Routes.SETTINGS)] -@using AIStudio.Provider -@using AIStudio.Settings @using AIStudio.Components.Settings -@using Host = AIStudio.Provider.SelfHosted.Host Settings - - Configured Providers - - What we call a provider is the combination of an LLM provider such as OpenAI and a model like GPT-4o. - You can configure as many providers as you want. This way, you can use the appropriate model for each - task. As an LLM provider, you can also choose local providers. However, to use this app, you must - configure at least one provider. - - - - - - - - - - - # - Instance Name - Provider - Model - Actions - - - @context.Num - @context.InstanceName - @context.UsedLLMProvider - - @if (context.UsedLLMProvider is not LLMProviders.SELF_HOSTED) - { - @this.GetLLMProviderModelName(context) - } - else if (context.UsedLLMProvider is LLMProviders.SELF_HOSTED && context.Host is not Host.LLAMACPP) - { - @this.GetLLMProviderModelName(context) - } - else - { - @("as selected by provider") - } - - - - Open Dashboard - - - Edit - - - Delete - - - - - - @if(this.SettingsManager.ConfigurationData.Providers.Count == 0) - { - No providers configured yet. - } - - - Add Provider - - - LLM Provider Confidence - - Do you want to always be able to recognize how trustworthy your LLM providers are? This way, - you keep control over which provider you send your data to. You have two options for this: - Either you choose a common schema, or you configure the trust levels for each LLM provider yourself. - - - - @if(this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence) - { - - } - - - @if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence) - { - - @if (this.SettingsManager.ConfigurationData.LLMProviders.ConfidenceScheme is ConfidenceSchemes.CUSTOM) - { - - - - - - - - LLM Provider - Description - Confidence Level - - - - @context.ToName() - - - - - - - @foreach (var confidenceLevel in Enum.GetValues().OrderBy(n => n)) - { - if(confidenceLevel is ConfidenceLevel.NONE or ConfidenceLevel.UNKNOWN) - continue; - - - @confidenceLevel.GetName() - - } - - - - - } - } - - - + diff --git a/app/MindWork AI Studio/Pages/Settings.razor.cs b/app/MindWork AI Studio/Pages/Settings.razor.cs index 6d8e5c23..a0b9d720 100644 --- a/app/MindWork AI Studio/Pages/Settings.razor.cs +++ b/app/MindWork AI Studio/Pages/Settings.razor.cs @@ -1,31 +1,17 @@ -using AIStudio.Dialogs; -using AIStudio.Provider; using AIStudio.Settings; using Microsoft.AspNetCore.Components; -using DialogOptions = AIStudio.Dialogs.DialogOptions; -using RustService = AIStudio.Tools.RustService; - // ReSharper disable ClassNeverInstantiated.Global namespace AIStudio.Pages; public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable { - [Inject] - private SettingsManager SettingsManager { get; init; } = null!; - - [Inject] - private IDialogService DialogService { get; init; } = null!; - [Inject] private MessageBus MessageBus { get; init; } = null!; - [Inject] - private RustService RustService { get; init; } = null!; - - private readonly List> availableLLMProviders = new(); + private List> availableLLMProviders = new(); private List> availableEmbeddingProviders = new(); #region Overrides of ComponentBase @@ -36,131 +22,11 @@ public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable this.MessageBus.RegisterComponent(this); this.MessageBus.ApplyFilters(this, [], [ Event.CONFIGURATION_CHANGED ]); - this.UpdateProviders(); await base.OnInitializedAsync(); } #endregion - #region Provider related - - private async Task AddLLMProvider() - { - var dialogParameters = new DialogParameters - { - { x => x.IsEditing, false }, - }; - - var dialogReference = await this.DialogService.ShowAsync("Add LLM Provider", dialogParameters, DialogOptions.FULLSCREEN); - var dialogResult = await dialogReference.Result; - if (dialogResult is null || dialogResult.Canceled) - return; - - var addedProvider = (AIStudio.Settings.Provider)dialogResult.Data!; - addedProvider = addedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; - - this.SettingsManager.ConfigurationData.Providers.Add(addedProvider); - this.UpdateProviders(); - - await this.SettingsManager.StoreSettings(); - await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); - } - - private async Task EditLLMProvider(AIStudio.Settings.Provider provider) - { - var dialogParameters = new DialogParameters - { - { x => x.DataNum, provider.Num }, - { x => x.DataId, provider.Id }, - { x => x.DataInstanceName, provider.InstanceName }, - { x => x.DataLLMProvider, provider.UsedLLMProvider }, - { x => x.DataModel, provider.Model }, - { x => x.DataHostname, provider.Hostname }, - { x => x.IsSelfHosted, provider.IsSelfHosted }, - { x => x.IsEditing, true }, - { x => x.DataHost, provider.Host }, - }; - - var dialogReference = await this.DialogService.ShowAsync("Edit LLM Provider", dialogParameters, DialogOptions.FULLSCREEN); - var dialogResult = await dialogReference.Result; - if (dialogResult is null || dialogResult.Canceled) - return; - - var editedProvider = (AIStudio.Settings.Provider)dialogResult.Data!; - - // Set the provider number if it's not set. This is important for providers - // added before we started saving the provider number. - if(editedProvider.Num == 0) - editedProvider = editedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; - - this.SettingsManager.ConfigurationData.Providers[this.SettingsManager.ConfigurationData.Providers.IndexOf(provider)] = editedProvider; - this.UpdateProviders(); - - await this.SettingsManager.StoreSettings(); - await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); - } - - private async Task DeleteLLMProvider(AIStudio.Settings.Provider provider) - { - var dialogParameters = new DialogParameters - { - { "Message", $"Are you sure you want to delete the provider '{provider.InstanceName}'?" }, - }; - - var dialogReference = await this.DialogService.ShowAsync("Delete LLM Provider", dialogParameters, DialogOptions.FULLSCREEN); - var dialogResult = await dialogReference.Result; - if (dialogResult is null || dialogResult.Canceled) - return; - - var deleteSecretResponse = await this.RustService.DeleteAPIKey(provider); - if(deleteSecretResponse.Success) - { - this.SettingsManager.ConfigurationData.Providers.Remove(provider); - await this.SettingsManager.StoreSettings(); - } - - this.UpdateProviders(); - await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); - } - - private string GetLLMProviderModelName(AIStudio.Settings.Provider provider) - { - const int MAX_LENGTH = 36; - var modelName = provider.Model.ToString(); - return modelName.Length > MAX_LENGTH ? "[...] " + modelName[^Math.Min(MAX_LENGTH, modelName.Length)..] : modelName; - } - - private void UpdateProviders() - { - this.availableLLMProviders.Clear(); - foreach (var provider in this.SettingsManager.ConfigurationData.Providers) - this.availableLLMProviders.Add(new (provider.InstanceName, provider.Id)); - } - - private string GetCurrentConfidenceLevelName(LLMProviders llmProvider) - { - if (this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme.TryGetValue(llmProvider, out var level)) - return level.GetName(); - - return "Not yet configured"; - } - - private string SetCurrentConfidenceLevelColorStyle(LLMProviders llmProvider) - { - if (this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme.TryGetValue(llmProvider, out var level)) - return $"background-color: {level.GetColor(this.SettingsManager)};"; - - return $"background-color: {ConfidenceLevel.UNKNOWN.GetColor(this.SettingsManager)};"; - } - - private async Task ChangeCustomConfidenceLevel(LLMProviders llmProvider, ConfidenceLevel level) - { - this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme[llmProvider] = level; - await this.SettingsManager.StoreSettings(); - } - - #endregion - #region Implementation of IMessageBusReceiver public Task ProcessMessage(ComponentBase? sendingComponent, Event triggeredEvent, TMsg? data)