AI-Studio/app/MindWork AI Studio/Settings/ConfigurationSelectDataFactory.cs
Thorsten Sommer fe35630eff
Merge branch 'main' into chunk-data
Resolved 29 conflicting files. The notable decisions:

Confidence: main's tool-calling gate (RequiredProviderConfidence) and this
branch's local-RAG gate (DataConfidenceLevel) turned out to be the same rule
on the same axis, so they are now one field. Both tool results and data
sources raise it through RequireProviderConfidence(). The gate checks the
level strictly and no longer exempts providers trusted by configuration:
TrustedProviderIds is documented as applying to data-source security checks
only, and organizations set confidence through DataConfidence
.CustomConfidenceScheme instead. The security axis (DataSecurity, ERI,
IsTrustedForDataSourceSecurityChecks) is unchanged.

Provider creation: main's CreateProvider signature won (hfEndpointKind,
capabilityOverrides, no model parameter); tokenizerPath was added to it and
is set for every provider, including the new Hetzner, IONOS and LiteLLM.
Provider and EmbeddingProvider combine the record parameters, Lua parsing and
Lua serialization of both sides.

File types: main's hierarchy (ODT leaf, WORD parent, PowerPoint without the
legacy .ppt, TABULAR instead of DELIMITED_TABLE) plus this branch's
SPREADSHEET parent with ODS and the xlsm/xlsb/xla/xlam extensions, which the
runtime already reads. Both sides had added a conflicting HTML filter; the
reading family keeps the name, and the export path uses a narrow
HTML_DOCUMENT, following the existing LATEX/TEX split.

Runtime: main's file_data.rs is the base, including the prompt-injection
sanitizer and the extraction routes. Token counting and chunk segmentation
moved into take_released, so they act on the text the filter has released
rather than on text it is still holding. A failed count is logged and left
out instead of ending the extraction, because the app counts such a segment
itself.

Data sources: the participating-provider checks of this branch are kept, and
main's GetAllowedDataSources overload now builds on them. DirectChatService
resolves the launched chat's data source options before the check, so filter
and chat see the same options.

.NET and Rust both build clean; I18N regenerated to 4060 keys.
2026-09-05 21:20:33 +02:00

327 lines
16 KiB
C#

using AIStudio.Assistants.Agenda;
using AIStudio.Assistants.Coding;
using AIStudio.Assistants.IconFinder;
using AIStudio.Assistants.RewriteImprove;
using AIStudio.Assistants.SlideBuilder;
using AIStudio.Assistants.TextSummarizer;
using AIStudio.Assistants.EMail;
using AIStudio.Provider;
using AIStudio.Agents.AssistantAudit;
using AIStudio.Settings.DataModel;
using AIStudio.Tools.PluginSystem;
using WritingStylesRewrite = AIStudio.Assistants.RewriteImprove.WritingStyles;
using WritingStylesEMail = AIStudio.Assistants.EMail.WritingStyles;
namespace AIStudio.Settings;
/// <summary>
/// A static factory class to get the lists of selectable values.
/// </summary>
public static class ConfigurationSelectDataFactory
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ConfigurationSelectDataFactory).Namespace, nameof(ConfigurationSelectDataFactory));
public static IEnumerable<ConfigurationSelectData<LangBehavior>> GetLangBehaviorData()
{
foreach (var behavior in Enum.GetValues<LangBehavior>())
yield return new(behavior.Name(), behavior);
}
public static IEnumerable<ConfigurationSelectData<Guid>> GetLanguagesData()
{
foreach (var runningPlugin in PluginFactory.RunningPlugins)
{
if(runningPlugin is ILanguagePlugin languagePlugin)
yield return new(languagePlugin.LangName, runningPlugin.Id);
}
}
public static IEnumerable<ConfigurationSelectData<LoadingChatProviderBehavior>> GetLoadingChatProviderBehavior()
{
yield return new(TB("When possible, use the LLM provider which was used for each chat in the first place"), LoadingChatProviderBehavior.USE_CHAT_PROVIDER_IF_AVAILABLE);
yield return new(TB("Use the latest LLM provider, which was used before; use the default chat provider initially"), LoadingChatProviderBehavior.ALWAYS_USE_LATEST_CHAT_PROVIDER);
yield return new(TB("Always use the default chat provider when loading chats"), LoadingChatProviderBehavior.ALWAYS_USE_DEFAULT_CHAT_PROVIDER);
}
public static IEnumerable<ConfigurationSelectData<AddChatProviderBehavior>> GetAddChatProviderBehavior()
{
yield return new(TB("Use the latest LLM provider, which was used before; use the default chat provider initially"), AddChatProviderBehavior.ADDED_CHATS_USE_LATEST_PROVIDER);
yield return new(TB("Always use the default chat provider for new chats"), AddChatProviderBehavior.ADDED_CHATS_USE_DEFAULT_PROVIDER);
}
public static IEnumerable<ConfigurationSelectData<SendBehavior>> GetSendBehaviorData()
{
yield return new(TB("No key is sending the input"), SendBehavior.NO_KEY_IS_SENDING);
yield return new(TB("Modifier key + enter is sending the input"), SendBehavior.MODIFER_ENTER_IS_SENDING);
yield return new(TB("Enter is sending the input"), SendBehavior.ENTER_IS_SENDING);
}
public static IEnumerable<ConfigurationSelectData<UpdateInterval>> GetUpdateIntervalData()
{
yield return new(TB("No automatic update checks"), UpdateInterval.NO_CHECK);
yield return new(TB("Once at startup"), UpdateInterval.ONCE_STARTUP);
yield return new(TB("Check every hour"), UpdateInterval.HOURLY);
yield return new(TB("Check every day"), UpdateInterval.DAILY);
yield return new (TB("Check every week"), UpdateInterval.WEEKLY);
}
public static IEnumerable<ConfigurationSelectData<UpdateInterval>> GetManagedUpdateIntervalData(UpdateInterval currentValue)
{
if (currentValue is UpdateInterval.DISABLE_UPDATES)
yield return new(TB("Updates disabled by your organization"), UpdateInterval.DISABLE_UPDATES);
foreach (var option in GetUpdateIntervalData())
yield return option;
}
public static IEnumerable<ConfigurationSelectData<UpdateInstallation>> GetUpdateBehaviourData()
{
yield return new(TB("Install updates manually"), UpdateInstallation.MANUAL);
yield return new(TB("Install updates automatically"), UpdateInstallation.AUTOMATIC);
}
public static IEnumerable<ConfigurationSelectData<WorkspaceStorageBehavior>> GetWorkspaceStorageBehaviorData()
{
yield return new(TB("Disable workspaces"), WorkspaceStorageBehavior.DISABLE_WORKSPACES);
yield return new(TB("Store chats automatically"), WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY);
yield return new(TB("Store chats manually"), WorkspaceStorageBehavior.STORE_CHATS_MANUALLY);
}
public static IEnumerable<ConfigurationSelectData<WorkspaceStorageTemporaryMaintenancePolicy>> GetWorkspaceStorageTemporaryMaintenancePolicyData()
{
yield return new(TB("No automatic maintenance for disappearing chats; old chats will never be deleted"), WorkspaceStorageTemporaryMaintenancePolicy.NO_AUTOMATIC_MAINTENANCE);
yield return new(TB("Delete disappearing chats older than 7 days"), WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_7_DAYS);
yield return new(TB("Delete disappearing chats older than 30 days"), WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_30_DAYS);
yield return new(TB("Delete disappearing chats older than 90 days"), WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS);
yield return new(TB("Delete disappearing chats older than 180 days"), WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_180_DAYS);
yield return new(TB("Delete disappearing chats older than 1 year"), WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_365_DAYS);
}
public static IEnumerable<ConfigurationSelectData<WorkspaceDisplayBehavior>> GetWorkspaceDisplayBehaviorData()
{
yield return new(TB("Toggle the overlay: the chat uses all the space, workspaces are temporarily shown"), WorkspaceDisplayBehavior.TOGGLE_OVERLAY);
yield return new(TB("Toggle the sidebar: show the workspaces next to the chat when desired"), WorkspaceDisplayBehavior.TOGGLE_SIDEBAR);
yield return new(TB("Sidebar is always visible: show the workspaces next to the chat all the time"), WorkspaceDisplayBehavior.SIDEBAR_ALWAYS_VISIBLE);
}
public static IEnumerable<ConfigurationSelectData<PreviewVisibility>> GetPreviewVisibility()
{
yield return new(TB("All preview features are hidden"), PreviewVisibility.NONE);
yield return new(TB("Also show features ready for release; these should be stable"), PreviewVisibility.RELEASE_CANDIDATE);
yield return new(TB("Also show features in beta: these are almost ready for release; expect some bugs"), PreviewVisibility.BETA);
yield return new(TB("Also show features in alpha: these are in development; expect bugs and missing features"), PreviewVisibility.ALPHA);
yield return new(TB("Show also prototype features: these are works in progress; expect bugs and missing features"), PreviewVisibility.PROTOTYPE);
yield return new(TB("Show also experimental features: these are experimental; expect bugs, missing features, many changes"), PreviewVisibility.EXPERIMENTAL);
}
public static IEnumerable<ConfigurationSelectData<PreviewFeatures>> GetPreviewFeaturesData(SettingsManager settingsManager)
{
foreach (var source in settingsManager.ConfigurationData.App.PreviewVisibility.GetPreviewFeatures().Where(x => !x.IsReleased()))
yield return new(source.GetPreviewDescription(), source);
}
public static IEnumerable<ConfigurationSelectData<SendToChatDataSourceBehavior>> GetSendToChatDataSourceBehaviorData()
{
foreach (var behavior in Enum.GetValues<SendToChatDataSourceBehavior>())
yield return new(behavior.Description(), behavior);
}
public static IEnumerable<ConfigurationSelectData<NavBehavior>> GetNavBehaviorData()
{
yield return new(TB("Navigation expands on mouse hover"), NavBehavior.EXPAND_ON_HOVER);
yield return new(TB("Navigation never expands, but there are tooltips"), NavBehavior.NEVER_EXPAND_USE_TOOLTIPS);
yield return new(TB("Navigation never expands, no tooltips"), NavBehavior.NEVER_EXPAND_NO_TOOLTIPS);
yield return new(TB("Always expand navigation"), NavBehavior.ALWAYS_EXPAND);
}
public static IEnumerable<ConfigurationSelectData<StartPage>> GetStartPageData()
{
yield return new(TB("Welcome"), StartPage.HOME);
yield return new(TB("Chat"), StartPage.CHAT);
yield return new(TB("Assistants"), StartPage.ASSISTANTS);
yield return new(TB("Information"), StartPage.INFORMATION);
yield return new(TB("Plugins"), StartPage.PLUGINS);
yield return new(TB("Supporters"), StartPage.SUPPORTERS);
yield return new(TB("Settings"), StartPage.SETTINGS);
}
public static IEnumerable<ConfigurationSelectData<IconSources>> GetIconSourcesData()
{
foreach (var source in Enum.GetValues<IconSources>())
yield return new(source.Name(), source);
}
public static IEnumerable<ConfigurationSelectData<CommonLanguages>> GetCommonLanguagesData()
{
foreach (var language in Enum.GetValues<CommonLanguages>())
yield return new(language.Name(), language);
}
public static IEnumerable<ConfigurationSelectData<CommonLanguages>> GetCommonLanguagesTranslationData()
{
foreach (var language in Enum.GetValues<CommonLanguages>())
if(language is CommonLanguages.AS_IS)
yield return new(TB("Not yet specified"), language);
else
yield return new(language.Name(), language);
}
public static IEnumerable<ConfigurationSelectData<CommonLanguages>> GetCommonLanguagesOptionalData()
{
foreach (var language in Enum.GetValues<CommonLanguages>())
if(language is CommonLanguages.AS_IS)
yield return new(TB("Do not specify the language"), language);
else
yield return new(language.Name(), language);
}
public static IEnumerable<ConfigurationSelectData<CommonCodingLanguages>> GetCommonCodingLanguagesData()
{
foreach (var language in Enum.GetValues<CommonCodingLanguages>())
yield return new(language.Name(), language);
}
public static IEnumerable<ConfigurationSelectData<Complexity>> GetComplexityData()
{
foreach (var complexity in Enum.GetValues<Complexity>())
yield return new(complexity.Name(), complexity);
}
public static IEnumerable<ConfigurationSelectData<NumberParticipants>> GetNumberParticipantsData()
{
foreach (var number in Enum.GetValues<NumberParticipants>())
yield return new(number.Name(), number);
}
public static IEnumerable<ConfigurationSelectData<WritingStylesRewrite>> GetWritingStyles4RewriteData()
{
foreach (var style in Enum.GetValues<WritingStylesRewrite>())
yield return new(style.Name(), style);
}
public static IEnumerable<ConfigurationSelectData<WritingStylesEMail>> GetWritingStyles4EMailData()
{
foreach (var style in Enum.GetValues<WritingStylesEMail>())
yield return new(style.Name(), style);
}
public static IEnumerable<ConfigurationSelectData<SentenceStructure>> GetSentenceStructureData()
{
foreach (var voice in Enum.GetValues<SentenceStructure>())
yield return new(voice.Name(), voice);
}
public static IEnumerable<ConfigurationSelectData<AudienceProfile>> GetSlideBuilderAudienceProfileData()
{
foreach (var profile in Enum.GetValues<AudienceProfile>())
yield return new(profile.Name(), profile);
}
public static IEnumerable<ConfigurationSelectData<AudienceAgeGroup>> GetSlideBuilderAudienceAgeGroupData()
{
foreach (var ageGroup in Enum.GetValues<AudienceAgeGroup>())
yield return new(ageGroup.Name(), ageGroup);
}
public static IEnumerable<ConfigurationSelectData<AudienceOrganizationalLevel>> GetSlideBuilderAudienceOrganizationalLevelData()
{
foreach (var level in Enum.GetValues<AudienceOrganizationalLevel>())
yield return new(level.Name(), level);
}
public static IEnumerable<ConfigurationSelectData<AudienceExpertise>> GetSlideBuilderAudienceExpertiseData()
{
foreach (var expertise in Enum.GetValues<AudienceExpertise>())
yield return new(expertise.Name(), expertise);
}
public static IEnumerable<ConfigurationSelectData<string>> GetProfilesData(IEnumerable<Profile> profiles)
{
foreach (var profile in profiles.GetAllProfiles())
yield return new(profile.GetSafeName(), profile.Id);
}
public static IEnumerable<ConfigurationSelectData<ProfilePreselection>> GetComponentProfilesData(IEnumerable<Profile> profiles)
{
yield return new(TB("Use app default profile"), ProfilePreselection.AppDefault);
yield return new(Profile.NO_PROFILE.GetSafeName(), ProfilePreselection.NoProfile);
foreach (var profile in profiles)
yield return new(profile.GetSafeName(), ProfilePreselection.Specific(profile.Id));
}
public static IEnumerable<ConfigurationSelectData<string>> GetTranscriptionProvidersData(IEnumerable<TranscriptionProvider> transcriptionProviders)
{
foreach (var provider in transcriptionProviders)
yield return new(provider.Name, provider.Id);
}
public static IEnumerable<ConfigurationSelectData<string>> GetChatTemplatesData(IEnumerable<ChatTemplate> chatTemplates)
{
foreach (var chatTemplate in chatTemplates.GetAllChatTemplates())
yield return new(chatTemplate.GetSafeName(), chatTemplate.Id);
}
public static IEnumerable<ConfigurationSelectData<ConfidenceSchemes>> GetConfidenceSchemesData()
{
foreach (var scheme in Enum.GetValues<ConfidenceSchemes>())
yield return new(scheme.GetListDescription(), scheme);
}
public static IEnumerable<ConfigurationSelectData<ConfidenceLevel>> GetConfidenceLevelsData(SettingsManager settingsManager, bool restrictToGlobalMinimum = false)
{
var minimumLevel = ConfidenceLevel.NONE;
if(restrictToGlobalMinimum && settingsManager.ConfigurationData.Confidence is { EnforceGlobalMinimumConfidence: true, GlobalMinimumConfidence: not ConfidenceLevel.NONE and not ConfidenceLevel.UNKNOWN })
minimumLevel = settingsManager.ConfigurationData.Confidence.GlobalMinimumConfidence;
foreach (var level in Enum.GetValues<ConfidenceLevel>())
{
if(level is ConfidenceLevel.NONE)
yield return new(TB("No minimum confidence level chosen"), level);
if(level < minimumLevel)
continue;
switch (level)
{
case ConfidenceLevel.NONE:
case ConfidenceLevel.UNKNOWN:
continue;
default:
yield return new(level.GetName(), level);
break;
}
}
}
public static IEnumerable<ConfigurationSelectData<ConfidenceLevel>> GetDataSourceConfidenceLevelsData()
{
foreach (var level in Enum.GetValues<ConfidenceLevel>())
{
if (level is ConfidenceLevel.NONE)
continue;
yield return new(level.GetName(), level);
}
}
public static IEnumerable<ConfigurationSelectData<Themes>> GetThemesData()
{
foreach (var theme in Enum.GetValues<Themes>())
yield return new(theme.GetName(), theme);
}
public static IEnumerable<ConfigurationSelectData<AssistantAuditLevel>> GetAssistantAuditLevelsData()
{
foreach (var level in Enum.GetValues<AssistantAuditLevel>())
{
if (level == AssistantAuditLevel.UNKNOWN)
continue;
yield return new(level.GetName(), level);
}
}
}