mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-10 21:47:21 +00:00
Moved all extension methods into extension blocks (#1155)
This commit is contained in:
1 parent
acc7d09fa2
commit
c0a75f39ac
138 files changed
+5884
-4954
No files matched your search
@@ -2,54 +2,57 @@ namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public static class BiasCategoryExtensions
|
||||
{
|
||||
public static string ToName(this BiasCategory biasCategory) => biasCategory switch
|
||||
extension(BiasCategory biasCategory)
|
||||
{
|
||||
BiasCategory.WHAT_SHOULD_WE_REMEMBER => "What should we remember?",
|
||||
BiasCategory.TOO_MUCH_INFORMATION => "Too much information",
|
||||
BiasCategory.NOT_ENOUGH_MEANING => "Not enough meaning",
|
||||
BiasCategory.NEED_TO_ACT_FAST => "Need to act fast",
|
||||
public string ToName() => biasCategory switch
|
||||
{
|
||||
BiasCategory.WHAT_SHOULD_WE_REMEMBER => "What should we remember?",
|
||||
BiasCategory.TOO_MUCH_INFORMATION => "Too much information",
|
||||
BiasCategory.NOT_ENOUGH_MEANING => "Not enough meaning",
|
||||
BiasCategory.NEED_TO_ACT_FAST => "Need to act fast",
|
||||
|
||||
_ => "Unknown category",
|
||||
};
|
||||
|
||||
public static string GetThoughts(this BiasCategory biasCategory) => biasCategory switch
|
||||
{
|
||||
BiasCategory.WHAT_SHOULD_WE_REMEMBER =>
|
||||
"""
|
||||
- We store memories differently based on how they were experienced
|
||||
- We reduce events and lists to their key elements
|
||||
- We discard specifics to form generalities
|
||||
- We edit and reinforce some memories after the fact
|
||||
""",
|
||||
_ => "Unknown category",
|
||||
};
|
||||
|
||||
public string GetThoughts() => biasCategory switch
|
||||
{
|
||||
BiasCategory.WHAT_SHOULD_WE_REMEMBER =>
|
||||
"""
|
||||
- We store memories differently based on how they were experienced
|
||||
- We reduce events and lists to their key elements
|
||||
- We discard specifics to form generalities
|
||||
- We edit and reinforce some memories after the fact
|
||||
""",
|
||||
|
||||
BiasCategory.TOO_MUCH_INFORMATION =>
|
||||
"""
|
||||
- We notice things already primed in memory or repeated often
|
||||
- Bizarre, funny, visually-striking, or anthropomorphic things stick out more than non-bizarre/unfunny things
|
||||
- We notice when something has changed
|
||||
- We are drawn to details that confirm our own existing beliefs
|
||||
- We notice flaws in others more easily than we notice flaws in ourselves
|
||||
""",
|
||||
BiasCategory.TOO_MUCH_INFORMATION =>
|
||||
"""
|
||||
- We notice things already primed in memory or repeated often
|
||||
- Bizarre, funny, visually-striking, or anthropomorphic things stick out more than non-bizarre/unfunny things
|
||||
- We notice when something has changed
|
||||
- We are drawn to details that confirm our own existing beliefs
|
||||
- We notice flaws in others more easily than we notice flaws in ourselves
|
||||
""",
|
||||
|
||||
BiasCategory.NOT_ENOUGH_MEANING =>
|
||||
"""
|
||||
- We tend to find stories and patterns even when looking at sparse data
|
||||
- We fill in characteristics from stereotypes, generalities, and prior histories
|
||||
- We imagine things and people we’re familiar with or fond of as better
|
||||
- We simplify probabilities and numbers to make them easier to think about
|
||||
- We project our current mindset and assumptions onto the past and future
|
||||
- We think we know what other people are thinking
|
||||
""",
|
||||
BiasCategory.NOT_ENOUGH_MEANING =>
|
||||
"""
|
||||
- We tend to find stories and patterns even when looking at sparse data
|
||||
- We fill in characteristics from stereotypes, generalities, and prior histories
|
||||
- We imagine things and people we’re familiar with or fond of as better
|
||||
- We simplify probabilities and numbers to make them easier to think about
|
||||
- We project our current mindset and assumptions onto the past and future
|
||||
- We think we know what other people are thinking
|
||||
""",
|
||||
|
||||
BiasCategory.NEED_TO_ACT_FAST =>
|
||||
"""
|
||||
- We favor simple-looking options and complete information over complex, ambiguous options
|
||||
- To avoid mistakes, we aim to preserve autonomy and group status, and avoid irreversible decisions
|
||||
- To get things done, we tend to complete things we’ve invested time & energy in
|
||||
- To stay focused, we favor the immediate, relatable thing in front of us
|
||||
- To act, we must be confident we can make an impact and feel what we do is important
|
||||
""",
|
||||
BiasCategory.NEED_TO_ACT_FAST =>
|
||||
"""
|
||||
- We favor simple-looking options and complete information over complex, ambiguous options
|
||||
- To avoid mistakes, we aim to preserve autonomy and group status, and avoid irreversible decisions
|
||||
- To get things done, we tend to complete things we’ve invested time & energy in
|
||||
- To stay focused, we favor the immediate, relatable thing in front of us
|
||||
- To act, we must be confident we can make an impact and feel what we do is important
|
||||
""",
|
||||
|
||||
_ => string.Empty,
|
||||
};
|
||||
_ => string.Empty,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,50 +6,56 @@ public static class DataSourceSecurityExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(DataSourceSecurityExtensions).Namespace, nameof(DataSourceSecurityExtensions));
|
||||
|
||||
public static string ToSelectionText(this DataSourceSecurity security) => security switch
|
||||
extension(DataSourceSecurity security)
|
||||
{
|
||||
DataSourceSecurity.NOT_SPECIFIED => TB("Please select a security policy"),
|
||||
public string ToSelectionText() => security switch
|
||||
{
|
||||
DataSourceSecurity.NOT_SPECIFIED => TB("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 => 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."),
|
||||
|
||||
_ => TB("Unknown security policy")
|
||||
};
|
||||
|
||||
public static string ToInfoText(this DataSourceSecurity security) => 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.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."),
|
||||
|
||||
_ => TB("Unknown security policy")
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The data security which demands what the one held and the one arriving demand together.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Data which may only be used with self-hosted providers keeps them as the only choice, no matter
|
||||
/// what arrives later: the data was seen. Data which may be used with any provider marks the holder
|
||||
/// as one which holds data of a data source, while a restriction set earlier stays. NOT_SPECIFIED
|
||||
/// demands nothing and changes nothing. The order does not matter.
|
||||
/// </remarks>
|
||||
/// <param name="held">The data security held so far.</param>
|
||||
/// <param name="arriving">What the data arriving demands.</param>
|
||||
/// <returns>The tightened data security; never looser than either of the two.</returns>
|
||||
public static DataSourceSecurity TightenedBy(this DataSourceSecurity held, DataSourceSecurity arriving) => (held, arriving) switch
|
||||
{
|
||||
(DataSourceSecurity.SELF_HOSTED, _) or (_, DataSourceSecurity.SELF_HOSTED) => DataSourceSecurity.SELF_HOSTED,
|
||||
(_, DataSourceSecurity.ALLOW_ANY) => DataSourceSecurity.ALLOW_ANY,
|
||||
_ => held,
|
||||
};
|
||||
_ => TB("Unknown security policy")
|
||||
};
|
||||
|
||||
public static TextColor GetColor(this DataSourceSecurity security) => security switch
|
||||
{
|
||||
DataSourceSecurity.ALLOW_ANY => TextColor.WARN,
|
||||
DataSourceSecurity.SELF_HOSTED => TextColor.SUCCESS,
|
||||
public string ToInfoText() => 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."),
|
||||
|
||||
_ => TextColor.ERROR
|
||||
};
|
||||
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."),
|
||||
|
||||
_ => TB("Unknown security policy")
|
||||
};
|
||||
|
||||
public TextColor GetColor() => security switch
|
||||
{
|
||||
DataSourceSecurity.ALLOW_ANY => TextColor.WARN,
|
||||
DataSourceSecurity.SELF_HOSTED => TextColor.SUCCESS,
|
||||
|
||||
_ => TextColor.ERROR
|
||||
};
|
||||
}
|
||||
|
||||
/// <param name="held">The data security held so far.</param>
|
||||
extension(DataSourceSecurity held)
|
||||
{
|
||||
/// <summary>
|
||||
/// The data security which demands what the one held and the one arriving demand together.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Data which may only be used with self-hosted providers keeps them as the only choice, no matter
|
||||
/// what arrives later: the data was seen. Data which may be used with any provider marks the holder
|
||||
/// as one which holds data of a data source, while a restriction set earlier stays. NOT_SPECIFIED
|
||||
/// demands nothing and changes nothing. The order does not matter.
|
||||
/// </remarks>
|
||||
/// <param name="arriving">What the data arriving demands.</param>
|
||||
/// <returns>The tightened data security; never looser than either of the two.</returns>
|
||||
public DataSourceSecurity TightenedBy(DataSourceSecurity arriving) => (held, arriving) switch
|
||||
{
|
||||
(DataSourceSecurity.SELF_HOSTED, _) or (_, DataSourceSecurity.SELF_HOSTED) => DataSourceSecurity.SELF_HOSTED,
|
||||
(_, DataSourceSecurity.ALLOW_ANY) => DataSourceSecurity.ALLOW_ANY,
|
||||
_ => held,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -9,18 +9,21 @@ public static class DataSourceTypeExtension
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(DataSourceTypeExtension).Namespace, nameof(DataSourceTypeExtension));
|
||||
|
||||
/// <summary>
|
||||
/// Get the display name of the data source type.
|
||||
/// </summary>
|
||||
/// <param name="type">The data source type.</param>
|
||||
/// <returns>The display name of the data source type.</returns>
|
||||
public static string GetDisplayName(this DataSourceType type) => type switch
|
||||
extension(DataSourceType type)
|
||||
{
|
||||
DataSourceType.LOCAL_FILE => TB("Local File"),
|
||||
DataSourceType.LOCAL_DIRECTORY => TB("Local Directory"),
|
||||
DataSourceType.ERI_V1 => TB("External ERI Server (v1)"),
|
||||
DataSourceType.MAILBOX => TB("Mailbox"),
|
||||
/// <summary>
|
||||
/// Get the display name of the data source type.
|
||||
/// </summary>
|
||||
/// <returns>The display name of the data source type.</returns>
|
||||
public string GetDisplayName() => type switch
|
||||
{
|
||||
DataSourceType.LOCAL_FILE => TB("Local File"),
|
||||
DataSourceType.LOCAL_DIRECTORY => TB("Local Directory"),
|
||||
DataSourceType.ERI_V1 => TB("External ERI Server (v1)"),
|
||||
DataSourceType.MAILBOX => TB("Mailbox"),
|
||||
|
||||
_ => TB("None"),
|
||||
};
|
||||
_ => TB("None"),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,14 @@ public static class LangBehaviorExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(LangBehaviorExtensions).Namespace, nameof(LangBehaviorExtensions));
|
||||
|
||||
public static string Name(this LangBehavior langBehavior) => langBehavior switch
|
||||
extension(LangBehavior langBehavior)
|
||||
{
|
||||
LangBehavior.AUTO => TB("Choose the language automatically, based on your system language."),
|
||||
LangBehavior.MANUAL => TB("Choose the language manually."),
|
||||
public string Name() => langBehavior switch
|
||||
{
|
||||
LangBehavior.AUTO => TB("Choose the language automatically, based on your system language."),
|
||||
LangBehavior.MANUAL => TB("Choose the language manually."),
|
||||
|
||||
_ => TB("Unknown option")
|
||||
};
|
||||
_ => TB("Unknown option")
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,31 +6,34 @@ public static class MailboxMaxAgeExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(MailboxMaxAgeExtensions).Namespace, nameof(MailboxMaxAgeExtensions));
|
||||
|
||||
public static string GetName(this MailboxMaxAge maxAge) => maxAge switch
|
||||
{
|
||||
MailboxMaxAge.LAST_3_MONTHS => TB("The last 3 months"),
|
||||
MailboxMaxAge.LAST_6_MONTHS => TB("The last 6 months"),
|
||||
MailboxMaxAge.LAST_12_MONTHS => TB("The last 12 months"),
|
||||
MailboxMaxAge.LAST_24_MONTHS => TB("The last 24 months"),
|
||||
MailboxMaxAge.ALL => TB("All mails"),
|
||||
|
||||
_ => TB("Unknown period"),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The first day of the period, as the sync asks the server for it.
|
||||
/// </summary>
|
||||
/// <param name="maxAge">The period.</param>
|
||||
/// <param name="now">The current time.</param>
|
||||
/// <returns>The first day, or null when the period has no end.</returns>
|
||||
public static DateTimeOffset? GetReceivedSince(this MailboxMaxAge maxAge, DateTimeOffset now) => maxAge switch
|
||||
extension(MailboxMaxAge maxAge)
|
||||
{
|
||||
MailboxMaxAge.LAST_6_MONTHS => now.AddMonths(-6),
|
||||
MailboxMaxAge.LAST_12_MONTHS => now.AddMonths(-12),
|
||||
MailboxMaxAge.LAST_24_MONTHS => now.AddMonths(-24),
|
||||
MailboxMaxAge.ALL => null,
|
||||
public string GetName() => maxAge switch
|
||||
{
|
||||
MailboxMaxAge.LAST_3_MONTHS => TB("The last 3 months"),
|
||||
MailboxMaxAge.LAST_6_MONTHS => TB("The last 6 months"),
|
||||
MailboxMaxAge.LAST_12_MONTHS => TB("The last 12 months"),
|
||||
MailboxMaxAge.LAST_24_MONTHS => TB("The last 24 months"),
|
||||
MailboxMaxAge.ALL => TB("All mails"),
|
||||
|
||||
// The shortest period also stands in for a value this version does not know, as it does in the settings:
|
||||
_ => now.AddMonths(-3),
|
||||
};
|
||||
_ => TB("Unknown period"),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The first day of the period, as the sync asks the server for it.
|
||||
/// </summary>
|
||||
/// <param name="now">The current time.</param>
|
||||
/// <returns>The first day, or null when the period has no end.</returns>
|
||||
public DateTimeOffset? GetReceivedSince(DateTimeOffset now) => maxAge switch
|
||||
{
|
||||
MailboxMaxAge.LAST_6_MONTHS => now.AddMonths(-6),
|
||||
MailboxMaxAge.LAST_12_MONTHS => now.AddMonths(-12),
|
||||
MailboxMaxAge.LAST_24_MONTHS => now.AddMonths(-24),
|
||||
MailboxMaxAge.ALL => null,
|
||||
|
||||
// The shortest period also stands in for a value this version does not know, as it does in the settings:
|
||||
_ => now.AddMonths(-3),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -16,23 +16,26 @@ public static class MailboxTransportSecurityExtensions
|
||||
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(MailboxTransportSecurityExtensions).Namespace, nameof(MailboxTransportSecurityExtensions));
|
||||
|
||||
public static string GetName(this MailboxTransportSecurity transportSecurity) => transportSecurity switch
|
||||
extension(MailboxTransportSecurity transportSecurity)
|
||||
{
|
||||
MailboxTransportSecurity.SSL_ON_CONNECT => TB("TLS from the start (usually port 993)"),
|
||||
MailboxTransportSecurity.STARTTLS => TB("STARTTLS (usually port 143)"),
|
||||
public string GetName() => transportSecurity switch
|
||||
{
|
||||
MailboxTransportSecurity.SSL_ON_CONNECT => TB("TLS from the start (usually port 993)"),
|
||||
MailboxTransportSecurity.STARTTLS => TB("STARTTLS (usually port 143)"),
|
||||
|
||||
_ => TB("Unknown encryption"),
|
||||
};
|
||||
_ => TB("Unknown encryption"),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The port the encryption usually comes with.
|
||||
/// </summary>
|
||||
/// <returns>The port, or null when there is no usual one.</returns>
|
||||
public static int? GetUsualPort(this MailboxTransportSecurity transportSecurity) => transportSecurity switch
|
||||
{
|
||||
MailboxTransportSecurity.SSL_ON_CONNECT => SSL_ON_CONNECT_PORT,
|
||||
MailboxTransportSecurity.STARTTLS => STARTTLS_PORT,
|
||||
/// <summary>
|
||||
/// The port the encryption usually comes with.
|
||||
/// </summary>
|
||||
/// <returns>The port, or null when there is no usual one.</returns>
|
||||
public int? GetUsualPort() => transportSecurity switch
|
||||
{
|
||||
MailboxTransportSecurity.SSL_ON_CONNECT => SSL_ON_CONNECT_PORT,
|
||||
MailboxTransportSecurity.STARTTLS => STARTTLS_PORT,
|
||||
|
||||
_ => null,
|
||||
};
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,31 +6,34 @@ public static class OutboundDataRequirementExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(OutboundDataRequirementExtensions).Namespace, nameof(OutboundDataRequirementExtensions));
|
||||
|
||||
/// <summary>
|
||||
/// Why a tool cannot run in a chat with this requirement, and how to get it back.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// One text for the tool selection and for a call which was turned down, so the user reads the
|
||||
/// same in both places, and the model can pass it on. It names the source which demands the
|
||||
/// requirement, and the setting as the user finds it labeled. The level is the one the setting
|
||||
/// had when the content was read: a change made later does not loosen the chat.<br/><br/>
|
||||
/// The text speaks of content the chat holds, not of content it read: the content may come from
|
||||
/// another chat or an assistant, which sent it here along with its restrictions.
|
||||
/// </remarks>
|
||||
/// <param name="requirement">What the chat demands.</param>
|
||||
/// <param name="settings">The configuration, to find the name of the mailbox or data source which demands it.</param>
|
||||
/// <returns>The text for the user.</returns>
|
||||
public static string GetToolBlockedMessage(this OutboundDataRequirement requirement, Data settings) => requirement.Origin switch
|
||||
extension(OutboundDataRequirement requirement)
|
||||
{
|
||||
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.GetName()),
|
||||
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.GetName()),
|
||||
OutboundDataOrigin.DATA_SOURCE => GetDataSourceBlockedMessage(requirement, settings.DataSources),
|
||||
/// <summary>
|
||||
/// Why a tool cannot run in a chat with this requirement, and how to get it back.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// One text for the tool selection and for a call which was turned down, so the user reads the
|
||||
/// same in both places, and the model can pass it on. It names the source which demands the
|
||||
/// requirement, and the setting as the user finds it labeled. The level is the one the setting
|
||||
/// had when the content was read: a change made later does not loosen the chat.<br/><br/>
|
||||
/// The text speaks of content the chat holds, not of content it read: the content may come from
|
||||
/// another chat or an assistant, which sent it here along with its restrictions.
|
||||
/// </remarks>
|
||||
/// <param name="settings">The configuration, to find the name of the mailbox or data source which demands it.</param>
|
||||
/// <returns>The text for the user.</returns>
|
||||
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.GetName()),
|
||||
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.GetName()),
|
||||
OutboundDataOrigin.DATA_SOURCE => GetDataSourceBlockedMessage(requirement, settings.DataSources),
|
||||
|
||||
// NONE keeps no tool from running, since nothing restricts such a chat. What is left is an
|
||||
// origin this version does not know:
|
||||
_ => string.Format(TB("This chat holds internal content, read while a chat was restricted to '{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.GetName()),
|
||||
};
|
||||
// NONE keeps no tool from running, since nothing restricts such a chat. What is left is an
|
||||
// origin this version does not know:
|
||||
_ => string.Format(TB("This chat holds internal content, read while a chat was restricted to '{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.GetName()),
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetMailboxBlockedMessage(OutboundDataRequirement requirement, IEnumerable<DataSourceMailbox> mailboxes)
|
||||
{
|
||||
|
||||
@@ -6,52 +6,54 @@ public static class OutboundDataRestrictionExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(OutboundDataRestrictionExtensions).Namespace, nameof(OutboundDataRestrictionExtensions));
|
||||
|
||||
/// <summary>
|
||||
/// The stricter of two restrictions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A restriction this version does not know counts as the strictest one, see OrStrictestWhenUnknown.
|
||||
/// </remarks>
|
||||
/// <param name="restriction">The one restriction.</param>
|
||||
/// <param name="other">The other restriction.</param>
|
||||
/// <returns>The restriction which allows less.</returns>
|
||||
public static OutboundDataRestriction StricterOf(this OutboundDataRestriction restriction, OutboundDataRestriction other)
|
||||
/// <param name="restriction">The restriction, as it was read.</param>
|
||||
extension(OutboundDataRestriction restriction)
|
||||
{
|
||||
var knownRestriction = restriction.OrStrictestWhenUnknown();
|
||||
var knownOther = other.OrStrictestWhenUnknown();
|
||||
return knownOther < knownRestriction ? knownOther : knownRestriction;
|
||||
/// <summary>
|
||||
/// The stricter of two restrictions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A restriction this version does not know counts as the strictest one, see OrStrictestWhenUnknown.
|
||||
/// </remarks>
|
||||
/// <param name="other">The other restriction.</param>
|
||||
/// <returns>The restriction which allows less.</returns>
|
||||
public OutboundDataRestriction StricterOf(OutboundDataRestriction other)
|
||||
{
|
||||
var knownRestriction = restriction.OrStrictestWhenUnknown();
|
||||
var knownOther = other.OrStrictestWhenUnknown();
|
||||
return knownOther < knownRestriction ? knownOther : knownRestriction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The restriction as this version applies it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The settings file and a saved chat may hold a number which names no member, e.g., one written
|
||||
/// by hand, and the settings read it all the same. Compared as it is, such a number would rank
|
||||
/// above UNRESTRICTED and lift every restriction it meets.
|
||||
/// </remarks>
|
||||
/// <returns>The restriction itself, or the strictest one when this version does not know it.</returns>
|
||||
public OutboundDataRestriction OrStrictestWhenUnknown() => Enum.IsDefined(restriction) ? restriction : OutboundDataRestriction.ONLY_CONFIGURED_SERVICES;
|
||||
|
||||
public string GetName() => restriction switch
|
||||
{
|
||||
OutboundDataRestriction.ONLY_CONFIGURED_SERVICES => TB("Only services configured in AI Studio"),
|
||||
OutboundDataRestriction.ONLY_LINKS_FROM_CHAT => TB("Configured services and addresses from the chat"),
|
||||
OutboundDataRestriction.UNRESTRICTED => TB("No restriction"),
|
||||
|
||||
_ => TB("Unknown restriction"),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// What a chat may still do on this level, once internal content entered it.
|
||||
/// </summary>
|
||||
public string GetDescription() => 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."),
|
||||
|
||||
_ => TB("This version of AI Studio does not know this restriction, so it applies the strictest one."),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The restriction as this version applies it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The settings file and a saved chat may hold a number which names no member, e.g., one written
|
||||
/// by hand, and the settings read it all the same. Compared as it is, such a number would rank
|
||||
/// above UNRESTRICTED and lift every restriction it meets.
|
||||
/// </remarks>
|
||||
/// <param name="restriction">The restriction as it was read.</param>
|
||||
/// <returns>The restriction itself, or the strictest one when this version does not know it.</returns>
|
||||
public static OutboundDataRestriction OrStrictestWhenUnknown(this OutboundDataRestriction restriction) => Enum.IsDefined(restriction) ? restriction : OutboundDataRestriction.ONLY_CONFIGURED_SERVICES;
|
||||
|
||||
public static string GetName(this OutboundDataRestriction restriction) => restriction switch
|
||||
{
|
||||
OutboundDataRestriction.ONLY_CONFIGURED_SERVICES => TB("Only services configured in AI Studio"),
|
||||
OutboundDataRestriction.ONLY_LINKS_FROM_CHAT => TB("Configured services and addresses from the chat"),
|
||||
OutboundDataRestriction.UNRESTRICTED => TB("No restriction"),
|
||||
|
||||
_ => TB("Unknown restriction"),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// What a chat may still do on this level, once internal content entered it.
|
||||
/// </summary>
|
||||
public static string GetDescription(this OutboundDataRestriction restriction) => 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."),
|
||||
|
||||
_ => TB("This version of AI Studio does not know this restriction, so it applies the strictest one."),
|
||||
};
|
||||
}
|
||||
@@ -6,46 +6,49 @@ public static class PreviewFeaturesExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(PreviewFeaturesExtensions).Namespace, nameof(PreviewFeaturesExtensions));
|
||||
|
||||
public static string GetPreviewDescription(this PreviewFeatures feature) => 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_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_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"),
|
||||
|
||||
_ => TB("Unknown preview feature")
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Check if the preview feature is released or not.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This metadata is necessary because we cannot remove the enum values from the list.
|
||||
/// Otherwise, we could not deserialize old settings files that may contain these values.
|
||||
/// </remarks>
|
||||
/// <param name="feature">The preview feature to check.</param>
|
||||
/// <returns>True when the preview feature is released, false otherwise.</returns>
|
||||
public static bool IsReleased(this PreviewFeatures feature) => feature switch
|
||||
extension(PreviewFeatures feature)
|
||||
{
|
||||
PreviewFeatures.PRE_READ_PDF_2025 => true,
|
||||
PreviewFeatures.PRE_PLUGINS_2025 => true,
|
||||
PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025 => true,
|
||||
PreviewFeatures.PRE_SPEECH_TO_TEXT_2026 => true,
|
||||
public string GetPreviewDescription() => 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"),
|
||||
|
||||
_ => false
|
||||
};
|
||||
|
||||
public static bool IsEnabled(this PreviewFeatures feature, SettingsManager settingsManager)
|
||||
{
|
||||
if(feature.IsReleased())
|
||||
return true;
|
||||
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_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"),
|
||||
|
||||
_ => TB("Unknown preview feature")
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Check if the preview feature is released or not.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This metadata is necessary because we cannot remove the enum values from the list.
|
||||
/// Otherwise, we could not deserialize old settings files that may contain these values.
|
||||
/// </remarks>
|
||||
/// <returns>True when the preview feature is released, false otherwise.</returns>
|
||||
public bool IsReleased() => feature switch
|
||||
{
|
||||
PreviewFeatures.PRE_READ_PDF_2025 => true,
|
||||
PreviewFeatures.PRE_PLUGINS_2025 => true,
|
||||
PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025 => true,
|
||||
PreviewFeatures.PRE_SPEECH_TO_TEXT_2026 => true,
|
||||
|
||||
return settingsManager.ConfigurationData.App.EnabledPreviewFeatures.Contains(feature);
|
||||
_ => false
|
||||
};
|
||||
|
||||
public bool IsEnabled(SettingsManager settingsManager)
|
||||
{
|
||||
if(feature.IsReleased())
|
||||
return true;
|
||||
|
||||
return settingsManager.ConfigurationData.App.EnabledPreviewFeatures.Contains(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,48 +2,51 @@ namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public static class PreviewVisibilityExtensions
|
||||
{
|
||||
public static IList<PreviewFeatures> GetPreviewFeatures(this PreviewVisibility visibility)
|
||||
extension(PreviewVisibility visibility)
|
||||
{
|
||||
var features = new List<PreviewFeatures>();
|
||||
if (visibility >= PreviewVisibility.RELEASE_CANDIDATE)
|
||||
public IList<PreviewFeatures> GetPreviewFeatures()
|
||||
{
|
||||
}
|
||||
var features = new List<PreviewFeatures>();
|
||||
if (visibility >= PreviewVisibility.RELEASE_CANDIDATE)
|
||||
{
|
||||
}
|
||||
|
||||
if (visibility >= PreviewVisibility.BETA)
|
||||
{
|
||||
features.Add(PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025);
|
||||
features.Add(PreviewFeatures.PRE_META_ASSISTANT_V1);
|
||||
features.Add(PreviewFeatures.PRE_RAG_2024);
|
||||
features.Add(PreviewFeatures.PRE_VISUAL_BRIEFING_ASSISTANT_2026);
|
||||
}
|
||||
if (visibility >= PreviewVisibility.BETA)
|
||||
{
|
||||
features.Add(PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025);
|
||||
features.Add(PreviewFeatures.PRE_META_ASSISTANT_V1);
|
||||
features.Add(PreviewFeatures.PRE_RAG_2024);
|
||||
features.Add(PreviewFeatures.PRE_VISUAL_BRIEFING_ASSISTANT_2026);
|
||||
}
|
||||
|
||||
if (visibility >= PreviewVisibility.ALPHA)
|
||||
{
|
||||
}
|
||||
if (visibility >= PreviewVisibility.ALPHA)
|
||||
{
|
||||
}
|
||||
|
||||
if (visibility >= PreviewVisibility.PROTOTYPE)
|
||||
{
|
||||
features.Add(PreviewFeatures.PRE_MAILBOXES_2026);
|
||||
if (visibility >= PreviewVisibility.PROTOTYPE)
|
||||
{
|
||||
features.Add(PreviewFeatures.PRE_MAILBOXES_2026);
|
||||
}
|
||||
|
||||
if (visibility >= PreviewVisibility.EXPERIMENTAL)
|
||||
{
|
||||
features.Add(PreviewFeatures.PRE_WRITER_MODE_2024);
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
if (visibility >= PreviewVisibility.EXPERIMENTAL)
|
||||
public HashSet<PreviewFeatures> FilterPreviewFeatures(HashSet<PreviewFeatures> enabledFeatures)
|
||||
{
|
||||
features.Add(PreviewFeatures.PRE_WRITER_MODE_2024);
|
||||
}
|
||||
var filteredFeatures = new HashSet<PreviewFeatures>();
|
||||
var previewFeatures = visibility.GetPreviewFeatures();
|
||||
foreach (var feature in enabledFeatures)
|
||||
{
|
||||
if (previewFeatures.Contains(feature))
|
||||
filteredFeatures.Add(feature);
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
public static HashSet<PreviewFeatures> FilterPreviewFeatures(this PreviewVisibility visibility, HashSet<PreviewFeatures> enabledFeatures)
|
||||
{
|
||||
var filteredFeatures = new HashSet<PreviewFeatures>();
|
||||
var previewFeatures = visibility.GetPreviewFeatures();
|
||||
foreach (var feature in enabledFeatures)
|
||||
{
|
||||
if (previewFeatures.Contains(feature))
|
||||
filteredFeatures.Add(feature);
|
||||
return filteredFeatures;
|
||||
}
|
||||
|
||||
return filteredFeatures;
|
||||
}
|
||||
}
|
||||
@@ -2,20 +2,26 @@ namespace AIStudio.Settings.DataModel.PreviousModels;
|
||||
|
||||
public static class ProviderV4Extensions
|
||||
{
|
||||
public static List<AIStudio.Settings.Provider> MigrateFromV4ToV5(this IEnumerable<Provider> providers)
|
||||
extension(IEnumerable<Provider> providers)
|
||||
{
|
||||
return providers.Select(provider => provider.MigrateFromV4ToV5()).ToList();
|
||||
public List<AIStudio.Settings.Provider> MigrateFromV4ToV5()
|
||||
{
|
||||
return providers.Select(provider => provider.MigrateFromV4ToV5()).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public static AIStudio.Settings.Provider MigrateFromV4ToV5(this Provider provider) => new()
|
||||
extension(Provider provider)
|
||||
{
|
||||
Num = provider.Num,
|
||||
Id = provider.Id,
|
||||
InstanceName = provider.InstanceName,
|
||||
UsedLLMProvider = provider.UsedProvider,
|
||||
Model = provider.Model,
|
||||
IsSelfHosted = provider.IsSelfHosted,
|
||||
Hostname = provider.Hostname,
|
||||
Host = provider.Host,
|
||||
};
|
||||
public AIStudio.Settings.Provider MigrateFromV4ToV5() => new()
|
||||
{
|
||||
Num = provider.Num,
|
||||
Id = provider.Id,
|
||||
InstanceName = provider.InstanceName,
|
||||
UsedLLMProvider = provider.UsedProvider,
|
||||
Model = provider.Model,
|
||||
IsSelfHosted = provider.IsSelfHosted,
|
||||
Hostname = provider.Hostname,
|
||||
Host = provider.Host,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,14 @@ public static class SendToChatDataSourceBehaviorExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(SendToChatDataSourceBehaviorExtensions).Namespace, nameof(SendToChatDataSourceBehaviorExtensions));
|
||||
|
||||
public static string Description(this SendToChatDataSourceBehavior behavior) => behavior switch
|
||||
extension(SendToChatDataSourceBehavior behavior)
|
||||
{
|
||||
SendToChatDataSourceBehavior.NO_DATA_SOURCES => TB("Use no data sources, when sending an assistant result to a chat"),
|
||||
SendToChatDataSourceBehavior.APPLY_STANDARD_CHAT_DATA_SOURCE_OPTIONS => TB("Apply standard chat data source options, when sending an assistant result to a chat"),
|
||||
public string Description() => behavior switch
|
||||
{
|
||||
SendToChatDataSourceBehavior.NO_DATA_SOURCES => TB("Use no data sources, when sending an assistant result to a chat"),
|
||||
SendToChatDataSourceBehavior.APPLY_STANDARD_CHAT_DATA_SOURCE_OPTIONS => TB("Apply standard chat data source options, when sending an assistant result to a chat"),
|
||||
|
||||
_ => TB("Unknown behavior"),
|
||||
};
|
||||
_ => TB("Unknown behavior"),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,19 @@ namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public static class StartPageExtensions
|
||||
{
|
||||
public static string ToRoute(this StartPage startPage) => startPage switch
|
||||
extension(StartPage startPage)
|
||||
{
|
||||
StartPage.HOME => string.Empty,
|
||||
StartPage.CHAT => Routes.CHAT,
|
||||
StartPage.ASSISTANTS => Routes.ASSISTANTS,
|
||||
StartPage.INFORMATION => Routes.ABOUT,
|
||||
StartPage.PLUGINS => Routes.PLUGINS,
|
||||
StartPage.SUPPORTERS => Routes.SUPPORTERS,
|
||||
StartPage.SETTINGS => Routes.SETTINGS,
|
||||
public string ToRoute() => startPage switch
|
||||
{
|
||||
StartPage.HOME => string.Empty,
|
||||
StartPage.CHAT => Routes.CHAT,
|
||||
StartPage.ASSISTANTS => Routes.ASSISTANTS,
|
||||
StartPage.INFORMATION => Routes.ABOUT,
|
||||
StartPage.PLUGINS => Routes.PLUGINS,
|
||||
StartPage.SUPPORTERS => Routes.SUPPORTERS,
|
||||
StartPage.SETTINGS => Routes.SETTINGS,
|
||||
|
||||
_ => string.Empty,
|
||||
};
|
||||
_ => string.Empty,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,15 @@ public static class ThemesExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ThemesExtensions).Namespace, nameof(ThemesExtensions));
|
||||
|
||||
public static string GetName(this Themes theme) => theme switch
|
||||
extension(Themes theme)
|
||||
{
|
||||
Themes.SYSTEM => TB("Synchronized with the operating system settings"),
|
||||
Themes.LIGHT => TB("Always use light theme"),
|
||||
Themes.DARK => TB("Always use dark theme"),
|
||||
public string GetName() => theme switch
|
||||
{
|
||||
Themes.SYSTEM => TB("Synchronized with the operating system settings"),
|
||||
Themes.LIGHT => TB("Always use light theme"),
|
||||
Themes.DARK => TB("Always use dark theme"),
|
||||
|
||||
_ => TB("Unknown setting"),
|
||||
};
|
||||
_ => TB("Unknown setting"),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,24 +6,27 @@ public static class TranscriptionOpusBitrateExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(TranscriptionOpusBitrateExtensions).Namespace, nameof(TranscriptionOpusBitrateExtensions));
|
||||
|
||||
public static string GetName(this TranscriptionOpusBitrate bitrate) => bitrate switch
|
||||
extension(TranscriptionOpusBitrate bitrate)
|
||||
{
|
||||
TranscriptionOpusBitrate.KBPS_32 => TB("32 kbps (smallest upload, lowest accuracy)"),
|
||||
TranscriptionOpusBitrate.KBPS_64 => TB("64 kbps"),
|
||||
TranscriptionOpusBitrate.KBPS_128 => TB("128 kbps (recommended)"),
|
||||
TranscriptionOpusBitrate.KBPS_256 => TB("256 kbps (largest upload, highest accuracy)"),
|
||||
_ => TB("Unknown"),
|
||||
};
|
||||
public string GetName() => bitrate switch
|
||||
{
|
||||
TranscriptionOpusBitrate.KBPS_32 => TB("32 kbps (smallest upload, lowest accuracy)"),
|
||||
TranscriptionOpusBitrate.KBPS_64 => TB("64 kbps"),
|
||||
TranscriptionOpusBitrate.KBPS_128 => TB("128 kbps (recommended)"),
|
||||
TranscriptionOpusBitrate.KBPS_256 => TB("256 kbps (largest upload, highest accuracy)"),
|
||||
_ => TB("Unknown"),
|
||||
};
|
||||
|
||||
public static uint GetBitsPerSecond(this TranscriptionOpusBitrate bitrate) => bitrate switch
|
||||
{
|
||||
TranscriptionOpusBitrate.KBPS_32 => 32_000,
|
||||
TranscriptionOpusBitrate.KBPS_64 => 64_000,
|
||||
TranscriptionOpusBitrate.KBPS_128 => 128_000,
|
||||
TranscriptionOpusBitrate.KBPS_256 => 256_000,
|
||||
public uint GetBitsPerSecond() => bitrate switch
|
||||
{
|
||||
TranscriptionOpusBitrate.KBPS_32 => 32_000,
|
||||
TranscriptionOpusBitrate.KBPS_64 => 64_000,
|
||||
TranscriptionOpusBitrate.KBPS_128 => 128_000,
|
||||
TranscriptionOpusBitrate.KBPS_256 => 256_000,
|
||||
|
||||
// A value we do not know must never mean the lowest quality: that is how quiet passages
|
||||
// went missing from transcripts in the first place. Fall back to the recommended bitrate.
|
||||
_ => 128_000,
|
||||
};
|
||||
// A value we do not know must never mean the lowest quality: that is how quiet passages
|
||||
// went missing from transcripts in the first place. Fall back to the recommended bitrate.
|
||||
_ => 128_000,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user