Adopted further C# 14 and .NET 10 features (#1158)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-04 14:04:10 +01:00
1 parent f649febf88
commit f0fa1411c8
40 files changed
+545 -56

No files matched your search

@@ -13,6 +13,19 @@ namespace AIStudio.Provider;
/// </remarks>
public static class AdditionalApiParametersParser
{
/// <summary>
/// Every name only once per object.
/// </summary>
/// <remarks>
/// The dialog for providers refuses a name written twice, but a configuration plugin brings its
/// providers past the dialog. With both values read, it would be open which of them reaches the
/// provider, and the dictionary below would refuse the second one with an exception.
/// </remarks>
private static readonly JsonDocumentOptions DOCUMENT_OPTIONS = new()
{
AllowDuplicateProperties = false,
};
/// <summary>
/// Try to parse an additional-API-parameters JSON fragment into a dictionary.
/// </summary>
@@ -30,7 +43,7 @@ public static class AdditionalApiParametersParser
try
{
// The UI stores only the object body, so wrap it before parsing.
using var jsonDoc = JsonDocument.Parse($"{{{additionalJsonApiParameters}}}");
using var jsonDoc = JsonDocument.Parse($"{{{additionalJsonApiParameters}}}", DOCUMENT_OPTIONS);
parameters = ConvertToDictionary(jsonDoc.RootElement);
return true;
}
@@ -77,7 +77,7 @@ public sealed class ProviderAlibabaCloud() : BaseProvider(LLMProviders.ALIBABA_C
public override async Task<ModelLoadResult> GetTextModels(string? apiKeyProvisional = null, CancellationToken token = default)
{
var result = await this.LoadModels(SecretStoreType.LLM_PROVIDER, apiKeyProvisional, token);
return result with { Models = [..result.Models.Where(model => model.IsChatModel(this.Provider)).OrderBy(x => x.Id)] };
return result with { Models = [..result.Models.Where(model => model.IsChatModel(this.Provider)).OrderBy(x => x.Id, Model.ID_ORDER)] };
}
/// <inheritdoc />
@@ -90,7 +90,7 @@ public sealed class ProviderAlibabaCloud() : BaseProvider(LLMProviders.ALIBABA_C
public override async Task<ModelLoadResult> GetEmbeddingModels(string? apiKeyProvisional = null, CancellationToken token = default)
{
var result = await this.LoadModels(SecretStoreType.EMBEDDING_PROVIDER, apiKeyProvisional, token);
return result with { Models = [..result.Models.Where(model => model.IsEmbeddingModel(this.Provider)).OrderBy(x => x.Id)] };
return result with { Models = [..result.Models.Where(model => model.IsEmbeddingModel(this.Provider)).OrderBy(x => x.Id, Model.ID_ORDER)] };
}
#region Overrides of BaseProvider
@@ -218,7 +218,7 @@ public sealed class ProviderAnthropic() : BaseProvider(LLMProviders.ANTHROPIC, n
// has not always been only something to talk to. The six above skip that question
// because they are not a catalog: every one of them was picked by hand.
//
Models = [..result.Models.Where(model => model.IsChatModel(this.Provider)).Concat(additionalModels).DistinctBy(x => x.Id).OrderBy(x => x.Id)]
Models = [..result.Models.Where(model => model.IsChatModel(this.Provider)).Concat(additionalModels).DistinctBy(x => x.Id).OrderBy(x => x.Id, Model.ID_ORDER)]
};
}
+12
View File
@@ -1,3 +1,5 @@
using System.Globalization;
using AIStudio.Tools.PluginSystem;
namespace AIStudio.Provider;
@@ -20,6 +22,16 @@ public readonly record struct Model(string Id, string? DisplayName)
/// </summary>
public static readonly Model SYSTEM_MODEL = new(SYSTEM_MODEL_ID, null);
/// <summary>
/// Orders model IDs by the numbers in them, as people read them.
/// </summary>
/// <remarks>
/// Compared digit by digit, "gpt-4.10" comes before "gpt-4.9", "o10" before "o3", and a list with the
/// newest models first puts an older one on top. The order does not depend on the language of the
/// operating system either.
/// </remarks>
public static readonly StringComparer ID_ORDER = StringComparer.Create(CultureInfo.InvariantCulture, CompareOptions.NumericOrdering);
/// <summary>
/// Checks if this model is the system-configured placeholder.
/// </summary>