Add default configuration for assistants (#52)

This commit is contained in:
Thorsten Sommer 2024-07-28 11:20:00 +02:00 committed by GitHub
parent a1c4618796
commit b3b8bf23dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 729 additions and 138 deletions

View File

@ -0,0 +1,7 @@
@inherits ConfigurationBase
<MudField Disabled="@this.Disabled()" Label="@this.OptionDescription" Variant="Variant.Outlined" HelperText="@this.OptionHelp" Class="@MARGIN_CLASS">
<MudSwitch T="bool" Disabled="@this.Disabled()" Value="@this.State()" ValueChanged="@this.OptionChanged" Color="Color.Primary">
@(this.State() ? this.LabelOn : this.LabelOff)
</MudSwitch>
</MudField>

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace AIStudio.Components; namespace AIStudio.Components.Blocks;
/// <summary> /// <summary>
/// Configuration component for any boolean option. /// Configuration component for any boolean option.

View File

@ -0,0 +1 @@
<ConfigurationSelect OptionDescription="Preselected provider" Disabled="@this.Disabled" OptionHelp="Select a provider that is preselected." Data="@this.Data" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/>

View File

@ -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<string> SelectedValue { get; set; } = () => string.Empty;
[Parameter]
public Action<string> SelectionUpdate { get; set; } = _ => { };
[Parameter]
public IEnumerable<ConfigurationSelectData<string>> Data { get; set; } = new List<ConfigurationSelectData<string>>();
/// <summary>
/// Is the selection component disabled?
/// </summary>
[Parameter]
public Func<bool> 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<T>(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<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
{
return Task.FromResult<TResult?>(default);
}
#endregion
#region Implementation of IDisposable
public void Dispose()
{
this.MessageBus.Unregister(this);
}
#endregion
}

View File

@ -0,0 +1,11 @@
@inherits ConfigurationBase
@typeparam T
<MudSelect T="T" Value="@this.SelectedValue()" Strict="@true" Disabled="@this.Disabled()" Margin="Margin.Dense" Label="@this.OptionDescription" Class="@GetClass" Variant="Variant.Outlined" HelperText="@this.OptionHelp" ValueChanged="@this.OptionChanged">
@foreach (var data in this.Data)
{
<MudSelectItem Value="@data.Value">
@data.Name
</MudSelectItem>
}
</MudSelect>

View File

@ -1,6 +1,8 @@
using AIStudio.Settings;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace AIStudio.Components; namespace AIStudio.Components.Blocks;
/// <summary> /// <summary>
/// Configuration component for selecting a value from a list. /// Configuration component for selecting a value from a list.

View File

@ -0,0 +1,8 @@
@typeparam T
@inherits ConfigurationBase
<MudField Label="@this.OptionDescription" Variant="Variant.Outlined" Class="mb-3" Disabled="@this.Disabled()">
<MudSlider T="@T" Size="Size.Medium" Value="@this.Value()" ValueChanged="@this.OptionChanged" Min="@this.Min" Max="@this.Max" Step="@this.Step" Immediate="@true" Disabled="@this.Disabled()">
@this.Value() @this.Unit
</MudSlider>
</MudField>

View File

@ -0,0 +1,51 @@
using System.Numerics;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components.Blocks;
public partial class ConfigurationSlider<T> : ConfigurationBase where T : struct, INumber<T>
{
/// <summary>
/// The minimum value for the slider.
/// </summary>
[Parameter]
public T Min { get; set; } = T.Zero;
/// <summary>
/// The maximum value for the slider.
/// </summary>
[Parameter]
public T Max { get; set; } = T.One;
/// <summary>
/// The step size for the slider.
/// </summary>
[Parameter]
public T Step { get; set; } = T.One;
/// <summary>
/// The unit to display next to the slider's value.
/// </summary>
[Parameter]
public string Unit { get; set; } = string.Empty;
/// <summary>
/// The value used for the slider.
/// </summary>
[Parameter]
public Func<T> Value { get; set; } = () => T.Zero;
/// <summary>
/// An action which is called when the option is changed.
/// </summary>
[Parameter]
public Action<T> ValueUpdate { get; set; } = _ => { };
private async Task OptionChanged(T updatedValue)
{
this.ValueUpdate(updatedValue);
await this.SettingsManager.StoreSettings();
await this.InformAboutChange();
}
}

View File

@ -0,0 +1,18 @@
@inherits ConfigurationBase
<MudTextField
T="string"
Text="@this.Text()"
TextChanged="@this.OptionChanged"
Label="@this.OptionDescription"
Disabled="@this.Disabled()"
Class="mb-3"
Adornment="Adornment.Start"
AdornmentIcon="@this.Icon"
AdornmentColor="@this.IconColor"
UserAttributes="@SPELLCHECK_ATTRIBUTES"
Lines="1"
Immediate="@false"
DebounceInterval="500"
Variant="Variant.Outlined"
/>

View File

@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components.Blocks;
public partial class ConfigurationText : ConfigurationBase
{
/// <summary>
/// The text used for the textfield.
/// </summary>
[Parameter]
public Func<string> Text { get; set; } = () => string.Empty;
/// <summary>
/// An action which is called when the option is changed.
/// </summary>
[Parameter]
public Action<string> TextUpdate { get; set; } = _ => { };
/// <summary>
/// The icon to display next to the textfield.
/// </summary>
[Parameter]
public string Icon { get; set; } = Icons.Material.Filled.Info;
/// <summary>
/// The color of the icon to use.
/// </summary>
[Parameter]
public Color IconColor { get; set; } = Color.Default;
private async Task OptionChanged(string updatedText)
{
this.TextUpdate(updatedText);
await this.SettingsManager.StoreSettings();
await this.InformAboutChange();
}
}

View File

@ -8,7 +8,7 @@ namespace AIStudio.Components;
/// <summary> /// <summary>
/// A base class for configuration options. /// A base class for configuration options.
/// </summary> /// </summary>
public partial class ConfigurationBase : ComponentBase public partial class ConfigurationBase : ComponentBase, IMessageBusReceiver, IDisposable
{ {
/// <summary> /// <summary>
/// The description of the option, i.e., the name. Should be /// The description of the option, i.e., the name. Should be
@ -23,6 +23,12 @@ public partial class ConfigurationBase : ComponentBase
[Parameter] [Parameter]
public string OptionHelp { get; set; } = string.Empty; public string OptionHelp { get; set; } = string.Empty;
/// <summary>
/// Is the option disabled?
/// </summary>
[Parameter]
public Func<bool> Disabled { get; set; } = () => false;
[Inject] [Inject]
protected SettingsManager SettingsManager { get; init; } = null!; protected SettingsManager SettingsManager { get; init; } = null!;
@ -30,6 +36,53 @@ public partial class ConfigurationBase : ComponentBase
protected MessageBus MessageBus { get; init; } = null!; protected MessageBus MessageBus { get; init; } = null!;
protected const string MARGIN_CLASS = "mb-6"; protected const string MARGIN_CLASS = "mb-6";
protected static readonly Dictionary<string, object?> 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<bool>(this, Event.CONFIGURATION_CHANGED); protected async Task InformAboutChange() => await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
#region Implementation of IMessageBusReceiver
public Task ProcessMessage<TMsg>(ComponentBase? sendingComponent, Event triggeredEvent, TMsg? data)
{
switch (triggeredEvent)
{
case Event.CONFIGURATION_CHANGED:
this.StateHasChanged();
break;
}
return Task.CompletedTask;
}
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
{
return Task.FromResult<TResult?>(default);
}
#endregion
#region Implementation of IDisposable
public void Dispose()
{
this.MessageBus.Unregister(this);
}
#endregion
} }

View File

@ -1,7 +0,0 @@
@inherits ConfigurationBase
<MudField Label="@this.OptionDescription" Variant="Variant.Outlined" HelperText="@this.OptionHelp" Class="@MARGIN_CLASS">
<MudSwitch T="bool" Value="@this.State()" ValueChanged="@(updatedState => this.OptionChanged(updatedState))">
@(this.State() ? this.LabelOn : this.LabelOff)
</MudSwitch>
</MudField>

View File

@ -1,11 +0,0 @@
@inherits ConfigurationBase
@typeparam T
<MudSelect T="T" Value="@this.SelectedValue()" Margin="Margin.Dense" Label="@this.OptionDescription" Class="@GetClass" Variant="Variant.Outlined" HelperText="@this.OptionHelp" ValueChanged="selectedValue => this.OptionChanged(selectedValue)">
@foreach (var data in this.Data)
{
<MudSelectItem Value="@data.Value">
@data.Name
</MudSelectItem>
}
</MudSelect>

View File

@ -1,7 +0,0 @@
@inherits ConfigurationBase
<MudField Label="@this.OptionDescription" Variant="Variant.Outlined" HelperText="@this.OptionHelp" Class="@MARGIN_CLASS">
<MudButton Variant="Variant.Filled" StartIcon="@this.TriggerIcon" OnClick="@this.Click">
@this.TriggerText
</MudButton>
</MudField>

View File

@ -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<Task> OnClickAsync { get; set; } = () => Task.CompletedTask;
private async Task Click()
{
this.OnClickSync();
await this.OnClickAsync();
}
}

View File

@ -1,4 +1,4 @@
@using AIStudio.Settings @using AIStudio.Settings.DataModel
@inherits LayoutComponentBase @inherits LayoutComponentBase
<MudPaper Height="calc(100vh);" Elevation="0"> <MudPaper Height="calc(100vh);" Elevation="0">

View File

@ -1,5 +1,6 @@
using AIStudio.Components.CommonDialogs; using AIStudio.Components.CommonDialogs;
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using AIStudio.Tools; using AIStudio.Tools;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@ -9,7 +10,7 @@ using DialogOptions = AIStudio.Components.CommonDialogs.DialogOptions;
namespace AIStudio.Components.Layout; namespace AIStudio.Components.Layout;
public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDisposable
{ {
[Inject] [Inject]
private IJSRuntime JsRuntime { get; init; } = null!; private IJSRuntime JsRuntime { get; init; } = null!;
@ -211,4 +212,13 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver
await MessageBus.INSTANCE.SendMessage<bool>(this, Event.RESET_CHAT_STATE); await MessageBus.INSTANCE.SendMessage<bool>(this, Event.RESET_CHAT_STATE);
} }
} }
#region Implementation of IDisposable
public void Dispose()
{
this.MessageBus.Unregister(this);
}
#endregion
} }

View File

@ -7,6 +7,6 @@
<MudGrid> <MudGrid>
<AssistantBlock Name="Icon Finder" Description="Using a LLM to find an icon for a given context." Icon="@Icons.Material.Filled.FindInPage" Link="/assistant/icons"/> <AssistantBlock Name="Icon Finder" Description="Using a LLM to find an icon for a given context." Icon="@Icons.Material.Filled.FindInPage" Link="/assistant/icons"/>
<AssistantBlock Name="Text Summarizer" Description="Using a LLM to summarize a given text." Icon="@Icons.Material.Filled.TextSnippet" Link="/assistant/summarizer"/> <AssistantBlock Name="Text Summarizer" Description="Using a LLM to summarize a given text." Icon="@Icons.Material.Filled.TextSnippet" Link="/assistant/summarizer"/>
<AssistantBlock Name="Translator" Description="Translate text into another language." Icon="@Icons.Material.Filled.Translate" Link="/assistant/translator"/> <AssistantBlock Name="Translation" Description="Translate text into another language." Icon="@Icons.Material.Filled.Translate" Link="/assistant/translation"/>
<AssistantBlock Name="Coding" Description="Get coding and debugging support from a LLM." Icon="@Icons.Material.Filled.Code" Link="/assistant/coding"/> <AssistantBlock Name="Coding" Description="Get coding and debugging support from a LLM." Icon="@Icons.Material.Filled.Code" Link="/assistant/coding"/>
</MudGrid> </MudGrid>

View File

@ -1,6 +1,7 @@
@page "/chat" @page "/chat"
@using AIStudio.Chat @using AIStudio.Chat
@using AIStudio.Settings @using AIStudio.Settings
@using AIStudio.Settings.DataModel
@inherits MSGComponentBase @inherits MSGComponentBase

View File

@ -3,6 +3,7 @@ using AIStudio.Components.Blocks;
using AIStudio.Components.CommonDialogs; using AIStudio.Components.CommonDialogs;
using AIStudio.Provider; using AIStudio.Provider;
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using AIStudio.Tools; using AIStudio.Tools;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;

View File

@ -16,7 +16,7 @@
</MudButton> </MudButton>
<MudStack Row="@false" Class="mb-3"> <MudStack Row="@false" Class="mb-3">
<MudSwitch T="bool" @bind-Value="@this.provideCompilerMessages"> <MudSwitch T="bool" @bind-Value="@this.provideCompilerMessages" Color="Color.Primary">
@(this.provideCompilerMessages ? "Provide compiler messages" : "Provide no compiler messages") @(this.provideCompilerMessages ? "Provide compiler messages" : "Provide no compiler messages")
</MudSwitch> </MudSwitch>
@if (this.provideCompilerMessages) @if (this.provideCompilerMessages)

View File

@ -29,6 +29,21 @@ public partial class AssistantCoding : AssistantBaseCore
private string compilerMessages = string.Empty; private string compilerMessages = string.Empty;
private string questions = 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) private string? ValidatingCompilerMessages(string checkCompilerMessages)
{ {
if(!this.provideCompilerMessages) if(!this.provideCompilerMessages)
@ -53,6 +68,8 @@ public partial class AssistantCoding : AssistantBaseCore
this.codingContexts.Add(new() this.codingContexts.Add(new()
{ {
Id = $"Context {this.codingContexts.Count + 1}", 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,
}); });
} }

View File

@ -5,6 +5,21 @@ public partial class AssistantIconFinder : AssistantBaseCore
private string inputContext = string.Empty; private string inputContext = string.Empty;
private IconSources selectedIconSource; 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 Title => "Icon Finder";
protected override string Description => protected override string Description =>

View File

@ -1,5 +1,9 @@
@page "/settings" @page "/settings"
@using AIStudio.Components.Pages.Coding
@using AIStudio.Components.Pages.TextSummarizer
@using AIStudio.Provider @using AIStudio.Provider
@using AIStudio.Settings
@using AIStudio.Tools
@using Host = AIStudio.Provider.SelfHosted.Host @using Host = AIStudio.Provider.SelfHosted.Host
<MudText Typo="Typo.h3" Class="mb-12">Settings</MudText> <MudText Typo="Typo.h3" Class="mb-12">Settings</MudText>
@ -59,20 +63,71 @@
<MudText Typo="Typo.h6" Class="mt-3">No providers configured yet.</MudText> <MudText Typo="Typo.h6" Class="mt-3">No providers configured yet.</MudText>
} }
<MudButton <MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddProvider">
Variant="Variant.Filled" Color="@Color.Primary"
StartIcon="@Icons.Material.Filled.AddRoad"
Class="mt-3 mb-6" OnClick="@this.AddProvider">
Add Provider Add Provider
</MudButton> </MudButton>
<MudText Typo="Typo.h4" Class="mb-3">Options</MudText> <MudText Typo="Typo.h4" Class="mb-3">App Options</MudText>
<ConfigurationOption OptionDescription="Save energy?" LabelOn="Energy saving is enabled" LabelOff="Energy saving is disabled" State="@(() => this.SettingsManager.ConfigurationData.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.IsSavingEnergy = updatedState)" OptionHelp="When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available."/> <ConfigurationOption OptionDescription="Save energy?" LabelOn="Energy saving is enabled" LabelOff="Energy saving is disabled" State="@(() => this.SettingsManager.ConfigurationData.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.IsSavingEnergy = updatedState)" OptionHelp="When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available."/>
<ConfigurationOption OptionDescription="Enable spellchecking?" LabelOn="Spellchecking is enabled" LabelOff="Spellchecking is disabled" State="@(() => this.SettingsManager.ConfigurationData.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.EnableSpellchecking = updatedState)" OptionHelp="When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections." /> <ConfigurationOption OptionDescription="Enable spellchecking?" LabelOn="Spellchecking is enabled" LabelOff="Spellchecking is disabled" State="@(() => this.SettingsManager.ConfigurationData.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.EnableSpellchecking = updatedState)" OptionHelp="When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections." />
<ConfigurationSelect OptionDescription="Shortcut to send input" SelectedValue="@(() => this.SettingsManager.ConfigurationData.ShortcutSendBehavior)" Data="@ConfigurationSelectDataFactory.GetSendBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.ShortcutSendBehavior = selectedValue)" OptionHelp="Do you want to use any shortcut to send your input?"/>
<ConfigurationSelect OptionDescription="Check for updates" SelectedValue="@(() => this.SettingsManager.ConfigurationData.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.UpdateBehavior = selectedValue)" OptionHelp="How often should we check for app updates?"/> <ConfigurationSelect OptionDescription="Check for updates" SelectedValue="@(() => this.SettingsManager.ConfigurationData.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.UpdateBehavior = selectedValue)" OptionHelp="How often should we check for app updates?"/>
<ConfigurationSelect OptionDescription="Navigation bar behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.NavigationBehavior = selectedValue)" OptionHelp="Select the desired behavior for the navigation bar."/>
<MudText Typo="Typo.h4" Class="mb-3">Chat Options</MudText>
<ConfigurationSelect OptionDescription="Shortcut to send input" SelectedValue="@(() => this.SettingsManager.ConfigurationData.ShortcutSendBehavior)" Data="@ConfigurationSelectDataFactory.GetSendBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.ShortcutSendBehavior = selectedValue)" OptionHelp="Do you want to use any shortcut to send your input?"/>
<MudText Typo="Typo.h4" Class="mb-3">Workspace Options</MudText>
<ConfigurationSelect OptionDescription="Workspace behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior = selectedValue)" OptionHelp="Should we store your chats?"/> <ConfigurationSelect OptionDescription="Workspace behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior = selectedValue)" OptionHelp="Should we store your chats?"/>
<ConfigurationSelect OptionDescription="Workspace maintenance" SelectedValue="@(() => this.SettingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageTemporaryMaintenancePolicyData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy = selectedValue)" OptionHelp="If and when should we delete your temporary chats?"/> <ConfigurationSelect OptionDescription="Workspace maintenance" SelectedValue="@(() => this.SettingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageTemporaryMaintenancePolicyData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy = selectedValue)" OptionHelp="If and when should we delete your temporary chats?"/>
<ConfigurationSelect OptionDescription="Navigation bar behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.NavigationBehavior = selectedValue)" OptionHelp="Select the desired behavior for the navigation bar."/>
<MudText Typo="Typo.h4" Class="mb-3">Assistants Options</MudText>
<MudText Typo="Typo.h5" Class="mb-3">Icon Finder Options</MudText>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<ConfigurationOption OptionDescription="Preselect icon options?" LabelOn="Icon options are preselected" LabelOff="No icon options are preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectIconOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectIconOptions = updatedState)" OptionHelp="When enabled, you can preselect the icon options. This is might be useful when you prefer a specific icon source or LLM model."/>
<ConfigurationSelect OptionDescription="Preselect the icon source" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectIconOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedIconSource)" Data="@ConfigurationSelectDataFactory.GetIconSourcesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedIconSource = selectedValue)" OptionHelp="Which icon source should be preselected?"/>
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectIconOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedIconProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedIconProvider = selectedValue)"/>
</MudPaper>
<MudText Typo="Typo.h5" Class="mb-3">Translator Options</MudText>
<ConfigurationSlider T="int" OptionDescription="How fast should the live translation react?" Min="500" Max="3_000" Step="100" Unit="milliseconds" Value="@(() => this.SettingsManager.ConfigurationData.LiveTranslationDebounceIntervalMilliseconds)" ValueUpdate="@(updatedValue => this.SettingsManager.ConfigurationData.LiveTranslationDebounceIntervalMilliseconds = updatedValue)"/>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<ConfigurationOption OptionDescription="Preselect translator options?" LabelOn="Translator options are preselected" LabelOff="No translator options are preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectTranslationOptions = updatedState)" OptionHelp="When enabled, you can preselect the translator options. This is might be useful when you prefer a specific target language or LLM model."/>
<ConfigurationOption OptionDescription="Preselect live translation?" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" LabelOn="Live translation is preselected" LabelOff="Live translation is not preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectLiveTranslation)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectLiveTranslation = updatedState)" />
<ConfigurationSelect OptionDescription="Preselect the target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage = selectedValue)" OptionHelp="Which target language should be preselected?"/>
@if (this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage is CommonLanguages.OTHER)
{
<ConfigurationText OptionDescription="Preselect another target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.PreselectTranslationOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.PreselectTranslationOtherLanguage = updatedText)"/>
}
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTranslationProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTranslationProvider = selectedValue)"/>
</MudPaper>
<MudText Typo="Typo.h5" Class="mb-3">Coding Options</MudText>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<ConfigurationOption OptionDescription="Preselect coding options?" LabelOn="Coding options are preselected" LabelOff="No coding options are preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectCodingOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectCodingOptions = updatedState)" OptionHelp="When enabled, you can preselect the coding options. This is might be useful when you prefer a specific programming language or LLM model."/>
<ConfigurationOption OptionDescription="Preselect compiler messages?" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectCodingOptions)" LabelOn="Compiler messages are preselected" LabelOff="Compiler messages are not preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectCodingCompilerMessages)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectCodingCompilerMessages = updatedState)" />
<ConfigurationSelect OptionDescription="Preselect a programming language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectCodingOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedCodingLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonCodingLanguagesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedCodingLanguage = selectedValue)" OptionHelp="Which programming language should be preselected for added contexts?"/>
@if (this.SettingsManager.ConfigurationData.PreselectedCodingLanguage is CommonCodingLanguages.OTHER)
{
<ConfigurationText OptionDescription="Preselect another programming language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectCodingOptions)" Icon="@Icons.Material.Filled.Code" Text="@(() => this.SettingsManager.ConfigurationData.PreselectedCodingOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.PreselectedCodingOtherLanguage = updatedText)"/>
}
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectCodingOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedCodingProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedCodingProvider = selectedValue)"/>
</MudPaper>
<MudText Typo="Typo.h5" Class="mb-3">Text Summarizer Options</MudText>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<ConfigurationOption OptionDescription="Preselect summarizer options?" LabelOn="Summarizer options are preselected" LabelOff="No summarizer options are preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions = updatedState)" OptionHelp="When enabled, you can preselect the text summarizer options. This is might be useful when you prefer a specific language, complexity, or LLM."/>
<ConfigurationSelect OptionDescription="Preselect the target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage = selectedValue)" OptionHelp="Which target language should be preselected?"/>
@if (this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage is CommonLanguages.OTHER)
{
<ConfigurationText OptionDescription="Preselect another target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerOtherLanguage = updatedText)"/>
}
<ConfigurationSelect OptionDescription="Preselect the summarizer complexity" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerComplexity)" Data="@ConfigurationSelectDataFactory.GetComplexityData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerComplexity = selectedValue)" OptionHelp="Which summarizer complexity should be preselected?"/>
@if(this.SettingsManager.ConfigurationData.PreselectedTextSummarizerComplexity is Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS)
{
<ConfigurationText OptionDescription="Preselect your expertise" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" Icon="@Icons.Material.Filled.Person" Text="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerExpertInField)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerExpertInField = updatedText)"/>
}
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerProvider = selectedValue)"/>
</MudPaper>
</MudPaper> </MudPaper>
</InnerScrolling> </InnerScrolling>

View File

@ -11,7 +11,7 @@ using DialogOptions = AIStudio.Components.CommonDialogs.DialogOptions;
namespace AIStudio.Components.Pages; namespace AIStudio.Components.Pages;
public partial class Settings : ComponentBase public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable
{ {
[Inject] [Inject]
public SettingsManager SettingsManager { get; init; } = null!; public SettingsManager SettingsManager { get; init; } = null!;
@ -25,6 +25,22 @@ public partial class Settings : ComponentBase
[Inject] [Inject]
protected MessageBus MessageBus { get; init; } = null!; protected MessageBus MessageBus { get; init; } = null!;
private readonly List<ConfigurationSelectData<string>> 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 #region Provider related
private async Task AddProvider() private async Task AddProvider()
@ -43,6 +59,8 @@ public partial class Settings : ComponentBase
addedProvider = addedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; addedProvider = addedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ };
this.SettingsManager.ConfigurationData.Providers.Add(addedProvider); this.SettingsManager.ConfigurationData.Providers.Add(addedProvider);
this.UpdateProviders();
await this.SettingsManager.StoreSettings(); await this.SettingsManager.StoreSettings();
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED); await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
} }
@ -75,6 +93,8 @@ public partial class Settings : ComponentBase
editedProvider = editedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; editedProvider = editedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ };
this.SettingsManager.ConfigurationData.Providers[this.SettingsManager.ConfigurationData.Providers.IndexOf(provider)] = editedProvider; this.SettingsManager.ConfigurationData.Providers[this.SettingsManager.ConfigurationData.Providers.IndexOf(provider)] = editedProvider;
this.UpdateProviders();
await this.SettingsManager.StoreSettings(); await this.SettingsManager.StoreSettings();
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED); await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
} }
@ -99,6 +119,7 @@ public partial class Settings : ComponentBase
await this.SettingsManager.StoreSettings(); await this.SettingsManager.StoreSettings();
} }
this.UpdateProviders();
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED); await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
} }
@ -129,5 +150,42 @@ public partial class Settings : ComponentBase
return modelName.Length > MAX_LENGTH ? "[...] " + modelName[^Math.Min(MAX_LENGTH, modelName.Length)..] : modelName; 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<TMsg>(ComponentBase? sendingComponent, Event triggeredEvent, TMsg? data)
{
switch (triggeredEvent)
{
case Event.CONFIGURATION_CHANGED:
this.StateHasChanged();
break;
}
return Task.CompletedTask;
}
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
{
return Task.FromResult<TResult?>(default);
}
#endregion
#region Implementation of IDisposable
public void Dispose()
{
this.MessageBus.Unregister(this);
}
#endregion #endregion
} }

View File

@ -29,6 +29,24 @@ public partial class AssistantTextSummarizer : AssistantBaseCore
private Complexity selectedComplexity; private Complexity selectedComplexity;
private string expertInField = string.Empty; 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) private string? ValidatingText(string text)
{ {
if(string.IsNullOrWhiteSpace(text)) if(string.IsNullOrWhiteSpace(text))

View File

@ -1,10 +1,10 @@
@page "/assistant/translator" @page "/assistant/translation"
@using AIStudio.Settings @using AIStudio.Settings
@using AIStudio.Tools @using AIStudio.Tools
@inherits AssistantBaseCore @inherits AssistantBaseCore
<MudField Label="Live translation" Variant="Variant.Outlined" Class="mb-3"> <MudField Label="Live translation" Variant="Variant.Outlined" Class="mb-3">
<MudSwitch T="bool" @bind-Value="@this.liveTranslation"> <MudSwitch T="bool" @bind-Value="@this.liveTranslation" Color="Color.Primary">
@(this.liveTranslation ? "Live translation" : "No live translation") @(this.liveTranslation ? "Live translation" : "No live translation")
</MudSwitch> </MudSwitch>
</MudField> </MudField>

View File

@ -1,10 +1,10 @@
using AIStudio.Tools; 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 => protected override string Description =>
""" """
@ -25,6 +25,23 @@ public partial class AssistantTranslator : AssistantBaseCore
private CommonLanguages selectedTargetLanguage; private CommonLanguages selectedTargetLanguage;
private string customTargetLanguage = string.Empty; 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) private string? ValidatingText(string text)
{ {
if(string.IsNullOrWhiteSpace(text)) if(string.IsNullOrWhiteSpace(text))

View File

@ -1,6 +1,6 @@
using AIStudio.Tools; using AIStudio.Tools;
namespace AIStudio.Components.Pages.Translator; namespace AIStudio.Components.Pages.Translation;
public static class CommonLanguageExtension public static class CommonLanguageExtension
{ {

View File

@ -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;
/// <summary> /// <summary>
/// A data structure to map a name to a value. /// 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("Navigation never expands, no tooltips", NavBehavior.NEVER_EXPAND_NO_TOOLTIPS);
yield return new("Always expand navigation", NavBehavior.ALWAYS_EXPAND); yield return new("Always expand navigation", NavBehavior.ALWAYS_EXPAND);
} }
public static IEnumerable<ConfigurationSelectData<IconSources>> GetIconSourcesData()
{
foreach (var source in Enum.GetValues<IconSources>())
yield return new(source.Name(), source);
}
public static IEnumerable<ConfigurationSelectData<CommonLanguages>> GetCommonLanguagesData()
{
foreach (var language in Enum.GetValues<CommonLanguages>())
yield return new(language.Name(), language);
}
public static IEnumerable<ConfigurationSelectData<CommonCodingLanguages>> GetCommonCodingLanguagesData()
{
foreach (var language in Enum.GetValues<CommonCodingLanguages>())
yield return new(language.Name(), language);
}
public static IEnumerable<ConfigurationSelectData<Complexity>> GetComplexityData()
{
foreach (var complexity in Enum.GetValues<Complexity>())
yield return new(complexity.Name(), complexity);
}
} }

View File

@ -1,59 +0,0 @@
namespace AIStudio.Settings;
/// <summary>
/// The data model for the settings file.
/// </summary>
public sealed class Data
{
/// <summary>
/// The version of the settings file. Allows us to upgrade the settings
/// when a new version is available.
/// </summary>
public Version Version { get; init; } = Version.V3;
/// <summary>
/// List of configured providers.
/// </summary>
public List<Provider> Providers { get; init; } = [];
/// <summary>
/// The next provider number to use.
/// </summary>
public uint NextProviderNum { get; set; } = 1;
/// <summary>
/// Should we save energy? When true, we will update content streamed
/// from the server, i.e., AI, less frequently.
/// </summary>
public bool IsSavingEnergy { get; set; }
/// <summary>
/// Shortcuts to send the input to the AI.
/// </summary>
public SendBehavior ShortcutSendBehavior { get; set; } = SendBehavior.MODIFER_ENTER_IS_SENDING;
/// <summary>
/// Should we enable spellchecking for all input fields?
/// </summary>
public bool EnableSpellchecking { get; set; }
/// <summary>
/// If and when we should look for updates.
/// </summary>
public UpdateBehavior UpdateBehavior { get; set; } = UpdateBehavior.ONCE_STARTUP;
/// <summary>
/// The chat storage behavior.
/// </summary>
public WorkspaceStorageBehavior WorkspaceStorageBehavior { get; set; } = WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY;
/// <summary>
/// The chat storage maintenance behavior.
/// </summary>
public WorkspaceStorageTemporaryMaintenancePolicy WorkspaceStorageTemporaryMaintenancePolicy { get; set; } = WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS;
/// <summary>
/// The navigation behavior.
/// </summary>
public NavBehavior NavigationBehavior { get; set; } = NavBehavior.EXPAND_ON_HOVER;
}

View File

@ -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;
/// <summary>
/// The data model for the settings file.
/// </summary>
public sealed class Data
{
/// <summary>
/// The version of the settings file. Allows us to upgrade the settings
/// when a new version is available.
/// </summary>
public Version Version { get; init; } = Version.V3;
/// <summary>
/// List of configured providers.
/// </summary>
public List<Provider> Providers { get; init; } = [];
/// <summary>
/// The next provider number to use.
/// </summary>
public uint NextProviderNum { get; set; } = 1;
#region App Settings
/// <summary>
/// Should we save energy? When true, we will update content streamed
/// from the server, i.e., AI, less frequently.
/// </summary>
public bool IsSavingEnergy { get; set; }
/// <summary>
/// Should we enable spellchecking for all input fields?
/// </summary>
public bool EnableSpellchecking { get; set; }
/// <summary>
/// If and when we should look for updates.
/// </summary>
public UpdateBehavior UpdateBehavior { get; set; } = UpdateBehavior.ONCE_STARTUP;
/// <summary>
/// The navigation behavior.
/// </summary>
public NavBehavior NavigationBehavior { get; set; } = NavBehavior.EXPAND_ON_HOVER;
#endregion
#region Chat Settings
/// <summary>
/// Shortcuts to send the input to the AI.
/// </summary>
public SendBehavior ShortcutSendBehavior { get; set; } = SendBehavior.MODIFER_ENTER_IS_SENDING;
#endregion
#region Workspace Settings
/// <summary>
/// The chat storage behavior.
/// </summary>
public WorkspaceStorageBehavior WorkspaceStorageBehavior { get; set; } = WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY;
/// <summary>
/// The chat storage maintenance behavior.
/// </summary>
public WorkspaceStorageTemporaryMaintenancePolicy WorkspaceStorageTemporaryMaintenancePolicy { get; set; } = WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS;
#endregion
#region Assiatant: Icon Finder Settings
/// <summary>
/// Do we want to preselect any icon options?
/// </summary>
public bool PreselectIconOptions { get; set; }
/// <summary>
/// The preselected icon source.
/// </summary>
public IconSources PreselectedIconSource { get; set; }
/// <summary>
/// The preselected icon provider.
/// </summary>
public string PreselectedIconProvider { get; set; } = string.Empty;
#endregion
#region Assistant: Translation Settings
/// <summary>
/// The live translation interval for debouncing in milliseconds.
/// </summary>
public int LiveTranslationDebounceIntervalMilliseconds { get; set; } = 1_000;
/// <summary>
/// Do we want to preselect any translator options?
/// </summary>
public bool PreselectTranslationOptions { get; set; }
/// <summary>
/// Preselect the live translation?
/// </summary>
public bool PreselectLiveTranslation { get; set; }
/// <summary>
/// Preselect the target language?
/// </summary>
public CommonLanguages PreselectedTranslationTargetLanguage { get; set; } = CommonLanguages.EN_US;
/// <summary>
/// Preselect any other language?
/// </summary>
public string PreselectTranslationOtherLanguage { get; set; } = string.Empty;
/// <summary>
/// The preselected translator provider.
/// </summary>
public string PreselectedTranslationProvider { get; set; } = string.Empty;
#endregion
#region Assistant: Coding Settings
/// <summary>
/// Preselect any coding options?
/// </summary>
public bool PreselectCodingOptions { get; set; }
/// <summary>
/// Preselect the compiler messages?
/// </summary>
public bool PreselectCodingCompilerMessages { get; set; }
/// <summary>
/// Preselect the coding language for new contexts?
/// </summary>
public CommonCodingLanguages PreselectedCodingLanguage { get; set; }
/// <summary>
/// Do you want to preselect any other language?
/// </summary>
public string PreselectedCodingOtherLanguage { get; set; } = string.Empty;
/// <summary>
/// Which coding provider should be preselected?
/// </summary>
public string PreselectedCodingProvider { get; set; } = string.Empty;
#endregion
#region Assistant: Text Summarizer Settings
/// <summary>
/// Preselect any text summarizer options?
/// </summary>
public bool PreselectTextSummarizerOptions { get; set; }
/// <summary>
/// Preselect the target language?
/// </summary>
public CommonLanguages PreselectedTextSummarizerTargetLanguage { get; set; }
/// <summary>
/// Preselect any other language?
/// </summary>
public string PreselectedTextSummarizerOtherLanguage { get; set; } = string.Empty;
/// <summary>
/// Preselect the complexity?
/// </summary>
public Complexity PreselectedTextSummarizerComplexity { get; set; }
/// <summary>
/// Preselect any expertise in a field?
/// </summary>
public string PreselectedTextSummarizerExpertInField { get; set; } = string.Empty;
/// <summary>
/// Preselect a text summarizer provider?
/// </summary>
public string PreselectedTextSummarizerProvider { get; set; } = string.Empty;
#endregion
}

View File

@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
public enum NavBehavior public enum NavBehavior
{ {

View File

@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
/// <summary> /// <summary>
/// Possible behaviors for sending the input to the AI. /// Possible behaviors for sending the input to the AI.

View File

@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
public enum UpdateBehavior public enum UpdateBehavior
{ {

View File

@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
public enum WorkspaceStorageBehavior public enum WorkspaceStorageBehavior
{ {

View File

@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
public enum WorkspaceStorageTemporaryMaintenancePolicy public enum WorkspaceStorageTemporaryMaintenancePolicy
{ {

View File

@ -1,5 +1,6 @@
using System.Text.Json; using System.Text.Json;
using AIStudio.Provider; using AIStudio.Provider;
using AIStudio.Settings.DataModel;
// ReSharper disable NotAccessedPositionalProperty.Local // ReSharper disable NotAccessedPositionalProperty.Local

View File

@ -1,3 +1,5 @@
using AIStudio.Settings.DataModel;
using Host = AIStudio.Provider.SelfHosted.Host; using Host = AIStudio.Provider.SelfHosted.Host;
namespace AIStudio.Settings; namespace AIStudio.Settings;

View File

@ -1,4 +1,5 @@
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Settings.DataModel;
namespace AIStudio.Tools; namespace AIStudio.Tools;

View File

@ -1,4 +1,5 @@
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;

View File

@ -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