You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the agent (or underlying LLM provider) sets the same MessageID on both a streaming text/tool-call update and the subsequent tool result update, the ToolCallResult AG-UI event ends up with the same messageId as the TextMessageStart event. AG-UI clients that use messageId to correlate events then incorrectly associate the tool result with the text message.
Fix: in updatesToAGUIEvents, detect when an update contains FunctionResultContent and generate a fresh messageId for those events rather than reusing the update's msgID. A new hasFunctionResultContent helper is added to support this check.
Changed files:
agent/hosting/aguihosting/events.go — generate a distinct toolResultMsgID when the update contains FunctionResultContent
agent/hosting/aguihosting/agui_test.go — add TestHandler_ToolResult_HasDistinctMessageID covering the collision scenario
No. The ToolCallResultmessageId field changes from reusing the update's MessageID to a freshly generated ID, but this was already the intended AG-UI semantic and no existing public API contracts are changed.
Tests and Examples
Ran go test ./agent/hosting/aguihosting/... — all existing tests pass
Added TestHandler_ToolResult_HasDistinctMessageID: sets up an agent that emits text, tool-call, and tool-result updates all sharing the same explicit MessageID, then asserts that the TOOL_CALL_RESULT event's messageId differs from the TEXT_MESSAGE_START event's messageId
Ran go test ./... — all tests pass
Notes
The other new upstream commits (c885ca3d #5895 OpenAI store-false helper fix, d81a8753 #5838 StateBag edge-case tests, 9b772f34 #5894 OpenAIWebSearch observer) are .NET-only: OpenAI-specific C# extensions, test coverage for a .NET StateBag concept absent from the Go SDK, and a harness console sample observer. None were ported.
Upstream head inspected: a60e541c (upstream-agent-framework/main at time of run).
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 dotnet-port/agui-tool-result-message-id-5800-8c6a7fe5d95d95b3.
To fix the permissions issue, go to Settings → Actions → General and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ
Show patch preview (147 of 147 lines)
From 4895b87614d20b02e551c4b189415c689a63f994 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Sat, 16 May 2026 09:31:17 +0000
Subject: [PATCH] fix(agui): avoid tool result message ID collisions with
streaming text messages
Port of microsoft/agent-framework#5800.
Tool result events (ToolCallResult) must not share the same message ID as
the preceding streaming text/tool-call message. When an update contains
FunctionResultContent, generate a fresh message ID for the tool result
rather than reusing the update's msgID. This prevents AG-UI clients from
incorrectly associating tool results with the wrong parent message.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
agent/hosting/aguihosting/agui_test.go | 68 ++++++++++++++++++++++++++
agent/hosting/aguihosting/events.go | 22 ++++++++-
2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/agent/hosting/aguihosting/agui_test.go b/agent/hosting/aguihosting/agui_test.go
index 1afe6aa3..0406224a 100644
--- a/agent/hosting/aguihosting/agui_test.go+++ b/agent/hosting/aguihosting/agui_test.go@@ -288,3 +288,71 @@ func TestHandler_UnknownDataContent_UsesCurrentMessageLifecycle(t *testing.T) {
t.Fatalf("expected fallback text to use current message id/content, got %q", content)
}
}
++// TestHandler_ToolResult_HasDistinctMessageID verifies that tool result events get a+// distinct message ID from the preceding text/tool-call message to avoid AG-UI+// message ID collisions (mirrors .NET fix in microsoft/agent-framework#5800).+func TestHandler_ToolResult_HasDistinctMessageID(t *testing.T) {+ a := newTestAgent(func(_ context.Context, _ []*message.Message, _ ...agent.Option) iter.Seq2[*agent.ResponseUpdate, error] {+ return func(yield func(*agent.ResponseUpdate, error) bool) {+ yield(&agent.ResponseUpdate{+ MessageID: "msg-stream-1",+ Role: message.RoleAssistant,+ Contents: message.Contents{&message.T
... (truncated)
Summary
When the agent (or underlying LLM provider) sets the same
MessageIDon both a streaming text/tool-call update and the subsequent tool result update, theToolCallResultAG-UI event ends up with the samemessageIdas theTextMessageStartevent. AG-UI clients that usemessageIdto correlate events then incorrectly associate the tool result with the text message.Fix: in
updatesToAGUIEvents, detect when an update containsFunctionResultContentand generate a freshmessageIdfor those events rather than reusing the update'smsgID. A newhasFunctionResultContenthelper is added to support this check.Changed files:
agent/hosting/aguihosting/events.go— generate a distincttoolResultMsgIDwhen the update containsFunctionResultContentagent/hosting/aguihosting/agui_test.go— addTestHandler_ToolResult_HasDistinctMessageIDcovering the collision scenarioPorted .NET PRs
Breaking Changes
No. The
ToolCallResultmessageIdfield changes from reusing the update'sMessageIDto a freshly generated ID, but this was already the intended AG-UI semantic and no existing public API contracts are changed.Tests and Examples
go test ./agent/hosting/aguihosting/...— all existing tests passTestHandler_ToolResult_HasDistinctMessageID: sets up an agent that emits text, tool-call, and tool-result updates all sharing the same explicitMessageID, then asserts that theTOOL_CALL_RESULTevent'smessageIddiffers from theTEXT_MESSAGE_STARTevent'smessageIdgo test ./...— all tests passNotes
The other new upstream commits (
c885ca3d#5895 OpenAI store-false helper fix,d81a8753#5838 StateBag edge-case tests,9b772f34#5894 OpenAIWebSearch observer) are .NET-only: OpenAI-specific C# extensions, test coverage for a .NETStateBagconcept absent from the Go SDK, and a harness console sample observer. None were ported.Upstream head inspected:
a60e541c(upstream-agent-framework/main at time of run).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
dotnet-port/agui-tool-result-message-id-5800-8c6a7fe5d95d95b3.Click here to create the pull request
To fix the permissions issue, go to Settings → Actions → General and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ
Show patch preview (147 of 147 lines)