mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
104 lines
5.2 KiB
C#
104 lines
5.2 KiB
C#
// Copyright (c) Microsoft. All rights reserved.
|
|
|
|
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;
|
|
|
|
/// <summary>
|
|
/// Extension methods for configuring durable options (agents and workflows).
|
|
/// </summary>
|
|
public static class DurableOptionsExtensions
|
|
{
|
|
/// <summary>
|
|
/// Configures durable agents and workflows in a unified way.
|
|
/// </summary>
|
|
/// <param name="builder">The Functions application builder.</param>
|
|
/// <param name="configure">A delegate to configure the durable options.</param>
|
|
/// <returns>The Functions application builder for method chaining.</returns>
|
|
/// <remarks>
|
|
/// This method provides a unified configuration point for both durable agents and workflows.
|
|
/// Agents configured here will be automatically registered when referenced in workflows.
|
|
/// </remarks>
|
|
public static FunctionsApplicationBuilder ConfigureDurableOptions(
|
|
this FunctionsApplicationBuilder builder,
|
|
Action<DurableOptions> configure)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(configure);
|
|
|
|
DurableOptions options = new();
|
|
configure(options);
|
|
|
|
// Register the unified DurableOptions for components that need both agents and workflows
|
|
builder.Services.AddSingleton(options);
|
|
|
|
// Register AgentsOption for backward compatibility. Can be removed if needed, after syncing with team.
|
|
builder.Services.AddSingleton(options.Agents);
|
|
|
|
// Configure agents using the existing infrastructure
|
|
builder.Services.ConfigureDurableAgents(agentOpts =>
|
|
{
|
|
// Copy agent registrations from the unified options to the service-level options
|
|
foreach (KeyValuePair<string, Func<IServiceProvider, AIAgent>> agentFactory in options.Agents.GetAgentFactories())
|
|
{
|
|
agentOpts.AddAIAgentFactory(
|
|
agentFactory.Key,
|
|
agentFactory.Value,
|
|
options.Agents.GetTimeToLive(agentFactory.Key));
|
|
}
|
|
|
|
// Copy TTL settings
|
|
agentOpts.DefaultTimeToLive = options.Agents.DefaultTimeToLive;
|
|
agentOpts.MinimumTimeToLiveSignalDelay = options.Agents.MinimumTimeToLiveSignalDelay;
|
|
});
|
|
|
|
builder.Services.TryAddSingleton<IFunctionsAgentOptionsProvider>(_ =>
|
|
new DefaultFunctionsAgentOptionsProvider(DurableAgentsOptionsExtensions.GetAgentOptionsSnapshot()));
|
|
|
|
builder.Services.AddSingleton<IFunctionMetadataTransformer, DurableAgentFunctionMetadataTransformer>();
|
|
|
|
// Handling of built-in function execution for Agent HTTP, MCP tool, or Entity invocations.
|
|
builder.UseWhen<BuiltInFunctionExecutionMiddleware>(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<BuiltInFunctionExecutor>();
|
|
|
|
builder.Services.AddSingleton<DurableWorkflowRunner>();
|
|
|
|
builder.ConfigureDurableWorker().AddTasks(t => t.AddOrchestratorFunc<DuableWorkflowRunRequest, List<string>>(
|
|
"WorkflowRunnerOrchestration",
|
|
async (tc, inputBindingData) =>
|
|
{
|
|
FunctionContext? functionContext = tc.GetFunctionContext();
|
|
if (functionContext == null)
|
|
{
|
|
throw new InvalidOperationException("FunctionContext is not available in the orchestration context.");
|
|
}
|
|
var logger = tc.CreateReplaySafeLogger("WorkflowRunnerOrchestration");
|
|
DurableWorkflowRunner runner = functionContext.InstanceServices.GetRequiredService<DurableWorkflowRunner>();
|
|
var orchestrationResult = await runner.RunWorkflowOrchestrationAsync(tc, inputBindingData, logger);
|
|
if (logger.IsEnabled(LogLevel.Information))
|
|
{
|
|
logger.LogInformation("Durable workflow orchestration completed. Result:{Result}", string.Join(",", orchestrationResult));
|
|
}
|
|
|
|
return orchestrationResult;
|
|
}));
|
|
|
|
builder.Services.AddSingleton<IFunctionMetadataTransformer, DurableWorkflowFunctionMetadataTransformer>();
|
|
|
|
return builder;
|
|
}
|
|
}
|