// Copyright (c) Microsoft. All rights reserved. using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Json.Serialization; namespace Microsoft.Agents.AI; /// Provides a collection of utility methods for working with JSON data in the context of agents. internal static partial class AgentJsonUtilities { /// /// Gets the singleton used as the default in JSON serialization operations. /// /// /// /// For Native AOT or applications disabling , this instance /// includes source generated contracts for all common exchange types contained in this library. /// /// /// It additionally turns on the following settings: /// /// Enables defaults. /// Enables as the default ignore condition for properties. /// Enables as the default number handling for number types. /// /// /// public static JsonSerializerOptions DefaultOptions { get; } = CreateDefaultOptions(); /// /// Creates default options to use for agents-related serialization. /// /// The configured options. [UnconditionalSuppressMessage("ReflectionAnalysis", "IL3050:RequiresDynamicCode", Justification = "Converter is guarded by IsReflectionEnabledByDefault check.")] [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access", Justification = "Converter is guarded by IsReflectionEnabledByDefault check.")] private static JsonSerializerOptions CreateDefaultOptions() { // Copy the configuration from the source generated context. JsonSerializerOptions options = new(JsonContext.Default.Options) { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, // same as in AgentAbstractionsJsonUtilities and AIJsonUtilities }; // Chain in the resolvers from both AgentAbstractionsJsonUtilities and our source generated context. // We want AgentAbstractionsJsonUtilities first to ensure any M.E.AI types are handled via its resolver. options.TypeInfoResolverChain.Clear(); options.TypeInfoResolverChain.Add(AgentAbstractionsJsonUtilities.DefaultOptions.TypeInfoResolver!); options.TypeInfoResolverChain.Add(JsonContext.Default.Options.TypeInfoResolver!); if (JsonSerializer.IsReflectionEnabledByDefault) { options.Converters.Add(new JsonStringEnumConverter()); } options.MakeReadOnly(); return options; } // Keep in sync with CreateDefaultOptions above. [JsonSourceGenerationOptions(JsonSerializerDefaults.Web, UseStringEnumConverter = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, NumberHandling = JsonNumberHandling.AllowReadingFromString)] // Agent abstraction types [JsonSerializable(typeof(ChatClientAgentSession))] [JsonSerializable(typeof(TextSearchProvider.TextSearchProviderState))] [JsonSerializable(typeof(ChatHistoryMemoryProvider.State))] // TodoProvider types [JsonSerializable(typeof(TodoState))] [JsonSerializable(typeof(TodoItem))] [JsonSerializable(typeof(TodoItemInput))] [JsonSerializable(typeof(List), TypeInfoPropertyName = "IntList")] [JsonSerializable(typeof(List), TypeInfoPropertyName = "TodoItemList")] [JsonSerializable(typeof(List), TypeInfoPropertyName = "TodoItemInputList")] // AgentModeProvider types [JsonSerializable(typeof(AgentModeState))] // ToolApprovalAgent types [JsonSerializable(typeof(ToolApprovalState))] [JsonSerializable(typeof(ToolApprovalRule))] [JsonSerializable(typeof(List), TypeInfoPropertyName = "ToolApprovalRuleList")] // FileMemoryProvider types [JsonSerializable(typeof(FileMemoryState))] [JsonSerializable(typeof(FileSearchResult))] [JsonSerializable(typeof(List), TypeInfoPropertyName = "FileSearchResultList")] [JsonSerializable(typeof(FileSearchMatch))] [JsonSerializable(typeof(List), TypeInfoPropertyName = "FileSearchMatchList")] [JsonSerializable(typeof(FileListEntry))] [JsonSerializable(typeof(List), TypeInfoPropertyName = "FileListEntryList")] // SubAgentsProvider types [JsonSerializable(typeof(SubAgentState))] [JsonSerializable(typeof(SubAgentRuntimeState))] [JsonSerializable(typeof(SubTaskInfo))] [JsonSerializable(typeof(SubTaskStatus))] [JsonSerializable(typeof(List), TypeInfoPropertyName = "SubTaskInfoList")] [ExcludeFromCodeCoverage] internal sealed partial class JsonContext : JsonSerializerContext; }