Skip to content

[dotnet-port] Port AGUI parallel tool call rendering fixes #216

Description

@github-actions

Summary

Ports two of the three bugs fixed in the upstream .NET commit de6d0267 (microsoft/agent-framework#6009) that prevent parallel tool calls from rendering correctly in AG-UI protocol clients.

Bug #2 — Deterministic result-{callID} message ID for tool results (events.go)

Tool result events now use "result-" + callID as their message ID instead of sharing a single randomly-generated ID across an entire update batch. When a batch contains multiple FunctionResultContent items (parallel tool results), all of them previously received the same generated UUID, causing the AG-UI frontend to collapse them into one entry during React reconciliation. The result-{callID} format is both unique per call and deterministic, matching the .NET fix exactly. The now-unused hasFunctionResultContent helper is removed.

Bug #3 — Coalesce consecutive assistant-tool-call messages (convert.go)

When toAgentMessages converts incoming AGUI messages from the frontend, it now merges consecutive assistant messages that each carry tool calls into a single message.Message before handing them to the agent. The AG-UI client emits one assistant message per tool call when parentMessageId is absent. Forwarding these as separate messages to an OpenAI-compatible provider triggers HTTP 400 ("tool_call_ids did not have response messages") because the API requires every assistant message with tool_calls to be immediately followed by tool results for each of its call IDs.

Note: Bug #1 from the upstream commit (synthetic streamingMessageId leaking into ToolCallStartEvent.ParentMessageId) does not apply here — Go's contentToEvents for FunctionCallContent never used the text-streaming message ID as a parent ID for tool call events.

Ported .NET PRs

Breaking Changes

No. The result-{callID} format is more correct; existing consumers should not depend on the specific format of the generated message IDs in tool result events.

Tests and Examples

  • TestHandler_ToolResult_HasDistinctMessageID — updated to assert the exact result-call-1 format
  • TestHandler_ParallelToolResults_HaveUniqueMessageIDs — new: verifies two parallel results get result-c1 and result-c2 respectively
  • TestHandler_ConsecutiveAssistantToolCallMessages_Coalesced — new: verifies that two consecutive frontend assistant messages each carrying one tool call are merged into a single agent message with both tool calls

All aguihosting package tests pass.

Notes

The upstream commit also touches AGUIStreamingMessageIdTests.cs and AGUIChatMessageExtensionsTests.cs on the .NET side; the Go test additions above cover the equivalent behaviour. The dc4bafbc (Hosted-AgentSkills sample) and 0099a6e2 (HarnessConsole rendering) commits in the same window are not applicable to the Go SDK.

Generated by .NET to Go Porting Agent · ● 23.2M ·


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-parallel-tool-calls-6b801f88e2f9a670.

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 (293 of 293 lines)
From adbeea4d0578f880cff07cdc8fd7e8541d5af0fc Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Mon, 25 May 2026 10:29:11 +0000
Subject: [PATCH] Port AGUI parallel tool call rendering fixes from .NET #6009

Fix two bugs that prevent parallel tool calls from rendering correctly
in AG-UI protocol clients:

Bug #2: Make ToolCallResultEvent.MessageId deterministically unique
using result-{callId} format. Multiple tool results in the same update
batch previously shared a single generated message ID, collapsing them
in FE reconciliation.

Bug #3: Coalesce consecutive assistant-with-tool-calls messages in
toAgentMessages. The AG-UI client creates one assistant message per
tool call when parentMessageId is absent. Sending them as separate
messages to the LLM triggers HTTP 400 because OpenAI requires tool
results to immediately follow every tool_call_id in an assistant message.

Also removes the now-dead hasFunctionResultContent helper.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 agent/hosting/aguihosting/agui_test.go | 120 ++++++++++++++++++++++++-
 agent/hosting/aguihosting/convert.go   |  35 +++++++-
 agent/hosting/aguihosting/events.go    |  31 ++-----
 3 files changed, 156 insertions(+), 30 deletions(-)

diff --git a/agent/hosting/aguihosting/agui_test.go b/agent/hosting/aguihosting/agui_test.go
index 0406224a..ff1c707f 100644
--- a/agent/hosting/aguihosting/agui_test.go
+++ b/agent/hosting/aguihosting/agui_test.go
@@ -290,8 +290,8 @@ func TestHandler_UnknownDataContent_UsesCurrentMessageLifecycle(t *testing.T) {
 }
 
 // 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).
+// deterministic message ID in "result-{callID}" format, distinct from the preceding
+// text/tool-call message (mirrors .NE
... (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