Multiple Profiles can now be selected

This commit is contained in:
Peer Hogeterp committed 2026-09-07 16:09:00 +02:00
1 parent d043fbc8f0
commit cefc5464d5
89 files changed
+1360 -503

No files matched your search

@@ -11,7 +11,7 @@ public sealed class Data
/// The version of the settings file. Allows us to upgrade the settings
/// when a new version is available.
/// </summary>
public Version Version { get; init; } = Version.V6;
public Version Version { get; init; } = Version.V7;
/// <summary>
/// List of configured providers.
@@ -65,5 +65,5 @@ public sealed class DataAgenda
/// <summary>
/// Preselect a profile?
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
}
public HashSet<string>? PreselectedProfileIds { get; set; }
}
@@ -98,9 +98,9 @@ public sealed class DataApp(Expression<Func<Data, DataApp>>? configSelection = n
public string PreselectedProvider { get; set; } = ManagedConfiguration.Register(configSelection, n => n.PreselectedProvider, string.Empty);
/// <summary>
/// Should we preselect a profile for the entire app?
/// Which profiles should be preselected for the entire app?
/// </summary>
public string PreselectedProfile { get; set; } = ManagedConfiguration.Register(configSelection, n => n.PreselectedProfile, string.Empty);
public HashSet<string> PreselectedProfileIds { get; set; } = ManagedConfiguration.Register(configSelection, n => n.PreselectedProfileIds, []);
/// <summary>
/// Should we preselect a chat template for the entire app?
@@ -52,10 +52,10 @@ public sealed class DataBiasOfTheDay
/// <summary>
/// Preselect a profile?
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
public HashSet<string>? PreselectedProfileIds { get; set; }
/// <summary>
/// Preselect a provider?
/// </summary>
public string PreselectedProvider { get; set; } = string.Empty;
}
}
@@ -42,9 +42,9 @@ public sealed class DataChat(Expression<Func<Data, DataChat>>? configSelection =
public string PreselectedProvider { get; set; } = ManagedConfiguration.Register(configSelection, n => n.PreselectedProvider, string.Empty);
/// <summary>
/// Preselect a profile?
/// Which profiles should be preselected? Null uses the app default.
/// </summary>
public string PreselectedProfile { get; set; } = ManagedConfiguration.Register(configSelection, n => n.PreselectedProfile, string.Empty);
public HashSet<string>? PreselectedProfileIds { get; set; } = ManagedConfiguration.RegisterProfilePreselection(configSelection, n => n.PreselectedProfileIds);
/// <summary>
/// Preselect a chat template?
@@ -97,4 +97,4 @@ public sealed class DataChat(Expression<Func<Data, DataChat>>? configSelection =
/// Should we show the latest message after loading? When false, we show the first (aka oldest) message.
/// </summary>
public bool ShowLatestMessageAfterLoading { get; set; } = true;
}
}
@@ -38,5 +38,5 @@ public sealed class DataCoding
/// <summary>
/// Preselect a profile?
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
}
public HashSet<string>? PreselectedProfileIds { get; set; }
}
@@ -77,9 +77,9 @@ public sealed record DataDocumentAnalysisPolicy : ConfigurationBaseObject
public string PreselectedProvider { get; set; } = string.Empty;
/// <summary>
/// Preselect a profile?
/// Which profiles should be preselected? Null uses the app default.
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
public HashSet<string>? PreselectedProfileIds { get; set; }
/// <summary>
/// Hide the policy definition section in the UI?
@@ -135,9 +135,31 @@ public sealed record DataDocumentAnalysisPolicy : ConfigurationBaseObject
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;
var hasLegacyProfile = table.TryGetValue("PreselectedProfile", out var profileValue);
var hasProfileIds = table.TryGetValue("PreselectedProfileIds", out var profileIdsValue);
if (hasLegacyProfile && hasProfileIds)
{
LOG.LogWarning("The configured document analysis policy {PolicyIndex} contains both PreselectedProfile and PreselectedProfileIds.", idx);
return false;
}
HashSet<string>? preselectedProfileIds = null;
if (hasLegacyProfile)
{
if (!profileValue.TryRead<string>(out var profileId) || !TryNormalizeLegacyProfileId(profileId, out preselectedProfileIds))
{
LOG.LogWarning("The configured document analysis policy {PolicyIndex} contains an invalid PreselectedProfile.", idx);
return false;
}
}
else if (hasProfileIds)
{
if (!profileIdsValue.TryRead<LuaTable>(out var profileIdsTable) || !TryReadProfileIds(profileIdsTable, out preselectedProfileIds))
{
LOG.LogWarning("The configured document analysis policy {PolicyIndex} contains invalid PreselectedProfileIds. Expected unique, non-empty GUIDs.", idx);
return false;
}
}
var hidePolicyDefinition = false;
if (table.TryGetValue("HidePolicyDefinition", out var hideValue) && hideValue.TryRead<bool>(out var hide))
@@ -171,7 +193,7 @@ public sealed record DataDocumentAnalysisPolicy : ConfigurationBaseObject
MinimumProviderConfidence = minimumConfidence,
AllowedToolIds = allowedToolIds,
PreselectedProvider = preselectedProvider,
PreselectedProfile = preselectedProfile,
PreselectedProfileIds = preselectedProfileIds,
HidePolicyDefinition = hidePolicyDefinition,
IsProtected = true,
IsEnterpriseConfiguration = true,
@@ -180,4 +202,36 @@ public sealed record DataDocumentAnalysisPolicy : ConfigurationBaseObject
return true;
}
}
private static bool TryNormalizeLegacyProfileId(string profileId, out HashSet<string>? profileIds)
{
profileIds = null;
if (string.IsNullOrWhiteSpace(profileId))
return true;
if (!Guid.TryParse(profileId, out var parsed))
return false;
profileIds = parsed == Guid.Empty ? [] : [parsed.ToString()];
return true;
}
private static bool TryReadProfileIds(LuaTable table, out HashSet<string>? profileIds)
{
var parsedIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
for (var index = 1; index <= table.ArrayLength; index++)
{
if (!table[index].TryRead<string>(out var profileId) ||
!Guid.TryParse(profileId, out var parsed) ||
parsed == Guid.Empty ||
!parsedIds.Add(parsed.ToString()))
{
profileIds = null;
return false;
}
}
profileIds = parsedIds;
return true;
}
}
@@ -48,5 +48,5 @@ public sealed class DataEMail
/// <summary>
/// Preselect a profile?
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
}
public HashSet<string>? PreselectedProfileIds { get; set; }
}
@@ -32,5 +32,5 @@ public sealed class DataERI
/// <summary>
/// Preselect a profile?
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
}
public HashSet<string>? PreselectedProfileIds { get; set; }
}
@@ -37,5 +37,5 @@ public class DataLegalCheck
/// <summary>
/// Preselect a profile?
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
}
public HashSet<string>? PreselectedProfileIds { get; set; }
}
@@ -32,5 +32,5 @@ public sealed class DataMyTasks
/// <summary>
/// Preselect a profile?
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
}
public HashSet<string>? PreselectedProfileIds { get; set; }
}
@@ -13,7 +13,7 @@ public class DataSlideBuilder
/// <summary>
/// Preselect a profile?
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
public HashSet<string>? PreselectedProfileIds { get; set; }
/// <summary>
/// Preselect a Slide Builder provider?
@@ -59,4 +59,4 @@ public class DataSlideBuilder
/// The minimum confidence level required for a provider to be considered.
/// </summary>
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
}
}
@@ -19,9 +19,9 @@ public sealed class DataVisualBriefing(Expression<Func<Data, DataVisualBriefing>
}
/// <summary>
/// Gets or sets the preselected profile identifier.
/// Gets or sets the preselected profile identifiers. Null uses the app default.
/// </summary>
public string PreselectedProfile { get; set; } = ManagedConfiguration.Register(configSelection, value => value.PreselectedProfile, string.Empty);
public HashSet<string>? PreselectedProfileIds { get; set; } = ManagedConfiguration.RegisterProfilePreselection(configSelection, value => value.PreselectedProfileIds);
/// <summary>
/// Gets or sets the preselected provider identifier.
@@ -72,4 +72,4 @@ public sealed class DataVisualBriefing(Expression<Func<Data, DataVisualBriefing>
/// Gets or sets the minimum confidence accepted for the selected provider.
/// </summary>
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ManagedConfiguration.Register(configSelection, value => value.MinimumProviderConfidence, ConfidenceLevel.NONE);
}
}