Skip to content

.NET: [Bug]: Handoff orchestration does not pass message to the handoff agent #3161

@frank-msft

Description

@frank-msft

Description

I'm using the code sample from:

https://learn.microsoft.com/en-us/agent-framework/user-guide/workflows/orchestrations/handoff?pivots=programming-language-csharp

Expect

Q: What is the derivative of x^2?
triage_agent: This is a math question. I'll hand this off to the math tutor.
math_tutor: The derivative of x^2 is 2x. Using the power rule, we bring down the exponent (2) and multiply it by the coefficient (1), then reduce the exponent by 1: d/dx(x^2) = 2x^(2-1) = 2x.

Actual

Q: What is the derivative of x^2?
math_tutor: I'm here to help with your math problems! What math question or topic would you like assistance with? Please provide the details, and I'll walk you through the solution step by step.

Code Sample

var historyTutorAgent = _agentFactory.CreateAIAgent(
    instructions: "You provide assistance with historical queries. Explain important events and context clearly. Only respond about history.",
    name: "History tutor",
    description: "Specialist agent for historical questions");
Console.WriteLine(await historyTutorAgent.RunAsync("hello"));

var mathTutorAgent = _agentFactory.CreateAIAgent(
    instructions: "You provide help with math problems. Explain your reasoning at each step and include examples. Only respond about math.",
    name: "Math tutor",
    description: "Specialist agent for math questions");
Console.WriteLine(await mathTutorAgent.RunAsync("hello"));

var triageAgent = _agentFactory.CreateAIAgent(
    instructions: "You determine which agent to use based on the user's homework question. ALWAYS handoff to another agent.",
    name: "Triage agent",
    description: "Routes messages to the appropriate specialist agent");

var workflow = AgentWorkflowBuilder.CreateHandoffBuilderWith(triageAgent)
    .WithHandoffs(triageAgent, [historyTutorAgent, mathTutorAgent])
    .WithHandoffs([historyTutorAgent, mathTutorAgent], triageAgent)
    .Build();

// Get or create conversation thread for state persistence
AgentThread thread = GetConversationThread(triageAgent, turnState);
var chatHistory = thread.GetService<IList<ChatMessage>>() ?? [];

// Create chat message from user input
ChatMessage userMessage = new(ChatRole.User, turnContext.Activity.Text);
chatHistory.Add(userMessage);

// Send typing indicator to show agent is working
await turnContext.SendActivitiesAsync(
    [new Activity { Type = ActivityTypes.Typing }],
    cancellationToken);

// Execute workflow and process events
StreamingRun run = await InProcessExecution.StreamAsync(workflow, chatHistory, cancellationToken: cancellationToken);
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));

var replyBuilder = new StringBuilder();
IList<ChatMessage> newMessages = [];
await foreach (WorkflowEvent evt in run.WatchStreamAsync(cancellationToken).ConfigureAwait(false))
{
    if (evt is AgentRunUpdateEvent e)
    {
        Console.WriteLine($"{e.ExecutorId}: {e.Data}");
        var replyMessage = e.Data.ToString();
        if (!string.IsNullOrEmpty(replyMessage))
        {
            replyBuilder.Append(replyMessage);
        }
    }
    else if (evt is WorkflowOutputEvent outputEvt)
    {
        newMessages = outputEvt.Data as IList<ChatMessage> ?? [];
        Console.WriteLine($"chatHistory: {JsonSerializer.Serialize(chatHistory)}");
        Console.WriteLine($"newMessages: {JsonSerializer.Serialize(newMessages)}");
        break;
    }
}

if (replyBuilder.Length > 0)
{
    // Send agent's reply back to user
    await turnContext.SendActivityAsync(replyBuilder.ToString(), cancellationToken: cancellationToken);
}
else
{
    await turnContext.SendActivityAsync("❗ The agent did not return any response.", cancellationToken: cancellationToken);
}

Error Messages / Stack Traces

No error message.

Here's the console messages from the code sample above:


chatHistory: [{"AuthorName":null,"CreatedAt":null,"Role":"user","Contents":[{"$type":"text","Text":"What is the derivative of x^2?","Annotations":null,"AdditionalProperties":null}],"MessageId":null,"AdditionalProperties":null}]
newMessages: [{"AuthorName":"Triage agent","CreatedAt":"2026-01-09T22:39:17+00:00","Role":"assistant","Contents":[{"$type":"functionCall","CallId":"call_xxx","Name":"handoff_to_2","Arguments":{"reasonForHandoff":"The user has a homework question that requires math expertise."},"Annotations":null,"AdditionalProperties":null}],"MessageId":"chatcmpl-xxx","AdditionalProperties":null},{"AuthorName":"Triage agent","CreatedAt":"2026-01-09T22:39:17.1924222+00:00","Role":"tool","Contents":[{"$type":"functionResult","CallId":"call_xxx","Result":"Transferred.","Annotations":null,"AdditionalProperties":null}],"MessageId":"xxx","AdditionalProperties":null},{"AuthorName":"Math tutor","CreatedAt":"2026-01-09T22:39:17+00:00","Role":"assistant","Contents":[{"$type":"text","Text":"Hi! How can I help you with your math problem today? Please tell me your question, and I\u0027ll explain every step clearly.","Annotations":null,"AdditionalProperties":null}],"MessageId":"chatcmpl-xxx","AdditionalProperties":null}]

Package Versions

Microsoft.Agents.AI: 1.0.0-preview.260108.1, Microsoft.Agents.AI.OpenAI: 1.0.0-preview.260108.1, Microsoft.Agents.AI.Workflows: 1.0.0-preview.260108.1,

.NET Version

NET 10.0

Additional Context

No response

Metadata

Metadata

Assignees

Labels

.NETagent orchestrationIssues related to agent orchestrationbugSomething isn't workingv1.0Features being tracked for the version 1.0 GA

Type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions