Skip to content

Commit ab01355

Browse files
authored
Add types from AIJsonUtilities.JsonContext to reporting JsonContext (#6078)
* Add types from AIJsonUtilities.JsonContext to reporting JsonContext * Add a few more tests * Chain M.E.AI.Eval serialization types through AIJsonUtilities * Fix reversed Compact/Default * Rename some of the types.
1 parent 29c6180 commit ab01355

File tree

15 files changed

+252
-98
lines changed

15 files changed

+252
-98
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Text.Encodings.Web;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
using System.Text.Json.Serialization.Metadata;
8+
using static Microsoft.Extensions.AI.Evaluation.Reporting.Storage.AzureStorageResponseCache;
9+
10+
namespace Microsoft.Extensions.AI.Evaluation.Reporting.JsonSerialization;
11+
12+
internal static partial class AzureStorageJsonUtilities
13+
{
14+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "Default matches the generated source naming convention.")]
15+
internal static class Default
16+
{
17+
private static JsonSerializerOptions? _options;
18+
internal static JsonSerializerOptions Options => _options ??= CreateJsonSerializerOptions(writeIndented: true);
19+
internal static JsonTypeInfo<CacheEntry> CacheEntryTypeInfo => Options.GetTypeInfo<CacheEntry>();
20+
internal static JsonTypeInfo<ScenarioRunResult> ScenarioRunResultTypeInfo => Options.GetTypeInfo<ScenarioRunResult>();
21+
}
22+
23+
internal static class Compact
24+
{
25+
private static JsonSerializerOptions? _options;
26+
internal static JsonSerializerOptions Options => _options ??= CreateJsonSerializerOptions(writeIndented: false);
27+
internal static JsonTypeInfo<ScenarioRunResult> ScenarioRunResultTypeInfo => Options.GetTypeInfo<ScenarioRunResult>();
28+
}
29+
30+
private static JsonTypeInfo<T> GetTypeInfo<T>(this JsonSerializerOptions options) => (JsonTypeInfo<T>)options.GetTypeInfo(typeof(T));
31+
32+
private static JsonSerializerOptions CreateJsonSerializerOptions(bool writeIndented)
33+
{
34+
var options = new JsonSerializerOptions(JsonContext.Default.Options)
35+
{
36+
WriteIndented = writeIndented,
37+
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
38+
};
39+
options.TypeInfoResolverChain.Add(AIJsonUtilities.DefaultOptions.TypeInfoResolver!);
40+
options.MakeReadOnly();
41+
return options;
42+
}
43+
44+
[JsonSerializable(typeof(ScenarioRunResult))]
45+
[JsonSerializable(typeof(CacheEntry))]
46+
[JsonSourceGenerationOptions(
47+
Converters = [
48+
typeof(AzureStorageCamelCaseEnumConverter<EvaluationDiagnosticSeverity>),
49+
typeof(AzureStorageCamelCaseEnumConverter<EvaluationRating>),
50+
typeof(AzureStorageTimeSpanConverter)
51+
],
52+
WriteIndented = true,
53+
IgnoreReadOnlyProperties = false,
54+
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
55+
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
56+
private sealed partial class JsonContext : JsonSerializerContext;
57+
58+
}

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Azure/JsonSerialization/AzureStorageSerializerContext.cs

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Azure/Storage/AzureStorageResponseCache.CacheEntry.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static CacheEntry Read(
4545
CacheEntry cacheEntry =
4646
JsonSerializer.Deserialize(
4747
content.Value.Content.ToMemory().Span,
48-
AzureStorageSerializerContext.Default.CacheEntry)
48+
AzureStorageJsonUtilities.Default.CacheEntryTypeInfo)
4949
?? throw new JsonException(
5050
string.Format(CultureInfo.CurrentCulture, DeserializationFailedMessage, fileClient.Name));
5151

@@ -62,7 +62,7 @@ public static async Task<CacheEntry> ReadAsync(
6262
CacheEntry cacheEntry =
6363
await JsonSerializer.DeserializeAsync(
6464
content.Value.Content.ToStream(),
65-
AzureStorageSerializerContext.Default.CacheEntry,
65+
AzureStorageJsonUtilities.Default.CacheEntryTypeInfo,
6666
cancellationToken).ConfigureAwait(false)
6767
?? throw new JsonException(
6868
string.Format(CultureInfo.CurrentCulture, DeserializationFailedMessage, fileClient.Name));
@@ -76,7 +76,7 @@ public void Write(
7676
{
7777
MemoryStream stream = new();
7878

79-
JsonSerializer.Serialize(stream, this, AzureStorageSerializerContext.Default.CacheEntry);
79+
JsonSerializer.Serialize(stream, this, AzureStorageJsonUtilities.Default.CacheEntryTypeInfo);
8080

8181
_ = stream.Seek(0, SeekOrigin.Begin);
8282
_ = fileClient.Upload(stream, overwrite: true, cancellationToken);
@@ -91,7 +91,7 @@ public async Task WriteAsync(
9191
await JsonSerializer.SerializeAsync(
9292
stream,
9393
this,
94-
AzureStorageSerializerContext.Default.CacheEntry,
94+
AzureStorageJsonUtilities.Default.CacheEntryTypeInfo,
9595
cancellationToken).ConfigureAwait(false);
9696

9797
_ = stream.Seek(0, SeekOrigin.Begin);

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Azure/Storage/AzureStorageResultStore.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public async IAsyncEnumerable<ScenarioRunResult> ReadResultsAsync(
119119

120120
ScenarioRunResult? result = await JsonSerializer.DeserializeAsync(
121121
content.Value.Content.ToStream(),
122-
AzureStorageSerializerContext.Default.ScenarioRunResult,
122+
AzureStorageJsonUtilities.Default.ScenarioRunResultTypeInfo,
123123
cancellationToken).ConfigureAwait(false)
124124
?? throw new JsonException(
125125
string.Format(CultureInfo.CurrentCulture, DeserializationFailedMessage, fileClient.Name));
@@ -171,7 +171,7 @@ public async ValueTask WriteResultsAsync(
171171
await JsonSerializer.SerializeAsync(
172172
stream,
173173
result,
174-
AzureStorageSerializerContext.Default.ScenarioRunResult,
174+
AzureStorageJsonUtilities.Default.ScenarioRunResultTypeInfo,
175175
cancellationToken).ConfigureAwait(false);
176176

177177
_ = stream.Seek(0, SeekOrigin.Begin);

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Formats/Html/HtmlReportWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public async ValueTask WriteReportAsync(
5656
await JsonSerializer.SerializeAsync(
5757
stream,
5858
dataset,
59-
SerializerContext.Compact.Dataset,
59+
JsonUtilities.Compact.DatasetTypeInfo,
6060
cancellationToken).ConfigureAwait(false);
6161

6262
#if NET

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Formats/Json/JsonReportWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public async ValueTask WriteReportAsync(
4545
await JsonSerializer.SerializeAsync(
4646
stream,
4747
dataset,
48-
SerializerContext.Default.Dataset,
48+
JsonUtilities.Default.DatasetTypeInfo,
4949
cancellationToken).ConfigureAwait(false);
5050
}
5151
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Text.Encodings.Web;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
using System.Text.Json.Serialization.Metadata;
8+
using Microsoft.Extensions.AI.Evaluation.Reporting.Formats;
9+
using static Microsoft.Extensions.AI.Evaluation.Reporting.Storage.DiskBasedResponseCache;
10+
11+
namespace Microsoft.Extensions.AI.Evaluation.Reporting.JsonSerialization;
12+
13+
internal static partial class JsonUtilities
14+
{
15+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "Default matches the generated source naming convention.")]
16+
internal static class Default
17+
{
18+
private static JsonSerializerOptions? _options;
19+
internal static JsonSerializerOptions Options => _options ??= CreateJsonSerializerOptions(writeIndented: true);
20+
internal static JsonTypeInfo<Dataset> DatasetTypeInfo => Options.GetTypeInfo<Dataset>();
21+
internal static JsonTypeInfo<CacheEntry> CacheEntryTypeInfo => Options.GetTypeInfo<CacheEntry>();
22+
internal static JsonTypeInfo<CacheOptions> CacheOptionsTypeInfo => Options.GetTypeInfo<CacheOptions>();
23+
internal static JsonTypeInfo<ScenarioRunResult> ScenarioRunResultTypeInfo => Options.GetTypeInfo<ScenarioRunResult>();
24+
}
25+
26+
internal static class Compact
27+
{
28+
private static JsonSerializerOptions? _options;
29+
internal static JsonSerializerOptions Options => _options ??= CreateJsonSerializerOptions(writeIndented: false);
30+
internal static JsonTypeInfo<Dataset> DatasetTypeInfo => Options.GetTypeInfo<Dataset>();
31+
internal static JsonTypeInfo<CacheEntry> CacheEntryTypeInfo => Options.GetTypeInfo<CacheEntry>();
32+
internal static JsonTypeInfo<CacheOptions> CacheOptionsTypeInfo => Options.GetTypeInfo<CacheOptions>();
33+
internal static JsonTypeInfo<ScenarioRunResult> ScenarioRunResultTypeInfo => Options.GetTypeInfo<ScenarioRunResult>();
34+
}
35+
36+
private static JsonTypeInfo<T> GetTypeInfo<T>(this JsonSerializerOptions options) => (JsonTypeInfo<T>)options.GetTypeInfo(typeof(T));
37+
38+
private static JsonSerializerOptions CreateJsonSerializerOptions(bool writeIndented)
39+
{
40+
var options = new JsonSerializerOptions(JsonContext.Default.Options)
41+
{
42+
WriteIndented = writeIndented,
43+
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
44+
};
45+
options.TypeInfoResolverChain.Add(AIJsonUtilities.DefaultOptions.TypeInfoResolver!);
46+
options.MakeReadOnly();
47+
return options;
48+
}
49+
50+
[JsonSerializable(typeof(EvaluationResult))]
51+
[JsonSerializable(typeof(Dataset))]
52+
[JsonSerializable(typeof(CacheEntry))]
53+
[JsonSerializable(typeof(CacheOptions))]
54+
[JsonSourceGenerationOptions(
55+
Converters = [
56+
typeof(CamelCaseEnumConverter<EvaluationDiagnosticSeverity>),
57+
typeof(CamelCaseEnumConverter<EvaluationRating>),
58+
typeof(CamelCaseEnumConverter<CacheMode>),
59+
typeof(TimeSpanConverter)
60+
],
61+
WriteIndented = true,
62+
IgnoreReadOnlyProperties = false,
63+
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
64+
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
65+
private sealed partial class JsonContext : JsonSerializerContext;
66+
67+
}

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/JsonSerialization/SerializerContext.cs

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Storage/DiskBasedResponseCache.CacheEntry.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public static CacheEntry Read(string cacheEntryFilePath)
4040
CacheEntry cacheEntry =
4141
JsonSerializer.Deserialize(
4242
cacheEntryFile,
43-
SerializerContext.Default.CacheEntry) ??
43+
JsonUtilities.Default.CacheEntryTypeInfo) ??
4444
throw new JsonException(
4545
string.Format(CultureInfo.CurrentCulture, DeserializationFailedMessage, cacheEntryFilePath));
4646

@@ -56,7 +56,7 @@ public static async Task<CacheEntry> ReadAsync(
5656
CacheEntry cacheEntry =
5757
await JsonSerializer.DeserializeAsync(
5858
cacheEntryFile,
59-
SerializerContext.Default.CacheEntry,
59+
JsonUtilities.Default.CacheEntryTypeInfo,
6060
cancellationToken).ConfigureAwait(false) ??
6161
throw new JsonException(
6262
string.Format(CultureInfo.CurrentCulture, DeserializationFailedMessage, cacheEntryFilePath));
@@ -67,7 +67,7 @@ await JsonSerializer.DeserializeAsync(
6767
public void Write(string cacheEntryFilePath)
6868
{
6969
using FileStream cacheEntryFile = File.Create(cacheEntryFilePath);
70-
JsonSerializer.Serialize(cacheEntryFile, this, SerializerContext.Default.CacheEntry);
70+
JsonSerializer.Serialize(cacheEntryFile, this, JsonUtilities.Default.CacheEntryTypeInfo);
7171
}
7272

7373
public async Task WriteAsync(
@@ -78,7 +78,7 @@ public async Task WriteAsync(
7878
await JsonSerializer.SerializeAsync(
7979
cacheEntryFile,
8080
this,
81-
SerializerContext.Default.CacheEntry,
81+
JsonUtilities.Default.CacheEntryTypeInfo,
8282
cancellationToken).ConfigureAwait(false);
8383
}
8484
}

src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Storage/DiskBasedResponseCache.CacheOptions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static CacheOptions Read(string cacheOptionsFilePath)
4545
CacheOptions cacheOptions =
4646
JsonSerializer.Deserialize(
4747
cacheOptionsFile,
48-
SerializerContext.Default.CacheOptions) ??
48+
JsonUtilities.Default.CacheOptionsTypeInfo) ??
4949
throw new JsonException(
5050
string.Format(CultureInfo.CurrentCulture, DeserializationFailedMessage, cacheOptionsFilePath));
5151

@@ -61,7 +61,7 @@ public static async Task<CacheOptions> ReadAsync(
6161
CacheOptions cacheOptions =
6262
await JsonSerializer.DeserializeAsync<CacheOptions>(
6363
cacheOptionsFile,
64-
SerializerContext.Default.CacheOptions,
64+
JsonUtilities.Default.CacheOptionsTypeInfo,
6565
cancellationToken).ConfigureAwait(false) ??
6666
throw new JsonException(
6767
string.Format(CultureInfo.CurrentCulture, DeserializationFailedMessage, cacheOptionsFilePath));
@@ -72,7 +72,7 @@ await JsonSerializer.DeserializeAsync<CacheOptions>(
7272
public void Write(string cacheOptionsFilePath)
7373
{
7474
using FileStream cacheOptionsFile = File.Create(cacheOptionsFilePath);
75-
JsonSerializer.Serialize(cacheOptionsFile, this, SerializerContext.Default.CacheOptions);
75+
JsonSerializer.Serialize(cacheOptionsFile, this, JsonUtilities.Default.CacheOptionsTypeInfo);
7676
}
7777

7878
public async Task WriteAsync(
@@ -83,7 +83,7 @@ public async Task WriteAsync(
8383
await JsonSerializer.SerializeAsync(
8484
cacheOptionsFile,
8585
this,
86-
SerializerContext.Default.CacheOptions,
86+
JsonUtilities.Default.CacheOptionsTypeInfo,
8787
cancellationToken).ConfigureAwait(false);
8888
}
8989
}

0 commit comments

Comments
 (0)