Rysweet 531 dotnet create hello agent continued (#606)

fixing base agent classes for io
This commit is contained in:
Ryan Sweet 2024-09-23 10:50:18 -07:00 committed by GitHub
parent 3cba258df7
commit a72ebaef90
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 270 additions and 10 deletions

View File

@ -41,6 +41,8 @@
<PackageVersion Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="8.7.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />

View File

@ -70,7 +70,7 @@ public static class AgentBaseExtensions
activity.Start();
// rpc attributes from https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/rpc.md
activity.SetTag("rpc.system", "starfleet");
activity.SetTag("rpc.system", "autogen");
activity.SetTag("rpc.service", agent.AgentId.ToString());
activity.SetTag("rpc.method", methodName);
}

View File

@ -0,0 +1,59 @@
using Microsoft.AutoGen.Agents.Abstractions;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AutoGen.Agents.Worker.Client;
public class ConsoleAgent : IOAgent<AgentState>,
IUseConsole,
IHandle<Input>,
IHandle<Output>
{
// instead of the primary constructor above, make a constructr here that still calls the base constructor
public ConsoleAgent(IAgentContext context, [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : base(context, typeRegistry)
{
_route = "console";
}
public override async Task Handle(Input item)
{
Console.WriteLine("Please enter input:");
string content = Console.ReadLine() ?? string.Empty;
await ProcessInput(content);
var evt = new InputProcessed
{
Route = _route
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
}
public override async Task Handle(Output item)
{
// Assuming item has a property `Content` that we want to write to the console
Console.WriteLine(item.Message);
var evt = new OutputWritten
{
Route = _route
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
}
public override Task<string> ProcessInput(string message)
{
// Implement your input processing logic here
return Task.FromResult(message);
}
public override Task ProcessOutput(string message)
{
// Implement your output processing logic here
return Task.CompletedTask;
}
}
public interface IUseConsole
{
public Task ProcessOutput(string message);
}

View File

@ -0,0 +1,83 @@
using Microsoft.AutoGen.Agents.Abstractions;
using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.Agents.Worker.Client;
[TopicSubscription("FileIO")]
public class FileAgent : IOAgent<AgentState>,
IUseFiles,
IHandle<Input>,
IHandle<Output>
{
public FileAgent(IAgentContext context, EventTypes typeRegistry, string filePath) : base(context, typeRegistry)
{
_filePath = filePath;
}
private readonly string _filePath;
public override async Task Handle(Input item)
{
// validate that the file exists
if (!File.Exists(_filePath))
{
string errorMessage = $"File not found: {_filePath}";
Logger.LogError(errorMessage);
//publish IOError event
var err = new IOError
{
Message = errorMessage
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(err);
return;
}
string content;
using (var reader = new StreamReader(item.Message))
{
content = await reader.ReadToEndAsync();
}
await ProcessInput(content);
var evt = new InputProcessed
{
Route = _route
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
}
public override async Task Handle(Output item)
{
using (var writer = new StreamWriter(_filePath, append: true))
{
await writer.WriteLineAsync(item.Message);
}
var evt = new OutputWritten
{
Route = _route
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
}
public override async Task<string> ProcessInput(string message)
{
var evt = new InputProcessed
{
Route = _route,
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
return message;
}
public override Task ProcessOutput(string message)
{
// Implement your output processing logic here
return Task.CompletedTask;
}
}
public interface IUseFiles
{
}

View File

@ -5,16 +5,16 @@ namespace Microsoft.AutoGen.Agents.Worker.Client;
public abstract class IOAgent<T> : AgentBase where T : class, new()
{
protected AgentState<T> _state;
private readonly string _route = "console";
public string _route = "base";
public IOAgent(IAgentContext context, EventTypes typeRegistry) : base(context, typeRegistry)
{
_state = new();
}
public async Task Handle(Input item)
public virtual async Task Handle(Input item)
{
//var processed = await ProcessInput(item.Message);
var evt = new InputProcessed
{
Route = _route
@ -22,6 +22,16 @@ public abstract class IOAgent<T> : AgentBase where T : class, new()
await PublishEvent(evt);
}
public abstract Task<string> ProcessInput(string message);
public virtual async Task Handle(Output item)
{
var evt = new OutputWritten
{
Route = _route
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
}
public abstract Task ProcessInput(string message);
public abstract Task ProcessOutput(string message);
}

View File

@ -0,0 +1,90 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.AutoGen.Agents.Abstractions;
namespace Microsoft.AutoGen.Agents.Worker.Client;
public class WebAPIAgent : IOAgent<AgentState>,
IUseWebAPI,
IHandle<Input>,
IHandle<Output>
{
private readonly string _url = "/agents/webio";
public WebAPIAgent(
IAgentContext context,
[FromKeyedServices("EventTypes")] EventTypes typeRegistry,
string url,
ILogger<WebAPIAgent> logger) : base(
context,
typeRegistry)
{
_url = url;
var builder = WebApplication.CreateBuilder();
var app = builder.Build();
app.MapPost(_url, async (HttpContext httpContext) =>
{
var input = await httpContext.Request.ReadFromJsonAsync<Input>();
if (input != null)
{
await Handle(input);
await httpContext.Response.WriteAsync("Input processed");
}
else
{
httpContext.Response.StatusCode = 400;
await httpContext.Response.WriteAsync("Invalid input");
}
});
app.MapGet(_url, async (HttpContext httpContext) =>
{
var output = new Output(); // Replace with actual output retrieval logic
await Handle(output);
await httpContext.Response.WriteAsJsonAsync(output);
});
app.Run();
}
public override async Task Handle(Input item)
{
// Process the input (this is a placeholder, replace with actual processing logic)
await ProcessInput(item.Message);
var evt = new InputProcessed
{
Route = _route
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
}
public override async Task Handle(Output item)
{
// Assuming item has a property `Content` that we want to return in the response
var evt = new OutputWritten
{
Route = _route
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
}
public override Task<string> ProcessInput(string message)
{
// Implement your input processing logic here
return Task.FromResult(message);
}
public override Task ProcessOutput(string message)
{
// Implement your output processing logic here
return Task.CompletedTask;
}
}
public interface IUseWebAPI
{
}

View File

@ -15,4 +15,9 @@
<ProjectReference Include="../Microsoft.AutoGen.Agents/Microsoft.AutoGen.Agents.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
</Project>

View File

@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>AutoGennnnnnn.Core</PackageId>
<PackageId>AutoGen.Core</PackageId>
<PackageProjectUrl>https://github.com/microsoft/agnext</PackageProjectUrl>
<Authors>Microsoft</Authors>
<Description>AutoGenn Core Library</Description>
@ -13,7 +13,8 @@
<ItemGroup>
<Protobuf Include="..\..\..\protos\agent_worker.proto" GrpcServices="Client;Server" Link="Protos\agent_worker.proto" />
<Protobuf Include="..\..\..\protos\cloudevent.proto" GrpcServices="Client;Server" Link="Protos\cloudevent.proto" />
<Protobuf Include="..\..\..\protos\agent_events.proto" GrpcServices="Client;Server" Link="Protos\cloudevent.proto" />
<Protobuf Include="..\..\..\protos\agent_events.proto" GrpcServices="Client;Server" Link="Protos\agent_events.proto" />
<Protobuf Include="..\..\..\protos\agent_states.proto" GrpcServices="Client;Server" Link="Protos\agent_states.proto" />
</ItemGroup>
<ItemGroup>

View File

@ -1,6 +1,6 @@
syntax = "proto3";
package helloagents;
package agents;
option csharp_namespace = "Microsoft.AutoGen.Agents.Worker.Client";
@ -14,7 +14,9 @@ message InputProcessed {
message Output {
string message = 1;
}
message OutputProcessed {
message OutputWritten {
string route = 1;
}
message IOError {
string message = 1;
}

View File

@ -0,0 +1,8 @@
syntax = "proto3";
package agents;
option csharp_namespace = "Microsoft.AutoGen.Agents.Worker.Client";
message AgentState {
string message = 1;
}