Skip to content

.NET: Honor terminal workflow outputs in Workflow.AsAIAgent responses#6212

Open
ssccinng wants to merge 2 commits into
microsoft:mainfrom
ssccinng:fix-workflow-agent-output-filtering
Open

.NET: Honor terminal workflow outputs in Workflow.AsAIAgent responses#6212
ssccinng wants to merge 2 commits into
microsoft:mainfrom
ssccinng:fix-workflow-agent-output-filtering

Conversation

@ssccinng
Copy link
Copy Markdown

Fixes #6211.

Summary

  • Convert terminal workflow string / AIContent outputs into response-compatible updates for Workflow.AsAIAgent.
  • When creating the final AgentResponse, prefer explicit terminal workflow outputs over intermediate agent response updates.
  • Preserve the existing streaming surface so observers still see intermediate workflow/agent events.
  • Add a regression test for �i -> ai -> uppercase string executor with .WithOutputFrom(uppercase).

Validation

ext dotnet test --project .\tests\Microsoft.Agents.AI.Workflows.UnitTests\Microsoft.Agents.AI.Workflows.UnitTests.csproj -v minimal

Result: 1269 passed across
et472 and
et10.0.

Copilot AI review requested due to automatic review settings May 30, 2026 18:13
@moonbox3 moonbox3 added .NET workflows Related to Workflows in agent-framework labels May 30, 2026
@github-actions github-actions Bot changed the title Honor terminal workflow outputs in Workflow.AsAIAgent responses .NET: Honor terminal workflow outputs in Workflow.AsAIAgent responses May 30, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR adjusts workflow-as-agent behavior so the final AgentResponse prefers designated workflow outputs (rather than intermediate agent responses), and improves message metadata propagation.

Changes:

  • Forward AuthorName from ChatMessage into AgentResponseUpdate.
  • Update workflow output forwarding logic to include terminal outputs even when intermediate outputs are excluded.
  • Change WorkflowHostAgent response construction to prefer terminal workflow output updates; add a unit test for the expected behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowHostSmokeTests.cs Adds a regression test and a helper executor to validate that workflow-as-agent returns the designated output.
dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowSession.cs Extends update creation to include AuthorName and refines which workflow outputs are forwarded into response updates.
dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowHostAgent.cs Changes how final AgentResponse is computed, preferring terminal workflow outputs when present.

Comment on lines 568 to 578
bool includeTerminalOutput = this.IsTerminalOutput(output.ExecutorId);
if (!this._includeWorkflowOutputsInResponse
&& !includeTerminalOutput)
{
goto default;
}

foreach (ChatMessage message in updateMessages)
foreach (ChatMessage message in this._includeWorkflowOutputsInResponse ? updateMessages ?? [] : [])
{
yield return this.CreateUpdate(this.LastResponseId, evt, message);
}
Comment on lines +119 to +129
WorkflowSession workflowSession = await this.UpdateSessionAsync(messages, session, cancellationToken).ConfigureAwait(false);
MessageMerger merger = new();
List<AgentResponseUpdate> updates = [];

await foreach (AgentResponseUpdate update in workflowSession.InvokeStageAsync(cancellationToken)
.ConfigureAwait(false)
.WithCancellation(cancellationToken))
{
merger.AddUpdate(update);
updates.Add(update);
}

AgentResponse response = merger.ComputeMerged(workflowSession.LastResponseId!, this.Id, this.Name);
AgentResponse response = this.CreateResponse(workflowSession.LastResponseId!, updates);
Comment on lines +179 to +190
private bool IsTerminalWorkflowOutputUpdate(AgentResponseUpdate update)
{
if (update.RawRepresentation is not WorkflowOutputEvent output
|| output is AgentResponseUpdateEvent
|| output is AgentResponseEvent)
{
return false;
}

return this._workflow.OutputExecutors.TryGetValue(output.ExecutorId, out HashSet<OutputTag>? tags)
&& !tags.Contains(OutputTag.Intermediate);
}
Comment on lines +562 to +566
if (updateMessages == null
&& updateContents == null)
{
goto default;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET workflows Related to Workflows in agent-framework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: Workflow.AsAIAgent returns intermediate agent text instead of designated workflow output

3 participants