Skip to content

feat: support metadata providers for remote A2A messages - #1679

Open
YuqiGuo105 wants to merge 1 commit into
google:mainfrom
YuqiGuo105:fix/issue-1438-a2a-metadata-local
Open

YuqiGuo105 wants to merge 1 commit into
google:mainfrom
YuqiGuo105:fix/issue-1438-a2a-metadata-local

Conversation

@YuqiGuo105

@YuqiGuo105 YuqiGuo105 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Link to Issue or Description of Change

Closes #1438.

Problem:
RemoteA2AAgent has no application hook for populating an outgoing A2A message's metadata. Applications cannot explicitly pass selected context, such as a user or tenant identifier, without mixing it into conversation content.

Solution:

  • Add the optional A2ARequestMetadataProvider callback and RemoteA2AAgent.Builder.requestMetadataProvider(...).
  • Invoke the provider for each outgoing message after its parts and identifiers have been populated, including function-call continuations.
  • Attach a shallow copy of the returned map to Message.metadata. Preserve existing behavior when no provider is configured or the provider returns null; stop the send if the provider throws.
  • Do not forward session state automatically or impose a fixed set of metadata keys.

Example builder configuration:

.requestMetadataProvider((context, message) ->
    Map.of("user_id", context.session().state().get("user_id")))

Testing Plan

Unit Tests:

  • Added 12 regression tests covering opt-in selection, default/null/empty behavior, provider reevaluation, message/task/context preservation, defensive copying, callback failure, and an empty session.
  • Verified metadata survives the SDK models' JSON serialization/deserialization and remains distinct from request-level metadata.
  • Verified an ADK receiver can read message metadata in its beforeExecuteCallback, while existing request metadata propagation into RunConfig is unchanged.
  • Ran ./mvnw -o -q -pl a2a -am test: the full core and A2A module test suites pass, including all 151 A2A tests.
  • Ran git diff --check and applied the repository's Google Java formatting.

Manual End-to-End (E2E) Tests:

Not run against a deployed remote agent. The tests exercise the sender, the SDK's JSON models, and the receiver callback locally; they do not claim transport-level E2E coverage. No model credentials or external services are needed for these tests.

Checklist

  • I have read CONTRIBUTING.md.
  • My pull request contains a single commit.
  • I have performed a self-review of my own code.
  • Added concise Javadocs for the callback and its semantics.
  • New and existing unit tests pass locally.
  • I have manually tested my changes end-to-end.

Additional context

This implements message-level metadata, as requested by #1438. On an ADK receiver it is readable via RequestContext.getMessage().getMetadata(). It is not automatically copied into session state or RunConfig.customMetadata(); the latter's existing a2a_metadata path consumes request-envelope metadata instead.

The current Python a2a_request_meta_provider populates request-level metadata. This PR does not claim identical wire semantics: request-envelope metadata and transport authentication headers are intentionally out of scope here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RemoteA2AAgent never attaches Message.metadata() - no way to propagate any custom data to the remote agent

1 participant