Skip to content

Commit

Permalink
add happy path test
Browse files Browse the repository at this point in the history
  • Loading branch information
LittleLittleCloud committed Nov 15, 2024
1 parent cac411b commit e00e63f
Show file tree
Hide file tree
Showing 14 changed files with 198 additions and 98 deletions.
3 changes: 1 addition & 2 deletions dotnet/samples/Hello/HelloAgent/HelloAgent.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
Expand All @@ -8,7 +8,6 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Aspire.Hosting.AppHost" />
</ItemGroup>

<ItemGroup>
Expand Down
97 changes: 50 additions & 47 deletions dotnet/samples/Hello/HelloAgent/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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>("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<Client>();
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<NewMessageReceived>,
IHandle<ConversationClosed>
{
[TopicSubscription("HelloAgents")]
public class HelloAgent(
IAgentRuntime context, IHostApplicationLifetime hostApplicationLifetime,
[FromKeyedServices("EventTypes")] EventTypes typeRegistry) : AgentBase(
context,
typeRegistry),
ISayHello,
IHandleConsole,
IHandle<NewMessageReceived>,
IHandle<ConversationClosed>
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<string> 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<string> SayHello(string ask)
{
public Task<string> SayHello(string ask);
var response = $"\n\n\n\n***************Hello {ask}**********************\n\n\n\n";
return response;
}
}
public interface ISayHello
{
public Task<string> SayHello(string ask);
}
2 changes: 1 addition & 1 deletion dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using Microsoft.AutoGen.Agents;
var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();
builder.AddAutoGenServices();
builder.AddAgentService();

var app = builder.Build();
Expand Down
2 changes: 1 addition & 1 deletion dotnet/samples/dev-team/DevTeam.Agents/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();
builder.AddAutoGenServices();

builder.ConfigureSemanticKernel();

Expand Down
2 changes: 1 addition & 1 deletion dotnet/samples/dev-team/DevTeam.Backend/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();
builder.AddAutoGenServices();
builder.ConfigureSemanticKernel();

builder.Services.AddHttpClient();
Expand Down
5 changes: 3 additions & 2 deletions dotnet/src/Microsoft.AutoGen/Agents/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<WebApplication> StartAsync(WebApplicationBuilder? builder = null, AgentTypes? agentTypes = null, bool local = false)
{
Expand All @@ -23,7 +24,7 @@ public static async ValueTask<WebApplication> StartAsync(WebApplicationBuilder?
}
builder.AddAgentWorker(local: local)
.AddAgents(agentTypes);
builder.AddServiceDefaults();
builder.AddAutoGenServices();
var app = builder.Build();
if (local)
{
Expand Down Expand Up @@ -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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);

Expand All @@ -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<GrpcGatewayService>(); }
Expand Down
2 changes: 1 addition & 1 deletion dotnet/src/Microsoft.AutoGen/Agents/Services/Host.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class Host
public static async Task<WebApplication> StartAsync(bool local = false, bool useGrpc = true)
{
var builder = WebApplication.CreateBuilder();
builder.AddServiceDefaults();
builder.AddAutoGenServices();
if (local)
{
builder.AddLocalAgentService(useGrpc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -98,7 +114,9 @@ public static AgentApplicationBuilder AddAgentWorker(this IHostApplicationBuilde
return new EventTypes(typeRegistry, types, eventsMap);
});
builder.Services.AddSingleton<Client>();
return new AgentApplicationBuilder(builder);
builder.Services.AddSingleton(new AgentApplicationBuilder(builder));

return builder;
}

private static MessageDescriptor? GetMessageDescriptor(Type type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<IRegistryGrain, RegistryGrain>();

// 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)
Expand Down Expand Up @@ -51,16 +57,16 @@ public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builde
options.SystemResponseTimeout = TimeSpan.FromMinutes(3);
});
siloBuilder.Configure<ClientMessagingOptions>(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 =>
{
Expand All @@ -84,7 +90,7 @@ public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builde
.AddMemoryGrainStorage("PubSubStore");
}
});
builder.Services.AddSingleton<IRegistryGrain, RegistryGrain>();

return builder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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 =>
{
Expand All @@ -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"]);

Expand All @@ -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.
Expand Down
Loading

0 comments on commit e00e63f

Please sign in to comment.