Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
.Net: Support polymorphic serialization of ChatMessageContent class a…
…nd its derivatives (#8901) ### Motivation, Context and Description Today, when serializing chat history, the `ChatMessageContent` type or its derivatives, like `OpenAIChatMessageContent`, are serialized as the `ChatMessageContent` type because the type is used as the chat history element type and the JSON serializer uses this type's public contract for serialization. However, when attempting serialization of instances of either the `ChatMessageContent` or `OpenAIChatMessageContent` type that are declared as `KernelContent` or `object` type, the serialization fails with the `System.NotSupportedException: Runtime type '{OpenAI}ChatMessageContent' is not supported by polymorphic type 'Microsoft.SemanticKernel.KernelContent'` exception. The reason for this exception is that neither of these types is registered for polymorphic serialization. This PR registers `ChatMessageContent` type for polymorphic serialization to allow serialization of the type instances declared as of `KernelContent` or `object` types: ```csharp KernelContent content = new ChatMessageContent(...); // Now it's possible to serialize the content variable of KernelContent type that holds reference to an instance of the ChatMessageContent type as ChatMessageContent type. var json = JsonSerializer.Serialize(content); ``` Additionally, it enables serialization of unknow in advance and external derivatives of `ChatMessageContent` type like `OpenAIChatMessageContent`. These types are serialized using contract of nearest ancestor which is `ChatMessageContent` by default. To change this behavior and register the unknown type for polymorphic serialization use the contract model - [Configure polymorphism with the contract model](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism?pivots=dotnet-8-0#configure-polymorphism-with-the-contract-model) ```csharp KernelContent content = new UnknownChatMessageContent(...); // The content variable will be serialized using the ChatMessageContent type contract. var json = JsonSerializer.Serialize(content); private class UnknownChatMessageContent : ChatMessageContent{} ``` Closes: #7478 ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄
- Loading branch information