Browse Source

Rysweet 531 dotnet create hello agent continued (#606)

fixing base agent classes for io
tags/v0.4.0.dev0
Ryan Sweet GitHub 1 year ago
parent
commit
a72ebaef90
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
11 changed files with 270 additions and 10 deletions
  1. +2
    -0
      dotnet/Directory.Packages.props
  2. +0
    -0
      dotnet/samples/HelloAgents/HelloAgents.Agents/Program.cs
  3. +1
    -1
      dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/AgentBaseExtensions.cs
  4. +59
    -0
      dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs
  5. +83
    -0
      dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Agents/IOAgent/FileAgent/FileAgent.cs
  6. +14
    -4
      dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Agents/IOAgent/IOAgent.cs
  7. +90
    -0
      dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Agents/IOAgent/WebAPIAgent/WebAPIAgent.cs
  8. +5
    -0
      dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Microsoft.AutoGen.Agents.Worker.Client.csproj
  9. +3
    -2
      dotnet/src/Microsoft.AutoGen.Agents/Microsoft.AutoGen.Agents.csproj
  10. +5
    -3
      protos/agent_events.proto
  11. +8
    -0
      protos/agent_states.proto

+ 2
- 0
dotnet/Directory.Packages.props 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" />


dotnet/samples/HelloAgents/HelloAgents.Agents/Agents/HelloAgent/Program.cs → dotnet/samples/HelloAgents/HelloAgents.Agents/Program.cs View File


+ 1
- 1
dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/AgentBaseExtensions.cs 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);
}


+ 59
- 0
dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs 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);
}

+ 83
- 0
dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Agents/IOAgent/FileAgent/FileAgent.cs 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
{
}

+ 14
- 4
dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Agents/IOAgent/IOAgent.cs 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);

}

+ 90
- 0
dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Agents/IOAgent/WebAPIAgent/WebAPIAgent.cs 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
{
}

+ 5
- 0
dotnet/src/Microsoft.AutoGen.Agents.Worker.Client/Microsoft.AutoGen.Agents.Worker.Client.csproj 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>

+ 3
- 2
dotnet/src/Microsoft.AutoGen.Agents/Microsoft.AutoGen.Agents.csproj 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>


+ 5
- 3
protos/agent_events.proto 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;
}

+ 8
- 0
protos/agent_states.proto View File

@@ -0,0 +1,8 @@
syntax = "proto3";
package agents;

option csharp_namespace = "Microsoft.AutoGen.Agents.Worker.Client";

message AgentState {
string message = 1;
}

Loading…
Cancel
Save