Added option to read web content into translation and text summarization assistants

This commit is contained in:
Thorsten Sommer 2024-08-01 21:48:42 +02:00
parent 5fe24fe861
commit 199be1e863
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
7 changed files with 59 additions and 9 deletions

View File

@ -82,7 +82,7 @@
<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?"/>
<MudText Typo="Typo.h4" Class="mb-3">Assistants Options</MudText> <MudText Typo="Typo.h4" Class="mb-3">Assistant Options</MudText>
<MudText Typo="Typo.h5" Class="mb-3">Icon Finder Options</MudText> <MudText Typo="Typo.h5" Class="mb-3">Icon Finder Options</MudText>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg"> <MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
@ -93,8 +93,11 @@
<MudText Typo="Typo.h5" Class="mb-3">Translator Options</MudText> <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)"/> <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)"/>
<ConfigurationOption OptionDescription="Hide the web content reader?" LabelOn="Web content reader is hidden" LabelOff="Web content reader is shown" State="@(() => this.SettingsManager.ConfigurationData.HideWebContentReaderForTranslation)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.HideWebContentReaderForTranslation = updatedState)" OptionHelp="When activated, the web content reader is hidden and cannot be used. As a result, the user interface becomes a bit easier to use."/>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg"> <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 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 the web content reader?" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions || this.SettingsManager.ConfigurationData.HideWebContentReaderForTranslation)" LabelOn="Web content reader is preselected" LabelOff="Web content reader is not preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectWebContentReaderForTranslation)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectWebContentReaderForTranslation = updatedState)" OptionHelp="When enabled, the web content reader is preselected. This is might be useful when you prefer to load content from the web very often."/>
<ConfigurationOption OptionDescription="Preselect the content cleaner agent?" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions || this.SettingsManager.ConfigurationData.HideWebContentReaderForTranslation)" LabelOn="Content cleaner agent is preselected" LabelOff="Content cleaner agent is not preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectContentCleanerAgentForTranslation)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectContentCleanerAgentForTranslation = updatedState)" OptionHelp="When enabled, the content cleaner agent is preselected. This is might be useful when you prefer to clean up the content before translating it."/>
<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)" /> <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?"/> <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) @if (this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage is CommonLanguages.OTHER)
@ -117,8 +120,11 @@
</MudPaper> </MudPaper>
<MudText Typo="Typo.h5" Class="mb-3">Text Summarizer Options</MudText> <MudText Typo="Typo.h5" Class="mb-3">Text Summarizer Options</MudText>
<ConfigurationOption OptionDescription="Hide the web content reader?" LabelOn="Web content reader is hidden" LabelOff="Web content reader is shown" State="@(() => this.SettingsManager.ConfigurationData.HideWebContentReaderForTextSummarizer)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.HideWebContentReaderForTextSummarizer = updatedState)" OptionHelp="When activated, the web content reader is hidden and cannot be used. As a result, the user interface becomes a bit easier to use."/>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg"> <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."/> <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."/>
<ConfigurationOption OptionDescription="Preselect the web content reader?" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions || this.SettingsManager.ConfigurationData.HideWebContentReaderForTextSummarizer)" LabelOn="Web content reader is preselected" LabelOff="Web content reader is not preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectWebContentReaderForTextSummarizer)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectWebContentReaderForTextSummarizer = updatedState)" OptionHelp="When enabled, the web content reader is preselected. This is might be useful when you prefer to load content from the web very often."/>
<ConfigurationOption OptionDescription="Preselect the content cleaner agent?" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions || this.SettingsManager.ConfigurationData.HideWebContentReaderForTextSummarizer)" LabelOn="Content cleaner agent is preselected" LabelOff="Content cleaner agent is not preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectContentCleanerAgentForTextSummarizer)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectContentCleanerAgentForTextSummarizer = updatedState)" OptionHelp="When enabled, the content cleaner agent is preselected. This is might be useful when you prefer to clean up the content before summarize it."/>
<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?"/> <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) @if (this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage is CommonLanguages.OTHER)
{ {

View File

@ -3,7 +3,12 @@
@using AIStudio.Tools @using AIStudio.Tools
@inherits AssistantBaseCore @inherits AssistantBaseCore
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/> @if (!this.SettingsManager.ConfigurationData.HideWebContentReaderForTextSummarizer)
{
<ReadWebContent @bind-Content="@this.inputText" ProviderSettings="@this.providerSettings" @bind-AgentIsRunning="@this.isAgentRunning" Preselect="@(this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions && this.SettingsManager.ConfigurationData.PreselectWebContentReaderForTextSummarizer)" PreselectContentCleanerAgent="@(this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions && this.SettingsManager.ConfigurationData.PreselectContentCleanerAgentForTextSummarizer)"/>
}
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudStack Row="@true" AlignItems="AlignItems.Center" Class="mb-3"> <MudStack Row="@true" AlignItems="AlignItems.Center" Class="mb-3">
<MudSelect T="CommonLanguages" @bind-Value="@this.selectedTargetLanguage" AdornmentIcon="@Icons.Material.Filled.Translate" Adornment="Adornment.Start" Label="Target language" Variant="Variant.Outlined" Margin="Margin.Dense"> <MudSelect T="CommonLanguages" @bind-Value="@this.selectedTargetLanguage" AdornmentIcon="@Icons.Material.Filled.Translate" Adornment="Adornment.Start" Label="Target language" Variant="Variant.Outlined" Margin="Margin.Dense">
@ -31,13 +36,13 @@
} }
</MudStack> </MudStack>
<MudSelect T="Provider" @bind-Value="@this.providerSettings" Validation="@this.ValidatingProvider" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Apps" Margin="Margin.Dense" Label="Provider" Class="mb-3 rounded-lg" Variant="Variant.Outlined"> <MudSelect T="Provider" Disabled="@this.isAgentRunning" @bind-Value="@this.providerSettings" Validation="@this.ValidatingProvider" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Apps" Margin="Margin.Dense" Label="Provider" Class="mb-3 rounded-lg" Variant="Variant.Outlined">
@foreach (var provider in this.SettingsManager.ConfigurationData.Providers) @foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
{ {
<MudSelectItem Value="@provider"/> <MudSelectItem Value="@provider"/>
} }
</MudSelect> </MudSelect>
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.SummarizeText()"> <MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.SummarizeText()" Disabled="@this.isAgentRunning">
Summarize Summarize
</MudButton> </MudButton>

View File

@ -24,6 +24,7 @@ public partial class AssistantTextSummarizer : AssistantBaseCore
"""; """;
private string inputText = string.Empty; private string inputText = string.Empty;
private bool isAgentRunning;
private CommonLanguages selectedTargetLanguage; private CommonLanguages selectedTargetLanguage;
private string customTargetLanguage = string.Empty; private string customTargetLanguage = string.Empty;
private Complexity selectedComplexity; private Complexity selectedComplexity;

View File

@ -3,6 +3,11 @@
@using AIStudio.Tools @using AIStudio.Tools
@inherits AssistantBaseCore @inherits AssistantBaseCore
@if (!this.SettingsManager.ConfigurationData.HideWebContentReaderForTranslation)
{
<ReadWebContent @bind-Content="@this.inputText" ProviderSettings="@this.providerSettings" @bind-AgentIsRunning="@this.isAgentRunning" Preselect="@(this.SettingsManager.ConfigurationData.PreselectTranslationOptions && this.SettingsManager.ConfigurationData.PreselectWebContentReaderForTranslation)" PreselectContentCleanerAgent="@(this.SettingsManager.ConfigurationData.PreselectTranslationOptions && this.SettingsManager.ConfigurationData.PreselectContentCleanerAgentForTranslation)"/>
}
<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" Color="Color.Primary"> <MudSwitch T="bool" @bind-Value="@this.liveTranslation" Color="Color.Primary">
@(this.liveTranslation ? "Live translation" : "No live translation") @(this.liveTranslation ? "Live translation" : "No live translation")
@ -11,11 +16,11 @@
@if (this.liveTranslation) @if (this.liveTranslation)
{ {
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" Immediate="@true" DebounceInterval="1_000" OnDebounceIntervalElapsed="() => this.TranslateText(force: false)" UserAttributes="@USER_INPUT_ATTRIBUTES"/> <MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" Immediate="@true" DebounceInterval="1_000" OnDebounceIntervalElapsed="() => this.TranslateText(force: false)" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
} }
else else
{ {
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/> <MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
} }
<MudStack Row="@true" AlignItems="AlignItems.Center" Class="mb-3"> <MudStack Row="@true" AlignItems="AlignItems.Center" Class="mb-3">
@ -38,13 +43,13 @@ else
} }
</MudStack> </MudStack>
<MudSelect T="Provider" @bind-Value="@this.providerSettings" Validation="@this.ValidatingProvider" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Apps" Margin="Margin.Dense" Label="Provider" Class="mb-3 rounded-lg" Variant="Variant.Outlined"> <MudSelect T="Provider" @bind-Value="@this.providerSettings" Disabled="@this.isAgentRunning" Validation="@this.ValidatingProvider" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Apps" Margin="Margin.Dense" Label="Provider" Class="mb-3 rounded-lg" Variant="Variant.Outlined">
@foreach (var provider in this.SettingsManager.ConfigurationData.Providers) @foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
{ {
<MudSelectItem Value="@provider"/> <MudSelectItem Value="@provider"/>
} }
</MudSelect> </MudSelect>
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.TranslateText(force: true)"> <MudButton Disabled="@this.isAgentRunning" Variant="Variant.Filled" Class="mb-3" OnClick="() => this.TranslateText(force: true)">
Translate Translate
</MudButton> </MudButton>

View File

@ -20,6 +20,7 @@ public partial class AssistantTranslation : AssistantBaseCore
"""; """;
private bool liveTranslation; private bool liveTranslation;
private bool isAgentRunning;
private string inputText = string.Empty; private string inputText = string.Empty;
private string inputTextLastTranslation = string.Empty; private string inputTextLastTranslation = string.Empty;
private CommonLanguages selectedTargetLanguage; private CommonLanguages selectedTargetLanguage;

View File

@ -120,6 +120,21 @@ public sealed class Data
/// </summary> /// </summary>
public bool PreselectLiveTranslation { get; set; } public bool PreselectLiveTranslation { get; set; }
/// <summary>
/// Hide the web content reader?
/// </summary>
public bool HideWebContentReaderForTranslation { get; set; }
/// <summary>
/// Preselect the web content reader?
/// </summary>
public bool PreselectWebContentReaderForTranslation { get; set; }
/// <summary>
/// Preselect the content cleaner agent?
/// </summary>
public bool PreselectContentCleanerAgentForTranslation { get; set; }
/// <summary> /// <summary>
/// Preselect the target language? /// Preselect the target language?
/// </summary> /// </summary>
@ -173,6 +188,22 @@ public sealed class Data
/// </summary> /// </summary>
public bool PreselectTextSummarizerOptions { get; set; } public bool PreselectTextSummarizerOptions { get; set; }
/// <summary>
/// Hide the web content reader?
/// </summary>
public bool HideWebContentReaderForTextSummarizer { get; set; }
/// <summary>
/// Preselect the web content reader?
/// </summary>
public bool PreselectWebContentReaderForTextSummarizer { get; set; }
/// <summary>
/// Preselect the content cleaner agent?
/// </summary>
public bool PreselectContentCleanerAgentForTextSummarizer { get; set; }
/// <summary> /// <summary>
/// Preselect the target language? /// Preselect the target language?
/// </summary> /// </summary>

View File

@ -2,7 +2,8 @@
- Added possibility to configure a default provider for chats - Added possibility to configure a default provider for chats
- Added architecture for future agent usage - Added architecture for future agent usage
- Added a first agent to read, analyze and extract text from Markdown data - Added a first agent to read, analyze and extract text from Markdown data
- Added option to read web content into translation and text summarization assistants
- Improved the readability of the `settings.json` file by using indentation and enum names instead of numbers - Improved the readability of the `settings.json` file by using indentation and enum names instead of numbers
- Improved assistant overview; assistants will now wrap to the next line if there are too many to fit on the row - Improved assistant overview; assistants will now wrap to the next line if there are too many to fit on the row
- Increased the default value for the live translation delay from 1,000 to 1,500 ms - Increased the default value for the live translation delay from 1,000 to 3_000 ms
- Fixed random number generator usage to be thread-safe - Fixed random number generator usage to be thread-safe