diff --git a/app/MindWork AI Studio/Components/Blocks/ConfigurationOption.razor b/app/MindWork AI Studio/Components/Blocks/ConfigurationOption.razor new file mode 100644 index 0000000..73ffe23 --- /dev/null +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationOption.razor @@ -0,0 +1,7 @@ +@inherits ConfigurationBase + + + + @(this.State() ? this.LabelOn : this.LabelOff) + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/ConfigurationOption.razor.cs b/app/MindWork AI Studio/Components/Blocks/ConfigurationOption.razor.cs similarity index 96% rename from app/MindWork AI Studio/Components/ConfigurationOption.razor.cs rename to app/MindWork AI Studio/Components/Blocks/ConfigurationOption.razor.cs index b3bed55..68d5cd4 100644 --- a/app/MindWork AI Studio/Components/ConfigurationOption.razor.cs +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationOption.razor.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Components; -namespace AIStudio.Components; +namespace AIStudio.Components.Blocks; /// /// Configuration component for any boolean option. diff --git a/app/MindWork AI Studio/Components/Blocks/ConfigurationProviderSelection.razor b/app/MindWork AI Studio/Components/Blocks/ConfigurationProviderSelection.razor new file mode 100644 index 0000000..45e6411 --- /dev/null +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationProviderSelection.razor @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Blocks/ConfigurationProviderSelection.razor.cs b/app/MindWork AI Studio/Components/Blocks/ConfigurationProviderSelection.razor.cs new file mode 100644 index 0000000..c860377 --- /dev/null +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationProviderSelection.razor.cs @@ -0,0 +1,83 @@ +using AIStudio.Settings; +using AIStudio.Tools; + +using Microsoft.AspNetCore.Components; + +namespace AIStudio.Components.Blocks; + +public partial class ConfigurationProviderSelection : ComponentBase, IMessageBusReceiver, IDisposable +{ + [Parameter] + public Func SelectedValue { get; set; } = () => string.Empty; + + [Parameter] + public Action SelectionUpdate { get; set; } = _ => { }; + + [Parameter] + public IEnumerable> Data { get; set; } = new List>(); + + /// + /// Is the selection component disabled? + /// + [Parameter] + public Func Disabled { get; set; } = () => false; + + [Inject] + private SettingsManager SettingsManager { get; init; } = null!; + + [Inject] + private MessageBus MessageBus { get; init; } = null!; + + #region Overrides of ComponentBase + + protected override async Task OnParametersSetAsync() + { + // Register this component with the message bus: + this.MessageBus.RegisterComponent(this); + this.MessageBus.ApplyFilters(this, [], [ Event.CONFIGURATION_CHANGED ]); + + await base.OnParametersSetAsync(); + } + + #endregion + + #region Implementation of IMessageBusReceiver + + public async Task ProcessMessage(ComponentBase? sendingComponent, Event triggeredEvent, T? data) + { + switch (triggeredEvent) + { + case Event.CONFIGURATION_CHANGED: + + if(string.IsNullOrWhiteSpace(this.SelectedValue())) + break; + + // Check if the selected value is still valid: + if (this.Data.All(x => x.Value != this.SelectedValue())) + { + this.SelectedValue = () => string.Empty; + this.SelectionUpdate(string.Empty); + await this.SettingsManager.StoreSettings(); + } + + this.StateHasChanged(); + break; + } + } + + public Task ProcessMessageWithResult(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data) + { + return Task.FromResult(default); + } + + #endregion + + #region Implementation of IDisposable + + public void Dispose() + { + this.MessageBus.Unregister(this); + } + + #endregion +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Blocks/ConfigurationSelect.razor b/app/MindWork AI Studio/Components/Blocks/ConfigurationSelect.razor new file mode 100644 index 0000000..b98aea6 --- /dev/null +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationSelect.razor @@ -0,0 +1,11 @@ +@inherits ConfigurationBase +@typeparam T + + + @foreach (var data in this.Data) + { + + @data.Name + + } + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/ConfigurationSelect.razor.cs b/app/MindWork AI Studio/Components/Blocks/ConfigurationSelect.razor.cs similarity index 94% rename from app/MindWork AI Studio/Components/ConfigurationSelect.razor.cs rename to app/MindWork AI Studio/Components/Blocks/ConfigurationSelect.razor.cs index 07c8abf..4f0fe49 100644 --- a/app/MindWork AI Studio/Components/ConfigurationSelect.razor.cs +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationSelect.razor.cs @@ -1,6 +1,8 @@ +using AIStudio.Settings; + using Microsoft.AspNetCore.Components; -namespace AIStudio.Components; +namespace AIStudio.Components.Blocks; /// /// Configuration component for selecting a value from a list. diff --git a/app/MindWork AI Studio/Components/Blocks/ConfigurationSlider.razor b/app/MindWork AI Studio/Components/Blocks/ConfigurationSlider.razor new file mode 100644 index 0000000..b42f4a4 --- /dev/null +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationSlider.razor @@ -0,0 +1,8 @@ +@typeparam T +@inherits ConfigurationBase + + + + @this.Value() @this.Unit + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Blocks/ConfigurationSlider.razor.cs b/app/MindWork AI Studio/Components/Blocks/ConfigurationSlider.razor.cs new file mode 100644 index 0000000..0df46f3 --- /dev/null +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationSlider.razor.cs @@ -0,0 +1,51 @@ +using System.Numerics; + +using Microsoft.AspNetCore.Components; + +namespace AIStudio.Components.Blocks; + +public partial class ConfigurationSlider : ConfigurationBase where T : struct, INumber +{ + /// + /// The minimum value for the slider. + /// + [Parameter] + public T Min { get; set; } = T.Zero; + + /// + /// The maximum value for the slider. + /// + [Parameter] + public T Max { get; set; } = T.One; + + /// + /// The step size for the slider. + /// + [Parameter] + public T Step { get; set; } = T.One; + + /// + /// The unit to display next to the slider's value. + /// + [Parameter] + public string Unit { get; set; } = string.Empty; + + /// + /// The value used for the slider. + /// + [Parameter] + public Func Value { get; set; } = () => T.Zero; + + /// + /// An action which is called when the option is changed. + /// + [Parameter] + public Action ValueUpdate { get; set; } = _ => { }; + + private async Task OptionChanged(T updatedValue) + { + this.ValueUpdate(updatedValue); + await this.SettingsManager.StoreSettings(); + await this.InformAboutChange(); + } +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Blocks/ConfigurationText.razor b/app/MindWork AI Studio/Components/Blocks/ConfigurationText.razor new file mode 100644 index 0000000..73d07be --- /dev/null +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationText.razor @@ -0,0 +1,18 @@ +@inherits ConfigurationBase + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Blocks/ConfigurationText.razor.cs b/app/MindWork AI Studio/Components/Blocks/ConfigurationText.razor.cs new file mode 100644 index 0000000..228fa13 --- /dev/null +++ b/app/MindWork AI Studio/Components/Blocks/ConfigurationText.razor.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Components; + +namespace AIStudio.Components.Blocks; + +public partial class ConfigurationText : ConfigurationBase +{ + /// + /// The text used for the textfield. + /// + [Parameter] + public Func Text { get; set; } = () => string.Empty; + + /// + /// An action which is called when the option is changed. + /// + [Parameter] + public Action TextUpdate { get; set; } = _ => { }; + + /// + /// The icon to display next to the textfield. + /// + [Parameter] + public string Icon { get; set; } = Icons.Material.Filled.Info; + + /// + /// The color of the icon to use. + /// + [Parameter] + public Color IconColor { get; set; } = Color.Default; + + private async Task OptionChanged(string updatedText) + { + this.TextUpdate(updatedText); + await this.SettingsManager.StoreSettings(); + await this.InformAboutChange(); + } +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/ConfigurationBase.razor.cs b/app/MindWork AI Studio/Components/ConfigurationBase.razor.cs index 03dc7db..bad94f6 100644 --- a/app/MindWork AI Studio/Components/ConfigurationBase.razor.cs +++ b/app/MindWork AI Studio/Components/ConfigurationBase.razor.cs @@ -8,7 +8,7 @@ namespace AIStudio.Components; /// /// A base class for configuration options. /// -public partial class ConfigurationBase : ComponentBase +public partial class ConfigurationBase : ComponentBase, IMessageBusReceiver, IDisposable { /// /// The description of the option, i.e., the name. Should be @@ -23,6 +23,12 @@ public partial class ConfigurationBase : ComponentBase [Parameter] public string OptionHelp { get; set; } = string.Empty; + /// + /// Is the option disabled? + /// + [Parameter] + public Func Disabled { get; set; } = () => false; + [Inject] protected SettingsManager SettingsManager { get; init; } = null!; @@ -30,6 +36,53 @@ public partial class ConfigurationBase : ComponentBase protected MessageBus MessageBus { get; init; } = null!; protected const string MARGIN_CLASS = "mb-6"; + protected static readonly Dictionary SPELLCHECK_ATTRIBUTES = new(); + + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + // Configure the spellchecking for the instance name input: + this.SettingsManager.InjectSpellchecking(SPELLCHECK_ATTRIBUTES); + + // Register this component with the message bus: + this.MessageBus.RegisterComponent(this); + this.MessageBus.ApplyFilters(this, [], [ Event.CONFIGURATION_CHANGED ]); + + await base.OnInitializedAsync(); + } + + #endregion protected async Task InformAboutChange() => await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + + #region Implementation of IMessageBusReceiver + + public Task ProcessMessage(ComponentBase? sendingComponent, Event triggeredEvent, TMsg? data) + { + switch (triggeredEvent) + { + case Event.CONFIGURATION_CHANGED: + this.StateHasChanged(); + break; + } + + return Task.CompletedTask; + } + + public Task ProcessMessageWithResult(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data) + { + return Task.FromResult(default); + } + + #endregion + + #region Implementation of IDisposable + + public void Dispose() + { + this.MessageBus.Unregister(this); + } + + #endregion } \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/ConfigurationOption.razor b/app/MindWork AI Studio/Components/ConfigurationOption.razor deleted file mode 100644 index f8de2b9..0000000 --- a/app/MindWork AI Studio/Components/ConfigurationOption.razor +++ /dev/null @@ -1,7 +0,0 @@ -@inherits ConfigurationBase - - - - @(this.State() ? this.LabelOn : this.LabelOff) - - \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/ConfigurationSelect.razor b/app/MindWork AI Studio/Components/ConfigurationSelect.razor deleted file mode 100644 index 852f7c6..0000000 --- a/app/MindWork AI Studio/Components/ConfigurationSelect.razor +++ /dev/null @@ -1,11 +0,0 @@ -@inherits ConfigurationBase -@typeparam T - - - @foreach (var data in this.Data) - { - - @data.Name - - } - \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/ConfigurationTrigger.razor b/app/MindWork AI Studio/Components/ConfigurationTrigger.razor deleted file mode 100644 index 5e1103f..0000000 --- a/app/MindWork AI Studio/Components/ConfigurationTrigger.razor +++ /dev/null @@ -1,7 +0,0 @@ -@inherits ConfigurationBase - - - - @this.TriggerText - - \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/ConfigurationTrigger.razor.cs b/app/MindWork AI Studio/Components/ConfigurationTrigger.razor.cs deleted file mode 100644 index 2f10e5d..0000000 --- a/app/MindWork AI Studio/Components/ConfigurationTrigger.razor.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.AspNetCore.Components; - -namespace AIStudio.Components; - -public partial class ConfigurationTrigger : ConfigurationBase -{ - [Parameter] - public string TriggerText { get; set; } = string.Empty; - - [Parameter] - public string TriggerIcon { get; set; } = Icons.Material.Filled.AddBox; - - [Parameter] - public Action OnClickSync { get; set; } = () => { }; - - [Parameter] - public Func OnClickAsync { get; set; } = () => Task.CompletedTask; - - private async Task Click() - { - this.OnClickSync(); - await this.OnClickAsync(); - } -} \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Layout/MainLayout.razor b/app/MindWork AI Studio/Components/Layout/MainLayout.razor index 1e6eb6a..c7044e7 100644 --- a/app/MindWork AI Studio/Components/Layout/MainLayout.razor +++ b/app/MindWork AI Studio/Components/Layout/MainLayout.razor @@ -1,4 +1,4 @@ -@using AIStudio.Settings +@using AIStudio.Settings.DataModel @inherits LayoutComponentBase diff --git a/app/MindWork AI Studio/Components/Layout/MainLayout.razor.cs b/app/MindWork AI Studio/Components/Layout/MainLayout.razor.cs index 6223b33..8bd60a9 100644 --- a/app/MindWork AI Studio/Components/Layout/MainLayout.razor.cs +++ b/app/MindWork AI Studio/Components/Layout/MainLayout.razor.cs @@ -1,5 +1,6 @@ using AIStudio.Components.CommonDialogs; using AIStudio.Settings; +using AIStudio.Settings.DataModel; using AIStudio.Tools; using Microsoft.AspNetCore.Components; @@ -9,7 +10,7 @@ using DialogOptions = AIStudio.Components.CommonDialogs.DialogOptions; namespace AIStudio.Components.Layout; -public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver +public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDisposable { [Inject] private IJSRuntime JsRuntime { get; init; } = null!; @@ -211,4 +212,13 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver await MessageBus.INSTANCE.SendMessage(this, Event.RESET_CHAT_STATE); } } + + #region Implementation of IDisposable + + public void Dispose() + { + this.MessageBus.Unregister(this); + } + + #endregion } \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Pages/Assistants.razor b/app/MindWork AI Studio/Components/Pages/Assistants.razor index 6495364..bfb25c4 100644 --- a/app/MindWork AI Studio/Components/Pages/Assistants.razor +++ b/app/MindWork AI Studio/Components/Pages/Assistants.razor @@ -7,6 +7,6 @@ - + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Pages/Chat.razor b/app/MindWork AI Studio/Components/Pages/Chat.razor index 807100f..a039e2c 100644 --- a/app/MindWork AI Studio/Components/Pages/Chat.razor +++ b/app/MindWork AI Studio/Components/Pages/Chat.razor @@ -1,6 +1,7 @@ @page "/chat" @using AIStudio.Chat @using AIStudio.Settings +@using AIStudio.Settings.DataModel @inherits MSGComponentBase diff --git a/app/MindWork AI Studio/Components/Pages/Chat.razor.cs b/app/MindWork AI Studio/Components/Pages/Chat.razor.cs index 491053d..6f1a403 100644 --- a/app/MindWork AI Studio/Components/Pages/Chat.razor.cs +++ b/app/MindWork AI Studio/Components/Pages/Chat.razor.cs @@ -3,6 +3,7 @@ using AIStudio.Components.Blocks; using AIStudio.Components.CommonDialogs; using AIStudio.Provider; using AIStudio.Settings; +using AIStudio.Settings.DataModel; using AIStudio.Tools; using Microsoft.AspNetCore.Components; diff --git a/app/MindWork AI Studio/Components/Pages/Coding/AssistantCoding.razor b/app/MindWork AI Studio/Components/Pages/Coding/AssistantCoding.razor index b286582..2f9af4b 100644 --- a/app/MindWork AI Studio/Components/Pages/Coding/AssistantCoding.razor +++ b/app/MindWork AI Studio/Components/Pages/Coding/AssistantCoding.razor @@ -16,7 +16,7 @@ - + @(this.provideCompilerMessages ? "Provide compiler messages" : "Provide no compiler messages") @if (this.provideCompilerMessages) diff --git a/app/MindWork AI Studio/Components/Pages/Coding/AssistantCoding.razor.cs b/app/MindWork AI Studio/Components/Pages/Coding/AssistantCoding.razor.cs index 5c0a2be..b4e5057 100644 --- a/app/MindWork AI Studio/Components/Pages/Coding/AssistantCoding.razor.cs +++ b/app/MindWork AI Studio/Components/Pages/Coding/AssistantCoding.razor.cs @@ -28,7 +28,22 @@ public partial class AssistantCoding : AssistantBaseCore private bool provideCompilerMessages; private string compilerMessages = string.Empty; private string questions = string.Empty; - + + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + if (this.SettingsManager.ConfigurationData.PreselectCodingOptions) + { + this.provideCompilerMessages = this.SettingsManager.ConfigurationData.PreselectCodingCompilerMessages; + this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.PreselectedCodingProvider); + } + + await base.OnInitializedAsync(); + } + + #endregion + private string? ValidatingCompilerMessages(string checkCompilerMessages) { if(!this.provideCompilerMessages) @@ -53,6 +68,8 @@ public partial class AssistantCoding : AssistantBaseCore this.codingContexts.Add(new() { Id = $"Context {this.codingContexts.Count + 1}", + Language = this.SettingsManager.ConfigurationData.PreselectCodingOptions ? this.SettingsManager.ConfigurationData.PreselectedCodingLanguage : default, + OtherLanguage = this.SettingsManager.ConfigurationData.PreselectCodingOptions ? this.SettingsManager.ConfigurationData.PreselectedCodingOtherLanguage : string.Empty, }); } diff --git a/app/MindWork AI Studio/Components/Pages/IconFinder/AssistantIconFinder.razor.cs b/app/MindWork AI Studio/Components/Pages/IconFinder/AssistantIconFinder.razor.cs index a04398b..a2cf367 100644 --- a/app/MindWork AI Studio/Components/Pages/IconFinder/AssistantIconFinder.razor.cs +++ b/app/MindWork AI Studio/Components/Pages/IconFinder/AssistantIconFinder.razor.cs @@ -5,6 +5,21 @@ public partial class AssistantIconFinder : AssistantBaseCore private string inputContext = string.Empty; private IconSources selectedIconSource; + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + if (this.SettingsManager.ConfigurationData.PreselectIconOptions) + { + this.selectedIconSource = this.SettingsManager.ConfigurationData.PreselectedIconSource; + this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.PreselectedIconProvider); + } + + await base.OnInitializedAsync(); + } + + #endregion + protected override string Title => "Icon Finder"; protected override string Description => diff --git a/app/MindWork AI Studio/Components/Pages/Settings.razor b/app/MindWork AI Studio/Components/Pages/Settings.razor index 7292c42..0667397 100644 --- a/app/MindWork AI Studio/Components/Pages/Settings.razor +++ b/app/MindWork AI Studio/Components/Pages/Settings.razor @@ -1,5 +1,9 @@ @page "/settings" +@using AIStudio.Components.Pages.Coding +@using AIStudio.Components.Pages.TextSummarizer @using AIStudio.Provider +@using AIStudio.Settings +@using AIStudio.Tools @using Host = AIStudio.Provider.SelfHosted.Host Settings @@ -59,20 +63,71 @@ No providers configured yet. } - + Add Provider - Options + App Options - + + + Chat Options + + + Workspace Options - + + Assistants Options + + Icon Finder Options + + + + + + + Translator Options + + + + + + @if (this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage is CommonLanguages.OTHER) + { + + } + + + + Coding Options + + + + + @if (this.SettingsManager.ConfigurationData.PreselectedCodingLanguage is CommonCodingLanguages.OTHER) + { + + } + + + + Text Summarizer Options + + + + @if (this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage is CommonLanguages.OTHER) + { + + } + + @if(this.SettingsManager.ConfigurationData.PreselectedTextSummarizerComplexity is Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS) + { + + } + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Pages/Settings.razor.cs b/app/MindWork AI Studio/Components/Pages/Settings.razor.cs index 2bf6f5f..1d72669 100644 --- a/app/MindWork AI Studio/Components/Pages/Settings.razor.cs +++ b/app/MindWork AI Studio/Components/Pages/Settings.razor.cs @@ -11,7 +11,7 @@ using DialogOptions = AIStudio.Components.CommonDialogs.DialogOptions; namespace AIStudio.Components.Pages; -public partial class Settings : ComponentBase +public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable { [Inject] public SettingsManager SettingsManager { get; init; } = null!; @@ -24,6 +24,22 @@ public partial class Settings : ComponentBase [Inject] protected MessageBus MessageBus { get; init; } = null!; + + private readonly List> availableProviders = new(); + + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + // Register this component with the message bus: + this.MessageBus.RegisterComponent(this); + this.MessageBus.ApplyFilters(this, [], [ Event.CONFIGURATION_CHANGED ]); + + this.UpdateProviders(); + await base.OnInitializedAsync(); + } + + #endregion #region Provider related @@ -43,6 +59,8 @@ public partial class Settings : ComponentBase 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); } @@ -75,6 +93,8 @@ public partial class Settings : ComponentBase 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); } @@ -99,6 +119,7 @@ public partial class Settings : ComponentBase await this.SettingsManager.StoreSettings(); } + this.UpdateProviders(); await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); } @@ -128,6 +149,43 @@ public partial class Settings : ComponentBase var modelName = provider.Model.ToString(); return modelName.Length > MAX_LENGTH ? "[...] " + modelName[^Math.Min(MAX_LENGTH, modelName.Length)..] : modelName; } + + private void UpdateProviders() + { + this.availableProviders.Clear(); + foreach (var provider in this.SettingsManager.ConfigurationData.Providers) + this.availableProviders.Add(new (provider.InstanceName, provider.Id)); + } + + #endregion + + #region Implementation of IMessageBusReceiver + + public Task ProcessMessage(ComponentBase? sendingComponent, Event triggeredEvent, TMsg? data) + { + switch (triggeredEvent) + { + case Event.CONFIGURATION_CHANGED: + this.StateHasChanged(); + break; + } + + return Task.CompletedTask; + } + + public Task ProcessMessageWithResult(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data) + { + return Task.FromResult(default); + } + + #endregion + + #region Implementation of IDisposable + + public void Dispose() + { + this.MessageBus.Unregister(this); + } #endregion } \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Pages/TextSummarizer/AssistantTextSummarizer.razor.cs b/app/MindWork AI Studio/Components/Pages/TextSummarizer/AssistantTextSummarizer.razor.cs index 1a15c90..829206d 100644 --- a/app/MindWork AI Studio/Components/Pages/TextSummarizer/AssistantTextSummarizer.razor.cs +++ b/app/MindWork AI Studio/Components/Pages/TextSummarizer/AssistantTextSummarizer.razor.cs @@ -29,6 +29,24 @@ public partial class AssistantTextSummarizer : AssistantBaseCore private Complexity selectedComplexity; private string expertInField = string.Empty; + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + if(this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions) + { + this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage; + this.customTargetLanguage = this.SettingsManager.ConfigurationData.PreselectedTextSummarizerOtherLanguage; + this.selectedComplexity = this.SettingsManager.ConfigurationData.PreselectedTextSummarizerComplexity; + this.expertInField = this.SettingsManager.ConfigurationData.PreselectedTextSummarizerExpertInField; + this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.PreselectedTextSummarizerProvider); + } + + await base.OnInitializedAsync(); + } + + #endregion + private string? ValidatingText(string text) { if(string.IsNullOrWhiteSpace(text)) diff --git a/app/MindWork AI Studio/Components/Pages/Translator/AssistantTranslator.razor b/app/MindWork AI Studio/Components/Pages/Translation/AssistantTranslation.razor similarity index 95% rename from app/MindWork AI Studio/Components/Pages/Translator/AssistantTranslator.razor rename to app/MindWork AI Studio/Components/Pages/Translation/AssistantTranslation.razor index ac06d21..8d14032 100644 --- a/app/MindWork AI Studio/Components/Pages/Translator/AssistantTranslator.razor +++ b/app/MindWork AI Studio/Components/Pages/Translation/AssistantTranslation.razor @@ -1,10 +1,10 @@ -@page "/assistant/translator" +@page "/assistant/translation" @using AIStudio.Settings @using AIStudio.Tools @inherits AssistantBaseCore - + @(this.liveTranslation ? "Live translation" : "No live translation") diff --git a/app/MindWork AI Studio/Components/Pages/Translator/AssistantTranslator.razor.cs b/app/MindWork AI Studio/Components/Pages/Translation/AssistantTranslation.razor.cs similarity index 70% rename from app/MindWork AI Studio/Components/Pages/Translator/AssistantTranslator.razor.cs rename to app/MindWork AI Studio/Components/Pages/Translation/AssistantTranslation.razor.cs index fcfcef3..1ae77c1 100644 --- a/app/MindWork AI Studio/Components/Pages/Translator/AssistantTranslator.razor.cs +++ b/app/MindWork AI Studio/Components/Pages/Translation/AssistantTranslation.razor.cs @@ -1,10 +1,10 @@ using AIStudio.Tools; -namespace AIStudio.Components.Pages.Translator; +namespace AIStudio.Components.Pages.Translation; -public partial class AssistantTranslator : AssistantBaseCore +public partial class AssistantTranslation : AssistantBaseCore { - protected override string Title => "Translator"; + protected override string Title => "Translation"; protected override string Description => """ @@ -24,7 +24,24 @@ public partial class AssistantTranslator : AssistantBaseCore private string inputTextLastTranslation = string.Empty; private CommonLanguages selectedTargetLanguage; private string customTargetLanguage = string.Empty; - + + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + if (this.SettingsManager.ConfigurationData.PreselectTranslationOptions) + { + this.liveTranslation = this.SettingsManager.ConfigurationData.PreselectLiveTranslation; + this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage; + this.customTargetLanguage = this.SettingsManager.ConfigurationData.PreselectTranslationOtherLanguage; + this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.PreselectedTranslationProvider); + } + + await base.OnInitializedAsync(); + } + + #endregion + private string? ValidatingText(string text) { if(string.IsNullOrWhiteSpace(text)) diff --git a/app/MindWork AI Studio/Components/Pages/Translator/CommonLanguageExtension.cs b/app/MindWork AI Studio/Components/Pages/Translation/CommonLanguageExtension.cs similarity index 87% rename from app/MindWork AI Studio/Components/Pages/Translator/CommonLanguageExtension.cs rename to app/MindWork AI Studio/Components/Pages/Translation/CommonLanguageExtension.cs index 3754515..97dcbbc 100644 --- a/app/MindWork AI Studio/Components/Pages/Translator/CommonLanguageExtension.cs +++ b/app/MindWork AI Studio/Components/Pages/Translation/CommonLanguageExtension.cs @@ -1,6 +1,6 @@ using AIStudio.Tools; -namespace AIStudio.Components.Pages.Translator; +namespace AIStudio.Components.Pages.Translation; public static class CommonLanguageExtension { diff --git a/app/MindWork AI Studio/Components/ConfigurationSelectData.cs b/app/MindWork AI Studio/Settings/ConfigurationSelectData.cs similarity index 74% rename from app/MindWork AI Studio/Components/ConfigurationSelectData.cs rename to app/MindWork AI Studio/Settings/ConfigurationSelectData.cs index cdb9cf4..95269f5 100644 --- a/app/MindWork AI Studio/Components/ConfigurationSelectData.cs +++ b/app/MindWork AI Studio/Settings/ConfigurationSelectData.cs @@ -1,6 +1,10 @@ -using AIStudio.Settings; +using AIStudio.Components.Pages.Coding; +using AIStudio.Components.Pages.IconFinder; +using AIStudio.Components.Pages.TextSummarizer; +using AIStudio.Settings.DataModel; +using AIStudio.Tools; -namespace AIStudio.Components; +namespace AIStudio.Settings; /// /// A data structure to map a name to a value. @@ -55,4 +59,28 @@ public static class ConfigurationSelectDataFactory yield return new("Navigation never expands, no tooltips", NavBehavior.NEVER_EXPAND_NO_TOOLTIPS); yield return new("Always expand navigation", NavBehavior.ALWAYS_EXPAND); } + + public static IEnumerable> GetIconSourcesData() + { + foreach (var source in Enum.GetValues()) + yield return new(source.Name(), source); + } + + public static IEnumerable> GetCommonLanguagesData() + { + foreach (var language in Enum.GetValues()) + yield return new(language.Name(), language); + } + + public static IEnumerable> GetCommonCodingLanguagesData() + { + foreach (var language in Enum.GetValues()) + yield return new(language.Name(), language); + } + + public static IEnumerable> GetComplexityData() + { + foreach (var complexity in Enum.GetValues()) + yield return new(complexity.Name(), complexity); + } } \ No newline at end of file diff --git a/app/MindWork AI Studio/Settings/Data.cs b/app/MindWork AI Studio/Settings/Data.cs deleted file mode 100644 index f18fd85..0000000 --- a/app/MindWork AI Studio/Settings/Data.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace AIStudio.Settings; - -/// -/// The data model for the settings file. -/// -public sealed class Data -{ - /// - /// The version of the settings file. Allows us to upgrade the settings - /// when a new version is available. - /// - public Version Version { get; init; } = Version.V3; - - /// - /// List of configured providers. - /// - public List Providers { get; init; } = []; - - /// - /// The next provider number to use. - /// - public uint NextProviderNum { get; set; } = 1; - - /// - /// Should we save energy? When true, we will update content streamed - /// from the server, i.e., AI, less frequently. - /// - public bool IsSavingEnergy { get; set; } - - /// - /// Shortcuts to send the input to the AI. - /// - public SendBehavior ShortcutSendBehavior { get; set; } = SendBehavior.MODIFER_ENTER_IS_SENDING; - - /// - /// Should we enable spellchecking for all input fields? - /// - public bool EnableSpellchecking { get; set; } - - /// - /// If and when we should look for updates. - /// - public UpdateBehavior UpdateBehavior { get; set; } = UpdateBehavior.ONCE_STARTUP; - - /// - /// The chat storage behavior. - /// - public WorkspaceStorageBehavior WorkspaceStorageBehavior { get; set; } = WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY; - - /// - /// The chat storage maintenance behavior. - /// - public WorkspaceStorageTemporaryMaintenancePolicy WorkspaceStorageTemporaryMaintenancePolicy { get; set; } = WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS; - - /// - /// The navigation behavior. - /// - public NavBehavior NavigationBehavior { get; set; } = NavBehavior.EXPAND_ON_HOVER; -} \ No newline at end of file diff --git a/app/MindWork AI Studio/Settings/DataModel/Data.cs b/app/MindWork AI Studio/Settings/DataModel/Data.cs new file mode 100644 index 0000000..251011c --- /dev/null +++ b/app/MindWork AI Studio/Settings/DataModel/Data.cs @@ -0,0 +1,192 @@ +using AIStudio.Components.Pages.Coding; +using AIStudio.Components.Pages.IconFinder; +using AIStudio.Components.Pages.TextSummarizer; +using AIStudio.Tools; + +namespace AIStudio.Settings.DataModel; + +/// +/// The data model for the settings file. +/// +public sealed class Data +{ + /// + /// The version of the settings file. Allows us to upgrade the settings + /// when a new version is available. + /// + public Version Version { get; init; } = Version.V3; + + /// + /// List of configured providers. + /// + public List Providers { get; init; } = []; + + /// + /// The next provider number to use. + /// + public uint NextProviderNum { get; set; } = 1; + + #region App Settings + + /// + /// Should we save energy? When true, we will update content streamed + /// from the server, i.e., AI, less frequently. + /// + public bool IsSavingEnergy { get; set; } + + /// + /// Should we enable spellchecking for all input fields? + /// + public bool EnableSpellchecking { get; set; } + + /// + /// If and when we should look for updates. + /// + public UpdateBehavior UpdateBehavior { get; set; } = UpdateBehavior.ONCE_STARTUP; + + /// + /// The navigation behavior. + /// + public NavBehavior NavigationBehavior { get; set; } = NavBehavior.EXPAND_ON_HOVER; + + #endregion + + #region Chat Settings + + /// + /// Shortcuts to send the input to the AI. + /// + public SendBehavior ShortcutSendBehavior { get; set; } = SendBehavior.MODIFER_ENTER_IS_SENDING; + + #endregion + + #region Workspace Settings + + /// + /// The chat storage behavior. + /// + public WorkspaceStorageBehavior WorkspaceStorageBehavior { get; set; } = WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY; + + /// + /// The chat storage maintenance behavior. + /// + public WorkspaceStorageTemporaryMaintenancePolicy WorkspaceStorageTemporaryMaintenancePolicy { get; set; } = WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS; + + #endregion + + #region Assiatant: Icon Finder Settings + + /// + /// Do we want to preselect any icon options? + /// + public bool PreselectIconOptions { get; set; } + + /// + /// The preselected icon source. + /// + public IconSources PreselectedIconSource { get; set; } + + /// + /// The preselected icon provider. + /// + public string PreselectedIconProvider { get; set; } = string.Empty; + + #endregion + + #region Assistant: Translation Settings + + /// + /// The live translation interval for debouncing in milliseconds. + /// + public int LiveTranslationDebounceIntervalMilliseconds { get; set; } = 1_000; + + /// + /// Do we want to preselect any translator options? + /// + public bool PreselectTranslationOptions { get; set; } + + /// + /// Preselect the live translation? + /// + public bool PreselectLiveTranslation { get; set; } + + /// + /// Preselect the target language? + /// + public CommonLanguages PreselectedTranslationTargetLanguage { get; set; } = CommonLanguages.EN_US; + + /// + /// Preselect any other language? + /// + public string PreselectTranslationOtherLanguage { get; set; } = string.Empty; + + /// + /// The preselected translator provider. + /// + public string PreselectedTranslationProvider { get; set; } = string.Empty; + + #endregion + + #region Assistant: Coding Settings + + /// + /// Preselect any coding options? + /// + public bool PreselectCodingOptions { get; set; } + + /// + /// Preselect the compiler messages? + /// + public bool PreselectCodingCompilerMessages { get; set; } + + /// + /// Preselect the coding language for new contexts? + /// + public CommonCodingLanguages PreselectedCodingLanguage { get; set; } + + /// + /// Do you want to preselect any other language? + /// + public string PreselectedCodingOtherLanguage { get; set; } = string.Empty; + + /// + /// Which coding provider should be preselected? + /// + public string PreselectedCodingProvider { get; set; } = string.Empty; + + #endregion + + #region Assistant: Text Summarizer Settings + + /// + /// Preselect any text summarizer options? + /// + public bool PreselectTextSummarizerOptions { get; set; } + + /// + /// Preselect the target language? + /// + public CommonLanguages PreselectedTextSummarizerTargetLanguage { get; set; } + + /// + /// Preselect any other language? + /// + public string PreselectedTextSummarizerOtherLanguage { get; set; } = string.Empty; + + /// + /// Preselect the complexity? + /// + public Complexity PreselectedTextSummarizerComplexity { get; set; } + + /// + /// Preselect any expertise in a field? + /// + public string PreselectedTextSummarizerExpertInField { get; set; } = string.Empty; + + /// + /// Preselect a text summarizer provider? + /// + public string PreselectedTextSummarizerProvider { get; set; } = string.Empty; + + #endregion +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Settings/NavBehavior.cs b/app/MindWork AI Studio/Settings/DataModel/NavBehavior.cs similarity index 76% rename from app/MindWork AI Studio/Settings/NavBehavior.cs rename to app/MindWork AI Studio/Settings/DataModel/NavBehavior.cs index 70170a1..668bf5c 100644 --- a/app/MindWork AI Studio/Settings/NavBehavior.cs +++ b/app/MindWork AI Studio/Settings/DataModel/NavBehavior.cs @@ -1,4 +1,4 @@ -namespace AIStudio.Settings; +namespace AIStudio.Settings.DataModel; public enum NavBehavior { diff --git a/app/MindWork AI Studio/Settings/SendBehavior.cs b/app/MindWork AI Studio/Settings/DataModel/SendBehavior.cs similarity index 95% rename from app/MindWork AI Studio/Settings/SendBehavior.cs rename to app/MindWork AI Studio/Settings/DataModel/SendBehavior.cs index cc92883..1e05790 100644 --- a/app/MindWork AI Studio/Settings/SendBehavior.cs +++ b/app/MindWork AI Studio/Settings/DataModel/SendBehavior.cs @@ -1,4 +1,4 @@ -namespace AIStudio.Settings; +namespace AIStudio.Settings.DataModel; /// /// Possible behaviors for sending the input to the AI. diff --git a/app/MindWork AI Studio/Settings/UpdateBehavior.cs b/app/MindWork AI Studio/Settings/DataModel/UpdateBehavior.cs similarity index 70% rename from app/MindWork AI Studio/Settings/UpdateBehavior.cs rename to app/MindWork AI Studio/Settings/DataModel/UpdateBehavior.cs index 30579f7..0b82604 100644 --- a/app/MindWork AI Studio/Settings/UpdateBehavior.cs +++ b/app/MindWork AI Studio/Settings/DataModel/UpdateBehavior.cs @@ -1,4 +1,4 @@ -namespace AIStudio.Settings; +namespace AIStudio.Settings.DataModel; public enum UpdateBehavior { diff --git a/app/MindWork AI Studio/Settings/WorkspaceStorageBehavior.cs b/app/MindWork AI Studio/Settings/DataModel/WorkspaceStorageBehavior.cs similarity index 75% rename from app/MindWork AI Studio/Settings/WorkspaceStorageBehavior.cs rename to app/MindWork AI Studio/Settings/DataModel/WorkspaceStorageBehavior.cs index d115fb1..1d6c654 100644 --- a/app/MindWork AI Studio/Settings/WorkspaceStorageBehavior.cs +++ b/app/MindWork AI Studio/Settings/DataModel/WorkspaceStorageBehavior.cs @@ -1,4 +1,4 @@ -namespace AIStudio.Settings; +namespace AIStudio.Settings.DataModel; public enum WorkspaceStorageBehavior { diff --git a/app/MindWork AI Studio/Settings/WorkspaceStorageTemporaryMaintenancePolicy.cs b/app/MindWork AI Studio/Settings/DataModel/WorkspaceStorageTemporaryMaintenancePolicy.cs similarity index 86% rename from app/MindWork AI Studio/Settings/WorkspaceStorageTemporaryMaintenancePolicy.cs rename to app/MindWork AI Studio/Settings/DataModel/WorkspaceStorageTemporaryMaintenancePolicy.cs index d635f01..7e221f9 100644 --- a/app/MindWork AI Studio/Settings/WorkspaceStorageTemporaryMaintenancePolicy.cs +++ b/app/MindWork AI Studio/Settings/DataModel/WorkspaceStorageTemporaryMaintenancePolicy.cs @@ -1,4 +1,4 @@ -namespace AIStudio.Settings; +namespace AIStudio.Settings.DataModel; public enum WorkspaceStorageTemporaryMaintenancePolicy { diff --git a/app/MindWork AI Studio/Settings/SettingsManager.cs b/app/MindWork AI Studio/Settings/SettingsManager.cs index 4a5d299..338c35c 100644 --- a/app/MindWork AI Studio/Settings/SettingsManager.cs +++ b/app/MindWork AI Studio/Settings/SettingsManager.cs @@ -1,5 +1,6 @@ using System.Text.Json; using AIStudio.Provider; +using AIStudio.Settings.DataModel; // ReSharper disable NotAccessedPositionalProperty.Local diff --git a/app/MindWork AI Studio/Settings/SettingsMigrations.cs b/app/MindWork AI Studio/Settings/SettingsMigrations.cs index 516a1c1..6e1669d 100644 --- a/app/MindWork AI Studio/Settings/SettingsMigrations.cs +++ b/app/MindWork AI Studio/Settings/SettingsMigrations.cs @@ -1,3 +1,5 @@ +using AIStudio.Settings.DataModel; + using Host = AIStudio.Provider.SelfHosted.Host; namespace AIStudio.Settings; diff --git a/app/MindWork AI Studio/Tools/TemporaryChatService.cs b/app/MindWork AI Studio/Tools/TemporaryChatService.cs index c7122ae..f820716 100644 --- a/app/MindWork AI Studio/Tools/TemporaryChatService.cs +++ b/app/MindWork AI Studio/Tools/TemporaryChatService.cs @@ -1,4 +1,5 @@ using AIStudio.Settings; +using AIStudio.Settings.DataModel; namespace AIStudio.Tools; diff --git a/app/MindWork AI Studio/Tools/UpdateService.cs b/app/MindWork AI Studio/Tools/UpdateService.cs index 2919343..71fcb9b 100644 --- a/app/MindWork AI Studio/Tools/UpdateService.cs +++ b/app/MindWork AI Studio/Tools/UpdateService.cs @@ -1,4 +1,5 @@ using AIStudio.Settings; +using AIStudio.Settings.DataModel; using Microsoft.AspNetCore.Components; diff --git a/app/MindWork AI Studio/wwwroot/changelog/v0.8.5.md b/app/MindWork AI Studio/wwwroot/changelog/v0.8.5.md new file mode 100644 index 0000000..fe4af6f --- /dev/null +++ b/app/MindWork AI Studio/wwwroot/changelog/v0.8.5.md @@ -0,0 +1,11 @@ +# v0.8.4, build 167 +- Added the possibility to provide default options for the icon finder assistant +- Added the possibility to provide default options for the translation assistant +- Added the possibility to provide default options for the coding assistant +- Added the possibility to provide default options for the text summarizer assistant +- Improved switches: when an option is enabled, the switch is using a different color +- Fixed the applying of spellchecking settings to the single-line dialog +- Restructured the layout of the settings page +- Refactored the settings data model +- Upgraded to Rust 1.80.0 +- Upgraded all Rust dependencies \ No newline at end of file