2025-04-12 19:13:33 +00:00
using AIStudio.Components ;
2026-03-24 13:09:48 +00:00
using AIStudio.Agents.AssistantAudit ;
using AIStudio.Dialogs ;
2026-03-26 21:34:39 +00:00
using AIStudio.Settings.DataModel ;
2026-03-24 13:09:48 +00:00
using AIStudio.Tools.PluginSystem.Assistants ;
2025-03-29 17:40:17 +00:00
using AIStudio.Tools.PluginSystem ;
2025-04-24 11:50:14 +00:00
using Microsoft.AspNetCore.Components ;
2026-03-24 13:09:48 +00:00
using DialogOptions = AIStudio . Dialogs . DialogOptions ;
2025-04-24 11:50:14 +00:00
2025-03-29 17:40:17 +00:00
namespace AIStudio.Pages ;
2025-04-12 19:13:33 +00:00
public partial class Plugins : MSGComponentBase
2025-03-29 17:40:17 +00:00
{
private const string GROUP_ENABLED = "Enabled" ;
private const string GROUP_DISABLED = "Disabled" ;
private const string GROUP_INTERNAL = "Internal" ;
2026-03-26 21:34:39 +00:00
private DataAssistantPluginAudit AssistantPluginAuditSettings = > this . SettingsManager . ConfigurationData . AssistantPluginAudit ;
2025-03-29 17:40:17 +00:00
private TableGroupDefinition < IPluginMetadata > groupConfig = null ! ;
2026-03-24 13:09:48 +00:00
[Inject]
private IDialogService DialogService { get ; init ; } = null ! ;
2025-03-29 17:40:17 +00:00
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync ( )
{
2025-04-24 11:50:14 +00:00
this . ApplyFilters ( [ ] , [ Event . PLUGINS_RELOADED ] ) ;
2025-03-30 18:34:30 +00:00
2025-03-29 17:40:17 +00:00
this . groupConfig = new TableGroupDefinition < IPluginMetadata >
{
Expandable = true ,
IsInitiallyExpanded = true ,
Selector = pluginMeta = >
{
if ( pluginMeta . IsInternal )
return GROUP_INTERNAL ;
return this . SettingsManager . IsPluginEnabled ( pluginMeta )
? GROUP_ENABLED
: GROUP_DISABLED ;
}
} ;
await base . OnInitializedAsync ( ) ;
}
#endregion
2025-04-12 19:13:33 +00:00
2025-03-29 17:40:17 +00:00
private async Task PluginActivationStateChanged ( IPluginMetadata pluginMeta )
{
if ( this . SettingsManager . IsPluginEnabled ( pluginMeta ) )
2026-03-24 13:09:48 +00:00
{
2025-03-29 17:40:17 +00:00
this . SettingsManager . ConfigurationData . EnabledPlugins . Remove ( pluginMeta . Id ) ;
2026-03-24 13:09:48 +00:00
await this . SettingsManager . StoreSettings ( ) ;
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
return ;
}
2026-03-26 21:34:39 +00:00
if ( pluginMeta . Type is not PluginType . ASSISTANT | | ! this . AssistantPluginAuditSettings . RequireAuditBeforeActivation )
2026-03-24 13:09:48 +00:00
{
2025-03-29 17:40:17 +00:00
this . SettingsManager . ConfigurationData . EnabledPlugins . Add ( pluginMeta . Id ) ;
2026-03-24 13:09:48 +00:00
await this . SettingsManager . StoreSettings ( ) ;
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
return ;
}
var assistantPlugin = PluginFactory . RunningPlugins . OfType < PluginAssistants > ( ) . FirstOrDefault ( x = > x . Id = = pluginMeta . Id ) ;
if ( assistantPlugin is null )
return ;
var pluginHash = assistantPlugin . ComputeAuditHash ( ) ;
var cachedAudit = this . SettingsManager . ConfigurationData . AssistantPluginAudits . FirstOrDefault ( x = > x . PluginId = = pluginMeta . Id ) ;
if ( cachedAudit is not null & & cachedAudit . PluginHash = = pluginHash )
{
2026-03-26 21:34:39 +00:00
if ( cachedAudit . Level < this . AssistantPluginAuditSettings . MinimumLevel & & this . AssistantPluginAuditSettings . BlockActivationBelowMinimum )
2026-03-24 13:09:48 +00:00
{
await this . DialogService . ShowMessageBox ( this . T ( "Assistant Audit" ) , $"{cachedAudit.Level.GetName()}: {cachedAudit.Summary}" , this . T ( "Close" ) ) ;
return ;
}
2026-03-26 21:34:39 +00:00
if ( cachedAudit . Level < this . AssistantPluginAuditSettings . MinimumLevel & &
! await this . ConfirmActivationBelowMinimumAsync ( pluginMeta . Name , cachedAudit . Level ) )
{
return ;
}
2026-03-24 13:09:48 +00:00
this . SettingsManager . ConfigurationData . EnabledPlugins . Add ( pluginMeta . Id ) ;
await this . SettingsManager . StoreSettings ( ) ;
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
return ;
}
var parameters = new DialogParameters < AssistantPluginAuditDialog >
{
{ x = > x . PluginId , pluginMeta . Id } ,
} ;
var dialog = await this . DialogService . ShowAsync < AssistantPluginAuditDialog > ( this . T ( "Assistant Audit" ) , parameters , DialogOptions . FULLSCREEN ) ;
var result = await dialog . Result ;
if ( result is null | | result . Canceled | | result . Data is not AssistantPluginAuditDialogResult auditResult )
return ;
if ( auditResult . Audit is not null )
this . UpsertAuditCard ( auditResult . Audit ) ;
if ( auditResult . ActivatePlugin )
this . SettingsManager . ConfigurationData . EnabledPlugins . Add ( pluginMeta . Id ) ;
2025-03-29 17:40:17 +00:00
await this . SettingsManager . StoreSettings ( ) ;
await this . MessageBus . SendMessage < bool > ( this , Event . CONFIGURATION_CHANGED ) ;
}
2026-03-26 21:34:39 +00:00
private async Task < bool > ConfirmActivationBelowMinimumAsync ( string pluginName , AssistantAuditLevel actualLevel )
{
var dialogParameters = new DialogParameters < ConfirmDialog >
{
{
x = > x . Message ,
string . Format (
this . T ( "The assistant plugin \"{0}\" was audited with the level \"{1}\", which is below the required minimum level \"{2}\". Your current settings allow activation anyway, but this may be potentially dangerous. Do you really want to enable this plugin?" ) ,
pluginName ,
actualLevel . GetName ( ) ,
this . AssistantPluginAuditSettings . MinimumLevel . GetName ( ) )
} ,
} ;
var dialogReference = await this . DialogService . ShowAsync < ConfirmDialog > ( this . T ( "Potentially Dangerous Plugin" ) , dialogParameters ,
DialogOptions . FULLSCREEN ) ;
var dialogResult = await dialogReference . Result ;
return dialogResult is not null & & ! dialogResult . Canceled ;
}
2026-02-10 14:23:56 +00:00
private static bool IsSendingMail ( string sourceUrl ) = > sourceUrl . TrimStart ( ) . StartsWith ( "mailto:" , StringComparison . OrdinalIgnoreCase ) ;
2025-04-24 11:50:14 +00:00
2026-03-24 13:09:48 +00:00
private void UpsertAuditCard ( PluginAssistantAudit audit )
{
var audits = this . SettingsManager . ConfigurationData . AssistantPluginAudits ;
var existingIndex = audits . FindIndex ( x = > x . PluginId = = audit . PluginId ) ;
if ( existingIndex > = 0 )
audits [ existingIndex ] = audit ;
else
audits . Add ( audit ) ;
}
2025-04-24 11:50:14 +00:00
#region Overrides of MSGComponentBase
protected override async Task ProcessIncomingMessage < T > ( ComponentBase ? sendingComponent , Event triggeredEvent , T ? data ) where T : default
{
switch ( triggeredEvent )
{
case Event . PLUGINS_RELOADED :
await this . InvokeAsync ( this . StateHasChanged ) ;
break ;
}
}
#endregion
2026-02-10 14:23:56 +00:00
}