diff --git a/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs b/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs
index 8f473fe3f7a..d0d3385749e 100644
--- a/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs
+++ b/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs
@@ -22,7 +22,7 @@ namespace Microsoft.Extensions.AI;
public static partial class AIFunctionFactory
{
/// Holds the default options instance used when creating function.
- private static readonly AIFunctionFactoryCreateOptions _defaultOptions = new();
+ private static readonly AIFunctionFactoryOptions _defaultOptions = new();
/// Creates an instance for a method, specified via a delegate.
/// The method to be represented via the created .
@@ -31,14 +31,14 @@ public static partial class AIFunctionFactory
///
///
/// Return values are serialized to using 's
- /// . Arguments that are not already of the expected type are
+ /// . Arguments that are not already of the expected type are
/// marshaled to the expected type via JSON and using 's
- /// . If the argument is a ,
+ /// . If the argument is a ,
/// , or , it is deserialized directly. If the argument is anything else unknown,
/// it is round-tripped through JSON, serializing the object as JSON and then deserializing it to the expected type.
///
///
- public static AIFunction Create(Delegate method, AIFunctionFactoryCreateOptions? options)
+ public static AIFunction Create(Delegate method, AIFunctionFactoryOptions? options)
{
_ = Throw.IfNull(method);
@@ -64,7 +64,7 @@ public static AIFunction Create(Delegate method, string? name = null, string? de
{
_ = Throw.IfNull(method);
- AIFunctionFactoryCreateOptions createOptions = serializerOptions is null && name is null && description is null
+ AIFunctionFactoryOptions createOptions = serializerOptions is null && name is null && description is null
? _defaultOptions
: new()
{
@@ -90,14 +90,14 @@ public static AIFunction Create(Delegate method, string? name = null, string? de
///
///
/// Return values are serialized to using 's
- /// . Arguments that are not already of the expected type are
+ /// . Arguments that are not already of the expected type are
/// marshaled to the expected type via JSON and using 's
- /// . If the argument is a ,
+ /// . If the argument is a ,
/// , or , it is deserialized directly. If the argument is anything else unknown,
/// it is round-tripped through JSON, serializing the object as JSON and then deserializing it to the expected type.
///
///
- public static AIFunction Create(MethodInfo method, object? target, AIFunctionFactoryCreateOptions? options)
+ public static AIFunction Create(MethodInfo method, object? target, AIFunctionFactoryOptions? options)
{
_ = Throw.IfNull(method);
return new ReflectionAIFunction(method, target, options ?? _defaultOptions);
@@ -129,7 +129,7 @@ public static AIFunction Create(MethodInfo method, object? target, string? name
{
_ = Throw.IfNull(method);
- AIFunctionFactoryCreateOptions? createOptions = serializerOptions is null && name is null && description is null
+ AIFunctionFactoryOptions? createOptions = serializerOptions is null && name is null && description is null
? _defaultOptions
: new()
{
@@ -160,12 +160,13 @@ private sealed class ReflectionAIFunction : AIFunction
/// This should be if and only if is a static method.
///
/// Function creation options.
- public ReflectionAIFunction(MethodInfo method, object? target, AIFunctionFactoryCreateOptions options)
+ public ReflectionAIFunction(MethodInfo method, object? target, AIFunctionFactoryOptions options)
{
_ = Throw.IfNull(method);
_ = Throw.IfNull(options);
- options.SerializerOptions.MakeReadOnly();
+ JsonSerializerOptions serializerOptions = options.SerializerOptions ?? AIJsonUtilities.DefaultOptions;
+ serializerOptions.MakeReadOnly();
if (method.ContainsGenericParameters)
{
@@ -222,20 +223,20 @@ static bool IsAsyncMethod(MethodInfo method)
bool sawAIContextParameter = false;
for (int i = 0; i < parameters.Length; i++)
{
- _parameterMarshallers[i] = GetParameterMarshaller(options, parameters[i], ref sawAIContextParameter);
+ _parameterMarshallers[i] = GetParameterMarshaller(serializerOptions, parameters[i], ref sawAIContextParameter);
}
_needsAIFunctionContext = sawAIContextParameter;
// Get the return type and a marshaling func for the return value.
_returnMarshaller = GetReturnMarshaller(method, out Type returnType);
- _returnTypeInfo = returnType != typeof(void) ? options.SerializerOptions.GetTypeInfo(returnType) : null;
+ _returnTypeInfo = returnType != typeof(void) ? serializerOptions.GetTypeInfo(returnType) : null;
Name = functionName;
Description = options.Description ?? method.GetCustomAttribute(inherit: true)?.Description ?? string.Empty;
UnderlyingMethod = method;
AdditionalProperties = options.AdditionalProperties ?? EmptyReadOnlyDictionary.Instance;
- JsonSerializerOptions = options.SerializerOptions;
+ JsonSerializerOptions = serializerOptions;
JsonSchema = AIJsonUtilities.CreateFunctionJsonSchema(
method,
title: Name,
@@ -308,7 +309,7 @@ static bool IsAsyncMethod(MethodInfo method)
/// Gets a delegate for handling the marshaling of a parameter.
///
private static Func, AIFunctionContext?, object?> GetParameterMarshaller(
- AIFunctionFactoryCreateOptions options,
+ JsonSerializerOptions serializerOptions,
ParameterInfo parameter,
ref bool sawAIFunctionContext)
{
@@ -336,7 +337,7 @@ static bool IsAsyncMethod(MethodInfo method)
// Resolve the contract used to marshal the value from JSON -- can throw if not supported or not found.
Type parameterType = parameter.ParameterType;
- JsonTypeInfo typeInfo = options.SerializerOptions.GetTypeInfo(parameterType);
+ JsonTypeInfo typeInfo = serializerOptions.GetTypeInfo(parameterType);
// Create a marshaller that simply looks up the parameter by name in the arguments dictionary.
return (IReadOnlyDictionary arguments, AIFunctionContext? _) =>
@@ -359,7 +360,7 @@ static bool IsAsyncMethod(MethodInfo method)
#pragma warning disable CA1031 // Do not catch general exception types
try
{
- string json = JsonSerializer.Serialize(value, options.SerializerOptions.GetTypeInfo(value.GetType()));
+ string json = JsonSerializer.Serialize(value, serializerOptions.GetTypeInfo(value.GetType()));
return JsonSerializer.Deserialize(json, typeInfo);
}
catch
diff --git a/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactoryCreateOptions.cs b/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactoryOptions.cs
similarity index 75%
rename from src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactoryCreateOptions.cs
rename to src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactoryOptions.cs
index 27db24acadb..ac285241469 100644
--- a/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactoryCreateOptions.cs
+++ b/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactoryOptions.cs
@@ -6,40 +6,34 @@
using System.ComponentModel;
using System.Reflection;
using System.Text.Json;
-using Microsoft.Shared.Diagnostics;
namespace Microsoft.Extensions.AI;
///
/// Represents options that can be provided when creating an from a method.
///
-public sealed class AIFunctionFactoryCreateOptions
+public sealed class AIFunctionFactoryOptions
{
- private JsonSerializerOptions _options = AIJsonUtilities.DefaultOptions;
- private AIJsonSchemaCreateOptions _jsonSchemaCreateOptions = AIJsonSchemaCreateOptions.Default;
-
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
- public AIFunctionFactoryCreateOptions()
+ public AIFunctionFactoryOptions()
{
}
/// Gets or sets the used to marshal .NET values being passed to the underlying delegate.
- public JsonSerializerOptions SerializerOptions
- {
- get => _options;
- set => _options = Throw.IfNull(value);
- }
+ ///
+ /// If no value has been specified, the instance will be used.
+ ///
+ public JsonSerializerOptions? SerializerOptions { get; set; }
///
/// Gets or sets the governing the generation of JSON schemas for the function.
///
- public AIJsonSchemaCreateOptions JsonSchemaCreateOptions
- {
- get => _jsonSchemaCreateOptions;
- set => _jsonSchemaCreateOptions = Throw.IfNull(value);
- }
+ ///
+ /// If no value has been specified, the instance will be used.
+ ///
+ public AIJsonSchemaCreateOptions? JsonSchemaCreateOptions { get; set; }
/// Gets or sets the name to use for the function.
///
diff --git a/test/Libraries/Microsoft.Extensions.AI.Tests/Functions/AIFunctionFactoryTest.cs b/test/Libraries/Microsoft.Extensions.AI.Tests/Functions/AIFunctionFactoryTest.cs
index d8673e36c4d..daece288cca 100644
--- a/test/Libraries/Microsoft.Extensions.AI.Tests/Functions/AIFunctionFactoryTest.cs
+++ b/test/Libraries/Microsoft.Extensions.AI.Tests/Functions/AIFunctionFactoryTest.cs
@@ -160,7 +160,7 @@ public void AIFunctionFactoryCreateOptions_ValuesPropagateToAIFunction()
{
IReadOnlyDictionary metadata = new Dictionary { ["a"] = "b" };
- var options = new AIFunctionFactoryCreateOptions
+ var options = new AIFunctionFactoryOptions
{
Name = "test name",
Description = "test description",
@@ -181,14 +181,14 @@ public void AIFunctionFactoryCreateOptions_ValuesPropagateToAIFunction()
}
[Fact]
- public void AIFunctionFactoryCreateOptions_SchemaOptions_HasExpectedDefaults()
+ public void AIFunctionFactoryOptions_DefaultValues()
{
- var options = new AIFunctionFactoryCreateOptions();
- var schemaOptions = options.JsonSchemaCreateOptions;
+ AIFunctionFactoryOptions options = new();
- Assert.NotNull(schemaOptions);
- Assert.True(schemaOptions.IncludeTypeInEnumSchemas);
- Assert.True(schemaOptions.RequireAllProperties);
- Assert.True(schemaOptions.DisallowAdditionalProperties);
+ Assert.Null(options.Name);
+ Assert.Null(options.Description);
+ Assert.Null(options.AdditionalProperties);
+ Assert.Null(options.SerializerOptions);
+ Assert.Null(options.JsonSchemaCreateOptions);
}
}