Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Libraries/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2012,7 +2012,7 @@ dotnet_style_null_propagation = true
# Title : Use auto property
# Category : Style
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0032
dotnet_diagnostic.IDE0032.severity = silent # https://github.com/dotnet/extensions/issues/6864 tracks re-enabling this
dotnet_diagnostic.IDE0032.severity = warning
dotnet_style_prefer_auto_properties = true

# Title : Use explicitly provided tuple name
Expand Down Expand Up @@ -5889,7 +5889,7 @@ dotnet_diagnostic.SA1414.severity = warning
# Title : Braces for multi-line statements should not share line
# Category : StyleCop.CSharp.LayoutRules
# Help Link: https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1500.md
dotnet_diagnostic.SA1500.severity = warning
dotnet_diagnostic.SA1500.severity = suggestion # rule does not work well with field-based property initializers

# Title : Statement should not be on a single line
# Category : StyleCop.CSharp.LayoutRules
Expand Down Expand Up @@ -5957,7 +5957,7 @@ dotnet_diagnostic.SA1512.severity = none
# Title : Closing brace should be followed by blank line
# Category : StyleCop.CSharp.LayoutRules
# Help Link: https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1513.md
dotnet_diagnostic.SA1513.severity = warning
dotnet_diagnostic.SA1513.severity = suggestion # rule does not work well with field-based property initializers

# Title : Element documentation header should be preceded by blank line
# Category : StyleCop.CSharp.LayoutRules
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,18 @@ namespace Microsoft.Extensions.AI;
[JsonConverter(typeof(Converter))]
public readonly struct ChatFinishReason : IEquatable<ChatFinishReason>
{
/// <summary>The finish reason value. If <see langword="null"/> because `default(ChatFinishReason)` was used, the instance will behave like <see cref="Stop"/>.</summary>
private readonly string? _value;

/// <summary>Initializes a new instance of the <see cref="ChatFinishReason"/> struct with a string that describes the reason.</summary>
/// <param name="value">The reason value.</param>
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="value"/> is empty or composed entirely of whitespace.</exception>
[JsonConstructor]
public ChatFinishReason(string value)
{
_value = Throw.IfNullOrWhitespace(value);
Value = Throw.IfNullOrWhitespace(value);
}

/// <summary>Gets the finish reason value.</summary>
public string Value => _value ?? Stop.Value;
public string Value => field ?? Stop.Value;

/// <inheritdoc />
public override bool Equals([NotNullWhen(true)] object? obj) => obj is ChatFinishReason other && Equals(other);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ public class ChatResponseUpdate
/// <summary>The response update content items.</summary>
private IList<AIContent>? _contents;

/// <summary>The name of the author of the update.</summary>
private string? _authorName;

/// <summary>Initializes a new instance of the <see cref="ChatResponseUpdate"/> class.</summary>
[JsonConstructor]
public ChatResponseUpdate()
Expand All @@ -64,8 +61,8 @@ public ChatResponseUpdate(ChatRole? role, IList<AIContent>? contents)
/// <summary>Gets or sets the name of the author of the response update.</summary>
public string? AuthorName
{
get => _authorName;
set => _authorName = string.IsNullOrWhiteSpace(value) ? null : value;
get;
set => field = string.IsNullOrWhiteSpace(value) ? null : value;
}

/// <summary>Gets or sets the role of the author of the response update.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System.Text.Json.Serialization;
using Microsoft.Shared.Diagnostics;

#pragma warning disable IDE0032 // Use auto property
#pragma warning disable CA1307 // Specify StringComparison for clarity

namespace Microsoft.Extensions.AI;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,19 @@ namespace Microsoft.Extensions.AI;
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class ErrorContent : AIContent
{
/// <summary>The error message.</summary>
private string? _message;

/// <summary>Initializes a new instance of the <see cref="ErrorContent"/> class with the specified error message.</summary>
/// <param name="message">The error message to store in this content.</param>
public ErrorContent(string? message)
{
_message = message;
Message = message;
}

/// <summary>Gets or sets the error message.</summary>
[AllowNull]
public string Message
{
get => _message ?? string.Empty;
set => _message = value;
get => field ?? string.Empty;
set;
}

/// <summary>Gets or sets an error code associated with the error.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ namespace Microsoft.Extensions.AI;
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public sealed class TextContent : AIContent
{
private string? _text;

/// <summary>
/// Initializes a new instance of the <see cref="TextContent"/> class.
/// </summary>
/// <param name="text">The text content.</param>
public TextContent(string? text)
{
_text = text;
Text = text;
}

/// <summary>
Expand All @@ -29,8 +27,8 @@ public TextContent(string? text)
[AllowNull]
public string Text
{
get => _text ?? string.Empty;
set => _text = value;
get => field ?? string.Empty;
set;
}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ namespace Microsoft.Extensions.AI;
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public sealed class TextReasoningContent : AIContent
{
private string? _text;

/// <summary>
/// Initializes a new instance of the <see cref="TextReasoningContent"/> class.
/// </summary>
/// <param name="text">The text reasoning content.</param>
public TextReasoningContent(string? text)
{
_text = text;
Text = text;
}

/// <summary>
Expand All @@ -34,8 +32,8 @@ public TextReasoningContent(string? text)
[AllowNull]
public string Text
{
get => _text ?? string.Empty;
set => _text = value;
get => field ?? string.Empty;
set;
}

/// <summary>Gets or sets an optional opaque blob of data associated with this reasoning content.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,18 @@ namespace Microsoft.Extensions.AI;
/// <summary>Represents the options for an embedding generation request.</summary>
public class EmbeddingGenerationOptions
{
private int? _dimensions;

/// <summary>Gets or sets the number of dimensions requested in the embedding.</summary>
public int? Dimensions
{
get => _dimensions;
get;
set
{
if (value is not null)
{
_ = Throw.IfLessThan(value.Value, 1, nameof(value));
}

_dimensions = value;
field = value;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ namespace Microsoft.Extensions.AI;
[Experimental("MEAI001")]
public class ImageGenerationResponse
{
/// <summary>The content items in the generated text response.</summary>
private IList<AIContent>? _contents;

/// <summary>Initializes a new instance of the <see cref="ImageGenerationResponse"/> class.</summary>
[JsonConstructor]
public ImageGenerationResponse()
Expand All @@ -24,7 +21,7 @@ public ImageGenerationResponse()
/// <param name="contents">The contents for this response.</param>
public ImageGenerationResponse(IList<AIContent>? contents)
{
_contents = contents;
Contents = contents;
}

/// <summary>Gets or sets the raw representation of the image generation response from an underlying implementation.</summary>
Expand All @@ -46,8 +43,8 @@ public ImageGenerationResponse(IList<AIContent>? contents)
[AllowNull]
public IList<AIContent> Contents
{
get => _contents ??= [];
set => _contents = value;
get => field ??= [];
set;
}

/// <summary>Gets or sets usage details for the image generation response.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@ internal static partial class AzureStorageJsonUtilities
{
internal static class Default
{
private static JsonSerializerOptions? _options;
internal static JsonSerializerOptions Options => _options ??= CreateJsonSerializerOptions(writeIndented: true);
internal static JsonSerializerOptions Options => field ??= CreateJsonSerializerOptions(writeIndented: true);
internal static JsonTypeInfo<CacheEntry> CacheEntryTypeInfo => Options.GetTypeInfo<CacheEntry>();
internal static JsonTypeInfo<ScenarioRunResult> ScenarioRunResultTypeInfo => Options.GetTypeInfo<ScenarioRunResult>();
}

internal static class Compact
{
private static JsonSerializerOptions? _options;
internal static JsonSerializerOptions Options => _options ??= CreateJsonSerializerOptions(writeIndented: false);
internal static JsonSerializerOptions Options => field ??= CreateJsonSerializerOptions(writeIndented: false);
internal static JsonTypeInfo<CacheEntry> CacheEntryTypeInfo => Options.GetTypeInfo<CacheEntry>();
internal static JsonTypeInfo<ScenarioRunResult> ScenarioRunResultTypeInfo => Options.GetTypeInfo<ScenarioRunResult>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,15 @@ internal static partial class JsonUtilities
{
internal static class Default
{
private static JsonSerializerOptions? _options;
internal static JsonSerializerOptions Options => _options ??= CreateJsonSerializerOptions(writeIndented: true);
internal static JsonSerializerOptions Options => field ??= CreateJsonSerializerOptions(writeIndented: true);
internal static JsonTypeInfo<Dataset> DatasetTypeInfo => Options.GetTypeInfo<Dataset>();
internal static JsonTypeInfo<CacheEntry> CacheEntryTypeInfo => Options.GetTypeInfo<CacheEntry>();
internal static JsonTypeInfo<ScenarioRunResult> ScenarioRunResultTypeInfo => Options.GetTypeInfo<ScenarioRunResult>();
}

internal static class Compact
{
private static JsonSerializerOptions? _options;
internal static JsonSerializerOptions Options => _options ??= CreateJsonSerializerOptions(writeIndented: false);
internal static JsonSerializerOptions Options => field ??= CreateJsonSerializerOptions(writeIndented: false);
internal static JsonTypeInfo<Dataset> DatasetTypeInfo => Options.GetTypeInfo<Dataset>();
internal static JsonTypeInfo<CacheEntry> CacheEntryTypeInfo => Options.GetTypeInfo<CacheEntry>();
internal static JsonTypeInfo<ScenarioRunResult> ScenarioRunResultTypeInfo => Options.GetTypeInfo<ScenarioRunResult>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,10 @@ internal sealed partial class ContentSafetyService(ContentSafetyServiceConfigura
private const string APIVersionForServiceDiscoveryInHubBasedProjects = "?api-version=2023-08-01-preview";
private const string APIVersionForNonHubBasedProjects = "?api-version=2025-05-15-preview";

private static HttpClient? _sharedHttpClient;
private static HttpClient SharedHttpClient
{
get
{
_sharedHttpClient ??= new HttpClient();
return _sharedHttpClient;
}
}
private static HttpClient SharedHttpClient =>
field ??
Interlocked.CompareExchange(ref field, new(), null) ??
field;

private static readonly ConcurrentDictionary<UrlCacheKey, string> _serviceUrlCache =
new ConcurrentDictionary<UrlCacheKey, string>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ public class DistributedCachingChatClient : CachingChatClient
/// <summary>Additional values used to inform the cache key employed for storing state.</summary>
private object[]? _cacheKeyAdditionalValues;

/// <summary>The <see cref="JsonSerializerOptions"/> to use when serializing cache data.</summary>
private JsonSerializerOptions _jsonSerializerOptions = AIJsonUtilities.DefaultOptions;

/// <summary>Initializes a new instance of the <see cref="DistributedCachingChatClient"/> class.</summary>
/// <param name="innerClient">The underlying <see cref="IChatClient"/>.</param>
/// <param name="storage">An <see cref="IDistributedCache"/> instance that will be used as the backing store for the cache.</param>
Expand All @@ -59,9 +56,9 @@ public DistributedCachingChatClient(IChatClient innerClient, IDistributedCache s
/// <summary>Gets or sets JSON serialization options to use when serializing cache data.</summary>
public JsonSerializerOptions JsonSerializerOptions
{
get => _jsonSerializerOptions;
set => _jsonSerializerOptions = Throw.IfNull(value);
}
get;
set => field = Throw.IfNull(value);
} = AIJsonUtilities.DefaultOptions;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you manually fix this one up? I was getting this on a separate line when using dotnet format.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see it was because of SA1500 and SA1513 being enabled as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. Those stylecop rules need to be updated to accomodate C# 14 features.


/// <summary>Gets or sets additional values used to inform the cache key employed for storing state.</summary>
/// <remarks>Any values set in this list will augment the other values used to inform the cache key.</remarks>
Expand All @@ -75,11 +72,11 @@ public IReadOnlyList<object>? CacheKeyAdditionalValues
protected override async Task<ChatResponse?> ReadCacheAsync(string key, CancellationToken cancellationToken)
{
_ = Throw.IfNull(key);
_jsonSerializerOptions.MakeReadOnly();
JsonSerializerOptions.MakeReadOnly();

if (await _storage.GetAsync(key, cancellationToken) is byte[] existingJson)
{
return (ChatResponse?)JsonSerializer.Deserialize(existingJson, _jsonSerializerOptions.GetTypeInfo(typeof(ChatResponse)));
return (ChatResponse?)JsonSerializer.Deserialize(existingJson, JsonSerializerOptions.GetTypeInfo(typeof(ChatResponse)));
}

return null;
Expand All @@ -89,11 +86,11 @@ public IReadOnlyList<object>? CacheKeyAdditionalValues
protected override async Task<IReadOnlyList<ChatResponseUpdate>?> ReadCacheStreamingAsync(string key, CancellationToken cancellationToken)
{
_ = Throw.IfNull(key);
_jsonSerializerOptions.MakeReadOnly();
JsonSerializerOptions.MakeReadOnly();

if (await _storage.GetAsync(key, cancellationToken) is byte[] existingJson)
{
return (IReadOnlyList<ChatResponseUpdate>?)JsonSerializer.Deserialize(existingJson, _jsonSerializerOptions.GetTypeInfo(typeof(IReadOnlyList<ChatResponseUpdate>)));
return (IReadOnlyList<ChatResponseUpdate>?)JsonSerializer.Deserialize(existingJson, JsonSerializerOptions.GetTypeInfo(typeof(IReadOnlyList<ChatResponseUpdate>)));
}

return null;
Expand All @@ -104,9 +101,9 @@ protected override async Task WriteCacheAsync(string key, ChatResponse value, Ca
{
_ = Throw.IfNull(key);
_ = Throw.IfNull(value);
_jsonSerializerOptions.MakeReadOnly();
JsonSerializerOptions.MakeReadOnly();

var newJson = JsonSerializer.SerializeToUtf8Bytes(value, _jsonSerializerOptions.GetTypeInfo(typeof(ChatResponse)));
var newJson = JsonSerializer.SerializeToUtf8Bytes(value, JsonSerializerOptions.GetTypeInfo(typeof(ChatResponse)));
await _storage.SetAsync(key, newJson, cancellationToken);
}

Expand All @@ -115,9 +112,9 @@ protected override async Task WriteCacheStreamingAsync(string key, IReadOnlyList
{
_ = Throw.IfNull(key);
_ = Throw.IfNull(value);
_jsonSerializerOptions.MakeReadOnly();
JsonSerializerOptions.MakeReadOnly();

var newJson = JsonSerializer.SerializeToUtf8Bytes(value, _jsonSerializerOptions.GetTypeInfo(typeof(IReadOnlyList<ChatResponseUpdate>)));
var newJson = JsonSerializer.SerializeToUtf8Bytes(value, JsonSerializerOptions.GetTypeInfo(typeof(IReadOnlyList<ChatResponseUpdate>)));
await _storage.SetAsync(key, newJson, cancellationToken);
}

Expand Down Expand Up @@ -151,7 +148,7 @@ protected override string GetCacheKey(IEnumerable<ChatMessage> messages, ChatOpt
additionalValues.CopyTo(arr.AsSpan(FixedValuesCount));
clientValues.CopyTo(arr, FixedValuesCount + additionalValues.Length);

return AIJsonUtilities.HashDataToString(arr.AsSpan(0, length), _jsonSerializerOptions);
return AIJsonUtilities.HashDataToString(arr.AsSpan(0, length), JsonSerializerOptions);
}
finally
{
Expand Down
Loading
Loading