From 72c79aeac513b0c452121f590ab6d6eae625e5d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 23:20:43 +0000 Subject: [PATCH] Add Task_Delegates_To_Correct_Agent E2E test with multi-participant routing assertion Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/9b34e409-61b8-4650-ae55-34efad034ed0 Co-authored-by: lokitoth <6936551+lokitoth@users.noreply.github.com> --- .../MagenticOrchestrationTests.cs | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/MagenticOrchestrationTests.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/MagenticOrchestrationTests.cs index 1632fc6059..763d23d20f 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/MagenticOrchestrationTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/MagenticOrchestrationTests.cs @@ -871,6 +871,68 @@ public class MagenticOrchestrationTests runResult.Result![0].Text.Should().Contain("Recovered after no-progress stall"); } + [Fact] + public async Task Task_Delegates_To_Correct_Agent() + { + // Arrange: Two participants (WorkerA, WorkerB). Manager selects "WorkerA" as next speaker. + // We verify that WorkerA produces a response update event and WorkerB does not. + // Flow: facts1, plan1 → ledger1(nextSpeaker=WorkerA, not satisfied) → WorkerA runs + // → TakeTurnAsync re-enters → facts2, plan2 → ledger2(satisfied) → finalAnswer + List factsResponse1 = CreatePlanResponse("Task delegation facts"); + List planResponse1 = CreatePlanResponse("Delegate to WorkerA"); + List ledger1 = CreateProgressLedgerResponse( + isRequestSatisfied: false, + isInLoop: false, + isProgressBeingMade: true, + nextSpeaker: "WorkerA", + instructionOrQuestion: "WorkerA please handle this"); + + // After WorkerA responds, orchestrator re-enters TakeTurnAsync → UpdatePlanAndDelegateAsync + List factsResponse2 = CreatePlanResponse("Updated facts after WorkerA"); + List planResponse2 = CreatePlanResponse("Updated plan after WorkerA"); + List ledger2 = CreateProgressLedgerResponse( + isRequestSatisfied: true, + isInLoop: false, + isProgressBeingMade: true, + nextSpeaker: "WorkerA", + instructionOrQuestion: "Done"); + List finalAnswerResponse = CreateFinalAnswerResponse("Delegated correctly!"); + + TestReplayAgent manager = new( + [factsResponse1, planResponse1, ledger1, + factsResponse2, planResponse2, ledger2, finalAnswerResponse], + name: "Manager"); + TestEchoAgent workerA = new(name: "WorkerA", prefix: "[A] "); + TestEchoAgent workerB = new(name: "WorkerB", prefix: "[B] "); + + List collectedEvents = []; + + Workflow workflow = new MagenticWorkflowBuilder(manager) + .AddParticipants(workerA, workerB) + .RequirePlanSignoff(false) + .Build(); + + // Act + WorkflowRunResult runResult = await RunMagenticWorkflowAsync( + workflow, + [new ChatMessage(ChatRole.User, "Test delegation routing")], + eventCollector: collectedEvents); + + // Assert: WorkerA should have produced response updates, WorkerB should not + List agentUpdates = collectedEvents.OfType().ToList(); + + // WorkerA's executor should appear in the events + agentUpdates.Should().Contain(e => e.Update.AuthorName == "WorkerA", + "WorkerA was selected as next speaker and should have responded"); + + // WorkerB should NOT have responded + agentUpdates.Should().NotContain(e => e.Update.AuthorName == "WorkerB", + "WorkerB was not selected and should not have responded"); + + runResult.Result.Should().NotBeNull(); + runResult.Result![0].Text.Should().Contain("Delegated correctly!"); + } + [Fact] public async Task PlanReview_Multiple_Revisions() {