mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-02-12 08:41:36 +00:00
Add support for document analysis policy configuration
This commit is contained in:
parent
cac7f70b16
commit
f6091be1b0
@ -64,7 +64,7 @@ else
|
|||||||
|
|
||||||
<ProfileFormSelection Disabled="@this.IsNoPolicySelected" Profile="@this.currentProfile" ProfileChanged="@this.PolicyPreselectedProfileWasChangedAsync" />
|
<ProfileFormSelection Disabled="@this.IsNoPolicySelected" Profile="@this.currentProfile" ProfileChanged="@this.PolicyPreselectedProfileWasChangedAsync" />
|
||||||
|
|
||||||
<MudTextSwitch Disabled="@(this.IsNoPolicySelected || (this.selectedPolicy?.IsManaged ?? true))" Label="@T("Would you like to protect this policy so that you cannot accidentally edit or delete it?")" Value="@this.policyIsProtected" ValueChanged="async state => await this.PolicyProtectionWasChanged(state)" LabelOn="@T("Yes, protect this policy")" LabelOff="@T("No, the policy can be edited")" />
|
<MudTextSwitch Disabled="@(this.IsNoPolicySelected || (this.selectedPolicy?.IsEnterpriseConfiguration ?? true))" Label="@T("Would you like to protect this policy so that you cannot accidentally edit or delete it?")" Value="@this.policyIsProtected" ValueChanged="async state => await this.PolicyProtectionWasChanged(state)" LabelOn="@T("Yes, protect this policy")" LabelOff="@T("No, the policy can be edited")" />
|
||||||
|
|
||||||
<MudText Typo="Typo.h5" Class="mt-6 mb-1">
|
<MudText Typo="Typo.h5" Class="mt-6 mb-1">
|
||||||
@T("Analysis and output rules")
|
@T("Analysis and output rules")
|
||||||
|
|||||||
@ -283,6 +283,8 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore<NoSettingsPan
|
|||||||
{
|
{
|
||||||
this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.Add(new ()
|
this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.Add(new ()
|
||||||
{
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
Num = this.SettingsManager.ConfigurationData.NextDocumentAnalysisPolicyNum++,
|
||||||
PolicyName = string.Format(T("Policy {0}"), DateTimeOffset.UtcNow),
|
PolicyName = string.Format(T("Policy {0}"), DateTimeOffset.UtcNow),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -213,6 +213,35 @@ CONFIG["CHAT_TEMPLATES"][#CONFIG["CHAT_TEMPLATES"]+1] = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
-- Document analysis policies for this configuration:
|
||||||
|
CONFIG["DOCUMENT_ANALYSIS_POLICIES"] = {}
|
||||||
|
|
||||||
|
-- An example document analysis policy:
|
||||||
|
-- CONFIG["DOCUMENT_ANALYSIS_POLICIES"][#CONFIG["DOCUMENT_ANALYSIS_POLICIES"]+1] = {
|
||||||
|
-- ["Id"] = "00000000-0000-0000-0000-000000000000",
|
||||||
|
-- ["PolicyName"] = "Compliance Summary Policy",
|
||||||
|
-- ["PolicyDescription"] = "Summarizes compliance-relevant clauses, obligations, and deadlines found in provided documents.",
|
||||||
|
--
|
||||||
|
-- ["AnalysisRules"] = [===[
|
||||||
|
-- Focus on compliance obligations, deadlines, and required actions.
|
||||||
|
-- Ignore marketing content and high-level summaries.
|
||||||
|
-- Flag any ambiguous or missing information.
|
||||||
|
-- ]===],
|
||||||
|
--
|
||||||
|
-- ["OutputRules"] = [===[
|
||||||
|
-- Provide a Markdown report with headings for Obligations, Deadlines,
|
||||||
|
-- and Open Questions.
|
||||||
|
-- ]===],
|
||||||
|
--
|
||||||
|
-- -- Optional: minimum provider confidence required for this policy.
|
||||||
|
-- -- Allowed values are: NONE, VERY_LOW, LOW, MODERATE, MEDIUM, HIGH
|
||||||
|
-- ["MinimumProviderConfidence"] = "MEDIUM",
|
||||||
|
--
|
||||||
|
-- -- Optional: preselect a provider or profile by ID.
|
||||||
|
-- -- The IDs must exist in CONFIG["LLM_PROVIDERS"] or CONFIG["PROFILES"].
|
||||||
|
-- ["PreselectedProvider"] = "00000000-0000-0000-0000-000000000000",
|
||||||
|
-- ["PreselectedProfile"] = "00000000-0000-0000-0000-000000000000"
|
||||||
|
-- }
|
||||||
|
|
||||||
-- Profiles for this configuration:
|
-- Profiles for this configuration:
|
||||||
CONFIG["PROFILES"] = {}
|
CONFIG["PROFILES"] = {}
|
||||||
|
|||||||
@ -81,6 +81,11 @@ public sealed class Data
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint NextChatTemplateNum { get; set; } = 1;
|
public uint NextChatTemplateNum { get; set; } = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The next document analysis policy number to use.
|
||||||
|
/// </summary>
|
||||||
|
public uint NextDocumentAnalysisPolicyNum { get; set; } = 1;
|
||||||
|
|
||||||
public DataApp App { get; init; } = new(x => x.App);
|
public DataApp App { get; init; } = new(x => x.App);
|
||||||
|
|
||||||
public DataChat Chat { get; init; } = new();
|
public DataChat Chat { get; init; } = new();
|
||||||
|
|||||||
@ -1,16 +1,37 @@
|
|||||||
using AIStudio.Provider;
|
using AIStudio.Provider;
|
||||||
|
using AIStudio.Tools.PluginSystem;
|
||||||
|
|
||||||
|
using Lua;
|
||||||
|
|
||||||
namespace AIStudio.Settings.DataModel;
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
public sealed class DataDocumentAnalysisPolicy
|
public sealed record DataDocumentAnalysisPolicy : ConfigurationBaseObject
|
||||||
{
|
{
|
||||||
|
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger<DataDocumentAnalysisPolicy>();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string Id { get; init; } = string.Empty;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override uint Num { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string Name
|
||||||
|
{
|
||||||
|
get => this.PolicyName;
|
||||||
|
init => this.PolicyName = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool IsEnterpriseConfiguration { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Preselect the policy name?
|
/// The name of the document analysis policy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PolicyName { get; set; } = string.Empty;
|
public string PolicyName { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Preselect the policy description?
|
/// The description of the document analysis policy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PolicyDescription { get; set; } = string.Empty;
|
public string PolicyDescription { get; set; } = string.Empty;
|
||||||
|
|
||||||
@ -19,11 +40,8 @@ public sealed class DataDocumentAnalysisPolicy
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsProtected { get; set; }
|
public bool IsProtected { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Is this a managed policy? Managed policies are created and managed by the organization
|
public override Guid EnterpriseConfigurationPluginId { get; init; } = Guid.Empty;
|
||||||
/// and cannot be modified or deleted by the user.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsManaged { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The rules for the document analysis policy.
|
/// The rules for the document analysis policy.
|
||||||
@ -49,4 +67,74 @@ public sealed class DataDocumentAnalysisPolicy
|
|||||||
/// Preselect a profile?
|
/// Preselect a profile?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PreselectedProfile { get; set; } = string.Empty;
|
public string PreselectedProfile { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public static bool TryProcessConfiguration(int idx, LuaTable table, Guid configPluginId, out ConfigurationBaseObject policy)
|
||||||
|
{
|
||||||
|
policy = new DataDocumentAnalysisPolicy();
|
||||||
|
if (!table.TryGetValue("Id", out var idValue) || !idValue.TryRead<string>(out var idText) || !Guid.TryParse(idText, out var id))
|
||||||
|
{
|
||||||
|
LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain a valid ID. The ID must be a valid GUID.", idx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!table.TryGetValue("PolicyName", out var nameValue) || !nameValue.TryRead<string>(out var name) || string.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain a valid PolicyName field.", idx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!table.TryGetValue("PolicyDescription", out var descriptionValue) || !descriptionValue.TryRead<string>(out var description) || string.IsNullOrWhiteSpace(description))
|
||||||
|
{
|
||||||
|
LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain a valid PolicyDescription field.", idx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!table.TryGetValue("AnalysisRules", out var analysisRulesValue) || !analysisRulesValue.TryRead<string>(out var analysisRules) || string.IsNullOrWhiteSpace(analysisRules))
|
||||||
|
{
|
||||||
|
LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain valid AnalysisRules field.", idx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!table.TryGetValue("OutputRules", out var outputRulesValue) || !outputRulesValue.TryRead<string>(out var outputRules) || string.IsNullOrWhiteSpace(outputRules))
|
||||||
|
{
|
||||||
|
LOG.LogWarning("The configured document analysis policy {PolicyIndex} does not contain valid OutputRules field.", idx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var minimumConfidence = ConfidenceLevel.NONE;
|
||||||
|
if (table.TryGetValue("MinimumProviderConfidence", out var minConfValue) && minConfValue.TryRead<string>(out var minConfText))
|
||||||
|
{
|
||||||
|
if (!Enum.TryParse(minConfText, true, out minimumConfidence))
|
||||||
|
{
|
||||||
|
LOG.LogWarning("The configured document analysis policy {PolicyIndex} contains an invalid MinimumProviderConfidence: {ConfidenceLevel}.", idx, minConfText);
|
||||||
|
minimumConfidence = ConfidenceLevel.NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var preselectedProvider = string.Empty;
|
||||||
|
if (table.TryGetValue("PreselectedProvider", out var providerValue) && providerValue.TryRead<string>(out var providerId))
|
||||||
|
preselectedProvider = providerId;
|
||||||
|
|
||||||
|
var preselectedProfile = string.Empty;
|
||||||
|
if (table.TryGetValue("PreselectedProfile", out var profileValue) && profileValue.TryRead<string>(out var profileId))
|
||||||
|
preselectedProfile = profileId;
|
||||||
|
|
||||||
|
policy = new DataDocumentAnalysisPolicy
|
||||||
|
{
|
||||||
|
Id = id.ToString(),
|
||||||
|
Num = 0, // will be set later by the PluginConfigurationObject
|
||||||
|
PolicyName = name,
|
||||||
|
PolicyDescription = description,
|
||||||
|
AnalysisRules = analysisRules,
|
||||||
|
OutputRules = outputRules,
|
||||||
|
MinimumProviderConfidence = minimumConfidence,
|
||||||
|
PreselectedProvider = preselectedProvider,
|
||||||
|
PreselectedProfile = preselectedProfile,
|
||||||
|
IsProtected = true,
|
||||||
|
IsEnterpriseConfiguration = true,
|
||||||
|
EnterpriseConfigurationPluginId = configPluginId,
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -88,6 +88,9 @@ public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginT
|
|||||||
// Handle configured profiles:
|
// Handle configured profiles:
|
||||||
PluginConfigurationObject.TryParse(PluginConfigurationObjectType.PROFILE, x => x.Profiles, x => x.NextProfileNum, mainTable, this.Id, ref this.configObjects, dryRun);
|
PluginConfigurationObject.TryParse(PluginConfigurationObjectType.PROFILE, x => x.Profiles, x => x.NextProfileNum, mainTable, this.Id, ref this.configObjects, dryRun);
|
||||||
|
|
||||||
|
// Handle configured document analysis policies:
|
||||||
|
PluginConfigurationObject.TryParse(PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY, x => x.DocumentAnalysis.Policies, x => x.NextDocumentAnalysisPolicyNum, mainTable, this.Id, ref this.configObjects, dryRun);
|
||||||
|
|
||||||
// Config: preselected profile?
|
// Config: preselected profile?
|
||||||
ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.PreselectedProfile, Guid.Empty, this.Id, settingsTable, dryRun);
|
ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.PreselectedProfile, Guid.Empty, this.Id, settingsTable, dryRun);
|
||||||
|
|
||||||
|
|||||||
@ -70,6 +70,7 @@ public sealed record PluginConfigurationObject
|
|||||||
PluginConfigurationObjectType.EMBEDDING_PROVIDER => "EMBEDDING_PROVIDERS",
|
PluginConfigurationObjectType.EMBEDDING_PROVIDER => "EMBEDDING_PROVIDERS",
|
||||||
PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER => "TRANSCRIPTION_PROVIDERS",
|
PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER => "TRANSCRIPTION_PROVIDERS",
|
||||||
PluginConfigurationObjectType.PROFILE => "PROFILES",
|
PluginConfigurationObjectType.PROFILE => "PROFILES",
|
||||||
|
PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY => "DOCUMENT_ANALYSIS_POLICIES",
|
||||||
|
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
@ -105,6 +106,7 @@ public sealed record PluginConfigurationObject
|
|||||||
PluginConfigurationObjectType.PROFILE => (Profile.TryParseProfileTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != Profile.NO_PROFILE, configurationObject),
|
PluginConfigurationObjectType.PROFILE => (Profile.TryParseProfileTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != Profile.NO_PROFILE, configurationObject),
|
||||||
PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER => (TranscriptionProvider.TryParseTranscriptionProviderTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != TranscriptionProvider.NONE, configurationObject),
|
PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER => (TranscriptionProvider.TryParseTranscriptionProviderTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != TranscriptionProvider.NONE, configurationObject),
|
||||||
PluginConfigurationObjectType.EMBEDDING_PROVIDER => (EmbeddingProvider.TryParseEmbeddingProviderTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != EmbeddingProvider.NONE, configurationObject),
|
PluginConfigurationObjectType.EMBEDDING_PROVIDER => (EmbeddingProvider.TryParseEmbeddingProviderTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != EmbeddingProvider.NONE, configurationObject),
|
||||||
|
PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY => (DataDocumentAnalysisPolicy.TryProcessConfiguration(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject is DataDocumentAnalysisPolicy, configurationObject),
|
||||||
|
|
||||||
_ => (false, NoConfigurationObject.INSTANCE)
|
_ => (false, NoConfigurationObject.INSTANCE)
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,4 +11,5 @@ public enum PluginConfigurationObjectType
|
|||||||
CHAT_TEMPLATE,
|
CHAT_TEMPLATE,
|
||||||
EMBEDDING_PROVIDER,
|
EMBEDDING_PROVIDER,
|
||||||
TRANSCRIPTION_PROVIDER,
|
TRANSCRIPTION_PROVIDER,
|
||||||
|
DOCUMENT_ANALYSIS_POLICY,
|
||||||
}
|
}
|
||||||
@ -149,6 +149,10 @@ public static partial class PluginFactory
|
|||||||
if(PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.PROFILE, x => x.Profiles, AVAILABLE_PLUGINS, configObjectList))
|
if(PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.PROFILE, x => x.Profiles, AVAILABLE_PLUGINS, configObjectList))
|
||||||
wasConfigurationChanged = true;
|
wasConfigurationChanged = true;
|
||||||
|
|
||||||
|
// Check document analysis policies:
|
||||||
|
if(PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY, x => x.DocumentAnalysis.Policies, AVAILABLE_PLUGINS, configObjectList))
|
||||||
|
wasConfigurationChanged = true;
|
||||||
|
|
||||||
// Check for a preselected profile:
|
// Check for a preselected profile:
|
||||||
if(ManagedConfiguration.IsConfigurationLeftOver(x => x.App, x => x.PreselectedProfile, AVAILABLE_PLUGINS))
|
if(ManagedConfiguration.IsConfigurationLeftOver(x => x.App, x => x.PreselectedProfile, AVAILABLE_PLUGINS))
|
||||||
wasConfigurationChanged = true;
|
wasConfigurationChanged = true;
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
# v26.2.1, build 233 (2026-02-xx xx:xx UTC)
|
# v26.2.1, build 233 (2026-02-xx xx:xx UTC)
|
||||||
- Added the ability to individually configure the minimum confidence level, standard profile, and default provider for each policy in the Document Analysis Assistant (in preview).
|
- Added the ability to individually configure the minimum confidence level, standard profile, and default provider for each policy in the Document Analysis Assistant (in preview).
|
||||||
|
- Added support for defining document analysis policies (in preview) by configuration plugins, enabling centralized management of policies across entire departments or organizations.
|
||||||
- Fixed a bug where the global minimum confidence level was not being applied to the assistants.
|
- Fixed a bug where the global minimum confidence level was not being applied to the assistants.
|
||||||
Loading…
Reference in New Issue
Block a user