Added an indicator for locally staged test configurations

This commit is contained in:
Thorsten Sommer 2026-08-09 18:41:33 +02:00
parent 52b4d70fc9
commit d53d7075a3
Signed by untrusted user who does not match committer: tsommer
GPG Key ID: 371BBA77A02C0108
3 changed files with 62 additions and 5 deletions

View File

@ -158,6 +158,31 @@
break; break;
} }
@*
A staged test configuration speaks for the organization without anybody
having deployed it. We report it without the details having to be expanded:
*@
@if (this.testConfigPlugins.Count > 0)
{
<MudText Typo="Typo.body1" Class="mt-2">
@T("A test configuration is active. It acts like a configuration of your organization and may, for example, approve assistant plugins. AI Studio removes it the next time you start the app.")
</MudText>
@foreach (var testConfigPlugin in this.testConfigPlugins)
{
<ConfigPluginInfoCard HeaderIcon="@Icons.Material.Filled.Science"
HeaderText="@testConfigPlugin.Name"
Items="@this.BuildTestConfigurationItems(testConfigPlugin)"
ShowWarning="@true"
WarningText="@T("Test configuration: nobody deployed this configuration. It is valid until you restart AI Studio.")"/>
}
}
else if (PluginFactory.RemovedTestConfigurationsAtStartup > 0)
{
<MudText Typo="Typo.body1" Class="mt-2">
@string.Format(T("AI Studio removed {0} test configuration(s) while starting. A test configuration is valid for one session: place it again while AI Studio is running."), PluginFactory.RemovedTestConfigurationsAtStartup)
</MudText>
}
@if (this.HasEnterpriseConfigurationDetails) @if (this.HasEnterpriseConfigurationDetails)
{ {
<MudButton StartIcon="@(this.showEnterpriseConfigDetails ? Icons.Material.Filled.ExpandLess : Icons.Material.Filled.ExpandMore)" <MudButton StartIcon="@(this.showEnterpriseConfigDetails ? Icons.Material.Filled.ExpandLess : Icons.Material.Filled.ExpandMore)"

View File

@ -107,10 +107,16 @@ public partial class Information : MSGComponentBase
private bool showVectorStoreDetails; private bool showVectorStoreDetails;
private bool showExternalHttpCustomRootCertificateDetails; private bool showExternalHttpCustomRootCertificateDetails;
private List<IAvailablePlugin> configPlugins = PluginFactory.AvailablePlugins private List<IAvailablePlugin> configPlugins = [];
.Where(x => x.Type is PluginType.CONFIGURATION)
.OfType<IAvailablePlugin>() /// <summary>
.ToList(); /// The configuration plugins an administrator staged for a test.
/// </summary>
/// <remarks>
/// They are kept apart from the other configuration plugins: nobody deployed them, yet they act
/// on behalf of the organization while they are loaded. That deserves its own note.
/// </remarks>
private List<IAvailablePlugin> testConfigPlugins = [];
private List<EnterpriseEnvironment> enterpriseEnvironments = EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.ToList(); private List<EnterpriseEnvironment> enterpriseEnvironments = EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.ToList();
@ -201,11 +207,14 @@ public partial class Information : MSGComponentBase
private void RefreshEnterpriseConfigurationState() private void RefreshEnterpriseConfigurationState()
{ {
this.configPlugins = PluginFactory.AvailablePlugins var availableConfigPlugins = PluginFactory.AvailablePlugins
.Where(x => x.Type is PluginType.CONFIGURATION) .Where(x => x.Type is PluginType.CONFIGURATION)
.OfType<IAvailablePlugin>() .OfType<IAvailablePlugin>()
.ToList(); .ToList();
this.testConfigPlugins = availableConfigPlugins.Where(plugin => PluginFactory.IsEnterpriseTestConfigurationPath(plugin.LocalPath)).ToList();
this.configPlugins = availableConfigPlugins.Except(this.testConfigPlugins).ToList();
this.enterpriseEnvironments = EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.ToList(); this.enterpriseEnvironments = EnterpriseEnvironmentService.CURRENT_ENVIRONMENTS.ToList();
this.mandatoryInfoPanels = PluginFactory.GetMandatoryInfos() this.mandatoryInfoPanels = PluginFactory.GetMandatoryInfos()
.Select(info => .Select(info =>
@ -404,6 +413,27 @@ public partial class Information : MSGComponentBase
return plugin.ManagedConfigurationId == configurationId && plugin.Id != configurationId; return plugin.ManagedConfigurationId == configurationId && plugin.Id != configurationId;
} }
/// <summary>
/// Collects what a user needs to find and judge a staged test configuration.
/// </summary>
/// <remarks>
/// There is no enterprise environment behind it, so we show what identifies it instead: the plugin
/// ID it claims and the directory it was staged in.
/// </remarks>
private IReadOnlyList<ConfigInfoRowItem> BuildTestConfigurationItems(IAvailablePlugin plugin) =>
[
new(Icons.Material.Filled.ArrowRightAlt,
$"{T("Configuration plugin ID:")} {plugin.Id}",
plugin.Id.ToString(),
T("Copies the configuration plugin ID to the clipboard")),
new(Icons.Material.Filled.ArrowRightAlt,
$"{T("Plugin directory:")} {plugin.LocalPath}",
plugin.LocalPath,
T("Copies the plugin directory to the clipboard"),
"margin-top: 4px;"),
];
private string ExternalHttpCustomRootCertificateWarningText private string ExternalHttpCustomRootCertificateWarningText
{ {
get get

View File

@ -439,6 +439,8 @@ Place the files **while AI Studio is running**: the test directory is emptied wh
3. Place the assistant plugin you want to test in `<data directory>/plugins/assistants/<any name>/`. 3. Place the assistant plugin you want to test in `<data directory>/plugins/assistants/<any name>/`.
4. AI Studio watches the plugin directory and picks both up without a restart. The security card of the assistant then states that your organization approved it, exactly as it will after the rollout. 4. AI Studio watches the plugin directory and picks both up without a restart. The security card of the assistant then states that your organization approved it, exactly as it will after the rollout.
While a test configuration is loaded, the Information page reports it, including the directory it was staged in. After a restart, that same page tells you that a test configuration was removed, so nobody has to wonder where the directory went.
What behaves like the later rollout: What behaves like the later rollout:
- The approvals for assistant plugins are honored. - The approvals for assistant plugins are honored.