diff --git a/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs b/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs
index 41550ba0451..5116238763f 100644
--- a/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs
+++ b/src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs
@@ -41,15 +41,67 @@ public static partial class AIFunctionFactory
/// The created for invoking .
///
///
- /// Return values are serialized to using 's
- /// . 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 ,
- /// , 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.
+ /// By default, any parameters to are sourced from the 's dictionary
+ /// of key/value pairs and are represented in the JSON schema for the function, as exposed in the returned 's
+ /// . There are a few exceptions to this:
+ ///
+ /// -
+ ///
+ /// parameters are automatically bound to the passed into
+ /// the invocation via 's parameter. The parameter is
+ /// not included in the generated JSON schema. The behavior of parameters may not be overridden.
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound from the property
+ /// and are not included in the JSON schema. If the parameter is optional, such that a default value is provided,
+ /// is allowed to be ; otherwise,
+ /// must be non-, or else the invocation will fail with an exception due to the required nature of the parameter.
+ /// The handling of parameters may be overridden via .
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound directly to instance
+ /// passed into and are not included in the JSON schema. If the
+ /// instance passed to is , the implementation
+ /// manufactures an empty instance, such that parameters of type may always be satisfied, whether
+ /// optional or not. The handling of parameters may be overridden via
+ /// .
+ ///
+ ///
+ ///
+ /// All other parameter types are, by default, bound from the dictionary passed into
+ /// and are included in the generated JSON schema. This may be overridden by the provided
+ /// via the parameter; for every parameter, the delegate is enabled to choose if the parameter should be included in the
+ /// generated schema and how its value should be bound, including handling of optionality (by default, required parameters that are not included in the
+ /// dictionary will result in an exception being thrown). Loosely-typed additional context information may be passed
+ /// into via the 's dictionary; the default
+ /// binding ignores this collection, but a custom binding supplied via may choose to
+ /// source arguments from this data.
+ ///
+ ///
+ /// The default marshaling of parameters from the dictionary permits values to be passed into the 's
+ /// invocation directly if the object is already of a compatible type. Otherwise, if the argument is a , ,
+ /// or , it is deserialized into the parameter type, utilizing if provided,
+ /// or else using . If the argument is anything else, it is round-tripped through JSON, serializing the object as JSON
+ /// and then deserializing it to the expected type.
+ ///
+ ///
+ /// In general, the data supplied via an 's dictionary is supplied from an AI service and should be considered
+ /// unvalidated and untrusted. To provide validated and trusted data to the invocation of , consider having
+ /// point to an instance method on an instance configured to hold the appropriate state. An parameter may also be
+ /// used to resolve services from a dependency injection container.
+ ///
+ ///
+ /// By default, return values are serialized to using 's
+ /// if provided, or else using .
+ /// Handling of return values may be overridden via .
///
///
/// is .
+ /// A parameter to is not serializable.
public static AIFunction Create(Delegate method, AIFunctionFactoryOptions? options)
{
_ = Throw.IfNull(method);
@@ -59,20 +111,72 @@ public static AIFunction Create(Delegate method, AIFunctionFactoryOptions? optio
/// Creates an instance for a method, specified via a delegate.
/// The method to be represented via the created .
- /// The name to use for the .
- /// The description to use for the .
+ ///
+ /// The name to use for the . If , the name will be derived from
+ /// the name of .
+ ///
+ ///
+ /// The description to use for the . If , a description will be derived from
+ /// any on , if available.
+ ///
/// The used to marshal function parameters and any return value.
/// The created for invoking .
///
///
- /// Return values are serialized to using .
- /// Arguments that are not already of the expected type are marshaled to the expected type via JSON and using
- /// . 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.
+ /// Any parameters to are sourced from the 's dictionary
+ /// of key/value pairs and are represented in the JSON schema for the function, as exposed in the returned 's
+ /// . There are a few exceptions to this:
+ ///
+ /// -
+ ///
+ /// parameters are automatically bound to the passed into
+ /// the invocation via 's parameter. The parameter is
+ /// not included in the generated JSON schema. The behavior of parameters may not be overridden.
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound from the property
+ /// and are not included in the JSON schema. If the parameter is optional, such that a default value is provided,
+ /// is allowed to be ; otherwise,
+ /// must be non-, or else the invocation will fail with an exception due to the required nature of the parameter.
+ /// The handling of parameters may be overridden via .
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound directly to instance
+ /// passed into and are not included in the JSON schema. If the
+ /// instance passed to is , the implementation
+ /// manufactures an empty instance, such that parameters of type may always be satisfied, whether
+ /// optional or not. The handling of parameters may be overridden via
+ /// .
+ ///
+ ///
+ ///
+ /// All other parameter types are bound from the dictionary passed into
+ /// and are included in the generated JSON schema.
+ ///
+ ///
+ /// The marshaling of parameters from the dictionary permits values to be passed into the 's
+ /// invocation directly if the object is already of a compatible type. Otherwise, if the argument is a , ,
+ /// or , it is deserialized into the parameter type, utilizing if provided, or else
+ /// . If the argument is anything else, it is round-tripped through JSON, serializing the object as JSON
+ /// and then deserializing it to the expected type.
+ ///
+ ///
+ /// In general, the data supplied via an 's dictionary is supplied from an AI service and should be considered
+ /// unvalidated and untrusted. To provide validated and trusted data to the invocation of , consider having
+ /// point to an instance method on an instance configured to hold the appropriate state. An parameter may also be
+ /// used to resolve services from a dependency injection container.
+ ///
+ ///
+ /// Return values are serialized to using if provided,
+ /// or else using .
///
///
/// is .
+ /// A parameter to is not serializable.
public static AIFunction Create(Delegate method, string? name = null, string? description = null, JsonSerializerOptions? serializerOptions = null)
{
_ = Throw.IfNull(method);
@@ -102,15 +206,70 @@ public static AIFunction Create(Delegate method, string? name = null, string? de
/// The created for invoking .
///
///
- /// Return values are serialized to using 's
- /// . 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 ,
- /// , 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.
+ /// By default, any parameters to are sourced from the 's dictionary
+ /// of key/value pairs and are represented in the JSON schema for the function, as exposed in the returned 's
+ /// . There are a few exceptions to this:
+ ///
+ /// -
+ ///
+ /// parameters are automatically bound to the passed into
+ /// the invocation via 's parameter. The parameter is
+ /// not included in the generated JSON schema. The behavior of parameters may not be overridden.
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound from the property
+ /// and are not included in the JSON schema. If the parameter is optional, such that a default value is provided,
+ /// is allowed to be ; otherwise,
+ /// must be non-, or else the invocation will fail with an exception due to the required nature of the parameter.
+ /// The handling of parameters may be overridden via .
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound directly to instance
+ /// passed into and are not included in the JSON schema. If the
+ /// instance passed to is , the implementation
+ /// manufactures an empty instance, such that parameters of type may always be satisfied, whether
+ /// optional or not. The handling of parameters may be overridden via
+ /// .
+ ///
+ ///
+ ///
+ /// All other parameter types are, by default, bound from the dictionary passed into
+ /// and are included in the generated JSON schema. This may be overridden by the provided
+ /// via the parameter; for every parameter, the delegate is enabled to choose if the parameter should be included in the
+ /// generated schema and how its value should be bound, including handling of optionality (by default, required parameters that are not included in the
+ /// dictionary will result in an exception being thrown). Loosely-typed additional context information may be passed
+ /// into via the 's dictionary; the default
+ /// binding ignores this collection, but a custom binding supplied via may choose to
+ /// source arguments from this data.
+ ///
+ ///
+ /// The default marshaling of parameters from the dictionary permits values to be passed into the 's
+ /// invocation directly if the object is already of a compatible type. Otherwise, if the argument is a , ,
+ /// or , it is deserialized into the parameter type, utilizing if provided,
+ /// or else using . If the argument is anything else, it is round-tripped through JSON, serializing the object as JSON
+ /// and then deserializing it to the expected type.
+ ///
+ ///
+ /// In general, the data supplied via an 's dictionary is supplied from an AI service and should be considered
+ /// unvalidated and untrusted. To provide validated and trusted data to the invocation of , consider having
+ /// point to an instance method on an instance configured to hold the appropriate state. An parameter may also be
+ /// used to resolve services from a dependency injection container.
+ ///
+ ///
+ /// By default, return values are serialized to using 's
+ /// if provided, or else using .
+ /// Handling of return values may be overridden via .
///
///
/// is .
+ /// represents an instance method but is null.
+ /// represents an open generic method.
+ /// contains a parameter without a parameter name.
+ /// A parameter to or its return type is not serializable.
public static AIFunction Create(MethodInfo method, object? target, AIFunctionFactoryOptions? options)
{
_ = Throw.IfNull(method);
@@ -118,6 +277,100 @@ public static AIFunction Create(MethodInfo method, object? target, AIFunctionFac
return ReflectionAIFunction.Build(method, target, options ?? _defaultOptions);
}
+ ///
+ /// Creates an instance for a method, specified via an instance
+ /// and an optional target object if the method is an instance method.
+ ///
+ /// The method to be represented via the created .
+ ///
+ /// The target object for the if it represents an instance method.
+ /// This should be if and only if is a static method.
+ ///
+ ///
+ /// The name to use for the . If , the name will be derived from
+ /// the name of .
+ ///
+ ///
+ /// The description to use for the . If , a description will be derived from
+ /// any on , if available.
+ ///
+ /// The used to marshal function parameters and return value.
+ /// The created for invoking .
+ ///
+ ///
+ /// Any parameters to are sourced from the 's dictionary
+ /// of key/value pairs and are represented in the JSON schema for the function, as exposed in the returned 's
+ /// . There are a few exceptions to this:
+ ///
+ /// -
+ ///
+ /// parameters are automatically bound to the passed into
+ /// the invocation via 's parameter. The parameter is
+ /// not included in the generated JSON schema. The behavior of parameters may not be overridden.
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound from the property
+ /// and are not included in the JSON schema. If the parameter is optional, such that a default value is provided,
+ /// is allowed to be ; otherwise,
+ /// must be non-, or else the invocation will fail with an exception due to the required nature of the parameter.
+ /// The handling of parameters may be overridden via .
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound directly to instance
+ /// passed into and are not included in the JSON schema. If the
+ /// instance passed to is , the implementation
+ /// manufactures an empty instance, such that parameters of type may always be satisfied, whether
+ /// optional or not. The handling of parameters may be overridden via
+ /// .
+ ///
+ ///
+ ///
+ /// All other parameter types are bound from the dictionary passed into
+ /// and are included in the generated JSON schema.
+ ///
+ ///
+ /// The marshaling of parameters from the dictionary permits values to be passed into the 's
+ /// invocation directly if the object is already of a compatible type. Otherwise, if the argument is a , ,
+ /// or , it is deserialized into the parameter type, utilizing if provided, or else
+ /// . If the argument is anything else, it is round-tripped through JSON, serializing the object as JSON
+ /// and then deserializing it to the expected type.
+ ///
+ ///
+ /// In general, the data supplied via an 's dictionary is supplied from an AI service and should be considered
+ /// unvalidated and untrusted. To provide validated and trusted data to the invocation of , consider having
+ /// point to an instance method on an instance configured to hold the appropriate state. An parameter may also be
+ /// used to resolve services from a dependency injection container.
+ ///
+ ///
+ /// Return values are serialized to using if provided,
+ /// or else using .
+ ///
+ ///
+ /// is .
+ /// represents an instance method but is null.
+ /// represents an open generic method.
+ /// contains a parameter without a parameter name.
+ /// A parameter to or its return type is not serializable.
+ public static AIFunction Create(MethodInfo method, object? target, string? name = null, string? description = null, JsonSerializerOptions? serializerOptions = null)
+ {
+ _ = Throw.IfNull(method);
+
+ AIFunctionFactoryOptions createOptions = serializerOptions is null && name is null && description is null
+ ? _defaultOptions
+ : new()
+ {
+ Name = name,
+ Description = description,
+ SerializerOptions = serializerOptions,
+ };
+
+ return ReflectionAIFunction.Build(method, target, createOptions);
+ }
+
///
/// Creates an instance for a method, specified via an for
/// and instance method, along with a representing the type of the target object to
@@ -127,7 +380,7 @@ public static AIFunction Create(MethodInfo method, object? target, AIFunctionFac
///
/// The to construct an instance of on which to invoke when
/// the resulting is invoked. If is provided,
- /// ActivatorUtilities.CreateInstance will be used to construct the instance using those services; otherwise,
+ /// will be used to construct the instance using those services; otherwise,
/// is used, utilizing the type's public parameterless constructor.
/// If an instance can't be constructed, an exception is thrown during the function's invocation.
///
@@ -142,8 +395,73 @@ public static AIFunction Create(MethodInfo method, object? target, AIFunctionFac
/// , 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.
///
+ ///
+ /// By default, any parameters to are sourced from the 's dictionary
+ /// of key/value pairs and are represented in the JSON schema for the function, as exposed in the returned 's
+ /// . There are a few exceptions to this:
+ ///
+ /// -
+ ///
+ /// parameters are automatically bound to the passed into
+ /// the invocation via 's parameter. The parameter is
+ /// not included in the generated JSON schema. The behavior of parameters may not be overridden.
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound from the property
+ /// and are not included in the JSON schema. If the parameter is optional, such that a default value is provided,
+ /// is allowed to be ; otherwise,
+ /// must be non-, or else the invocation will fail with an exception due to the required nature of the parameter.
+ /// The handling of parameters may be overridden via .
+ ///
+ ///
+ /// -
+ ///
+ /// By default, parameters are bound directly to instance
+ /// passed into and are not included in the JSON schema. If the
+ /// instance passed to is , the implementation
+ /// manufactures an empty instance, such that parameters of type may always be satisfied, whether
+ /// optional or not. The handling of parameters may be overridden via
+ /// .
+ ///
+ ///
+ ///
+ /// All other parameter types are, by default, bound from the dictionary passed into
+ /// and are included in the generated JSON schema. This may be overridden by the provided
+ /// via the parameter; for every parameter, the delegate is enabled to choose if the parameter should be included in the
+ /// generated schema and how its value should be bound, including handling of optionality (by default, required parameters that are not included in the
+ /// dictionary will result in an exception being thrown). Loosely-typed additional context information may be passed
+ /// into via the 's dictionary; the default
+ /// binding ignores this collection, but a custom binding supplied via may choose to
+ /// source arguments from this data.
+ ///
+ ///
+ /// The default marshaling of parameters from the dictionary permits values to be passed into the 's
+ /// invocation directly if the object is already of a compatible type. Otherwise, if the argument is a , ,
+ /// or , it is deserialized into the parameter type, utilizing if provided,
+ /// or else using . If the argument is anything else, it is round-tripped through JSON, serializing the object as JSON
+ /// and then deserializing it to the expected type.
+ ///
+ ///
+ /// In general, the data supplied via an 's dictionary is supplied from an AI service and should be considered
+ /// unvalidated and untrusted. To provide validated and trusted data to the invocation of , the instance constructed
+ /// for each invocation may contain that data in it, such that it's then available to as instance data.
+ /// An parameter may also be used to resolve services from a dependency injection container.
+ ///
+ ///
+ /// By default, return values are serialized to using 's
+ /// if provided, or else using .
+ /// Handling of return values may be overridden via .
+ ///
///
/// is .
+ /// is .
+ /// represents a static method.
+ /// represents an open generic method.
+ /// contains a parameter without a parameter name.
+ /// is not assignable to 's declaring type.
+ /// A parameter to or its return type is not serializable.
public static AIFunction Create(
MethodInfo method,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type targetType,
@@ -155,45 +473,6 @@ public static AIFunction Create(
return ReflectionAIFunction.Build(method, targetType, options ?? _defaultOptions);
}
- ///
- /// Creates an instance for a method, specified via an instance
- /// and an optional target object if the method is an instance method.
- ///
- /// The method to be represented via the created .
- ///
- /// The target object for the if it represents an instance method.
- /// This should be if and only if is a static method.
- ///
- /// The name to use for the .
- /// The description to use for the .
- /// The used to marshal function parameters and return value.
- /// The created for invoking .
- ///
- ///
- /// Return values are serialized to using .
- /// Arguments that are not already of the expected type are marshaled to the expected type via JSON and using
- /// . 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.
- ///
- ///
- /// is .
- public static AIFunction Create(MethodInfo method, object? target, string? name = null, string? description = null, JsonSerializerOptions? serializerOptions = null)
- {
- _ = Throw.IfNull(method);
-
- AIFunctionFactoryOptions createOptions = serializerOptions is null && name is null && description is null
- ? _defaultOptions
- : new()
- {
- Name = name,
- Description = description,
- SerializerOptions = serializerOptions,
- };
-
- return ReflectionAIFunction.Build(method, target, createOptions);
- }
-
private sealed class ReflectionAIFunction : AIFunction
{
public static ReflectionAIFunction Build(MethodInfo method, object? target, AIFunctionFactoryOptions options)