Skip to content

.NET: fix: preserve AG-UI event metadata - #5816

Closed
Yufeng He (he-yufeng) wants to merge 2 commits into
microsoft:mainfrom
he-yufeng:fix/agui-text-additional-properties
Closed

.NET: fix: preserve AG-UI event metadata#5816
Yufeng He (he-yufeng) wants to merge 2 commits into
microsoft:mainfrom
he-yufeng:fix/agui-text-additional-properties

Conversation

@he-yufeng

Copy link
Copy Markdown
Contributor

Summary

  • preserve TextContent.AdditionalProperties as AG-UI passthrough fields on text start/content events
  • preserve event passthrough fields when converting AG-UI text events back to TextContent
  • carry DataContent.AdditionalProperties through state snapshot/delta events as the same passthrough metadata path
  • filter event-owned fields like type, messageId, delta, and snapshot so metadata cannot shadow AG-UI protocol fields

Fixes #4923

Validation

  • dotnet run --project dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\Microsoft.Agents.AI.AGUI.UnitTests.csproj --framework net10.0 -- --filter-class Microsoft.Agents.AI.AGUI.UnitTests.ChatResponseUpdateAGUIExtensionsTests
  • dotnet run --project dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\Microsoft.Agents.AI.AGUI.UnitTests.csproj --framework net10.0
  • dotnet format dotnet\agent-framework-dotnet.slnx --verify-no-changes --include dotnet\src\Microsoft.Agents.AI.AGUI\Shared\BaseEvent.cs dotnet\src\Microsoft.Agents.AI.AGUI\Shared\ChatResponseUpdateAGUIExtensions.cs dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\ChatResponseUpdateAGUIExtensionsTests.cs
  • git diff --check

Copilot AI review requested due to automatic review settings May 13, 2026 16:11
@moonbox3 Evan Mattson (moonbox3) added the .NET Usage: [Issues, PRs], Target: .Net label May 13, 2026
@github-actions github-actions Bot changed the title fix: preserve AG-UI event metadata .NET: fix: preserve AG-UI event metadata May 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the .NET AG-UI adapter layer to preserve AIContent.AdditionalProperties as AG-UI “passthrough” JSON fields when converting between ChatResponseUpdate streams and AG-UI event streams, while filtering reserved protocol-owned field names so they can’t be shadowed by metadata.

Changes:

  • Add JsonExtensionData support to AG-UI events (BaseEvent) to carry arbitrary passthrough fields.
  • Preserve passthrough metadata across conversions (TextContentTEXT_MESSAGE_* events, DataContentSTATE_* events) with reserved-field filtering.
  • Add unit tests validating passthrough emission, filtering of reserved fields, and round-tripping back into AIContent.

Reviewed changes

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

File Description
dotnet/src/Microsoft.Agents.AI.AGUI/Shared/BaseEvent.cs Adds JsonExtensionData-backed AdditionalProperties for AG-UI passthrough fields on all events.
dotnet/src/Microsoft.Agents.AI.AGUI/Shared/ChatResponseUpdateAGUIExtensions.cs Copies AdditionalProperties between AIContent and events and filters reserved protocol fields during event emission.
dotnet/tests/Microsoft.Agents.AI.AGUI.UnitTests/ChatResponseUpdateAGUIExtensionsTests.cs Adds coverage for preserving passthrough metadata and ensuring reserved fields aren’t shadowed in serialized output.

@he-yufeng

Copy link
Copy Markdown
Contributor Author

Addressed both review comments in a follow-up commit.

Changes:

  • TextMessageBuilder now captures passthrough metadata from TextMessageStartEvent and merges it into emitted TextContent.AdditionalProperties.
  • When the same key exists on START and CONTENT, the CONTENT value wins.
  • BaseEventJsonConverter.Read now maps STATE_DELTA to StateDeltaEvent, matching the existing write path.
  • Added tests for START metadata merging and STATE_DELTA BaseEvent deserialization.

Local validation:

dotnet build dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\Microsoft.Agents.AI.AGUI.UnitTests.csproj --no-restore
dotnet dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\bin\Debug\net10.0\Microsoft.Agents.AI.AGUI.UnitTests.dll --filter-method '*AsChatResponseUpdatesAsync_WithTextStartAdditionalProperties_PreservesAndMergesMetadataAsync' --filter-method '*BaseEventJsonConverter_WithStateDeltaEvent_DeserializesStateDeltaEvent' --filter-method '*AsAGUIEventStreamAsync_ConvertsDataContentWithJsonPatch_ToStateDeltaEventAsync' --filter-method '*AsChatResponseUpdatesAsync_WithTextEventAdditionalProperties_PreservesTextContentMetadataAsync' --no-progress
dotnet format dotnet\agent-framework-dotnet.slnx --verify-no-changes --no-restore --include dotnet\src\Microsoft.Agents.AI.AGUI\Shared\ChatResponseUpdateAGUIExtensions.cs dotnet\src\Microsoft.Agents.AI.AGUI\Shared\BaseEventJsonConverter.cs dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\ChatResponseUpdateAGUIExtensionsTests.cs
git diff --check

Result: build succeeded with 0 warnings/errors; 4 targeted tests passed; format and diff checks passed.

Note: dotnet test with this .NET 10 SDK hits the Microsoft.Testing.Platform/VSTest transition error, so I used the built MTP test assembly directly for the targeted run.

@he-yufeng
Yufeng He (he-yufeng) force-pushed the fix/agui-text-additional-properties branch from 3c5586b to b04daf6 Compare May 14, 2026 14:33
@he-yufeng

Copy link
Copy Markdown
Contributor Author

Rebased this branch onto current main and force-pushed with lease. Re-ran the focused AG-UI validation after the rebase: AGUI unit-test project build passed with 0 warnings/errors; the text START metadata test, StateDelta BaseEvent converter test, JSON Patch StateDelta emission test, and existing text-event metadata test all passed; dotnet format --verify-no-changes passed for the touched files; git diff --check passed.

@he-yufeng

Copy link
Copy Markdown
Contributor Author

Merged current upstream/main into this branch and re-ran the focused AG-UI validation.

Validation:

dotnet build dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\Microsoft.Agents.AI.AGUI.UnitTests.csproj --no-restore
dotnet dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\bin\Debug\net10.0\Microsoft.Agents.AI.AGUI.UnitTests.dll --filter-method '*AsChatResponseUpdatesAsync_WithTextStartAdditionalProperties_PreservesAndMergesMetadataAsync' --filter-method '*BaseEventJsonConverter_WithStateDeltaEvent_DeserializesStateDeltaEvent' --filter-method '*AsAGUIEventStreamAsync_ConvertsDataContentWithJsonPatch_ToStateDeltaEventAsync' --filter-method '*AsChatResponseUpdatesAsync_WithTextEventAdditionalProperties_PreservesTextContentMetadataAsync' --no-progress
dotnet format dotnet\agent-framework-dotnet.slnx --verify-no-changes --no-restore --include dotnet\src\Microsoft.Agents.AI.AGUI\Shared\ChatResponseUpdateAGUIExtensions.cs dotnet\src\Microsoft.Agents.AI.AGUI\Shared\BaseEventJsonConverter.cs dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\ChatResponseUpdateAGUIExtensionsTests.cs
git diff --check

Result: build passed with 0 warnings/errors, 4 targeted tests passed, format and diff checks passed.

@moonbox3

Copy link
Copy Markdown
Contributor

Yufeng He (@he-yufeng) please have a look at the conflicted file. Thanks.

@he-yufeng

Copy link
Copy Markdown
Contributor Author

Resolved the current conflict in ChatResponseUpdateAGUIExtensions.cs and rebased onto latest microsoft:main.

The conflict was between the newer textMessageId fallback logic on main and this PR's START-event metadata preservation. I kept both: the start/end/content events still use textMessageId, and TextMessageStartEvent still receives copied TextContent.AdditionalProperties with AG-UI reserved fields filtered.

Validation:

dotnet build dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\Microsoft.Agents.AI.AGUI.UnitTests.csproj --tl:off
# succeeded, 0 warnings, 0 errors

dotnet dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\bin\Debug\net10.0\Microsoft.Agents.AI.AGUI.UnitTests.dll --filter-method '*AsChatResponseUpdatesAsync_WithTextStartAdditionalProperties_PreservesAndMergesMetadataAsync' --filter-method '*BaseEventJsonConverter_WithStateDeltaEvent_DeserializesStateDeltaEvent' --filter-method '*AsAGUIEventStreamAsync_ConvertsDataContentWithJsonPatch_ToStateDeltaEventAsync' --filter-method '*AsChatResponseUpdatesAsync_WithTextEventAdditionalProperties_PreservesTextContentMetadataAsync' --no-progress
# 4 passed

dotnet format dotnet\agent-framework-dotnet.slnx --verify-no-changes --no-restore --include dotnet\src\Microsoft.Agents.AI.AGUI\Shared\ChatResponseUpdateAGUIExtensions.cs dotnet\src\Microsoft.Agents.AI.AGUI\Shared\BaseEventJsonConverter.cs dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\ChatResponseUpdateAGUIExtensionsTests.cs

git diff --check

@he-yufeng
Yufeng He (he-yufeng) force-pushed the fix/agui-text-additional-properties branch from b5712e9 to 614846a Compare June 4, 2026 20:18
@he-yufeng

Copy link
Copy Markdown
Contributor Author

Rebased this branch onto current microsoft:main and pushed 614846a5.

There were no conflicts in the latest rebase; this just brings the AG-UI metadata patch back up to date with main.

Validation on Windows:

dotnet build dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\Microsoft.Agents.AI.AGUI.UnitTests.csproj --tl:off
# succeeded, 0 warnings, 0 errors

dotnet dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\bin\Debug\net10.0\Microsoft.Agents.AI.AGUI.UnitTests.dll --filter-method '*AsChatResponseUpdatesAsync_WithTextStartAdditionalProperties_PreservesAndMergesMetadataAsync' --filter-method '*BaseEventJsonConverter_WithStateDeltaEvent_DeserializesStateDeltaEvent' --filter-method '*AsAGUIEventStreamAsync_ConvertsDataContentWithJsonPatch_ToStateDeltaEventAsync' --filter-method '*AsChatResponseUpdatesAsync_WithTextEventAdditionalProperties_PreservesTextContentMetadataAsync' --no-progress
# 4 passed

dotnet format dotnet\agent-framework-dotnet.slnx --verify-no-changes --no-restore --include dotnet\src\Microsoft.Agents.AI.AGUI\Shared\ChatResponseUpdateAGUIExtensions.cs dotnet\src\Microsoft.Agents.AI.AGUI\Shared\BaseEventJsonConverter.cs dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\ChatResponseUpdateAGUIExtensionsTests.cs
# exit 0; workspace load warning only

git diff --check
# passed

@he-yufeng
Yufeng He (he-yufeng) force-pushed the fix/agui-text-additional-properties branch from 614846a to 997ace5 Compare June 4, 2026 20:22
@he-yufeng

Copy link
Copy Markdown
Contributor Author

One more main commit landed while I was updating the branch, so I rebased again and pushed 997ace53.

Current local check against the latest fetched upstream/main:

git rev-list --left-right --count HEAD...upstream/main
# 2 0

Validation after the second rebase:

dotnet build dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\Microsoft.Agents.AI.AGUI.UnitTests.csproj --tl:off
# succeeded, 0 warnings, 0 errors

dotnet dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\bin\Debug\net10.0\Microsoft.Agents.AI.AGUI.UnitTests.dll --filter-method '*AsChatResponseUpdatesAsync_WithTextStartAdditionalProperties_PreservesAndMergesMetadataAsync' --filter-method '*BaseEventJsonConverter_WithStateDeltaEvent_DeserializesStateDeltaEvent' --filter-method '*AsAGUIEventStreamAsync_ConvertsDataContentWithJsonPatch_ToStateDeltaEventAsync' --filter-method '*AsChatResponseUpdatesAsync_WithTextEventAdditionalProperties_PreservesTextContentMetadataAsync' --no-progress
# 4 passed

dotnet format dotnet\agent-framework-dotnet.slnx --verify-no-changes --no-restore --include dotnet\src\Microsoft.Agents.AI.AGUI\Shared\ChatResponseUpdateAGUIExtensions.cs dotnet\src\Microsoft.Agents.AI.AGUI\Shared\BaseEventJsonConverter.cs dotnet\tests\Microsoft.Agents.AI.AGUI.UnitTests\ChatResponseUpdateAGUIExtensionsTests.cs
# exit 0; workspace load warning only

git diff --check
# passed

@he-yufeng

Copy link
Copy Markdown
Contributor Author

Gentle ping on this AG-UI metadata preservation fix. The branch has two approvals, the focused AG-UI validation passed after the last rebase, and current checks are green.

The patch still keeps reserved AG-UI protocol fields filtered while preserving user metadata through the event/content conversions. Happy to rebase again if maintainers want a fresher head before landing.

@he-yufeng

Copy link
Copy Markdown
Contributor Author

Same story as the other AG-UI PRs: #6653 swapped the in-tree AG-UI abstractions (Shared/BaseEvent.cs, BaseEventJsonConverter.cs, ChatResponseUpdateAGUIExtensions.cs) for the external AG-UI C# SDK and deleted that directory, so this can no longer be rebased. Closing. Thanks Jacob Alber (@lokitoth) Evan Mattson (@moonbox3) for the reviews — the metadata-preservation behavior would need to move to the AGUI.Server SDK now, which I'll check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET Usage: [Issues, PRs], Target: .Net

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET: [Bug]: TextContent.AdditionalProperties dropped by AsAGUIEventStreamAsync for TEXT_MESSAGE_START/TEXT_MESSAGE_CONTENT events

4 participants