Added optional enforcement for a min. confidence level (#145)

This commit is contained in:
Thorsten Sommer 2024-09-13 23:29:19 +02:00 committed by GitHub
parent 1cac1a7913
commit 4175387a93
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 242 additions and 16 deletions

View File

@ -1 +1 @@
<ConfigurationSelect OptionDescription="Preselected provider" Disabled="@this.Disabled" OptionHelp="@this.HelpText()" Data="@this.Data" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/> <ConfigurationSelect OptionDescription="Preselected provider" Disabled="@this.Disabled" OptionHelp="@this.HelpText()" Data="@this.FilteredData()" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/>

View File

@ -1,3 +1,4 @@
using AIStudio.Provider;
using AIStudio.Settings; using AIStudio.Settings;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@ -43,6 +44,25 @@ public partial class ConfigurationProviderSelection : ComponentBase, IMessageBus
#endregion #endregion
private IEnumerable<ConfigurationSelectData<string>> FilteredData()
{
if (this.SettingsManager.ConfigurationData.LLMProviders is { EnforceGlobalMinimumConfidence: true, GlobalMinimumConfidence: not ConfidenceLevel.NONE and not ConfidenceLevel.UNKNOWN })
{
var minimumLevel = this.SettingsManager.ConfigurationData.LLMProviders.GlobalMinimumConfidence;
foreach (var providerId in this.Data)
{
var provider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == providerId.Value);
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
yield return providerId;
}
}
else
{
foreach (var provider in this.Data)
yield return provider;
}
}
#region Implementation of IMessageBusReceiver #region Implementation of IMessageBusReceiver
public async Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) public async Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)

View File

@ -1,7 +1,7 @@
@using AIStudio.Settings @using AIStudio.Settings
<MudSelect T="Provider" Value="@this.ProviderSettings" ValueChanged="@this.SelectionChanged" Validation="@this.ValidateProvider" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Apps" Margin="Margin.Dense" Label="Provider" Class="mb-3 rounded-lg" Variant="Variant.Outlined"> <MudSelect T="Provider" Value="@this.ProviderSettings" ValueChanged="@this.SelectionChanged" Validation="@this.ValidateProvider" 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.GetAvailableProviders())
{ {
<MudSelectItem Value="@provider"/> <MudSelectItem Value="@provider"/>
} }

View File

@ -1,3 +1,4 @@
using AIStudio.Provider;
using AIStudio.Settings; using AIStudio.Settings;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@ -16,11 +17,27 @@ public partial class ProviderSelection : ComponentBase
public Func<Settings.Provider, string?> ValidateProvider { get; set; } = _ => null; public Func<Settings.Provider, string?> ValidateProvider { get; set; } = _ => null;
[Inject] [Inject]
protected SettingsManager SettingsManager { get; set; } = null!; private SettingsManager SettingsManager { get; init; } = null!;
private async Task SelectionChanged(Settings.Provider provider) private async Task SelectionChanged(Settings.Provider provider)
{ {
this.ProviderSettings = provider; this.ProviderSettings = provider;
await this.ProviderSettingsChanged.InvokeAsync(provider); await this.ProviderSettingsChanged.InvokeAsync(provider);
} }
private IEnumerable<Settings.Provider> GetAvailableProviders()
{
if (this.SettingsManager.ConfigurationData.LLMProviders is { EnforceGlobalMinimumConfidence: true, GlobalMinimumConfidence: not ConfidenceLevel.NONE and not ConfidenceLevel.UNKNOWN })
{
var minimumLevel = this.SettingsManager.ConfigurationData.LLMProviders.GlobalMinimumConfidence;
foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
yield return provider;
}
else
{
foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
yield return provider;
}
}
} }

View File

@ -80,6 +80,12 @@
Either you choose a common schema, or you configure the trust levels for each LLM provider yourself. Either you choose a common schema, or you configure the trust levels for each LLM provider yourself.
</MudJustifiedText> </MudJustifiedText>
<ConfigurationOption OptionDescription="Do you want to enforce an app-wide minimum confidence level?" LabelOn="Yes, enforce a minimum confidence level" LabelOff="No, do not enforce a minimum confidence level" State="@(() => this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence = updatedState)" OptionHelp="When enabled, you can enforce a minimum confidence level for all LLM providers. This way, you can ensure that only trustworthy providers are used."/>
@if(this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence)
{
<ConfigurationSelect OptionDescription="Select a minimum confidence level" SelectedValue="@(() => this.SettingsManager.ConfigurationData.LLMProviders.GlobalMinimumConfidence)" Data="@ConfigurationSelectDataFactory.GetConfidenceLevelsData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.LLMProviders.GlobalMinimumConfidence = selectedValue)" OptionHelp="Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level."/>
}
<ConfigurationOption OptionDescription="Show provider's confidence level?" LabelOn="Yes, show me the confidence level" LabelOff="No, please hide the confidence level" State="@(() => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence = updatedState)" OptionHelp="When enabled, we show you the confidence level for the selected provider in the app. This helps you assess where you are sending your data at any time. Example: are you currently working with sensitive data? Then choose a particularly trustworthy provider, etc."/> <ConfigurationOption OptionDescription="Show provider's confidence level?" LabelOn="Yes, show me the confidence level" LabelOff="No, please hide the confidence level" State="@(() => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence = updatedState)" OptionHelp="When enabled, we show you the confidence level for the selected provider in the app. This helps you assess where you are sending your data at any time. Example: are you currently working with sensitive data? Then choose a particularly trustworthy provider, etc."/>
@if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence) @if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)
{ {

View File

@ -4,6 +4,7 @@ using AIStudio.Assistants.IconFinder;
using AIStudio.Assistants.RewriteImprove; using AIStudio.Assistants.RewriteImprove;
using AIStudio.Assistants.TextSummarizer; using AIStudio.Assistants.TextSummarizer;
using AIStudio.Assistants.EMail; using AIStudio.Assistants.EMail;
using AIStudio.Provider;
using AIStudio.Settings.DataModel; using AIStudio.Settings.DataModel;
using WritingStylesRewrite = AIStudio.Assistants.RewriteImprove.WritingStyles; using WritingStylesRewrite = AIStudio.Assistants.RewriteImprove.WritingStyles;
@ -142,4 +143,24 @@ public static class ConfigurationSelectDataFactory
foreach (var scheme in Enum.GetValues<ConfidenceSchemes>()) foreach (var scheme in Enum.GetValues<ConfidenceSchemes>())
yield return new(scheme.GetListDescription(), scheme); yield return new(scheme.GetListDescription(), scheme);
} }
public static IEnumerable<ConfigurationSelectData<ConfidenceLevel>> GetConfidenceLevelsData()
{
foreach (var level in Enum.GetValues<ConfidenceLevel>())
{
switch (level)
{
case ConfidenceLevel.UNKNOWN:
continue;
case ConfidenceLevel.NONE:
yield return new("No minimum confidence level chosen", level);
break;
default:
yield return new(level.GetName(), level);
break;
}
}
}
} }

View File

@ -9,7 +9,7 @@ public sealed class Data
/// The version of the settings file. Allows us to upgrade the settings /// The version of the settings file. Allows us to upgrade the settings
/// when a new version is available. /// when a new version is available.
/// </summary> /// </summary>
public Version Version { get; init; } = Version.V4; public Version Version { get; init; } = Version.V5;
/// <summary> /// <summary>
/// List of configured providers. /// List of configured providers.

View File

@ -4,6 +4,16 @@ namespace AIStudio.Settings.DataModel;
public sealed class DataLLMProviders public sealed class DataLLMProviders
{ {
/// <summary>
/// Should we enforce a global minimum confidence level?
/// </summary>
public bool EnforceGlobalMinimumConfidence { get; set; }
/// <summary>
/// The global minimum confidence level to enforce.
/// </summary>
public ConfidenceLevel GlobalMinimumConfidence { get; set; } = ConfidenceLevel.NONE;
/// <summary> /// <summary>
/// Should we show the provider confidence level? /// Should we show the provider confidence level?
/// </summary> /// </summary>

View File

@ -0,0 +1,65 @@
namespace AIStudio.Settings.DataModel.PreviousModels;
public sealed class DataV4
{
/// <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; }
/// <summary>
/// List of configured providers.
/// </summary>
public List<Provider> Providers { get; init; } = [];
/// <summary>
/// Settings concerning the LLM providers.
/// </summary>
public DataLLMProviders LLMProviders { get; init; } = new();
/// <summary>
/// List of configured profiles.
/// </summary>
public List<Profile> Profiles { get; init; } = [];
/// <summary>
/// The next provider number to use.
/// </summary>
public uint NextProviderNum { get; set; } = 1;
/// <summary>
/// The next profile number to use.
/// </summary>
public uint NextProfileNum { get; set; } = 1;
public DataApp App { get; init; } = new();
public DataChat Chat { get; init; } = new();
public DataWorkspace Workspace { get; init; } = new();
public DataIconFinder IconFinder { get; init; } = new();
public DataTranslation Translation { get; init; } = new();
public DataCoding Coding { get; init; } = new();
public DataTextSummarizer TextSummarizer { get; init; } = new();
public DataTextContentCleaner TextContentCleaner { get; init; } = new();
public DataAgenda Agenda { get; init; } = new();
public DataGrammarSpelling GrammarSpelling { get; init; } = new();
public DataRewriteImprove RewriteImprove { get; init; } = new();
public DataEMail EMail { get; set; } = new();
public DataLegalCheck LegalCheck { get; set; } = new();
public DataSynonyms Synonyms { get; set; } = new();
public DataMyTasks MyTasks { get; set; } = new();
}

View File

@ -0,0 +1,15 @@
using AIStudio.Provider;
using Host = AIStudio.Provider.SelfHosted.Host;
namespace AIStudio.Settings.DataModel.PreviousModels;
public readonly record struct Provider(
uint Num,
string Id,
string InstanceName,
LLMProviders UsedProvider,
Model Model,
bool IsSelfHosted = false,
string Hostname = "http://localhost:1234",
Host Host = Host.NONE);

View File

@ -0,0 +1,21 @@
namespace AIStudio.Settings.DataModel.PreviousModels;
public static class ProviderV4Extensions
{
public static List<Settings.Provider> MigrateFromV4ToV5(this IEnumerable<Provider> providers)
{
return providers.Select(provider => provider.MigrateFromV4ToV5()).ToList();
}
public static Settings.Provider MigrateFromV4ToV5(this Provider provider) => new()
{
Num = provider.Num,
Id = provider.Id,
InstanceName = provider.InstanceName,
UsedLLMProvider = provider.UsedProvider,
Model = provider.Model,
IsSelfHosted = provider.IsSelfHosted,
Hostname = provider.Hostname,
Host = provider.Host,
};
}

View File

@ -114,7 +114,9 @@ public sealed class SettingsManager(ILogger<SettingsManager> logger)
public Provider GetPreselectedProvider(Tools.Components component) public Provider GetPreselectedProvider(Tools.Components component)
{ {
if(this.ConfigurationData.Providers.Count == 1) var minimumLevel = this.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence ? this.ConfigurationData.LLMProviders.GlobalMinimumConfidence : ConfidenceLevel.NONE;
if (this.ConfigurationData.Providers.Count == 1 && this.ConfigurationData.Providers[0].UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
return this.ConfigurationData.Providers[0]; return this.ConfigurationData.Providers[0];
var preselection = component switch var preselection = component switch
@ -135,10 +137,10 @@ public sealed class SettingsManager(ILogger<SettingsManager> logger)
_ => default, _ => default,
}; };
if (preselection != default) if(preselection != default && preselection.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
return preselection; return preselection;
return this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.App.PreselectedProvider); return this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.App.PreselectedProvider && x.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel);
} }
public Profile GetPreselectedProfile(Tools.Components component) public Profile GetPreselectedProfile(Tools.Components component)

View File

@ -23,7 +23,8 @@ public static class SettingsMigrations
configV1 = MigrateV1ToV2(logger, configV1); configV1 = MigrateV1ToV2(logger, configV1);
configV1 = MigrateV2ToV3(logger, configV1); configV1 = MigrateV2ToV3(logger, configV1);
return MigrateV3ToV4(logger, configV1); var configV14 = MigrateV3ToV4(logger, configV1);
return MigrateV4ToV5(logger, configV14);
case Version.V2: case Version.V2:
var configV2 = JsonSerializer.Deserialize<DataV1V3>(configData, jsonOptions); var configV2 = JsonSerializer.Deserialize<DataV1V3>(configData, jsonOptions);
@ -34,7 +35,8 @@ public static class SettingsMigrations
} }
configV2 = MigrateV2ToV3(logger, configV2); configV2 = MigrateV2ToV3(logger, configV2);
return MigrateV3ToV4(logger, configV2); var configV24 = MigrateV3ToV4(logger, configV2);
return MigrateV4ToV5(logger, configV24);
case Version.V3: case Version.V3:
var configV3 = JsonSerializer.Deserialize<DataV1V3>(configData, jsonOptions); var configV3 = JsonSerializer.Deserialize<DataV1V3>(configData, jsonOptions);
@ -44,18 +46,29 @@ public static class SettingsMigrations
return new(); return new();
} }
return MigrateV3ToV4(logger, configV3); var configV34 = MigrateV3ToV4(logger, configV3);
return MigrateV4ToV5(logger, configV34);
default: case Version.V4:
logger.LogInformation("No configuration migration is needed."); var configV4 = JsonSerializer.Deserialize<DataV4>(configData, jsonOptions);
var configV4 = JsonSerializer.Deserialize<Data>(configData, jsonOptions);
if (configV4 is null) if (configV4 is null)
{ {
logger.LogError("Failed to parse the v4 configuration. Using default values."); logger.LogError("Failed to parse the v4 configuration. Using default values.");
return new(); return new();
} }
return configV4; return MigrateV4ToV5(logger, configV4);
default:
logger.LogInformation("No configuration migration is needed.");
var configV5 = JsonSerializer.Deserialize<Data>(configData, jsonOptions);
if (configV5 is null)
{
logger.LogError("Failed to parse the v4 configuration. Using default values.");
return new();
}
return configV5;
} }
} }
@ -110,7 +123,7 @@ public static class SettingsMigrations
}; };
} }
private static Data MigrateV3ToV4(ILogger<SettingsManager> logger, DataV1V3 previousConfig) private static DataV4 MigrateV3ToV4(ILogger<SettingsManager> logger, DataV1V3 previousConfig)
{ {
// //
// Summary: // Summary:
@ -194,4 +207,38 @@ public static class SettingsMigrations
}, },
}; };
} }
private static Data MigrateV4ToV5(ILogger<SettingsManager> logger, DataV4 previousConfig)
{
//
// Summary:
// We renamed the LLM provider enum.
//
logger.LogInformation("Migrating from v4 to v5...");
return new()
{
Version = Version.V5,
Providers = previousConfig.Providers.MigrateFromV4ToV5(),
LLMProviders = previousConfig.LLMProviders,
Profiles = previousConfig.Profiles,
NextProviderNum = previousConfig.NextProviderNum,
NextProfileNum = previousConfig.NextProfileNum,
App = previousConfig.App,
Chat = previousConfig.Chat,
Workspace = previousConfig.Workspace,
IconFinder = previousConfig.IconFinder,
Translation = previousConfig.Translation,
Coding = previousConfig.Coding,
TextSummarizer = previousConfig.TextSummarizer,
TextContentCleaner = previousConfig.TextContentCleaner,
Agenda = previousConfig.Agenda,
GrammarSpelling = previousConfig.GrammarSpelling,
RewriteImprove = previousConfig.RewriteImprove,
EMail = previousConfig.EMail,
LegalCheck = previousConfig.LegalCheck,
Synonyms = previousConfig.Synonyms,
MyTasks = previousConfig.MyTasks,
};
}
} }

View File

@ -12,4 +12,5 @@ public enum Version
V2, V2,
V3, V3,
V4, V4,
V5,
} }

View File

@ -1,3 +1,4 @@
# v0.9.11, build 186 # v0.9.11, build 186
- Added a tooltip to the confidence card button. - Added a tooltip to the confidence card button.
- Added an option to enforce a minimum confidence level throughout the entire app.
- Renamed the `Providers` enum to `LLMProviders` for better clarity. Renamed also all dependent variables and methods. - Renamed the `Providers` enum to `LLMProviders` for better clarity. Renamed also all dependent variables and methods.