diff --git a/app/MindWork AI Studio/Assistants/Agenda/AssistantAgenda.razor.cs b/app/MindWork AI Studio/Assistants/Agenda/AssistantAgenda.razor.cs index c0571c7c..4658a16b 100644 --- a/app/MindWork AI Studio/Assistants/Agenda/AssistantAgenda.razor.cs +++ b/app/MindWork AI Studio/Assistants/Agenda/AssistantAgenda.razor.cs @@ -7,7 +7,7 @@ namespace AIStudio.Assistants.Agenda; public partial class AssistantAgenda : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.AGENDA_ASSISTANT; + protected override Tools.Components Component => Tools.Components.AGENDA_ASSISTANT; protected override string Title => T("Agenda Planner"); diff --git a/app/MindWork AI Studio/Assistants/AssistantBase.razor b/app/MindWork AI Studio/Assistants/AssistantBase.razor index fa0fc2a9..5fee5f0a 100644 --- a/app/MindWork AI Studio/Assistants/AssistantBase.razor +++ b/app/MindWork AI Studio/Assistants/AssistantBase.razor @@ -9,7 +9,10 @@ @this.Title - + @if (this.HasSettingsPanel) + { + + } @@ -147,4 +150,4 @@ - \ No newline at end of file + diff --git a/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs b/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs index b260b8ed..a91f2b57 100644 --- a/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs +++ b/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs @@ -1,6 +1,7 @@ using AIStudio.Chat; using AIStudio.Provider; using AIStudio.Settings; +using AIStudio.Dialogs.Settings; using AIStudio.Tools.Services; using Microsoft.AspNetCore.Components; @@ -41,8 +42,8 @@ public abstract partial class AssistantBase : AssistantLowerBase wher protected abstract string Description { get; } protected abstract string SystemPrompt { get; } - - public abstract Tools.Components Component { get; } + + protected abstract Tools.Components Component { get; } protected virtual Func Result2Copy => () => this.resultingContentBlock is null ? string.Empty : this.resultingContentBlock.Content switch { @@ -81,6 +82,8 @@ public abstract partial class AssistantBase : AssistantLowerBase wher protected virtual ChatThread ConvertToChatThread => this.chatThread ?? new(); protected virtual IReadOnlyList FooterButtons => []; + + protected virtual bool HasSettingsPanel => typeof(TSettings) != typeof(NoSettingsPanel); protected AIStudio.Settings.Provider providerSettings = Settings.Provider.NONE; protected MudForm? form; @@ -185,6 +188,16 @@ public abstract partial class AssistantBase : AssistantLowerBase wher this.inputIsValid = false; this.StateHasChanged(); } + + /// + /// Clear all input issues. + /// + protected void ClearInputIssues() + { + this.inputIssues = []; + this.inputIsValid = true; + this.StateHasChanged(); + } protected void CreateChatThread() { @@ -218,6 +231,13 @@ public abstract partial class AssistantBase : AssistantLowerBase wher return chatId; } + + protected virtual void ResetProviderAndProfileSelection() + { + this.providerSettings = this.SettingsManager.GetPreselectedProvider(this.Component); + this.currentProfile = this.SettingsManager.GetPreselectedProfile(this.Component); + this.currentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(this.Component); + } protected DateTimeOffset AddUserRequest(string request, bool hideContentFromUser = false, params List attachments) { @@ -310,6 +330,9 @@ public abstract partial class AssistantBase : AssistantLowerBase wher protected async Task OpenSettingsDialog() { + if (!this.HasSettingsPanel) + return; + var dialogParameters = new DialogParameters(); await this.DialogService.ShowAsync(null, dialogParameters, DialogOptions.FULLSCREEN); } @@ -356,9 +379,7 @@ public abstract partial class AssistantBase : AssistantLowerBase wher await this.JsRuntime.ClearDiv(AFTER_RESULT_DIV_ID); this.ResetForm(); - this.providerSettings = this.SettingsManager.GetPreselectedProvider(this.Component); - this.currentProfile = this.SettingsManager.GetPreselectedProfile(this.Component); - this.currentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(this.Component); + this.ResetProviderAndProfileSelection(); this.inputIsValid = false; this.inputIssues = []; @@ -398,4 +419,4 @@ public abstract partial class AssistantBase : AssistantLowerBase wher } #endregion -} \ No newline at end of file +} diff --git a/app/MindWork AI Studio/Assistants/BiasDay/BiasOfTheDayAssistant.razor.cs b/app/MindWork AI Studio/Assistants/BiasDay/BiasOfTheDayAssistant.razor.cs index d87701a3..bf28b7c4 100644 --- a/app/MindWork AI Studio/Assistants/BiasDay/BiasOfTheDayAssistant.razor.cs +++ b/app/MindWork AI Studio/Assistants/BiasDay/BiasOfTheDayAssistant.razor.cs @@ -8,7 +8,7 @@ namespace AIStudio.Assistants.BiasDay; public partial class BiasOfTheDayAssistant : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.BIAS_DAY_ASSISTANT; + protected override Tools.Components Component => Tools.Components.BIAS_DAY_ASSISTANT; protected override string Title => T("Bias of the Day"); diff --git a/app/MindWork AI Studio/Assistants/Coding/AssistantCoding.razor.cs b/app/MindWork AI Studio/Assistants/Coding/AssistantCoding.razor.cs index 7bf8e932..c96043ab 100644 --- a/app/MindWork AI Studio/Assistants/Coding/AssistantCoding.razor.cs +++ b/app/MindWork AI Studio/Assistants/Coding/AssistantCoding.razor.cs @@ -6,7 +6,7 @@ namespace AIStudio.Assistants.Coding; public partial class AssistantCoding : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.CODING_ASSISTANT; + protected override Tools.Components Component => Tools.Components.CODING_ASSISTANT; protected override string Title => T("Coding Assistant"); diff --git a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor index 576664bb..93fc8846 100644 --- a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor +++ b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor @@ -1,6 +1,5 @@ @attribute [Route(Routes.ASSISTANT_DOCUMENT_ANALYSIS)] -@inherits AssistantBaseCore - +@inherits AssistantBaseCore @using AIStudio.Settings.DataModel @@ -25,9 +24,21 @@ else @foreach (var policy in this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies) { - - @policy.PolicyName - + @if (policy.IsEnterpriseConfiguration) + { + + @policy.PolicyName + + + + + } + else + { + + @policy.PolicyName + + } } } @@ -36,85 +47,124 @@ else @T("Add policy") - + @T("Delete this policy") - - - @if (!this.policyDefinitionExpanded) - { - - @T("Expand this section to view and edit the policy definition.") - - } - else - { - - @T("Common settings") - - - - - - - + - - @T("Analysis and output rules") - - - - @T("Use the analysis and output rules to define how the AI evaluates your documents and formats the results.") - - - - @T("The analysis rules specify what the AI should pay particular attention to while reviewing the documents you provide, and which aspects it should highlight or save. For example, if you want to extract the potential of green hydrogen for agriculture from a variety of general publications, you can explicitly define this in the analysis rules.") - - - - - - - - @T("After the AI has processed all documents, it needs your instructions on how the result should be formatted. Would you like a structured list with keywords or a continuous text? Should the output include emojis or be written in formal business language? You can specify all these preferences in the output rules. There, you can also predefine a desired structure—for example, by using Markdown formatting to define headings, paragraphs, or bullet points.") - - - - - - - - @T("Preparation for enterprise distribution") - - - - - @T("Export policy as configuration section") - - - } - - - - - - +@if ((this.selectedPolicy?.HidePolicyDefinition ?? false) && (this.selectedPolicy?.IsEnterpriseConfiguration ?? false)) +{ + @* When HidePolicyDefinition is true AND the policy is an enterprise configuration, show only the document selection section without expansion panels *@ +
+ + @T("Document selection - Policy"): @this.selectedPolicy?.PolicyName + + + @T("Policy Description") - + @this.selectedPolicy?.PolicyDescription - - + + @T("Documents for the analysis") - + - - - +
+} +else +{ + @* Standard view with expansion panels *@ + + + @if (!this.policyDefinitionExpanded) + { + + @T("Expand this section to view and edit the policy definition.") + + } + else + { + + @T("Common settings") + + + + + + + + + + @T("Note: This setting only takes effect when this policy is exported and distributed via a configuration plugin to other users. When enabled, users will only see the document selection interface and cannot view or modify the policy details. This setting does NOT affect your local view - you will always see the full policy definition for policies you create.") + + + + + + + + + + + + @T("Analysis and output rules") + + + + @T("Use the analysis and output rules to define how the AI evaluates your documents and formats the results.") + + + + @T("The analysis rules specify what the AI should pay particular attention to while reviewing the documents you provide, and which aspects it should highlight or save. For example, if you want to extract the potential of green hydrogen for agriculture from a variety of general publications, you can explicitly define this in the analysis rules.") + + + + + + + + @T("After the AI has processed all documents, it needs your instructions on how the result should be formatted. Would you like a structured list with keywords or a continuous text? Should the output include emojis or be written in formal business language? You can specify all these preferences in the output rules. There, you can also predefine a desired structure—for example, by using Markdown formatting to define headings, paragraphs, or bullet points.") + + + + + + + + @T("Preparation for enterprise distribution") + + + + @T("Export policy as configuration section") + + } + + + + + + + @T("Policy Description") + + + + @this.selectedPolicy?.PolicyDescription + + + + @T("Documents for the analysis") + + + + + + +} - \ No newline at end of file + diff --git a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs index 7604e071..f58e6619 100644 --- a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs +++ b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs @@ -1,8 +1,11 @@ using System.Text; +using System.Diagnostics.CodeAnalysis; using AIStudio.Chat; using AIStudio.Dialogs; using AIStudio.Dialogs.Settings; +using AIStudio.Provider; +using AIStudio.Settings; using AIStudio.Settings.DataModel; using Microsoft.AspNetCore.Components; @@ -11,12 +14,12 @@ using DialogOptions = AIStudio.Dialogs.DialogOptions; namespace AIStudio.Assistants.DocumentAnalysis; -public partial class DocumentAnalysisAssistant : AssistantBaseCore +public partial class DocumentAnalysisAssistant : AssistantBaseCore { [Inject] private IDialogService DialogService { get; init; } = null!; - - public override Tools.Components Component => Tools.Components.DOCUMENT_ANALYSIS_ASSISTANT; + + protected override Tools.Components Component => Tools.Components.DOCUMENT_ANALYSIS_ASSISTANT; protected override string Title => T("Document Analysis Assistant"); @@ -116,7 +119,7 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore SubmitAction => this.Analyze; - protected override bool SubmitDisabled => (this.IsNoPolicySelected || this.loadedDocumentPaths.Count==0); + protected override bool SubmitDisabled => this.IsNoPolicySelected || this.loadedDocumentPaths.Count == 0; protected override ChatThread ConvertToChatThread { @@ -162,15 +165,31 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore(Event.SEND_TO_DOCUMENT_ANALYSIS_ASSISTANT).FirstOrDefault(); - if (receivedDeferredContent is not null) - this.deferredContent = receivedDeferredContent; - await base.OnInitializedAsync(); + this.ApplyFilters([], [ Event.CONFIGURATION_CHANGED, Event.PLUGINS_RELOADED ]); + this.UpdateProviders(); + this.ApplyPolicyPreselection(preferPolicyPreselection: true); } #endregion @@ -219,34 +240,43 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore loadedDocumentPaths = []; + private readonly List> availableLLMProviders = new(); private bool IsNoPolicySelectedOrProtected => this.selectedPolicy is null || this.selectedPolicy.IsProtected; @@ -257,6 +287,10 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore(provider.InstanceName, provider.Id)); + } + private async Task RemovePolicy() { if(this.selectedPolicy is null) @@ -283,6 +327,9 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore { { x => x.Message, string.Format(T("Are you sure you want to delete the document analysis policy '{0}'?"), this.selectedPolicy.PolicyName) }, @@ -316,6 +363,9 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore= minimumLevel) + { + this.currentProfile = this.ResolveProfileSelection(); + return; + } + } + + // Try to apply the policy preselection: + var policyProvider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.selectedPolicy.PreselectedProvider); + if (policyProvider is not null && policyProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel) + { + this.providerSettings = policyProvider; + this.currentProfile = this.ResolveProfileSelection(); + return; + } + + var fallbackProvider = this.SettingsManager.GetPreselectedProvider(this.Component, this.providerSettings.Id); + if (fallbackProvider != Settings.Provider.NONE && + fallbackProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level < minimumLevel) + fallbackProvider = Settings.Provider.NONE; + + this.providerSettings = fallbackProvider; + this.currentProfile = this.ResolveProfileSelection(); + } + + private ConfidenceLevel GetPolicyMinimumConfidenceLevel() + { + var minimumLevel = ConfidenceLevel.NONE; + var llmSettings = this.SettingsManager.ConfigurationData.LLMProviders; + var enforceGlobalMinimumConfidence = llmSettings is { EnforceGlobalMinimumConfidence: true, GlobalMinimumConfidence: not ConfidenceLevel.NONE and not ConfidenceLevel.UNKNOWN }; + if (enforceGlobalMinimumConfidence) + minimumLevel = llmSettings.GlobalMinimumConfidence; + + if (this.selectedPolicy is not null && this.selectedPolicy.MinimumProviderConfidence > minimumLevel) + minimumLevel = this.selectedPolicy.MinimumProviderConfidence; + + return minimumLevel; + } + + private Profile ResolveProfileSelection() + { + if (this.selectedPolicy is not null && !string.IsNullOrWhiteSpace(this.selectedPolicy.PreselectedProfile)) + { + var policyProfile = this.SettingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == this.selectedPolicy.PreselectedProfile); + if (policyProfile is not null) + return policyProfile; + } + + return this.SettingsManager.GetPreselectedProfile(this.Component); + } + + private async Task PolicyMinimumConfidenceWasChangedAsync(ConfidenceLevel level) + { + this.policyMinimumProviderConfidence = level; + await this.AutoSave(); + + this.ApplyPolicyPreselection(); + } + + private void PolicyPreselectedProviderWasChanged(string providerId) + { + if (this.selectedPolicy is null) + return; + + this.policyPreselectedProviderId = providerId; + this.selectedPolicy.PreselectedProvider = providerId; + this.providerSettings = Settings.Provider.NONE; + this.ApplyPolicyPreselection(); + } + + private async Task PolicyPreselectedProfileWasChangedAsync(Profile profile) + { + this.policyPreselectedProfileId = profile.Id; + if (this.selectedPolicy is not null) + this.selectedPolicy.PreselectedProfile = this.policyPreselectedProfileId; + + this.currentProfile = this.ResolveProfileSelection(); + await this.AutoSave(); + } + + #region Overrides of MSGComponentBase + + protected override Task ProcessIncomingMessage(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default + { + switch (triggeredEvent) + { + case Event.CONFIGURATION_CHANGED: + this.UpdateProviders(); + this.StateHasChanged(); + break; + + case Event.PLUGINS_RELOADED: + this.HandlePluginsReloaded(); + this.StateHasChanged(); + break; + } + + return Task.CompletedTask; + } + + #endregion + + private void HandlePluginsReloaded() + { + // Check if the currently selected policy still exists after plugin reload: + if (this.selectedPolicy is not null) + { + var stillExists = this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies + .Any(p => p.Id == this.selectedPolicy.Id); + + if (!stillExists) + { + // Policy was removed, select a new one: + this.selectedPolicy = this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.FirstOrDefault(); + } + else + { + // Policy still exists, update the reference to the potentially updated version: + this.selectedPolicy = this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies + .First(p => p.Id == this.selectedPolicy.Id); + } + } + else + { + // No policy was selected, select the first one if available: + this.selectedPolicy = this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.FirstOrDefault(); + } + + // Update form values to reflect the current policy: + this.ResetForm(); + + // Update the expansion state based on the policy protection: + this.policyDefinitionExpanded = !this.selectedPolicy?.IsProtected ?? true; + + // Update available providers: + this.UpdateProviders(); + + // Apply policy preselection: + this.ApplyPolicyPreselection(preferPolicyPreselection: true); + + // Reset validation state: + this.form?.ResetValidation(); + this.ClearInputIssues(); + } private string? ValidatePolicyName(string name) { + if(this.selectedPolicy?.IsEnterpriseConfiguration == true) + return null; + if(string.IsNullOrWhiteSpace(name)) return T("Please provide a name for your policy. This name will be used to identify the policy in AI Studio."); @@ -346,6 +573,9 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.EMAIL_ASSISTANT; + protected override Tools.Components Component => Tools.Components.EMAIL_ASSISTANT; protected override string Title => T("E-Mail"); diff --git a/app/MindWork AI Studio/Assistants/ERI/AssistantERI.razor.cs b/app/MindWork AI Studio/Assistants/ERI/AssistantERI.razor.cs index 6268b137..d8866cfe 100644 --- a/app/MindWork AI Studio/Assistants/ERI/AssistantERI.razor.cs +++ b/app/MindWork AI Studio/Assistants/ERI/AssistantERI.razor.cs @@ -19,8 +19,8 @@ public partial class AssistantERI : AssistantBaseCore [Inject] private IDialogService DialogService { get; init; } = null!; - - public override Tools.Components Component => Tools.Components.ERI_ASSISTANT; + + protected override Tools.Components Component => Tools.Components.ERI_ASSISTANT; protected override string Title => T("ERI Server"); diff --git a/app/MindWork AI Studio/Assistants/GrammarSpelling/AssistantGrammarSpelling.razor.cs b/app/MindWork AI Studio/Assistants/GrammarSpelling/AssistantGrammarSpelling.razor.cs index 6025f133..64168fd2 100644 --- a/app/MindWork AI Studio/Assistants/GrammarSpelling/AssistantGrammarSpelling.razor.cs +++ b/app/MindWork AI Studio/Assistants/GrammarSpelling/AssistantGrammarSpelling.razor.cs @@ -5,7 +5,7 @@ namespace AIStudio.Assistants.GrammarSpelling; public partial class AssistantGrammarSpelling : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.GRAMMAR_SPELLING_ASSISTANT; + protected override Tools.Components Component => Tools.Components.GRAMMAR_SPELLING_ASSISTANT; protected override string Title => T("Grammar & Spelling Checker"); diff --git a/app/MindWork AI Studio/Assistants/I18N/AssistantI18N.razor.cs b/app/MindWork AI Studio/Assistants/I18N/AssistantI18N.razor.cs index a00ff8b4..d229eb9b 100644 --- a/app/MindWork AI Studio/Assistants/I18N/AssistantI18N.razor.cs +++ b/app/MindWork AI Studio/Assistants/I18N/AssistantI18N.razor.cs @@ -16,7 +16,7 @@ namespace AIStudio.Assistants.I18N; public partial class AssistantI18N : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.I18N_ASSISTANT; + protected override Tools.Components Component => Tools.Components.I18N_ASSISTANT; protected override string Title => T("Localization"); diff --git a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua index 2196497c..a3f56347 100644 --- a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua +++ b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua @@ -397,9 +397,6 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Please provide a description of your analysis rules. This rules will be used to instruct the AI on how to analyze the documents. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1291179736"] = "Please provide a description of your analysis rules. This rules will be used to instruct the AI on how to analyze the documents." --- Not implemented yet. -UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1568777658"] = "Not implemented yet." - -- Yes, protect this policy UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1762380857"] = "Yes, protect this policy" @@ -409,9 +406,18 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Please provide a description for your policy. This description will be used to inform users about the purpose of your document analysis policy. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1837166236"] = "Please provide a description for your policy. This description will be used to inform users about the purpose of your document analysis policy." +-- Hide the policy definition when distributed via configuration plugin? +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1875622568"] = "Hide the policy definition when distributed via configuration plugin?" + -- Common settings UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1963959073"] = "Common settings" +-- Note: This setting only takes effect when this policy is exported and distributed via a configuration plugin to other users. When enabled, users will only see the document selection interface and cannot view or modify the policy details. This setting does NOT affect your local view - you will always see the full policy definition for policies you create. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1984494439"] = "Note: This setting only takes effect when this policy is exported and distributed via a configuration plugin to other users. When enabled, users will only see the document selection interface and cannot view or modify the policy details. This setting does NOT affect your local view - you will always see the full policy definition for policies you create." + +-- This policy is managed by your organization. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2035084381"] = "This policy is managed by your organization." + -- The document analysis assistant helps you to analyze and extract information from documents based on predefined policies. You can create, edit, and manage document analysis policies that define how documents should be processed and what information should be extracted. Some policies might be protected by your organization and cannot be modified or deleted. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T206207667"] = "The document analysis assistant helps you to analyze and extract information from documents based on predefined policies. You can create, edit, and manage document analysis policies that define how documents should be processed and what information should be extracted. Some policies might be protected by your organization and cannot be modified or deleted." @@ -451,6 +457,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Policy name UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2879019438"] = "Policy name" +-- No policy is selected. Please select a policy to export. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2929693091"] = "No policy is selected. Please select a policy to export." + -- Policy Description UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3023558273"] = "Policy Description" @@ -466,6 +475,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Policy {0} UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3157740273"] = "Policy {0}" +-- No, show the policy definition +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3166091879"] = "No, show the policy definition" + -- The description of your policy must be between 32 and 512 characters long. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3285636934"] = "The description of your policy must be between 32 and 512 characters long." @@ -508,6 +520,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- After the AI has processed all documents, it needs your instructions on how the result should be formatted. Would you like a structured list with keywords or a continuous text? Should the output include emojis or be written in formal business language? You can specify all these preferences in the output rules. There, you can also predefine a desired structure—for example, by using Markdown formatting to define headings, paragraphs, or bullet points. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T726434276"] = "After the AI has processed all documents, it needs your instructions on how the result should be formatted. Would you like a structured list with keywords or a continuous text? Should the output include emojis or be written in formal business language? You can specify all these preferences in the output rules. There, you can also predefine a desired structure—for example, by using Markdown formatting to define headings, paragraphs, or bullet points." +-- The selected policy contains invalid data. Please fix the issues before exporting the policy. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T736334861"] = "The selected policy contains invalid data. Please fix the issues before exporting the policy." + -- Policy description UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T748735777"] = "Policy description" @@ -517,6 +532,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Here you have the option to save different policies for various document analysis assistants and switch between them. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T848153710"] = "Here you have the option to save different policies for various document analysis assistants and switch between them." +-- Yes, hide the policy definition +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T940701960"] = "Yes, hide the policy definition" + -- Provide a list of bullet points and some basic information for an e-mail. The assistant will generate an e-mail based on that input. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::EMAIL::ASSISTANTEMAIL::T1143222914"] = "Provide a list of bullet points and some basic information for an e-mail. The assistant will generate an e-mail based on that input." @@ -4027,33 +4045,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDATASOURCES::T774473 -- Local Directory UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDATASOURCES::T926703547"] = "Local Directory" --- Assistant: Document Analysis -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T1372406750"] = "Assistant: Document Analysis" - --- Most document analysis options can be customized and saved directly in the assistant. For this, the assistant has an auto-save function. -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T1870328357"] = "Most document analysis options can be customized and saved directly in the assistant. For this, the assistant has an auto-save function." - --- Would you like to preselect one of your profiles? -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2221665527"] = "Would you like to preselect one of your profiles?" - --- Preselect document analysis options? -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2230062650"] = "Preselect document analysis options?" - --- When enabled, you can preselect some document analysis options. -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2301091111"] = "When enabled, you can preselect some document analysis options." - --- No document analysis options are preselected -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3317802895"] = "No document analysis options are preselected" - --- Close -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3448155331"] = "Close" - --- Document analysis options are preselected -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3945756386"] = "Document analysis options are preselected" - --- Preselect one of your profiles? -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T4004501229"] = "Preselect one of your profiles?" - -- When enabled, you can preselect some ERI server options. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGERISERVER::T1280666275"] = "When enabled, you can preselect some ERI server options." diff --git a/app/MindWork AI Studio/Assistants/IconFinder/AssistantIconFinder.razor.cs b/app/MindWork AI Studio/Assistants/IconFinder/AssistantIconFinder.razor.cs index 08d616d8..294cdd3a 100644 --- a/app/MindWork AI Studio/Assistants/IconFinder/AssistantIconFinder.razor.cs +++ b/app/MindWork AI Studio/Assistants/IconFinder/AssistantIconFinder.razor.cs @@ -4,7 +4,7 @@ namespace AIStudio.Assistants.IconFinder; public partial class AssistantIconFinder : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.ICON_FINDER_ASSISTANT; + protected override Tools.Components Component => Tools.Components.ICON_FINDER_ASSISTANT; protected override string Title => T("Icon Finder"); diff --git a/app/MindWork AI Studio/Assistants/JobPosting/AssistantJobPostings.razor.cs b/app/MindWork AI Studio/Assistants/JobPosting/AssistantJobPostings.razor.cs index 21b183f0..d13c2f6d 100644 --- a/app/MindWork AI Studio/Assistants/JobPosting/AssistantJobPostings.razor.cs +++ b/app/MindWork AI Studio/Assistants/JobPosting/AssistantJobPostings.razor.cs @@ -5,7 +5,7 @@ namespace AIStudio.Assistants.JobPosting; public partial class AssistantJobPostings : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.JOB_POSTING_ASSISTANT; + protected override Tools.Components Component => Tools.Components.JOB_POSTING_ASSISTANT; protected override string Title => T("Job Posting"); diff --git a/app/MindWork AI Studio/Assistants/LegalCheck/AssistantLegalCheck.razor.cs b/app/MindWork AI Studio/Assistants/LegalCheck/AssistantLegalCheck.razor.cs index c0b502ee..100c3df4 100644 --- a/app/MindWork AI Studio/Assistants/LegalCheck/AssistantLegalCheck.razor.cs +++ b/app/MindWork AI Studio/Assistants/LegalCheck/AssistantLegalCheck.razor.cs @@ -5,7 +5,7 @@ namespace AIStudio.Assistants.LegalCheck; public partial class AssistantLegalCheck : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.LEGAL_CHECK_ASSISTANT; + protected override Tools.Components Component => Tools.Components.LEGAL_CHECK_ASSISTANT; protected override string Title => T("Legal Check"); diff --git a/app/MindWork AI Studio/Assistants/MyTasks/AssistantMyTasks.razor.cs b/app/MindWork AI Studio/Assistants/MyTasks/AssistantMyTasks.razor.cs index fa5d1e27..c93246a8 100644 --- a/app/MindWork AI Studio/Assistants/MyTasks/AssistantMyTasks.razor.cs +++ b/app/MindWork AI Studio/Assistants/MyTasks/AssistantMyTasks.razor.cs @@ -6,7 +6,7 @@ namespace AIStudio.Assistants.MyTasks; public partial class AssistantMyTasks : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.MY_TASKS_ASSISTANT; + protected override Tools.Components Component => Tools.Components.MY_TASKS_ASSISTANT; protected override string Title => T("My Tasks"); diff --git a/app/MindWork AI Studio/Assistants/RewriteImprove/AssistantRewriteImprove.razor.cs b/app/MindWork AI Studio/Assistants/RewriteImprove/AssistantRewriteImprove.razor.cs index 44aa94d2..2ddac0fd 100644 --- a/app/MindWork AI Studio/Assistants/RewriteImprove/AssistantRewriteImprove.razor.cs +++ b/app/MindWork AI Studio/Assistants/RewriteImprove/AssistantRewriteImprove.razor.cs @@ -5,7 +5,7 @@ namespace AIStudio.Assistants.RewriteImprove; public partial class AssistantRewriteImprove : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.REWRITE_ASSISTANT; + protected override Tools.Components Component => Tools.Components.REWRITE_ASSISTANT; protected override string Title => T("Rewrite & Improve Text"); diff --git a/app/MindWork AI Studio/Assistants/Synonym/AssistantSynonyms.razor.cs b/app/MindWork AI Studio/Assistants/Synonym/AssistantSynonyms.razor.cs index 3581a5d3..739a4a2f 100644 --- a/app/MindWork AI Studio/Assistants/Synonym/AssistantSynonyms.razor.cs +++ b/app/MindWork AI Studio/Assistants/Synonym/AssistantSynonyms.razor.cs @@ -5,7 +5,7 @@ namespace AIStudio.Assistants.Synonym; public partial class AssistantSynonyms : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.SYNONYMS_ASSISTANT; + protected override Tools.Components Component => Tools.Components.SYNONYMS_ASSISTANT; protected override string Title => T("Synonyms"); diff --git a/app/MindWork AI Studio/Assistants/TextSummarizer/AssistantTextSummarizer.razor.cs b/app/MindWork AI Studio/Assistants/TextSummarizer/AssistantTextSummarizer.razor.cs index 257ff39c..35dee799 100644 --- a/app/MindWork AI Studio/Assistants/TextSummarizer/AssistantTextSummarizer.razor.cs +++ b/app/MindWork AI Studio/Assistants/TextSummarizer/AssistantTextSummarizer.razor.cs @@ -5,7 +5,7 @@ namespace AIStudio.Assistants.TextSummarizer; public partial class AssistantTextSummarizer : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.TEXT_SUMMARIZER_ASSISTANT; + protected override Tools.Components Component => Tools.Components.TEXT_SUMMARIZER_ASSISTANT; protected override string Title => T("Text Summarizer"); diff --git a/app/MindWork AI Studio/Assistants/Translation/AssistantTranslation.razor.cs b/app/MindWork AI Studio/Assistants/Translation/AssistantTranslation.razor.cs index 51359e40..6b890ee5 100644 --- a/app/MindWork AI Studio/Assistants/Translation/AssistantTranslation.razor.cs +++ b/app/MindWork AI Studio/Assistants/Translation/AssistantTranslation.razor.cs @@ -5,7 +5,7 @@ namespace AIStudio.Assistants.Translation; public partial class AssistantTranslation : AssistantBaseCore { - public override Tools.Components Component => Tools.Components.TRANSLATION_ASSISTANT; + protected override Tools.Components Component => Tools.Components.TRANSLATION_ASSISTANT; protected override string Title => T("Translation"); diff --git a/app/MindWork AI Studio/Components/AssistantBlock.razor b/app/MindWork AI Studio/Components/AssistantBlock.razor index 372fae7e..8af43e72 100644 --- a/app/MindWork AI Studio/Components/AssistantBlock.razor +++ b/app/MindWork AI Studio/Components/AssistantBlock.razor @@ -26,8 +26,11 @@ @this.ButtonText - + @if (this.HasSettingsPanel) + { + + } -} \ No newline at end of file +} diff --git a/app/MindWork AI Studio/Components/AssistantBlock.razor.cs b/app/MindWork AI Studio/Components/AssistantBlock.razor.cs index 69dfe49b..09f0d73d 100644 --- a/app/MindWork AI Studio/Components/AssistantBlock.razor.cs +++ b/app/MindWork AI Studio/Components/AssistantBlock.razor.cs @@ -1,4 +1,5 @@ using AIStudio.Settings.DataModel; +using AIStudio.Dialogs.Settings; using Microsoft.AspNetCore.Components; @@ -37,6 +38,9 @@ public partial class AssistantBlock : MSGComponentBase where TSetting private async Task OpenSettingsDialog() { + if (!this.HasSettingsPanel) + return; + var dialogParameters = new DialogParameters(); await this.DialogService.ShowAsync(T("Open Settings"), dialogParameters, DialogOptions.FULLSCREEN); @@ -51,4 +55,6 @@ public partial class AssistantBlock : MSGComponentBase where TSetting private string BlockStyle => $"border-width: 2px; border-color: {this.BorderColor}; border-radius: 12px; border-style: solid; max-width: 20em;"; private bool IsVisible => this.SettingsManager.IsAssistantVisible(this.Component, assistantName: this.Name, requiredPreviewFeature: this.RequiredPreviewFeature); -} \ No newline at end of file + + private bool HasSettingsPanel => typeof(TSettings) != typeof(NoSettingsPanel); +} diff --git a/app/MindWork AI Studio/Components/ConfigurationMinConfidenceSelection.razor b/app/MindWork AI Studio/Components/ConfigurationMinConfidenceSelection.razor index 93a47e8b..01cf6850 100644 --- a/app/MindWork AI Studio/Components/ConfigurationMinConfidenceSelection.razor +++ b/app/MindWork AI Studio/Components/ConfigurationMinConfidenceSelection.razor @@ -1,3 +1,3 @@ @using AIStudio.Settings @inherits MSGComponentBase - \ No newline at end of file + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/ConfigurationMinConfidenceSelection.razor.cs b/app/MindWork AI Studio/Components/ConfigurationMinConfidenceSelection.razor.cs index b5d130c8..c980d457 100644 --- a/app/MindWork AI Studio/Components/ConfigurationMinConfidenceSelection.razor.cs +++ b/app/MindWork AI Studio/Components/ConfigurationMinConfidenceSelection.razor.cs @@ -17,6 +17,12 @@ public partial class ConfigurationMinConfidenceSelection : MSGComponentBase /// [Parameter] public Action SelectionUpdate { get; set; } = _ => { }; + + /// + /// An asynchronous action that is called when the selection changes. + /// + [Parameter] + public Func SelectionUpdateAsync { get; set; } = _ => Task.CompletedTask; /// /// Boolean value indicating whether the selection is restricted to a global minimum confidence level. diff --git a/app/MindWork AI Studio/Components/ConfigurationProviderSelection.razor.cs b/app/MindWork AI Studio/Components/ConfigurationProviderSelection.razor.cs index 39ae76be..8267219c 100644 --- a/app/MindWork AI Studio/Components/ConfigurationProviderSelection.razor.cs +++ b/app/MindWork AI Studio/Components/ConfigurationProviderSelection.razor.cs @@ -25,6 +25,9 @@ public partial class ConfigurationProviderSelection : MSGComponentBase [Parameter] public Tools.Components Component { get; set; } = Tools.Components.NONE; + + [Parameter] + public ConfidenceLevel ExplicitMinimumConfidence { get; set; } = ConfidenceLevel.UNKNOWN; [Parameter] public Func Disabled { get; set; } = () => false; @@ -38,7 +41,14 @@ public partial class ConfigurationProviderSelection : MSGComponentBase if(this.Component is not Tools.Components.NONE and not Tools.Components.APP_SETTINGS) yield return new(T("Use app default"), string.Empty); + // Get the minimum confidence level for this component, and/or the enforced global minimum confidence level: var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.Component); + + // Apply the explicit minimum confidence level if set and higher than the current minimum level: + if (this.ExplicitMinimumConfidence is not ConfidenceLevel.UNKNOWN && this.ExplicitMinimumConfidence > minimumLevel) + minimumLevel = this.ExplicitMinimumConfidence; + + // Filter the providers based on the minimum confidence level: foreach (var providerId in this.Data) { var provider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == providerId.Value); @@ -75,4 +85,4 @@ public partial class ConfigurationProviderSelection : MSGComponentBase } #endregion -} \ No newline at end of file +} diff --git a/app/MindWork AI Studio/Components/ConfigurationSelect.razor.cs b/app/MindWork AI Studio/Components/ConfigurationSelect.razor.cs index e5780c9d..820a4ee0 100644 --- a/app/MindWork AI Studio/Components/ConfigurationSelect.razor.cs +++ b/app/MindWork AI Studio/Components/ConfigurationSelect.razor.cs @@ -27,6 +27,12 @@ public partial class ConfigurationSelect : ConfigurationBaseCore /// [Parameter] public Action SelectionUpdate { get; set; } = _ => { }; + + /// + /// An asynchronous action that is called when the selection changes. + /// + [Parameter] + public Func SelectionUpdateAsync { get; set; } = _ => Task.CompletedTask; #region Overrides of ConfigurationBase @@ -44,6 +50,7 @@ public partial class ConfigurationSelect : ConfigurationBaseCore private async Task OptionChanged(TConfig updatedValue) { this.SelectionUpdate(updatedValue); + await this.SelectionUpdateAsync(updatedValue); await this.SettingsManager.StoreSettings(); await this.InformAboutChange(); } diff --git a/app/MindWork AI Studio/Components/ProfileFormSelection.razor b/app/MindWork AI Studio/Components/ProfileFormSelection.razor index f963ced7..cd063d41 100644 --- a/app/MindWork AI Studio/Components/ProfileFormSelection.razor +++ b/app/MindWork AI Studio/Components/ProfileFormSelection.razor @@ -2,7 +2,7 @@ @inherits MSGComponentBase - + @foreach (var profile in this.SettingsManager.ConfigurationData.Profiles.GetAllProfiles()) { @@ -11,5 +11,5 @@ } - - \ No newline at end of file + + diff --git a/app/MindWork AI Studio/Components/ProfileFormSelection.razor.cs b/app/MindWork AI Studio/Components/ProfileFormSelection.razor.cs index ec71737e..3dc80979 100644 --- a/app/MindWork AI Studio/Components/ProfileFormSelection.razor.cs +++ b/app/MindWork AI Studio/Components/ProfileFormSelection.razor.cs @@ -17,6 +17,9 @@ public partial class ProfileFormSelection : MSGComponentBase [Parameter] public Func Validation { get; set; } = _ => null; + + [Parameter] + public bool Disabled { get; set; } [Inject] public IDialogService DialogService { get; init; } = null!; diff --git a/app/MindWork AI Studio/Components/ProviderSelection.razor.cs b/app/MindWork AI Studio/Components/ProviderSelection.razor.cs index bdc76ddc..809ed089 100644 --- a/app/MindWork AI Studio/Components/ProviderSelection.razor.cs +++ b/app/MindWork AI Studio/Components/ProviderSelection.razor.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; using AIStudio.Provider; @@ -20,6 +19,9 @@ public partial class ProviderSelection : MSGComponentBase [Parameter] public Func ValidateProvider { get; set; } = _ => null; + + [Parameter] + public ConfidenceLevel ExplicitMinimumConfidence { get; set; } = ConfidenceLevel.UNKNOWN; [Inject] private ILogger Logger { get; init; } = null!; @@ -44,7 +46,15 @@ public partial class ProviderSelection : MSGComponentBase yield break; case { } component: + + // Get the minimum confidence level for this component, and/or the global minimum if enforced: var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(component); + + // Override with the explicit minimum level if set and higher: + if (this.ExplicitMinimumConfidence is not ConfidenceLevel.UNKNOWN && this.ExplicitMinimumConfidence > minimumLevel) + minimumLevel = this.ExplicitMinimumConfidence; + + // Filter providers based on the minimum confidence level: foreach (var provider in this.SettingsManager.ConfigurationData.Providers) if (provider.UsedLLMProvider != LLMProviders.NONE) if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel) diff --git a/app/MindWork AI Studio/Components/ReadFileContent.razor b/app/MindWork AI Studio/Components/ReadFileContent.razor index 05a63722..302224de 100644 --- a/app/MindWork AI Studio/Components/ReadFileContent.razor +++ b/app/MindWork AI Studio/Components/ReadFileContent.razor @@ -1,5 +1,5 @@ @inherits MSGComponentBase - + @if (string.IsNullOrWhiteSpace(this.Text)) { @T("Use file content as input") @@ -8,4 +8,4 @@ { @this.Text } - \ No newline at end of file + diff --git a/app/MindWork AI Studio/Components/ReadFileContent.razor.cs b/app/MindWork AI Studio/Components/ReadFileContent.razor.cs index 5db85e21..d3248937 100644 --- a/app/MindWork AI Studio/Components/ReadFileContent.razor.cs +++ b/app/MindWork AI Studio/Components/ReadFileContent.razor.cs @@ -15,6 +15,9 @@ public partial class ReadFileContent : MSGComponentBase [Parameter] public EventCallback FileContentChanged { get; set; } + + [Parameter] + public bool Disabled { get; set; } [Inject] private RustService RustService { get; init; } = null!; @@ -30,6 +33,9 @@ public partial class ReadFileContent : MSGComponentBase private async Task SelectFile() { + if (this.Disabled) + return; + // Ensure that Pandoc is installed and ready: var pandocState = await this.PandocAvailabilityService.EnsureAvailabilityAsync( showSuccessMessage: false, @@ -73,4 +79,4 @@ public partial class ReadFileContent : MSGComponentBase await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Error, T("Failed to load file content"))); } } -} \ No newline at end of file +} diff --git a/app/MindWork AI Studio/Dialogs/Settings/NoSettingsPanel.razor b/app/MindWork AI Studio/Dialogs/Settings/NoSettingsPanel.razor new file mode 100644 index 00000000..132ca131 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/NoSettingsPanel.razor @@ -0,0 +1,2 @@ +@namespace AIStudio.Dialogs.Settings + diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDocumentAnalysis.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDocumentAnalysis.razor deleted file mode 100644 index 2b9744b0..00000000 --- a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDocumentAnalysis.razor +++ /dev/null @@ -1,28 +0,0 @@ -@using AIStudio.Settings -@inherits SettingsDialogBase - - - - - - - @T("Assistant: Document Analysis") - - - - - - - - - - @T("Most document analysis options can be customized and saved directly in the assistant. For this, the assistant has an auto-save function.") - - - - - - @T("Close") - - - \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDocumentAnalysis.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDocumentAnalysis.razor.cs deleted file mode 100644 index caafcb44..00000000 --- a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDocumentAnalysis.razor.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace AIStudio.Dialogs.Settings; - -public partial class SettingsDialogDocumentAnalysis : SettingsDialogBase; \ No newline at end of file diff --git a/app/MindWork AI Studio/Pages/Assistants.razor b/app/MindWork AI Studio/Pages/Assistants.razor index 250aa06c..610a68cd 100644 --- a/app/MindWork AI Studio/Pages/Assistants.razor +++ b/app/MindWork AI Studio/Pages/Assistants.razor @@ -45,7 +45,7 @@
- + diff --git a/app/MindWork AI Studio/Plugins/configuration/plugin.lua b/app/MindWork AI Studio/Plugins/configuration/plugin.lua index ff421ff7..73061b73 100644 --- a/app/MindWork AI Studio/Plugins/configuration/plugin.lua +++ b/app/MindWork AI Studio/Plugins/configuration/plugin.lua @@ -49,26 +49,26 @@ CONFIG = {} CONFIG["LLM_PROVIDERS"] = {} -- An example of a configuration for a self-hosted server: -CONFIG["LLM_PROVIDERS"][#CONFIG["LLM_PROVIDERS"]+1] = { - ["Id"] = "00000000-0000-0000-0000-000000000000", - ["InstanceName"] = "", - ["UsedLLMProvider"] = "SELF_HOSTED", - - -- Allowed values for Host are: LM_STUDIO, LLAMACPP, OLLAMA, and VLLM - ["Host"] = "OLLAMA", - ["Hostname"] = "", - - -- Optional: Additional parameters for the API. - -- Please refer to the documentation of the selected host for details. - -- Might be something like ... \"temperature\": 0.5 ... for one parameter. - -- Could be something like ... \"temperature\": 0.5, \"max_tokens\": 1000 ... for multiple parameters. - -- Please do not add the enclosing curly braces {} here. Also, no trailing comma is allowed. - ["AdditionalJsonApiParameters"] = "", - ["Model"] = { - ["Id"] = "", - ["DisplayName"] = "", - } -} +-- CONFIG["LLM_PROVIDERS"][#CONFIG["LLM_PROVIDERS"]+1] = { +-- ["Id"] = "00000000-0000-0000-0000-000000000000", +-- ["InstanceName"] = "", +-- ["UsedLLMProvider"] = "SELF_HOSTED", +-- +-- -- Allowed values for Host are: LM_STUDIO, LLAMACPP, OLLAMA, and VLLM +-- ["Host"] = "OLLAMA", +-- ["Hostname"] = "", +-- +-- -- Optional: Additional parameters for the API. +-- -- Please refer to the documentation of the selected host for details. +-- -- Might be something like ... \"temperature\": 0.5 ... for one parameter. +-- -- Could be something like ... \"temperature\": 0.5, \"max_tokens\": 1000 ... for multiple parameters. +-- -- Please do not add the enclosing curly braces {} here. Also, no trailing comma is allowed. +-- ["AdditionalJsonApiParameters"] = "", +-- ["Model"] = { +-- ["Id"] = "", +-- ["DisplayName"] = "", +-- } +-- } -- Transcription providers for voice-to-text functionality: CONFIG["TRANSCRIPTION_PROVIDERS"] = {} @@ -167,60 +167,97 @@ CONFIG["SETTINGS"] = {} CONFIG["CHAT_TEMPLATES"] = {} -- A simple example chat template: -CONFIG["CHAT_TEMPLATES"][#CONFIG["CHAT_TEMPLATES"]+1] = { - ["Id"] = "00000000-0000-0000-0000-000000000000", - ["Name"] = "", - ["SystemPrompt"] = "You are 's helpful AI assistant for . Your task is ...", - ["PredefinedUserPrompt"] = "Please help me with ...", - ["AllowProfileUsage"] = true, - ["ExampleConversation"] = { - { - -- Allowed values are: USER, AI, SYSTEM - ["Role"] = "USER", - ["Content"] = "Hello! Can you help me with a quick task?" - }, - { - -- Allowed values are: USER, AI, SYSTEM - ["Role"] = "AI", - ["Content"] = "Of course. What do you need?" - } - } -} +-- CONFIG["CHAT_TEMPLATES"][#CONFIG["CHAT_TEMPLATES"]+1] = { +-- ["Id"] = "00000000-0000-0000-0000-000000000000", +-- ["Name"] = "", +-- ["SystemPrompt"] = "You are 's helpful AI assistant for . Your task is ...", +-- ["PredefinedUserPrompt"] = "Please help me with ...", +-- ["AllowProfileUsage"] = true, +-- ["ExampleConversation"] = { +-- { +-- -- Allowed values are: USER, AI, SYSTEM +-- ["Role"] = "USER", +-- ["Content"] = "Hello! Can you help me with a quick task?" +-- }, +-- { +-- -- Allowed values are: USER, AI, SYSTEM +-- ["Role"] = "AI", +-- ["Content"] = "Of course. What do you need?" +-- } +-- } +-- } -- An example chat template with file attachments: -- This template automatically attaches specified files when the user selects it. -CONFIG["CHAT_TEMPLATES"][#CONFIG["CHAT_TEMPLATES"]+1] = { - ["Id"] = "00000000-0000-0000-0000-000000000001", - ["Name"] = "Document Analysis Template", - ["SystemPrompt"] = "You are an expert document analyst. Please analyze the attached documents and provide insights.", - ["PredefinedUserPrompt"] = "Please analyze the attached company guidelines and summarize the key points.", - ["AllowProfileUsage"] = true, - -- Optional: Pre-attach files that will be automatically included when using this template. - -- These files will be loaded when the user selects this chat template. - -- Note: File paths must be absolute paths and accessible to all users. - ["FileAttachments"] = { - "G:\\Company\\Documents\\Guidelines.pdf", - "G:\\Company\\Documents\\CompanyPolicies.docx" - }, - ["ExampleConversation"] = { - { - ["Role"] = "USER", - ["Content"] = "I have attached the company documents for analysis." - }, - { - ["Role"] = "AI", - ["Content"] = "Thank you. I'll analyze the documents and provide a comprehensive summary." - } - } -} +-- CONFIG["CHAT_TEMPLATES"][#CONFIG["CHAT_TEMPLATES"]+1] = { +-- ["Id"] = "00000000-0000-0000-0000-000000000001", +-- ["Name"] = "Document Analysis Template", +-- ["SystemPrompt"] = "You are an expert document analyst. Please analyze the attached documents and provide insights.", +-- ["PredefinedUserPrompt"] = "Please analyze the attached company guidelines and summarize the key points.", +-- ["AllowProfileUsage"] = true, +-- -- Optional: Pre-attach files that will be automatically included when using this template. +-- -- These files will be loaded when the user selects this chat template. +-- -- Note: File paths must be absolute paths and accessible to all users. +-- ["FileAttachments"] = { +-- "G:\\Company\\Documents\\Guidelines.pdf", +-- "G:\\Company\\Documents\\CompanyPolicies.docx" +-- }, +-- ["ExampleConversation"] = { +-- { +-- ["Role"] = "USER", +-- ["Content"] = "I have attached the company documents for analysis." +-- }, +-- { +-- ["Role"] = "AI", +-- ["Content"] = "Thank you. I'll analyze the documents and provide a comprehensive summary." +-- } +-- } +-- } + +-- Document analysis policies for this configuration: +CONFIG["DOCUMENT_ANALYSIS_POLICIES"] = {} + +-- An example document analysis policy: +-- CONFIG["DOCUMENT_ANALYSIS_POLICIES"][#CONFIG["DOCUMENT_ANALYSIS_POLICIES"]+1] = { +-- ["Id"] = "00000000-0000-0000-0000-000000000000", +-- ["PolicyName"] = "Compliance Summary Policy", +-- ["PolicyDescription"] = "Summarizes compliance-relevant clauses, obligations, and deadlines found in provided documents.", +-- +-- ["AnalysisRules"] = [===[ +-- Focus on compliance obligations, deadlines, and required actions. +-- Ignore marketing content and high-level summaries. +-- Flag any ambiguous or missing information. +-- ]===], +-- +-- ["OutputRules"] = [===[ +-- Provide a Markdown report with headings for Obligations, Deadlines, +-- and Open Questions. +-- ]===], +-- +-- -- Optional: minimum provider confidence required for this policy. +-- -- Allowed values are: NONE, VERY_LOW, LOW, MODERATE, MEDIUM, HIGH +-- ["MinimumProviderConfidence"] = "MEDIUM", +-- +-- -- Optional: preselect a provider or profile by ID. +-- -- The IDs must exist in CONFIG["LLM_PROVIDERS"] or CONFIG["PROFILES"]. +-- ["PreselectedProvider"] = "00000000-0000-0000-0000-000000000000", +-- ["PreselectedProfile"] = "00000000-0000-0000-0000-000000000000", +-- +-- -- Optional: hide the policy definition section in the UI. +-- -- When set to true, users will only see the document selection interface +-- -- and cannot view or modify the policy settings. +-- -- This is useful for enterprise configurations where policy details should remain hidden. +-- -- Allowed values are: true, false (default: false) +-- ["HidePolicyDefinition"] = false +-- } -- Profiles for this configuration: CONFIG["PROFILES"] = {} -- A simple profile template: -CONFIG["PROFILES"][#CONFIG["PROFILES"]+1] = { - ["Id"] = "00000000-0000-0000-0000-000000000000", - ["Name"] = "", - ["NeedToKnow"] = "I like to cook in my free time. My favorite meal is ...", - ["Actions"] = "Please always ensure the portion size is ..." -} \ No newline at end of file +-- CONFIG["PROFILES"][#CONFIG["PROFILES"]+1] = { +-- ["Id"] = "00000000-0000-0000-0000-000000000000", +-- ["Name"] = "", +-- ["NeedToKnow"] = "I like to cook in my free time. My favorite meal is ...", +-- ["Actions"] = "Please always ensure the portion size is ..." +-- } \ No newline at end of file diff --git a/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua b/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua index cd9768f8..6adbe50f 100644 --- a/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua +++ b/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua @@ -399,9 +399,6 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Please provide a description of your analysis rules. This rules will be used to instruct the AI on how to analyze the documents. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1291179736"] = "Bitte geben Sie eine Beschreibung Ihrer Analyseregeln an. Diese Regeln werden verwendet, um die KI anzuweisen, wie die Dokumente analysiert werden sollen." --- Not implemented yet. -UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1568777658"] = "Noch nicht implementiert." - -- Yes, protect this policy UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1762380857"] = "Ja, dieses Regelwerk schützen" @@ -411,9 +408,18 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Please provide a description for your policy. This description will be used to inform users about the purpose of your document analysis policy. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1837166236"] = "Bitte geben Sie eine Beschreibung für Ihr Regelwerk an. Diese Beschreibung wird verwendet, um Benutzer über den Zweck Ihres Regelwerks zur Dokumentenanalyse zu informieren." +-- Hide the policy definition when distributed via configuration plugin? +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1875622568"] = "Die Definition des Regelwerks ausblenden, wenn diese über ein Konfigurations-Plugin verteilt wird?" + -- Common settings UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1963959073"] = "Allgemeine Einstellungen" +-- Note: This setting only takes effect when this policy is exported and distributed via a configuration plugin to other users. When enabled, users will only see the document selection interface and cannot view or modify the policy details. This setting does NOT affect your local view - you will always see the full policy definition for policies you create. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1984494439"] = "Hinweis: Diese Einstellung wird nur wirksam, wenn dieses Regelwerk exportiert und über ein Konfigurations-Plugin an andere Nutzer verteilt wird. Wenn sie aktiviert ist, sehen Nutzer nur die Oberfläche zur Dokumentauswahl und können die Details des Regelwerks weder anzeigen noch ändern. Diese Einstellung wirkt sich NICHT auf Ihre lokale Ansicht aus – Sie sehen bei von Ihnen erstellten Regelwerken immer die Definition." + +-- This policy is managed by your organization. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2035084381"] = "Dieses Regelwerk wird von Ihrer Organisation verwaltet." + -- The document analysis assistant helps you to analyze and extract information from documents based on predefined policies. You can create, edit, and manage document analysis policies that define how documents should be processed and what information should be extracted. Some policies might be protected by your organization and cannot be modified or deleted. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T206207667"] = "Der Assistent für Dokumentenanalyse hilft Ihnen dabei, Informationen aus Dokumenten basierend auf vordefinierten Regelwerken zu analysieren und zu extrahieren. Sie können Regelwerke für die Dokumentenanalyse erstellen, bearbeiten und verwalten, die festlegen, wie Dokumente verarbeitet werden und welche Informationen extrahiert werden sollen. Einige Regelwerke könnten durch Ihre Organisation geschützt sein und können nicht geändert oder gelöscht werden." @@ -453,6 +459,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Policy name UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2879019438"] = "Name des Regelwerks" +-- No policy is selected. Please select a policy to export. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2929693091"] = "Es ist kein Regelwerk ausgewählt. Bitte wählen Sie ein Regelwerk zum Exportieren aus." + -- Policy Description UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3023558273"] = "Beschreibung des Regelwerks" @@ -468,6 +477,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Policy {0} UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3157740273"] = "Regelwerk {0}" +-- No, show the policy definition +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3166091879"] = "Nein, zeige die Definition des Regelwerks" + -- The description of your policy must be between 32 and 512 characters long. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3285636934"] = "Die Beschreibung des Regelwerks muss zwischen 32 und 512 Zeichen lang sein." @@ -510,6 +522,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- After the AI has processed all documents, it needs your instructions on how the result should be formatted. Would you like a structured list with keywords or a continuous text? Should the output include emojis or be written in formal business language? You can specify all these preferences in the output rules. There, you can also predefine a desired structure—for example, by using Markdown formatting to define headings, paragraphs, or bullet points. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T726434276"] = "Nachdem die KI alle Dokumente verarbeitet hat, benötigt sie Ihre Anweisungen, wie das Ergebnis formatiert werden soll. Möchten Sie eine strukturierte Liste mit Schlüsselwörtern oder einen fließenden Text? Soll die Ausgabe Emojis enthalten oder in formeller Geschäftssprache verfasst sein? Alle diese Präferenzen können Sie in den Ausgaberegeln festlegen. Dort können Sie auch eine gewünschte Struktur vordefinieren – zum Beispiel durch Verwendung von Markdown-Formatierung, um Überschriften, Absätze oder Aufzählungspunkte zu definieren." +-- The selected policy contains invalid data. Please fix the issues before exporting the policy. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T736334861"] = "Das ausgewählte Regelwerk enthält ungültige Daten. Bitte beheben Sie die Probleme, bevor Sie das Regelwerk exportieren." + -- Policy description UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T748735777"] = "Beschreibung des Regelwerks" @@ -519,6 +534,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Here you have the option to save different policies for various document analysis assistants and switch between them. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T848153710"] = "Hier haben Sie die Möglichkeit, verschiedene Regelwerke für unterschiedliche Dokumentenanalysen zu speichern und zwischen ihnen zu wechseln." +-- Yes, hide the policy definition +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T940701960"] = "Ja, die Definition des Regelwerks ausblenden" + -- Provide a list of bullet points and some basic information for an e-mail. The assistant will generate an e-mail based on that input. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::EMAIL::ASSISTANTEMAIL::T1143222914"] = "Geben Sie eine Liste von Stichpunkten sowie einige Basisinformationen für eine E-Mail ein. Der Assistent erstellt anschließend eine E-Mail auf Grundlage ihrer Angaben." @@ -4029,33 +4047,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDATASOURCES::T774473 -- Local Directory UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDATASOURCES::T926703547"] = "Lokaler Ordner" --- Assistant: Document Analysis -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T1372406750"] = "Assistent: Dokumentenanalyse" - --- Most document analysis options can be customized and saved directly in the assistant. For this, the assistant has an auto-save function. -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T1870328357"] = "Die meisten Optionen für die Analyse von Dokumenten können im Assistenten angepasst und direkt gespeichert werden. Dafür verfügt der Assistent über eine automatische Speicherfunktion." - --- Would you like to preselect one of your profiles? -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2221665527"] = "Möchten Sie eines Ihrer Profile vorab auswählen?" - --- Preselect document analysis options? -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2230062650"] = "Dokumentenanalyse-Optionen vorab auswählen?" - --- When enabled, you can preselect some document analysis options. -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2301091111"] = "Wenn aktiviert, können Sie einige Dokumentanalyse-Optionen vorab auswählen." - --- No document analysis options are preselected -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3317802895"] = "Keine Dokumentenanalyse-Optionen sind vorausgewählt." - --- Close -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3448155331"] = "Schließen" - --- Document analysis options are preselected -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3945756386"] = "Dokumentenanalyse-Optionen sind vorausgewählt." - --- Preselect one of your profiles? -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T4004501229"] = "Eines Ihrer Profile vorauswählen?" - -- When enabled, you can preselect some ERI server options. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGERISERVER::T1280666275"] = "Wenn aktiviert, können Sie einige ERI-Serveroptionen vorauswählen." diff --git a/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua b/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua index d4fa1ba7..5c164305 100644 --- a/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua +++ b/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua @@ -399,9 +399,6 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Please provide a description of your analysis rules. This rules will be used to instruct the AI on how to analyze the documents. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1291179736"] = "Please provide a description of your analysis rules. This rules will be used to instruct the AI on how to analyze the documents." --- Not implemented yet. -UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1568777658"] = "Not implemented yet." - -- Yes, protect this policy UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1762380857"] = "Yes, protect this policy" @@ -411,9 +408,18 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Please provide a description for your policy. This description will be used to inform users about the purpose of your document analysis policy. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1837166236"] = "Please provide a description for your policy. This description will be used to inform users about the purpose of your document analysis policy." +-- Hide the policy definition when distributed via configuration plugin? +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1875622568"] = "Hide the policy definition when distributed via configuration plugin?" + -- Common settings UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1963959073"] = "Common settings" +-- Note: This setting only takes effect when this policy is exported and distributed via a configuration plugin to other users. When enabled, users will only see the document selection interface and cannot view or modify the policy details. This setting does NOT affect your local view - you will always see the full policy definition for policies you create. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1984494439"] = "Note: This setting only takes effect when this policy is exported and distributed via a configuration plugin to other users. When enabled, users will only see the document selection interface and cannot view or modify the policy details. This setting does NOT affect your local view - you will always see the full policy definition for policies you create." + +-- This policy is managed by your organization. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2035084381"] = "This policy is managed by your organization." + -- The document analysis assistant helps you to analyze and extract information from documents based on predefined policies. You can create, edit, and manage document analysis policies that define how documents should be processed and what information should be extracted. Some policies might be protected by your organization and cannot be modified or deleted. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T206207667"] = "The document analysis assistant helps you to analyze and extract information from documents based on predefined policies. You can create, edit, and manage document analysis policies that define how documents should be processed and what information should be extracted. Some policies might be protected by your organization and cannot be modified or deleted." @@ -453,6 +459,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Policy name UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2879019438"] = "Policy name" +-- No policy is selected. Please select a policy to export. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2929693091"] = "No policy is selected. Please select a policy to export." + -- Policy Description UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3023558273"] = "Policy Description" @@ -468,6 +477,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Policy {0} UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3157740273"] = "Policy {0}" +-- No, show the policy definition +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3166091879"] = "No, show the policy definition" + -- The description of your policy must be between 32 and 512 characters long. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3285636934"] = "The description of your policy must be between 32 and 512 characters long." @@ -510,6 +522,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- After the AI has processed all documents, it needs your instructions on how the result should be formatted. Would you like a structured list with keywords or a continuous text? Should the output include emojis or be written in formal business language? You can specify all these preferences in the output rules. There, you can also predefine a desired structure—for example, by using Markdown formatting to define headings, paragraphs, or bullet points. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T726434276"] = "After the AI has processed all documents, it needs your instructions on how the result should be formatted. Would you like a structured list with keywords or a continuous text? Should the output include emojis or be written in formal business language? You can specify all these preferences in the output rules. There, you can also predefine a desired structure—for example, by using Markdown formatting to define headings, paragraphs, or bullet points." +-- The selected policy contains invalid data. Please fix the issues before exporting the policy. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T736334861"] = "The selected policy contains invalid data. Please fix the issues before exporting the policy." + -- Policy description UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T748735777"] = "Policy description" @@ -519,6 +534,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTA -- Here you have the option to save different policies for various document analysis assistants and switch between them. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T848153710"] = "Here you have the option to save different policies for various document analysis assistants and switch between them." +-- Yes, hide the policy definition +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T940701960"] = "Yes, hide the policy definition" + -- Provide a list of bullet points and some basic information for an e-mail. The assistant will generate an e-mail based on that input. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::EMAIL::ASSISTANTEMAIL::T1143222914"] = "Provide a list of bullet points and some basic information for an e-mail. The assistant will generate an e-mail based on that input." @@ -4029,33 +4047,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDATASOURCES::T774473 -- Local Directory UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDATASOURCES::T926703547"] = "Local Directory" --- Assistant: Document Analysis -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T1372406750"] = "Assistant: Document Analysis" - --- Most document analysis options can be customized and saved directly in the assistant. For this, the assistant has an auto-save function. -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T1870328357"] = "Most document analysis options can be customized and saved directly in the assistant. For this, the assistant has an auto-save function." - --- Would you like to preselect one of your profiles? -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2221665527"] = "Would you like to preselect one of your profiles?" - --- Preselect document analysis options? -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2230062650"] = "Preselect document analysis options?" - --- When enabled, you can preselect some document analysis options. -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2301091111"] = "When enabled, you can preselect some document analysis options." - --- No document analysis options are preselected -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3317802895"] = "No document analysis options are preselected" - --- Close -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3448155331"] = "Close" - --- Document analysis options are preselected -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3945756386"] = "Document analysis options are preselected" - --- Preselect one of your profiles? -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T4004501229"] = "Preselect one of your profiles?" - -- When enabled, you can preselect some ERI server options. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGERISERVER::T1280666275"] = "When enabled, you can preselect some ERI server options." diff --git a/app/MindWork AI Studio/Settings/ChatTemplate.cs b/app/MindWork AI Studio/Settings/ChatTemplate.cs index 5f3c597a..78879a62 100644 --- a/app/MindWork AI Studio/Settings/ChatTemplate.cs +++ b/app/MindWork AI Studio/Settings/ChatTemplate.cs @@ -107,7 +107,7 @@ public record ChatTemplate( template = new ChatTemplate { - Num = 0, + Num = 0, // will be set later by the PluginConfigurationObject Id = id.ToString(), Name = name, SystemPrompt = systemPrompt, diff --git a/app/MindWork AI Studio/Settings/DataModel/Data.cs b/app/MindWork AI Studio/Settings/DataModel/Data.cs index 622d737e..f174d6c2 100644 --- a/app/MindWork AI Studio/Settings/DataModel/Data.cs +++ b/app/MindWork AI Studio/Settings/DataModel/Data.cs @@ -80,6 +80,11 @@ public sealed class Data /// The next chat template number to use. /// public uint NextChatTemplateNum { get; set; } = 1; + + /// + /// The next document analysis policy number to use. + /// + public uint NextDocumentAnalysisPolicyNum { get; set; } = 1; public DataApp App { get; init; } = new(x => x.App); diff --git a/app/MindWork AI Studio/Settings/DataModel/DataDocumentAnalysisPolicy.cs b/app/MindWork AI Studio/Settings/DataModel/DataDocumentAnalysisPolicy.cs index aae8ede1..f2cbcfea 100644 --- a/app/MindWork AI Studio/Settings/DataModel/DataDocumentAnalysisPolicy.cs +++ b/app/MindWork AI Studio/Settings/DataModel/DataDocumentAnalysisPolicy.cs @@ -1,16 +1,37 @@ using AIStudio.Provider; +using AIStudio.Tools.PluginSystem; + +using Lua; namespace AIStudio.Settings.DataModel; -public sealed class DataDocumentAnalysisPolicy +public sealed record DataDocumentAnalysisPolicy : ConfigurationBaseObject { + private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger(); + + /// + public override string Id { get; init; } = string.Empty; + + /// + public override uint Num { get; init; } + + /// + public override string Name + { + get => this.PolicyName; + init => this.PolicyName = value; + } + + /// + public override bool IsEnterpriseConfiguration { get; init; } + /// - /// Preselect the policy name? + /// The name of the document analysis policy. /// public string PolicyName { get; set; } = string.Empty; /// - /// Preselect the policy description? + /// The description of the document analysis policy. /// public string PolicyDescription { get; set; } = string.Empty; @@ -18,12 +39,9 @@ public sealed class DataDocumentAnalysisPolicy /// Is this policy protected? If so, it cannot be deleted or modified by the user. /// public bool IsProtected { get; set; } - - /// - /// Is this a managed policy? Managed policies are created and managed by the organization - /// and cannot be modified or deleted by the user. - /// - public bool IsManaged { get; set; } + + /// + public override Guid EnterpriseConfigurationPluginId { get; init; } = Guid.Empty; /// /// The rules for the document analysis policy. @@ -49,4 +67,86 @@ public sealed class DataDocumentAnalysisPolicy /// Preselect a profile? /// public string PreselectedProfile { get; set; } = string.Empty; + + /// + /// Hide the policy definition section in the UI? + /// If true, the policy definition panel will be hidden and only the document selection will be shown. + /// This is useful for enterprise configurations where users should not see or modify the policy details. + /// + public bool HidePolicyDefinition { get; set; } + + public static bool TryProcessConfiguration(int idx, LuaTable table, Guid configPluginId, out ConfigurationBaseObject policy) + { + policy = new DataDocumentAnalysisPolicy(); + if (!table.TryGetValue("Id", out var idValue) || !idValue.TryRead(out var idText) || !Guid.TryParse(idText, out var id)) + { + LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain a valid ID. The ID must be a valid GUID.", idx); + return false; + } + + if (!table.TryGetValue("PolicyName", out var nameValue) || !nameValue.TryRead(out var name) || string.IsNullOrWhiteSpace(name)) + { + LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain a valid PolicyName field.", idx); + return false; + } + + if (!table.TryGetValue("PolicyDescription", out var descriptionValue) || !descriptionValue.TryRead(out var description) || string.IsNullOrWhiteSpace(description)) + { + LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain a valid PolicyDescription field.", idx); + return false; + } + + if (!table.TryGetValue("AnalysisRules", out var analysisRulesValue) || !analysisRulesValue.TryRead(out var analysisRules) || string.IsNullOrWhiteSpace(analysisRules)) + { + LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain valid AnalysisRules field.", idx); + return false; + } + + if (!table.TryGetValue("OutputRules", out var outputRulesValue) || !outputRulesValue.TryRead(out var outputRules) || string.IsNullOrWhiteSpace(outputRules)) + { + LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain valid OutputRules field.", idx); + return false; + } + + var minimumConfidence = ConfidenceLevel.NONE; + if (table.TryGetValue("MinimumProviderConfidence", out var minConfValue) && minConfValue.TryRead(out var minConfText)) + { + if (!Enum.TryParse(minConfText, true, out minimumConfidence)) + { + LOG.LogWarning("The configured document analysis policy {PolicyIndex} contains an invalid MinimumProviderConfidence: {ConfidenceLevel}.", idx, minConfText); + minimumConfidence = ConfidenceLevel.NONE; + } + } + + var preselectedProvider = string.Empty; + if (table.TryGetValue("PreselectedProvider", out var providerValue) && providerValue.TryRead(out var providerId)) + preselectedProvider = providerId; + + var preselectedProfile = string.Empty; + if (table.TryGetValue("PreselectedProfile", out var profileValue) && profileValue.TryRead(out var profileId)) + preselectedProfile = profileId; + + var hidePolicyDefinition = false; + if (table.TryGetValue("HidePolicyDefinition", out var hideValue) && hideValue.TryRead(out var hide)) + hidePolicyDefinition = hide; + + policy = new DataDocumentAnalysisPolicy + { + Id = id.ToString(), + Num = 0, // will be set later by the PluginConfigurationObject + PolicyName = name, + PolicyDescription = description, + AnalysisRules = analysisRules, + OutputRules = outputRules, + MinimumProviderConfidence = minimumConfidence, + PreselectedProvider = preselectedProvider, + PreselectedProfile = preselectedProfile, + HidePolicyDefinition = hidePolicyDefinition, + IsProtected = true, + IsEnterpriseConfiguration = true, + EnterpriseConfigurationPluginId = configPluginId, + }; + + return true; + } } \ No newline at end of file diff --git a/app/MindWork AI Studio/Settings/EmbeddingProvider.cs b/app/MindWork AI Studio/Settings/EmbeddingProvider.cs index c5e48d4f..e88831f0 100644 --- a/app/MindWork AI Studio/Settings/EmbeddingProvider.cs +++ b/app/MindWork AI Studio/Settings/EmbeddingProvider.cs @@ -98,7 +98,7 @@ public sealed record EmbeddingProvider( provider = new EmbeddingProvider { - Num = 0, + Num = 0, // will be set later by the PluginConfigurationObject Id = id.ToString(), Name = name, UsedLLMProvider = usedLLMProvider, diff --git a/app/MindWork AI Studio/Settings/Profile.cs b/app/MindWork AI Studio/Settings/Profile.cs index 9d0eddfd..ac657ba6 100644 --- a/app/MindWork AI Studio/Settings/Profile.cs +++ b/app/MindWork AI Studio/Settings/Profile.cs @@ -122,7 +122,7 @@ public record Profile( template = new Profile { - Num = 0, + Num = 0, // will be set later by the PluginConfigurationObject Id = id.ToString(), Name = name, NeedToKnow = needToKnow, diff --git a/app/MindWork AI Studio/Settings/Provider.cs b/app/MindWork AI Studio/Settings/Provider.cs index 82340485..89a0dbbd 100644 --- a/app/MindWork AI Studio/Settings/Provider.cs +++ b/app/MindWork AI Studio/Settings/Provider.cs @@ -143,7 +143,7 @@ public sealed record Provider( provider = new Provider { - Num = 0, + Num = 0, // will be set later by the PluginConfigurationObject Id = id.ToString(), InstanceName = instanceName, UsedLLMProvider = usedLLMProvider, diff --git a/app/MindWork AI Studio/Settings/TranscriptionProvider.cs b/app/MindWork AI Studio/Settings/TranscriptionProvider.cs index 02b20792..7a5f2ef5 100644 --- a/app/MindWork AI Studio/Settings/TranscriptionProvider.cs +++ b/app/MindWork AI Studio/Settings/TranscriptionProvider.cs @@ -98,7 +98,7 @@ public sealed record TranscriptionProvider( provider = new TranscriptionProvider { - Num = 0, + Num = 0, // will be set later by the PluginConfigurationObject Id = id.ToString(), Name = name, UsedLLMProvider = usedLLMProvider, diff --git a/app/MindWork AI Studio/Tools/ComponentsExtensions.cs b/app/MindWork AI Studio/Tools/ComponentsExtensions.cs index 54eb2cfa..721ae79d 100644 --- a/app/MindWork AI Studio/Tools/ComponentsExtensions.cs +++ b/app/MindWork AI Studio/Tools/ComponentsExtensions.cs @@ -16,6 +16,7 @@ public static class ComponentsExtensions Components.ERI_ASSISTANT => false, Components.BIAS_DAY_ASSISTANT => false, Components.I18N_ASSISTANT => false, + Components.DOCUMENT_ANALYSIS_ASSISTANT => false, Components.APP_SETTINGS => false, @@ -87,8 +88,9 @@ public static class ComponentsExtensions Components.BIAS_DAY_ASSISTANT => settingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions ? settingsManager.ConfigurationData.BiasOfTheDay.MinimumProviderConfidence : default, Components.ERI_ASSISTANT => settingsManager.ConfigurationData.ERI.PreselectOptions ? settingsManager.ConfigurationData.ERI.MinimumProviderConfidence : default, - #warning Add minimum confidence for DOCUMENT_ANALYSIS_ASSISTANT: - //Components.DOCUMENT_ANALYSIS_ASSISTANT => settingsManager.ConfigurationData.DocumentAnalysis.PreselectOptions ? settingsManager.ConfigurationData.DocumentAnalysis.MinimumProviderConfidence : default, + // The minimum confidence for the Document Analysis Assistant is set per policy. + // We do this inside the Document Analysis Assistant component: + Components.DOCUMENT_ANALYSIS_ASSISTANT => ConfidenceLevel.NONE, _ => default, }; @@ -114,8 +116,9 @@ public static class ComponentsExtensions Components.ERI_ASSISTANT => settingsManager.ConfigurationData.ERI.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.ERI.PreselectedProvider) : null, Components.I18N_ASSISTANT => settingsManager.ConfigurationData.I18N.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.I18N.PreselectedProvider) : null, - #warning Add preselected provider for DOCUMENT_ANALYSIS_ASSISTANT: - //Components.DOCUMENT_ANALYSIS_ASSISTANT => settingsManager.ConfigurationData.DocumentAnalysis.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.DocumentAnalysis.PreselectedProvider) : null, + // The Document Analysis Assistant does not have a preselected provider at the component level. + // The provider is selected per policy instead. We do this inside the Document Analysis Assistant component. + Components.DOCUMENT_ANALYSIS_ASSISTANT => Settings.Provider.NONE, Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedProvider) : null, @@ -131,8 +134,6 @@ public static class ComponentsExtensions public static Profile PreselectedProfile(this Components component, SettingsManager settingsManager) => component switch { - #warning Add preselected profile for DOCUMENT_ANALYSIS_ASSISTANT: - // Components.DOCUMENT_ANALYSIS_ASSISTANT => settingsManager.ConfigurationData.DocumentAnalysis.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.DocumentAnalysis.PreselectedProfile) : default, Components.AGENDA_ASSISTANT => settingsManager.ConfigurationData.Agenda.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Agenda.PreselectedProfile) ?? Profile.NO_PROFILE : Profile.NO_PROFILE, Components.CODING_ASSISTANT => settingsManager.ConfigurationData.Coding.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Coding.PreselectedProfile) ?? Profile.NO_PROFILE : Profile.NO_PROFILE, Components.EMAIL_ASSISTANT => settingsManager.ConfigurationData.EMail.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.EMail.PreselectedProfile) ?? Profile.NO_PROFILE : Profile.NO_PROFILE, @@ -141,6 +142,10 @@ public static class ComponentsExtensions Components.BIAS_DAY_ASSISTANT => settingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.BiasOfTheDay.PreselectedProfile) ?? Profile.NO_PROFILE : Profile.NO_PROFILE, Components.ERI_ASSISTANT => settingsManager.ConfigurationData.ERI.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.ERI.PreselectedProfile) ?? Profile.NO_PROFILE : Profile.NO_PROFILE, + // 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: + Components.DOCUMENT_ANALYSIS_ASSISTANT => Profile.NO_PROFILE, + Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedProfile) ?? Profile.NO_PROFILE : Profile.NO_PROFILE, _ => Profile.NO_PROFILE, diff --git a/app/MindWork AI Studio/Tools/PluginSystem/PluginConfiguration.cs b/app/MindWork AI Studio/Tools/PluginSystem/PluginConfiguration.cs index e85c8eba..29d95e76 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/PluginConfiguration.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/PluginConfiguration.cs @@ -88,6 +88,9 @@ public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginT // Handle configured profiles: PluginConfigurationObject.TryParse(PluginConfigurationObjectType.PROFILE, x => x.Profiles, x => x.NextProfileNum, mainTable, this.Id, ref this.configObjects, dryRun); + // Handle configured document analysis policies: + PluginConfigurationObject.TryParse(PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY, x => x.DocumentAnalysis.Policies, x => x.NextDocumentAnalysisPolicyNum, mainTable, this.Id, ref this.configObjects, dryRun); + // Config: preselected profile? ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.PreselectedProfile, Guid.Empty, this.Id, settingsTable, dryRun); diff --git a/app/MindWork AI Studio/Tools/PluginSystem/PluginConfigurationObject.cs b/app/MindWork AI Studio/Tools/PluginSystem/PluginConfigurationObject.cs index da5c46c2..647c79bf 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/PluginConfigurationObject.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/PluginConfigurationObject.cs @@ -70,6 +70,7 @@ public sealed record PluginConfigurationObject PluginConfigurationObjectType.EMBEDDING_PROVIDER => "EMBEDDING_PROVIDERS", PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER => "TRANSCRIPTION_PROVIDERS", PluginConfigurationObjectType.PROFILE => "PROFILES", + PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY => "DOCUMENT_ANALYSIS_POLICIES", _ => null, }; @@ -105,6 +106,7 @@ public sealed record PluginConfigurationObject PluginConfigurationObjectType.PROFILE => (Profile.TryParseProfileTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != Profile.NO_PROFILE, configurationObject), PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER => (TranscriptionProvider.TryParseTranscriptionProviderTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != TranscriptionProvider.NONE, configurationObject), PluginConfigurationObjectType.EMBEDDING_PROVIDER => (EmbeddingProvider.TryParseEmbeddingProviderTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != EmbeddingProvider.NONE, configurationObject), + PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY => (DataDocumentAnalysisPolicy.TryProcessConfiguration(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject is DataDocumentAnalysisPolicy, configurationObject), _ => (false, NoConfigurationObject.INSTANCE) }; diff --git a/app/MindWork AI Studio/Tools/PluginSystem/PluginConfigurationObjectType.cs b/app/MindWork AI Studio/Tools/PluginSystem/PluginConfigurationObjectType.cs index 82931873..4236af12 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/PluginConfigurationObjectType.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/PluginConfigurationObjectType.cs @@ -11,4 +11,5 @@ public enum PluginConfigurationObjectType CHAT_TEMPLATE, EMBEDDING_PROVIDER, TRANSCRIPTION_PROVIDER, + DOCUMENT_ANALYSIS_POLICY, } \ No newline at end of file diff --git a/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs b/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs index bdfdba81..b2b45aba 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs @@ -148,6 +148,10 @@ public static partial class PluginFactory // Check profiles: if(PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.PROFILE, x => x.Profiles, AVAILABLE_PLUGINS, configObjectList)) wasConfigurationChanged = true; + + // Check document analysis policies: + if(PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY, x => x.DocumentAnalysis.Policies, AVAILABLE_PLUGINS, configObjectList)) + wasConfigurationChanged = true; // Check for a preselected profile: if(ManagedConfiguration.IsConfigurationLeftOver(x => x.App, x => x.PreselectedProfile, AVAILABLE_PLUGINS)) diff --git a/app/MindWork AI Studio/wwwroot/changelog/v26.2.1.md b/app/MindWork AI Studio/wwwroot/changelog/v26.2.1.md index 13dde977..4cd8fdb9 100644 --- a/app/MindWork AI Studio/wwwroot/changelog/v26.2.1.md +++ b/app/MindWork AI Studio/wwwroot/changelog/v26.2.1.md @@ -1,2 +1,6 @@ # v26.2.1, build 233 (2026-02-xx xx:xx UTC) +- Added the ability to individually configure the minimum confidence level, standard profile, and default provider for each policy in the Document Analysis Assistant (in preview). +- Added support for defining document analysis policies (in preview) by configuration plugins, enabling centralized management of policies across entire departments or organizations. +- Added an option to hide the policy definition in the Document Analysis Assistant (in preview) when exporting and distributing that policy by a configuration plugin in organizations, making it easier for users to use. +- Added the policy export functionality to the Document Analysis Assistant (in preview). You can now export policies as Lua code for a configuration plugin to distribute the policy across your organization. - Fixed a bug where the global minimum confidence level was not being applied to the assistants. \ No newline at end of file