Skip to content

fix(a2a): recover completed peers when a paused caller resumes - #7849

Open
Samecho wants to merge 1 commit into
google:mainfrom
Samecho:codex/a2a-paused-task-check
Open

Samecho wants to merge 1 commit into
google:mainfrom
Samecho:codex/a2a-paused-task-check

Conversation

@Samecho

@Samecho Samecho commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

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

Link to Issue or Description of Change

Problem:

A task-mode peer can finish after receiving a confirmation directly. When the caller later resumes, it still sends a message to the completed task and returns a terminal-state error instead of the result.

Solution:

On the caller's next turn, use GetTask to check the recorded peer task before continuing the paused delegation. Recover the matching finish_task arguments from the returned task or its agent-authored history, then complete the delegation with the existing output-schema handling. Keep the caller context from the before-request hooks and persist only the lookup status.

This covers ADK task-mode peers that complete successfully through finish_task. The plain chat LlmAgent in the original reproduction does not emit that marker, so its completion is tracked in #7251. FAILED and CANCELED peer tasks still follow the existing send path.

The check uses the latest paused task in the current delegation and context. A peer still waiting for input follows the existing send path. Custom inbound converters and after-request hooks retain their existing routing behavior.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally. See the earlier full-suite results below.

After rebasing onto dc7d743, I reran the A2A and agent registry unit tests on Python 3.13. With a2a-sdk 1.2.3, 1,113 passed and 57 skipped. With 0.3.26, 1,141 passed and 29 skipped.

In the earlier run, all eight main regression cases failed against unchanged production code at 392feb2. They cover both converter paths, wrapped and primitive output, and completion calls stored in the task snapshot or history. Additional cases cover mismatched tasks, user-authored history, lookup errors, private-input persistence and caller context. Existing continuation tests also check that stale or unrelated tasks are not queried.

The original local A2A runs at 6219432 passed with both SDK versions. The local type comparison introduced no new errors, and applicable pre-commit checks passed.

The earlier Linux fork run at 6219432 passed pre-commit, the full-project type comparison on Python 3.11–3.13, and the A2A 0.3, A2A 1.2.3 and MCP v2 suites on Python 3.11–3.14. Both installed-wheel E2E checks passed.

Full unit-suite results from that earlier run

Python Passed Failed Skipped
3.11 22,034 14 96
3.12 22,025 14 97
3.13 22,025 14 97
3.14 22,027 14 95

Each run has the same 14 baseline failures: the custom-factory test with A2A SDK 1.3 (_httpx_client, tracked in #7777) and 13 telemetry schema comparisons. I reran those tests against unchanged 392feb2 in the same resolved environment; the failing test IDs and error messages match exactly. The full-suite jobs remain red, and no tests were excluded to hide these failures. Each version also reports 12 expected failures and 2 unexpected passes.

Manual End-to-End (E2E) Tests:

Adapted the reporter's in-process setup to serve the peer as an ADK task-mode agent. Before the fix, resuming the caller sends another message to the completed task and returns an error. With the fix, both executor versions retrieve the result with GetTask, the coordinator completes, and the tool executes once. No live model or cloud credentials are needed.

I reran the same in-process test from a fresh wheel built from 568f7a6, with a2a-sdk 1.2.3. Both the legacy and V2 executors completed on the caller's next turn. The caller's peer requests were SendStreamingMessage and GetTask, and the tool ran once. Earlier fork validation.

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. See the earlier full-suite results.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules. No dependent changes are required.

Additional context

This addresses next-turn reconciliation in #7811. Background subscription, polling and automatic caller wake-up remain part of that issue.

Prepared with Codex.

Read the recorded peer task before continuing a paused task-mode delegation.
Recover its matching finish_task result when the peer completed out of band,
without forwarding the peer's private conversation history.

Related google#7811
@Samecho
Samecho force-pushed the codex/a2a-paused-task-check branch from 6219432 to 568f7a6 Compare November 10, 2026 19:59
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.

1 participant