Skip to content

Commit

Permalink
Move AIFunction parameter schematization from parameter level to func…
Browse files Browse the repository at this point in the history
…tion level. (#5826)

* Move AIFunction parameter schematization from parameter level to function level.

* Address feedback

* Address feedback.
  • Loading branch information
eiriktsarpalis authored Feb 7, 2025
1 parent 11ccd68 commit 7f98df2
Show file tree
Hide file tree
Showing 16 changed files with 216 additions and 316 deletions.
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;

/// <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.",
/// "type": "object",
/// "properties": {
/// "a" : { "type": "number" },
/// "b" : { "type": "number", "default": 1 }
/// },
/// "required" : ["a"]
/// }
/// </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
{
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

0 comments on commit 7f98df2

Please sign in to comment.