Skip to content

[dotnet-port-fixes] Align workflow message ordering with .NET #502

Description

@github-actions

Summary

Align workflow/agentworkflow response merging with the upstream .NET workflow-hosting fix from microsoft/agent-framework#7123 (05834b56e31f941e90e3337eb0f09d1a6ad8ee88).

The Go port keeps workflow-agent message ordering in first-seen order by:

  • preserving first-seen response/message grouping instead of re-sorting merged messages by timestamp,
  • keeping identifierless update segments in their original position instead of appending all dangling updates at the end,
  • preserving per-message CreatedAt values when stamping merged messages.

It also adds focused parity tests for the ordering cases that regressed upstream: contiguous response ordering, function call/result ordering, and identifierless segment handling.

Ported .NET PRs

Upstream commit: 05834b56e31f941e90e3337eb0f09d1a6ad8ee88

Breaking Changes

No.

Tests and Examples

  • Ran go test ./workflow/agentworkflow/...
  • Added workflow/agentworkflow/message_merger_test.go parity coverage for first-seen ordering, contiguous response grouping, function call/result ordering, and identifierless segments

Notes

  • This port is intentionally scoped to the shared Go message-merging behavior and does not add any public API.
  • The .NET PR also added handoff-orchestration coverage; Go does not have the corresponding handoff builder/executor surface yet, so this PR ports the shared ordering fix and its direct parity tests.

Generated by .NET to Go Fixes and Test Porting Agent · 724.7 AIC · ⌖ 43.2 AIC · ⊞ 21.7K ·


Note

This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch copilot/dotnet-port-fixes-message-ordering-20260716-af0566627077a9c6.

Click here to create the pull request

To fix the permissions issue, go to SettingsActionsGeneral and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ

Show patch preview (314 of 314 lines)
From fd18b8baff49d09508a7699881b2aa9e2e15f8b4 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Thu, 16 Jul 2026 03:38:03 +0000
Subject: [PATCH] [dotnet-port-fixes] Preserve workflow message ordering

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 workflow/agentworkflow/message_merger.go      |  76 ++++----
 workflow/agentworkflow/message_merger_test.go | 168 ++++++++++++++++++
 2 files changed, 204 insertions(+), 40 deletions(-)
 create mode 100644 workflow/agentworkflow/message_merger_test.go

diff --git a/workflow/agentworkflow/message_merger.go b/workflow/agentworkflow/message_merger.go
index df7bb5ce8..b19d29a69 100644
--- a/workflow/agentworkflow/message_merger.go
+++ b/workflow/agentworkflow/message_merger.go
@@ -30,7 +30,7 @@ func (m *messageMerger) AddUpdate(update *agent.ResponseUpdate) {
 		return
 	}
 	if update.ResponseID == "" {
-		m.danglingState.addDangling(update)
+		m.danglingState.addUpdate(update)
 		return
 	}
 	state, ok := m.states[update.ResponseID]
@@ -51,7 +51,6 @@ func (m *messageMerger) ComputeMerged(primaryResponseID string, primaryAgentID s
 	for _, responseID := range m.stateOrder {
 		state := m.states[responseID]
 		responses := state.computeResponses()
-		slices.SortFunc(responses, compareResponsesByCreatedAt)
 		merged := mergeResponseList(responses)
 		if merged == nil {
 			continue
@@ -89,37 +88,49 @@ func (m *messageMerger) ComputeMerged(primaryResponseID string, primaryAgentID s
 }
 
 type responseMergeState struct {
-	responseID         string
-	updatesByMessageID map[string][]*agent.ResponseUpdate
-	messageOrder       []string
-	danglingUpdates    []*agent.ResponseUpdate
+	responseID        string
+	messageStatesByID map[string]*messageMergeState
+	messageStateOrder []*messageMergeState
+	lastObservedState *messageMergeState
+}
+
+type messageMergeState struct {
+	messageID      string
+	identifierless bool
+	updates        []*agent.ResponseUp
... (truncated)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions