mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Working demos
This commit is contained in:
@@ -8,3 +8,6 @@ dotnet_diagnostic.DURABLE0003.severity = none
|
||||
dotnet_diagnostic.DURABLE0004.severity = none
|
||||
dotnet_diagnostic.DURABLE0005.severity = none
|
||||
dotnet_diagnostic.DURABLE0006.severity = none
|
||||
|
||||
# CA1812: Internal classes are instantiated via dependency injection or reflection in samples
|
||||
dotnet_diagnostic.CA1812.severity = none
|
||||
|
||||
@@ -23,9 +23,8 @@ var orderParserExecutor = orderParserFunc.BindAsExecutor("ParseOrderId");
|
||||
OrderLookup orderLookupExecutor = new();
|
||||
OrderEnrich orderEnricherExeecutor = new();
|
||||
PaymentProcessor paymentProcessorExecutor = new();
|
||||
OrderCancel orderArchiverExecutor = new();
|
||||
|
||||
Workflow processOrder = new WorkflowBuilder(orderParserExecutor)
|
||||
Workflow fulfillOrder = new WorkflowBuilder(orderParserExecutor)
|
||||
.WithName("FulfillOrder")
|
||||
.WithDescription("Looks up an order by ID and run payment processing")
|
||||
.AddEdge(orderParserExecutor, orderLookupExecutor)
|
||||
@@ -33,20 +32,17 @@ Workflow processOrder = new WorkflowBuilder(orderParserExecutor)
|
||||
.AddEdge(orderEnricherExeecutor, paymentProcessorExecutor)
|
||||
.Build();
|
||||
|
||||
Workflow cancelOrder = new WorkflowBuilder(orderParserExecutor)
|
||||
.WithName("CancelOrder")
|
||||
.WithDescription("Cancel an order")
|
||||
.AddEdge(orderParserExecutor, orderLookupExecutor)
|
||||
.AddEdge(orderLookupExecutor, orderArchiverExecutor)
|
||||
.Build();
|
||||
//OrderCancel orderArchiverExecutor = new();
|
||||
//Workflow cancelOrder = new WorkflowBuilder(orderParserExecutor)
|
||||
// .WithName("CancelOrder")
|
||||
// .WithDescription("Cancel an order")
|
||||
// .AddEdge(orderParserExecutor, orderLookupExecutor)
|
||||
// .AddEdge(orderLookupExecutor, orderArchiverExecutor)
|
||||
// .Build();
|
||||
|
||||
var host = FunctionsApplication.CreateBuilder(args)
|
||||
.ConfigureFunctionsWebApplication()
|
||||
.ConfigureDurableOptions(options =>
|
||||
{
|
||||
options.Workflows.AddWorkflow(processOrder);
|
||||
options.Workflows.AddWorkflow(cancelOrder, true);
|
||||
})
|
||||
.ConfigureDurableOptions(options => options.Workflows.AddWorkflow(fulfillOrder))
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
|
||||
@@ -30,21 +30,19 @@ AIAgent chemist = client.GetChatClient(deploymentName).CreateAIAgent("You are an
|
||||
var startExecutor = new ConcurrentStartExecutor();
|
||||
var aggregationExecutor = new ResultAggregationExecutor();
|
||||
|
||||
// Build the workflow by adding executors and connecting them
|
||||
var workflow = new WorkflowBuilder(startExecutor)
|
||||
.WithName("FanOutWorkflow")
|
||||
.WithName("ExpertReview")
|
||||
.AddFanOutEdge(startExecutor, [physicist, chemist])
|
||||
.AddFanInEdge([physicist, chemist], aggregationExecutor)
|
||||
.Build();
|
||||
|
||||
// Configure the function app to host AI agents and workflows in a unified way.
|
||||
// This will automatically generate HTTP API endpoints for agents and workflows.
|
||||
|
||||
FunctionsApplication.CreateBuilder(args)
|
||||
var host = FunctionsApplication.CreateBuilder(args)
|
||||
.ConfigureFunctionsWebApplication()
|
||||
.ConfigureDurableOptions(options =>
|
||||
{
|
||||
// Configure workflows
|
||||
options.Workflows.AddWorkflow(workflow, enableMcpToolTrigger: true);
|
||||
options.Workflows.AddWorkflow(workflow);
|
||||
})
|
||||
.Build().Run();
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@authority=http://localhost:7071
|
||||
|
||||
### Start the workflow
|
||||
POST {{authority}}/api/workflows/FanOutWorkflow/run
|
||||
POST {{authority}}/api/workflows/ExpertReview/run
|
||||
Content-Type: text/plain
|
||||
|
||||
What is temperature?
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.Azure.Functions.Worker;
|
||||
using Microsoft.Azure.Functions.Worker.Http;
|
||||
using Microsoft.DurableTask;
|
||||
using Microsoft.DurableTask.Client;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace SingleAgent;
|
||||
|
||||
public static class MyOrchFunction
|
||||
{
|
||||
[Function(nameof(MyOrchFunction))]
|
||||
public static async Task<List<string>> RunOrchestratorAsync(
|
||||
[OrchestrationTrigger] TaskOrchestrationContext context)
|
||||
{
|
||||
ILogger logger = context.CreateReplaySafeLogger(nameof(MyOrchFunction));
|
||||
logger.LogInformation("Saying hello.");
|
||||
var outputs = new List<string>();
|
||||
|
||||
// Replace name and input with values relevant for your Durable Functions Activity
|
||||
outputs.Add(await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo"));
|
||||
outputs.Add(await context.CallActivityAsync<string>(nameof(SayHello), "Seattle"));
|
||||
outputs.Add(await context.CallActivityAsync<string>(nameof(SayHello), "London"));
|
||||
|
||||
// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
|
||||
return outputs;
|
||||
}
|
||||
|
||||
[Function(nameof(SayHello))]
|
||||
public static string SayHello([ActivityTrigger] string name,
|
||||
TaskActivityContext taskActivityContext,
|
||||
FunctionContext functionContext)
|
||||
{
|
||||
ILogger logger = functionContext.GetLogger("SayHello");
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
var instanceId = (string)functionContext.BindingContext.BindingData["instanceId"]!;
|
||||
logger.LogInformation("Saying hello to {Name} for instanceId:{InstanceId}", name, instanceId);
|
||||
}
|
||||
return $"Hello {name}!";
|
||||
}
|
||||
|
||||
[Function("MyOrchFunction_HttpStart")]
|
||||
public static async Task<HttpResponseData> HttpStartAsync(
|
||||
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
|
||||
[DurableClient] DurableTaskClient client,
|
||||
FunctionContext executionContext)
|
||||
{
|
||||
ILogger logger = executionContext.GetLogger("MyOrchFunction_HttpStart");
|
||||
|
||||
// Function input comes from the request content.
|
||||
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
|
||||
nameof(MyOrchFunction));
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
logger.LogInformation("Started orchestration with ID = '{InstanceId}'.", instanceId);
|
||||
}
|
||||
|
||||
// Returns an HTTP 202 response with an instance management payload.
|
||||
// See https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-http-api#start-orchestration
|
||||
return await client.CreateCheckStatusResponseAsync(req, instanceId);
|
||||
}
|
||||
}
|
||||
@@ -19,11 +19,5 @@ var workflow = builder.WithName("ProcessOrder").Build();
|
||||
|
||||
FunctionsApplication.CreateBuilder(args)
|
||||
.ConfigureFunctionsWebApplication()
|
||||
.ConfigureDurableOptions(options =>
|
||||
{
|
||||
options.Workflows.AddWorkflow(workflow);
|
||||
|
||||
// Optional - Configure AI agents
|
||||
// options.Agents.AddAIAgent(agent);
|
||||
})
|
||||
.ConfigureDurableOptions(options => options.Workflows.AddWorkflow(workflow))
|
||||
.Build().Run();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net10.0</TargetFrameworks>
|
||||
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
|
||||
@@ -15,7 +15,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="local.settings.json" />
|
||||
<None Include="local.settings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Azure Functions packages -->
|
||||
|
||||
@@ -12,13 +12,15 @@ PaymentProcesserExecutor paymentProcessor = new();
|
||||
NotifyFraudExecutor notifyFraud = new();
|
||||
|
||||
WorkflowBuilder builder = new(orderParser);
|
||||
builder.AddEdge(orderParser, orderEnrich);
|
||||
builder.AddEdge(orderEnrich, notifyFraud, condition: OrderRouteConditions.WhenBlocked());
|
||||
builder.AddEdge(orderEnrich, paymentProcessor, condition: OrderRouteConditions.WhenNotBlocked());
|
||||
builder
|
||||
.AddEdge(orderParser, orderEnrich)
|
||||
.AddEdge(orderEnrich, notifyFraud, condition: OrderRouteConditions.WhenBlocked())
|
||||
.AddEdge(orderEnrich, paymentProcessor, condition: OrderRouteConditions.WhenNotBlocked());
|
||||
|
||||
var workflow = builder.WithName("ProcessOrder").Build();
|
||||
var workflow = builder.WithName("AuditOrder").Build();
|
||||
|
||||
FunctionsApplication.CreateBuilder(args)
|
||||
.ConfigureFunctionsWebApplication()
|
||||
.ConfigureDurableOptions(options => options.Workflows.AddWorkflow(workflow))
|
||||
.Build().Run();
|
||||
.Build()
|
||||
.Run();
|
||||
|
||||
@@ -67,7 +67,7 @@ public sealed class DurableWorkflowOptions
|
||||
/// Adds a collection of workflows to the current instance.
|
||||
/// </summary>
|
||||
/// <param name="workflows">The collection of <see cref="Workflow"/> objects to add. Cannot be <see langword="null"/>.</param>
|
||||
public void AddWorkflow(IEnumerable<Workflow> workflows)
|
||||
public void AddWorkflows(IEnumerable<Workflow> workflows)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(workflows);
|
||||
|
||||
|
||||
@@ -103,37 +103,37 @@ internal static partial class Logs
|
||||
|
||||
[LoggerMessage(
|
||||
EventId = 12,
|
||||
Level = LogLevel.Information,
|
||||
Level = LogLevel.Debug,
|
||||
Message = "Attempting to run workflow: {WorkflowName}")]
|
||||
public static partial void LogAttemptingToRunWorkflow(this ILogger logger, string workflowName);
|
||||
|
||||
[LoggerMessage(
|
||||
EventId = 13,
|
||||
Level = LogLevel.Information,
|
||||
Level = LogLevel.Debug,
|
||||
Message = "Running workflow: {WorkflowName}")]
|
||||
public static partial void LogRunningWorkflow(this ILogger logger, string? workflowName);
|
||||
|
||||
[LoggerMessage(
|
||||
EventId = 14,
|
||||
Level = LogLevel.Information,
|
||||
Level = LogLevel.Debug,
|
||||
Message = "Attempting to execute activity in workflow '{WorkflowName}' for executor '{ExecutorName}'")]
|
||||
public static partial void LogAttemptingToExecuteActivity(this ILogger logger, string workflowName, string executorName);
|
||||
|
||||
[LoggerMessage(
|
||||
EventId = 15,
|
||||
Level = LogLevel.Information,
|
||||
Level = LogLevel.Debug,
|
||||
Message = "Executing activity for executor '{ExecutorId}' of type '{ExecutorType}'")]
|
||||
public static partial void LogExecutingActivity(this ILogger logger, string executorId, string executorType);
|
||||
|
||||
[LoggerMessage(
|
||||
EventId = 16,
|
||||
Level = LogLevel.Information,
|
||||
Level = LogLevel.Debug,
|
||||
Message = "Activity executed for executor '{ExecutorId}' with result: {Result}")]
|
||||
public static partial void LogActivityExecuted(this ILogger logger, string executorId, string result);
|
||||
|
||||
[LoggerMessage(
|
||||
EventId = 17,
|
||||
Level = LogLevel.Information,
|
||||
Level = LogLevel.Debug,
|
||||
Message = "Executor '{ExecutorId}' skipped due to edge condition evaluation")]
|
||||
public static partial void LogExecutorSkipped(this ILogger logger, string executorId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user