mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
First round of cleanup of runtime abstractions (#156)
This commit is contained in:
committed by
GitHub
Unverified
parent
a233d31813
commit
fbf1f10a8a
+47
-47
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.AI.Agents.Runtime.InProcess.Tests;
|
||||
@@ -18,7 +19,7 @@ public class InProcessRuntimeTests()
|
||||
|
||||
// Assert
|
||||
Assert.False(runtime.DeliverToSelf);
|
||||
Assert.Equal(0, runtime.messageQueueCount);
|
||||
Assert.Equal(0, runtime._messageQueueCount);
|
||||
|
||||
// Act
|
||||
await runtime.StopAsync(); // Already stopped
|
||||
@@ -29,13 +30,13 @@ public class InProcessRuntimeTests()
|
||||
// Assert
|
||||
// Invalid to start runtime that is already started
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => runtime.StartAsync());
|
||||
Assert.Equal(0, runtime.messageQueueCount);
|
||||
Assert.Equal(0, runtime._messageQueueCount);
|
||||
|
||||
// Act
|
||||
await runtime.StopAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, runtime.messageQueueCount);
|
||||
Assert.Equal(0, runtime._messageQueueCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -43,7 +44,7 @@ public class InProcessRuntimeTests()
|
||||
{
|
||||
// Arrange
|
||||
await using InProcessRuntime runtime = new();
|
||||
TestSubscription subscription = new("TestTopic", "MyAgent");
|
||||
TestSubscription subscription = new("TestTopic", new("MyAgent"));
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await runtime.RemoveSubscriptionAsync(subscription.Id));
|
||||
@@ -68,44 +69,44 @@ public class InProcessRuntimeTests()
|
||||
await using InProcessRuntime runtime = new();
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await runtime.GetAgentAsync(AgentType, lazy: false));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await runtime.GetActorAsync(AgentType, lazy: false));
|
||||
|
||||
// Arrange
|
||||
await runtime.RegisterAgentFactoryAsync(AgentType, factoryFunc);
|
||||
await runtime.RegisterActorFactoryAsync(new(AgentType), factoryFunc);
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await runtime.RegisterAgentFactoryAsync(AgentType, factoryFunc));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await runtime.RegisterActorFactoryAsync(new(AgentType), factoryFunc));
|
||||
|
||||
// Act: Lookup by type
|
||||
AgentId agentId = await runtime.GetAgentAsync(AgentType, lazy: false);
|
||||
ActorId agentId = await runtime.GetActorAsync(AgentType, lazy: false);
|
||||
|
||||
// Assert
|
||||
Assert.Single(agents);
|
||||
Assert.Single(runtime.agentInstances);
|
||||
Assert.Single(runtime._actorInstances);
|
||||
|
||||
// Act
|
||||
MockAgent agent = await runtime.TryGetUnderlyingAgentInstanceAsync<MockAgent>(agentId);
|
||||
MockAgent agent = await runtime.TryGetUnderlyingActorInstanceAsync<MockAgent>(agentId);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(agentId, agent.Id);
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await runtime.TryGetUnderlyingAgentInstanceAsync<WrongAgent>(agentId));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(async () => await runtime.TryGetUnderlyingActorInstanceAsync<WrongAgent>(agentId));
|
||||
|
||||
// Act: Lookup by ID
|
||||
AgentId sameId = await runtime.GetAgentAsync(agentId, lazy: false);
|
||||
ActorId sameId = await runtime.GetActorAsync(agentId, lazy: false);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(agentId, sameId);
|
||||
|
||||
// Act: Lookup by Type
|
||||
sameId = await runtime.GetAgentAsync((AgentType)agent.Id.Type, lazy: false);
|
||||
sameId = await runtime.GetActorAsync((ActorType)agent.Id.Type, lazy: false);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(agentId, sameId);
|
||||
|
||||
// Act: Lookup metadata
|
||||
AgentMetadata metadata = await runtime.GetAgentMetadataAsync(agentId);
|
||||
ActorMetadata metadata = await runtime.GetActorMetadataAsync(agentId);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(agentId.Type, metadata.Type);
|
||||
@@ -113,15 +114,16 @@ public class InProcessRuntimeTests()
|
||||
Assert.Equal(agentId.Key, metadata.Key);
|
||||
|
||||
// Act: Access proxy
|
||||
AgentProxy proxy = await runtime.TryGetAgentProxyAsync(agentId);
|
||||
IdProxyActor? proxy = await runtime.TryGetActorProxyAsync(agentId);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(proxy);
|
||||
Assert.Equal(agentId, proxy.Id);
|
||||
Assert.Equal(metadata.Type, proxy.Metadata.Type);
|
||||
Assert.Equal(metadata.Description, proxy.Metadata.Description);
|
||||
Assert.Equal(metadata.Key, proxy.Metadata.Key);
|
||||
|
||||
async ValueTask<MockAgent> factoryFunc(AgentId id, IAgentRuntime runtime)
|
||||
async ValueTask<MockAgent> factoryFunc(ActorId id, IAgentRuntime runtime)
|
||||
{
|
||||
MockAgent agent = new(id, runtime, AgentDescription);
|
||||
agents.Add(agent);
|
||||
@@ -137,35 +139,35 @@ public class InProcessRuntimeTests()
|
||||
const string TestMessage = "test message";
|
||||
|
||||
await using InProcessRuntime firstRuntime = new();
|
||||
await firstRuntime.RegisterAgentFactoryAsync(AgentType, factoryFunc);
|
||||
await firstRuntime.RegisterActorFactoryAsync(new(AgentType), factoryFunc);
|
||||
|
||||
// Act
|
||||
AgentId agentId = await firstRuntime.GetAgentAsync(AgentType, lazy: false);
|
||||
ActorId agentId = await firstRuntime.GetActorAsync(AgentType, lazy: false);
|
||||
|
||||
// Assert
|
||||
Assert.Single(firstRuntime.agentInstances);
|
||||
Assert.Single(firstRuntime._actorInstances);
|
||||
|
||||
// Arrange
|
||||
MockAgent agent = (MockAgent)firstRuntime.agentInstances[agentId];
|
||||
MockAgent agent = (MockAgent)firstRuntime._actorInstances[agentId];
|
||||
agent.ReceivedMessages.Add(TestMessage);
|
||||
|
||||
// Act
|
||||
JsonElement agentState = await firstRuntime.SaveAgentStateAsync(agentId);
|
||||
JsonElement agentState = await firstRuntime.SaveActorStateAsync(agentId);
|
||||
|
||||
// Arrange
|
||||
await using InProcessRuntime secondRuntime = new();
|
||||
await secondRuntime.RegisterAgentFactoryAsync(AgentType, factoryFunc);
|
||||
await secondRuntime.RegisterActorFactoryAsync(new(AgentType), factoryFunc);
|
||||
|
||||
// Act
|
||||
await secondRuntime.LoadAgentStateAsync(agentId, agentState);
|
||||
await secondRuntime.LoadActorStateAsync(agentId, agentState);
|
||||
|
||||
// Assert
|
||||
Assert.Single(secondRuntime.agentInstances);
|
||||
MockAgent copy = (MockAgent)secondRuntime.agentInstances[agentId];
|
||||
Assert.Single(secondRuntime._actorInstances);
|
||||
MockAgent copy = (MockAgent)secondRuntime._actorInstances[agentId];
|
||||
Assert.Single(copy.ReceivedMessages);
|
||||
Assert.Equal(TestMessage, copy.ReceivedMessages.Single().ToString());
|
||||
|
||||
static async ValueTask<MockAgent> factoryFunc(AgentId id, IAgentRuntime runtime)
|
||||
static async ValueTask<MockAgent> factoryFunc(ActorId id, IAgentRuntime runtime)
|
||||
{
|
||||
MockAgent agent = new(id, runtime, "A test agent");
|
||||
return agent;
|
||||
@@ -178,14 +180,14 @@ public class InProcessRuntimeTests()
|
||||
// Arrange
|
||||
await using InProcessRuntime runtime = new();
|
||||
MockAgent? agent = null;
|
||||
await runtime.RegisterAgentFactoryAsync("MyAgent", async (id, runtime) =>
|
||||
await runtime.RegisterActorFactoryAsync(new("MyAgent"), async (id, runtime) =>
|
||||
{
|
||||
agent = new MockAgent(id, runtime, "A test agent");
|
||||
return agent;
|
||||
});
|
||||
|
||||
// Act: Ensure the agent is actually created
|
||||
AgentId agentId = await runtime.GetAgentAsync("MyAgent", lazy: false);
|
||||
ActorId agentId = await runtime.GetActorAsync("MyAgent", lazy: false);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -197,7 +199,7 @@ public class InProcessRuntimeTests()
|
||||
await runtime.RunUntilIdleAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, runtime.messageQueueCount);
|
||||
Assert.Equal(0, runtime._messageQueueCount);
|
||||
Assert.Single(agent.ReceivedMessages);
|
||||
}
|
||||
|
||||
@@ -214,21 +216,21 @@ public class InProcessRuntimeTests()
|
||||
};
|
||||
|
||||
MockAgent? agent = null;
|
||||
await runtime.RegisterAgentFactoryAsync("MyAgent", async (id, runtime) =>
|
||||
await runtime.RegisterActorFactoryAsync(new("MyAgent"), async (id, runtime) =>
|
||||
{
|
||||
agent = new MockAgent(id, runtime, "A test agent");
|
||||
return agent;
|
||||
});
|
||||
|
||||
// Assert
|
||||
Assert.Empty(runtime.agentInstances);
|
||||
Assert.Empty(runtime._actorInstances);
|
||||
|
||||
// Act: Ensure the agent is actually created
|
||||
AgentId agentId = await runtime.GetAgentAsync("MyAgent", lazy: false);
|
||||
ActorId agentId = await runtime.GetActorAsync("MyAgent", lazy: false);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
Assert.Single(runtime.agentInstances);
|
||||
Assert.Single(runtime._actorInstances);
|
||||
|
||||
const string TopicType = "TestTopic";
|
||||
|
||||
@@ -250,14 +252,14 @@ public class InProcessRuntimeTests()
|
||||
// Arrange: Create a runtime and register an agent
|
||||
await using InProcessRuntime runtime = new();
|
||||
MockAgent? agent = null;
|
||||
await runtime.RegisterAgentFactoryAsync("MyAgent", async (id, runtime) =>
|
||||
await runtime.RegisterActorFactoryAsync(new("MyAgent"), async (id, runtime) =>
|
||||
{
|
||||
agent = new MockAgent(id, runtime, "test agent");
|
||||
return agent;
|
||||
});
|
||||
|
||||
// Get agent ID and instantiate agent by publishing
|
||||
AgentId agentId = await runtime.GetAgentAsync("MyAgent", lazy: false);
|
||||
ActorId agentId = await runtime.GetActorAsync("MyAgent", lazy: false);
|
||||
const string TopicType = "TestTopic";
|
||||
await runtime.AddSubscriptionAsync(new TestSubscription(TopicType, agentId.Type));
|
||||
|
||||
@@ -286,46 +288,44 @@ public class InProcessRuntimeTests()
|
||||
agent = null;
|
||||
await using InProcessRuntime newRuntime = new();
|
||||
await newRuntime.StartAsync();
|
||||
await newRuntime.RegisterAgentFactoryAsync("MyAgent", async (id, runtime) =>
|
||||
await newRuntime.RegisterActorFactoryAsync(new("MyAgent"), async (id, runtime) =>
|
||||
{
|
||||
agent = new MockAgent(id, runtime, "another agent");
|
||||
return agent;
|
||||
});
|
||||
|
||||
// Assert: Show that no agent instances exist in the new runtime
|
||||
Assert.Empty(newRuntime.agentInstances);
|
||||
Assert.Empty(newRuntime._actorInstances);
|
||||
|
||||
// Act: Load the state into the new runtime and show that agent is now instantiated
|
||||
await newRuntime.LoadStateAsync(savedState);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
Assert.Single(newRuntime.agentInstances);
|
||||
Assert.True(newRuntime.agentInstances.ContainsKey(agentId));
|
||||
Assert.Single(newRuntime._actorInstances);
|
||||
Assert.True(newRuntime._actorInstances.ContainsKey(agentId));
|
||||
Assert.Single(agent.ReceivedMessages);
|
||||
}
|
||||
|
||||
#pragma warning disable CA1812 // Avoid uninstantiated internal classes
|
||||
private sealed class WrongAgent : IHostableAgent
|
||||
private sealed class WrongAgent : IRuntimeActor
|
||||
#pragma warning restore CA1812
|
||||
{
|
||||
public AgentId Id => throw new NotImplementedException();
|
||||
public ActorId Id => throw new NotImplementedException();
|
||||
|
||||
public AgentMetadata Metadata => throw new NotImplementedException();
|
||||
public ActorMetadata Metadata => throw new NotImplementedException();
|
||||
|
||||
public ValueTask CloseAsync() => default;
|
||||
|
||||
public ValueTask LoadStateAsync(JsonElement state)
|
||||
public ValueTask LoadStateAsync(JsonElement state, CancellationToken cancellationToken = default)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ValueTask<object?> OnMessageAsync(object message, MessageContext messageContext)
|
||||
public ValueTask<object?> OnMessageAsync(object message, MessageContext messageContext, CancellationToken cancellationToken = default)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ValueTask<JsonElement> SaveStateAsync()
|
||||
public ValueTask<JsonElement> SaveStateAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user