Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move AIFunction parameter schematization from parameter level to function level. #5826

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@ namespace Microsoft.Extensions.AI;
public sealed class AIFunctionMetadata
{
/// <summary>The name of the function.</summary>
private string _name = string.Empty;
private readonly string _name = string.Empty;

/// <summary>The description of the function.</summary>
private string _description = string.Empty;
private readonly string _description = string.Empty;
stephentoub marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>The JSON schema describing the function and its input parameters.</summary>
private readonly JsonElement _schema = AIJsonUtilities.DefaultJsonSchema;

/// <summary>The function's parameters.</summary>
private IReadOnlyList<AIFunctionParameterMetadata> _parameters = [];
private readonly IReadOnlyList<AIFunctionParameterMetadata> _parameters = [];

/// <summary>The function's return parameter.</summary>
private AIFunctionReturnParameterMetadata _returnParameter = AIFunctionReturnParameterMetadata.Empty;
private readonly AIFunctionReturnParameterMetadata _returnParameter = AIFunctionReturnParameterMetadata.Empty;

/// <summary>Optional additional properties in addition to the named properties already available on this class.</summary>
private IReadOnlyDictionary<string, object?> _additionalProperties = EmptyReadOnlyDictionary<string, object?>.Instance;
private readonly IReadOnlyDictionary<string, object?> _additionalProperties = EmptyReadOnlyDictionary<string, object?>.Instance;

/// <summary><see cref="_parameters"/> indexed by name, lazily initialized.</summary>
private Dictionary<string, AIFunctionParameterMetadata>? _parametersByName;
Expand All @@ -55,6 +58,7 @@ public AIFunctionMetadata(AIFunctionMetadata metadata)
Parameters = metadata.Parameters;
ReturnParameter = metadata.ReturnParameter;
AdditionalProperties = metadata.AdditionalProperties;
Schema = metadata.Schema;
}

/// <summary>Gets the name of the function.</summary>
Expand Down Expand Up @@ -100,6 +104,43 @@ public AIFunctionReturnParameterMetadata ReturnParameter
init => _returnParameter = Throw.IfNull(value);
}

/// <summary>Gets a JSON Schema describing the function and its input parameters.</summary>
/// <remarks>
/// <para>
/// When specified, declares a self-contained JSON schema document that describes the function and its input parameters.
/// A simple example of a JSON schema for a function that adds two numbers together is shown below:
/// </para>
/// <code>
/// {
/// "title" : "addNumbers",
/// "description": "A simple function that adds two numbers together.",
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
/// "type": "object",
/// "properties": {
/// "a" : { "type": "number" },
/// "b" : { "type": "number", "default": 1 }
/// },
/// "required" : ["a"]
eiriktsarpalis marked this conversation as resolved.
Show resolved Hide resolved
/// }
/// </code>
/// <para>
/// The metadata present in the schema document plays an important role in guiding AI function invocation.
/// Functions should incorporate as much detail as possible. The arity of the "properties" keyword should
/// also match the length of the <see cref="Parameters"/> list.
/// </para>
/// <para>
/// When no schema is specified, consuming chat clients should assume the "{}" or "true" schema, indicating that any JSON input is admissible.
/// </para>
/// </remarks>
public JsonElement Schema
eiriktsarpalis marked this conversation as resolved.
Show resolved Hide resolved
{
get => _schema;
init
{
AIJsonUtilities.ValidateSchemaDocument(value);
_schema = value;
}
}

/// <summary>Gets any additional properties associated with the function.</summary>
public IReadOnlyDictionary<string, object?> AdditionalProperties
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Microsoft.Extensions.AI;
/// </summary>
public sealed class AIFunctionParameterMetadata
{
private string _name;
private readonly string _name;

/// <summary>Initializes a new instance of the <see cref="AIFunctionParameterMetadata"/> class for a parameter with the specified name.</summary>
/// <param name="name">The name of the parameter.</param>
Expand All @@ -37,7 +37,6 @@ public AIFunctionParameterMetadata(AIFunctionParameterMetadata metadata)
DefaultValue = metadata.DefaultValue;
IsRequired = metadata.IsRequired;
ParameterType = metadata.ParameterType;
Schema = metadata.Schema;
}

/// <summary>Gets the name of the parameter.</summary>
Expand All @@ -61,7 +60,4 @@ public string Name

/// <summary>Gets the .NET type of the parameter.</summary>
public Type? ParameterType { get; init; }

/// <summary>Gets a JSON Schema describing the parameter's type.</summary>
public object? Schema { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Text.Json;
using Microsoft.Shared.Diagnostics;

namespace Microsoft.Extensions.AI;
Expand All @@ -14,6 +15,9 @@ public sealed class AIFunctionReturnParameterMetadata
/// <summary>Gets an empty return parameter metadata instance.</summary>
public static AIFunctionReturnParameterMetadata Empty { get; } = new();

/// <summary>The JSON schema describing the function and its input parameters.</summary>
private readonly JsonElement _schema = AIJsonUtilities.DefaultJsonSchema;

/// <summary>Initializes a new instance of the <see cref="AIFunctionReturnParameterMetadata"/> class.</summary>
public AIFunctionReturnParameterMetadata()
{
Expand All @@ -34,5 +38,13 @@ public AIFunctionReturnParameterMetadata(AIFunctionReturnParameterMetadata metad
public Type? ParameterType { get; init; }

/// <summary>Gets a JSON Schema describing the type of the return parameter.</summary>
public object? Schema { get; init; }
public JsonElement Schema
{
get => _schema;
init
{
AIJsonUtilities.ValidateSchemaDocument(value);
_schema = value;
}
}
}
Loading