diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Defaults.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Defaults.cs index 777d723b790..380b109471e 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Defaults.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/Defaults.cs @@ -30,4 +30,10 @@ public static class Defaults /// in the 's cache before they are considered expired and evicted. /// public static TimeSpan DefaultTimeToLiveForCacheEntries { get; } = TimeSpan.FromDays(14); + + /// + /// Defines the version number for the reporting format. If and when the serialized format undergoes + /// breaking changes, this number will be incremented. + /// + internal const int ReportingFormatVersion = 1; } diff --git a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ScenarioRunResult.cs b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ScenarioRunResult.cs index e1a4102e42c..e4b9401d926 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ScenarioRunResult.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/CSharp/ScenarioRunResult.cs @@ -37,6 +37,7 @@ namespace Microsoft.Extensions.AI.Evaluation.Reporting; /// The for the corresponding to the /// being constructed. /// +/// The version of the format used to persist the current . [method: JsonConstructor] public sealed class ScenarioRunResult( string scenarioName, @@ -45,7 +46,8 @@ public sealed class ScenarioRunResult( DateTime creationTime, IList messages, ChatResponse modelResponse, - EvaluationResult evaluationResult) + EvaluationResult evaluationResult, + int? formatVersion = null) { /// /// Initializes a new instance of the class. @@ -81,6 +83,11 @@ public ScenarioRunResult( { } + /// + /// Gets the version of the format used to persist the current . + /// + public int? FormatVersion { get; } = formatVersion ?? Defaults.ReportingFormatVersion; + /// /// Gets or sets the . /// diff --git a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/DistributedCachingChatClient.cs b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/DistributedCachingChatClient.cs index 67bd64cfa54..c59c78c9cd9 100644 --- a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/DistributedCachingChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/DistributedCachingChatClient.cs @@ -107,6 +107,11 @@ protected override async Task WriteCacheStreamingAsync(string key, IReadOnlyList /// The generated cache key is not guaranteed to be stable across releases of the library. /// /// - protected override string GetCacheKey(params ReadOnlySpan values) => - AIJsonUtilities.HashDataToString(values, _jsonSerializerOptions); + protected override string GetCacheKey(params ReadOnlySpan values) + { + // Bump the cache version to invalidate existing caches if the serialization format changes in a breaking way. + const int CacheVersion = 1; + + return AIJsonUtilities.HashDataToString([CacheVersion, .. values], _jsonSerializerOptions); + } } diff --git a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Tests/ScenarioRunResultTests.cs b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Tests/ScenarioRunResultTests.cs index 9418a5db359..b6f173abd5a 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Tests/ScenarioRunResultTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting.Tests/ScenarioRunResultTests.cs @@ -38,6 +38,7 @@ public void SerializeScenarioRunResult() messages: [new ChatMessage(ChatRole.User, "prompt")], modelResponse: new ChatResponse(new ChatMessage(ChatRole.Assistant, "response")), evaluationResult: new EvaluationResult(booleanMetric, numericMetric, stringMetric, metricWithNoValue)); + Assert.Equal(Defaults.ReportingFormatVersion, entry.FormatVersion); string json = JsonSerializer.Serialize(entry, SerializerContext.Default.ScenarioRunResult); ScenarioRunResult? deserialized = JsonSerializer.Deserialize(json, SerializerContext.Default.ScenarioRunResult); @@ -49,6 +50,7 @@ public void SerializeScenarioRunResult() Assert.Equal(entry.CreationTime, deserialized.CreationTime); Assert.True(entry.Messages.SequenceEqual(deserialized.Messages, ChatMessageComparer.Instance)); Assert.Equal(entry.ModelResponse, deserialized.ModelResponse, ChatResponseComparer.Instance); + Assert.Equal(entry.FormatVersion, deserialized.FormatVersion); ValidateEquivalence(entry.EvaluationResult, deserialized.EvaluationResult); }