diff --git a/dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunResponse.cs b/dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunResponse.cs
index 001cfd9469..7828b5c62d 100644
--- a/dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunResponse.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunResponse.cs
@@ -291,6 +291,15 @@ public AgentRunResponseUpdate[] ToAgentRunResponseUpdates()
return updates;
}
+ ///
+ /// Deserializes the response text into the given type.
+ ///
+ /// The output type to deserialize into.
+ /// The result as the requested type.
+ /// The result is not parsable into the requested type.
+ public T Deserialize() =>
+ this.Deserialize(AgentAbstractionsJsonUtilities.DefaultOptions);
+
///
/// Deserializes the response text into the given type using the specified serializer options.
///
@@ -311,6 +320,15 @@ public T Deserialize(JsonSerializerOptions serializerOptions)
};
}
+ ///
+ /// Tries to deserialize response text into the given type.
+ ///
+ /// The output type to deserialize into.
+ /// The parsed structured output.
+ /// if parsing was successful; otherwise, .
+ public bool TryDeserialize([NotNullWhen(true)] out T? structuredOutput) =>
+ this.TryDeserialize(AgentAbstractionsJsonUtilities.DefaultOptions, out structuredOutput);
+
///
/// Tries to deserialize response text into the given type using the specified serializer options.
///
diff --git a/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgentOptions.cs b/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgentOptions.cs
index 4a72d66f2d..dd1ff3b228 100644
--- a/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgentOptions.cs
+++ b/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgentOptions.cs
@@ -80,7 +80,7 @@ public ChatClientAgentOptions Clone()
///
/// Context object passed to the to create a new instance of .
///
- public class AIContextProviderFactoryContext
+ public sealed class AIContextProviderFactoryContext
{
///
/// Gets or sets the serialized state of the , if any.
@@ -97,7 +97,7 @@ public class AIContextProviderFactoryContext
///
/// Context object passed to the to create a new instance of .
///
- public class ChatMessageStoreFactoryContext
+ public sealed class ChatMessageStoreFactoryContext
{
///
/// Gets or sets the serialized state of the chat message store, if any.
diff --git a/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgentRunResponse{T}.cs b/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgentRunResponse{T}.cs
index 13b536a457..352be764eb 100644
--- a/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgentRunResponse{T}.cs
+++ b/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgentRunResponse{T}.cs
@@ -40,7 +40,6 @@ public ChatClientAgentRunResponse(ChatResponse response) : base(response)
///
///
/// If the response did not contain JSON, or if deserialization fails, this property will throw.
- /// To avoid exceptions, use instead.
///
public override T Result => this._response.Result;
}
diff --git a/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentRunResponseTests.cs b/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentRunResponseTests.cs
index 981f1e3933..a81446d062 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentRunResponseTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentRunResponseTests.cs
@@ -214,6 +214,12 @@ public void ToAgentRunResponseUpdatesProducesUpdates()
Assert.Equal(100, usageContent.Details.TotalTokenCount);
}
+#if NETFRAMEWORK
+ ///
+ /// Since Json Serialization using reflection is disabled in .net core builds, and we are using a custom type here that wouldn't
+ /// be registered with the default source generated serializer, this test will only pass in .net framework builds where reflection-based
+ /// serialization is available.
+ ///
[Fact]
public void ParseAsStructuredOutputSuccess()
{
@@ -221,6 +227,24 @@ public void ParseAsStructuredOutputSuccess()
var expectedResult = new Animal { Id = 1, FullName = "Tigger", Species = Species.Tiger };
var response = new AgentRunResponse(new ChatMessage(ChatRole.Assistant, JsonSerializer.Serialize(expectedResult, TestJsonSerializerContext.Default.Animal)));
+ // Act.
+ var animal = response.Deserialize();
+
+ // Assert.
+ Assert.NotNull(animal);
+ Assert.Equal(expectedResult.Id, animal.Id);
+ Assert.Equal(expectedResult.FullName, animal.FullName);
+ Assert.Equal(expectedResult.Species, animal.Species);
+ }
+#endif
+
+ [Fact]
+ public void ParseAsStructuredOutputWithJSOSuccess()
+ {
+ // Arrange.
+ var expectedResult = new Animal { Id = 1, FullName = "Tigger", Species = Species.Tiger };
+ var response = new AgentRunResponse(new ChatMessage(ChatRole.Assistant, JsonSerializer.Serialize(expectedResult, TestJsonSerializerContext.Default.Animal)));
+
// Act.
var animal = response.Deserialize(TestJsonSerializerContext.Default.Options);
@@ -262,6 +286,12 @@ public void ParseAsStructuredOutputFailsWithIncorrectTypedJson()
Assert.Throws(() => response.Deserialize(TestJsonSerializerContext.Default.Options));
}
+#if NETFRAMEWORK
+ ///
+ /// Since Json Serialization using reflection is disabled in .net core builds, and we are using a custom type here that wouldn't
+ /// be registered with the default source generated serializer, this test will only pass in .net framework builds where reflection-based
+ /// serialization is available.
+ ///
[Fact]
public void TryParseAsStructuredOutputSuccess()
{
@@ -269,6 +299,24 @@ public void TryParseAsStructuredOutputSuccess()
var expectedResult = new Animal { Id = 1, FullName = "Tigger", Species = Species.Tiger };
var response = new AgentRunResponse(new ChatMessage(ChatRole.Assistant, JsonSerializer.Serialize(expectedResult, TestJsonSerializerContext.Default.Animal)));
+ // Act.
+ response.TryDeserialize(out Animal? animal);
+
+ // Assert.
+ Assert.NotNull(animal);
+ Assert.Equal(expectedResult.Id, animal.Id);
+ Assert.Equal(expectedResult.FullName, animal.FullName);
+ Assert.Equal(expectedResult.Species, animal.Species);
+ }
+#endif
+
+ [Fact]
+ public void TryParseAsStructuredOutputWithJSOSuccess()
+ {
+ // Arrange.
+ var expectedResult = new Animal { Id = 1, FullName = "Tigger", Species = Species.Tiger };
+ var response = new AgentRunResponse(new ChatMessage(ChatRole.Assistant, JsonSerializer.Serialize(expectedResult, TestJsonSerializerContext.Default.Animal)));
+
// Act.
response.TryDeserialize(TestJsonSerializerContext.Default.Options, out Animal? animal);