Skip to content

feat(a2a): save artifacts returned by RemoteA2aAgent to the orchestrator session#6184

Open
vaibhav-patel wants to merge 2 commits into
google:mainfrom
vaibhav-patel:fix/3145-remotea2a-artifacts
Open

feat(a2a): save artifacts returned by RemoteA2aAgent to the orchestrator session#6184
vaibhav-patel wants to merge 2 commits into
google:mainfrom
vaibhav-patel:fix/3145-remotea2a-artifacts

Conversation

@vaibhav-patel

Copy link
Copy Markdown

Summary

Fixes #3145.

When a RemoteA2aAgent receives artifacts (e.g. files) from a remote A2A agent, they are now persisted into the orchestrator (parent) session's artifact service, so downstream/sibling agents can load them via context.load_artifact(...).

Previously, artifacts in an A2A response were only flattened into the event's content parts (convert_a2a_task_to_event) and never written to the artifact service, so the orchestrator had no durable, named handle to the returned files.

What changed

  • New best-effort helper RemoteA2aAgent._save_a2a_artifacts_to_session(...) that:
    • saves each artifact's blob-like part (FilePart / FileWithBytes / FileWithUri, or inline data) under the artifact's name (falling back to its artifact_id);
    • records the saved version on the event's actions.artifact_delta;
    • is a no-op when no artifact service is configured, and never breaks A2A response handling on a per-artifact failure.
  • Wired into both the legacy (_handle_a2a_response) and v2 (_handle_a2a_response_v2) handlers, covering full-task responses (task.artifacts) and streaming artifact updates (TaskArtifactUpdateEvent.artifact).
  • This is the client-side counterpart to the existing server-side include_artifacts_in_a2a_event interceptor, completing the artifact round-trip across the A2A boundary.

Tests

  • New TestRemoteA2aAgentArtifactPersistence (7 tests) using a real InMemoryArtifactService and real A2A objects, asserting artifacts land in the service and artifact_delta is populated; covers inline bytes, file-by-URI, multiple artifacts, artifact_id fallback, no-service no-op, and text-only (skipped) artifacts.
  • All existing RemoteA2aAgent and a2a unit tests pass (467 passed locally).

Note: experimental A2A surface (@a2a_experimental); behavior is additive and gated on an artifact service being present.

When a RemoteA2aAgent receives artifacts (e.g. files) from a remote A2A
agent, persist them into the orchestrator (parent) session's artifact
service so downstream agents can load them via context.load_artifact.

Previously, A2A artifacts were only flattened into the event's content
parts and never written to the artifact service, so the orchestrator and
sibling agents had no durable, named handle to the returned files.

Both the full-task response (task.artifacts) and streaming artifact
updates (TaskArtifactUpdateEvent.artifact) are handled, in the legacy and
v2 response handlers. Each artifact's blob-like part (FilePart /
FileWithBytes / FileWithUri, or inline data) is saved under the
artifact's name (falling back to its id), and the resulting version is
recorded on the event's artifact_delta. Saving is best-effort: it is a
no-op when no artifact service is configured and never breaks A2A
response handling on a per-artifact failure.

Fixes google#3145.
@google-cla

google-cla Bot commented Jun 22, 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.

@vaibhav-patel

Copy link
Copy Markdown
Author

@googlebot I signed it!

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.

Save artifacts from RemoteA2aAgent to Orchestrator session

1 participant