Skip to content

Legacy A2A executor finalizes metadata-only responses as status=working instead of completed #5188

Closed

Description

@YizukiAme

Bug Description

The legacy A2aAgentExecutor in a2a_agent_executor.py has several finalization issues:

  1. Wrong terminal status: When the final ADK event has no content parts (metadata-only or action-only), finalization produces final=True with status=working instead of completed, leaving clients with a "still processing" Task that never updates.

  2. Truncated streaming text: Delta-style text streaming only retains the last chunk; earlier partial text is discarded in the synthesized final artifact.

  3. Missing artifact metadata: The synthesized final TaskArtifactUpdateEvent does not carry response metadata, so Task.artifacts[*].metadata is empty.

Expected Behavior

  • Finalization without failure/interaction should produce status=completed
  • Streamed text chunks should be accumulated for the final artifact
  • Final artifact events should propagate response metadata

Affected Files

  • src/google/adk/a2a/executor/a2a_agent_executor.py

Activity

  1. added
    core[Component] This issue is related to the core interface and implementation
    on Apr 7, 2026
  2. added theissue type on Apr 7, 2026
  3. enjoykumawat commented on Apr 7, 2026

    @enjoykumawat
    Contributor

    I'd like to work on this. Will fix the finalization logic to correctly set status=completed for metadata-only responses. PR incoming.

  4. surajksharma07 commented on Apr 8, 2026

    @surajksharma07
    Collaborator

    @YizukiAme All three bugs trace back to the same two spots: TaskResultAggregator.process_event overwrites _task_status_message on each chunk instead of extending parts (which is what causes the truncation), and the finalization else-branch in _handle_request blindly uses task_state which never leaves working on a clean run — hence the wrong terminal state.

    As a workaround, try patching process_event to accumulate parts instead of overwriting, and add a working → completed promotion in the else-branch.
    That should cover both issues — could you give that a try and confirm it holds up on your end?

    And thanks to @enjoykumawat for jumping on this too!
    Once the workaround is verified, that'd be a great baseline to anchor the PR against.

  5. YizukiAme commented on Apr 9, 2026

    @YizukiAme
    Author

    @surajksharma07 Thanks for the detailed root-cause analysis — it matches exactly what I found when investigating this!

    I've already verified a fix locally that addresses both spots you mentioned:

    1. Streaming text truncation: I introduced a _merge_streamed_text_parts() helper that accumulates text across working status chunks instead of letting process_event overwrite them. It also handles the snapshot-vs-delta ambiguity (if a new chunk already contains the previous text, it deduplicates rather than double-appending).

    2. working → completed promotion: The else-branch now unconditionally promotes to completed when no failure or interaction pause occurred, regardless of whether there are final content parts.

    I also added metadata propagation for the synthesized final artifact, so Task.artifacts[*].metadata carries the last response's semantic metadata.

    All A2A executor + integration tests pass with these changes. Happy to share the diff or help @enjoykumawat with the PR if needed!

  6. surajksharma07 commented on Apr 9, 2026

    @surajksharma07
    Collaborator

    @YizukiAme — great work on the local verification, that's really thorough!
    And the snapshot-vs-delta deduplication in _merge_streamed_text_parts() is a smart edge case to catch — good thinking.

    PR #5225 is already open and linked to close this, and your diff and test results would be really valuable input there.
    Would you be open to sharing the diff directly on #5225 or syncing with @giulio-leone?
    Having your working implementation as a reference should make the review a lot smoother!

    Team is looking more into it.

  7. surajksharma07 commented on May 22, 2026

    @surajksharma07
    Collaborator

    @YizukiAme — since we haven't heard back since tagging you on Apr 9 about contributing your local fix to PR #5225, and that PR from @giulio-leone is already open tracking the same root cause, going ahead and closing this out to keep things tidy.

    The underlying fixes for all three finalization bugs will continue through #5225 — if you'd still like to contribute your _merge_streamed_text_parts() implementation or the metadata propagation piece, that's the best place to do it and it'd make the review a lot stronger.

    Feel free to reopen if anything changes on your end, and thanks again for the thorough report that got the ball rolling on this!

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

Metadata

Metadata

Labels

core[Component] This issue is related to the core interface and implementationrequest clarification[Status] The maintainer need clarification or more information from the author

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions