From 1b3c67df963651332c1ec80b98b9b0ae1e747717 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Thu, 15 Jan 2026 15:15:08 -0800 Subject: [PATCH] Minor cleanup/reorg --- .../AzureFunctions/09_Workflow/Program.cs | 2 +- .../CoreAgentConfigurationExtensions.cs | 73 +++++++++++++++++++ .../DurableOptionsExtensions.cs | 37 +++------- .../FunctionsApplicationBuilderExtensions.cs | 20 +---- 4 files changed, 88 insertions(+), 44 deletions(-) create mode 100644 dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/CoreAgentConfigurationExtensions.cs diff --git a/dotnet/samples/AzureFunctions/09_Workflow/Program.cs b/dotnet/samples/AzureFunctions/09_Workflow/Program.cs index 4261fb9533..a4b8b4effb 100644 --- a/dotnet/samples/AzureFunctions/09_Workflow/Program.cs +++ b/dotnet/samples/AzureFunctions/09_Workflow/Program.cs @@ -75,7 +75,7 @@ var workflow = builder.WithName("HandleSurveyResponse").Build(); FunctionsApplication.CreateBuilder(args) .ConfigureFunctionsWebApplication() - //.ConfigureDurableAgents(options => options.AddAIAgent(agent)) + .ConfigureDurableAgents(options => options.AddAIAgent(agent)) .ConfigureDurableOptions(options => { // Configure workflows diff --git a/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/CoreAgentConfigurationExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/CoreAgentConfigurationExtensions.cs new file mode 100644 index 0000000000..ff5c77416c --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/CoreAgentConfigurationExtensions.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft. All rights reserved. + +using Microsoft.Azure.Functions.Worker.Builder; +using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Hosting; + +namespace Microsoft.Agents.AI.Hosting.AzureFunctions; + +/// +/// Shared configuration logic for durable agents and workflows. +/// This class consolidates common service registrations used by both +/// and +/// . +/// +internal static class CoreAgentConfigurationExtensions +{ + /// + /// Registers the core agent services required for durable agents. + /// + /// The functions application builder. + /// The functions application builder for method chaining. + internal static FunctionsApplicationBuilder RegisterCoreAgentServices(this FunctionsApplicationBuilder builder) + { + builder.Services.TryAddSingleton(_ => + new DefaultFunctionsAgentOptionsProvider(DurableAgentsOptionsExtensions.GetAgentOptionsSnapshot())); + + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + + return builder; + } + + /// + /// Registers the workflow-specific services required for durable workflows. + /// This should only be called when workflows are configured in the application. + /// + /// The functions application builder. + /// The functions application builder for method chaining. + internal static FunctionsApplicationBuilder RegisterWorkflowServices(this FunctionsApplicationBuilder builder) + { + builder.Services.TryAddSingleton(); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + + return builder; + } + + /// + /// Configures the middleware and executor for handling built-in function execution. + /// This is shared by both agents and workflows, handling Agent HTTP, MCP tool, + /// workflow orchestration, and Entity invocations. + /// + /// The functions application builder. + /// The functions application builder for method chaining. + internal static FunctionsApplicationBuilder ConfigureBuiltInFunctionMiddleware(this FunctionsApplicationBuilder builder) + { + builder.Services.TryAddSingleton(); + + builder.UseWhen(static context => + IsBuiltInFunction(context.FunctionDefinition.EntryPoint)); + + return builder; + } + + private static bool IsBuiltInFunction(string? entryPoint) + { + return string.Equals(entryPoint, BuiltInFunctions.RunAgentHttpFunctionEntryPoint, StringComparison.Ordinal) + || string.Equals(entryPoint, BuiltInFunctions.RunAgentMcpToolFunctionEntryPoint, StringComparison.Ordinal) + || string.Equals(entryPoint, BuiltInFunctions.RunWorkflowOrechstrtationHttpFunctionEntryPoint, StringComparison.Ordinal) + || string.Equals(entryPoint, BuiltInFunctions.InvokeWorkflowActivityFunctionEntryPoint, StringComparison.Ordinal) + || string.Equals(entryPoint, BuiltInFunctions.RunAgentEntityFunctionEntryPoint, StringComparison.Ordinal); + } +} diff --git a/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/DurableOptionsExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/DurableOptionsExtensions.cs index 4b801f2e99..10dab0f73d 100644 --- a/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/DurableOptionsExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/DurableOptionsExtensions.cs @@ -3,12 +3,10 @@ using Microsoft.Agents.AI.DurableTask; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Builder; -using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata; using Microsoft.DurableTask; using Microsoft.DurableTask.Worker; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace Microsoft.Agents.AI.Hosting.AzureFunctions; @@ -41,23 +39,23 @@ public static class DurableOptionsExtensions RegisterServices(builder, options); ConfigureAgents(builder, options); - ConfigureMiddleware(builder); - ConfigureWorkflowOrchestration(builder); + builder.ConfigureBuiltInFunctionMiddleware(); + + if (options.Workflows.Workflows.Count > 0) + { + builder.RegisterWorkflowServices(); + ConfigureWorkflowOrchestration(builder); + } return builder; } private static void RegisterServices(FunctionsApplicationBuilder builder, DurableOptions options) { - builder.Services.AddSingleton(options); - builder.Services.AddSingleton(options.Agents); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); + builder.Services.TryAddSingleton(options); + builder.Services.TryAddSingleton(options.Agents); // backward compatibility. can be removed in future. - builder.Services.TryAddSingleton(_ => - new DefaultFunctionsAgentOptionsProvider(DurableAgentsOptionsExtensions.GetAgentOptionsSnapshot())); + builder.RegisterCoreAgentServices(); } private static void ConfigureAgents(FunctionsApplicationBuilder builder, DurableOptions options) @@ -81,21 +79,6 @@ public static class DurableOptionsExtensions }); } - private static void ConfigureMiddleware(FunctionsApplicationBuilder builder) - { - builder.UseWhen(static context => - IsBuiltInFunction(context.FunctionDefinition.EntryPoint)); - } - - private static bool IsBuiltInFunction(string? entryPoint) - { - return string.Equals(entryPoint, BuiltInFunctions.RunAgentHttpFunctionEntryPoint, StringComparison.Ordinal) - || string.Equals(entryPoint, BuiltInFunctions.RunAgentMcpToolFunctionEntryPoint, StringComparison.Ordinal) - || string.Equals(entryPoint, BuiltInFunctions.RunWorkflowOrechstrtationHttpFunctionEntryPoint, StringComparison.Ordinal) - || string.Equals(entryPoint, BuiltInFunctions.InvokeWorkflowActivityFunctionEntryPoint, StringComparison.Ordinal) - || string.Equals(entryPoint, BuiltInFunctions.RunAgentEntityFunctionEntryPoint, StringComparison.Ordinal); - } - private static void ConfigureWorkflowOrchestration(FunctionsApplicationBuilder builder) { // Registering a single orchestration function to handle all workflow runs. diff --git a/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/FunctionsApplicationBuilderExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/FunctionsApplicationBuilderExtensions.cs index b9487ca507..11b30093cd 100644 --- a/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/FunctionsApplicationBuilderExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/FunctionsApplicationBuilderExtensions.cs @@ -2,10 +2,6 @@ using Microsoft.Agents.AI.DurableTask; using Microsoft.Azure.Functions.Worker.Builder; -using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Hosting; namespace Microsoft.Agents.AI.Hosting.AzureFunctions; @@ -24,24 +20,16 @@ public static class FunctionsApplicationBuilderExtensions this FunctionsApplicationBuilder builder, Action configure) { + ArgumentNullException.ThrowIfNull(builder); ArgumentNullException.ThrowIfNull(configure); // The main agent services registration is done in Microsoft.DurableTask.Agents. builder.Services.ConfigureDurableAgents(configure); - builder.Services.TryAddSingleton(_ => - new DefaultFunctionsAgentOptionsProvider(DurableAgentsOptionsExtensions.GetAgentOptionsSnapshot())); + builder.RegisterCoreAgentServices(); - builder.Services.AddSingleton(); - - // Handling of built-in function execution for Agent HTTP, MCP tool, or Entity invocations. - builder.UseWhen(static context => - string.Equals(context.FunctionDefinition.EntryPoint, BuiltInFunctions.RunAgentHttpFunctionEntryPoint, StringComparison.Ordinal) || - string.Equals(context.FunctionDefinition.EntryPoint, BuiltInFunctions.RunAgentMcpToolFunctionEntryPoint, StringComparison.Ordinal) || - string.Equals(context.FunctionDefinition.EntryPoint, BuiltInFunctions.RunWorkflowOrechstrtationHttpFunctionEntryPoint, StringComparison.Ordinal) || - string.Equals(context.FunctionDefinition.EntryPoint, BuiltInFunctions.InvokeWorkflowActivityFunctionEntryPoint, StringComparison.Ordinal) || - string.Equals(context.FunctionDefinition.EntryPoint, BuiltInFunctions.RunAgentEntityFunctionEntryPoint, StringComparison.Ordinal)); - builder.Services.AddSingleton(); + // Configure middleware for built-in function execution. + builder.ConfigureBuiltInFunctionMiddleware(); return builder; }