mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-03-12 18:49:08 +00:00
Improved data security by enforcing provider filtering (#290)
This commit is contained in:
parent
bfc9f2ea1d
commit
9bd79bd3a0
@ -2,6 +2,8 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindWork AI Studio", "MindWork AI Studio\MindWork AI Studio.csproj", "{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceCodeRules", "SourceCodeRules\SourceCodeRules\SourceCodeRules.csproj", "{0976C1CB-D499-4C86-8ADA-B7A7A4DE0BF8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -12,6 +14,10 @@ Global
|
||||
{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0976C1CB-D499-4C86-8ADA-B7A7A4DE0BF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0976C1CB-D499-4C86-8ADA-B7A7A4DE0BF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0976C1CB-D499-4C86-8ADA-B7A7A4DE0BF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0976C1CB-D499-4C86-8ADA-B7A7A4DE0BF8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
EndGlobalSection
|
||||
|
@ -9,5 +9,6 @@
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=agentic/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=groq/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=mwais/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ollama/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=tauri_0027s/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
@ -140,17 +140,7 @@ public sealed class AgentDataSourceSelection (ILogger<AgentDataSourceSelection>
|
||||
//
|
||||
|
||||
// We start with the provider currently selected by the user:
|
||||
var agentProvider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == provider.Id);
|
||||
|
||||
// If the user preselected an agent provider, we try to use this one:
|
||||
if (this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions)
|
||||
{
|
||||
var configuredAgentProvider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectedAgentProvider);
|
||||
|
||||
// If the configured agent provider is available, we use it:
|
||||
if (configuredAgentProvider != default)
|
||||
agentProvider = configuredAgentProvider;
|
||||
}
|
||||
var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_DATA_SOURCE_SELECTION, provider.Id, true);
|
||||
|
||||
// Assign the provider settings to the agent:
|
||||
logger.LogInformation($"The agent for the data source selection uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()}).");
|
||||
|
@ -132,17 +132,7 @@ public sealed class AgentRetrievalContextValidation (ILogger<AgentRetrievalConte
|
||||
public void SetLLMProvider(IProvider provider)
|
||||
{
|
||||
// We start with the provider currently selected by the user:
|
||||
var agentProvider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == provider.Id);
|
||||
|
||||
// If the user preselected an agent provider, we try to use this one:
|
||||
if (this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions)
|
||||
{
|
||||
var configuredAgentProvider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectedAgentProvider);
|
||||
|
||||
// If the configured agent provider is available, we use it:
|
||||
if (configuredAgentProvider != default)
|
||||
agentProvider = configuredAgentProvider;
|
||||
}
|
||||
var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION, provider.Id, true);
|
||||
|
||||
// Assign the provider settings to the agent:
|
||||
logger.LogInformation($"The agent for the retrieval context validation uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()}).");
|
||||
@ -163,11 +153,16 @@ public sealed class AgentRetrievalContextValidation (ILogger<AgentRetrievalConte
|
||||
if (!this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation)
|
||||
return [];
|
||||
|
||||
logger.LogInformation($"Validating {retrievalContexts.Count:###,###,###,###} retrieval contexts.");
|
||||
|
||||
// Prepare the list of validation tasks:
|
||||
var validationTasks = new List<Task<RetrievalContextValidationResult>>(retrievalContexts.Count);
|
||||
|
||||
// Read the number of parallel validations:
|
||||
var numParallelValidations = this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.NumParallelValidations;
|
||||
var numParallelValidations = 3;
|
||||
if(this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions)
|
||||
numParallelValidations = this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.NumParallelValidations;
|
||||
|
||||
numParallelValidations = Math.Max(1, numParallelValidations);
|
||||
|
||||
// Use a semaphore to limit the number of parallel validations:
|
||||
|
@ -1,3 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
|
||||
@ -47,6 +49,7 @@ public partial class ConfigurationProviderSelection : ComponentBase, IMessageBus
|
||||
|
||||
#endregion
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||
private IEnumerable<ConfigurationSelectData<string>> FilteredData()
|
||||
{
|
||||
if(this.Component is not Tools.Components.NONE and not Tools.Components.APP_SETTINGS)
|
||||
|
@ -37,7 +37,11 @@
|
||||
@if (this.areDataSourcesEnabled)
|
||||
{
|
||||
<MudTextSwitch Label="AI-based data source selection" Value="@this.aiBasedSourceSelection" LabelOn="Yes, let the AI decide which data sources are needed." LabelOff="No, I manually decide which data source to use." ValueChanged="@this.AutoModeChanged"/>
|
||||
|
||||
@if (this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation)
|
||||
{
|
||||
<MudTextSwitch Label="AI-based data validation" Value="@this.aiBasedValidation" LabelOn="Yes, let the AI validate & filter the retrieved data." LabelOff="No, use all data retrieved from the data sources." ValueChanged="@this.ValidationModeChanged"/>
|
||||
}
|
||||
|
||||
@if (this.aiBasedSourceSelection is false || this.DataSourcesAISelected.Count == 0)
|
||||
{
|
||||
|
@ -1,3 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
using AIStudio.Assistants;
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
@ -29,6 +31,7 @@ public partial class ProviderSelection : ComponentBase
|
||||
await this.ProviderSettingsChanged.InvokeAsync(provider);
|
||||
}
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||
private IEnumerable<AIStudio.Settings.Provider> GetAvailableProviders()
|
||||
{
|
||||
var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.AssistantBase?.Component ?? Tools.Components.NONE);
|
||||
|
@ -59,11 +59,7 @@ public partial class ReadWebContent : ComponentBase
|
||||
if(this.PreselectContentCleanerAgent)
|
||||
this.useContentCleanerAgent = true;
|
||||
|
||||
if (this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions)
|
||||
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectedAgentProvider);
|
||||
else
|
||||
this.providerSettings = this.ProviderSettings;
|
||||
|
||||
this.ProviderSettings = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_TEXT_CONTENT_CLEANER, this.ProviderSettings.Id, true);
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
using AIStudio.Dialogs;
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
@ -26,6 +28,7 @@ public partial class SettingsPanelProviders : SettingsPanelBase
|
||||
|
||||
#endregion
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||
private async Task AddLLMProvider()
|
||||
{
|
||||
var dialogParameters = new DialogParameters<ProviderDialog>
|
||||
@ -48,6 +51,7 @@ public partial class SettingsPanelProviders : SettingsPanelBase
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||
private async Task EditLLMProvider(AIStudio.Settings.Provider provider)
|
||||
{
|
||||
var dialogParameters = new DialogParameters<ProviderDialog>
|
||||
@ -82,6 +86,7 @@ public partial class SettingsPanelProviders : SettingsPanelBase
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||
private async Task DeleteLLMProvider(AIStudio.Settings.Provider provider)
|
||||
{
|
||||
var dialogParameters = new DialogParameters
|
||||
@ -112,6 +117,7 @@ public partial class SettingsPanelProviders : SettingsPanelBase
|
||||
return modelName.Length > MAX_LENGTH ? "[...] " + modelName[^Math.Min(MAX_LENGTH, modelName.Length)..] : modelName;
|
||||
}
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||
private async Task UpdateProviders()
|
||||
{
|
||||
this.AvailableLLMProviders.Clear();
|
||||
|
@ -137,7 +137,9 @@ public partial class ProviderDialog : ComponentBase, ISecretId
|
||||
this.SettingsManager.InjectSpellchecking(SPELLCHECK_ATTRIBUTES);
|
||||
|
||||
// Load the used instance names:
|
||||
#pragma warning disable MWAIS0001
|
||||
this.UsedInstanceNames = this.SettingsManager.ConfigurationData.Providers.Select(x => x.InstanceName.ToLowerInvariant()).ToList();
|
||||
#pragma warning restore MWAIS0001
|
||||
|
||||
// When editing, we need to load the data:
|
||||
if(this.IsEditing)
|
||||
|
@ -53,6 +53,10 @@
|
||||
<PackageReference Include="ReverseMarkdown" Version="4.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SourceCodeRules\SourceCodeRules\SourceCodeRules.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Read the meta data file -->
|
||||
<Target Name="ReadMetaData" BeforeTargets="BeforeBuild">
|
||||
<Error Text="The ../../metadata.txt file was not found!" Condition="!Exists('../../metadata.txt')" />
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
@ -141,7 +142,8 @@ public sealed class SettingsManager(ILogger<SettingsManager> logger)
|
||||
return minimumLevel;
|
||||
}
|
||||
|
||||
public Provider GetPreselectedProvider(Tools.Components component, string? chatProviderId = null)
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||
public Provider GetPreselectedProvider(Tools.Components component, string? currentProviderId = null, bool usePreselectionBeforeCurrentProvider = false)
|
||||
{
|
||||
var minimumLevel = this.GetMinimumConfidenceLevel(component);
|
||||
|
||||
@ -149,17 +151,43 @@ public sealed class SettingsManager(ILogger<SettingsManager> logger)
|
||||
if (this.ConfigurationData.Providers.Count == 1 && this.ConfigurationData.Providers[0].UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||
return this.ConfigurationData.Providers[0];
|
||||
|
||||
// When there is a chat provider, and it has a confidence level that is high enough, we return it:
|
||||
if (chatProviderId is not null && !string.IsNullOrWhiteSpace(chatProviderId))
|
||||
// Is there a current provider with a sufficiently high confidence level?
|
||||
Provider currentProvider = default;
|
||||
if (currentProviderId is not null && !string.IsNullOrWhiteSpace(currentProviderId))
|
||||
{
|
||||
var chatProvider = this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == chatProviderId);
|
||||
if (chatProvider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||
return chatProvider;
|
||||
var currentProviderProbe = this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == currentProviderId);
|
||||
if (currentProviderProbe.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||
currentProvider = currentProviderProbe;
|
||||
}
|
||||
|
||||
// When there is a component-preselected provider, and it has a confidence level that is high enough, we return it:
|
||||
var preselectedProvider = component.PreselectedProvider(this);
|
||||
if(preselectedProvider != default && preselectedProvider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||
// Is there a component-preselected provider with a sufficiently high confidence level?
|
||||
Provider preselectedProvider = default;
|
||||
var preselectedProviderProbe = component.PreselectedProvider(this);
|
||||
if(preselectedProviderProbe != default && preselectedProviderProbe.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||
preselectedProvider = preselectedProviderProbe;
|
||||
|
||||
//
|
||||
// Case: The preselected provider should be used before the current provider,
|
||||
// and the preselected provider is available and has a confidence level
|
||||
// that is high enough.
|
||||
//
|
||||
if(usePreselectionBeforeCurrentProvider && preselectedProvider != default)
|
||||
return preselectedProvider;
|
||||
|
||||
//
|
||||
// Case: The current provider is available and has a confidence level that is
|
||||
// high enough.
|
||||
//
|
||||
if(currentProvider != default)
|
||||
return currentProvider;
|
||||
|
||||
//
|
||||
// Case: The current provider should be used before the preselected provider,
|
||||
// but the current provider is not available or does not have a confidence
|
||||
// level that is high enough. The preselected provider is available and
|
||||
// has a confidence level that is high enough.
|
||||
//
|
||||
if(preselectedProvider != default)
|
||||
return preselectedProvider;
|
||||
|
||||
// When there is an app-wide preselected provider, and it has a confidence level that is high enough, we return it:
|
||||
|
@ -21,4 +21,8 @@ public enum Components
|
||||
|
||||
CHAT,
|
||||
APP_SETTINGS,
|
||||
|
||||
AGENT_TEXT_CONTENT_CLEANER,
|
||||
AGENT_DATA_SOURCE_SELECTION,
|
||||
AGENT_RETRIEVAL_CONTEXT_VALIDATION,
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
|
||||
@ -12,6 +14,10 @@ public static class ComponentsExtensions
|
||||
Components.BIAS_DAY_ASSISTANT => false,
|
||||
Components.APP_SETTINGS => false,
|
||||
|
||||
Components.AGENT_TEXT_CONTENT_CLEANER => false,
|
||||
Components.AGENT_DATA_SOURCE_SELECTION => false,
|
||||
Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION => false,
|
||||
|
||||
_ => true,
|
||||
};
|
||||
|
||||
@ -76,6 +82,7 @@ public static class ComponentsExtensions
|
||||
_ => default,
|
||||
};
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||
public static AIStudio.Settings.Provider PreselectedProvider(this Components component, SettingsManager settingsManager) => component switch
|
||||
{
|
||||
Components.GRAMMAR_SPELLING_ASSISTANT => settingsManager.ConfigurationData.GrammarSpelling.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider) : default,
|
||||
@ -95,6 +102,10 @@ public static class ComponentsExtensions
|
||||
|
||||
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedProvider) : default,
|
||||
|
||||
Components.AGENT_TEXT_CONTENT_CLEANER => settingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.TextContentCleaner.PreselectedAgentProvider) : default,
|
||||
Components.AGENT_DATA_SOURCE_SELECTION => settingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.AgentDataSourceSelection.PreselectedAgentProvider) : default,
|
||||
Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION => settingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectedAgentProvider) : default,
|
||||
|
||||
_ => default,
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,7 @@ public sealed class AugmentationOne : IAugmentationProcess
|
||||
var numTotalRetrievalContexts = retrievalContexts.Count;
|
||||
|
||||
// Want the user to validate all retrieval contexts?
|
||||
if (settings.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation)
|
||||
if (settings.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation && chatThread.DataSourceOptions.AutomaticValidation)
|
||||
{
|
||||
// Let's get the validation agent & set up its provider:
|
||||
var validationAgent = Program.SERVICE_PROVIDER.GetService<AgentRetrievalContextValidation>()!;
|
||||
|
@ -77,6 +77,11 @@
|
||||
"resolved": "31.0.3",
|
||||
"contentHash": "ygck8DR4mG/VDA/LgIVVGpEtXXPDVaaNZNJGrOAJ4pckVw4MbAQ3n/u6YFDv3bwlQhlxTmPhCyk5E4hxe96Crg=="
|
||||
},
|
||||
"Humanizer.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.14.1",
|
||||
"contentHash": "lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw=="
|
||||
},
|
||||
"Markdig": {
|
||||
"type": "Transitive",
|
||||
"resolved": "0.37.0",
|
||||
@ -132,6 +137,56 @@
|
||||
"resolved": "8.0.11",
|
||||
"contentHash": "cy04xnMSTXTkRPjEwseRz57R5zjR/CWsdEOHH6NhWbNl97k+U1w6dSjqIOC7kv08tyzmM30FzIilSDtE5HdL/A=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg=="
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "Hhaw6DKZHiR+vgOdIqvndfUntJhmDR7MjylUJ55EvWtDyJFLDf2eij8r9tcwXP35FLD+bVNNCO0+KIYuvJjNnA==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Analyzers": "3.3.3",
|
||||
"System.Collections.Immutable": "6.0.0",
|
||||
"System.Memory": "4.5.4",
|
||||
"System.Reflection.Metadata": "5.0.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
||||
"System.Text.Encoding.CodePages": "6.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.CSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "0PU4a2h7L6N9SlF/oNHwj2A/+n0LK/7n6PEGvXyIZq8hc7r/TztB+47mhVLvapT6bWSV7nMT78cNxbQuC6tk6g==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Common": "[4.3.0]"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.CSharp.Workspaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "CH2kezeYUD9/+nGs7QZ6xpOqD6OH6000YkAyU8LbhqLp7W65Xb+HerBzDX9yfprmRwArlF887QhZd8nW6enHIg==",
|
||||
"dependencies": {
|
||||
"Humanizer.Core": "2.14.1",
|
||||
"Microsoft.CodeAnalysis.CSharp": "[4.3.0]",
|
||||
"Microsoft.CodeAnalysis.Common": "[4.3.0]",
|
||||
"Microsoft.CodeAnalysis.Workspaces.Common": "[4.3.0]"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Workspaces.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "oFF7lU3dQIeEbAVF6Qq/YEA4jvys3oQKkDezP8NcQTFgD8uRUiIA4NimRxANaWxK2n2PT4DAQspIOtrAE2hSdA==",
|
||||
"dependencies": {
|
||||
"Humanizer.Core": "2.14.1",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "6.0.0",
|
||||
"Microsoft.CodeAnalysis.Common": "[4.3.0]",
|
||||
"System.Composition": "6.0.0",
|
||||
"System.IO.Pipelines": "6.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.1",
|
||||
@ -196,17 +251,117 @@
|
||||
"resolved": "8.0.11",
|
||||
"contentHash": "UYSbAkNGTWVUne3I04/9IRQel3Bt1Ww6Y5cjvZEZ89rWhBD1yWu7YDotvQS62V6mgSfFaXXPGrCUm1VG824QXw=="
|
||||
},
|
||||
"System.Collections.Immutable": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "d7wMuKQtfsxUa7S13tITC8n1cQzewuhD5iDjZtK2prwFfKVzdYtgrTHgjaV03Zq7feGQ5gkP85tJJntXwInsJA==",
|
||||
"dependencies": {
|
||||
"System.Composition.AttributedModel": "6.0.0",
|
||||
"System.Composition.Convention": "6.0.0",
|
||||
"System.Composition.Hosting": "6.0.0",
|
||||
"System.Composition.Runtime": "6.0.0",
|
||||
"System.Composition.TypedParts": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition.AttributedModel": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "WK1nSDLByK/4VoC7fkNiFuTVEiperuCN/Hyn+VN30R+W2ijO1d0Z2Qm0ScEl9xkSn1G2MyapJi8xpf4R8WRa/w=="
|
||||
},
|
||||
"System.Composition.Convention": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "XYi4lPRdu5bM4JVJ3/UIHAiG6V6lWWUlkhB9ab4IOq0FrRsp0F4wTyV4Dj+Ds+efoXJ3qbLqlvaUozDO7OLeXA==",
|
||||
"dependencies": {
|
||||
"System.Composition.AttributedModel": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition.Hosting": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "w/wXjj7kvxuHPLdzZ0PAUt++qJl03t7lENmb2Oev0n3zbxyNULbWBlnd5J5WUMMv15kg5o+/TCZFb6lSwfaUUQ==",
|
||||
"dependencies": {
|
||||
"System.Composition.Runtime": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition.Runtime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "qkRH/YBaMPTnzxrS5RDk1juvqed4A6HOD/CwRcDGyPpYps1J27waBddiiq1y93jk2ZZ9wuA/kynM+NO0kb3PKg=="
|
||||
},
|
||||
"System.Composition.TypedParts": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "iUR1eHrL8Cwd82neQCJ00MpwNIBs4NZgXzrPqx8NJf/k4+mwBO0XCRmHYJT4OLSwDDqh5nBLJWkz5cROnrGhRA==",
|
||||
"dependencies": {
|
||||
"System.Composition.AttributedModel": "6.0.0",
|
||||
"System.Composition.Hosting": "6.0.0",
|
||||
"System.Composition.Runtime": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.IO.Pipelines": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw=="
|
||||
},
|
||||
"System.Reflection.Metadata": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
},
|
||||
"System.Text.Encoding.CodePages": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
|
||||
},
|
||||
"ZXing.Net": {
|
||||
"type": "Transitive",
|
||||
"resolved": "0.16.9",
|
||||
"contentHash": "7WaVMHklpT3Ye2ragqRIwlFRsb6kOk63BOGADV0fan3ulVfGLUYkDi5yNUsZS/7FVNkWbtHAlDLmu4WnHGfqvQ=="
|
||||
},
|
||||
"sourcecoderules": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.CSharp": "[4.3.0, )",
|
||||
"Microsoft.CodeAnalysis.CSharp.Workspaces": "[4.3.0, )"
|
||||
}
|
||||
}
|
||||
},
|
||||
"net8.0/osx-arm64": {}
|
||||
"net8.0/osx-arm64": {
|
||||
"System.Text.Encoding.CodePages": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,4 +6,5 @@
|
||||
- Added an agent to validate whether a retrieval context makes sense for the given prompt. This preview feature is hidden behind the RAG feature flag.
|
||||
- Added a generic RAG process to integrate possibly any data in your chats. Although the generic RAG process is now implemented, the retrieval part is working only with external data sources using the ERI interface. That means that you could integrate your company's data from the corporate network by now. The retrieval process for your local data is still under development and will take several weeks to be released. In order to use data through ERI, you (or your company) have to develop an ERI server. You might use the ERI server assistant within AI Studio to do so. This preview feature is hidden behind the RAG feature flag.
|
||||
- Improved confidence card for small spaces.
|
||||
- Improved data security by enforcing provider filtering based on the chosen confidence level. To ensure this in the future, source code analyzers have been added to warn developers about insecure code.
|
||||
- Fixed a bug in which 'APP_SETTINGS' appeared as a valid destination in the "send to" menu.
|
@ -0,0 +1,7 @@
|
||||
## Release 1.0
|
||||
|
||||
### New Rules
|
||||
|
||||
Rule ID | Category | Severity | Notes
|
||||
-----------|----------|----------|------------------------
|
||||
MWAIS0001 | Usage | Error | ProviderAccessAnalyzer
|
@ -0,0 +1,10 @@
|
||||
### New Rules
|
||||
|
||||
Rule ID | Category | Severity | Notes
|
||||
---------|----------|----------|-------
|
||||
|
||||
|
||||
### Changed Rules
|
||||
|
||||
Rule ID | New Category | New Severity | Old Category | Old Severity | Notes
|
||||
---------|--------------|--------------|--------------|--------------|-------
|
@ -0,0 +1,71 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
|
||||
namespace SourceCodeRules;
|
||||
|
||||
#pragma warning disable RS1038
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
#pragma warning restore RS1038
|
||||
public class ProviderAccessAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
private const string DIAGNOSTIC_ID = $"{Tools.ID_PREFIX}0001";
|
||||
|
||||
private static readonly string TITLE = "Direct access to `Providers` is not allowed";
|
||||
|
||||
private static readonly string MESSAGE_FORMAT = "Direct access to `SettingsManager.ConfigurationData.Providers` is not allowed. Instead, use APIs like `SettingsManager.GetPreselectedProvider`, etc.";
|
||||
|
||||
private static readonly string DESCRIPTION = MESSAGE_FORMAT;
|
||||
|
||||
private const string CATEGORY = "Usage";
|
||||
|
||||
private static readonly DiagnosticDescriptor RULE = new(DIAGNOSTIC_ID, TITLE, MESSAGE_FORMAT, CATEGORY, DiagnosticSeverity.Error, isEnabledByDefault: true, description: DESCRIPTION);
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(RULE);
|
||||
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
|
||||
context.EnableConcurrentExecution();
|
||||
context.RegisterSyntaxNodeAction(this.AnalyzeMemberAccess, SyntaxKind.SimpleMemberAccessExpression);
|
||||
}
|
||||
|
||||
private void AnalyzeMemberAccess(SyntaxNodeAnalysisContext context)
|
||||
{
|
||||
var memberAccess = (MemberAccessExpressionSyntax)context.Node;
|
||||
|
||||
// Prüfen, ob wir eine Kette von Zugriffen haben, die auf "Providers" endet
|
||||
if (memberAccess.Name.Identifier.Text != "Providers")
|
||||
return;
|
||||
|
||||
// Den kompletten Zugriffspfad aufbauen
|
||||
var fullPath = this.GetFullMemberAccessPath(memberAccess);
|
||||
|
||||
// Prüfen, ob der Pfad unserem verbotenen Muster entspricht
|
||||
if (fullPath.EndsWith("ConfigurationData.Providers"))
|
||||
{
|
||||
var diagnostic = Diagnostic.Create(RULE, memberAccess.GetLocation());
|
||||
context.ReportDiagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFullMemberAccessPath(ExpressionSyntax expression)
|
||||
{
|
||||
var parts = new List<string>();
|
||||
while (expression is MemberAccessExpressionSyntax memberAccess)
|
||||
{
|
||||
parts.Add(memberAccess.Name.Identifier.Text);
|
||||
expression = memberAccess.Expression;
|
||||
}
|
||||
|
||||
if (expression is IdentifierNameSyntax identifier)
|
||||
parts.Add(identifier.Identifier.Text);
|
||||
|
||||
parts.Reverse();
|
||||
return string.Join(".", parts);
|
||||
}
|
||||
}
|
26
app/SourceCodeRules/SourceCodeRules/SourceCodeRules.csproj
Normal file
26
app/SourceCodeRules/SourceCodeRules/SourceCodeRules.csproj
Normal file
@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||
<IsRoslynComponent>true</IsRoslynComponent>
|
||||
|
||||
<RootNamespace>SourceCodeRules</RootNamespace>
|
||||
<AssemblyName>SourceCodeRules</AssemblyName>
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.12.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
6
app/SourceCodeRules/SourceCodeRules/Tools.cs
Normal file
6
app/SourceCodeRules/SourceCodeRules/Tools.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace SourceCodeRules;
|
||||
|
||||
public static class Tools
|
||||
{
|
||||
public const string ID_PREFIX = "MWAIS";
|
||||
}
|
Loading…
Reference in New Issue
Block a user