diff --git a/dotnet/src/Microsoft.Agents.AI.DurableTask/AgentEntity.cs b/dotnet/src/Microsoft.Agents.AI.DurableTask/AgentEntity.cs index fe26f176a1..ec4ba3acf6 100644 --- a/dotnet/src/Microsoft.Agents.AI.DurableTask/AgentEntity.cs +++ b/dotnet/src/Microsoft.Agents.AI.DurableTask/AgentEntity.cs @@ -21,7 +21,17 @@ internal class AgentEntity(IServiceProvider services, CancellationToken cancella ? cancellationToken : services.GetService()?.ApplicationStopping ?? CancellationToken.None; - public async Task RunAgentAsync(RunRequest request) + public Task RunAgentAsync(RunRequest request) + { + return this.Run(request); + } + + // IDE1006 and VSTHRD200 disabled to allow method name to match the common cross-platform entity operation name. +#pragma warning disable IDE1006 +#pragma warning disable VSTHRD200 + public async Task Run(RunRequest request) +#pragma warning restore VSTHRD200 +#pragma warning restore IDE1006 { AgentSessionId sessionId = this.Context.Id; AIAgent agent = this.GetAgent(sessionId); diff --git a/dotnet/src/Microsoft.Agents.AI.DurableTask/CHANGELOG.md b/dotnet/src/Microsoft.Agents.AI.DurableTask/CHANGELOG.md index 0f66ddc14c..ccc6aa7181 100644 --- a/dotnet/src/Microsoft.Agents.AI.DurableTask/CHANGELOG.md +++ b/dotnet/src/Microsoft.Agents.AI.DurableTask/CHANGELOG.md @@ -2,7 +2,10 @@ ## [Unreleased] +### Changed + - Added TTL configuration for durable agent entities ([#2679](https://github.com/microsoft/agent-framework/pull/2679)) +- Switch to new "Run" method name ([#2843](https://github.com/microsoft/agent-framework/pull/2843)) ## v1.0.0-preview.251204.1 diff --git a/dotnet/src/Microsoft.Agents.AI.DurableTask/DefaultDurableAgentClient.cs b/dotnet/src/Microsoft.Agents.AI.DurableTask/DefaultDurableAgentClient.cs index 2086a00ecb..9005641860 100644 --- a/dotnet/src/Microsoft.Agents.AI.DurableTask/DefaultDurableAgentClient.cs +++ b/dotnet/src/Microsoft.Agents.AI.DurableTask/DefaultDurableAgentClient.cs @@ -22,7 +22,7 @@ public async Task RunAgentAsync( await this._client.Entities.SignalEntityAsync( sessionId, - nameof(AgentEntity.RunAgentAsync), + nameof(AgentEntity.Run), request, cancellation: cancellationToken); diff --git a/dotnet/src/Microsoft.Agents.AI.DurableTask/DurableAIAgent.cs b/dotnet/src/Microsoft.Agents.AI.DurableTask/DurableAIAgent.cs index 021c8f22c7..2035b792fd 100644 --- a/dotnet/src/Microsoft.Agents.AI.DurableTask/DurableAIAgent.cs +++ b/dotnet/src/Microsoft.Agents.AI.DurableTask/DurableAIAgent.cs @@ -107,7 +107,7 @@ public override async Task RunAsync( { return await this._context.Entities.CallEntityAsync( durableThread.SessionId, - nameof(AgentEntity.RunAgentAsync), + nameof(AgentEntity.Run), request); } catch (EntityOperationFailedException e) when (e.FailureDetails.ErrorType == "EntityTaskNotFound") diff --git a/dotnet/tests/Microsoft.Agents.AI.DurableTask.IntegrationTests/AgentEntityTests.cs b/dotnet/tests/Microsoft.Agents.AI.DurableTask.IntegrationTests/AgentEntityTests.cs index 98e40ad4fb..b615bf1cd6 100644 --- a/dotnet/tests/Microsoft.Agents.AI.DurableTask.IntegrationTests/AgentEntityTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.DurableTask.IntegrationTests/AgentEntityTests.cs @@ -81,6 +81,64 @@ await simpleAgentProxy.RunAsync( Assert.Null(request.OrchestrationId); } + [Theory] + [InlineData("run")] + [InlineData("Run")] + [InlineData("RunAgentAsync")] + public async Task RunAgentMethodNamesAllWorkAsync(string runAgentMethodName) + { + // Setup + AIAgent simpleAgent = TestHelper.GetAzureOpenAIChatClient(s_configuration).CreateAIAgent( + name: "TestAgent", + instructions: "You are a helpful assistant that always responds with a friendly greeting." + ); + + using TestHelper testHelper = TestHelper.Start([simpleAgent], this._outputHelper); + + // A proxy agent is needed to call the hosted test agent + AIAgent simpleAgentProxy = simpleAgent.AsDurableAgentProxy(testHelper.Services); + + AgentThread thread = simpleAgentProxy.GetNewThread(); + + DurableTaskClient client = testHelper.GetClient(); + + AgentSessionId sessionId = thread.GetService(); + EntityInstanceId expectedEntityId = new($"dafx-{simpleAgent.Name}", sessionId.Key); + + EntityMetadata? entity = await client.Entities.GetEntityAsync(expectedEntityId, false, this.TestTimeoutToken); + + Assert.Null(entity); + + // Act: send a prompt to the agent + await client.Entities.SignalEntityAsync( + expectedEntityId, + runAgentMethodName, + new RunRequest("Hello!"), + cancellation: this.TestTimeoutToken); + + while (!this.TestTimeoutToken.IsCancellationRequested) + { + await Task.Delay(500, this.TestTimeoutToken); + + // Assert: verify the agent state was stored with the correct entity name prefix + entity = await client.Entities.GetEntityAsync(expectedEntityId, true, this.TestTimeoutToken); + + if (entity is not null) + { + break; + } + } + + Assert.NotNull(entity); + Assert.True(entity.IncludesState); + + DurableAgentState state = entity.State.ReadAs(); + + DurableAgentStateRequest request = Assert.Single(state.Data.ConversationHistory.OfType()); + + Assert.Null(request.OrchestrationId); + } + [Fact] public async Task OrchestrationIdSetDuringOrchestrationAsync() {