mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-13 17:47:21 +00:00
Added the choice between formal and informal address to the whole app (#1200)
This commit is contained in:
1 parent
382db4b8d0
commit
c9a376f742
342 files changed
+14378
-1893
No files matched your search
@@ -26,6 +26,8 @@ namespace AIStudio.Provider;
|
||||
public abstract class BaseProvider : IProvider, ISecretId
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(BaseProvider).Namespace, nameof(BaseProvider));
|
||||
|
||||
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(BaseProvider).Namespace, nameof(BaseProvider));
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP client to use it for all requests.
|
||||
@@ -154,7 +156,7 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
protected Task SendTimeoutError(string action) => MessageBus.INSTANCE.SendError(new(
|
||||
AppIcons.TIMEOUT,
|
||||
string.Format(
|
||||
TB("The request to the LLM provider '{0}' (type={1}) timed out after {2} while {3}. Please try again or check whether the provider is still responding."),
|
||||
TA("The request to the LLM provider '{0}' (type={1}) timed out after {2} while {3}. Please try again or check whether the provider is still responding."),
|
||||
this.InstanceName,
|
||||
this.Provider,
|
||||
ExternalHttpClientTimeout.GetTimeoutDescription(),
|
||||
@@ -262,11 +264,11 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
/// <returns>The message to show, or an empty string when we have nothing to say.</returns>
|
||||
protected virtual string GetProviderRequestFailureUserMessage(ProviderRequestFailureReason failureReason, ContextWindow contextWindow = default) => failureReason switch
|
||||
{
|
||||
ProviderRequestFailureReason.TOO_MANY_REQUESTS => TB("The provider rejected the request because too many requests were sent. Please wait a moment and try again."),
|
||||
ProviderRequestFailureReason.INVALID_OR_MISSING_API_KEY => string.Format(TB("The API key for the provider '{0}' is missing or was rejected. Please check the key in the settings."), this.InstanceName),
|
||||
ProviderRequestFailureReason.AUTHENTICATION_OR_PERMISSION_ERROR => string.Format(TB("The provider '{0}' refused the request. Your account might not be allowed to use the selected model, or the provider might not serve your region."), this.InstanceName),
|
||||
ProviderRequestFailureReason.PROVIDER_UNAVAILABLE => string.Format(TB("The provider '{0}' could not be reached. Please check whether it is running and reachable, then try again."), this.InstanceName),
|
||||
ProviderRequestFailureReason.MODEL_NOT_FOUND => string.Format(TB("The provider '{0}' does not know the selected model. Please select another model."), this.InstanceName),
|
||||
ProviderRequestFailureReason.TOO_MANY_REQUESTS => TA("The provider rejected the request because too many requests were sent. Please wait a moment and try again."),
|
||||
ProviderRequestFailureReason.INVALID_OR_MISSING_API_KEY => string.Format(TA("The API key for the provider '{0}' is missing or was rejected. Please check the key in the settings."), this.InstanceName),
|
||||
ProviderRequestFailureReason.AUTHENTICATION_OR_PERMISSION_ERROR => string.Format(TA("The provider '{0}' refused the request. Your account might not be allowed to use the selected model, or the provider might not serve your region."), this.InstanceName),
|
||||
ProviderRequestFailureReason.PROVIDER_UNAVAILABLE => string.Format(TA("The provider '{0}' could not be reached. Please check whether it is running and reachable, then try again."), this.InstanceName),
|
||||
ProviderRequestFailureReason.MODEL_NOT_FOUND => string.Format(TA("The provider '{0}' does not know the selected model. Please select another model."), this.InstanceName),
|
||||
//
|
||||
// Naming the number is the whole point of knowing it: "too long" leaves the user guessing
|
||||
// by how much, while the window turns the next step into arithmetic. Where nobody knows the
|
||||
@@ -276,10 +278,10 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
// by asking the user to set a chunk size, and 32.77k is not a number anybody types into a
|
||||
// field.
|
||||
//
|
||||
ProviderRequestFailureReason.CONTEXT_LENGTH_EXCEEDED when contextWindow.IsKnown => string.Format(TB("The text was longer than the selected model accepts, which is {0} tokens. Please select a model which takes longer texts, or reduce the chunk size of the data source."), contextWindow.DefaultTokens.ToString("N0", I18N.I.Culture)),
|
||||
ProviderRequestFailureReason.CONTEXT_LENGTH_EXCEEDED => TB("The text was longer than the selected model accepts. Please select a model which takes longer texts, or reduce the chunk size of the data source."),
|
||||
ProviderRequestFailureReason.TOOLS_NOT_SUPPORTED => string.Format(TB("The selected model is not able to use tools. Please select a model which can, or open the settings of the provider '{0}', show its expert settings, and switch the function calling capability off there."), this.InstanceName),
|
||||
ProviderRequestFailureReason.EMBEDDINGS_NOT_SUPPORTED => string.Format(TB("The provider '{0}' cannot create embeddings. Please select a provider which offers an embedding model."), this.InstanceName),
|
||||
ProviderRequestFailureReason.CONTEXT_LENGTH_EXCEEDED when contextWindow.IsKnown => string.Format(TA("The text was longer than the selected model accepts, which is {0} tokens. Please select a model which takes longer texts, or reduce the chunk size of the data source."), contextWindow.DefaultTokens.ToString("N0", I18N.I.Culture)),
|
||||
ProviderRequestFailureReason.CONTEXT_LENGTH_EXCEEDED => TA("The text was longer than the selected model accepts. Please select a model which takes longer texts, or reduce the chunk size of the data source."),
|
||||
ProviderRequestFailureReason.TOOLS_NOT_SUPPORTED => string.Format(TA("The selected model is not able to use tools. Please select a model which can, or open the settings of the provider '{0}', show its expert settings, and switch the function calling capability off there."), this.InstanceName),
|
||||
ProviderRequestFailureReason.EMBEDDINGS_NOT_SUPPORTED => string.Format(TA("The provider '{0}' cannot create embeddings. Please select a provider which offers an embedding model."), this.InstanceName),
|
||||
ProviderRequestFailureReason.INVALID_RESPONSE => string.Format(TB("The provider '{0}' sent an answer AI Studio was not able to read."), this.InstanceName),
|
||||
_ => string.Empty,
|
||||
};
|
||||
@@ -700,7 +702,7 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
/// </remarks>
|
||||
/// <param name="providerMessage">What the provider itself said about the failure.</param>
|
||||
/// <returns>The message to show.</returns>
|
||||
private string GetContextTooLargeUserMessage(string? providerMessage) => string.Format(TB("We tried to communicate with the LLM provider '{0}' (type={1}). The data of the chat, including all file attachments and the passages of your data sources, is probably too large for the selected model and provider. The provider message is: '{2}'"), this.InstanceName, this.Provider, providerMessage);
|
||||
private string GetContextTooLargeUserMessage(string? providerMessage) => string.Format(TA("We tried to communicate with the LLM provider '{0}' (type={1}). The data of the chat, including all file attachments and the passages of your data sources, is probably too large for the selected model and provider. The provider message is: '{2}'"), this.InstanceName, this.Provider, providerMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a request and handles rate limiting by exponential backoff.
|
||||
@@ -774,7 +776,7 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
|
||||
if (nextResponse.StatusCode is HttpStatusCode.Forbidden)
|
||||
{
|
||||
await MessageBus.INSTANCE.SendError(new(AppIcons.BLOCKED, string.Format(TB("We tried to communicate with the LLM provider '{0}' (type={1}). You might not be able to use this provider from your location. The provider message is: '{2}'"), this.InstanceName, this.Provider, nextResponse.ReasonPhrase)));
|
||||
await MessageBus.INSTANCE.SendError(new(AppIcons.BLOCKED, string.Format(TA("We tried to communicate with the LLM provider '{0}' (type={1}). You might not be able to use this provider from your location. The provider message is: '{2}'"), this.InstanceName, this.Provider, nextResponse.ReasonPhrase)));
|
||||
this.logger.LogError("Failed request with status code {ResponseStatusCode} (message = '{ResponseReasonPhrase}', error body = '{ErrorBody}').", nextResponse.StatusCode, nextResponse.ReasonPhrase, errorBody);
|
||||
errorMessage = nextResponse.ReasonPhrase;
|
||||
failureAlreadyExplained = true;
|
||||
@@ -1508,7 +1510,7 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
return classifiedMessage;
|
||||
|
||||
if (IsUndecodableFormatFailure(statusCode, responseBody))
|
||||
return string.Format(TB("The provider '{0}' was not able to read the audio file. It probably does not support the WebM/Opus format which AI Studio sends. Please contact the provider about it."), this.InstanceName);
|
||||
return string.Format(TA("The provider '{0}' was not able to read the audio file. It probably does not support the WebM/Opus format which AI Studio sends. Please contact the provider about it."), this.InstanceName);
|
||||
|
||||
var providerMessage = ReadProviderErrorMessage(responseBody);
|
||||
if (!string.IsNullOrWhiteSpace(providerMessage))
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace AIStudio.Provider;
|
||||
public sealed record Confidence
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(Confidence).Namespace, nameof(Confidence));
|
||||
|
||||
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(Confidence).Namespace, nameof(Confidence));
|
||||
|
||||
public ConfidenceLevel Level { get; private init; } = ConfidenceLevel.UNKNOWN;
|
||||
|
||||
@@ -32,43 +34,43 @@ public sealed record Confidence
|
||||
public static readonly Confidence NONE = new()
|
||||
{
|
||||
Level = ConfidenceLevel.NONE,
|
||||
Description = TB("No provider selected. Please select a provider to get see its confidence level."),
|
||||
Description = TA("No provider selected. Please select a provider to see its confidence level."),
|
||||
};
|
||||
|
||||
public static readonly Confidence USA_HUB = new()
|
||||
{
|
||||
Level = ConfidenceLevel.UNKNOWN,
|
||||
Description = TB("The provider operates its service from the USA and is subject to **U.S. jurisdiction**. In case of suspicion, authorities in the USA can access your data. Please inform yourself about the use of your data. We do not know if your data is safe."),
|
||||
Description = TA("The provider operates its service from the USA and is subject to **U.S. jurisdiction**. In case of suspicion, authorities in the USA can access your data. Please inform yourself about the use of your data. We do not know if your data is safe."),
|
||||
};
|
||||
|
||||
public static readonly Confidence UNKNOWN = new()
|
||||
{
|
||||
Level = ConfidenceLevel.UNKNOWN,
|
||||
Description = TB("The trust level of this provider **has not yet** been thoroughly **investigated and evaluated**. We do not know if your data is safe."),
|
||||
Description = TA("The trust level of this provider **has not yet** been thoroughly **investigated and evaluated**. We do not know if your data is safe."),
|
||||
};
|
||||
|
||||
public static readonly Confidence USER_OPERATED_GATEWAY = new()
|
||||
{
|
||||
Level = ConfidenceLevel.UNKNOWN,
|
||||
Description = TB("You or your organization operate this gateway. However, it forwards your data to **whichever providers you configured behind it**, which may be cloud services in any jurisdiction. We cannot know where your data ends up, so **please assign the trust level yourself**."),
|
||||
Description = TA("You or your organization operate this gateway. However, it forwards your data to **whichever providers you configured behind it**, which may be cloud services in any jurisdiction. We cannot know where your data ends up, so **please assign the trust level yourself**."),
|
||||
};
|
||||
|
||||
public static readonly Confidence USA_NO_TRAINING = new()
|
||||
{
|
||||
Level = ConfidenceLevel.MODERATE,
|
||||
Description = TB("The provider operates its service from the USA and is subject to **US jurisdiction**. In case of suspicion, authorities in the USA can access your data. However, **your data is not used for training** purposes."),
|
||||
Description = TA("The provider operates its service from the USA and is subject to **US jurisdiction**. In case of suspicion, authorities in the USA can access your data. However, **your data is not used for training** purposes."),
|
||||
};
|
||||
|
||||
public static readonly Confidence CHINA_NO_TRAINING = new()
|
||||
{
|
||||
Level = ConfidenceLevel.MODERATE,
|
||||
Description = TB("The provider operates its service from China. In case of suspicion, authorities in the respective countries of operation may access your data. However, **your data is not used for training** purposes."),
|
||||
Description = TA("The provider operates its service from China. In case of suspicion, authorities in the respective countries of operation may access your data. However, **your data is not used for training** purposes."),
|
||||
};
|
||||
|
||||
public static readonly Confidence GDPR_NO_TRAINING = new()
|
||||
{
|
||||
Level = ConfidenceLevel.MEDIUM,
|
||||
Description = TB("The provider is located in the EU and is subject to the **GDPR** (General Data Protection Regulation). Additionally, the provider states that **your data is not used for training**."),
|
||||
Description = TA("The provider is located in the EU and is subject to the **GDPR** (General Data Protection Regulation). Additionally, the provider states that **your data is not used for training**."),
|
||||
};
|
||||
|
||||
public static readonly Confidence GDPR_EXPERIMENTAL_OPEN_SOURCE = new()
|
||||
@@ -80,6 +82,6 @@ public sealed record Confidence
|
||||
public static readonly Confidence SELF_HOSTED = new()
|
||||
{
|
||||
Level = ConfidenceLevel.HIGH,
|
||||
Description = TB("You or your organization operate the LLM locally or within your trusted network. In terms of data processing and security, this is the best possible way."),
|
||||
Description = TA("You or your organization operate the LLM locally or within your trusted network. In terms of data processing and security, this is the best possible way."),
|
||||
};
|
||||
}
|
||||
@@ -6,6 +6,8 @@ public static class HFInferenceProviderExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(HFInferenceProviderExtensions).Namespace, nameof(HFInferenceProviderExtensions));
|
||||
|
||||
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(HFInferenceProviderExtensions).Namespace, nameof(HFInferenceProviderExtensions));
|
||||
|
||||
/// <param name="provider">The inference provider.</param>
|
||||
extension(HFInferenceProvider provider)
|
||||
{
|
||||
@@ -117,7 +119,7 @@ public static class HFInferenceProviderExtensions
|
||||
{
|
||||
HFInferenceProvider.AUTOMATIC => TB("Automatic: the fastest provider"),
|
||||
HFInferenceProvider.CHEAPEST => TB("Automatic: the cheapest provider"),
|
||||
HFInferenceProvider.PREFERRED => TB("Automatic: your preferred order"),
|
||||
HFInferenceProvider.PREFERRED => TA("Automatic: your preferred order"),
|
||||
|
||||
HFInferenceProvider.BASETEN => "Baseten",
|
||||
HFInferenceProvider.CEREBRAS => "Cerebras",
|
||||
|
||||
@@ -14,7 +14,7 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
{
|
||||
private static readonly ILogger<ProviderHuggingFace> LOGGER = Program.LOGGER_FACTORY.CreateLogger<ProviderHuggingFace>();
|
||||
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ProviderHuggingFace).Namespace, nameof(ProviderHuggingFace));
|
||||
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(ProviderHuggingFace).Namespace, nameof(ProviderHuggingFace));
|
||||
|
||||
/// <summary>
|
||||
/// The OpenAI-compatible endpoint which serves every inference provider.
|
||||
@@ -139,9 +139,9 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
// nobody: they never picked it, and no other choice of provider is left to try:
|
||||
//
|
||||
if (this.hfProvider is HFInferenceProvider.NONE or HFInferenceProvider.AUTOMATIC or HFInferenceProvider.CHEAPEST or HFInferenceProvider.PREFERRED)
|
||||
return TB("No Hugging Face inference provider offers the selected model. Please check the model name and whether it is still available on Hugging Face.");
|
||||
return TA("No Hugging Face inference provider offers the selected model. Please check the model name and whether it is still available on Hugging Face.");
|
||||
|
||||
return string.Format(TB("The Hugging Face inference provider '{0}' does not offer the selected model. Please select another inference provider, or let Hugging Face choose one for you."), this.hfProvider.Name);
|
||||
return string.Format(TA("The Hugging Face inference provider '{0}' does not offer the selected model. Please select another inference provider, or let Hugging Face choose one for you."), this.hfProvider.Name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -6,6 +6,8 @@ public static class ModelLoadFailureReasonExtensions
|
||||
{
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ModelLoadFailureReasonExtensions).Namespace, nameof(ModelLoadFailureReasonExtensions));
|
||||
|
||||
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(ModelLoadFailureReasonExtensions).Namespace, nameof(ModelLoadFailureReasonExtensions));
|
||||
|
||||
extension(ModelLoadFailureReason failureReason)
|
||||
{
|
||||
public string ToUserMessage(string providerName) => failureReason switch
|
||||
@@ -13,7 +15,7 @@ public static class ModelLoadFailureReasonExtensions
|
||||
ModelLoadFailureReason.INVALID_OR_MISSING_API_KEY => string.Format(TB("We could not load models from '{0}'. The API key is probably missing, invalid, or expired."), providerName),
|
||||
ModelLoadFailureReason.AUTHENTICATION_OR_PERMISSION_ERROR => string.Format(TB("We could not load models from '{0}'. The account or API key does not have the required permissions."), providerName),
|
||||
ModelLoadFailureReason.INSUFFICIENT_QUOTA => string.Format(TB("We could not load models from '{0}' because the account appears to have no API credits left."), providerName),
|
||||
ModelLoadFailureReason.TOO_MANY_REQUESTS => string.Format(TB("We could not load models from '{0}' because too many requests were sent. Please wait a moment and try again."), providerName),
|
||||
ModelLoadFailureReason.TOO_MANY_REQUESTS => string.Format(TA("We could not load models from '{0}' because too many requests were sent. Please wait a moment and try again."), providerName),
|
||||
ModelLoadFailureReason.PROVIDER_UNAVAILABLE => string.Format(TB("We could not load models from '{0}' because the provider is currently unavailable or could not be reached."), providerName),
|
||||
ModelLoadFailureReason.INVALID_RESPONSE => string.Format(TB("We could not load models from '{0}' because the provider returned an unexpected response."), providerName),
|
||||
ModelLoadFailureReason.UNKNOWN => string.Format(TB("We could not load models from '{0}' due to an unknown error."), providerName),
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace AIStudio.Provider.OpenAI;
|
||||
public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Uri("https://api.openai.com/v1/"), ExternalHttpTrustPolicy.SYSTEM_TRUST_ONLY, LOGGER)
|
||||
{
|
||||
private static readonly ILogger<ProviderOpenAI> LOGGER = Program.LOGGER_FACTORY.CreateLogger<ProviderOpenAI>();
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ProviderOpenAI).Namespace, nameof(ProviderOpenAI));
|
||||
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(ProviderOpenAI).Namespace, nameof(ProviderOpenAI));
|
||||
|
||||
#region Implementation of IProvider
|
||||
|
||||
@@ -51,7 +51,7 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
||||
|
||||
protected override string GetProviderRequestFailureUserMessage(ProviderRequestFailureReason failureReason, ContextWindow contextWindow = default) => failureReason switch
|
||||
{
|
||||
ProviderRequestFailureReason.INSUFFICIENT_QUOTA => TB("It looks like you do not have any API credits left with OpenAI. Please add credits to your account and try again."),
|
||||
ProviderRequestFailureReason.INSUFFICIENT_QUOTA => TA("It looks like you do not have any API credits left with OpenAI. Please add credits to your account and try again."),
|
||||
_ => base.GetProviderRequestFailureUserMessage(failureReason, contextWindow),
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
|
||||
|
||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ProviderSelfHosted).Namespace, nameof(ProviderSelfHosted));
|
||||
|
||||
private static string TA(string fallbackEN) => I18N.I.TA(fallbackEN, typeof(ProviderSelfHosted).Namespace, nameof(ProviderSelfHosted));
|
||||
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -260,7 +262,7 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
|
||||
throw new ProviderRequestException(
|
||||
ProviderRequestFailureReason.NONE,
|
||||
string.Format(
|
||||
TB("The llama.cpp provider '{0}' does not offer a usable text model. Please check your provider settings."),
|
||||
TA("The llama.cpp provider '{0}' does not offer a usable text model. Please check your provider settings."),
|
||||
this.InstanceName));
|
||||
}
|
||||
|
||||
@@ -276,7 +278,7 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
|
||||
throw new ProviderRequestException(
|
||||
ProviderRequestFailureReason.NONE,
|
||||
string.Format(
|
||||
TB("The llama.cpp provider '{0}' offers multiple models. Please open the provider settings and select the model to use."),
|
||||
TA("The llama.cpp provider '{0}' offers multiple models. Please open the provider settings and select the model to use."),
|
||||
this.InstanceName));
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user