mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: Remove sequential\concurrent workflow extensions (#1731)
* remove non-standard workflow extensions, create overloads for IHostedAgentBuilder * rework * rollback extensions in a2a
This commit is contained in:
committed by
GitHub
Unverified
parent
e5d9d74c2d
commit
b7cddaaba8
@@ -78,8 +78,19 @@ var literatureAgent = builder.AddAIAgent("literator",
|
||||
description: "An agent that helps with literature.",
|
||||
chatClientServiceKey: "chat-model");
|
||||
|
||||
builder.AddSequentialWorkflow("science-sequential-workflow", [chemistryAgent, mathsAgent, literatureAgent]).AddAsAIAgent();
|
||||
builder.AddConcurrentWorkflow("science-concurrent-workflow", [chemistryAgent, mathsAgent, literatureAgent]).AddAsAIAgent();
|
||||
var scienceSequentialWorkflow = builder.AddWorkflow("science-sequential-workflow", (sp, key) =>
|
||||
{
|
||||
List<IHostedAgentBuilder> usedAgents = [chemistryAgent, mathsAgent, literatureAgent];
|
||||
var agents = usedAgents.Select(ab => sp.GetRequiredKeyedService<AIAgent>(ab.Name));
|
||||
return AgentWorkflowBuilder.BuildSequential(workflowName: key, agents: agents);
|
||||
}).AddAsAIAgent();
|
||||
|
||||
var scienceConcurrentWorkflow = builder.AddWorkflow("science-concurrent-workflow", (sp, key) =>
|
||||
{
|
||||
List<IHostedAgentBuilder> usedAgents = [chemistryAgent, mathsAgent, literatureAgent];
|
||||
var agents = usedAgents.Select(ab => sp.GetRequiredKeyedService<AIAgent>(ab.Name));
|
||||
return AgentWorkflowBuilder.BuildConcurrent(workflowName: key, agents: agents);
|
||||
}).AddAsAIAgent();
|
||||
|
||||
builder.AddOpenAIChatCompletions();
|
||||
builder.AddOpenAIResponses();
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
|
||||
using Azure.AI.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Agents.AI.DevUI;
|
||||
using Microsoft.Agents.AI.Hosting;
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace DevUI_Step01_BasicUsage;
|
||||
@@ -56,10 +58,11 @@ internal static class Program
|
||||
// Register sample workflows
|
||||
var assistantBuilder = builder.AddAIAgent("workflow-assistant", "You are a helpful assistant in a workflow.");
|
||||
var reviewerBuilder = builder.AddAIAgent("workflow-reviewer", "You are a reviewer. Review and critique the previous response.");
|
||||
builder.AddSequentialWorkflow(
|
||||
"review-workflow",
|
||||
[assistantBuilder, reviewerBuilder])
|
||||
.AddAsAIAgent();
|
||||
builder.AddWorkflow("review-workflow", (sp, key) =>
|
||||
{
|
||||
var agents = new List<IHostedAgentBuilder>() { assistantBuilder, reviewerBuilder }.Select(ab => sp.GetRequiredKeyedService<AIAgent>(ab.Name));
|
||||
return AgentWorkflowBuilder.BuildSequential(workflowName: key, agents: agents);
|
||||
}).AddAsAIAgent();
|
||||
|
||||
if (builder.Environment.IsDevelopment())
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Agents.AI.Hosting.Local;
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
@@ -16,46 +15,6 @@ namespace Microsoft.Agents.AI.Hosting;
|
||||
/// </summary>
|
||||
public static class HostApplicationBuilderWorkflowExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a concurrent workflow that executes multiple agents in parallel.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IHostApplicationBuilder"/> to configure.</param>
|
||||
/// <param name="name">The unique name for the workflow.</param>
|
||||
/// <param name="agentBuilders">A collection of <see cref="IHostedAgentBuilder"/> instances representing agents to execute concurrently.</param>
|
||||
/// <returns>An <see cref="IHostedWorkflowBuilder"/> that can be used to further configure the workflow.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="builder"/>, <paramref name="name"/>, or <paramref name="agentBuilders"/> is null.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown when <paramref name="name"/> or <paramref name="agentBuilders"/> is empty.</exception>
|
||||
public static IHostedWorkflowBuilder AddConcurrentWorkflow(this IHostApplicationBuilder builder, string name, IEnumerable<IHostedAgentBuilder> agentBuilders)
|
||||
{
|
||||
Throw.IfNullOrEmpty(agentBuilders);
|
||||
|
||||
return builder.AddWorkflow(name, (sp, key) =>
|
||||
{
|
||||
var agents = agentBuilders.Select(ab => sp.GetRequiredKeyedService<AIAgent>(ab.Name));
|
||||
return AgentWorkflowBuilder.BuildConcurrent(workflowName: name, agents: agents);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a sequential workflow that executes agents in a specific order.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IHostApplicationBuilder"/> to configure.</param>
|
||||
/// <param name="name">The unique name for the workflow.</param>
|
||||
/// <param name="agentBuilders">A collection of <see cref="IHostedAgentBuilder"/> instances representing agents to execute in sequence.</param>
|
||||
/// <returns>An <see cref="IHostedWorkflowBuilder"/> that can be used to further configure the workflow.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="builder"/>, <paramref name="name"/>, or <paramref name="agentBuilders"/> is null.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown when <paramref name="name"/> or <paramref name="agentBuilders"/> is empty.</exception>
|
||||
public static IHostedWorkflowBuilder AddSequentialWorkflow(this IHostApplicationBuilder builder, string name, IEnumerable<IHostedAgentBuilder> agentBuilders)
|
||||
{
|
||||
Throw.IfNullOrEmpty(agentBuilders);
|
||||
|
||||
return builder.AddWorkflow(name, (sp, key) =>
|
||||
{
|
||||
var agents = agentBuilders.Select(ab => sp.GetRequiredKeyedService<AIAgent>(ab.Name));
|
||||
return AgentWorkflowBuilder.BuildSequential(workflowName: name, agents: agents);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a custom workflow using a factory delegate.
|
||||
/// </summary>
|
||||
|
||||
-96
@@ -137,102 +137,6 @@ public class HostApplicationBuilderWorkflowExtensionsTests
|
||||
Assert.NotNull(descriptor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that providing a null builder to AddConcurrentWorkflow throws an ArgumentNullException.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void AddConcurrentWorkflow_NullBuilder_ThrowsArgumentNullException()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() =>
|
||||
HostApplicationBuilderWorkflowExtensions.AddConcurrentWorkflow(null!, "workflow", [null!]));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that AddConcurrentWorkflow throws ArgumentNullException for null name.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void AddConcurrentWorkflow_NullName_ThrowsArgumentNullException()
|
||||
{
|
||||
var builder = new HostApplicationBuilder();
|
||||
|
||||
var exception = Assert.Throws<ArgumentNullException>(() =>
|
||||
builder.AddConcurrentWorkflow(null!, [new HostedAgentBuilder("test", builder)]));
|
||||
Assert.Equal("name", exception.ParamName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that AddConcurrentWorkflow throws ArgumentNullException for null agent builders.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void AddConcurrentWorkflow_NullAgentBuilders_ThrowsArgumentNullException()
|
||||
{
|
||||
var builder = new HostApplicationBuilder();
|
||||
|
||||
var exception = Assert.Throws<ArgumentNullException>(() =>
|
||||
builder.AddConcurrentWorkflow("workflowName", null!));
|
||||
Assert.Equal("agentBuilders", exception.ParamName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that AddConcurrentWorkflow returns IHostWorkflowBuilder instance.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void AddConcurrentWorkflow_ValidParameters_ReturnsBuilder()
|
||||
{
|
||||
var builder = new HostApplicationBuilder();
|
||||
|
||||
var result = builder.AddConcurrentWorkflow("concurrentWorkflow", [new HostedAgentBuilder("test", builder)]);
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.IsAssignableFrom<IHostedWorkflowBuilder>(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that providing a null builder to AddSequentialWorkflow throws an ArgumentNullException.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void AddSequentialWorkflow_NullBuilder_ThrowsArgumentNullException()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() =>
|
||||
HostApplicationBuilderWorkflowExtensions.AddSequentialWorkflow(null!, "workflow", [null!]));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that AddSequentialWorkflow throws ArgumentNullException for null name.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void AddSequentialWorkflow_NullName_ThrowsArgumentNullException()
|
||||
{
|
||||
var builder = new HostApplicationBuilder();
|
||||
|
||||
var exception = Assert.Throws<ArgumentNullException>(() =>
|
||||
builder.AddSequentialWorkflow(null!, [new HostedAgentBuilder("test", builder)]));
|
||||
Assert.Equal("name", exception.ParamName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that AddSequentialWorkflow throws ArgumentNullException for null agent builders.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void AddSequentialWorkflow_NullAgentBuilders_ThrowsArgumentNullException()
|
||||
{
|
||||
var builder = new HostApplicationBuilder();
|
||||
|
||||
var exception = Assert.Throws<ArgumentNullException>(() =>
|
||||
builder.AddSequentialWorkflow("workflowName", null!));
|
||||
Assert.Equal("agentBuilders", exception.ParamName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddSequentialWorkflow_EmptyAgentBuilders_Throws()
|
||||
{
|
||||
var builder = new HostApplicationBuilder();
|
||||
|
||||
var exception = Assert.Throws<ArgumentException>(() =>
|
||||
builder.AddSequentialWorkflow("sequentialWorkflow", Array.Empty<IHostedAgentBuilder>()));
|
||||
Assert.Equal("agentBuilders", exception.ParamName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that AddAsAIAgent without a name parameter uses the workflow name as the agent name.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user