mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-24 20:52:11 +00:00
wireing revision dialog and logic to a footer button in dynamic assistants
This commit is contained in:
parent
29263c1bf8
commit
e30bb3d00f
@ -42,6 +42,12 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private protected override RenderFragment? HeaderActions => this.CanReviseCurrentAssistant
|
||||||
|
? @<MudTooltip Text="@T("Revise assistant")">
|
||||||
|
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.AutoMode" OnClick="@(async () => await this.OpenRevisionDialogAsync())"/>
|
||||||
|
</MudTooltip>
|
||||||
|
: null;
|
||||||
|
|
||||||
private RenderFragment RenderSwitch(AssistantSwitch assistantSwitch) => @<MudSwitch T="bool"
|
private RenderFragment RenderSwitch(AssistantSwitch assistantSwitch) => @<MudSwitch T="bool"
|
||||||
Value="@this.assistantState.Booleans[assistantSwitch.Name]"
|
Value="@this.assistantState.Booleans[assistantSwitch.Name]"
|
||||||
ValueChanged="@(value => this.ExecuteSwitchChangedAsync(assistantSwitch, value))"
|
ValueChanged="@(value => this.ExecuteSwitchChangedAsync(assistantSwitch, value))"
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
|
using AIStudio.Agents.AssistantAudit;
|
||||||
|
using AIStudio.Chat;
|
||||||
|
using AIStudio.Dialogs;
|
||||||
using AIStudio.Dialogs.Settings;
|
using AIStudio.Dialogs.Settings;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Tools.AssistantSessions;
|
using AIStudio.Tools.AssistantSessions;
|
||||||
@ -8,11 +11,15 @@ using AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
|||||||
using Lua;
|
using Lua;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.WebUtilities;
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
||||||
|
|
||||||
namespace AIStudio.Assistants.Dynamic;
|
namespace AIStudio.Assistants.Dynamic;
|
||||||
|
|
||||||
public partial class AssistantDynamic : AssistantBaseCore<NoSettingsPanel>
|
public partial class AssistantDynamic : AssistantBaseCore<NoSettingsPanel>
|
||||||
{
|
{
|
||||||
|
[Inject]
|
||||||
|
private IDialogService DialogService { get; init; } = null!;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public AssistantForm? RootComponent { get; set; }
|
public AssistantForm? RootComponent { get; set; }
|
||||||
|
|
||||||
@ -33,6 +40,18 @@ public partial class AssistantDynamic : AssistantBaseCore<NoSettingsPanel>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected override string AssistantSessionInstanceId => this.assistantPlugin is null ? base.AssistantSessionInstanceId : this.assistantPlugin.Id.ToString();
|
protected override string AssistantSessionInstanceId => this.assistantPlugin is null ? base.AssistantSessionInstanceId : this.assistantPlugin.Id.ToString();
|
||||||
|
|
||||||
|
protected override IReadOnlyList<IButtonData> FooterButtons =>
|
||||||
|
[
|
||||||
|
new ButtonData
|
||||||
|
{
|
||||||
|
Text = T("Revise"),
|
||||||
|
Icon = Icons.Material.Filled.AutoMode,
|
||||||
|
Color = Color.Default,
|
||||||
|
AsyncAction = this.OpenRevisionDialogAsync,
|
||||||
|
DisabledActionParam = () => !this.CanReviseCurrentAssistant,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
private string title = string.Empty;
|
private string title = string.Empty;
|
||||||
private string description = string.Empty;
|
private string description = string.Empty;
|
||||||
private string systemPrompt = string.Empty;
|
private string systemPrompt = string.Empty;
|
||||||
@ -67,6 +86,9 @@ public partial class AssistantDynamic : AssistantBaseCore<NoSettingsPanel>
|
|||||||
private static readonly AssistantSessionStateKey<string> SECURITY_MESSAGE_STATE_KEY = new(nameof(securityMessage));
|
private static readonly AssistantSessionStateKey<string> SECURITY_MESSAGE_STATE_KEY = new(nameof(securityMessage));
|
||||||
private static readonly AssistantSessionStateKey<bool> IS_SECURITY_BLOCKED_STATE_KEY = new(nameof(isSecurityBlocked));
|
private static readonly AssistantSessionStateKey<bool> IS_SECURITY_BLOCKED_STATE_KEY = new(nameof(isSecurityBlocked));
|
||||||
|
|
||||||
|
private bool CanReviseCurrentAssistant => this.assistantPlugin is { IsInternal: false, IsAssistantBuilderGenerated: true } &&
|
||||||
|
!string.IsNullOrWhiteSpace(this.assistantPlugin.PluginPath);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void CaptureCustomAssistantSessionState(AssistantSessionStateWriter state)
|
protected override void CaptureCustomAssistantSessionState(AssistantSessionStateWriter state)
|
||||||
{
|
{
|
||||||
@ -210,6 +232,93 @@ public partial class AssistantDynamic : AssistantBaseCore<NoSettingsPanel>
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task OpenRevisionDialogAsync()
|
||||||
|
{
|
||||||
|
if (this.assistantPlugin is null || !this.CanReviseCurrentAssistant)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var testContext = await this.BuildRevisionTestContextAsync();
|
||||||
|
var parameters = new DialogParameters<AssistantPluginRevisionDialog>
|
||||||
|
{
|
||||||
|
{ x => x.PluginId, this.assistantPlugin.Id },
|
||||||
|
{ x => x.PluginLocalPath, this.assistantPlugin.PluginPath },
|
||||||
|
{ x => x.TestContext, testContext },
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialog = await this.DialogService.ShowAsync<AssistantPluginRevisionDialog>(this.T("Revise Assistant"), parameters, DialogOptions.BLOCKING_FULLSCREEN);
|
||||||
|
var result = await dialog.Result;
|
||||||
|
if (result is null || result.Canceled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (result.Data is not AssistantPluginRevisionDialogResult revisionResult)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.Logger.LogInformation($"AssistantDynamic of plugin '{revisionResult.PluginName}' ({revisionResult.PluginName}) was successfully revised with audit result {revisionResult.Audit?.Level ?? AssistantAuditLevel.UNKNOWN}.");
|
||||||
|
var updatedPlugin = PluginFactory.RunningPlugins.OfType<PluginAssistants>().FirstOrDefault(x => x.Id == revisionResult.PluginId);
|
||||||
|
if (updatedPlugin is not null)
|
||||||
|
this.ApplyUpdatedAssistantPlugin(updatedPlugin);
|
||||||
|
|
||||||
|
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.AutoFixHigh, string.Format(this.T("The assistant '{0}' has been updated."), revisionResult.PluginName)));
|
||||||
|
await this.MessageBus.SendMessage<bool>(this, Event.PLUGINS_RELOADED);
|
||||||
|
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||||
|
await this.InvokeAsync(this.StateHasChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> BuildRevisionTestContextAsync()
|
||||||
|
{
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
|
if (this.assistantPlugin is not null)
|
||||||
|
{
|
||||||
|
var componentSummary = this.assistantPlugin.CreateAuditComponentSummary();
|
||||||
|
if (!string.IsNullOrWhiteSpace(componentSummary))
|
||||||
|
{
|
||||||
|
builder.AppendLine("Current component overview:");
|
||||||
|
builder.AppendLine(componentSummary);
|
||||||
|
builder.AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var promptPreview = await this.CollectUserPromptAsync();
|
||||||
|
if (!string.IsNullOrWhiteSpace(promptPreview))
|
||||||
|
{
|
||||||
|
builder.AppendLine("Current prompt preview from the assistant form:");
|
||||||
|
builder.AppendLine(promptPreview);
|
||||||
|
builder.AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.ResultingContentBlock?.Content is ContentText text && !string.IsNullOrWhiteSpace(text.Text))
|
||||||
|
{
|
||||||
|
builder.AppendLine("Last assistant response visible in this session:");
|
||||||
|
builder.AppendLine(text.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString().Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyUpdatedAssistantPlugin(PluginAssistants updatedPlugin)
|
||||||
|
{
|
||||||
|
this.assistantPlugin = updatedPlugin;
|
||||||
|
this.RootComponent = updatedPlugin.RootComponent;
|
||||||
|
this.title = updatedPlugin.AssistantTitle;
|
||||||
|
this.description = updatedPlugin.AssistantDescription;
|
||||||
|
this.systemPrompt = updatedPlugin.SystemPrompt;
|
||||||
|
this.submitText = updatedPlugin.SubmitText;
|
||||||
|
this.allowProfiles = updatedPlugin.AllowProfiles;
|
||||||
|
this.showFooterProfileSelection = !updatedPlugin.HasEmbeddedProfileSelection;
|
||||||
|
this.pluginPath = updatedPlugin.PluginPath;
|
||||||
|
var pluginHash = updatedPlugin.ComputeAuditHash();
|
||||||
|
this.audit = this.SettingsManager.ConfigurationData.AssistantPluginAudits.FirstOrDefault(x => x.PluginId == updatedPlugin.Id && x.PluginHash == pluginHash);
|
||||||
|
|
||||||
|
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, updatedPlugin);
|
||||||
|
this.securityMessage = securityState.CanStartAssistant ? string.Empty : securityState.Description;
|
||||||
|
this.isSecurityBlocked = !securityState.CanStartAssistant;
|
||||||
|
|
||||||
|
this.assistantState.Clear();
|
||||||
|
if (this.RootComponent is not null)
|
||||||
|
this.InitializeComponentState(this.RootComponent.Children);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private string ResolveImageSource(AssistantImage image)
|
private string ResolveImageSource(AssistantImage image)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user