autogen/dotnet/src/AutoGen.SourceGenerator
Ryan Sweet 0214299de5
updating dependencies and build to ensure works with net9 (#3800)
* interim - doesn't work - sharing

* turn off EnforceExtended

* works with dotnet build now... ;-)

* interim progress

* more updates

* make VS happy

* update

* Update AutoGen.Ollama.csproj

* Update Microsoft.AutoGen.Agents.Abstractions.csproj

* Delete dotnet/test/AutoGen.Gemini.Tests/ApprovalTests/FunctionContractExtensionTests.ItGenerateGetWeatherToolTest.received.txt

* fix tests

---------

Co-authored-by: XiaoYun Zhang <xiaoyuz@microsoft.com>
2024-10-16 11:03:05 -07:00
..

AutoGen.SourceGenerator

This package carries a source generator that adds support for type-safe function definition generation. Simply mark a method with Function attribute, and the source generator will generate a function definition and a function call wrapper for you.

Get start

First, add the following to your project file and set GenerateDocumentationFile property to true

<PropertyGroup>
    <!-- This enables structural xml document support -->
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
    <PackageReference Include="AutoGen.SourceGenerator" />
</ItemGroup>

Nightly Build feed: https://devdiv.pkgs.visualstudio.com/DevDiv/_packaging/AutoGen/nuget/v3/index.json

Then, for the methods you want to generate function definition and function call wrapper, mark them with Function attribute:

Note: For the best of performance, try using primitive types for the parameters and return type.

// file: MyFunctions.cs

using AutoGen;

// a partial class is required
// and the class must be public
public partial class MyFunctions
{
    /// <summary>
    /// Add two numbers.
    /// </summary>
    /// <param name="a">The first number.</param>
    /// <param name="b">The second number.</param>
    [Function]
    public Task<string> AddAsync(int a, int b)
    {
        return Task.FromResult($"{a} + {b} = {a + b}");
    }
}

The source generator will generate the following code based on the method signature and documentation. It helps you save the effort of writing function definition and keep it up to date with the actual method signature.

// file: MyFunctions.generated.cs
public partial class MyFunctions
{
    private class AddAsyncSchema
    {
		public int a {get; set;}
		public int b {get; set;}
    }

    public Task<string> AddAsyncWrapper(string arguments)
    {
        var schema = JsonSerializer.Deserialize<AddAsyncSchema>(
            arguments, 
            new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            });
        return AddAsync(schema.a, schema.b);
    }

    public FunctionDefinition AddAsyncFunction
    {
        get => new FunctionDefinition
		{
			Name = @"AddAsync",
            Description = """
Add two numbers.
""",
            Parameters = BinaryData.FromObjectAsJson(new
            {
                Type = "object",
                Properties = new
				{
				    a = new
				    {
					    Type = @"number",
					    Description = @"The first number.",
				    },
				    b = new
				    {
					    Type = @"number",
					    Description = @"The second number.",
				    },
                },
                Required = new []
				{
				    "a",
				    "b",
				},
            },
            new JsonSerializerOptions
			{
				PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
			})
        };
    }
}

For more examples, please check out the following project