Turned getter-like extension methods into extension properties (#1157)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-04 13:00:56 +01:00
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";