respect dynamic assistant plugins instead of hardcoding GUID

This commit is contained in:
krut_ni 2026-02-24 13:20:46 +01:00
parent b4702b17d4
commit 12881e33b0
No known key found for this signature in database
GPG Key ID: A5C0151B4DDB172C
2 changed files with 109 additions and 58 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using AIStudio.Dialogs.Settings; using AIStudio.Dialogs.Settings;
using AIStudio.Tools.PluginSystem; using AIStudio.Tools.PluginSystem;
@ -7,6 +8,7 @@ using AIStudio.Settings;
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 Microsoft.AspNetCore.WebUtilities;
namespace AIStudio.Assistants.Dynamic; namespace AIStudio.Assistants.Dynamic;
@ -41,67 +43,110 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
private Dictionary<string, FileContentState> fileContentFields = new(); private Dictionary<string, FileContentState> fileContentFields = new();
private readonly Dictionary<string, string> imageCache = new(); private readonly Dictionary<string, string> imageCache = new();
private string pluginPath = string.Empty; private string pluginPath = string.Empty;
const string PLUGIN_SCHEME = "plugin://"; private const string PLUGIN_SCHEME = "plugin://";
private const string ASSISTANT_QUERY_KEY = "assistantId";
protected override void OnInitialized() protected override void OnInitialized()
{ {
var guid = Guid.Parse("958312de-a9e7-4666-901f-4d5b61647efb"); var assistantPlugin = this.ResolveAssistantPlugin();
var plugin = PluginFactory.RunningPlugins.FirstOrDefault(e => e.Id == guid); if (assistantPlugin is null)
if (plugin is PluginAssistants assistantPlugin)
{ {
this.RootComponent = assistantPlugin.RootComponent; this.Logger.LogWarning("AssistantDynamic could not resolve a registered assistant plugin.");
this.title = assistantPlugin.AssistantTitle; base.OnInitialized();
this.description = assistantPlugin.AssistantDescription; return;
this.systemPrompt = assistantPlugin.SystemPrompt;
this.submitText = assistantPlugin.SubmitText;
this.allowProfiles = assistantPlugin.AllowProfiles;
this.showFooterProfileSelection = !assistantPlugin.HasEmbeddedProfileSelection;
this.pluginPath = assistantPlugin.PluginPath;
} }
foreach (var component in this.RootComponent!.Children) this.RootComponent = assistantPlugin.RootComponent;
this.title = assistantPlugin.AssistantTitle;
this.description = assistantPlugin.AssistantDescription;
this.systemPrompt = assistantPlugin.SystemPrompt;
this.submitText = assistantPlugin.SubmitText;
this.allowProfiles = assistantPlugin.AllowProfiles;
this.showFooterProfileSelection = !assistantPlugin.HasEmbeddedProfileSelection;
this.pluginPath = assistantPlugin.PluginPath;
var rootComponent = this.RootComponent;
if (rootComponent is not null)
{ {
switch (component.Type) foreach (var component in rootComponent.Children)
{ {
case AssistantComponentType.TEXT_AREA: switch (component.Type)
if (component is AssistantTextArea textArea) {
{ case AssistantComponentType.TEXT_AREA:
this.inputFields.Add(textArea.Name, textArea.PrefillText); if (component is AssistantTextArea textArea)
}
break;
case AssistantComponentType.DROPDOWN:
if (component is AssistantDropdown dropdown)
{
this.dropdownFields.Add(dropdown.Name, dropdown.Default.Value);
}
break;
case AssistantComponentType.SWITCH:
if (component is AssistantSwitch switchComponent)
{
this.switchFields.Add(switchComponent.Name, switchComponent.Value);
}
break;
case AssistantComponentType.WEB_CONTENT_READER:
if (component is AssistantWebContentReader webContent)
{
this.webContentFields.Add(webContent.Name, new WebContentState
{ {
Preselect = webContent.Preselect, this.inputFields.Add(textArea.Name, textArea.PrefillText);
PreselectContentCleanerAgent = webContent.PreselectContentCleanerAgent, }
}); break;
} case AssistantComponentType.DROPDOWN:
break; if (component is AssistantDropdown dropdown)
case AssistantComponentType.FILE_CONTENT_READER: {
if (component is AssistantFileContentReader fileContent) this.dropdownFields.Add(dropdown.Name, dropdown.Default.Value);
{ }
this.fileContentFields.Add(fileContent.Name, new FileContentState()); break;
} case AssistantComponentType.SWITCH:
break; if (component is AssistantSwitch switchComponent)
{
this.switchFields.Add(switchComponent.Name, switchComponent.Value);
}
break;
case AssistantComponentType.WEB_CONTENT_READER:
if (component is AssistantWebContentReader webContent)
{
this.webContentFields.Add(webContent.Name, new WebContentState
{
Preselect = webContent.Preselect,
PreselectContentCleanerAgent = webContent.PreselectContentCleanerAgent,
});
}
break;
case AssistantComponentType.FILE_CONTENT_READER:
if (component is AssistantFileContentReader fileContent)
{
this.fileContentFields.Add(fileContent.Name, new FileContentState());
}
break;
}
} }
} }
base.OnInitialized(); base.OnInitialized();
} }
private PluginAssistants? ResolveAssistantPlugin()
{
var assistantPlugins = PluginFactory.RunningPlugins.OfType<PluginAssistants>().ToList();
if (assistantPlugins.Count == 0)
return null;
var requestedPluginId = this.TryGetAssistantIdFromQuery();
if (requestedPluginId is not { } id) return assistantPlugins.First();
var requestedPlugin = assistantPlugins.FirstOrDefault(p => p.Id == id);
return requestedPlugin ?? assistantPlugins.First();
}
private Guid? TryGetAssistantIdFromQuery()
{
var uri = this.NavigationManager.ToAbsoluteUri(this.NavigationManager.Uri);
if (string.IsNullOrWhiteSpace(uri.Query))
return null;
var query = QueryHelpers.ParseQuery(uri.Query);
if (!query.TryGetValue(ASSISTANT_QUERY_KEY, out var values))
return null;
var value = values.FirstOrDefault();
if (string.IsNullOrWhiteSpace(value))
return null;
if (Guid.TryParse(value, out var assistantId))
return assistantId;
this.Logger.LogWarning("AssistantDynamic query parameter '{Parameter}' is not a valid GUID.", value);
return null;
}
protected override void ResetForm() protected override void ResetForm()
{ {
foreach (var entry in this.inputFields) foreach (var entry in this.inputFields)
@ -119,6 +164,7 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
} }
} }
// TODO
protected override bool MightPreselectValues() protected override bool MightPreselectValues()
{ {
Console.WriteLine("throw new NotImplementedException();"); Console.WriteLine("throw new NotImplementedException();");
@ -180,13 +226,14 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
}; };
} }
private string? ValidateCustomLanguage(string value) => string.Empty;
private string CollectUserPrompt() private string CollectUserPrompt()
{ {
var prompt = string.Empty; var prompt = string.Empty;
var rootComponent = this.RootComponent;
if (rootComponent is null)
return prompt;
foreach (var component in this.RootComponent!.Children) foreach (var component in rootComponent.Children)
{ {
var userInput = string.Empty; var userInput = string.Empty;
var userDecision = false; var userDecision = false;

View File

@ -35,13 +35,17 @@
<AssistantBlock TSettings="SettingsDialogLegalCheck" Name="@T("Legal Check")" Description="@T("Ask a question about a legal document.")" Icon="@Icons.Material.Filled.Gavel" Link="@Routes.ASSISTANT_LEGAL_CHECK"/> <AssistantBlock TSettings="SettingsDialogLegalCheck" Name="@T("Legal Check")" Description="@T("Ask a question about a legal document.")" Icon="@Icons.Material.Filled.Gavel" Link="@Routes.ASSISTANT_LEGAL_CHECK"/>
<AssistantBlock TSettings="SettingsDialogIconFinder" Name="@T("Icon Finder")" Description="@T("Use an LLM to find an icon for a given context.")" Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_ICON_FINDER"/> <AssistantBlock TSettings="SettingsDialogIconFinder" Name="@T("Icon Finder")" Description="@T("Use an LLM to find an icon for a given context.")" Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_ICON_FINDER"/>
@foreach (var assistant in PluginFactory.RunningPlugins.Where(e => e.Type == PluginType.ASSISTANT)) @foreach (var assistant in PluginFactory.RunningPlugins.Where(e => e.Type == PluginType.ASSISTANT))
{ {
if (assistant is PluginAssistants assistantPlugin) if (assistant is PluginAssistants assistantPlugin)
{ {
<AssistantBlock TSettings="SettingsDialogTranslation" Name="@T(assistantPlugin.AssistantTitle)" Description="@T(assistantPlugin.Description)" Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_DYNAMIC"/> <AssistantBlock TSettings="SettingsDialogTranslation"
} Name="@T(assistantPlugin.AssistantTitle)"
} Description="@T(assistantPlugin.Description)"
Icon="@Icons.Material.Filled.FindInPage"
Link="@($"{Routes.ASSISTANT_DYNAMIC}?assistantId={assistantPlugin.Id}")"/>
}
}
</MudStack> </MudStack>
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6"> <MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
@ -70,4 +74,4 @@
</MudStack> </MudStack>
</InnerScrolling> </InnerScrolling>
</div> </div>