Repository navigation
fix(a2a): keep metadata-only messages in convert_a2a_message_to_event - #7705
Open
danieldutu wants to merge 1 commit into
Open
danieldutu wants to merge 1 commit into
danieldutu wants to merge 1 commit into
Conversation
A2A message with parts=[] and adk_custom_metadata came back as None (1 of 1 repro runs on f08f9d6). The peer's custom_metadata, usage_metadata, error_code, grounding_metadata and citation_metadata were lost. _create_event (to_adk_event.py:215-220) returns None when there are no parts and no actions. convert_a2a_message_to_event extracted the metadata fields but never told _create_event that they count as content. The message converter now passes allow_empty_event=True when any extracted metadata field is set. The event keeps content=None. The task and status update converters are unchanged: test_contentless_progress_does_not_emit_a_final_response requires metadata-only progress to stay dropped on those paths. Evidence: the new test fails on main (1 failed, 97 passed) and passes with the change (98 passed). tests/unittests/a2a: 949 passed, 57 skipped. Fixes google#5185
BichengWang
approved these changes
Oct 23, 2026
BichengWang
left a comment
Contributor
There was a problem hiding this comment.
Validated at 667a8a1a4cf3bb2e95ad2a00139558cab25d53fd. The new regression fails on current main and passes here. The A2A suite passes locally: 949 passed, 57 skipped; changed-file pre-commit checks pass.
I also checked each restored metadata field with native and JSON-string inputs, including zero token usage, plus empty messages and rejected peer state/transfer actions. The message-only condition preserves those fields without changing task/status progress filtering. I found no blocking issue in this change. Validation used Python 3.11 and a2a-sdk 1.2.3; I did not run the 0.3 SDK path or full tox matrix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to Issue
Fixes #5185
Problem
convert_a2a_message_to_eventreturnsNonefor an A2A message withparts=[]and only restored metadata. On main (f08f9d6), a message carryingadk_custom_metadata={"flag": True}was dropped in 1 of 1 runs, and the peer'scustom_metadata,usage_metadata,error_code,grounding_metadataandcitation_metadatawere lost with it._create_event(to_adk_event.py:215-220) returnsNonewhen there are no parts and no actions. The message converter extracts the metadata fields at:656but does not mark them as content.Solution
convert_a2a_message_to_eventnow passesallow_empty_event=any(metadata_fields.values()). The event keepscontent=Noneand carries the restored metadata. Peer actions stay filtered by_PEER_SETTABLE_ACTION_FIELDS, so the untrusted-metadata rule is unchanged.Relation to earlier PRs: #5222 (closed 2026-05-12, formatting requested) and #5205 (closed 2026-08-12 as superseded) both changed
_create_eventfor all callers and added their own metadata extraction. Main now restores the metadata fields through_extract_genai_metadata, so this change adds only the missing message-path condition.I did not change
_create_eventfor all callers. That variant fails 3 cases oftest_contentless_progress_does_not_emit_a_final_response: a content-less event on task and status-update paths counts as a final response. I can widen the change to those paths if you prefer, together with a change to that test.Testing Plan
Unit tests:
The new test
test_convert_a2a_message_to_event_returns_metadata_only_eventfails on main (1 failed, 97 passed) and passes with the change.E2E log, repro from the issue (
PYTHONPATH=src uv run python repro5185.py):uv run pre-commit run --files <touched files>: pyink, addlicense, ADK compliance checks, doc links, codespell passed.Checklist
Not covered:
long_running_tool_idsis not read from message-level metadata. GWeale asked for a separate issue. The task and status-update converters still drop metadata-only progress, as the existing tests require. Tested with a2a protobuf 1.x only; the 0.3.x path was not run.