From 88999d985c14d269a398f5f96ff603bf7b964e3b Mon Sep 17 00:00:00 2001 From: PaulKoudelka Date: Fri, 14 Aug 2026 12:03:16 +0200 Subject: [PATCH] refactored confidence levels and ensured checks work --- .../Agents/AgentDataSourceSelection.cs | 8 +- .../Agents/AgentRetrievalContextValidation.cs | 10 +- .../Assistants/I18N/allTexts.lua | 68 ++++++-------- app/MindWork AI Studio/Chat/ChatThread.cs | 2 +- .../Chat/ChatThreadExtensions.cs | 4 +- app/MindWork AI Studio/Chat/ContentText.cs | 2 +- .../Components/ChatComponent.razor | 2 +- .../Components/DataSourceSelection.razor | 28 +++--- .../Components/DataSourceSelection.razor.cs | 10 +- .../Dialogs/DataSourceERI_V1Dialog.razor | 10 -- .../Dialogs/DataSourceERI_V1Dialog.razor.cs | 5 - .../Dialogs/DataSourceERI_V1InfoDialog.razor | 2 - .../DataSourceLocalDirectoryDialog.razor | 4 +- .../DataSourceLocalDirectoryDialog.razor.cs | 12 +-- .../DataSourceLocalDirectoryInfoDialog.razor | 2 +- .../Dialogs/DataSourceLocalFileDialog.razor | 4 +- .../DataSourceLocalFileDialog.razor.cs | 12 +-- .../DataSourceLocalFileInfoDialog.razor | 2 +- .../Plugins/configuration/plugin.lua | 4 - .../plugin.lua | 53 +++++------ .../plugin.lua | 47 +++++----- .../ConfigurationSelectDataFactory.cs | 2 +- .../Settings/DataModel/DataSourceERI_V1.cs | 16 ---- .../DataModel/DataSourceLocalDirectory.cs | 5 +- .../Settings/DataModel/DataSourceLocalFile.cs | 5 +- .../DataSourceSecurityTrustExtensions.cs | 37 +++----- .../Settings/IDataSource.cs | 11 --- .../Settings/IExternalDataSource.cs | 7 ++ .../Settings/IInternalDataSource.cs | 7 ++ .../EmbeddingState/EmbeddingStateClient.cs | 8 +- .../EmbeddingState/EmbeddingStateDbContext.cs | 14 +-- .../20260804000000_InitialRagIndex.cs | 8 +- .../EmbeddingStateDbContextModelSnapshot.cs | 16 ++-- ...qliteEmbeddingStateClientImplementation.cs | 12 +-- .../VectorStore/VectorSearchResult.cs | 4 +- .../VectorStore/VectorStoragePoint.cs | 4 +- .../AugmentationProcesses/AugmentationOne.cs | 4 +- .../RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs | 18 ++-- .../DataSourceEmbeddingService.Files.cs | 14 +-- .../Services/DataSourceEmbeddingService.cs | 22 +++-- .../DataSourceLocalRetrievalService.cs | 12 +-- .../Tools/Services/DataSourceService.cs | 94 +++++++++++++++---- .../Tools/Validation/DataSourceValidation.cs | 32 +++---- runtime/src/qdrant_edge_database.rs | 16 ++-- 44 files changed, 324 insertions(+), 335 deletions(-) diff --git a/app/MindWork AI Studio/Agents/AgentDataSourceSelection.cs b/app/MindWork AI Studio/Agents/AgentDataSourceSelection.cs index c7743252..dc7c295c 100644 --- a/app/MindWork AI Studio/Agents/AgentDataSourceSelection.cs +++ b/app/MindWork AI Studio/Agents/AgentDataSourceSelection.cs @@ -141,17 +141,17 @@ public sealed class AgentDataSourceSelection (ILogger // We start with the provider currently selected by the user: var requiredDataSecurity = dataSources.AllowedDataSources.GetRequiredSecurityPolicy(); - var requiredComplianceLevel = dataSources.AllowedDataSources.GetRequiredComplianceLevel(); - var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_DATA_SOURCE_SELECTION, provider.Id, true); + var requiredConfidenceLevel = dataSources.AllowedDataSources.GetRequiredConfidenceLevel(); + var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_DATA_SOURCE_SELECTION, provider.ConfiguredProviderId, true); if (agentProvider == Settings.Provider.NONE) { logger.LogWarning("No provider is selected for the agent. The agent cannot select data sources."); return []; } - if (!agentProvider.AllowsDataSourceAccess(this.SettingsManager, requiredDataSecurity, requiredComplianceLevel)) + if (!agentProvider.AllowsDataSourceAccess(this.SettingsManager, requiredDataSecurity, requiredConfidenceLevel)) { - logger.LogWarning($"The agent for data source selection uses provider '{agentProvider.InstanceName}' with confidence '{agentProvider.GetConfidenceLevel(this.SettingsManager).GetName()}', but the available data sources require data security '{requiredDataSecurity}' and provider confidence '{requiredComplianceLevel.GetName()}'. The agent cannot select data sources."); + logger.LogWarning($"The agent for data source selection uses provider '{agentProvider.InstanceName}' with confidence '{agentProvider.GetConfidenceLevel(this.SettingsManager).GetName()}', but the available data sources require data security '{requiredDataSecurity}' and provider confidence '{requiredConfidenceLevel.GetName()}'. The agent cannot select data sources."); return []; } diff --git a/app/MindWork AI Studio/Agents/AgentRetrievalContextValidation.cs b/app/MindWork AI Studio/Agents/AgentRetrievalContextValidation.cs index a0fd5be6..c10ad6bc 100644 --- a/app/MindWork AI Studio/Agents/AgentRetrievalContextValidation.cs +++ b/app/MindWork AI Studio/Agents/AgentRetrievalContextValidation.cs @@ -131,11 +131,11 @@ public sealed class AgentRetrievalContextValidation (ILogger /// The current LLM provider. When the user doesn't preselect an agent provider, the agent uses this provider. /// The data security required by the retrieved data. - /// The minimum provider confidence required by the retrieved data. - public bool SetLLMProvider(IProvider provider, DataSourceSecurity requiredDataSecurity = DataSourceSecurity.NOT_SPECIFIED, ConfidenceLevel requiredComplianceLevel = ConfidenceLevel.NONE) + /// The minimum provider confidence required by the retrieved data. + public bool SetLLMProvider(IProvider provider, DataSourceSecurity requiredDataSecurity = DataSourceSecurity.NOT_SPECIFIED, ConfidenceLevel requiredConfidenceLevel = ConfidenceLevel.NONE) { // We start with the provider currently selected by the user: - var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION, provider.Id, true); + var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION, provider.ConfiguredProviderId, true); if (agentProvider == Settings.Provider.NONE) { logger.LogWarning("No provider is selected for the agent."); @@ -143,9 +143,9 @@ public sealed class AgentRetrievalContextValidation (ILogger /// The minimum provider confidence required by data sources used so far. /// - public ConfidenceLevel DataComplianceLevel { get; set; } = ConfidenceLevel.NONE; + public ConfidenceLevel DataConfidenceLevel { get; set; } = ConfidenceLevel.NONE; /// /// The name of the chat thread. Usually generated by an AI model or manually edited by the user. diff --git a/app/MindWork AI Studio/Chat/ChatThreadExtensions.cs b/app/MindWork AI Studio/Chat/ChatThreadExtensions.cs index 4d673cfd..73a8bbb6 100644 --- a/app/MindWork AI Studio/Chat/ChatThreadExtensions.cs +++ b/app/MindWork AI Studio/Chat/ChatThreadExtensions.cs @@ -16,7 +16,7 @@ public static class ChatThreadExtensions /// One thing which is not so obvious: after RAG was used on this thread, the entire chat /// thread is kind of a data source by itself. Why? Because the augmentation data collected /// from the data sources is stored in the chat thread. This means we must check if the - /// selected provider is allowed to use this thread's data security and compliance level. + /// selected provider is allowed to use this thread's data security and confidence level. /// /// The chat thread to check. /// The provider to check. @@ -36,7 +36,7 @@ public static class ChatThreadExtensions _ => ConfidenceLevel.NONE, }; - if (!providerConfidenceLevel.AllowsDataSourceComplianceLevel(chatThread.DataComplianceLevel)) + if (!providerConfidenceLevel.AllowsDataSourceConfidenceLevel(chatThread.DataConfidenceLevel)) return false; // The chat thread is available, but the data security is not specified. diff --git a/app/MindWork AI Studio/Chat/ContentText.cs b/app/MindWork AI Studio/Chat/ContentText.cs index f57054e8..bacb3386 100644 --- a/app/MindWork AI Studio/Chat/ContentText.cs +++ b/app/MindWork AI Studio/Chat/ContentText.cs @@ -57,7 +57,7 @@ public sealed class ContentText : IContent if(!chatThread.IsLLMProviderAllowed(provider)) { - LOGGER.LogError("The provider is not allowed for this chat thread due to data security or compliance reasons. Skipping the AI process."); + LOGGER.LogError("The provider is not allowed for this chat thread due to data security or confidence-level requirements. Skipping the AI process."); await this.CompleteWithoutStreaming(); return chatThread; } diff --git a/app/MindWork AI Studio/Components/ChatComponent.razor b/app/MindWork AI Studio/Components/ChatComponent.razor index 7a829d61..32573793 100644 --- a/app/MindWork AI Studio/Components/ChatComponent.razor +++ b/app/MindWork AI Studio/Components/ChatComponent.razor @@ -147,7 +147,7 @@ @if (!this.ChatThread.IsLLMProviderAllowed(this.Provider)) { - + } diff --git a/app/MindWork AI Studio/Components/DataSourceSelection.razor b/app/MindWork AI Studio/Components/DataSourceSelection.razor index 08ae07ec..c1ef70f1 100644 --- a/app/MindWork AI Studio/Components/DataSourceSelection.razor +++ b/app/MindWork AI Studio/Components/DataSourceSelection.razor @@ -71,7 +71,7 @@ { case true when this.availableDataSources.Count == 0: - @T("Your data sources cannot be used with the LLM provider you selected due to data privacy or compliance requirements, or they are currently unavailable.") + @T("Your data sources cannot be used with the selected providers due to data privacy or confidence-level requirements, or they are currently unavailable.") break; @@ -83,7 +83,7 @@ case false when this.availableDataSources.Count == 0: - @T("Your data sources cannot be used with the LLM provider you selected due to data privacy or compliance requirements, or they are currently unavailable.") + @T("Your data sources cannot be used with the selected providers due to data privacy or confidence-level requirements, or they are currently unavailable.") break; @@ -97,11 +97,11 @@ @source.Name - @if (source is IInternalDataSource) + @if (source is IInternalDataSource internalSource) { - - + + } @@ -122,11 +122,11 @@ @source.Name - @if (source is IInternalDataSource) + @if (source is IInternalDataSource internalSource) { - - + + } @@ -144,11 +144,11 @@ @source.DataSource.Name - @if (source.DataSource is IInternalDataSource) + @if (source.DataSource is IInternalDataSource internalSource) { - - + + } @@ -206,11 +206,11 @@ else if (this.SelectionMode is DataSourceSelectionMode.CONFIGURATION_MODE) @source.Name - @if (source is IInternalDataSource) + @if (source is IInternalDataSource internalSource) { - - + + } diff --git a/app/MindWork AI Studio/Components/DataSourceSelection.razor.cs b/app/MindWork AI Studio/Components/DataSourceSelection.razor.cs index 50e7164d..9ad90e26 100644 --- a/app/MindWork AI Studio/Components/DataSourceSelection.razor.cs +++ b/app/MindWork AI Studio/Components/DataSourceSelection.razor.cs @@ -143,7 +143,7 @@ public partial class DataSourceSelection : MSGComponentBase private string GetAIReasoning(DataSourceAgentSelected source) => $"AI reasoning (confidence {source.AIDecision.Confidence:P0}): {source.AIDecision.Reason}"; - private string GetConfidenceIconStyle(IDataSource source) => $"{source.ComplianceLevel.SetColorStyle(this.SettingsManager)} flex-shrink: 0;"; + private string GetConfidenceIconStyle(IInternalDataSource source) => $"{source.ConfidenceLevel.SetColorStyle(this.SettingsManager)} flex-shrink: 0;"; public void ChangeOptionWithoutSaving(DataSourceOptions options, IReadOnlyList? aiSelectedDataSources = null) { @@ -201,7 +201,7 @@ public partial class DataSourceSelection : MSGComponentBase this.StateHasChanged(); // Load the data sources: - var sources = await this.DataSourceService.GetDataSources(this.LLMProvider, this.selectedDataSources); + var sources = await this.DataSourceService.GetDataSources(this.LLMProvider, this.DataSourceOptions, this.selectedDataSources); if (generation != this.loadAndApplyFiltersGeneration) return; @@ -225,7 +225,8 @@ public partial class DataSourceSelection : MSGComponentBase { this.aiBasedSourceSelection = state; this.DataSourceOptions.AutomaticDataSourceSelection = this.aiBasedSourceSelection; - + + await this.LoadAndApplyFilters(); await this.OptionsChanged(); } @@ -233,7 +234,8 @@ public partial class DataSourceSelection : MSGComponentBase { this.aiBasedValidation = state; this.DataSourceOptions.AutomaticValidation = this.aiBasedValidation; - + + await this.LoadAndApplyFilters(); await this.OptionsChanged(); } diff --git a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor index cc1af8df..3a3d4b00 100644 --- a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor +++ b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor @@ -1,6 +1,5 @@ @using AIStudio.Settings.DataModel @using AIStudio.Tools.Validation -@using AIStudio.Provider @using AIStudio.Tools.ERIClient.DataModel @inherits MSGComponentBase @@ -122,15 +121,6 @@ } - - @foreach (var level in this.ComplianceLevels) - { - - @level.Name - - } - - diff --git a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor.cs b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor.cs index cda00e32..843968d5 100644 --- a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor.cs +++ b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor.cs @@ -48,7 +48,6 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId private string dataEditingPreviousInstanceName = string.Empty; private List availableAuthMethods = []; private DataSourceSecurity dataSecurityPolicy; - private ConfidenceLevel dataComplianceLevel = ConfidenceLevel.UNKNOWN; private SecurityRequirements dataSourceSecurityRequirements; private ushort dataMaxMatches = 10; private bool connectionTested; @@ -108,7 +107,6 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId this.dataAuthMethod = this.DataSource.AuthMethod; this.dataUsername = this.DataSource.Username; this.dataSecurityPolicy = this.DataSource.SecurityPolicy; - this.dataComplianceLevel = this.DataSource.ComplianceLevel; this.dataMaxMatches = this.DataSource.MaxMatches; // We cannot load the retrieval processes now, since we have @@ -161,8 +159,6 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId #endregion - private IEnumerable> ComplianceLevels => ConfigurationSelectDataFactory.GetDataSourceComplianceLevelsData(); - private DataSourceERI_V1 CreateDataSource() { var cleanedHostname = this.dataHostname.Trim(); @@ -178,7 +174,6 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId UsernamePasswordMode = DataSourceERIUsernamePasswordMode.USER_MANAGED, Type = DataSourceType.ERI_V1, SecurityPolicy = this.dataSecurityPolicy, - ComplianceLevel = this.dataComplianceLevel, SelectedRetrievalId = this.dataSelectedRetrievalProcess.Id, MaxMatches = this.dataMaxMatches, }; diff --git a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1InfoDialog.razor b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1InfoDialog.razor index b35d183c..fa9766fe 100644 --- a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1InfoDialog.razor +++ b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1InfoDialog.razor @@ -1,5 +1,4 @@ @using AIStudio.Settings.DataModel -@using AIStudio.Provider @using AIStudio.Tools.ERIClient.DataModel @inherits MSGComponentBase @@ -28,7 +27,6 @@ - diff --git a/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryDialog.razor b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryDialog.razor index 0ffa4a08..370a52e0 100644 --- a/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryDialog.razor +++ b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryDialog.razor @@ -114,8 +114,8 @@ - - @foreach (var level in this.ComplianceLevels) + + @foreach (var level in this.ConfidenceLevels) { @level.Name diff --git a/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryDialog.razor.cs b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryDialog.razor.cs index ba88041e..5d0c9393 100644 --- a/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryDialog.razor.cs +++ b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryDialog.razor.cs @@ -49,7 +49,7 @@ public partial class DataSourceLocalDirectoryDialog : MSGComponentBase private int dataChunkOverlapTokenLength; private ushort dataMaxMatches = 10; private bool showExpertSettings; - private ConfidenceLevel dataComplianceLevel = ConfidenceLevel.UNKNOWN; + private ConfidenceLevel dataConfidenceLevel = ConfidenceLevel.UNKNOWN; // We get the form reference from Blazor code to validate it manually: private MudForm form = null!; @@ -60,8 +60,7 @@ public partial class DataSourceLocalDirectoryDialog : MSGComponentBase { GetSelectedCloudEmbedding = () => this.SelectedCloudEmbedding, GetSelectedEmbeddingProvider = () => this.SelectedEmbedding, - GetSecurityPolicy = () => DataSourceSecurity.ALLOW_ANY, - GetComplianceLevel = () => this.dataComplianceLevel, + GetConfidenceLevel = () => this.dataConfidenceLevel, GetSettingsManager = () => this.SettingsManager, GetPreviousDataSourceName = () => this.dataEditingPreviousInstanceName, GetUsedDataSourceNames = () => this.UsedDataSourcesNames, @@ -90,7 +89,7 @@ public partial class DataSourceLocalDirectoryDialog : MSGComponentBase this.dataPath = this.DataSource.Path; this.dataMaxChunkTokenLength = this.DataSource.MaxChunkTokenLength; this.dataChunkOverlapTokenLength = this.DataSource.ChunkOverlapTokenLength; - this.dataComplianceLevel = this.DataSource.ComplianceLevel; + this.dataConfidenceLevel = this.DataSource.ConfidenceLevel; this.dataMaxMatches = this.DataSource.MaxMatches; this.showExpertSettings = this.dataMaxChunkTokenLength > 0 || this.dataChunkOverlapTokenLength > 0; } @@ -117,7 +116,7 @@ public partial class DataSourceLocalDirectoryDialog : MSGComponentBase private bool CanChangeSourceAndEmbedding => !this.IsEditing || !this.LockSourceAndEmbedding; - private IEnumerable> ComplianceLevels => ConfigurationSelectDataFactory.GetDataSourceComplianceLevelsData(); + private IEnumerable> ConfidenceLevels => ConfigurationSelectDataFactory.GetDataSourceConfidenceLevelsData(); private string SelectedEmbeddingNameText { @@ -145,8 +144,7 @@ public partial class DataSourceLocalDirectoryDialog : MSGComponentBase Path = this.CanChangeSourceAndEmbedding ? this.dataPath : this.DataSource.Path, MaxChunkTokenLength = this.dataMaxChunkTokenLength, ChunkOverlapTokenLength = this.dataChunkOverlapTokenLength, - SecurityPolicy = DataSourceSecurity.ALLOW_ANY, - ComplianceLevel = this.dataComplianceLevel, + ConfidenceLevel = this.dataConfidenceLevel, MaxMatches = this.dataMaxMatches, }; diff --git a/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor index 0d4feace..8d82297d 100644 --- a/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor +++ b/app/MindWork AI Studio/Dialogs/DataSourceLocalDirectoryInfoDialog.razor @@ -38,7 +38,7 @@ } - + diff --git a/app/MindWork AI Studio/Dialogs/DataSourceLocalFileDialog.razor b/app/MindWork AI Studio/Dialogs/DataSourceLocalFileDialog.razor index 8248e8be..57e27e3c 100644 --- a/app/MindWork AI Studio/Dialogs/DataSourceLocalFileDialog.razor +++ b/app/MindWork AI Studio/Dialogs/DataSourceLocalFileDialog.razor @@ -114,8 +114,8 @@ - - @foreach (var level in this.ComplianceLevels) + + @foreach (var level in this.ConfidenceLevels) { @level.Name diff --git a/app/MindWork AI Studio/Dialogs/DataSourceLocalFileDialog.razor.cs b/app/MindWork AI Studio/Dialogs/DataSourceLocalFileDialog.razor.cs index a0491649..2bcfcb46 100644 --- a/app/MindWork AI Studio/Dialogs/DataSourceLocalFileDialog.razor.cs +++ b/app/MindWork AI Studio/Dialogs/DataSourceLocalFileDialog.razor.cs @@ -49,7 +49,7 @@ public partial class DataSourceLocalFileDialog : MSGComponentBase private int dataChunkOverlapTokenLength; private ushort dataMaxMatches = 10; private bool showExpertSettings; - private ConfidenceLevel dataComplianceLevel = ConfidenceLevel.UNKNOWN; + private ConfidenceLevel dataConfidenceLevel = ConfidenceLevel.UNKNOWN; // We get the form reference from Blazor code to validate it manually: private MudForm form = null!; @@ -60,8 +60,7 @@ public partial class DataSourceLocalFileDialog : MSGComponentBase { GetSelectedCloudEmbedding = () => this.SelectedCloudEmbedding, GetSelectedEmbeddingProvider = () => this.SelectedEmbedding, - GetSecurityPolicy = () => DataSourceSecurity.ALLOW_ANY, - GetComplianceLevel = () => this.dataComplianceLevel, + GetConfidenceLevel = () => this.dataConfidenceLevel, GetSettingsManager = () => this.SettingsManager, GetPreviousDataSourceName = () => this.dataEditingPreviousInstanceName, GetUsedDataSourceNames = () => this.UsedDataSourcesNames, @@ -90,7 +89,7 @@ public partial class DataSourceLocalFileDialog : MSGComponentBase this.dataFilePath = this.DataSource.FilePath; this.dataMaxChunkTokenLength = this.DataSource.MaxChunkTokenLength; this.dataChunkOverlapTokenLength = this.DataSource.ChunkOverlapTokenLength; - this.dataComplianceLevel = this.DataSource.ComplianceLevel; + this.dataConfidenceLevel = this.DataSource.ConfidenceLevel; this.dataMaxMatches = this.DataSource.MaxMatches; this.showExpertSettings = this.dataMaxChunkTokenLength > 0 || this.dataChunkOverlapTokenLength > 0; } @@ -117,7 +116,7 @@ public partial class DataSourceLocalFileDialog : MSGComponentBase private bool CanChangeSourceAndEmbedding => !this.IsEditing || !this.LockSourceAndEmbedding; - private IEnumerable> ComplianceLevels => ConfigurationSelectDataFactory.GetDataSourceComplianceLevelsData(); + private IEnumerable> ConfidenceLevels => ConfigurationSelectDataFactory.GetDataSourceConfidenceLevelsData(); private string SelectedEmbeddingNameText { @@ -145,8 +144,7 @@ public partial class DataSourceLocalFileDialog : MSGComponentBase FilePath = this.CanChangeSourceAndEmbedding ? this.dataFilePath : this.DataSource.FilePath, MaxChunkTokenLength = this.dataMaxChunkTokenLength, ChunkOverlapTokenLength = this.dataChunkOverlapTokenLength, - SecurityPolicy = DataSourceSecurity.ALLOW_ANY, - ComplianceLevel = this.dataComplianceLevel, + ConfidenceLevel = this.dataConfidenceLevel, MaxMatches = this.dataMaxMatches, }; diff --git a/app/MindWork AI Studio/Dialogs/DataSourceLocalFileInfoDialog.razor b/app/MindWork AI Studio/Dialogs/DataSourceLocalFileInfoDialog.razor index 37e58dff..e2d54b03 100644 --- a/app/MindWork AI Studio/Dialogs/DataSourceLocalFileInfoDialog.razor +++ b/app/MindWork AI Studio/Dialogs/DataSourceLocalFileInfoDialog.razor @@ -38,7 +38,7 @@ } - + diff --git a/app/MindWork AI Studio/Plugins/configuration/plugin.lua b/app/MindWork AI Studio/Plugins/configuration/plugin.lua index 12114275..e8d79111 100644 --- a/app/MindWork AI Studio/Plugins/configuration/plugin.lua +++ b/app/MindWork AI Studio/Plugins/configuration/plugin.lua @@ -162,7 +162,6 @@ CONFIG["EMBEDDING_PROVIDERS"] = {} -- ERI v1 data sources for retrieval-augmented generation: CONFIG["DATA_SOURCES"] = {} --- Allowed compliance levels are: UNTRUSTED, UNKNOWN, VERY_LOW, LOW, MODERATE, MEDIUM, HIGH -- Example: ERI v1 data source with a shared access token. -- CONFIG["DATA_SOURCES"][#CONFIG["DATA_SOURCES"]+1] = { @@ -174,7 +173,6 @@ CONFIG["DATA_SOURCES"] = {} -- ["AuthMethod"] = "TOKEN", -- ["Token"] = "ENC:v1:", -- ["SecurityPolicy"] = "SELF_HOSTED", --- ["ComplianceLevel"] = "UNKNOWN", -- ["SelectedRetrievalId"] = "", -- ["MaxMatches"] = 10, -- } @@ -191,7 +189,6 @@ CONFIG["DATA_SOURCES"] = {} -- ["Username"] = "", -- ["Password"] = "ENC:v1:", -- ["SecurityPolicy"] = "SELF_HOSTED", --- ["ComplianceLevel"] = "UNKNOWN", -- ["SelectedRetrievalId"] = "", -- ["MaxMatches"] = 10, -- } @@ -207,7 +204,6 @@ CONFIG["DATA_SOURCES"] = {} -- ["UsernamePasswordMode"] = "OS_USERNAME_SHARED_PASSWORD", -- ["Password"] = "ENC:v1:", -- ["SecurityPolicy"] = "SELF_HOSTED", --- ["ComplianceLevel"] = "UNKNOWN", -- ["SelectedRetrievalId"] = "", -- ["MaxMatches"] = 10, -- } 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 c06bef28..cb9d391d 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 @@ -3114,8 +3114,8 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2991985411"] = "Diesen Ch -- Move Chat to Workspace UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T3045856778"] = "Chat in den Arbeitsbereich verschieben" --- The selected provider is not allowed in this chat due to data security reasons. -UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T3403290862"] = "Der ausgewählte Anbieter ist aus Gründen der Datensicherheit in diesem Chat nicht erlaubt." +-- The selected provider is not allowed in this chat due to data security or confidence-level requirements. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2672162875"] = "Der ausgewählte Anbieter ist in diesem Chat aufgrund der Datensicherheit oder der Anforderungen an das Vertrauensniveau nicht zulässig." -- Select a provider first UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T3654197869"] = "Wähle zuerst einen Anbieter aus" @@ -3285,8 +3285,8 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T3100256862"] = "KI- -- No, I don't want to use data sources. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T3135725655"] = "Nein, ich möchte keine Datenquellen verwenden." --- Your data sources cannot be used with the LLM provider you selected due to data privacy, or they are currently unavailable. -UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T3215374102"] = "Ihre Datenquellen können mit dem von Ihnen ausgewählten LLM-Anbieter aufgrund von Datenschutzbestimmungen nicht verwendet werden oder sind derzeit nicht verfügbar." +-- Your data sources cannot be used with the selected providers due to data privacy or confidence-level requirements, or they are currently unavailable. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T2975936221"] = "Ihre Datenquellen können aufgrund von Datenschutz- oder Vertrauensniveauanforderungen nicht mit den ausgewählten Anbietern verwendet werden oder sind derzeit nicht verfügbar." -- No, I manually decide which data source to use. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T3440789294"] = "Nein, ich wähle die Datenquelle manuell aus." @@ -3910,10 +3910,10 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T922066419"] UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T929143445"] = "Die Optionen für die Administration sind nicht sichtbar." -- Show provider's confidence level? -UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T1052533048"] = "Anzeigen, wie sicher der Anbieter ist?" +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T1052533048"] = "Vertrauensniveau des Anbieters anzeigen?" -- Choose the scheme that best suits you and your organization. Do you trust any western provider? Or only providers from the USA or exclusively European providers? Then choose the appropriate scheme. Alternatively, you can assign the confidence levels to each provider yourself. -UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T1081931329"] = "Wählen Sie das Schema, das am besten zu Ihnen und Ihrer Organisation passt. Vertrauen Sie irgendeinem westlichen Anbieter? Oder nur Anbietern aus den USA oder ausschließlich europäischen Anbietern? Wählen Sie dann das passende Schema. Alternativ können Sie auch die Vertrauensstufen für jeden Anbieter eigenständig festlegen." +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T1081931329"] = "Wählen Sie das Schema, das am besten zu Ihnen und Ihrer Organisation passt. Vertrauen Sie irgendeinem westlichen Anbieter? Oder nur Anbietern aus den USA oder ausschließlich europäischen Anbietern? Wählen Sie dann das passende Schema. Alternativ können Sie auch die Vertrauensniveaus für jeden Anbieter eigenständig festlegen." -- Provider Confidence UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T1453422580"] = "Vertrauen in die Anbieter" @@ -3949,7 +3949,7 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T45885 UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T48051324"] = "Noch nicht konfiguriert" -- Do you want to always see how trustworthy your providers are? This way, you stay in control of which provider you send your data to. You can choose a common schema or configure the trust levels for each provider yourself. -UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T700839804"] = "Möchten Sie immer sehen, wie vertrauenswürdig Ihre Anbieter sind? So behalten Sie die Kontrolle darüber, an welchen Anbieter Sie Ihre Daten senden. Sie können ein gängiges Schema wählen oder die Vertrauensstufen für jeden Anbieter selbst festlegen." +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T700839804"] = "Möchten Sie immer sehen, wie vertrauenswürdig Ihre Anbieter sind? So behalten Sie die Kontrolle darüber, an welchen Anbieter Sie Ihre Daten senden. Sie können ein gängiges Schema wählen oder die Vertrauensniveaus für jeden Anbieter selbst festlegen." -- Yes, show me the confidence level UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCONFIDENCE::T853225204"] = "Ja, zeige mir das Vertrauensniveau" @@ -4827,9 +4827,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3804576966"] = "Por -- Connection failed. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3820825672"] = "Verbindung fehlgeschlagen." --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3995796156"] = "Compliance-Stufe" - -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T4081226330"] = "Ihre Sicherheitsrichtlinie" @@ -4947,9 +4944,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3448155331"] = -- ERI server port UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3843835535"] = "ERI-Server-Port" --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3995796156"] = "Compliance-Stufe" - -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T4081226330"] = "Ihre Sicherheitsrichtlinie" @@ -4965,9 +4959,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T470340825"] = " -- the security requirements of the data provider UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T503852885"] = "Die Sicherheitsanforderungen des Datenanbieters" --- the compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T607609781"] = "die Compliance-Stufe" - -- When to use UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T629595477"] = "Wann verwenden" @@ -5076,8 +5067,8 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3424652889" -- Please enter 0 or a positive token limit. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3659673500"] = "Bitte geben Sie 0 oder eine positive Token-Grenze ein." --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3995796156"] = "Compliance-Stufe" +-- Required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T236253137"] = "Erforderliches Vertrauensniveau des Anbieters" -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T4081226330"] = "Ihre Sicherheitsrichtlinie" @@ -5154,8 +5145,8 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3602384 -- Path UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3949388886"] = "Pfad" --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3995796156"] = "Compliance-Stufe" +-- Required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T236253137"] = "Erforderliches Vertrauensniveau des Anbieters" -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T4081226330"] = "Ihre Sicherheitsrichtlinie" @@ -5169,8 +5160,8 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T4438734 -- The directory chosen for the data source exists. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T445858624"] = "Das ausgewählte Verzeichnis für die Datenquelle ist vorhanden." --- the compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T607609781"] = "die Compliance-Stufe" +-- the required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T818422588"] = "das erforderliche Vertrauensniveau des Anbieters" -- Hide Expert Settings UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1108876344"] = "Experten-Einstellungen ausblenden" @@ -5247,8 +5238,8 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3659673500"] = " -- Select the file UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3740148848"] = "Datei auswählen" --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3995796156"] = "Compliance-Stufe" +-- Required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T236253137"] = "Erforderliches Vertrauensniveau des Anbieters" -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T4081226330"] = "Ihre Sicherheitsrichtlinie" @@ -5322,14 +5313,14 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3650018664"] -- The embedding runs in the cloud. All your data within the file '{0}' will be sent to the cloud. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3688254408"] = "Das Einbetten erfolgt in der Cloud. Alle ihre Daten in der Datei „{0}“ werden in die Cloud gesendet." --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3995796156"] = "Compliance-Stufe" +-- Required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T236253137"] = "Erforderliches Vertrauensniveau des Anbieters" -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T4081226330"] = "Ihre Sicherheitsrichtlinie" --- the compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T607609781"] = "die Compliance-Stufe" +-- the required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T818422588"] = "das erforderliche Vertrauensniveau des Anbieters" -- Markdown View UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1373123357"] = "Markdown-Ansicht" @@ -9987,6 +9978,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::USERFILE::T932243993"] = "Der Dateipfad ist le -- The hostname is not a valid HTTP(S) URL. UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "Der Hostname ist keine gültige HTTP(S)-URL." +-- Please select a required provider confidence level. +UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1120586536"] = "Bitte wählen Sie ein erforderliches Vertrauensniveau des Anbieters aus." + -- The connection test failed. Please check the connection settings. UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T132896331"] = "Der Verbindungstest ist fehlgeschlagen. Bitte überprüfe die Verbindungseinstellungen." @@ -10023,6 +10017,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T2250909198" -- Please test the connection before saving. UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T285470497"] = "Bitte testen Sie die Verbindung, bevor Sie speichern." +-- The selected embedding provider has confidence '{0}', but this data source requires provider confidence '{1}'. Select an embedding provider with equal or higher confidence or lower the required confidence level. +UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T2999173576"] = "Der ausgewählte Embedding-Anbieter hat das Vertrauensniveau '{0}', aber diese Datenquelle erfordert das Vertrauensniveau '{1}'. Wählen Sie einen Embedding-Anbieter mit gleichem oder höherem Vertrauensniveau oder senken Sie das erforderliche Vertrauensniveau." + -- Please enter your secure access token. UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T3086932434"] = "Bitte geben Sie ihren sicheren Zugangstoken ein." 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 9ed794c1..25e81661 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 @@ -3114,8 +3114,8 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2991985411"] = "Delete th -- Move Chat to Workspace UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T3045856778"] = "Move Chat to Workspace" --- The selected provider is not allowed in this chat due to data security reasons. -UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T3403290862"] = "The selected provider is not allowed in this chat due to data security reasons." +-- The selected provider is not allowed in this chat due to data security or confidence-level requirements. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2672162875"] = "The selected provider is not allowed in this chat due to data security or confidence-level requirements." -- Select a provider first UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T3654197869"] = "Select a provider first" @@ -3285,8 +3285,8 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T3100256862"] = "AI- -- No, I don't want to use data sources. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T3135725655"] = "No, I don't want to use data sources." --- Your data sources cannot be used with the LLM provider you selected due to data privacy, or they are currently unavailable. -UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T3215374102"] = "Your data sources cannot be used with the LLM provider you selected due to data privacy, or they are currently unavailable." +-- Your data sources cannot be used with the selected providers due to data privacy or confidence-level requirements, or they are currently unavailable. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T2975936221"] = "Your data sources cannot be used with the selected providers due to data privacy or confidence-level requirements, or they are currently unavailable." -- No, I manually decide which data source to use. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T3440789294"] = "No, I manually decide which data source to use." @@ -4827,9 +4827,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3804576966"] = "Por -- Connection failed. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3820825672"] = "Connection failed." --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3995796156"] = "Compliance level" - -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T4081226330"] = "Your security policy" @@ -4947,9 +4944,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3448155331"] = -- ERI server port UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3843835535"] = "ERI server port" --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3995796156"] = "Compliance level" - -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T4081226330"] = "Your security policy" @@ -4965,9 +4959,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T470340825"] = " -- the security requirements of the data provider UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T503852885"] = "the security requirements of the data provider" --- the compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T607609781"] = "the compliance level" - -- When to use UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T629595477"] = "When to use" @@ -5076,8 +5067,8 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3424652889" -- Please enter 0 or a positive token limit. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3659673500"] = "Please enter 0 or a positive token limit." --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3995796156"] = "Compliance level" +-- Required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T236253137"] = "Required provider confidence level" -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T4081226330"] = "Your security policy" @@ -5154,8 +5145,8 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3602384 -- Path UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3949388886"] = "Path" --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3995796156"] = "Compliance level" +-- Required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T236253137"] = "Required provider confidence level" -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T4081226330"] = "Your security policy" @@ -5169,8 +5160,8 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T4438734 -- The directory chosen for the data source exists. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T445858624"] = "The directory chosen for the data source exists." --- the compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T607609781"] = "the compliance level" +-- the required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T818422588"] = "the required provider confidence level" -- Hide Expert Settings UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1108876344"] = "Hide Expert Settings" @@ -5247,8 +5238,8 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3659673500"] = " -- Select the file UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3740148848"] = "Select the file" --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3995796156"] = "Compliance level" +-- Required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T236253137"] = "Required provider confidence level" -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T4081226330"] = "Your security policy" @@ -5322,14 +5313,14 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3650018664"] -- The embedding runs in the cloud. All your data within the file '{0}' will be sent to the cloud. UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3688254408"] = "The embedding runs in the cloud. All your data within the file '{0}' will be sent to the cloud." --- Compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3995796156"] = "Compliance level" +-- Required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T236253137"] = "Required provider confidence level" -- Your security policy UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T4081226330"] = "Your security policy" --- the compliance level -UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T607609781"] = "the compliance level" +-- the required provider confidence level +UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T818422588"] = "the required provider confidence level" -- Markdown View UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1373123357"] = "Markdown View" @@ -9987,6 +9978,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::USERFILE::T932243993"] = "The file path is nul -- The hostname is not a valid HTTP(S) URL. UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "The hostname is not a valid HTTP(S) URL." +-- Please select a required provider confidence level. +UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1120586536"] = "Please select a required provider confidence level." + -- The connection test failed. Please check the connection settings. UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T132896331"] = "The connection test failed. Please check the connection settings." @@ -10023,6 +10017,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T2250909198" -- Please test the connection before saving. UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T285470497"] = "Please test the connection before saving." +-- The selected embedding provider has confidence '{0}', but this data source requires provider confidence '{1}'. Select an embedding provider with equal or higher confidence or lower the required confidence level. +UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T2999173576"] = "The selected embedding provider has confidence '{0}', but this data source requires provider confidence '{1}'. Select an embedding provider with equal or higher confidence or lower the required confidence level." + -- Please enter your secure access token. UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T3086932434"] = "Please enter your secure access token." diff --git a/app/MindWork AI Studio/Settings/ConfigurationSelectDataFactory.cs b/app/MindWork AI Studio/Settings/ConfigurationSelectDataFactory.cs index 79b2789f..0f9e25ba 100644 --- a/app/MindWork AI Studio/Settings/ConfigurationSelectDataFactory.cs +++ b/app/MindWork AI Studio/Settings/ConfigurationSelectDataFactory.cs @@ -304,7 +304,7 @@ public static class ConfigurationSelectDataFactory } } - public static IEnumerable> GetDataSourceComplianceLevelsData() + public static IEnumerable> GetDataSourceConfidenceLevelsData() { foreach (var level in Enum.GetValues()) { diff --git a/app/MindWork AI Studio/Settings/DataModel/DataSourceERI_V1.cs b/app/MindWork AI Studio/Settings/DataModel/DataSourceERI_V1.cs index ca35d491..db1ef4e3 100644 --- a/app/MindWork AI Studio/Settings/DataModel/DataSourceERI_V1.cs +++ b/app/MindWork AI Studio/Settings/DataModel/DataSourceERI_V1.cs @@ -2,7 +2,6 @@ using AIStudio.Assistants.ERI; using AIStudio.Chat; -using AIStudio.Provider; using AIStudio.Tools.ERIClient; using AIStudio.Tools.ERIClient.DataModel; using AIStudio.Tools.PluginSystem; @@ -59,9 +58,6 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource /// public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED; - /// - public ConfidenceLevel ComplianceLevel { get; init; } = ConfidenceLevel.UNKNOWN; - /// public bool IsEnterpriseConfiguration { get; init; } @@ -211,16 +207,6 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource return false; } - var complianceLevel = ConfidenceLevel.UNKNOWN; - if (table.TryGetValue("ComplianceLevel", out var complianceLevelValue) && - (!complianceLevelValue.TryRead(out var complianceLevelText) || - !Enum.TryParse(complianceLevelText, true, out complianceLevel) || - complianceLevel is ConfidenceLevel.NONE)) - { - LOGGER.LogWarning($"The configured data source {idx} contains an invalid compliance level. Falling back to UNKNOWN. (Plugin ID: {configPluginId})"); - complianceLevel = ConfidenceLevel.UNKNOWN; - } - if (!table.TryGetValue("SelectedRetrievalId", out var selectedRetrievalIdValue) || !selectedRetrievalIdValue.TryRead(out var selectedRetrievalId) || string.IsNullOrWhiteSpace(selectedRetrievalId)) { LOGGER.LogWarning($"The configured data source {idx} must specify a selected retrieval ID. (Plugin ID: {configPluginId})"); @@ -278,7 +264,6 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource Username = username, UsernamePasswordMode = usernamePasswordMode, SecurityPolicy = securityPolicy, - ComplianceLevel = complianceLevel, Version = ERIVersion.V1, SelectedRetrievalId = selectedRetrievalId, MaxMatches = (ushort)maxMatches, @@ -339,7 +324,6 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource {{usernameLine}} {{secretLine}} ["SecurityPolicy"] = "{{this.SecurityPolicy}}", - ["ComplianceLevel"] = "{{this.ComplianceLevel}}", ["SelectedRetrievalId"] = "{{LuaTools.EscapeLuaString(this.SelectedRetrievalId)}}", ["MaxMatches"] = {{this.MaxMatches}}, } diff --git a/app/MindWork AI Studio/Settings/DataModel/DataSourceLocalDirectory.cs b/app/MindWork AI Studio/Settings/DataModel/DataSourceLocalDirectory.cs index c7d37140..f4216e62 100644 --- a/app/MindWork AI Studio/Settings/DataModel/DataSourceLocalDirectory.cs +++ b/app/MindWork AI Studio/Settings/DataModel/DataSourceLocalDirectory.cs @@ -42,10 +42,7 @@ public readonly record struct DataSourceLocalDirectory : IInternalDataSource public int ChunkOverlapTokenLength { get; init; } /// - public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.ALLOW_ANY; - - /// - public ConfidenceLevel ComplianceLevel { get; init; } = ConfidenceLevel.UNKNOWN; + public ConfidenceLevel ConfidenceLevel { get; init; } = ConfidenceLevel.UNKNOWN; /// public bool IsEnterpriseConfiguration { get; init; } diff --git a/app/MindWork AI Studio/Settings/DataModel/DataSourceLocalFile.cs b/app/MindWork AI Studio/Settings/DataModel/DataSourceLocalFile.cs index 20971a83..14fbe619 100644 --- a/app/MindWork AI Studio/Settings/DataModel/DataSourceLocalFile.cs +++ b/app/MindWork AI Studio/Settings/DataModel/DataSourceLocalFile.cs @@ -42,10 +42,7 @@ public readonly record struct DataSourceLocalFile : IInternalDataSource public int ChunkOverlapTokenLength { get; init; } /// - public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.ALLOW_ANY; - - /// - public ConfidenceLevel ComplianceLevel { get; init; } = ConfidenceLevel.UNKNOWN; + public ConfidenceLevel ConfidenceLevel { get; init; } = ConfidenceLevel.UNKNOWN; /// public bool IsEnterpriseConfiguration { get; init; } diff --git a/app/MindWork AI Studio/Settings/DataSourceSecurityTrustExtensions.cs b/app/MindWork AI Studio/Settings/DataSourceSecurityTrustExtensions.cs index f70216b9..4f368efa 100644 --- a/app/MindWork AI Studio/Settings/DataSourceSecurityTrustExtensions.cs +++ b/app/MindWork AI Studio/Settings/DataSourceSecurityTrustExtensions.cs @@ -61,30 +61,21 @@ public static class DataSourceSecurityTrustExtensions return provider.Provider.GetConfidence(settingsManager).Level; } - public static bool AllowsDataSourceAccess(this Provider provider, SettingsManager settingsManager, DataSourceSecurity dataSourceSecurity, ConfidenceLevel dataSourceComplianceLevel) + public static bool AllowsDataSourceAccess(this Provider provider, SettingsManager settingsManager, DataSourceSecurity dataSourceSecurity, ConfidenceLevel requiredConfidenceLevel) { return provider.AllowsDataSourceSecurity(dataSourceSecurity, settingsManager) - && provider.GetConfidenceLevel(settingsManager).AllowsDataSourceComplianceLevel(dataSourceComplianceLevel); + && provider.GetConfidenceLevel(settingsManager).AllowsDataSourceConfidenceLevel(requiredConfidenceLevel); } - public static bool AllowsDataSourceAccess(this EmbeddingProvider provider, SettingsManager settingsManager, DataSourceSecurity dataSourceSecurity, ConfidenceLevel dataSourceComplianceLevel) + public static bool AllowsDataSourceAccess(this IProvider provider, SettingsManager settingsManager, DataSourceSecurity dataSourceSecurity, ConfidenceLevel requiredConfidenceLevel) { return provider.AllowsDataSourceSecurity(dataSourceSecurity, settingsManager) - && provider.GetConfidenceLevel(settingsManager).AllowsDataSourceComplianceLevel(dataSourceComplianceLevel); - } - - public static bool AllowsDataSourceAccess(this IProvider provider, SettingsManager settingsManager, DataSourceSecurity dataSourceSecurity, ConfidenceLevel dataSourceComplianceLevel) - { - return provider.AllowsDataSourceSecurity(dataSourceSecurity, settingsManager) - && provider.GetConfidenceLevel(settingsManager).AllowsDataSourceComplianceLevel(dataSourceComplianceLevel); + && provider.GetConfidenceLevel(settingsManager).AllowsDataSourceConfidenceLevel(requiredConfidenceLevel); } public static bool AllowsDataSourceSecurity(this Provider provider, DataSourceSecurity dataSourceSecurity, SettingsManager settingsManager) => provider.IsTrustedForDataSourceSecurityChecks(settingsManager).AllowsDataSourceSecurity(dataSourceSecurity); - public static bool AllowsDataSourceSecurity(this EmbeddingProvider provider, DataSourceSecurity dataSourceSecurity, SettingsManager settingsManager) - => provider.IsTrustedForDataSourceSecurityChecks(settingsManager).AllowsDataSourceSecurity(dataSourceSecurity); - public static bool AllowsDataSourceSecurity(this IProvider provider, DataSourceSecurity dataSourceSecurity, SettingsManager settingsManager) => provider.IsTrustedForDataSourceSecurityChecks(settingsManager).AllowsDataSourceSecurity(dataSourceSecurity); @@ -95,28 +86,28 @@ public static class DataSourceSecurityTrustExtensions _ => false, }; - public static bool AllowsDataSourceComplianceLevel(this ConfidenceLevel providerConfidenceLevel, ConfidenceLevel dataSourceComplianceLevel) + public static bool AllowsDataSourceConfidenceLevel(this ConfidenceLevel providerConfidenceLevel, ConfidenceLevel requiredConfidenceLevel) { - if (dataSourceComplianceLevel is ConfidenceLevel.NONE) + if (requiredConfidenceLevel is ConfidenceLevel.NONE) return true; - return providerConfidenceLevel >= dataSourceComplianceLevel; + return providerConfidenceLevel >= requiredConfidenceLevel; } - public static ConfidenceLevel GetRequiredComplianceLevel(this IEnumerable dataSources) + public static ConfidenceLevel GetRequiredConfidenceLevel(this IEnumerable dataSources) { - var requiredComplianceLevel = ConfidenceLevel.NONE; - foreach (var dataSource in dataSources) - if (dataSource.ComplianceLevel > requiredComplianceLevel) - requiredComplianceLevel = dataSource.ComplianceLevel; + var requiredConfidenceLevel = ConfidenceLevel.NONE; + foreach (var dataSource in dataSources.OfType()) + if (dataSource.ConfidenceLevel > requiredConfidenceLevel) + requiredConfidenceLevel = dataSource.ConfidenceLevel; - return requiredComplianceLevel; + return requiredConfidenceLevel; } public static DataSourceSecurity GetRequiredSecurityPolicy(this IEnumerable dataSources) { var requiredSecurityPolicy = DataSourceSecurity.ALLOW_ANY; - foreach (var dataSource in dataSources) + foreach (var dataSource in dataSources.OfType()) { if (dataSource.SecurityPolicy is DataSourceSecurity.NOT_SPECIFIED) return DataSourceSecurity.NOT_SPECIFIED; diff --git a/app/MindWork AI Studio/Settings/IDataSource.cs b/app/MindWork AI Studio/Settings/IDataSource.cs index 87a24d88..c04bd199 100644 --- a/app/MindWork AI Studio/Settings/IDataSource.cs +++ b/app/MindWork AI Studio/Settings/IDataSource.cs @@ -1,7 +1,6 @@ using System.Text.Json.Serialization; using AIStudio.Chat; -using AIStudio.Provider; using AIStudio.Settings.DataModel; using AIStudio.Tools.PluginSystem; using AIStudio.Tools.RAG; @@ -22,16 +21,6 @@ public interface IDataSource : IConfigurationObject /// public DataSourceType Type { get; init; } - /// - /// Which data security policy is applied to this data source? - /// - public DataSourceSecurity SecurityPolicy { get; init; } - - /// - /// Which compliance level is assigned to this data source? - /// - public ConfidenceLevel ComplianceLevel { get; init; } - /// /// The maximum number of matches to return when retrieving data from the ERI server. /// diff --git a/app/MindWork AI Studio/Settings/IExternalDataSource.cs b/app/MindWork AI Studio/Settings/IExternalDataSource.cs index 6b75fa56..74d41f2a 100644 --- a/app/MindWork AI Studio/Settings/IExternalDataSource.cs +++ b/app/MindWork AI Studio/Settings/IExternalDataSource.cs @@ -1,9 +1,16 @@ using System.Text.Json.Serialization; +using AIStudio.Settings.DataModel; + namespace AIStudio.Settings; public interface IExternalDataSource : IDataSource, ISecretId { + /// + /// Which data security policy is applied to this external data source? + /// + public DataSourceSecurity SecurityPolicy { get; init; } + #region Implementation of ISecretId [JsonIgnore] diff --git a/app/MindWork AI Studio/Settings/IInternalDataSource.cs b/app/MindWork AI Studio/Settings/IInternalDataSource.cs index 1bd1c13f..73b22e9d 100644 --- a/app/MindWork AI Studio/Settings/IInternalDataSource.cs +++ b/app/MindWork AI Studio/Settings/IInternalDataSource.cs @@ -1,7 +1,14 @@ +using AIStudio.Provider; + namespace AIStudio.Settings; public interface IInternalDataSource : IDataSource { + /// + /// Which provider confidence level is required by this internal data source? + /// + public ConfidenceLevel ConfidenceLevel { get; init; } + /// /// The unique identifier of the embedding method used by this internal data source. /// diff --git a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/EmbeddingStateClient.cs b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/EmbeddingStateClient.cs index 775b05c5..7ebb4851 100644 --- a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/EmbeddingStateClient.cs +++ b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/EmbeddingStateClient.cs @@ -43,8 +43,8 @@ public sealed record EmbeddingStateFile( DateTimeOffset LastWriteUtc, DateTimeOffset EmbeddedAtUtc, int ChunkCount, - string ComplianceLevel, - int ComplianceLevelRank); + string ConfidenceLevel, + int ConfidenceLevelRank); public sealed record EmbeddingStateChunk( string ChunkId, @@ -74,5 +74,5 @@ public sealed record EmbeddingStateSearchResult( DateTimeOffset LastWriteUtc, DateTimeOffset EmbeddedAtUtc, int ChunkCount, - string ComplianceLevel, - int ComplianceLevelRank); + string ConfidenceLevel, + int ConfidenceLevelRank); diff --git a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/EmbeddingStateDbContext.cs b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/EmbeddingStateDbContext.cs index 4c4a353e..1000ef53 100644 --- a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/EmbeddingStateDbContext.cs +++ b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/EmbeddingStateDbContext.cs @@ -62,13 +62,13 @@ internal sealed class EmbeddingStateDbContext(DbContextOptions file.LastWriteUtc).HasColumnName("last_write_utc").HasConversion(utcDateTimeOffsetConverter).IsRequired(); entity.Property(file => file.EmbeddedAtUtc).HasColumnName("embedded_at_utc").HasConversion(utcDateTimeOffsetConverter).IsRequired(); entity.Property(file => file.ChunkCount).HasColumnName("chunk_count"); - entity.Property(file => file.ComplianceLevel).HasColumnName("compliance_level").IsRequired(); - entity.Property(file => file.ComplianceLevelRank).HasColumnName("compliance_level_rank"); + entity.Property(file => file.ConfidenceLevel).HasColumnName("confidence_level").IsRequired(); + entity.Property(file => file.ConfidenceLevelRank).HasColumnName("confidence_level_rank"); entity.HasIndex(file => file.DataSourceId).HasDatabaseName("idx_embedded_files_data_source"); entity.HasIndex(file => file.AbsolutePath).HasDatabaseName("idx_embedded_files_absolute_path"); entity.HasIndex(file => file.FileType).HasDatabaseName("idx_embedded_files_file_type"); - entity.HasIndex(file => file.ComplianceLevelRank).HasDatabaseName("idx_embedded_files_compliance"); + entity.HasIndex(file => file.ConfidenceLevelRank).HasDatabaseName("idx_embedded_files_confidence"); entity.HasIndex(file => new { file.DataSourceId, file.AbsolutePath }).HasDatabaseName("idx_embedded_files_data_source_absolute_path").IsUnique(); entity @@ -165,9 +165,9 @@ internal sealed class EmbeddingStateFileEntity public int ChunkCount { get; set; } - public string ComplianceLevel { get; set; } = string.Empty; + public string ConfidenceLevel { get; set; } = string.Empty; - public int ComplianceLevelRank { get; set; } + public int ConfidenceLevelRank { get; set; } public EmbeddingStateDataSourceEntity? DataSource { get; set; } @@ -233,9 +233,9 @@ internal sealed class EmbeddingStateSearchResultEntity public int ChunkCount { get; set; } - public string ComplianceLevel { get; set; } = string.Empty; + public string ConfidenceLevel { get; set; } = string.Empty; - public int ComplianceLevelRank { get; set; } + public int ConfidenceLevelRank { get; set; } } internal sealed class EmbeddingStateDateTimeOffsetConverter() : ValueConverter( diff --git a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/Migrations/20260804000000_InitialRagIndex.cs b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/Migrations/20260804000000_InitialRagIndex.cs index 990081e6..2eaa31d1 100644 --- a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/Migrations/20260804000000_InitialRagIndex.cs +++ b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/Migrations/20260804000000_InitialRagIndex.cs @@ -45,8 +45,8 @@ public partial class InitialRagIndex : Migration last_write_utc = table.Column(type: "TEXT", nullable: false), embedded_at_utc = table.Column(type: "TEXT", nullable: false), chunk_count = table.Column(type: "INTEGER", nullable: false), - compliance_level = table.Column(type: "TEXT", nullable: false), - compliance_level_rank = table.Column(type: "INTEGER", nullable: false), + confidence_level = table.Column(type: "TEXT", nullable: false), + confidence_level_rank = table.Column(type: "INTEGER", nullable: false), }, constraints: table => { @@ -89,9 +89,9 @@ public partial class InitialRagIndex : Migration column: "absolute_path"); migrationBuilder.CreateIndex( - name: "idx_embedded_files_compliance", + name: "idx_embedded_files_confidence", table: "embedded_files", - column: "compliance_level_rank"); + column: "confidence_level_rank"); migrationBuilder.CreateIndex( name: "idx_embedded_files_data_source", diff --git a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/Migrations/EmbeddingStateDbContextModelSnapshot.cs b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/Migrations/EmbeddingStateDbContextModelSnapshot.cs index c1209ec8..3721b8a2 100644 --- a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/Migrations/EmbeddingStateDbContextModelSnapshot.cs +++ b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/Migrations/EmbeddingStateDbContextModelSnapshot.cs @@ -77,14 +77,14 @@ partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot .HasColumnType("INTEGER") .HasColumnName("chunk_count"); - entity.Property("ComplianceLevel") + entity.Property("ConfidenceLevel") .IsRequired() .HasColumnType("TEXT") - .HasColumnName("compliance_level"); + .HasColumnName("confidence_level"); - entity.Property("ComplianceLevelRank") + entity.Property("ConfidenceLevelRank") .HasColumnType("INTEGER") - .HasColumnName("compliance_level_rank"); + .HasColumnName("confidence_level_rank"); entity.Property("CreationUtc") .HasConversion(utcDateTimeOffsetConverter) @@ -135,8 +135,8 @@ partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot entity.HasIndex("AbsolutePath") .HasDatabaseName("idx_embedded_files_absolute_path"); - entity.HasIndex("ComplianceLevelRank") - .HasDatabaseName("idx_embedded_files_compliance"); + entity.HasIndex("ConfidenceLevelRank") + .HasDatabaseName("idx_embedded_files_confidence"); entity.HasIndex("DataSourceId") .HasDatabaseName("idx_embedded_files_data_source"); @@ -226,11 +226,11 @@ partial class EmbeddingStateDbContextModelSnapshot : ModelSnapshot .IsRequired() .HasColumnType("TEXT"); - entity.Property("ComplianceLevel") + entity.Property("ConfidenceLevel") .IsRequired() .HasColumnType("TEXT"); - entity.Property("ComplianceLevelRank") + entity.Property("ConfidenceLevelRank") .HasColumnType("INTEGER"); entity.Property("CreationUtc") diff --git a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/SqliteEmbeddingStateClientImplementation.cs b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/SqliteEmbeddingStateClientImplementation.cs index ce187c3b..fe132378 100644 --- a/app/MindWork AI Studio/Tools/Databases/EmbeddingState/SqliteEmbeddingStateClientImplementation.cs +++ b/app/MindWork AI Studio/Tools/Databases/EmbeddingState/SqliteEmbeddingStateClientImplementation.cs @@ -268,8 +268,8 @@ public sealed class SqliteEmbeddingStateClientImplementation( f.last_write_utc AS LastWriteUtc, c.embedded_at_utc AS EmbeddedAtUtc, f.chunk_count AS ChunkCount, - f.compliance_level AS ComplianceLevel, - f.compliance_level_rank AS ComplianceLevelRank + f.confidence_level AS ConfidenceLevel, + f.confidence_level_rank AS ConfidenceLevelRank FROM embedding_chunks_fts JOIN embedding_chunks c ON c.id = embedding_chunks_fts.rowid JOIN embedded_files f ON f.parent_file_id = c.parent_file_id @@ -359,8 +359,8 @@ public sealed class SqliteEmbeddingStateClientImplementation( fileEntity.LastWriteUtc = file.LastWriteUtc; fileEntity.EmbeddedAtUtc = file.EmbeddedAtUtc; fileEntity.ChunkCount = file.ChunkCount; - fileEntity.ComplianceLevel = file.ComplianceLevel; - fileEntity.ComplianceLevelRank = file.ComplianceLevelRank; + fileEntity.ConfidenceLevel = file.ConfidenceLevel; + fileEntity.ConfidenceLevelRank = file.ConfidenceLevelRank; } private static void ApplyChunk(EmbeddingStateChunkEntity chunkEntity, EmbeddingStateChunk chunk) @@ -393,8 +393,8 @@ public sealed class SqliteEmbeddingStateClientImplementation( result.LastWriteUtc, result.EmbeddedAtUtc, result.ChunkCount, - result.ComplianceLevel, - result.ComplianceLevelRank); + result.ConfidenceLevel, + result.ConfidenceLevelRank); private static string BuildFtsQuery(string query) { diff --git a/app/MindWork AI Studio/Tools/Databases/VectorStore/VectorSearchResult.cs b/app/MindWork AI Studio/Tools/Databases/VectorStore/VectorSearchResult.cs index 94319c3c..693b2527 100644 --- a/app/MindWork AI Studio/Tools/Databases/VectorStore/VectorSearchResult.cs +++ b/app/MindWork AI Studio/Tools/Databases/VectorStore/VectorSearchResult.cs @@ -20,5 +20,5 @@ public sealed record VectorSearchResult( string CreationUtc, string LastWriteUtc, string EmbeddedAtUtc, - string ComplianceLevel, - int ComplianceLevelRank); + string ConfidenceLevel, + int ConfidenceLevelRank); diff --git a/app/MindWork AI Studio/Tools/Databases/VectorStore/VectorStoragePoint.cs b/app/MindWork AI Studio/Tools/Databases/VectorStore/VectorStoragePoint.cs index f224dc0e..042824d9 100644 --- a/app/MindWork AI Studio/Tools/Databases/VectorStore/VectorStoragePoint.cs +++ b/app/MindWork AI Studio/Tools/Databases/VectorStore/VectorStoragePoint.cs @@ -20,5 +20,5 @@ public sealed record VectorStoragePoint( DateTimeOffset CreationUtc, DateTimeOffset LastWriteUtc, DateTimeOffset EmbeddedAtUtc, - string ComplianceLevel, - int ComplianceLevelRank); + string ConfidenceLevel, + int ConfidenceLevelRank); diff --git a/app/MindWork AI Studio/Tools/RAG/AugmentationProcesses/AugmentationOne.cs b/app/MindWork AI Studio/Tools/RAG/AugmentationProcesses/AugmentationOne.cs index b3c56369..beac02c3 100644 --- a/app/MindWork AI Studio/Tools/RAG/AugmentationProcesses/AugmentationOne.cs +++ b/app/MindWork AI Studio/Tools/RAG/AugmentationProcesses/AugmentationOne.cs @@ -43,7 +43,7 @@ public sealed class AugmentationOne : IAugmentationProcess { // Let's get the validation agent & set up its provider: var validationAgent = Program.SERVICE_PROVIDER.GetService()!; - if (validationAgent.SetLLMProvider(provider, chatThread.DataSecurity, chatThread.DataComplianceLevel)) + if (validationAgent.SetLLMProvider(provider, chatThread.DataSecurity, chatThread.DataConfidenceLevel)) { // Let's validate all retrieval contexts: var validationResults = await validationAgent.ValidateRetrievalContextsAsync(lastUserPrompt, chatThread, retrievalContexts, token); @@ -58,7 +58,7 @@ public sealed class AugmentationOne : IAugmentationProcess retrievalContexts = validationResults.Where(x => x.RetrievalContext is not null && x.Confidence >= threshold).Select(x => x.RetrievalContext!).ToList(); } else - LOGGER.LogWarning("Skipping retrieval context validation because no compliant validation agent provider is available."); + LOGGER.LogWarning("Skipping retrieval context validation because no sufficiently trusted validation agent provider is available."); } LOGGER.LogInformation($"Starting the augmentation process over {numTotalRetrievalContexts:###,###,###,###} retrieval contexts."); diff --git a/app/MindWork AI Studio/Tools/RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs b/app/MindWork AI Studio/Tools/RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs index 6cd62f95..781ed34e 100644 --- a/app/MindWork AI Studio/Tools/RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs +++ b/app/MindWork AI Studio/Tools/RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs @@ -74,7 +74,7 @@ public sealed class AISrcSelWithRetCtxVal : IRagProcess // data sources changed its security requirements. // List preselectedDataSources = chatThread.DataSourceOptions.PreselectedDataSourceIds.Select(id => settings.ConfigurationData.DataSources.FirstOrDefault(ds => ds.Id == id)).Where(ds => ds is not null).ToList()!; - var dataSources = await dataSourceService.GetDataSources(provider, preselectedDataSources); + var dataSources = await dataSourceService.GetDataSources(provider, chatThread.DataSourceOptions, preselectedDataSources); var selectedDataSources = dataSources.SelectedDataSources; // @@ -104,13 +104,15 @@ public sealed class AISrcSelWithRetCtxVal : IRagProcess else { var previousDataSecurity = chatThread.DataSecurity; - var previousDataComplianceLevel = chatThread.DataComplianceLevel; + var previousDataConfidenceLevel = chatThread.DataConfidenceLevel; // // Update the data security of the chat thread. We consider the current data security // of the chat thread and the data security of the selected data sources: // - var dataSecurityRestrictedToSelfHosted = selectedDataSources.Any(x => x is not IInternalDataSource && x.SecurityPolicy is DataSourceSecurity.SELF_HOSTED); + var dataSecurityRestrictedToSelfHosted = selectedDataSources + .OfType() + .Any(dataSource => dataSource.SecurityPolicy is DataSourceSecurity.SELF_HOSTED); chatThread.DataSecurity = dataSecurityRestrictedToSelfHosted switch { // @@ -152,12 +154,12 @@ public sealed class AISrcSelWithRetCtxVal : IRagProcess if (previousDataSecurity != chatThread.DataSecurity) LOGGER.LogInformation($"The data security of the chat thread was updated from '{previousDataSecurity}' to '{chatThread.DataSecurity}'."); - foreach (var dataSource in selectedDataSources) - if (dataSource.ComplianceLevel > chatThread.DataComplianceLevel) - chatThread.DataComplianceLevel = dataSource.ComplianceLevel; + foreach (var dataSource in selectedDataSources.OfType()) + if (dataSource.ConfidenceLevel > chatThread.DataConfidenceLevel) + chatThread.DataConfidenceLevel = dataSource.ConfidenceLevel; - if (previousDataComplianceLevel != chatThread.DataComplianceLevel) - LOGGER.LogInformation($"The data compliance level of the chat thread was updated from '{previousDataComplianceLevel.GetName()}' to '{chatThread.DataComplianceLevel.GetName()}'."); + if (previousDataConfidenceLevel != chatThread.DataConfidenceLevel) + LOGGER.LogInformation($"The data confidence level of the chat thread was updated from '{previousDataConfidenceLevel.GetName()}' to '{chatThread.DataConfidenceLevel.GetName()}'."); } // diff --git a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.Files.cs b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.Files.cs index 44366557..551852fd 100644 --- a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.Files.cs +++ b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.Files.cs @@ -946,7 +946,7 @@ public sealed partial class DataSourceEmbeddingService embeddingProvider.Hostname, embeddingProvider.TokenizerPath, embeddingProvider.EffectiveTokenLimit, - GetDataSourceComplianceLevel(dataSource).ToString(), + GetDataSourceConfidenceLevel(dataSource).ToString(), dataSource is IInternalDataSource internalDataSource ? internalDataSource.MaxChunkTokenLength : 0, dataSource is IInternalDataSource overlapDataSource ? overlapDataSource.ChunkOverlapTokenLength : 0, chunkingOptions.MaxChunkTokenLength, @@ -1050,7 +1050,7 @@ public sealed partial class DataSourceEmbeddingService { file.Refresh(); var absolutePath = Path.GetFullPath(file.FullName); - var complianceLevel = GetDataSourceComplianceLevel(dataSource); + var confidenceLevel = GetDataSourceConfidenceLevel(dataSource); return new( this.CreateParentFileId(dataSource.Id, absolutePath), absolutePath, @@ -1063,8 +1063,8 @@ public sealed partial class DataSourceEmbeddingService file.Exists ? new DateTimeOffset(file.LastWriteTimeUtc) : DateTimeOffset.UnixEpoch, embeddedAtUtc, chunkCount, - complianceLevel.ToString(), - (int)complianceLevel); + confidenceLevel.ToString(), + (int)confidenceLevel); } private IReadOnlyList CreateEmbeddingStateChunks(EmbeddingStateFile parentFile, IReadOnlyList batch, DateTimeOffset embeddedAtUtc) @@ -1080,10 +1080,10 @@ public sealed partial class DataSourceEmbeddingService .ToList(); } - private static ConfidenceLevel GetDataSourceComplianceLevel(IDataSource dataSource) => - dataSource.ComplianceLevel is ConfidenceLevel.NONE + private static ConfidenceLevel GetDataSourceConfidenceLevel(IDataSource dataSource) => + dataSource is not IInternalDataSource internalDataSource || internalDataSource.ConfidenceLevel is ConfidenceLevel.NONE ? ConfidenceLevel.UNKNOWN - : dataSource.ComplianceLevel; + : internalDataSource.ConfidenceLevel; private static string GetFileType(FileInfo file) { diff --git a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs index 8bf87010..f7a56717 100644 --- a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs +++ b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs @@ -393,6 +393,15 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM private async Task ProcessDataSourceAsync(IDataSource dataSource, DataSourceEmbeddingRefreshMode refreshMode, CancellationToken token) { + if (dataSource is not IInternalDataSource internalDataSource) + { + logger.LogWarning( + "Skipping background embeddings for non-internal data source '{DataSourceName}' ({DataSourceId}).", + dataSource.Name, + dataSource.Id); + return; + } + logger.LogInformation( "Starting background embedding hash check for data source '{DataSourceName}' ({DataSourceId}). RefreshMode={RefreshMode}.", dataSource.Name, @@ -451,17 +460,16 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM return; } - if (!embeddingProvider.AllowsDataSourceAccess(settingsManager, dataSource.SecurityPolicy, dataSource.ComplianceLevel)) + if (!embeddingProvider.GetConfidenceLevel(settingsManager).AllowsDataSourceConfidenceLevel(internalDataSource.ConfidenceLevel)) { - var errorMessage = $"The selected embedding provider is not allowed to embed this data source. The data source requires provider confidence '{dataSource.ComplianceLevel.GetName()}'. The embedding provider has confidence '{embeddingProvider.GetConfidenceLevel(settingsManager).GetName()}'."; + var errorMessage = $"The selected embedding provider is not allowed to embed this data source. The data source requires provider confidence '{internalDataSource.ConfidenceLevel.GetName()}'. The embedding provider has confidence '{embeddingProvider.GetConfidenceLevel(settingsManager).GetName()}'."; logger.LogWarning( - "Skipping background embeddings for data source '{DataSourceName}' ({DataSourceId}) because embedding provider '{EmbeddingProviderName}' ({EmbeddingProviderId}) is not allowed. RequiredDataSecurity={RequiredDataSecurity}, RequiredCompliance={RequiredCompliance}, EmbeddingProviderConfidence={EmbeddingProviderConfidence}.", + "Skipping background embeddings for data source '{DataSourceName}' ({DataSourceId}) because embedding provider '{EmbeddingProviderName}' ({EmbeddingProviderId}) does not meet the required confidence. RequiredConfidence={RequiredConfidence}, EmbeddingProviderConfidence={EmbeddingProviderConfidence}.", dataSource.Name, dataSource.Id, embeddingProvider.Name, embeddingProvider.Id, - dataSource.SecurityPolicy, - dataSource.ComplianceLevel.GetName(), + internalDataSource.ConfidenceLevel.GetName(), embeddingProvider.GetConfidenceLevel(settingsManager).GetName()); token.ThrowIfCancellationRequested(); @@ -877,8 +885,8 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM parentFile.CreationUtc, parentFile.LastWriteUtc, embeddedAtUtc, - parentFile.ComplianceLevel, - parentFile.ComplianceLevelRank)).ToList(); + parentFile.ConfidenceLevel, + parentFile.ConfidenceLevelRank)).ToList(); await vectorStore.InsertEmbedding(collectionName, points, token); } diff --git a/app/MindWork AI Studio/Tools/Services/DataSourceLocalRetrievalService.cs b/app/MindWork AI Studio/Tools/Services/DataSourceLocalRetrievalService.cs index f81788a2..723ccbd8 100644 --- a/app/MindWork AI Studio/Tools/Services/DataSourceLocalRetrievalService.cs +++ b/app/MindWork AI Studio/Tools/Services/DataSourceLocalRetrievalService.cs @@ -38,8 +38,8 @@ public sealed class DataSourceLocalRetrievalService( string Text, double Score, int Rank, - string ComplianceLevel, - int ComplianceLevelRank); + string ConfidenceLevel, + int ConfidenceLevelRank); public Task> RetrieveDataAsync(DataSourceLocalFile dataSource, IContent lastUserPrompt, ChatThread thread, CancellationToken token = default) => this.RetrieveDataAsync((IInternalDataSource)dataSource, lastUserPrompt, token); @@ -296,8 +296,8 @@ public sealed class DataSourceLocalRetrievalService( result.Text, result.Score, rank, - result.ComplianceLevel, - result.ComplianceLevelRank); + result.ConfidenceLevel, + result.ConfidenceLevelRank); private static LocalRetrievalHit FromBm25Result(EmbeddingStateSearchResult result, int rank) => new( @@ -316,8 +316,8 @@ public sealed class DataSourceLocalRetrievalService( result.ChunkText, result.Score, rank, - result.ComplianceLevel, - result.ComplianceLevelRank); + result.ConfidenceLevel, + result.ConfidenceLevelRank); private static RetrievalTextContext ToRetrievalContext(LocalRetrievalHit hit) { diff --git a/app/MindWork AI Studio/Tools/Services/DataSourceService.cs b/app/MindWork AI Studio/Tools/Services/DataSourceService.cs index 34747d93..91389e21 100644 --- a/app/MindWork AI Studio/Tools/Services/DataSourceService.cs +++ b/app/MindWork AI Studio/Tools/Services/DataSourceService.cs @@ -9,6 +9,8 @@ namespace AIStudio.Tools.Services; public sealed class DataSourceService { + private readonly record struct ParticipatingProvider(string Role, bool IsTrusted, ConfidenceLevel ConfidenceLevel); + private readonly RustService rustService; private readonly SettingsManager settingsManager; private readonly ILogger logger; @@ -27,9 +29,10 @@ public sealed class DataSourceService /// It also returns the data sources selected before when they are still allowed. /// /// The selected LLM provider. + /// The active data source options, which determine which agent providers participate. /// The data sources selected before. /// The allowed data sources and the data sources selected before -- when they are still allowed. - public async Task GetDataSources(AIStudio.Settings.Provider selectedLLMProvider, IReadOnlyCollection? previousSelectedDataSources = null) + public async Task GetDataSources(AIStudio.Settings.Provider selectedLLMProvider, DataSourceOptions dataSourceOptions, IReadOnlyCollection? previousSelectedDataSources = null) { // // Case: Somehow the selected LLM provider was not set. The default provider @@ -42,10 +45,10 @@ public sealed class DataSourceService return new([], []); } - return await this.GetDataSources( - selectedLLMProvider.IsTrustedForDataSourceSecurityChecks(this.settingsManager), - selectedLLMProvider.GetConfidenceLevel(this.settingsManager), - previousSelectedDataSources); + var usingTrustedProvider = selectedLLMProvider.IsTrustedForDataSourceSecurityChecks(this.settingsManager); + var participatingProviders = this.GetParticipatingProviders(selectedLLMProvider.Id, dataSourceOptions, + new("chat provider", usingTrustedProvider, selectedLLMProvider.GetConfidenceLevel(this.settingsManager))); + return await this.GetDataSources(usingTrustedProvider, participatingProviders, previousSelectedDataSources); } /// @@ -53,9 +56,10 @@ public sealed class DataSourceService /// It also returns the data sources selected before when they are still allowed. /// /// The selected LLM provider. + /// The active data source options, which determine which agent providers participate. /// The data sources selected before. /// The allowed data sources and the data sources selected before -- when they are still allowed. - public async Task GetDataSources(IProvider selectedLLMProvider, IReadOnlyCollection? previousSelectedDataSources = null) + public async Task GetDataSources(IProvider selectedLLMProvider, DataSourceOptions dataSourceOptions, IReadOnlyCollection? previousSelectedDataSources = null) { // // Case: Somehow the selected LLM provider was not set. The default provider @@ -68,13 +72,42 @@ public sealed class DataSourceService return new([], []); } - return await this.GetDataSources( - selectedLLMProvider.IsTrustedForDataSourceSecurityChecks(this.settingsManager), - selectedLLMProvider.GetConfidenceLevel(this.settingsManager), - previousSelectedDataSources); + var usingTrustedProvider = selectedLLMProvider.IsTrustedForDataSourceSecurityChecks(this.settingsManager); + var participatingProviders = this.GetParticipatingProviders(selectedLLMProvider.ConfiguredProviderId, dataSourceOptions, + new("chat provider", usingTrustedProvider, selectedLLMProvider.GetConfidenceLevel(this.settingsManager))); + return await this.GetDataSources(usingTrustedProvider, participatingProviders, previousSelectedDataSources); } - private async Task GetDataSources(bool usingTrustedProvider, ConfidenceLevel providerConfidenceLevel, IReadOnlyCollection? previousSelectedDataSources = null) + private IReadOnlyList GetParticipatingProviders(string currentProviderId, DataSourceOptions dataSourceOptions, ParticipatingProvider currentProvider) + { + var providers = new List { currentProvider }; + + if (dataSourceOptions.AutomaticDataSourceSelection) + this.AddAgentProvider(providers, Components.AGENT_DATA_SOURCE_SELECTION, currentProviderId, "data source selection agent"); + + if (dataSourceOptions.AutomaticValidation && this.settingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation) + this.AddAgentProvider(providers, Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION, currentProviderId, "retrieval context validation agent"); + + return providers; + } + + private void AddAgentProvider(List providers, Components component, string currentProviderId, string role) + { + var provider = this.settingsManager.GetPreselectedProvider(component, currentProviderId, true); + if (provider == Settings.Provider.NONE) + { + this.logger.LogWarning($"No provider is available for the {role}. Data sources cannot be made available while this agent is enabled."); + providers.Add(new(role, false, ConfidenceLevel.NONE)); + return; + } + + providers.Add(new( + role, + provider.IsTrustedForDataSourceSecurityChecks(this.settingsManager), + provider.GetConfidenceLevel(this.settingsManager))); + } + + private async Task GetDataSources(bool usingTrustedProvider, IReadOnlyList participatingProviders, IReadOnlyCollection? previousSelectedDataSources = null) { var allDataSources = this.settingsManager.ConfigurationData.DataSources.ToList(); var previousSelectedDataSourceIds = previousSelectedDataSources?.Select(source => source.Id).ToHashSet(StringComparer.Ordinal) ?? []; @@ -84,7 +117,7 @@ public sealed class DataSourceService // Start all checks in parallel: foreach (var source in allDataSources) - tasks.Add(this.CheckOneDataSource(source, usingTrustedProvider, providerConfidenceLevel)); + tasks.Add(this.CheckOneDataSource(source, usingTrustedProvider, participatingProviders)); // Wait for all checks and collect the results: foreach (var task in tasks) @@ -101,16 +134,34 @@ public sealed class DataSourceService return new(filteredDataSources, filteredSelectedDataSources); } - private async Task CheckOneDataSource(IDataSource source, bool usingTrustedProvider, ConfidenceLevel providerConfidenceLevel) + private async Task CheckOneDataSource(IDataSource source, bool usingTrustedProvider, IReadOnlyList participatingProviders) { - if (!providerConfidenceLevel.AllowsDataSourceComplianceLevel(source.ComplianceLevel)) + if (source is IInternalDataSource internalSource) { - this.logger.LogWarning($"The data source '{source.Name}' (id={source.Id}) requires provider confidence '{source.ComplianceLevel.GetName()}'. The selected provider only has confidence '{providerConfidenceLevel.GetName()}'. We skip this source."); - return null; - } + foreach (var provider in participatingProviders) + { + if (!provider.ConfidenceLevel.AllowsDataSourceConfidenceLevel(internalSource.ConfidenceLevel)) + { + this.logger.LogWarning($"The internal data source '{source.Name}' (id={source.Id}) requires provider confidence '{internalSource.ConfidenceLevel.GetName()}'. The {provider.Role} only has confidence '{provider.ConfidenceLevel.GetName()}'. We skip this source."); + return null; + } + } + + if (!DataSourceEmbeddingProviders.TryResolve(this.settingsManager, source, out var embeddingProvider)) + { + this.logger.LogWarning($"The internal data source '{source.Name}' (id={source.Id}) has no usable embedding provider. We skip this source."); + return null; + } + + var embeddingProviderConfidence = embeddingProvider.GetConfidenceLevel(this.settingsManager); + if (!embeddingProviderConfidence.AllowsDataSourceConfidenceLevel(internalSource.ConfidenceLevel)) + { + this.logger.LogWarning($"The internal data source '{source.Name}' (id={source.Id}) requires provider confidence '{internalSource.ConfidenceLevel.GetName()}'. Its embedding provider '{embeddingProvider.Name}' only has confidence '{embeddingProviderConfidence.GetName()}'. We skip this source."); + return null; + } - if (source is IInternalDataSource) return source; + } // // Unfortunately, we have to live-check any ERI source for its security requirements. @@ -146,8 +197,11 @@ public sealed class DataSourceService eriSourceRequirements = securityRequest.Data; this.logger.LogInformation($"Security requirements for ERI source '{source.Name}' (id={source.Id}) retrieved successfully."); } - - switch (source.SecurityPolicy) + + if (source is not IExternalDataSource externalSource) + return source; + + switch (externalSource.SecurityPolicy) { case DataSourceSecurity.ALLOW_ANY: diff --git a/app/MindWork AI Studio/Tools/Validation/DataSourceValidation.cs b/app/MindWork AI Studio/Tools/Validation/DataSourceValidation.cs index ad52ede0..acf51a71 100644 --- a/app/MindWork AI Studio/Tools/Validation/DataSourceValidation.cs +++ b/app/MindWork AI Studio/Tools/Validation/DataSourceValidation.cs @@ -23,14 +23,12 @@ public sealed class DataSourceValidation public Func GetAuthMethod { get; init; } = () => AuthMethod.NONE; public Func GetSecurityRequirements { get; init; } = () => null; - + public Func GetSelectedCloudEmbedding { get; init; } = () => false; public Func GetSelectedEmbeddingProvider { get; init; } = () => null; - public Func GetSecurityPolicy { get; init; } = () => DataSourceSecurity.ALLOW_ANY; - - public Func GetComplianceLevel { get; init; } = () => ConfidenceLevel.NONE; + public Func GetConfidenceLevel { get; init; } = () => ConfidenceLevel.NONE; public Func GetSettingsManager { get; init; } = () => null; @@ -61,19 +59,19 @@ public sealed class DataSourceValidation return null; } - + public string? ValidateSecurityPolicy(DataSourceSecurity securityPolicy) { if(securityPolicy is DataSourceSecurity.NOT_SPECIFIED) return TB("Please select your security policy."); - + var dataSourceSecurity = this.GetSecurityRequirements(); if (dataSourceSecurity is null) return null; - + if(dataSourceSecurity.Value.AllowedProviderType is ProviderType.SELF_HOSTED && securityPolicy is not DataSourceSecurity.SELF_HOSTED) return TB("This data source can only be used with a self-hosted LLM provider. Please change the security policy."); - + return null; } @@ -172,10 +170,10 @@ public sealed class DataSourceValidation return embeddingIssue ?? this.ValidateSelectedEmbeddingProviderAccess(); } - public string? ValidateDataSourceComplianceLevel(ConfidenceLevel complianceLevel) + public string? ValidateDataSourceConfidenceLevel(ConfidenceLevel confidenceLevel) { - if(complianceLevel is ConfidenceLevel.NONE) - return TB("Please select a compliance level."); + if(confidenceLevel is ConfidenceLevel.NONE) + return TB("Please select a required provider confidence level."); return this.ValidateSelectedEmbeddingProviderAccess(); } @@ -214,17 +212,13 @@ public sealed class DataSourceValidation if(selectedEmbedding is null || settingsManager is null) return null; - var dataSecurity = this.GetSecurityPolicy(); - var complianceLevel = this.GetComplianceLevel(); - if(selectedEmbedding.AllowsDataSourceAccess(settingsManager, dataSecurity, complianceLevel)) + var confidenceLevel = this.GetConfidenceLevel(); + if(selectedEmbedding.GetConfidenceLevel(settingsManager).AllowsDataSourceConfidenceLevel(confidenceLevel)) return null; - if(!selectedEmbedding.AllowsDataSourceSecurity(dataSecurity, settingsManager)) - return TB("The selected embedding provider is not allowed to process this data source due to its data security policy. Select a self-hosted or organization-trusted embedding provider."); - return string.Format( - TB("The selected embedding provider has confidence '{0}', but this data source requires provider confidence '{1}'. Select an embedding provider with equal or higher confidence or lower the compliance level."), + TB("The selected embedding provider has confidence '{0}', but this data source requires provider confidence '{1}'. Select an embedding provider with equal or higher confidence or lower the required confidence level."), selectedEmbedding.GetConfidenceLevel(settingsManager).GetName(), - complianceLevel.GetName()); + confidenceLevel.GetName()); } } diff --git a/runtime/src/qdrant_edge_database.rs b/runtime/src/qdrant_edge_database.rs index 83e23f4a..659b72ec 100644 --- a/runtime/src/qdrant_edge_database.rs +++ b/runtime/src/qdrant_edge_database.rs @@ -86,8 +86,8 @@ pub struct QdrantEdgeStoragePoint { pub creation_utc: String, pub last_write_utc: String, pub embedded_at_utc: String, - pub compliance_level: String, - pub compliance_level_rank: i32, + pub confidence_level: String, + pub confidence_level_rank: i32, } #[derive(Deserialize)] @@ -159,8 +159,8 @@ pub struct QdrantEdgeSearchResult { pub creation_utc: String, pub last_write_utc: String, pub embedded_at_utc: String, - pub compliance_level: String, - pub compliance_level_rank: i32, + pub confidence_level: String, + pub confidence_level_rank: i32, } #[derive(Clone, Serialize)] @@ -758,8 +758,8 @@ fn to_qdrant_edge_point(point: QdrantEdgeStoragePoint) -> QdrantEdgeResult QdrantEdgeSearchResult { creation_utc: payload_string(&payload, "creation_utc"), last_write_utc: payload_string(&payload, "last_write_utc"), embedded_at_utc: payload_string(&payload, "embedded_at_utc"), - compliance_level: payload_string(&payload, "compliance_level"), - compliance_level_rank: payload_i32(&payload, "compliance_level_rank").unwrap_or_default(), + confidence_level: payload_string(&payload, "confidence_level"), + confidence_level_rank: payload_i32(&payload, "confidence_level_rank").unwrap_or_default(), } }