Skip to content

fix(a2a): send append=True for the final chunk of a streamed artifact - #6686

Open
chelsealong wants to merge 1 commit into
google:mainfrom
chelsealong:fix-a2a-streaming-artifact-append-6680
Open

fix(a2a): send append=True for the final chunk of a streamed artifact#6686
chelsealong wants to merge 1 commit into
google:mainfrom
chelsealong:fix-a2a-streaming-artifact-append-6680

Conversation

@chelsealong

Copy link
Copy Markdown

Link to Issue or Description of Change

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

Problem:

google.adk.a2a.converters.from_adk_event.convert_event_to_a2a_events()
tracks in-flight streamed artifacts per agent in an agents_artifacts
dict so that later chunks can be marked append=True and appended to
the artifact created by the first chunk. For continuation chunks it
computed append = partial instead of append = True, so the final
chunk of a stream (partial=False) was sent with append=False.

Per the A2A task_manager.append_artifact_to_task semantics, an
append=False update for an artifact_id that already exists
replaces the artifact's parts wholesale rather than appending to
them. So the last chunk of any multi-chunk streamed text/artifact
response silently overwrites everything streamed before it, and the
consumer (e.g. a RemoteA2aAgent client, or any A2A client consuming
message:stream) ends up with only the tail of the response instead
of the full text — matching the truncation/dropped-content symptoms
described in #6680 for message:stream against agents that stream
multi-chunk responses.

Solution:

Once an artifact_id has already been established for an agent's
in-flight stream (i.e. a prior chunk created it with append=False),
every subsequent chunk — including the final, non-partial one — must
set append=True. last_chunk (derived from partial) already
signals when the stream ends; append should only be False for the
very first chunk that creates the artifact.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Added test_convert_event_to_a2a_events_final_chunk_appends, which
streams a first partial=True chunk (expects append=False, and the
artifact id gets tracked) followed by a final partial=False chunk
for the same agent (expects append=True, and the artifact id is
cleared from the tracking dict). Verified the new test fails against
the unfixed code (git checkout HEAD~1 -- src/.../from_adk_event.py)
with:

FAILED tests/unittests/a2a/converters/test_from_adk.py::TestFromAdk::test_convert_event_to_a2a_events_final_chunk_appends - assert False is True

With the fix applied, full local run:

$ pytest tests/unittests/a2a -q
442 passed, 45 skipped, 693 warnings in 4.87s

tests/unittests/a2a/converters/test_from_adk.py specifically:

17 passed, 7 warnings in 1.80s

Also verified formatting/import ordering with pyink --check and
isort --check on both changed files (no issues).

Manual End-to-End (E2E) Tests:

Not run — this fix targets a specific dict/flag bug in the ADK-side
A2A event converter and is covered by the unit test above; reproducing
the full deployed Agent Engine streaming scenario from the issue is
out of scope for this change.

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

This addresses one concrete, reproducible defect in the streaming
artifact path that #6680 exercises (convert_event_to_a2a_events,
used by the ADK A2aAgentExecutor when converting streamed ADK events
into TaskArtifactUpdateEvents, and consumed client-side by
RemoteA2aAgent/any A2A streaming client). The issue also describes a
distinct symptom (append=True for nonexistent artifact_id) and
truncation specifically against a deployed Vertex AI Agent Engine
target, which the reporter suspects may live in Agent Engine's own
REST-wrapped proxy layer rather than in google-adk or a2a-sdk
directly — this PR does not claim to resolve that half of the report,
only the append-flag bug found in this repo's own conversion code.

Note on AI assistance: this change was developed with the help of an
AI coding agent (Claude Code), including drafting the fix, the
regression test, and this PR description; the change was reviewed and
verified (tests run locally as shown above) before submission.

convert_event_to_a2a_events() set append=partial for continuation
chunks, so the final (non-partial) chunk of a multi-chunk streamed
artifact was sent with append=False. Per the A2A task_manager, an
append=False update replaces the artifact's parts entirely instead of
appending to them, silently discarding everything streamed before the
last chunk.

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

Labels

live [Component] This issue is related to live, voice and video chat

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants