From 415ed35422f7cca9486bcca48bcca99bebccdb5f Mon Sep 17 00:00:00 2001 From: nilskruthoff <69095224+nilskruthoff@users.noreply.github.com> Date: Tue, 25 Aug 2026 14:53:38 +0200 Subject: [PATCH] Added a component for dynamic assistants (#911) --- .../Dynamic/AssistantDynamic.razor.cs | 6 ++--- app/MindWork AI Studio/Pages/Assistants.razor | 1 + .../Tools/AssistantVisibilityExtensions.cs | 6 +++++ app/MindWork AI Studio/Tools/Components.cs | 4 ++++ .../Tools/ComponentsExtensions.cs | 23 +++++++++++-------- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor.cs b/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor.cs index 19cd7183..1f4255c3 100644 --- a/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor.cs +++ b/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor.cs @@ -31,9 +31,9 @@ public partial class AssistantDynamic : AssistantBaseCore protected override string SubmitText => this.submitText; protected override Func SubmitAction => this.Submit; protected override bool SubmitDisabled => this.isSecurityBlocked; - // Dynamic assistants do not have dedicated settings yet. - // Reuse chat-level provider filtering/preselection instead of NONE. - protected override Tools.Components Component => Tools.Components.CHAT; + // Dynamic assistants do not have dedicated settings yet. Their internal identity keeps their + // session and media state separate while ComponentsExtensions derives their defaults from chat. + protected override Tools.Components Component => Tools.Components.DYNAMIC_ASSISTANT; /// /// Gets the plugin ID as the assistant session instance ID. diff --git a/app/MindWork AI Studio/Pages/Assistants.razor b/app/MindWork AI Studio/Pages/Assistants.razor index 8f4bd907..cfe5ba5d 100644 --- a/app/MindWork AI Studio/Pages/Assistants.razor +++ b/app/MindWork AI Studio/Pages/Assistants.razor @@ -31,6 +31,7 @@ var launchLink = assistantPlugin.StartsChatDirectly ? string.Empty : $"{Routes.ASSISTANT_DYNAMIC}?assistantId={assistantPlugin.Id}"; var availablePlugin = PluginFactory.AvailablePlugins.OfType().FirstOrDefault(plugin => plugin.Id == assistantPlugin.Id); /// - /// Components return false for two different reasons. The chat has no assistant sessions - /// at all. The visual briefing assistant keys its sessions per briefing, so it owns one slot per - /// stored briefing rather than one per component. Both must be excluded from the single-slot - /// checks, which is why this is a capability and not a component comparison. + /// Components return false for three different reasons. The chat has no assistant sessions + /// at all. Dynamic assistants key their sessions per plugin. The visual briefing assistant keys + /// its sessions per briefing, so it owns one slot per stored briefing rather than one per + /// component. All must be excluded from the single-slot checks, which is why this is a + /// capability and not a component comparison. /// /// The component to look up. /// true when the component owns exactly one session slot. public static bool HasSingleSessionSlot(this Components component) => component switch { - Components.CHAT => false, + Components.CHAT or Components.DYNAMIC_ASSISTANT => false, Components.VISUAL_BRIEFING_ASSISTANT => false, _ => true, @@ -59,7 +60,8 @@ public static class ComponentsExtensions public static bool AllowSendTo(this Components component) => component switch { Components.NONE => false, - + Components.DYNAMIC_ASSISTANT => false, + Components.ERI_ASSISTANT => false, Components.BIAS_DAY_ASSISTANT => false, Components.I18N_ASSISTANT => false, @@ -190,7 +192,8 @@ public static class ComponentsExtensions Components.BATCH_PROCESSING_ASSISTANT => settingsManager.ConfigurationData.BatchProcessing.PreselectOptions ? settingsManager.GetProviderById(settingsManager.ConfigurationData.BatchProcessing.PreselectedProvider) : Settings.Provider.NONE, - Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.GetProviderById(settingsManager.ConfigurationData.Chat.PreselectedProvider) : Settings.Provider.NONE, + // Dynamic assistants have no dedicated settings yet, so they derive their defaults from the chat: + Components.DYNAMIC_ASSISTANT or Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.GetProviderById(settingsManager.ConfigurationData.Chat.PreselectedProvider) : Settings.Provider.NONE, Components.AGENT_TEXT_CONTENT_CLEANER => settingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions ? settingsManager.GetProviderById(settingsManager.ConfigurationData.TextContentCleaner.PreselectedAgentProvider) : Settings.Provider.NONE, Components.AGENT_DATA_SOURCE_SELECTION => settingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions ? settingsManager.GetProviderById(settingsManager.ConfigurationData.AgentDataSourceSelection.PreselectedAgentProvider) : Settings.Provider.NONE, @@ -213,7 +216,8 @@ public static class ComponentsExtensions Components.ERI_ASSISTANT => settingsManager.ConfigurationData.ERI.PreselectOptions ? settingsManager.ConfigurationData.ERI.PreselectedProfile : string.Empty, Components.SLIDE_BUILDER_ASSISTANT => settingsManager.ConfigurationData.SlideBuilder.PreselectOptions ? settingsManager.ConfigurationData.SlideBuilder.PreselectedProfile : string.Empty, Components.VISUAL_BRIEFING_ASSISTANT => settingsManager.ConfigurationData.VisualBriefing.PreselectedProfile, - Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Chat.PreselectedProfile : string.Empty, + // Dynamic assistants have no dedicated settings yet, so they derive their defaults from the chat: + Components.DYNAMIC_ASSISTANT or Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Chat.PreselectedProfile : string.Empty, // The Document Analysis Assistant does not have a preselected profile at the component level. // The profile is selected per policy instead. We do this inside the Document Analysis Assistant component: @@ -227,7 +231,8 @@ public static class ComponentsExtensions public static ChatTemplate PreselectedChatTemplate(this Components component, SettingsManager settingsManager) => component switch { - Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.GetChatTemplateById(settingsManager.ConfigurationData.Chat.PreselectedChatTemplate) : ChatTemplate.NO_CHAT_TEMPLATE, + // Dynamic assistants have no dedicated settings yet, so they derive their defaults from the chat: + Components.DYNAMIC_ASSISTANT or Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.GetChatTemplateById(settingsManager.ConfigurationData.Chat.PreselectedChatTemplate) : ChatTemplate.NO_CHAT_TEMPLATE, _ => ChatTemplate.NO_CHAT_TEMPLATE, };