From e00e63ffb18b2b14d45992beafda0b35a7062051 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Fri, 15 Nov 2024 13:43:50 -0800 Subject: [PATCH 1/5] add happy path test --- .../Hello/HelloAgent/HelloAgent.csproj | 3 +- dotnet/samples/Hello/HelloAgent/Program.cs | 97 ++++++++++--------- .../dev-team/DevTeam.AgentHost/Program.cs | 2 +- .../dev-team/DevTeam.Agents/Program.cs | 2 +- .../dev-team/DevTeam.Backend/Program.cs | 2 +- dotnet/src/Microsoft.AutoGen/Agents/App.cs | 5 +- .../Services/AgentWorkerHostingExtensions.cs | 25 +---- .../Microsoft.AutoGen/Agents/Services/Host.cs | 2 +- .../Agents/Services/HostBuilderExtensions.cs | 22 ++++- .../Orleans/OrleansRuntimeHostingExtenions.cs | 28 +++--- .../Extensions/ServiceDefaults/Extensions.cs | 11 ++- .../AgentBaseTests.cs | 91 ++++++++++++++++- .../Microsoft.AutoGen.Agents.Tests.csproj | 1 + protos/agent_events.proto | 5 +- 14 files changed, 198 insertions(+), 98 deletions(-) diff --git a/dotnet/samples/Hello/HelloAgent/HelloAgent.csproj b/dotnet/samples/Hello/HelloAgent/HelloAgent.csproj index f2f3e473fef..88893ccc874 100644 --- a/dotnet/samples/Hello/HelloAgent/HelloAgent.csproj +++ b/dotnet/samples/Hello/HelloAgent/HelloAgent.csproj @@ -1,4 +1,4 @@ - + Exe net8.0 @@ -8,7 +8,6 @@ - diff --git a/dotnet/samples/Hello/HelloAgent/Program.cs b/dotnet/samples/Hello/HelloAgent/Program.cs index 506d9150232..7575adb74ad 100644 --- a/dotnet/samples/Hello/HelloAgent/Program.cs +++ b/dotnet/samples/Hello/HelloAgent/Program.cs @@ -5,69 +5,72 @@ using Microsoft.AutoGen.Agents; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Host = Microsoft.Extensions.Hosting.Host; -// step 1: create in-memory agent runtime +var builder = Host.CreateApplicationBuilder(); +// step 1: create in-memory agent runtime // step 2: register HelloAgent to that agent runtime +builder + .AddAgentService(local: true, useGrpc: false) + .AddAgentWorker(local: true) + .AddAgent("HelloAgent"); -// step 3: start the agent runtime - -// step 4: send a message to the agent +// step 3: wait for the agent runtime to shutdown +var app = builder.Build(); +await app.StartAsync(); -// step 5: wait for the agent runtime to shutdown -var app = await AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived +var client = app.Services.GetRequiredService(); +await client.PublishEventAsync("HelloAgents", new NewMessageReceived { Message = "World" -}, local: true); +}, new CancellationToken()); await app.WaitForShutdownAsync(); -namespace Hello +[TopicSubscription("HelloAgents")] +public class HelloAgent( + IAgentRuntime context, IHostApplicationLifetime hostApplicationLifetime, + [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : AgentBase( + context, + typeRegistry), + ISayHello, + IHandleConsole, + IHandle, + IHandle { - [TopicSubscription("HelloAgents")] - public class HelloAgent( - IAgentRuntime context, IHostApplicationLifetime hostApplicationLifetime, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : AgentBase( - context, - typeRegistry), - ISayHello, - IHandleConsole, - IHandle, - IHandle + public async Task Handle(NewMessageReceived item) { - public async Task Handle(NewMessageReceived item) + var response = await SayHello(item.Message); + var evt = new Output { Message = response }; + await PublishMessageAsync(evt); + var goodbye = new ConversationClosed { - var response = await SayHello(item.Message).ConfigureAwait(false); - var evt = new Output { Message = response }; - await PublishMessageAsync(evt).ConfigureAwait(false); - var goodbye = new ConversationClosed - { - UserId = this.AgentId.Key, - UserMessage = "Goodbye" - }; - await PublishMessageAsync(goodbye).ConfigureAwait(false); - } - public async Task Handle(ConversationClosed item) + UserId = this.AgentId.Key, + UserMessage = "Goodbye" + }; + await PublishMessageAsync(goodbye); + } + public async Task Handle(ConversationClosed item) + { + var goodbye = $"********************* {item.UserId} said {item.UserMessage} ************************"; + var evt = new Output { - var goodbye = $"********************* {item.UserId} said {item.UserMessage} ************************"; - var evt = new Output - { - Message = goodbye - }; - await PublishMessageAsync(evt).ConfigureAwait(false); + Message = goodbye + }; + await PublishMessageAsync(evt); - // Signal shutdown. - hostApplicationLifetime.StopApplication(); - } - - public async Task SayHello(string ask) - { - var response = $"\n\n\n\n***************Hello {ask}**********************\n\n\n\n"; - return response; - } + // Signal shutdown. + hostApplicationLifetime.StopApplication(); } - public interface ISayHello + + public async Task SayHello(string ask) { - public Task SayHello(string ask); + var response = $"\n\n\n\n***************Hello {ask}**********************\n\n\n\n"; + return response; } } +public interface ISayHello +{ + public Task SayHello(string ask); +} diff --git a/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs b/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs index 6480e72a0b4..2f513ec20f7 100644 --- a/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs +++ b/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs @@ -4,7 +4,7 @@ using Microsoft.AutoGen.Agents; var builder = WebApplication.CreateBuilder(args); -builder.AddServiceDefaults(); +builder.AddAutoGenServices(); builder.AddAgentService(); var app = builder.Build(); diff --git a/dotnet/samples/dev-team/DevTeam.Agents/Program.cs b/dotnet/samples/dev-team/DevTeam.Agents/Program.cs index 6d993788949..7e6bdec7ce7 100644 --- a/dotnet/samples/dev-team/DevTeam.Agents/Program.cs +++ b/dotnet/samples/dev-team/DevTeam.Agents/Program.cs @@ -7,7 +7,7 @@ var builder = WebApplication.CreateBuilder(args); -builder.AddServiceDefaults(); +builder.AddAutoGenServices(); builder.ConfigureSemanticKernel(); diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Program.cs b/dotnet/samples/dev-team/DevTeam.Backend/Program.cs index b24476692d0..adcb5b348ba 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Program.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Program.cs @@ -14,7 +14,7 @@ var builder = WebApplication.CreateBuilder(args); -builder.AddServiceDefaults(); +builder.AddAutoGenServices(); builder.ConfigureSemanticKernel(); builder.Services.AddHttpClient(); diff --git a/dotnet/src/Microsoft.AutoGen/Agents/App.cs b/dotnet/src/Microsoft.AutoGen/Agents/App.cs index fc36d336779..ea2380f116a 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/App.cs @@ -12,6 +12,7 @@ public static class AgentsApp { // need a variable to store the runtime instance public static WebApplication? Host { get; private set; } + [MemberNotNull(nameof(Host))] public static async ValueTask StartAsync(WebApplicationBuilder? builder = null, AgentTypes? agentTypes = null, bool local = false) { @@ -23,7 +24,7 @@ public static async ValueTask StartAsync(WebApplicationBuilder? } builder.AddAgentWorker(local: local) .AddAgents(agentTypes); - builder.AddServiceDefaults(); + builder.AddAutoGenServices(); var app = builder.Build(); if (local) { @@ -58,7 +59,7 @@ public static async ValueTask ShutdownAsync() await Host.StopAsync(); } - private static AgentApplicationBuilder AddAgents(this AgentApplicationBuilder builder, AgentTypes? agentTypes) + private static IHostApplicationBuilder AddAgents(this IHostApplicationBuilder builder, AgentTypes? agentTypes) { agentTypes ??= AgentTypes.GetAgentTypesFromAssembly() ?? throw new InvalidOperationException("No agent types found in the assembly"); diff --git a/dotnet/src/Microsoft.AutoGen/Agents/Services/AgentWorkerHostingExtensions.cs b/dotnet/src/Microsoft.AutoGen/Agents/Services/AgentWorkerHostingExtensions.cs index 8215f203276..3736fc76cb6 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/Services/AgentWorkerHostingExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/Services/AgentWorkerHostingExtensions.cs @@ -3,8 +3,6 @@ using System.Diagnostics; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; @@ -13,25 +11,9 @@ namespace Microsoft.AutoGen.Agents; public static class AgentWorkerHostingExtensions { - public static WebApplicationBuilder AddAgentService(this WebApplicationBuilder builder, bool local = false, bool useGrpc = true) + public static IHostApplicationBuilder AddAgentService(this IHostApplicationBuilder builder, bool local = false, bool useGrpc = true) { - if (local) - { - //TODO: make configuration more flexible - builder.WebHost.ConfigureKestrel(serverOptions => - { - serverOptions.ListenLocalhost(5001, listenOptions => - { - listenOptions.Protocols = HttpProtocols.Http2; - listenOptions.UseHttps(); - }); - }); - builder.AddOrleans(local); - } - else - { - builder.AddOrleans(); - } + builder.AddOrleans(local); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); @@ -45,10 +27,11 @@ public static WebApplicationBuilder AddAgentService(this WebApplicationBuilder b return builder; } - public static WebApplicationBuilder AddLocalAgentService(this WebApplicationBuilder builder, bool useGrpc = true) + public static IHostApplicationBuilder AddLocalAgentService(this IHostApplicationBuilder builder, bool useGrpc = true) { return builder.AddAgentService(local: true, useGrpc); } + public static WebApplication MapAgentService(this WebApplication app, bool local = false, bool useGrpc = true) { if (useGrpc) { app.MapGrpcService(); } diff --git a/dotnet/src/Microsoft.AutoGen/Agents/Services/Host.cs b/dotnet/src/Microsoft.AutoGen/Agents/Services/Host.cs index 5b725af0c9a..58cb921aea1 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/Services/Host.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/Services/Host.cs @@ -11,7 +11,7 @@ public static class Host public static async Task StartAsync(bool local = false, bool useGrpc = true) { var builder = WebApplication.CreateBuilder(); - builder.AddServiceDefaults(); + builder.AddAutoGenServices(); if (local) { builder.AddLocalAgentService(useGrpc); diff --git a/dotnet/src/Microsoft.AutoGen/Agents/Services/HostBuilderExtensions.cs b/dotnet/src/Microsoft.AutoGen/Agents/Services/HostBuilderExtensions.cs index 8ded5cb03d2..f020f0bb667 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/Services/HostBuilderExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/Services/HostBuilderExtensions.cs @@ -16,7 +16,23 @@ namespace Microsoft.AutoGen.Agents; public static class HostBuilderExtensions { private const string _defaultAgentServiceAddress = "https://localhost:5001"; - public static AgentApplicationBuilder AddAgentWorker(this IHostApplicationBuilder builder, string agentServiceAddress = _defaultAgentServiceAddress, bool local = false) + + public static IHostApplicationBuilder AddAgent< + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TAgent>(this IHostApplicationBuilder builder, string typeName) where TAgent : AgentBase + { + builder.Services.AddKeyedSingleton("AgentTypes", (sp, key) => Tuple.Create(typeName, typeof(TAgent))); + + return builder; + } + + public static IHostApplicationBuilder AddAgent(this IHostApplicationBuilder builder, string typeName, Type agentType) + { + builder.Services.AddKeyedSingleton("AgentTypes", (sp, key) => Tuple.Create(typeName, agentType)); + + return builder; + } + + public static IHostApplicationBuilder AddAgentWorker(this IHostApplicationBuilder builder, string agentServiceAddress = _defaultAgentServiceAddress, bool local = false) { builder.Services.TryAddSingleton(DistributedContextPropagator.Current); @@ -98,7 +114,9 @@ public static AgentApplicationBuilder AddAgentWorker(this IHostApplicationBuilde return new EventTypes(typeRegistry, types, eventsMap); }); builder.Services.AddSingleton(); - return new AgentApplicationBuilder(builder); + builder.Services.AddSingleton(new AgentApplicationBuilder(builder)); + + return builder; } private static MessageDescriptor? GetMessageDescriptor(Type type) diff --git a/dotnet/src/Microsoft.AutoGen/Agents/Services/Orleans/OrleansRuntimeHostingExtenions.cs b/dotnet/src/Microsoft.AutoGen/Agents/Services/Orleans/OrleansRuntimeHostingExtenions.cs index cd59bcefc38..374e49f7a50 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/Services/Orleans/OrleansRuntimeHostingExtenions.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/Services/Orleans/OrleansRuntimeHostingExtenions.cs @@ -15,11 +15,17 @@ public static class OrleansRuntimeHostingExtenions { public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builder, bool local = false) { + return builder.AddOrleans(local); + } + public static IHostApplicationBuilder AddOrleans(this IHostApplicationBuilder builder, bool local = false) + { builder.Services.AddSerializer(serializer => serializer.AddProtobufSerializer()); + builder.Services.AddSingleton(); + // Ensure Orleans is added before the hosted service to guarantee that it starts first. //TODO: make all of this configurable - builder.Host.UseOrleans(siloBuilder => + builder.UseOrleans((siloBuilder) => { // Development mode or local mode uses in-memory storage and streams if (builder.Environment.IsDevelopment() || local) @@ -51,16 +57,16 @@ public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builde options.SystemResponseTimeout = TimeSpan.FromMinutes(3); }); siloBuilder.Configure(options => - { - options.ResponseTimeout = TimeSpan.FromMinutes(3); - }); + { + options.ResponseTimeout = TimeSpan.FromMinutes(3); + }); siloBuilder.UseCosmosClustering(o => - { - o.ConfigureCosmosClient(cosmosDbconnectionString); - o.ContainerName = "AutoGen"; - o.DatabaseName = "clustering"; - o.IsResourceCreationEnabled = true; - }); + { + o.ConfigureCosmosClient(cosmosDbconnectionString); + o.ContainerName = "AutoGen"; + o.DatabaseName = "clustering"; + o.IsResourceCreationEnabled = true; + }); siloBuilder.UseCosmosReminderService(o => { @@ -84,7 +90,7 @@ public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builde .AddMemoryGrainStorage("PubSubStore"); } }); - builder.Services.AddSingleton(); + return builder; } } diff --git a/dotnet/src/Microsoft.AutoGen/Extensions/ServiceDefaults/Extensions.cs b/dotnet/src/Microsoft.AutoGen/Extensions/ServiceDefaults/Extensions.cs index a4eccacb7fd..310366bede7 100644 --- a/dotnet/src/Microsoft.AutoGen/Extensions/ServiceDefaults/Extensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Extensions/ServiceDefaults/Extensions.cs @@ -17,9 +17,9 @@ namespace Microsoft.Extensions.Hosting; // To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults public static class Extensions { - public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder) + public static IHostApplicationBuilder AddAutoGenServices(this IHostApplicationBuilder builder) { - builder.ConfigureOpenTelemetry(); + builder.ConfigureOpenTelemetryForAutoGen(); builder.AddDefaultHealthChecks(); @@ -41,7 +41,7 @@ public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBu // }); return builder; } - public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder) + public static IHostApplicationBuilder ConfigureOpenTelemetryForAutoGen(this IHostApplicationBuilder builder) { builder.Logging.AddOpenTelemetry(logging => { @@ -66,11 +66,11 @@ public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicati .AddSource("AutoGen.Agent"); }); - builder.AddOpenTelemetryExporters(); + builder.AddOpenTelemetryExportersForAutoGen(); return builder; } - private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder) + private static IHostApplicationBuilder AddOpenTelemetryExportersForAutoGen(this IHostApplicationBuilder builder) { var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); @@ -94,6 +94,7 @@ public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicati .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]); return builder; } + public static WebApplication MapDefaultEndpoints(this WebApplication app) { // Adding health checks endpoints to applications in non-development environments has security implications. diff --git a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs b/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs index b10f82e7d43..66bb8301a27 100644 --- a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs @@ -1,17 +1,25 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // AgentBaseTests.cs +using System.Collections.Concurrent; using FluentAssertions; using Google.Protobuf.Reflection; using Microsoft.AutoGen.Abstractions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Moq; +using Orleans.TestingHost; using Xunit; +using static Microsoft.AutoGen.Agents.Tests.AgentBaseTests; namespace Microsoft.AutoGen.Agents.Tests; -public class AgentBaseTests +[Collection(ClusterFixtureCollection.Name)] +public class AgentBaseTests(InMemoryAgentRuntimeFixture fixture) { + private readonly InMemoryAgentRuntimeFixture _fixture = fixture; + [Fact] public async Task ItInvokeRightHandlerTestAsync() { @@ -26,12 +34,37 @@ public async Task ItInvokeRightHandlerTestAsync() agent.ReceivedItems[1].Should().Be(42); } + [Fact] + public async Task ItDelegateMessageToTestAgentAsync() + { + var client = _fixture.AppHost.Services.GetRequiredService(); + + await client.PublishMessageAsync(new TextMessage() + { + Source = nameof(ItDelegateMessageToTestAgentAsync), + TextMessage_ = "buffer" + }, token: CancellationToken.None); + + // wait for 10 seconds + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); + while (!TestAgent.ReceivedMessages.ContainsKey(nameof(ItDelegateMessageToTestAgentAsync)) && !cts.Token.IsCancellationRequested) + { + await Task.Delay(100); + } + + TestAgent.ReceivedMessages[nameof(ItDelegateMessageToTestAgentAsync)].Should().NotBeNull(); + } + /// /// The test agent is a simple agent that is used for testing purposes. /// - public class TestAgent : AgentBase, IHandle, IHandle + [TopicSubscription(nameof(AgentBaseTests.ItDelegateMessageToTestAgentAsync))] + public class TestAgent : AgentBase, IHandle, IHandle, IHandle { - public TestAgent(IAgentRuntime context, EventTypes eventTypes, Logger logger) : base(context, eventTypes, logger) + public TestAgent( + IAgentRuntime context, + [FromKeyedServices("EventTypes")] EventTypes eventTypes, + Logger? logger = null) : base(context, eventTypes, logger) { } @@ -47,6 +80,58 @@ public Task Handle(int item) return Task.CompletedTask; } + public Task Handle(TextMessage item) + { + ReceivedMessages[item.Source] = item.TextMessage_; + return Task.CompletedTask; + } + public List ReceivedItems { get; private set; } = []; + + /// + /// Key: source + /// Value: message + /// + public static ConcurrentDictionary ReceivedMessages { get; private set; } = new(); + } +} + +public sealed class InMemoryAgentRuntimeFixture : IDisposable +{ + public InMemoryAgentRuntimeFixture() + { + var builder = Microsoft.Extensions.Hosting.Host.CreateApplicationBuilder(); + + // step 1: create in-memory agent runtime + // step 2: register TestAgent to that agent runtime + builder + .AddAgentService(local: true, useGrpc: false) + .AddAgentWorker(local: true) + .AddAgent(nameof(TestAgent)); + + AppHost = builder.Build(); + AppHost.StartAsync().Wait(); + } + public IHost AppHost { get; } + + void IDisposable.Dispose() + { + AppHost.StopAsync().Wait(); + AppHost.Dispose(); + } +} + +[CollectionDefinition(Name)] +public sealed class ClusterFixtureCollection : ICollectionFixture +{ + public const string Name = nameof(ClusterFixtureCollection); +} + +public sealed class TestSiloConfigurator : ISiloConfigurator +{ + public void Configure(ISiloBuilder hostBuilder) + { + hostBuilder + .AddMemoryGrainStorage("PubSubStore"); } } diff --git a/dotnet/test/Microsoft.AutoGen.Agents.Tests/Microsoft.AutoGen.Agents.Tests.csproj b/dotnet/test/Microsoft.AutoGen.Agents.Tests/Microsoft.AutoGen.Agents.Tests.csproj index db7467bf123..4abf1dc834d 100644 --- a/dotnet/test/Microsoft.AutoGen.Agents.Tests/Microsoft.AutoGen.Agents.Tests.csproj +++ b/dotnet/test/Microsoft.AutoGen.Agents.Tests/Microsoft.AutoGen.Agents.Tests.csproj @@ -9,6 +9,7 @@ + diff --git a/protos/agent_events.proto b/protos/agent_events.proto index 811c888c642..5fd88bf8c44 100644 --- a/protos/agent_events.proto +++ b/protos/agent_events.proto @@ -3,7 +3,10 @@ syntax = "proto3"; package agents; option csharp_namespace = "Microsoft.AutoGen.Abstractions"; - +message TextMessage { + string textMessage = 1; + string source = 2; +} message Input { string message = 1; } From 2f3cf0dc1aa4b8bb6ac5a3a954951ac6c8613be0 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Fri, 15 Nov 2024 13:49:19 -0800 Subject: [PATCH 2/5] remove unnecessary namespace --- dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs b/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs index 66bb8301a27..a03b17993ec 100644 --- a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs @@ -9,7 +9,6 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Moq; -using Orleans.TestingHost; using Xunit; using static Microsoft.AutoGen.Agents.Tests.AgentBaseTests; From f7be0fcb560be10dbb8e7f2c5bc6578835413cfe Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Fri, 15 Nov 2024 13:50:15 -0800 Subject: [PATCH 3/5] fix build error --- .../Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs b/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs index a03b17993ec..a349705fb8f 100644 --- a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs @@ -125,12 +125,3 @@ public sealed class ClusterFixtureCollection : ICollectionFixture Date: Fri, 15 Nov 2024 13:52:56 -0800 Subject: [PATCH 4/5] Update AgentBaseTests.cs --- dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs b/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs index a349705fb8f..e58fdb00f0a 100644 --- a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentBaseTests.cs @@ -57,7 +57,6 @@ await client.PublishMessageAsync(new TextMessage() /// /// The test agent is a simple agent that is used for testing purposes. /// - [TopicSubscription(nameof(AgentBaseTests.ItDelegateMessageToTestAgentAsync))] public class TestAgent : AgentBase, IHandle, IHandle, IHandle { public TestAgent( From ce0778ac70b6ddcdc6a484b78e28c1231188e296 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Mon, 18 Nov 2024 10:22:52 -0800 Subject: [PATCH 5/5] revert changes --- dotnet/samples/Hello/HelloAgent/Program.cs | 97 +++++++++---------- .../dev-team/DevTeam.AgentHost/Program.cs | 2 +- .../dev-team/DevTeam.Agents/Program.cs | 2 +- .../dev-team/DevTeam.Backend/Program.cs | 2 +- dotnet/src/Microsoft.AutoGen/Agents/App.cs | 2 +- .../Microsoft.AutoGen/Agents/Services/Host.cs | 2 +- .../Extensions/ServiceDefaults/Extensions.cs | 11 +-- 7 files changed, 57 insertions(+), 61 deletions(-) diff --git a/dotnet/samples/Hello/HelloAgent/Program.cs b/dotnet/samples/Hello/HelloAgent/Program.cs index 7575adb74ad..506d9150232 100644 --- a/dotnet/samples/Hello/HelloAgent/Program.cs +++ b/dotnet/samples/Hello/HelloAgent/Program.cs @@ -5,72 +5,69 @@ using Microsoft.AutoGen.Agents; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Host = Microsoft.Extensions.Hosting.Host; - -var builder = Host.CreateApplicationBuilder(); // step 1: create in-memory agent runtime + // step 2: register HelloAgent to that agent runtime -builder - .AddAgentService(local: true, useGrpc: false) - .AddAgentWorker(local: true) - .AddAgent("HelloAgent"); -// step 3: wait for the agent runtime to shutdown -var app = builder.Build(); -await app.StartAsync(); +// step 3: start the agent runtime + +// step 4: send a message to the agent -var client = app.Services.GetRequiredService(); -await client.PublishEventAsync("HelloAgents", new NewMessageReceived +// step 5: wait for the agent runtime to shutdown +var app = await AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived { Message = "World" -}, new CancellationToken()); +}, local: true); await app.WaitForShutdownAsync(); -[TopicSubscription("HelloAgents")] -public class HelloAgent( - IAgentRuntime context, IHostApplicationLifetime hostApplicationLifetime, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : AgentBase( - context, - typeRegistry), - ISayHello, - IHandleConsole, - IHandle, - IHandle +namespace Hello { - public async Task Handle(NewMessageReceived item) + [TopicSubscription("HelloAgents")] + public class HelloAgent( + IAgentRuntime context, IHostApplicationLifetime hostApplicationLifetime, + [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : AgentBase( + context, + typeRegistry), + ISayHello, + IHandleConsole, + IHandle, + IHandle { - var response = await SayHello(item.Message); - var evt = new Output { Message = response }; - await PublishMessageAsync(evt); - var goodbye = new ConversationClosed + public async Task Handle(NewMessageReceived item) { - UserId = this.AgentId.Key, - UserMessage = "Goodbye" - }; - await PublishMessageAsync(goodbye); - } - public async Task Handle(ConversationClosed item) - { - var goodbye = $"********************* {item.UserId} said {item.UserMessage} ************************"; - var evt = new Output + var response = await SayHello(item.Message).ConfigureAwait(false); + var evt = new Output { Message = response }; + await PublishMessageAsync(evt).ConfigureAwait(false); + var goodbye = new ConversationClosed + { + UserId = this.AgentId.Key, + UserMessage = "Goodbye" + }; + await PublishMessageAsync(goodbye).ConfigureAwait(false); + } + public async Task Handle(ConversationClosed item) { - Message = goodbye - }; - await PublishMessageAsync(evt); + var goodbye = $"********************* {item.UserId} said {item.UserMessage} ************************"; + var evt = new Output + { + Message = goodbye + }; + await PublishMessageAsync(evt).ConfigureAwait(false); - // Signal shutdown. - hostApplicationLifetime.StopApplication(); - } + // Signal shutdown. + hostApplicationLifetime.StopApplication(); + } - public async Task SayHello(string ask) + public async Task SayHello(string ask) + { + var response = $"\n\n\n\n***************Hello {ask}**********************\n\n\n\n"; + return response; + } + } + public interface ISayHello { - var response = $"\n\n\n\n***************Hello {ask}**********************\n\n\n\n"; - return response; + public Task SayHello(string ask); } } -public interface ISayHello -{ - public Task SayHello(string ask); -} diff --git a/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs b/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs index 2f513ec20f7..6480e72a0b4 100644 --- a/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs +++ b/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs @@ -4,7 +4,7 @@ using Microsoft.AutoGen.Agents; var builder = WebApplication.CreateBuilder(args); -builder.AddAutoGenServices(); +builder.AddServiceDefaults(); builder.AddAgentService(); var app = builder.Build(); diff --git a/dotnet/samples/dev-team/DevTeam.Agents/Program.cs b/dotnet/samples/dev-team/DevTeam.Agents/Program.cs index 7e6bdec7ce7..6d993788949 100644 --- a/dotnet/samples/dev-team/DevTeam.Agents/Program.cs +++ b/dotnet/samples/dev-team/DevTeam.Agents/Program.cs @@ -7,7 +7,7 @@ var builder = WebApplication.CreateBuilder(args); -builder.AddAutoGenServices(); +builder.AddServiceDefaults(); builder.ConfigureSemanticKernel(); diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Program.cs b/dotnet/samples/dev-team/DevTeam.Backend/Program.cs index adcb5b348ba..b24476692d0 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Program.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Program.cs @@ -14,7 +14,7 @@ var builder = WebApplication.CreateBuilder(args); -builder.AddAutoGenServices(); +builder.AddServiceDefaults(); builder.ConfigureSemanticKernel(); builder.Services.AddHttpClient(); diff --git a/dotnet/src/Microsoft.AutoGen/Agents/App.cs b/dotnet/src/Microsoft.AutoGen/Agents/App.cs index ea2380f116a..8a233bcd489 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/App.cs @@ -24,7 +24,7 @@ public static async ValueTask StartAsync(WebApplicationBuilder? } builder.AddAgentWorker(local: local) .AddAgents(agentTypes); - builder.AddAutoGenServices(); + builder.AddServiceDefaults(); var app = builder.Build(); if (local) { diff --git a/dotnet/src/Microsoft.AutoGen/Agents/Services/Host.cs b/dotnet/src/Microsoft.AutoGen/Agents/Services/Host.cs index 58cb921aea1..5b725af0c9a 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/Services/Host.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/Services/Host.cs @@ -11,7 +11,7 @@ public static class Host public static async Task StartAsync(bool local = false, bool useGrpc = true) { var builder = WebApplication.CreateBuilder(); - builder.AddAutoGenServices(); + builder.AddServiceDefaults(); if (local) { builder.AddLocalAgentService(useGrpc); diff --git a/dotnet/src/Microsoft.AutoGen/Extensions/ServiceDefaults/Extensions.cs b/dotnet/src/Microsoft.AutoGen/Extensions/ServiceDefaults/Extensions.cs index 310366bede7..a4eccacb7fd 100644 --- a/dotnet/src/Microsoft.AutoGen/Extensions/ServiceDefaults/Extensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Extensions/ServiceDefaults/Extensions.cs @@ -17,9 +17,9 @@ namespace Microsoft.Extensions.Hosting; // To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults public static class Extensions { - public static IHostApplicationBuilder AddAutoGenServices(this IHostApplicationBuilder builder) + public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder) { - builder.ConfigureOpenTelemetryForAutoGen(); + builder.ConfigureOpenTelemetry(); builder.AddDefaultHealthChecks(); @@ -41,7 +41,7 @@ public static IHostApplicationBuilder AddAutoGenServices(this IHostApplicationBu // }); return builder; } - public static IHostApplicationBuilder ConfigureOpenTelemetryForAutoGen(this IHostApplicationBuilder builder) + public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder) { builder.Logging.AddOpenTelemetry(logging => { @@ -66,11 +66,11 @@ public static IHostApplicationBuilder ConfigureOpenTelemetryForAutoGen(this IHos .AddSource("AutoGen.Agent"); }); - builder.AddOpenTelemetryExportersForAutoGen(); + builder.AddOpenTelemetryExporters(); return builder; } - private static IHostApplicationBuilder AddOpenTelemetryExportersForAutoGen(this IHostApplicationBuilder builder) + private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder) { var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); @@ -94,7 +94,6 @@ public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicati .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]); return builder; } - public static WebApplication MapDefaultEndpoints(this WebApplication app) { // Adding health checks endpoints to applications in non-development environments has security implications.