mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-10 23:27:21 +00:00
Turned getter-like extension methods into extension properties (#1157)
This commit is contained in:
1 parent
0375318b1b
commit
f649febf88
286 files changed
+1379
-1109
No files matched your search
@@ -13,7 +13,7 @@ public sealed class ProviderAlibabaCloud() : BaseProvider(LLMProviders.ALIBABA_C
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.ALIBABA_CLOUD.ToSecretId();
|
||||
public override string Id => LLMProviders.ALIBABA_CLOUD.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "AlibabaCloud";
|
||||
|
||||
@@ -17,7 +17,7 @@ public sealed class ProviderAnthropic() : BaseProvider(LLMProviders.ANTHROPIC, n
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.ANTHROPIC.ToSecretId();
|
||||
public override string Id => LLMProviders.ANTHROPIC.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Anthropic";
|
||||
|
||||
@@ -1573,7 +1573,7 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
//
|
||||
form.Add(new StringContent("json"), "response_format");
|
||||
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, host.TranscriptionURL());
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, host.TranscriptionURL);
|
||||
request.Content = form;
|
||||
|
||||
// Handle the authorization header based on the provider:
|
||||
@@ -1664,7 +1664,7 @@ public abstract class BaseProvider : IProvider, ISecretId
|
||||
// Prepare the HTTP embedding request:
|
||||
var payload = new EmbeddingRequest(modelName, texts);
|
||||
var embeddingRequest = JsonSerializer.Serialize(payload, JSON_SERIALIZER_OPTIONS);
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, host.EmbeddingURL());
|
||||
using var request = new HttpRequestMessage(HttpMethod.Post, host.EmbeddingURL);
|
||||
|
||||
// Handle the authorization header based on the provider:
|
||||
switch (this.Provider)
|
||||
|
||||
@@ -9,7 +9,7 @@ public static class ConfidenceLevelExtensions
|
||||
|
||||
extension(ConfidenceLevel level)
|
||||
{
|
||||
public string GetName() => level switch
|
||||
public string Name => level switch
|
||||
{
|
||||
ConfidenceLevel.NONE => TB("No provider selected"),
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public sealed class ProviderDeepSeek() : BaseProvider(LLMProviders.DEEP_SEEK, ne
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.DEEP_SEEK.ToSecretId();
|
||||
public override string Id => LLMProviders.DEEP_SEEK.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "DeepSeek";
|
||||
|
||||
@@ -13,7 +13,7 @@ public class ProviderFireworks() : BaseProvider(LLMProviders.FIREWORKS, new Uri(
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.FIREWORKS.ToSecretId();
|
||||
public override string Id => LLMProviders.FIREWORKS.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Fireworks.ai";
|
||||
|
||||
@@ -28,7 +28,7 @@ public sealed class ProviderGWDG() : BaseProvider(LLMProviders.GWDG, new Uri("ht
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.GWDG.ToSecretId();
|
||||
public override string Id => LLMProviders.GWDG.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "GWDG SAIA";
|
||||
|
||||
@@ -15,7 +15,7 @@ public class ProviderGoogle() : BaseProvider(LLMProviders.GOOGLE, new Uri("https
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.GOOGLE.ToSecretId();
|
||||
public override string Id => LLMProviders.GOOGLE.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Google Gemini";
|
||||
|
||||
@@ -14,7 +14,7 @@ public class ProviderGroq() : BaseProvider(LLMProviders.GROQ, new Uri("https://a
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.GROQ.ToSecretId();
|
||||
public override string Id => LLMProviders.GROQ.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Groq";
|
||||
|
||||
@@ -15,7 +15,7 @@ public sealed class ProviderHelmholtz() : BaseProvider(LLMProviders.HELMHOLTZ, n
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.HELMHOLTZ.ToSecretId();
|
||||
public override string Id => LLMProviders.HELMHOLTZ.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Helmholtz Blablador";
|
||||
|
||||
@@ -13,7 +13,7 @@ public sealed class ProviderHetzner() : BaseProvider(LLMProviders.HETZNER, new U
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.HETZNER.ToSecretId();
|
||||
public override string Id => LLMProviders.HETZNER.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Hetzner (Experimental)";
|
||||
|
||||
@@ -12,8 +12,8 @@ public static class HFInferenceProviderExtensions
|
||||
/// <summary>
|
||||
/// The slug Hugging Face uses for this inference provider.
|
||||
/// </summary>
|
||||
/// <returns>The slug, or an empty string for the routing strategies, which name no provider.</returns>
|
||||
public string EndpointsId() => provider switch
|
||||
/// <value>The slug, or an empty string for the routing strategies, which name no provider.</value>
|
||||
public string EndpointsId => provider switch
|
||||
{
|
||||
HFInferenceProvider.BASETEN => "baseten",
|
||||
HFInferenceProvider.CEREBRAS => "cerebras",
|
||||
@@ -41,22 +41,22 @@ public static class HFInferenceProviderExtensions
|
||||
/// a suffix on the model name, e.g. "google/gemma-4-31B-it:novita". Without a suffix, the router
|
||||
/// picks the fastest provider itself.
|
||||
/// </remarks>
|
||||
/// <returns>The suffix including its colon, or an empty string when the router should choose.</returns>
|
||||
public string ModelSuffix() => provider switch
|
||||
/// <value>The suffix including its colon, or an empty string when the router should choose.</value>
|
||||
public string ModelSuffix => provider switch
|
||||
{
|
||||
HFInferenceProvider.NONE or HFInferenceProvider.AUTOMATIC => string.Empty,
|
||||
|
||||
HFInferenceProvider.CHEAPEST => ":cheapest",
|
||||
HFInferenceProvider.PREFERRED => ":preferred",
|
||||
|
||||
_ => $":{provider.EndpointsId()}",
|
||||
_ => $":{provider.EndpointsId}",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Whether this inference provider serves models to chat with.
|
||||
/// </summary>
|
||||
/// <returns>True, when the provider serves chat models.</returns>
|
||||
public bool SupportsChat() => provider is not HFInferenceProvider.NONE;
|
||||
/// <value>True, when the provider serves chat models.</value>
|
||||
public bool SupportsChat => provider is not HFInferenceProvider.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this inference provider creates embeddings for us.
|
||||
@@ -67,8 +67,8 @@ public static class HFInferenceProviderExtensions
|
||||
/// OpenAI-compatible form we send. The routing strategies are out by their nature: without a
|
||||
/// named provider there is no route to address.
|
||||
/// </remarks>
|
||||
/// <returns>True, when we can create embeddings through this provider.</returns>
|
||||
public bool SupportsEmbeddings() => provider is HFInferenceProvider.TOGETHER_AI or HFInferenceProvider.DEEPINFRA;
|
||||
/// <value>True, when we can create embeddings through this provider.</value>
|
||||
public bool SupportsEmbeddings => provider is HFInferenceProvider.TOGETHER_AI or HFInferenceProvider.DEEPINFRA;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this inference provider transcribes audio for us.
|
||||
@@ -79,8 +79,8 @@ public static class HFInferenceProviderExtensions
|
||||
/// transcribe for Hugging Face, but not in a shape we could send an audio file to: fal-ai and
|
||||
/// Replicate both turn the request down with "Model not supported by provider".
|
||||
/// </remarks>
|
||||
/// <returns>True, when we can transcribe audio through this provider.</returns>
|
||||
public bool SupportsTranscription() => provider is HFInferenceProvider.TOGETHER_AI or HFInferenceProvider.DEEPINFRA;
|
||||
/// <value>True, when we can transcribe audio through this provider.</value>
|
||||
public bool SupportsTranscription => provider is HFInferenceProvider.TOGETHER_AI or HFInferenceProvider.DEEPINFRA;
|
||||
|
||||
/// <summary>
|
||||
/// The base URL of the provider's own OpenAI-compatible route.
|
||||
@@ -91,8 +91,8 @@ public static class HFInferenceProviderExtensions
|
||||
/// keeps it below an additional "openai" segment, and answers the path without it with
|
||||
/// "Not allowed to POST /v1/embeddings for provider deepinfra".
|
||||
/// </remarks>
|
||||
/// <returns>The base URL, or an empty string when the provider has no such route.</returns>
|
||||
public string ProviderBaseURL() => provider switch
|
||||
/// <value>The base URL, or an empty string when the provider has no such route.</value>
|
||||
public string ProviderBaseURL => provider switch
|
||||
{
|
||||
HFInferenceProvider.TOGETHER_AI => "https://router.huggingface.co/together/v1/",
|
||||
HFInferenceProvider.DEEPINFRA => "https://router.huggingface.co/deepinfra/v1/openai/",
|
||||
@@ -103,14 +103,17 @@ public static class HFInferenceProviderExtensions
|
||||
/// <summary>
|
||||
/// The value to filter the Hugging Face model catalog by.
|
||||
/// </summary>
|
||||
/// <returns>The provider slug, or "all" when no particular provider was chosen.</returns>
|
||||
public string CatalogFilter()
|
||||
/// <value>The provider slug, or "all" when no particular provider was chosen.</value>
|
||||
public string CatalogFilter
|
||||
{
|
||||
var slug = provider.EndpointsId();
|
||||
return string.IsNullOrEmpty(slug) ? "all" : slug;
|
||||
get
|
||||
{
|
||||
var slug = provider.EndpointsId;
|
||||
return string.IsNullOrEmpty(slug) ? "all" : slug;
|
||||
}
|
||||
}
|
||||
|
||||
public string ToName() => provider switch
|
||||
public string Name => provider switch
|
||||
{
|
||||
HFInferenceProvider.AUTOMATIC => TB("Automatic: the fastest provider"),
|
||||
HFInferenceProvider.CHEAPEST => TB("Automatic: the cheapest provider"),
|
||||
|
||||
@@ -64,7 +64,7 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
if (endpointKind is HFEndpointKind.CHAT)
|
||||
return ROUTER_BASE_URL;
|
||||
|
||||
var providerBaseURL = hfProvider.ProviderBaseURL();
|
||||
var providerBaseURL = hfProvider.ProviderBaseURL;
|
||||
return string.IsNullOrEmpty(providerBaseURL) ? ROUTER_BASE_URL : providerBaseURL;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
if (string.IsNullOrWhiteSpace(modelId) || modelId.Contains(':'))
|
||||
return modelId;
|
||||
|
||||
return $"{modelId}{this.hfProvider.ModelSuffix()}";
|
||||
return $"{modelId}{this.hfProvider.ModelSuffix}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -141,7 +141,7 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
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 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.ToName());
|
||||
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);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -149,7 +149,7 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.HUGGINGFACE.ToSecretId();
|
||||
public override string Id => LLMProviders.HUGGINGFACE.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "HuggingFace";
|
||||
@@ -247,7 +247,7 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
/// <returns>One listing per model, which says nothing for the models nobody stated a window for.</returns>
|
||||
private IEnumerable<ModelListing> ListingsOf(ModelsResponse response)
|
||||
{
|
||||
var providerSlug = this.hfProvider.EndpointsId();
|
||||
var providerSlug = this.hfProvider.EndpointsId;
|
||||
return response.Data.Select(hfModel => ModelListing.For(hfModel.Id, hfModel.ContextWindowTokens(providerSlug)));
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
private IEnumerable<Model> SelectChatModels(ModelsResponse response)
|
||||
{
|
||||
var chatModels = response.Data.Where(hfModel => new Model(hfModel.Id, null).IsChatModel(this.Provider));
|
||||
var providerSlug = this.hfProvider.EndpointsId();
|
||||
var providerSlug = this.hfProvider.EndpointsId;
|
||||
if (string.IsNullOrEmpty(providerSlug))
|
||||
return ToModels(chatModels);
|
||||
|
||||
@@ -293,7 +293,7 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
/// <inheritdoc />
|
||||
public override Task<ModelLoadResult> GetEmbeddingModels(string? apiKeyProvisional = null, CancellationToken token = default)
|
||||
{
|
||||
if (!this.hfProvider.SupportsEmbeddings())
|
||||
if (!this.hfProvider.SupportsEmbeddings)
|
||||
return Task.FromResult(ModelLoadResult.FromModels([]));
|
||||
|
||||
return this.LoadHubModels(SecretStoreType.EMBEDDING_PROVIDER, "feature-extraction", apiKeyProvisional, token);
|
||||
@@ -309,14 +309,14 @@ public sealed class ProviderHuggingFace : BaseProvider
|
||||
/// <returns>The models of that provider for that task.</returns>
|
||||
private Task<ModelLoadResult> LoadHubModels(SecretStoreType storeType, string pipelineTag, string? apiKeyProvisional, CancellationToken token)
|
||||
{
|
||||
var requestURL = $"{HUB_MODELS_URL}{this.hfProvider.EndpointsId()}&pipeline_tag={pipelineTag}";
|
||||
var requestURL = $"{HUB_MODELS_URL}{this.hfProvider.EndpointsId}&pipeline_tag={pipelineTag}";
|
||||
return this.LoadModelsResponse<IList<HubModel>>(storeType, requestURL, hubModels => hubModels.Select(hubModel => new Model(hubModel.Id, null)), apiKeyProvisional, token: token);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<ModelLoadResult> GetTranscriptionModels(string? apiKeyProvisional = null, CancellationToken token = default)
|
||||
{
|
||||
if (!this.hfProvider.SupportsTranscription())
|
||||
if (!this.hfProvider.SupportsTranscription)
|
||||
return Task.FromResult(ModelLoadResult.FromModels([]));
|
||||
|
||||
return this.LoadHubModels(SecretStoreType.TRANSCRIPTION_PROVIDER, "automatic-speech-recognition", apiKeyProvisional, token);
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class ProviderIONOS() : BaseProvider(LLMProviders.IONOS, new Uri("
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.IONOS.ToSecretId();
|
||||
public override string Id => LLMProviders.IONOS.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "IONOS";
|
||||
|
||||
@@ -40,8 +40,8 @@ public static class LLMProvidersExtensions
|
||||
/// This value is UI text and may be localized. Do not use it for persisted IDs, secret namespaces,
|
||||
/// or other stable identifiers.
|
||||
/// </remarks>
|
||||
/// <returns>The human-readable name of the provider.</returns>
|
||||
public string ToName() => provider.ToName(translate: true);
|
||||
/// <value>The human-readable name of the provider.</value>
|
||||
public string Name => provider.ToName(translate: true);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the human-readable name of the provider.
|
||||
@@ -85,8 +85,8 @@ public static class LLMProvidersExtensions
|
||||
/// These values are used for OS keyring namespaces. They must never be localized or changed without
|
||||
/// an explicit migration for existing API keys.
|
||||
/// </remarks>
|
||||
/// <returns>The stable secret namespace for the provider.</returns>
|
||||
public string ToSecretId() => provider switch
|
||||
/// <value>The stable secret namespace for the provider.</value>
|
||||
public string SecretId => provider switch
|
||||
{
|
||||
LLMProviders.NONE => "No provider selected",
|
||||
|
||||
@@ -195,8 +195,8 @@ public static class LLMProvidersExtensions
|
||||
/// <summary>
|
||||
/// Determines if the specified provider supports embeddings.
|
||||
/// </summary>
|
||||
/// <returns>True if the provider supports embeddings; otherwise, false.</returns>
|
||||
public bool ProvideEmbeddingAPI() => provider switch
|
||||
/// <value>True if the provider supports embeddings; otherwise, false.</value>
|
||||
public bool ProvideEmbeddingAPI => provider switch
|
||||
{
|
||||
//
|
||||
// Providers that support embeddings:
|
||||
@@ -239,7 +239,7 @@ public static class LLMProvidersExtensions
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public bool ProvideTranscriptionAPI() => provider switch
|
||||
public bool ProvideTranscriptionAPI => provider switch
|
||||
{
|
||||
//
|
||||
// Providers that support transcription:
|
||||
@@ -294,8 +294,8 @@ public static class LLMProvidersExtensions
|
||||
/// larger images through another provider. What we actually send is asked through
|
||||
/// IImageSourceExtensions.MaxImageSizeBytesFor, which also applies our own limit.
|
||||
/// </remarks>
|
||||
/// <returns>The size limit of one image file, or null when the provider states none we know of.</returns>
|
||||
public long? GetMaxImageSizeBytes() => provider switch
|
||||
/// <value>The size limit of one image file, or null when the provider states none we know of.</value>
|
||||
public long? MaxImageSizeBytes => provider switch
|
||||
{
|
||||
//
|
||||
// Anthropic accepts at most 5 MiB (5,242,880 bytes) of base64 per image. Base64 needs four
|
||||
@@ -360,7 +360,7 @@ public static class LLMProvidersExtensions
|
||||
}
|
||||
}
|
||||
|
||||
public string GetCreationURL() => provider switch
|
||||
public string CreationURL => provider switch
|
||||
{
|
||||
LLMProviders.OPEN_AI => "https://platform.openai.com/signup",
|
||||
LLMProviders.MISTRAL => "https://console.mistral.ai/",
|
||||
@@ -385,7 +385,7 @@ public static class LLMProvidersExtensions
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
public string GetDashboardURL() => provider switch
|
||||
public string DashboardURL => provider switch
|
||||
{
|
||||
LLMProviders.OPEN_AI => "https://platform.openai.com/usage",
|
||||
LLMProviders.MISTRAL => "https://console.mistral.ai/usage/",
|
||||
@@ -408,7 +408,7 @@ public static class LLMProvidersExtensions
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
public bool HasDashboard() => provider switch
|
||||
public bool HasDashboard => provider switch
|
||||
{
|
||||
LLMProviders.OPEN_AI => true,
|
||||
LLMProviders.MISTRAL => true,
|
||||
@@ -434,11 +434,11 @@ public static class LLMProvidersExtensions
|
||||
public string GetModelsOverviewURL(HFInferenceProvider inferenceProvider) => provider switch
|
||||
{
|
||||
LLMProviders.FIREWORKS => "https://fireworks.ai/models?show=Serverless",
|
||||
LLMProviders.HUGGINGFACE => $"https://huggingface.co/models?inference_provider={inferenceProvider.CatalogFilter()}",
|
||||
LLMProviders.HUGGINGFACE => $"https://huggingface.co/models?inference_provider={inferenceProvider.CatalogFilter}",
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
public bool IsLLMModelProvidedManually() => provider switch
|
||||
public bool IsLLMModelProvidedManually => provider switch
|
||||
{
|
||||
LLMProviders.FIREWORKS => true,
|
||||
_ => false,
|
||||
@@ -467,13 +467,13 @@ public static class LLMProvidersExtensions
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public bool IsHostNeeded() => provider switch
|
||||
public bool IsHostNeeded => provider switch
|
||||
{
|
||||
LLMProviders.SELF_HOSTED => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public bool IsHostnameNeeded() => provider switch
|
||||
public bool IsHostnameNeeded => provider switch
|
||||
{
|
||||
LLMProviders.SELF_HOSTED => true,
|
||||
LLMProviders.LITE_LLM => true,
|
||||
@@ -490,8 +490,8 @@ public static class LLMProvidersExtensions
|
||||
/// today: whether a dialog asks for a hostname is a question of the user interface, and it must
|
||||
/// never silently decide what a server learns about the user.
|
||||
/// </remarks>
|
||||
/// <returns>True when the provider runs on a self-hosted server; otherwise, false.</returns>
|
||||
public bool RunsOnSelfHostedServer() => provider switch
|
||||
/// <value>True when the provider runs on a self-hosted server; otherwise, false.</value>
|
||||
public bool RunsOnSelfHostedServer => provider switch
|
||||
{
|
||||
LLMProviders.SELF_HOSTED => true,
|
||||
LLMProviders.LITE_LLM => true,
|
||||
@@ -529,7 +529,7 @@ public static class LLMProvidersExtensions
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public bool ShowRegisterButton() => provider switch
|
||||
public bool ShowRegisterButton => provider switch
|
||||
{
|
||||
LLMProviders.OPEN_AI => true,
|
||||
LLMProviders.MISTRAL => true,
|
||||
@@ -556,7 +556,7 @@ public static class LLMProvidersExtensions
|
||||
public bool CanLoadModels(Host host, string? apiKey)
|
||||
{
|
||||
if (provider is LLMProviders.SELF_HOSTED)
|
||||
return host.IsModelListSupported();
|
||||
return host.IsModelListSupported;
|
||||
|
||||
if(provider is LLMProviders.NONE)
|
||||
return false;
|
||||
@@ -567,7 +567,7 @@ public static class LLMProvidersExtensions
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsHFInstanceProviderNeeded() => provider switch
|
||||
public bool IsHFInstanceProviderNeeded => provider switch
|
||||
{
|
||||
LLMProviders.HUGGINGFACE => true,
|
||||
_ => false,
|
||||
|
||||
@@ -13,7 +13,7 @@ public sealed class ProviderLiteLLM(string hostname) : BaseProvider(LLMProviders
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.LITE_LLM.ToSecretId();
|
||||
public override string Id => LLMProviders.LITE_LLM.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "LiteLLM";
|
||||
|
||||
@@ -14,7 +14,7 @@ public sealed class ProviderMistral() : BaseProvider(LLMProviders.MISTRAL, new U
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.MISTRAL.ToSecretId();
|
||||
public override string Id => LLMProviders.MISTRAL.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Mistral";
|
||||
|
||||
@@ -25,7 +25,7 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.OPEN_AI.ToSecretId();
|
||||
public override string Id => LLMProviders.OPEN_AI.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "OpenAI";
|
||||
@@ -71,7 +71,7 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, new Ur
|
||||
// OpenAI changed the role of the system prompt from one generation to the next, and the
|
||||
// early reasoning models take no system prompt at all. Which role a model takes is stated
|
||||
// by the OpenAI families in Models/OpenAI:
|
||||
var systemPromptRole = modelProfile.SystemPromptRole.ToOpenAIRole();
|
||||
var systemPromptRole = modelProfile.SystemPromptRole.OpenAIRole;
|
||||
|
||||
// Check if we are using the Responses API or the Chat Completion API:
|
||||
var usingResponsesAPI = modelProfile.Has(Capability.RESPONSES_API);
|
||||
|
||||
@@ -15,8 +15,8 @@ public static class SystemPromptRoleExtensions
|
||||
/// model the rules do not know is almost always one released after they were written, and the
|
||||
/// older generations which still want "system" say so in their families.
|
||||
/// </remarks>
|
||||
/// <returns>The role, as OpenAI names it.</returns>
|
||||
public string ToOpenAIRole() => role switch
|
||||
/// <value>The role, as OpenAI names it.</value>
|
||||
public string OpenAIRole => role switch
|
||||
{
|
||||
SystemPromptRole.SYSTEM => "system",
|
||||
SystemPromptRole.DEVELOPER => "developer",
|
||||
|
||||
@@ -15,7 +15,7 @@ public sealed class ProviderOpenRouter() : BaseProvider(LLMProviders.OPEN_ROUTER
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.OPEN_ROUTER.ToSecretId();
|
||||
public override string Id => LLMProviders.OPEN_ROUTER.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "OpenRouter";
|
||||
|
||||
@@ -22,7 +22,7 @@ public sealed class ProviderPerplexity() : BaseProvider(LLMProviders.PERPLEXITY,
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.PERPLEXITY.ToSecretId();
|
||||
public override string Id => LLMProviders.PERPLEXITY.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Perplexity";
|
||||
|
||||
@@ -15,7 +15,7 @@ public static class ProviderRequestFailureReasonExtensions
|
||||
/// Meant as a label beside the full message, so a list of failures can be scanned instead of
|
||||
/// read: twenty entries which all say API key are one problem, not twenty.
|
||||
/// </remarks>
|
||||
public string GetName() => failureReason switch
|
||||
public string Name => failureReason switch
|
||||
{
|
||||
ProviderRequestFailureReason.INSUFFICIENT_QUOTA => TB("No credits left"),
|
||||
ProviderRequestFailureReason.TOO_MANY_REQUESTS => TB("Too many requests"),
|
||||
@@ -39,7 +39,7 @@ public static class ProviderRequestFailureReasonExtensions
|
||||
/// Only for the failures a setting actually fixes. Pointing at the settings for a provider
|
||||
/// which is merely overloaded would send the user looking for a mistake they never made.
|
||||
/// </remarks>
|
||||
public bool IsFixedInProviderSettings() => failureReason is
|
||||
public bool IsFixedInProviderSettings => failureReason is
|
||||
ProviderRequestFailureReason.INVALID_OR_MISSING_API_KEY or
|
||||
ProviderRequestFailureReason.AUTHENTICATION_OR_PERMISSION_ERROR or
|
||||
ProviderRequestFailureReason.MODEL_NOT_FOUND or
|
||||
|
||||
@@ -15,7 +15,7 @@ public sealed class ProviderRequesty() : BaseProvider(LLMProviders.REQUESTY, new
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.REQUESTY.ToSecretId();
|
||||
public override string Id => LLMProviders.REQUESTY.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Requesty";
|
||||
|
||||
@@ -5,7 +5,7 @@ public static class HostExtensions
|
||||
/// <param name="host">The engine.</param>
|
||||
extension(Host host)
|
||||
{
|
||||
public string Name() => host switch
|
||||
public string Name => host switch
|
||||
{
|
||||
Host.NONE => "None",
|
||||
|
||||
@@ -19,22 +19,22 @@ public static class HostExtensions
|
||||
_ => "Unknown",
|
||||
};
|
||||
|
||||
public string BaseURL() => host switch
|
||||
public string BaseURL => host switch
|
||||
{
|
||||
_ => "/v1/",
|
||||
};
|
||||
|
||||
public string ChatURL() => host switch
|
||||
public string ChatURL => host switch
|
||||
{
|
||||
_ => "chat/completions",
|
||||
};
|
||||
|
||||
public string TranscriptionURL() => host switch
|
||||
public string TranscriptionURL => host switch
|
||||
{
|
||||
_ => "audio/transcriptions",
|
||||
};
|
||||
|
||||
public string EmbeddingURL() => host switch
|
||||
public string EmbeddingURL => host switch
|
||||
{
|
||||
_ => "embeddings",
|
||||
};
|
||||
@@ -43,12 +43,12 @@ public static class HostExtensions
|
||||
/// The largest image file, in bytes, which the engine accepts in a chat request, where we know of one.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Like the limit of a cloud provider, see LLMProvidersExtensions.GetMaxImageSizeBytes, this
|
||||
/// Like the limit of a cloud provider, see LLMProvidersExtensions.MaxImageSizeBytes, this
|
||||
/// belongs to the API of the engine, not to the model. What we actually send is asked through
|
||||
/// IImageSourceExtensions.MaxImageSizeBytesFor.
|
||||
/// </remarks>
|
||||
/// <returns>The size limit of one image file, or null when the engine states none we know of.</returns>
|
||||
public long? GetMaxImageSizeBytes() => host switch
|
||||
/// <value>The size limit of one image file, or null when the engine states none we know of.</value>
|
||||
public long? MaxImageSizeBytes => host switch
|
||||
{
|
||||
//
|
||||
// llmman answers a chat request larger than 2 MiB with 413: its route /v1/chat/completions
|
||||
@@ -61,53 +61,62 @@ public static class HostExtensions
|
||||
_ => null,
|
||||
};
|
||||
|
||||
public bool IsChatSupported()
|
||||
public bool IsChatSupported
|
||||
{
|
||||
switch (host)
|
||||
get
|
||||
{
|
||||
case Host.WHISPER_CPP:
|
||||
return false;
|
||||
|
||||
default:
|
||||
case Host.OLLAMA:
|
||||
case Host.VLLM:
|
||||
case Host.LM_STUDIO:
|
||||
case Host.LLAMA_CPP:
|
||||
case Host.LLMMAN:
|
||||
return true;
|
||||
switch (host)
|
||||
{
|
||||
case Host.WHISPER_CPP:
|
||||
return false;
|
||||
|
||||
default:
|
||||
case Host.OLLAMA:
|
||||
case Host.VLLM:
|
||||
case Host.LM_STUDIO:
|
||||
case Host.LLAMA_CPP:
|
||||
case Host.LLMMAN:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmbeddingSupported()
|
||||
public bool IsEmbeddingSupported
|
||||
{
|
||||
switch (host)
|
||||
get
|
||||
{
|
||||
case Host.LM_STUDIO:
|
||||
case Host.OLLAMA:
|
||||
case Host.VLLM:
|
||||
case Host.LLMMAN:
|
||||
return true;
|
||||
|
||||
default:
|
||||
case Host.LLAMA_CPP:
|
||||
return false;
|
||||
switch (host)
|
||||
{
|
||||
case Host.LM_STUDIO:
|
||||
case Host.OLLAMA:
|
||||
case Host.VLLM:
|
||||
case Host.LLMMAN:
|
||||
return true;
|
||||
|
||||
default:
|
||||
case Host.LLAMA_CPP:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsTranscriptionSupported()
|
||||
public bool IsTranscriptionSupported
|
||||
{
|
||||
switch (host)
|
||||
get
|
||||
{
|
||||
case Host.OLLAMA:
|
||||
case Host.VLLM:
|
||||
case Host.WHISPER_CPP:
|
||||
case Host.LLMMAN:
|
||||
return true;
|
||||
switch (host)
|
||||
{
|
||||
case Host.OLLAMA:
|
||||
case Host.VLLM:
|
||||
case Host.WHISPER_CPP:
|
||||
case Host.LLMMAN:
|
||||
return true;
|
||||
|
||||
default:
|
||||
case Host.LM_STUDIO:
|
||||
case Host.LLAMA_CPP:
|
||||
return false;
|
||||
default:
|
||||
case Host.LM_STUDIO:
|
||||
case Host.LLAMA_CPP:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,22 +131,25 @@ public static class HostExtensions
|
||||
/// provider offers that model under a fixed name instead. llama.cpp is, even though builds
|
||||
/// older than the route answer it with 404; the provider handles those builds itself.
|
||||
/// </remarks>
|
||||
/// <returns>True when the models can be loaded from the engine; otherwise, false.</returns>
|
||||
public bool IsModelListSupported()
|
||||
/// <value>True when the models can be loaded from the engine; otherwise, false.</value>
|
||||
public bool IsModelListSupported
|
||||
{
|
||||
switch (host)
|
||||
get
|
||||
{
|
||||
case Host.LLAMA_CPP:
|
||||
case Host.OLLAMA:
|
||||
case Host.LM_STUDIO:
|
||||
case Host.VLLM:
|
||||
case Host.LLMMAN:
|
||||
return true;
|
||||
switch (host)
|
||||
{
|
||||
case Host.LLAMA_CPP:
|
||||
case Host.OLLAMA:
|
||||
case Host.LM_STUDIO:
|
||||
case Host.VLLM:
|
||||
case Host.LLMMAN:
|
||||
return true;
|
||||
|
||||
default:
|
||||
case Host.NONE:
|
||||
case Host.WHISPER_CPP:
|
||||
return false;
|
||||
default:
|
||||
case Host.NONE:
|
||||
case Host.WHISPER_CPP:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ using AIStudio.Tools.PluginSystem;
|
||||
|
||||
namespace AIStudio.Provider.SelfHosted;
|
||||
|
||||
public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvider(LLMProviders.SELF_HOSTED, new Uri($"{hostname}{host.BaseURL()}"), ExternalHttpTrustPolicy.ALLOW_CUSTOM_ROOTS_WHEN_HOST_WHITELISTED, LOGGER)
|
||||
public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvider(LLMProviders.SELF_HOSTED, new Uri($"{hostname}{host.BaseURL}"), ExternalHttpTrustPolicy.ALLOW_CUSTOM_ROOTS_WHEN_HOST_WHITELISTED, LOGGER)
|
||||
{
|
||||
private static readonly ILogger<ProviderSelfHosted> LOGGER = Program.LOGGER_FACTORY.CreateLogger<ProviderSelfHosted>();
|
||||
|
||||
@@ -19,13 +19,13 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.SELF_HOSTED.ToSecretId();
|
||||
public override string Id => LLMProviders.SELF_HOSTED.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "Self-hosted";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasModelLoadingCapability => host.IsModelListSupported();
|
||||
public override bool HasModelLoadingCapability => host.IsModelListSupported;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async IAsyncEnumerable<ContentStreamChunk> StreamChatCompletion(Provider.Model chatModel, ChatThread chatThread, SettingsManager settingsManager, [EnumeratorCancellation] CancellationToken token = default)
|
||||
@@ -63,7 +63,7 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
|
||||
};
|
||||
},
|
||||
isTryingSecret: true,
|
||||
requestPath: host.ChatURL(),
|
||||
requestPath: host.ChatURL,
|
||||
token: token))
|
||||
yield return content;
|
||||
}
|
||||
@@ -97,7 +97,7 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
|
||||
if (host is Host.LLAMA_CPP)
|
||||
return await this.LoadLlamaCppTextModels(apiKeyProvisional, token);
|
||||
|
||||
if (!host.IsChatSupported() || !host.IsModelListSupported())
|
||||
if (!host.IsChatSupported || !host.IsModelListSupported)
|
||||
return ModelLoadResult.FromModels([]);
|
||||
|
||||
var result = await this.LoadModels(SecretStoreType.LLM_PROVIDER, apiKeyProvisional, token);
|
||||
@@ -123,7 +123,7 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!host.IsEmbeddingSupported() || !host.IsModelListSupported())
|
||||
if (!host.IsEmbeddingSupported || !host.IsModelListSupported)
|
||||
return ModelLoadResult.FromModels([]);
|
||||
|
||||
var result = await this.LoadModels(SecretStoreType.EMBEDDING_PROVIDER, apiKeyProvisional, token);
|
||||
@@ -150,7 +150,7 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
|
||||
new Provider.Model("loaded-model", TB("Model as configured by whisper.cpp")),
|
||||
]);
|
||||
|
||||
if (!host.IsTranscriptionSupported() || !host.IsModelListSupported())
|
||||
if (!host.IsTranscriptionSupported || !host.IsModelListSupported)
|
||||
return ModelLoadResult.FromModels([]);
|
||||
|
||||
//
|
||||
|
||||
@@ -13,7 +13,7 @@ public sealed class ProviderX() : BaseProvider(LLMProviders.X, new Uri("https://
|
||||
#region Implementation of IProvider
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Id => LLMProviders.X.ToSecretId();
|
||||
public override string Id => LLMProviders.X.SecretId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string InstanceName { get; set; } = "xAI";
|
||||
|
||||
Reference in new issue
Block a user