Skip to content

Commit f273ca7

Browse files
authored
Fix InMemoryChatMessageStore serialization bug. (microsoft#2185)
1 parent 7e5de8f commit f273ca7

3 files changed

Lines changed: 35 additions & 2 deletions

File tree

dotnet/src/Microsoft.Agents.AI.Abstractions/InMemoryChatMessageStore.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ public InMemoryChatMessageStore(IChatReducer? chatReducer, JsonElement serialize
9797

9898
if (serializedStoreState.ValueKind is JsonValueKind.Object)
9999
{
100+
var jso = jsonSerializerOptions ?? AgentAbstractionsJsonUtilities.DefaultOptions;
100101
var state = serializedStoreState.Deserialize(
101-
AgentAbstractionsJsonUtilities.DefaultOptions.GetTypeInfo(typeof(StoreState))) as StoreState;
102+
jso.GetTypeInfo(typeof(StoreState))) as StoreState;
102103
if (state?.Messages is { } messages)
103104
{
104105
this._messages = messages;
@@ -164,7 +165,8 @@ public override JsonElement Serialize(JsonSerializerOptions? jsonSerializerOptio
164165
Messages = this._messages,
165166
};
166167

167-
return JsonSerializer.SerializeToElement(state, AgentAbstractionsJsonUtilities.DefaultOptions.GetTypeInfo(typeof(StoreState)));
168+
var jso = jsonSerializerOptions ?? AgentAbstractionsJsonUtilities.DefaultOptions;
169+
return JsonSerializer.SerializeToElement(state, jso.GetTypeInfo(typeof(StoreState)));
168170
}
169171

170172
/// <inheritdoc />

dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/InMemoryChatMessageStoreTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
using System;
44
using System.Collections.Generic;
55
using System.Linq;
6+
using System.Text.Encodings.Web;
67
using System.Text.Json;
8+
using System.Text.Json.Serialization.Metadata;
79
using System.Threading;
810
using System.Threading.Tasks;
911
using Microsoft.Extensions.AI;
@@ -114,6 +116,29 @@ public async Task SerializeAndDeserializeConstructorRoundtripsAsync()
114116
Assert.Equal("B", newStore[1].Text);
115117
}
116118

119+
[Fact]
120+
public async Task SerializeAndDeserializeConstructorRoundtripsWithCustomAIContentAsync()
121+
{
122+
JsonSerializerOptions options = new(TestJsonSerializerContext.Default.Options)
123+
{
124+
TypeInfoResolver = JsonTypeInfoResolver.Combine(AgentAbstractionsJsonUtilities.DefaultOptions.TypeInfoResolver, TestJsonSerializerContext.Default),
125+
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
126+
};
127+
options.AddAIContentType<TestAIContent>(typeDiscriminatorId: "testContent");
128+
129+
var store = new InMemoryChatMessageStore
130+
{
131+
new ChatMessage(ChatRole.User, [new TestAIContent("foo data")]),
132+
};
133+
134+
var jsonElement = store.Serialize(options);
135+
var newStore = new InMemoryChatMessageStore(jsonElement, options);
136+
137+
Assert.Single(newStore);
138+
var actualTestAIContent = Assert.IsType<TestAIContent>(newStore[0].Contents[0]);
139+
Assert.Equal("foo data", actualTestAIContent.TestData);
140+
}
141+
117142
[Fact]
118143
public async Task SerializeAndDeserializeWorksWithExperimentalContentTypesAsync()
119144
{
@@ -558,4 +583,9 @@ public async Task GetMessagesAsync_WithReducer_ButWrongTrigger_DoesNotInvokeRedu
558583
Assert.Equal("Hello", result[0].Text);
559584
reducerMock.Verify(r => r.ReduceAsync(It.IsAny<IEnumerable<ChatMessage>>(), It.IsAny<CancellationToken>()), Times.Never);
560585
}
586+
587+
public class TestAIContent(string testData) : AIContent
588+
{
589+
public string TestData => testData;
590+
}
561591
}

dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/TestJsonSerializerContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ namespace Microsoft.Agents.AI.Abstractions.UnitTests;
2222
[JsonSerializable(typeof(InMemoryAgentThread.InMemoryAgentThreadState))]
2323
[JsonSerializable(typeof(ServiceIdAgentThread.ServiceIdAgentThreadState))]
2424
[JsonSerializable(typeof(ServiceIdAgentThreadTests.EmptyObject))]
25+
[JsonSerializable(typeof(InMemoryChatMessageStoreTests.TestAIContent))]
2526
internal sealed partial class TestJsonSerializerContext : JsonSerializerContext;

0 commit comments

Comments
 (0)