Python: Propagate A2A metadata from Message, Artifact, Task, and event types by kartikmadan11 · Pull Request #5256 · microsoft/agent-framework
Motivation and Context
The A2A protocol defines a metadata field on Message, Artifact, Task, TaskStatusUpdateEvent, and TaskArtifactUpdateEvent. Currently, A2AAgent only propagates Part-level metadata (via _parse_contents_from_a2a), but silently drops metadata at every other level, losing information transmitted by the server.
Fixes #5240
Description
Metadata is now propagated at each conversion boundary in _agent.py, namespaced under an "a2a_metadata" key inside additional_properties to avoid collisions with other framework code that may also populate additional_properties.
| A2A Type | Target | How |
|---|---|---|
Message |
AgentResponseUpdate.additional_properties["a2a_metadata"] |
{"a2a_metadata": message.metadata} |
Artifact |
intermediate Message.additional_properties → merged into update |
{"a2a_metadata": {**artifact.metadata, **task.metadata}} |
Task |
AgentResponseUpdate.additional_properties["a2a_metadata"] |
{"a2a_metadata": task.metadata} on all updates produced from the task |
TaskArtifactUpdateEvent |
AgentResponseUpdate.additional_properties["a2a_metadata"] |
{"a2a_metadata": {**artifact.metadata, **event.metadata}} merged |
TaskStatusUpdateEvent |
AgentResponseUpdate.additional_properties["a2a_metadata"] |
{"a2a_metadata": {**message.metadata, **event.metadata}} merged |
History Message |
Message.additional_properties |
{"a2a_metadata": history_item.metadata} |
On the outbound side, _prepare_message_for_a2a reads message.additional_properties.get("a2a_metadata") to reconstruct wire metadata cleanly.
For streaming events, metadata from the inner object (artifact or status message) is merged with the outer event metadata, since they represent different layers of information.
Eight regression tests cover all affected types plus a None-safety check.
Contribution Checklist
- The code builds clean without any errors or warnings
- The PR follows the Contribution Guidelines
- All unit tests pass (74/74 in a2a package), and I have added new tests where possible
- Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.