mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-05-21 18:32:15 +00:00
small ui fixes
This commit is contained in:
parent
3f2d76337a
commit
92267b129f
@ -9,7 +9,7 @@ public static class AssistantAuditLevelExtensions
|
|||||||
public static string GetName(this AssistantAuditLevel level) => level switch
|
public static string GetName(this AssistantAuditLevel level) => level switch
|
||||||
{
|
{
|
||||||
AssistantAuditLevel.DANGEROUS => TB("Dangerous"),
|
AssistantAuditLevel.DANGEROUS => TB("Dangerous"),
|
||||||
AssistantAuditLevel.CAUTION => TB("Needs Review"),
|
AssistantAuditLevel.CAUTION => TB("Concerning"),
|
||||||
AssistantAuditLevel.SAFE => TB("Safe"),
|
AssistantAuditLevel.SAFE => TB("Safe"),
|
||||||
_ => TB("Unknown"),
|
_ => TB("Unknown"),
|
||||||
};
|
};
|
||||||
@ -22,5 +22,26 @@ public static class AssistantAuditLevelExtensions
|
|||||||
_ => Severity.Info,
|
_ => Severity.Info,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static Color GetColor(this AssistantAuditLevel level) => level switch
|
||||||
|
{
|
||||||
|
AssistantAuditLevel.DANGEROUS => Color.Error,
|
||||||
|
AssistantAuditLevel.CAUTION => Color.Warning,
|
||||||
|
AssistantAuditLevel.SAFE => Color.Success,
|
||||||
|
_ => Color.Default,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string GetIcon(this AssistantAuditLevel level) => level switch
|
||||||
|
{
|
||||||
|
AssistantAuditLevel.DANGEROUS => Icons.Material.Filled.Dangerous,
|
||||||
|
AssistantAuditLevel.CAUTION => Icons.Material.Filled.Warning,
|
||||||
|
AssistantAuditLevel.SAFE => Icons.Material.Filled.Verified,
|
||||||
|
_ => Icons.Material.Filled.HelpOutline,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parses an audit level string and falls back to <see cref="AssistantAuditLevel.UNKNOWN"/> when parsing fails.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The audit level text to parse.</param>
|
||||||
|
/// <returns>The parsed audit level, or <see cref="AssistantAuditLevel.UNKNOWN"/> for null, empty, or invalid values.</returns>
|
||||||
public static AssistantAuditLevel Parse(string? value) => Enum.TryParse<AssistantAuditLevel>(value, true, out var level) ? level : AssistantAuditLevel.UNKNOWN;
|
public static AssistantAuditLevel Parse(string? value) => Enum.TryParse<AssistantAuditLevel>(value, true, out var level) ? level : AssistantAuditLevel.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,21 @@
|
|||||||
@using AIStudio.Tools.PluginSystem.Assistants.DataModel.Layout
|
@using AIStudio.Tools.PluginSystem.Assistants.DataModel.Layout
|
||||||
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogDynamic>
|
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogDynamic>
|
||||||
|
|
||||||
@if (this.RootComponent is null)
|
@if (!string.IsNullOrWhiteSpace(this.securityMessage))
|
||||||
|
{
|
||||||
|
<MudPaper Class="pa-4 ma-4" Elevation="0">
|
||||||
|
<MudAlert Severity="Severity.Error" Variant="Variant.Filled" Square="false" Elevation="6" Class="pa-4">
|
||||||
|
@this.securityMessage
|
||||||
|
</MudAlert>
|
||||||
|
@if (this.assistantPlugin is not null)
|
||||||
|
{
|
||||||
|
<div class="mt-4">
|
||||||
|
<AssistantPluginSecurityCard Plugin="@this.assistantPlugin"/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</MudPaper>
|
||||||
|
}
|
||||||
|
else if (this.RootComponent is null)
|
||||||
{
|
{
|
||||||
<MudAlert Severity="Severity.Warning">
|
<MudAlert Severity="Severity.Warning">
|
||||||
@this.T("No assistant plugin are currently installed.")
|
@this.T("No assistant plugin are currently installed.")
|
||||||
|
|||||||
@ -22,6 +22,7 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
protected override bool ShowProfileSelection => this.showFooterProfileSelection;
|
protected override bool ShowProfileSelection => this.showFooterProfileSelection;
|
||||||
protected override string SubmitText => this.submitText;
|
protected override string SubmitText => this.submitText;
|
||||||
protected override Func<Task> SubmitAction => this.Submit;
|
protected override Func<Task> SubmitAction => this.Submit;
|
||||||
|
protected override bool SubmitDisabled => this.isSecurityBlocked;
|
||||||
// Dynamic assistants do not have dedicated settings yet.
|
// Dynamic assistants do not have dedicated settings yet.
|
||||||
// Reuse chat-level provider filtering/preselection instead of NONE.
|
// Reuse chat-level provider filtering/preselection instead of NONE.
|
||||||
protected override Tools.Components Component => Tools.Components.CHAT;
|
protected override Tools.Components Component => Tools.Components.CHAT;
|
||||||
@ -40,6 +41,8 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
private readonly HashSet<string> executingSwitchActions = [];
|
private readonly HashSet<string> executingSwitchActions = [];
|
||||||
private string pluginPath = string.Empty;
|
private string pluginPath = string.Empty;
|
||||||
private PluginAssistantAudit? audit;
|
private PluginAssistantAudit? audit;
|
||||||
|
private string securityMessage = string.Empty;
|
||||||
|
private bool isSecurityBlocked;
|
||||||
private const string ASSISTANT_QUERY_KEY = "assistantId";
|
private const string ASSISTANT_QUERY_KEY = "assistantId";
|
||||||
|
|
||||||
#region Implementation of AssistantBase
|
#region Implementation of AssistantBase
|
||||||
@ -66,6 +69,16 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
var pluginHash = pluginAssistant.ComputeAuditHash();
|
var pluginHash = pluginAssistant.ComputeAuditHash();
|
||||||
this.audit = this.SettingsManager.ConfigurationData.AssistantPluginAudits.FirstOrDefault(x => x.PluginId == pluginAssistant.Id && x.PluginHash == pluginHash);
|
this.audit = this.SettingsManager.ConfigurationData.AssistantPluginAudits.FirstOrDefault(x => x.PluginId == pluginAssistant.Id && x.PluginHash == pluginHash);
|
||||||
|
|
||||||
|
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, pluginAssistant);
|
||||||
|
if (!securityState.CanStartAssistant)
|
||||||
|
{
|
||||||
|
this.assistantPlugin = pluginAssistant;
|
||||||
|
this.securityMessage = securityState.Description;
|
||||||
|
this.isSecurityBlocked = true;
|
||||||
|
base.OnInitialized();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var rootComponent = this.RootComponent;
|
var rootComponent = this.RootComponent;
|
||||||
if (rootComponent is not null)
|
if (rootComponent is not null)
|
||||||
{
|
{
|
||||||
@ -387,6 +400,13 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
|
|
||||||
private async Task Submit()
|
private async Task Submit()
|
||||||
{
|
{
|
||||||
|
if (this.assistantPlugin is not null)
|
||||||
|
{
|
||||||
|
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, this.assistantPlugin);
|
||||||
|
if (!securityState.CanStartAssistant)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.CreateChatThread();
|
this.CreateChatThread();
|
||||||
var time = this.AddUserRequest(await this.CollectUserPromptAsync());
|
var time = this.AddUserRequest(await this.CollectUserPromptAsync());
|
||||||
await this.AddAIResponseAsync(time);
|
await this.AddAIResponseAsync(time);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
@using AIStudio.Agents.AssistantAudit
|
@using AIStudio.Agents.AssistantAudit
|
||||||
@using AIStudio.Components
|
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog DefaultFocus="DefaultFocus.FirstChild">
|
<MudDialog DefaultFocus="DefaultFocus.FirstChild">
|
||||||
@ -299,7 +298,7 @@
|
|||||||
<MudButton OnClick="@this.CloseWithoutActivation" Variant="Variant.Filled">
|
<MudButton OnClick="@this.CloseWithoutActivation" Variant="Variant.Filled">
|
||||||
@(this.audit is null ? T("Cancel") : T("Close"))
|
@(this.audit is null ? T("Cancel") : T("Close"))
|
||||||
</MudButton>
|
</MudButton>
|
||||||
<MudButton OnClick="@this.RunAudit" Variant="Variant.Filled" Color="Color.Primary" Disabled="@(!this.CanRunAudit)">
|
<MudButton OnClick="@this.RunAudit" Variant="Variant.Filled" Color="Color.Primary" Disabled="@(!this.CanRunAudit || this.justAudited)">
|
||||||
@T("Start Security Check")
|
@T("Start Security Check")
|
||||||
</MudButton>
|
</MudButton>
|
||||||
@if (this.CanEnablePlugin)
|
@if (this.CanEnablePlugin)
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
using AIStudio.Agents.AssistantAudit;
|
using AIStudio.Agents.AssistantAudit;
|
||||||
using AIStudio.Components;
|
using AIStudio.Components;
|
||||||
using AIStudio.Provider;
|
using AIStudio.Provider;
|
||||||
@ -6,17 +10,12 @@ using AIStudio.Tools.PluginSystem;
|
|||||||
using AIStudio.Tools.PluginSystem.Assistants;
|
using AIStudio.Tools.PluginSystem.Assistants;
|
||||||
using AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
using AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class AssistantPluginAuditDialog : MSGComponentBase
|
public partial class AssistantPluginAuditDialog : MSGComponentBase
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(AssistantPluginAuditDialog).Namespace,
|
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(AssistantPluginAuditDialog).Namespace, nameof(AssistantPluginAuditDialog));
|
||||||
nameof(AssistantPluginAuditDialog));
|
|
||||||
|
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@ -37,7 +36,7 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
|
|||||||
private ImmutableDictionary<string, string> luaFiles = ImmutableDictionary.Create<string, string>();
|
private ImmutableDictionary<string, string> luaFiles = ImmutableDictionary.Create<string, string>();
|
||||||
private IReadOnlyCollection<TreeItemData<ITreeItem>> componentTreeItems = [];
|
private IReadOnlyCollection<TreeItemData<ITreeItem>> componentTreeItems = [];
|
||||||
private IReadOnlyCollection<TreeItemData<ITreeItem>> fileSystemTreeItems = [];
|
private IReadOnlyCollection<TreeItemData<ITreeItem>> fileSystemTreeItems = [];
|
||||||
private CultureInfo fileInfoCulture = CultureInfo.InvariantCulture;
|
private CultureInfo currentCultureInfo = CultureInfo.InvariantCulture;
|
||||||
private bool isAuditing;
|
private bool isAuditing;
|
||||||
|
|
||||||
private AIStudio.Settings.Provider CurrentProvider => this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_ASSISTANT_PLUGIN_AUDIT, null, true);
|
private AIStudio.Settings.Provider CurrentProvider => this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_ASSISTANT_PLUGIN_AUDIT, null, true);
|
||||||
@ -63,13 +62,14 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
|
|||||||
private bool CanEnablePlugin => this.audit is not null && !this.isAuditing && !this.IsActivationBlockedBySettings;
|
private bool CanEnablePlugin => this.audit is not null && !this.isAuditing && !this.IsActivationBlockedBySettings;
|
||||||
|
|
||||||
private Color EnableButtonColor => this.RequiresActivationConfirmation ? Color.Warning : Color.Success;
|
private Color EnableButtonColor => this.RequiresActivationConfirmation ? Color.Warning : Color.Success;
|
||||||
|
private bool justAudited;
|
||||||
|
|
||||||
private const ushort BYTES_PER_KILOBYTE = 1024;
|
private const ushort BYTES_PER_KILOBYTE = 1024;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
var activeLanguagePlugin = await this.SettingsManager.GetActiveLanguagePlugin();
|
var activeLanguagePlugin = await this.SettingsManager.GetActiveLanguagePlugin();
|
||||||
this.fileInfoCulture = this.CreateFileInfoCulture(activeLanguagePlugin.IETFTag);
|
this.currentCultureInfo = CommonTools.DeriveActiveCultureOrInvariant(activeLanguagePlugin.IETFTag);
|
||||||
|
|
||||||
this.plugin = PluginFactory.RunningPlugins.OfType<PluginAssistants>()
|
this.plugin = PluginFactory.RunningPlugins.OfType<PluginAssistants>()
|
||||||
.FirstOrDefault(x => x.Id == this.PluginId);
|
.FirstOrDefault(x => x.Id == this.PluginId);
|
||||||
@ -116,6 +116,7 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
this.isAuditing = false;
|
this.isAuditing = false;
|
||||||
|
this.justAudited = true;
|
||||||
await this.InvokeAsync(this.StateHasChanged);
|
await this.InvokeAsync(this.StateHasChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -453,7 +454,7 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
|
|||||||
string stringValue when string.IsNullOrWhiteSpace(stringValue) => TB("empty"),
|
string stringValue when string.IsNullOrWhiteSpace(stringValue) => TB("empty"),
|
||||||
string stringValue => stringValue,
|
string stringValue => stringValue,
|
||||||
bool boolValue => boolValue ? "true" : "false",
|
bool boolValue => boolValue ? "true" : "false",
|
||||||
_ => Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture) ?? string.Empty,
|
_ => Convert.ToString(value, CultureInfo.InvariantCulture) ?? string.Empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
private string GetStructuredValueCaption(object? value) => value switch
|
private string GetStructuredValueCaption(object? value) => value switch
|
||||||
@ -477,37 +478,23 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
|
|||||||
_ => Icons.Material.Filled.DataArray,
|
_ => Icons.Material.Filled.DataArray,
|
||||||
};
|
};
|
||||||
|
|
||||||
private string FormatFileTimestamp(DateTime timestamp) => timestamp.ToString("g", this.fileInfoCulture);
|
private string FormatFileTimestamp(DateTime timestamp) => CommonTools.FormatTimestampToGeneral(timestamp, this.currentCultureInfo);
|
||||||
|
|
||||||
private string FormatFileSize(long bytes)
|
private string FormatFileSize(long bytes)
|
||||||
{
|
{
|
||||||
if (bytes < BYTES_PER_KILOBYTE)
|
if (bytes < BYTES_PER_KILOBYTE)
|
||||||
return string.Format(this.fileInfoCulture, TB("{0} B"), bytes);
|
return string.Format(this.currentCultureInfo, TB("{0} B"), bytes);
|
||||||
|
|
||||||
var kilobyte = bytes / (double)BYTES_PER_KILOBYTE;
|
var kilobyte = bytes / (double)BYTES_PER_KILOBYTE;
|
||||||
if (kilobyte < BYTES_PER_KILOBYTE)
|
if (kilobyte < BYTES_PER_KILOBYTE)
|
||||||
return string.Format(this.fileInfoCulture, TB("{0:0.##} KB"), kilobyte);
|
return string.Format(this.currentCultureInfo, TB("{0:0.##} KB"), kilobyte);
|
||||||
|
|
||||||
var megabyte = kilobyte / BYTES_PER_KILOBYTE;
|
var megabyte = kilobyte / BYTES_PER_KILOBYTE;
|
||||||
if (megabyte < BYTES_PER_KILOBYTE)
|
if (megabyte < BYTES_PER_KILOBYTE)
|
||||||
return string.Format(this.fileInfoCulture, TB("{0:0.##} MB"), megabyte);
|
return string.Format(this.currentCultureInfo, TB("{0:0.##} MB"), megabyte);
|
||||||
|
|
||||||
var gigabyte = megabyte / BYTES_PER_KILOBYTE;
|
var gigabyte = megabyte / BYTES_PER_KILOBYTE;
|
||||||
return string.Format(this.fileInfoCulture, TB("{0:0.##} GB"), gigabyte);
|
return string.Format(this.currentCultureInfo, TB("{0:0.##} GB"), gigabyte);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CultureInfo CreateFileInfoCulture(string ietfTag)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(ietfTag))
|
|
||||||
return CultureInfo.InvariantCulture;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return CultureInfo.GetCultureInfo(ietfTag);
|
|
||||||
}
|
|
||||||
catch (CultureNotFoundException)
|
|
||||||
{
|
|
||||||
return CultureInfo.InvariantCulture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user