Added the choice between formal and informal address to the whole app (#1200)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-13 10:16:56 +01:00
1 parent 382db4b8d0
commit c9a376f742
342 files changed
+14378 -1893

No files matched your search

@@ -109,6 +109,8 @@ public record ChatTemplate(
public string? WorkspaceName { get; set; }
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ChatTemplate).Namespace, nameof(ChatTemplate));
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(ChatTemplate).Namespace, nameof(ChatTemplate));
private static readonly ILogger<ChatTemplate> LOGGER = Program.LOGGER_FACTORY.CreateLogger<ChatTemplate>();
@@ -601,7 +603,7 @@ public record ChatTemplate(
if (string.IsNullOrWhiteSpace(pluginDirectory) || !File.Exists(Path.Combine(pluginDirectory, "plugin.lua")))
{
issue = TB("Please select a valid configuration plugin folder. The folder must contain a plugin.lua file.");
issue = TA("Please select a valid configuration plugin folder. The folder must contain a plugin.lua file.");
return false;
}
@@ -21,6 +21,8 @@ namespace AIStudio.Settings;
public static class ConfigurationSelectDataFactory
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ConfigurationSelectDataFactory).Namespace, nameof(ConfigurationSelectDataFactory));
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(ConfigurationSelectDataFactory).Namespace, nameof(ConfigurationSelectDataFactory));
public static IEnumerable<ConfigurationSelectData<LangBehavior>> GetLangBehaviorData()
{
@@ -52,7 +54,7 @@ public static class ConfigurationSelectDataFactory
public static IEnumerable<ConfigurationSelectData<SendBehavior>> GetSendBehaviorData()
{
yield return new(TB("No key is sending the input"), SendBehavior.NO_KEY_IS_SENDING);
yield return new(TA("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);
}
@@ -69,7 +71,7 @@ public static class ConfigurationSelectDataFactory
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);
yield return new(TA("Updates disabled by your organization"), UpdateInterval.DISABLE_UPDATES);
foreach (var option in GetUpdateIntervalData())
yield return option;
@@ -330,7 +332,7 @@ public static class ConfigurationSelectDataFactory
yield return new(level.Name, level);
}
public static IEnumerable<ConfigurationSelectData<AddressForm>> GetBeyondFactsLabAddressFormData()
public static IEnumerable<ConfigurationSelectData<AddressForm>> GetAddressFormData()
{
foreach (var addressForm in Enum.GetValues<AddressForm>())
yield return new(addressForm.Name, addressForm);
@@ -23,7 +23,13 @@ public sealed class DataApp(Expression<Func<Data, DataApp>>? configSelection = n
/// The language plugin ID to use.
/// </summary>
public Guid LanguagePluginId { get; set; } = Guid.Empty;
/// <summary>
/// How the texts address the person in languages with a formal and an informal address, such as German; see
/// I18N.AddressForm.
/// </summary>
public AddressForm AddressForm { get; set; } = ManagedConfiguration.Register(configSelection, n => n.AddressForm, AddressForm.FORMAL);
/// <summary>
/// The preferred theme to use.
/// </summary>
@@ -40,11 +40,6 @@ public sealed class DataBeyondFactsLab(Expression<Func<Data, DataBeyondFactsLab>
/// </remarks>
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ManagedConfiguration.Register(configSelection, value => value.MinimumProviderConfidence, MINIMUM_CONFIDENCE_FLOOR);
/// <summary>
/// Gets or sets how the lab addresses the person in languages with a formal and an informal address.
/// </summary>
public AddressForm AddressForm { get; set; } = ManagedConfiguration.Register(configSelection, value => value.AddressForm, AddressForm.FORMAL);
/// <summary>
/// Gets or sets whether files in the folder for prompt overrides replace the prompts which come with the lab.
/// </summary>
@@ -5,25 +5,27 @@ namespace AIStudio.Settings.DataModel;
public static class DataSourceSecurityExtensions
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(DataSourceSecurityExtensions).Namespace, nameof(DataSourceSecurityExtensions));
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(DataSourceSecurityExtensions).Namespace, nameof(DataSourceSecurityExtensions));
extension(DataSourceSecurity security)
{
public string SelectionText => security switch
{
DataSourceSecurity.NOT_SPECIFIED => TB("Please select a security policy"),
DataSourceSecurity.NOT_SPECIFIED => TA("Please select a security policy"),
DataSourceSecurity.ALLOW_ANY => TB("This data source can be used with any LLM provider. Your data may be sent to a cloud-based provider."),
DataSourceSecurity.SELF_HOSTED => TB("This data source can only be used with a self-hosted LLM provider. Your data will not be sent to any cloud-based provider."),
DataSourceSecurity.ALLOW_ANY => TA("This data source can be used with any LLM provider. Your data may be sent to a cloud-based provider."),
DataSourceSecurity.SELF_HOSTED => TA("This data source can only be used with a self-hosted LLM provider. Your data will not be sent to any cloud-based provider."),
_ => TB("Unknown security policy")
};
public string InfoText => security switch
{
DataSourceSecurity.NOT_SPECIFIED => TB("The security of the data source is not specified yet. You cannot use this data source until you specify a security policy."),
DataSourceSecurity.NOT_SPECIFIED => TA("The security of the data source is not specified yet. You cannot use this data source until you specify a security policy."),
DataSourceSecurity.ALLOW_ANY => TB("This data source can be used with any LLM provider. Your data may be sent to a cloud-based provider."),
DataSourceSecurity.SELF_HOSTED => TB("This data source can only be used with a self-hosted LLM provider. Your data will not be sent to any cloud-based provider."),
DataSourceSecurity.ALLOW_ANY => TA("This data source can be used with any LLM provider. Your data may be sent to a cloud-based provider."),
DataSourceSecurity.SELF_HOSTED => TA("This data source can only be used with a self-hosted LLM provider. Your data will not be sent to any cloud-based provider."),
_ => TB("Unknown security policy")
};
@@ -5,12 +5,14 @@ namespace AIStudio.Settings.DataModel;
public static class LangBehaviorExtensions
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(LangBehaviorExtensions).Namespace, nameof(LangBehaviorExtensions));
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(LangBehaviorExtensions).Namespace, nameof(LangBehaviorExtensions));
extension(LangBehavior langBehavior)
{
public string Name => langBehavior switch
{
LangBehavior.AUTO => TB("Choose the language automatically, based on your system language."),
LangBehavior.AUTO => TA("Choose the language automatically, based on your system language."),
LangBehavior.MANUAL => TB("Choose the language manually."),
_ => TB("Unknown option")
@@ -5,6 +5,8 @@ namespace AIStudio.Settings.DataModel;
public static class OutboundDataRequirementExtensions
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(OutboundDataRequirementExtensions).Namespace, nameof(OutboundDataRequirementExtensions));
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(OutboundDataRequirementExtensions).Namespace, nameof(OutboundDataRequirementExtensions));
/// <param name="requirement">What the chat demands.</param>
extension(OutboundDataRequirement requirement)
{
@@ -24,7 +26,7 @@ public static class OutboundDataRequirementExtensions
public string GetToolBlockedMessage(Data settings) => requirement.Origin switch
{
OutboundDataOrigin.MAILBOX => GetMailboxBlockedMessage(requirement, settings.Mailboxes),
OutboundDataOrigin.CONFLUENCE_WIKI => string.Format(TB("This chat holds content from your Confluence wiki, found while the setting 'Where a chat may send data after reading internal pages' of the tool 'Read Web Page' was '{0}'. This tool would send data beyond that, so it is not available in this chat. A new chat without this content can use it again."), requirement.Restriction.Name),
OutboundDataOrigin.CONFLUENCE_WIKI => string.Format(TA("This chat holds content from your Confluence wiki, found while the setting 'Where a chat may send data after reading internal pages' of the tool 'Read Web Page' was '{0}'. This tool would send data beyond that, so it is not available in this chat. A new chat without this content can use it again."), requirement.Restriction.Name),
OutboundDataOrigin.INTERNAL_WEB_PAGE => string.Format(TB("This chat holds content from an internal web page on '{0}', read while the setting 'Where a chat may send data after reading internal pages' of the tool 'Read Web Page' was '{1}'. This tool would send data beyond that, so it is not available in this chat. A new chat without this content can use it again."), requirement.Reference, requirement.Restriction.Name),
OutboundDataOrigin.DATA_SOURCE => GetDataSourceBlockedMessage(requirement, settings.DataSources),
OutboundDataOrigin.BEYOND_FACTS_LAB => TB("This chat holds a preparation of the BeyondFacts Lab, which may be unpublished, so it reads only web pages whose addresses stand in the chat. This tool would send data beyond that, so it is not available in this chat. The lab searches the web in a research of its own, which receives only the public details about the event. A new chat without this content can use it again."),
@@ -6,6 +6,8 @@ public static class OutboundDataRestrictionExtensions
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(OutboundDataRestrictionExtensions).Namespace, nameof(OutboundDataRestrictionExtensions));
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(OutboundDataRestrictionExtensions).Namespace, nameof(OutboundDataRestrictionExtensions));
/// <param name="restriction">The restriction, as it was read.</param>
extension(OutboundDataRestriction restriction)
{
@@ -49,9 +51,9 @@ public static class OutboundDataRestrictionExtensions
/// </summary>
public string Description => restriction switch
{
OutboundDataRestriction.ONLY_CONFIGURED_SERVICES => TB("The chat may only use services configured in AI Studio: your mailboxes, your data sources, your Confluence wiki, and the allowed private hosts of the tool 'Read Web Page'. It reads no other web pages, and it does not search the web."),
OutboundDataRestriction.ONLY_LINKS_FROM_CHAT => TB("The chat may also read web pages whose addresses stand in the chat, written by you or returned by a tool, exactly as they stand there. It does not search the web, and the AI cannot choose addresses of its own outside the services configured in AI Studio."),
OutboundDataRestriction.UNRESTRICTED => TB("The chat may use every tool you chose, web search and any web page included. Internal content, such as your mails or the documents of your data sources, can then reach third parties, e.g., inside a search query or the address of a web page."),
OutboundDataRestriction.ONLY_CONFIGURED_SERVICES => TA("The chat may only use services configured in AI Studio: your mailboxes, your data sources, your Confluence wiki, and the allowed private hosts of the tool 'Read Web Page'. It reads no other web pages, and it does not search the web."),
OutboundDataRestriction.ONLY_LINKS_FROM_CHAT => TA("The chat may also read web pages whose addresses stand in the chat, written by you or returned by a tool, exactly as they stand there. It does not search the web, and the AI cannot choose addresses of its own outside the services configured in AI Studio."),
OutboundDataRestriction.UNRESTRICTED => TA("The chat may use every tool you chose, web search and any web page included. Internal content, such as your mails or the documents of your data sources, can then reach third parties, e.g., inside a search query or the address of a web page."),
_ => TB("This version of AI Studio does not know this restriction, so it applies the strictest one."),
};
@@ -5,6 +5,8 @@ namespace AIStudio.Settings.DataModel;
public static class PreviewFeaturesExtensions
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(PreviewFeaturesExtensions).Namespace, nameof(PreviewFeaturesExtensions));
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(PreviewFeaturesExtensions).Namespace, nameof(PreviewFeaturesExtensions));
/// <param name="feature">The preview feature to check.</param>
extension(PreviewFeatures feature)
@@ -12,17 +14,17 @@ public static class PreviewFeaturesExtensions
public string PreviewDescription => feature switch
{
PreviewFeatures.PRE_WRITER_MODE_2024 => TB("Writer Mode: Experiments about how to write long texts using AI"),
PreviewFeatures.PRE_RAG_2024 => TB("RAG: Preview of our RAG implementation where you can refer your files or integrate enterprise data within your company"),
PreviewFeatures.PRE_RAG_2024 => TA("RAG: Preview of our RAG implementation where you can refer your files or integrate enterprise data within your company"),
PreviewFeatures.PRE_PLUGINS_2025 => TB("Plugins: Preview of our plugin system where you can extend the functionality of the app"),
PreviewFeatures.PRE_READ_PDF_2025 => TB("Read PDF: Preview of our PDF reading system where you can read and extract text from PDF files"),
PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025 => TB("Document Analysis: Preview of our document analysis system where you can analyze and extract information from documents"),
PreviewFeatures.PRE_PLUGINS_2025 => TA("Plugins: Preview of our plugin system where you can extend the functionality of the app"),
PreviewFeatures.PRE_READ_PDF_2025 => TA("Read PDF: Preview of our PDF reading system where you can read and extract text from PDF files"),
PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025 => TA("Document Analysis: Preview of our document analysis system where you can analyze and extract information from documents"),
PreviewFeatures.PRE_SPEECH_TO_TEXT_2026 => TB("Transcription: Convert recordings and audio files into text"),
PreviewFeatures.PRE_META_ASSISTANT_V1 => TB("Assistant Builder: Generate and install assistant plugins"),
PreviewFeatures.PRE_VISUAL_BRIEFING_ASSISTANT_2026 => TB("Visual Briefing Assistant: Turn source material into an interactive briefing"),
PreviewFeatures.PRE_MAILBOXES_2026 => TB("Mailboxes: Let the AI search and read your e-mails, kept in a local index on your computer"),
PreviewFeatures.PRE_MATHEMATICS_2026 => TB("Mathematics: Let the AI calculate exactly and work with formulas, right on your computer"),
PreviewFeatures.PRE_BEYOND_FACTS_LAB_2026 => TB("BeyondFacts Lab: Prepare for challenging conversations about your research, step by step"),
PreviewFeatures.PRE_MAILBOXES_2026 => TA("Mailboxes: Let the AI search and read your e-mails, kept in a local index on your computer"),
PreviewFeatures.PRE_MATHEMATICS_2026 => TA("Mathematics: Let the AI calculate exactly and work with formulas, right on your computer"),
PreviewFeatures.PRE_BEYOND_FACTS_LAB_2026 => TA("BeyondFacts Lab: Prepare for challenging conversations about your research, step by step"),
_ => TB("Unknown preview feature")
};