2024-08-21 06:30:01 +00:00
using AIStudio.Dialogs ;
2024-04-20 15:06:50 +00:00
using AIStudio.Provider ;
2024-04-19 19:25:44 +00:00
using AIStudio.Settings ;
2024-07-24 13:17:45 +00:00
2024-04-19 19:25:44 +00:00
using Microsoft.AspNetCore.Components ;
2024-08-21 06:30:01 +00:00
using DialogOptions = AIStudio . Dialogs . DialogOptions ;
2024-09-01 18:10:03 +00:00
using RustService = AIStudio . Tools . RustService ;
2024-06-30 13:26:28 +00:00
2024-04-19 19:25:44 +00:00
// ReSharper disable ClassNeverInstantiated.Global
2024-08-21 06:30:01 +00:00
namespace AIStudio.Pages ;
2024-04-19 19:25:44 +00:00
2024-07-28 09:20:00 +00:00
public partial class Settings : ComponentBase , IMessageBusReceiver , IDisposable
2024-04-19 19:25:44 +00:00
{
[Inject]
2024-09-01 18:10:03 +00:00
private SettingsManager SettingsManager { get ; init ; } = null ! ;
2024-04-19 19:25:44 +00:00
[Inject]
2024-09-01 18:10:03 +00:00
private IDialogService DialogService { get ; init ; } = null ! ;
2024-04-20 15:06:50 +00:00
[Inject]
2024-09-01 18:10:03 +00:00
private MessageBus MessageBus { get ; init ; } = null ! ;
2024-07-24 13:17:45 +00:00
[Inject]
2024-09-01 18:10:03 +00:00
private ILogger < Settings > Logger { get ; init ; } = null ! ;
[Inject]
private RustService RustService { get ; init ; } = null ! ;
2024-07-28 09:20:00 +00:00
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
2024-04-19 19:25:44 +00:00
2024-05-04 08:55:00 +00:00
#region Provider related
2024-04-19 19:25:44 +00:00
private async Task AddProvider ( )
{
2024-04-19 21:27:38 +00:00
var dialogParameters = new DialogParameters < ProviderDialog >
{
2024-04-20 15:06:50 +00:00
{ x = > x . IsEditing , false } ,
2024-04-19 21:27:38 +00:00
} ;
2024-04-20 15:06:50 +00:00
2024-06-30 13:26:28 +00:00
var dialogReference = await this . DialogService . ShowAsync < ProviderDialog > ( "Add Provider" , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-04-19 19:25:44 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-04-19 19:25:44 +00:00
return ;
2024-07-24 13:17:45 +00:00
var addedProvider = ( AIStudio . Settings . Provider ) dialogResult . Data ! ;
2024-05-19 18:28:25 +00:00
addedProvider = addedProvider with { Num = this . SettingsManager . ConfigurationData . NextProviderNum + + } ;
2024-04-20 15:06:50 +00:00
this . SettingsManager . ConfigurationData . Providers . Add ( addedProvider ) ;
2024-07-28 09:20:00 +00:00
this . UpdateProviders ( ) ;
2024-04-20 15:06:50 +00:00
await this . SettingsManager . StoreSettings ( ) ;
2024-07-24 13:17:45 +00:00
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
2024-04-20 15:06:50 +00:00
}
2024-05-04 09:08:45 +00:00
private async Task EditProvider ( AIStudio . Settings . Provider provider )
2024-04-20 15:06:50 +00:00
{
var dialogParameters = new DialogParameters < ProviderDialog >
{
2024-05-19 18:28:25 +00:00
{ x = > x . DataNum , provider . Num } ,
2024-04-20 15:06:50 +00:00
{ x = > x . DataId , provider . Id } ,
{ x = > x . DataInstanceName , provider . InstanceName } ,
2024-09-13 19:50:00 +00:00
{ x = > x . DataLLMProvider , provider . UsedLLMProvider } ,
2024-05-19 14:16:16 +00:00
{ x = > x . DataModel , provider . Model } ,
2024-07-03 18:31:04 +00:00
{ x = > x . DataHostname , provider . Hostname } ,
{ x = > x . IsSelfHosted , provider . IsSelfHosted } ,
2024-04-20 15:06:50 +00:00
{ x = > x . IsEditing , true } ,
2024-07-16 08:28:13 +00:00
{ x = > x . DataHost , provider . Host } ,
2024-04-20 15:06:50 +00:00
} ;
2024-06-30 13:26:28 +00:00
var dialogReference = await this . DialogService . ShowAsync < ProviderDialog > ( "Edit Provider" , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-04-20 15:06:50 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-04-20 15:06:50 +00:00
return ;
2024-07-24 13:17:45 +00:00
var editedProvider = ( AIStudio . Settings . Provider ) dialogResult . Data ! ;
2024-05-19 18:28:25 +00:00
// Set the provider number if it's not set. This is important for providers
// added before we started saving the provider number.
if ( editedProvider . Num = = 0 )
editedProvider = editedProvider with { Num = this . SettingsManager . ConfigurationData . NextProviderNum + + } ;
2024-04-20 15:06:50 +00:00
this . SettingsManager . ConfigurationData . Providers [ this . SettingsManager . ConfigurationData . Providers . IndexOf ( provider ) ] = editedProvider ;
2024-07-28 09:20:00 +00:00
this . UpdateProviders ( ) ;
2024-04-20 15:06:50 +00:00
await this . SettingsManager . StoreSettings ( ) ;
2024-07-24 13:17:45 +00:00
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
2024-04-20 15:06:50 +00:00
}
2024-05-04 09:08:45 +00:00
private async Task DeleteProvider ( AIStudio . Settings . Provider provider )
2024-04-20 15:06:50 +00:00
{
var dialogParameters = new DialogParameters
{
{ "Message" , $"Are you sure you want to delete the provider '{provider.InstanceName}'?" } ,
} ;
2024-06-30 13:26:28 +00:00
var dialogReference = await this . DialogService . ShowAsync < ConfirmDialog > ( "Delete Provider" , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-04-20 15:06:50 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-04-20 15:06:50 +00:00
return ;
2024-09-01 18:10:03 +00:00
var providerInstance = provider . CreateProvider ( this . Logger ) ;
var deleteSecretResponse = await this . RustService . DeleteAPIKey ( providerInstance ) ;
2024-04-20 15:06:50 +00:00
if ( deleteSecretResponse . Success )
{
this . SettingsManager . ConfigurationData . Providers . Remove ( provider ) ;
await this . SettingsManager . StoreSettings ( ) ;
}
2024-07-24 13:17:45 +00:00
2024-07-28 09:20:00 +00:00
this . UpdateProviders ( ) ;
2024-07-24 13:17:45 +00:00
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
2024-04-19 19:25:44 +00:00
}
2024-07-03 18:31:04 +00:00
2024-09-13 19:50:00 +00:00
private bool HasDashboard ( LLMProviders llmProvider ) = > llmProvider switch
2024-07-25 13:29:44 +00:00
{
2024-09-13 19:50:00 +00:00
LLMProviders . OPEN_AI = > true ,
LLMProviders . MISTRAL = > true ,
LLMProviders . ANTHROPIC = > true ,
2024-11-09 19:13:14 +00:00
LLMProviders . GROQ = > true ,
2024-09-13 19:50:00 +00:00
LLMProviders . FIREWORKS = > true ,
2024-11-09 21:04:00 +00:00
LLMProviders . GOOGLE = > true ,
2024-07-25 13:29:44 +00:00
_ = > false ,
} ;
2024-09-13 19:50:00 +00:00
private string GetProviderDashboardURL ( LLMProviders llmProvider ) = > llmProvider switch
2024-07-03 18:31:04 +00:00
{
2024-09-13 19:50:00 +00:00
LLMProviders . OPEN_AI = > "https://platform.openai.com/usage" ,
LLMProviders . MISTRAL = > "https://console.mistral.ai/usage/" ,
LLMProviders . ANTHROPIC = > "https://console.anthropic.com/settings/plans" ,
2024-11-09 19:13:14 +00:00
LLMProviders . GROQ = > "https://console.groq.com/settings/usage" ,
2024-11-09 21:04:00 +00:00
LLMProviders . GOOGLE = > "https://console.cloud.google.com/billing" ,
2024-09-13 19:50:00 +00:00
LLMProviders . FIREWORKS = > "https://fireworks.ai/account/billing" ,
2024-07-03 18:31:04 +00:00
_ = > string . Empty ,
} ;
2024-05-04 08:55:00 +00:00
2024-07-24 17:27:25 +00:00
private string GetProviderModelName ( AIStudio . Settings . Provider provider )
{
const int MAX_LENGTH = 36 ;
var modelName = provider . Model . ToString ( ) ;
return modelName . Length > MAX_LENGTH ? "[...] " + modelName [ ^ Math . Min ( MAX_LENGTH , modelName . Length ) . . ] : modelName ;
}
2024-07-28 09:20:00 +00:00
private void UpdateProviders ( )
{
this . availableProviders . Clear ( ) ;
foreach ( var provider in this . SettingsManager . ConfigurationData . Providers )
this . availableProviders . Add ( new ( provider . InstanceName , provider . Id ) ) ;
}
2024-09-13 19:50:00 +00:00
private string GetCurrentConfidenceLevelName ( LLMProviders llmProvider )
2024-09-11 21:08:02 +00:00
{
2024-09-13 19:50:00 +00:00
if ( this . SettingsManager . ConfigurationData . LLMProviders . CustomConfidenceScheme . TryGetValue ( llmProvider , out var level ) )
2024-09-11 21:08:02 +00:00
return level . GetName ( ) ;
return "Not yet configured" ;
}
2024-09-13 19:50:00 +00:00
private string SetCurrentConfidenceLevelColorStyle ( LLMProviders llmProvider )
2024-09-11 21:08:02 +00:00
{
2024-09-13 19:50:00 +00:00
if ( this . SettingsManager . ConfigurationData . LLMProviders . CustomConfidenceScheme . TryGetValue ( llmProvider , out var level ) )
2024-09-15 10:30:07 +00:00
return $"background-color: {level.GetColor(this.SettingsManager)};" ;
2024-09-11 21:08:02 +00:00
2024-09-15 10:30:07 +00:00
return $"background-color: {ConfidenceLevel.UNKNOWN.GetColor(this.SettingsManager)};" ;
2024-09-11 21:08:02 +00:00
}
2024-09-13 19:50:00 +00:00
private async Task ChangeCustomConfidenceLevel ( LLMProviders llmProvider , ConfidenceLevel level )
2024-09-11 21:08:02 +00:00
{
2024-09-13 19:50:00 +00:00
this . SettingsManager . ConfigurationData . LLMProviders . CustomConfidenceScheme [ llmProvider ] = level ;
2024-09-11 21:08:02 +00:00
await this . SettingsManager . StoreSettings ( ) ;
}
2024-09-08 19:01:51 +00:00
#endregion
#region Profile related
private async Task AddProfile ( )
{
var dialogParameters = new DialogParameters < ProfileDialog >
{
{ x = > x . IsEditing , false } ,
} ;
var dialogReference = await this . DialogService . ShowAsync < ProfileDialog > ( "Add Profile" , dialogParameters , DialogOptions . FULLSCREEN ) ;
var dialogResult = await dialogReference . Result ;
if ( dialogResult is null | | dialogResult . Canceled )
return ;
var addedProfile = ( Profile ) dialogResult . Data ! ;
addedProfile = addedProfile with { Num = this . SettingsManager . ConfigurationData . NextProfileNum + + } ;
this . SettingsManager . ConfigurationData . Profiles . Add ( addedProfile ) ;
await this . SettingsManager . StoreSettings ( ) ;
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
}
private async Task EditProfile ( Profile profile )
{
var dialogParameters = new DialogParameters < ProfileDialog >
{
{ x = > x . DataNum , profile . Num } ,
{ x = > x . DataId , profile . Id } ,
{ x = > x . DataName , profile . Name } ,
{ x = > x . DataNeedToKnow , profile . NeedToKnow } ,
{ x = > x . DataActions , profile . Actions } ,
{ x = > x . IsEditing , true } ,
} ;
var dialogReference = await this . DialogService . ShowAsync < ProfileDialog > ( "Edit Profile" , dialogParameters , DialogOptions . FULLSCREEN ) ;
var dialogResult = await dialogReference . Result ;
if ( dialogResult is null | | dialogResult . Canceled )
return ;
var editedProfile = ( Profile ) dialogResult . Data ! ;
this . SettingsManager . ConfigurationData . Profiles [ this . SettingsManager . ConfigurationData . Profiles . IndexOf ( profile ) ] = editedProfile ;
await this . SettingsManager . StoreSettings ( ) ;
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
}
private async Task DeleteProfile ( Profile profile )
{
var dialogParameters = new DialogParameters
{
{ "Message" , $"Are you sure you want to delete the profile '{profile.Name}'?" } ,
} ;
var dialogReference = await this . DialogService . ShowAsync < ConfirmDialog > ( "Delete Profile" , dialogParameters , DialogOptions . FULLSCREEN ) ;
var dialogResult = await dialogReference . Result ;
if ( dialogResult is null | | dialogResult . Canceled )
return ;
this . SettingsManager . ConfigurationData . Profiles . Remove ( profile ) ;
await this . SettingsManager . StoreSettings ( ) ;
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
}
2024-10-28 14:41:00 +00:00
#endregion
#region Bias - of - the - day related
private async Task ResetBiasOfTheDayHistory ( )
{
var dialogParameters = new DialogParameters
{
{ "Message" , "Are you sure you want to reset your bias-of-the-day statistics? The system will no longer remember which biases you already know. As a result, biases you are already familiar with may be addressed again." } ,
} ;
var dialogReference = await this . DialogService . ShowAsync < ConfirmDialog > ( "Reset your bias-of-the-day statistics" , dialogParameters , DialogOptions . FULLSCREEN ) ;
var dialogResult = await dialogReference . Result ;
if ( dialogResult is null | | dialogResult . Canceled )
return ;
this . SettingsManager . ConfigurationData . BiasOfTheDay . UsedBias . Clear ( ) ;
this . SettingsManager . ConfigurationData . BiasOfTheDay . DateLastBiasDrawn = DateOnly . MinValue ;
await this . SettingsManager . StoreSettings ( ) ;
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
}
2024-07-28 09:20:00 +00:00
#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 ) ;
}
2024-07-24 17:27:25 +00:00
2024-05-04 08:55:00 +00:00
#endregion
2024-04-19 19:25:44 +00:00
}