diff --git a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/ChatClientStructuredOutputExtensions.cs b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/ChatClientStructuredOutputExtensions.cs
index 84effb1737b..a320600bee2 100644
--- a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/ChatClientStructuredOutputExtensions.cs
+++ b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/ChatClientStructuredOutputExtensions.cs
@@ -1,16 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System;
using System.Collections.Generic;
using System.ComponentModel;
-using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Schema;
-using System.Text.Json.Serialization;
-using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Shared.Diagnostics;
@@ -21,13 +17,8 @@ namespace Microsoft.Extensions.AI;
///
/// Provides extension methods on that simplify working with structured output.
///
-public static partial class ChatClientStructuredOutputExtensions
+public static class ChatClientStructuredOutputExtensions
{
- private const string UsesReflectionJsonSerializerMessage =
- "This method uses the reflection-based JsonSerializer which can break in trimmed or AOT applications.";
-
- private static JsonSerializerOptions? _defaultJsonSerializerOptions;
-
/// Sends chat messages to the model, requesting a response matching the type .
/// The .
/// The chat content to send.
@@ -44,8 +35,6 @@ public static partial class ChatClientStructuredOutputExtensions
/// by the client, including any messages for roundtrips to the model as part of the implementation of this request, will be included.
///
/// The type of structured output to request.
- [RequiresUnreferencedCode(UsesReflectionJsonSerializerMessage)]
- [RequiresDynamicCode(UsesReflectionJsonSerializerMessage)]
public static Task> CompleteAsync(
this IChatClient chatClient,
IList chatMessages,
@@ -53,7 +42,7 @@ public static Task> CompleteAsync(
bool? useNativeJsonSchema = null,
CancellationToken cancellationToken = default)
where T : class =>
- CompleteAsync(chatClient, chatMessages, DefaultJsonSerializerOptions, options, useNativeJsonSchema, cancellationToken);
+ CompleteAsync(chatClient, chatMessages, JsonDefaults.Options, options, useNativeJsonSchema, cancellationToken);
/// Sends a user chat text message to the model, requesting a response matching the type .
/// The .
@@ -67,10 +56,6 @@ public static Task> CompleteAsync(
/// The to monitor for cancellation requests. The default is .
/// The response messages generated by the client.
/// The type of structured output to request.
- [RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. "
- + "Use System.Text.Json source generation for native AOT applications.")]
- [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. "
- + "Use System.Text.Json source generation for native AOT applications.")]
public static Task> CompleteAsync(
this IChatClient chatClient,
string chatMessage,
@@ -154,7 +139,7 @@ public static async Task> CompleteAsync(
});
schemaNode.Insert(0, "$schema", "https://json-schema.org/draft/2020-12/schema");
schemaNode.Add("additionalProperties", false);
- var schema = JsonSerializer.Serialize(schemaNode, JsonNodeContext.Default.JsonNode);
+ var schema = JsonSerializer.Serialize(schemaNode, JsonDefaults.Options.GetTypeInfo(typeof(JsonNode)));
ChatMessage? promptAugmentation = null;
options = (options ?? new()).Clone();
@@ -201,28 +186,4 @@ public static async Task> CompleteAsync(
}
}
}
-
- private static JsonSerializerOptions DefaultJsonSerializerOptions
- {
- [RequiresUnreferencedCode(UsesReflectionJsonSerializerMessage)]
- [RequiresDynamicCode(UsesReflectionJsonSerializerMessage)]
- get => _defaultJsonSerializerOptions ?? GetOrCreateDefaultJsonSerializerOptions();
- }
-
- [RequiresUnreferencedCode(UsesReflectionJsonSerializerMessage)]
- [RequiresDynamicCode(UsesReflectionJsonSerializerMessage)]
- private static JsonSerializerOptions GetOrCreateDefaultJsonSerializerOptions()
- {
- var options = new JsonSerializerOptions(JsonSerializerDefaults.General)
- {
- Converters = { new JsonStringEnumConverter() },
- TypeInfoResolver = new DefaultJsonTypeInfoResolver(),
- WriteIndented = true,
- };
- return Interlocked.CompareExchange(ref _defaultJsonSerializerOptions, options, null) ?? options;
- }
-
- [JsonSerializable(typeof(JsonNode))]
- [JsonSourceGenerationOptions(WriteIndented = true)]
- private sealed partial class JsonNodeContext : JsonSerializerContext;
}
diff --git a/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs b/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs
index 84ce1fa15a0..70928e63e82 100644
--- a/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs
+++ b/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs
@@ -23,17 +23,12 @@ namespace Microsoft.Extensions.AI;
/// Provides factory methods for creating commonly-used implementations of .
public static class AIFunctionFactory
{
- internal const string UsesReflectionJsonSerializerMessage =
- "This method uses the reflection-based JsonSerializer which can break in trimmed or AOT applications.";
-
/// Lazily-initialized default options instance.
private static AIFunctionFactoryCreateOptions? _defaultOptions;
/// Creates an instance for a method, specified via a delegate.
/// The method to be represented via the created .
/// The created for invoking .
- [RequiresUnreferencedCode(UsesReflectionJsonSerializerMessage)]
- [RequiresDynamicCode(UsesReflectionJsonSerializerMessage)]
public static AIFunction Create(Delegate method) => Create(method, _defaultOptions ??= new());
/// Creates an instance for a method, specified via a delegate.
@@ -52,8 +47,6 @@ public static AIFunction Create(Delegate method, AIFunctionFactoryCreateOptions
/// The name to use for the .
/// The description to use for the .
/// The created for invoking .
- [RequiresUnreferencedCode("Reflection is used to access types from the supplied Delegate.")]
- [RequiresDynamicCode("Reflection is used to access types from the supplied Delegate.")]
public static AIFunction Create(Delegate method, string? name, string? description = null)
=> Create(method, (_defaultOptions ??= new()).SerializerOptions, name, description);
@@ -80,8 +73,6 @@ public static AIFunction Create(Delegate method, JsonSerializerOptions options,
/// This should be if and only if is a static method.
///
/// The created for invoking .
- [RequiresUnreferencedCode("Reflection is used to access types from the supplied MethodInfo.")]
- [RequiresDynamicCode("Reflection is used to access types from the supplied MethodInfo.")]
public static AIFunction Create(MethodInfo method, object? target = null)
=> Create(method, target, _defaultOptions ??= new());
@@ -107,8 +98,8 @@ private sealed class ReflectionAIFunction : AIFunction
{
private readonly MethodInfo _method;
private readonly object? _target;
- private readonly Func, AIFunctionContext?, object?>[] _parameterMarshalers;
- private readonly Func