Skip to content

fix(a2a): keep relayed HITL confirmations as function responses - #6759

Open
AAH20 wants to merge 1 commit into
google:mainfrom
AAH20:fix/a2a-relayed-hitl-flatten-bypass
Open

fix(a2a): keep relayed HITL confirmations as function responses#6759
AAH20 wants to merge 1 commit into
google:mainfrom
AAH20:fix/a2a-relayed-hitl-flatten-bypass

Conversation

@AAH20

@AAH20 AAH20 commented Aug 17, 2026

Copy link
Copy Markdown

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.
pytest tests/unittests/agents/test_remote_a2a_agent.py::TestHitlResumeRewrite -q
18 passed

New coverage in TestHitlResumeRewrite:

  • A confirmation / request-input pause authored by the remote peer is forwarded as a function_response DataPart (the peer can resume).
  • The same shape without a2a:response metadata still resumes (origin is author == self.name).
  • A local confirmation pause is still flattened (existing tests).
  • A credential sibling on a relayed confirmation resume is still dropped (aec7aa3).

Manual End-to-End (E2E) Tests:

The unit tests reconstruct the session shape from the issue's reproduction: the remote agent's long-running adk_request_confirmation (or adk_request_input) is in the caller's session, then the human's FunctionResponse. _create_a2a_request_for_user_function_response is the function that 2.7.0 used to flatten that answer into text.

I did not run the three-agent live chain from the issue (orchestrator → research → math with require_confirmation) because it needs Gemini keys and two A2A servers. The origin classification is the same path that chain hits.

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

RemoteA2aAgent in 2.7.0 (aec7aa3) flattens human-input answers by function-call name. That is correct for a pause the caller raised. A pause raised inside the remote agent and relayed up uses the same names (adk_request_confirmation, adk_request_input). Flattening it means the remote invocation never gets a FunctionResponse, so it cannot resume. Under the legacy executor the flattened JSON is accepted as a new user turn: the human approved, the gated tool never ran, and the caller is handed a fabricated tool result.

This change classifies by origin, not name:

  • If the matching function-call event is a remote response (_is_remote_response) or is authored by this RemoteA2aAgent, keep confirmation / request-input answers as function responses.
  • Local workflow / mock HITL pauses still flatten.
  • Credential and auth answers still drop, so the security intent of aec7aa3 is unchanged.

No Agent Action Gate vendoring. Soft pointers for teams whose agents are already in production with this pause shape:

Made with Cursor

2.7.0 flattened human-input answers by function-call name, so a nested
A2A confirmation became text and the remote peer never resumed. Classify
by origin: pauses authored by the remote agent stay FunctionResponses.
Local workflow pauses still flatten. Credentials still drop.

Fixes google#6721

Co-authored-by: Cursor <cursoragent@cursor.com>
@google-cla

google-cla Bot commented Aug 17, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

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.

A2A: 2.7.0 flattens the answer to a RELAYED human-input pause, so a remote agent can never resume (silent approval-gate bypass)

2 participants