GoogleCloudPlatform / GoogleCloudPlatform/BigQuery-Agent-Analytics-SDK

A2A: propagate task_id onto receiver spans (was 129b3)

Open
#138 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
47
Forks
21
Avg merge
2d 13h
Merged PRs (30d)
33

Description

## Why

Follow-up from [#129](https://github.com/GoogleCloudPlatform/BigQuery-Agent-Analytics-SDK/issues/129). The A2A joint lineage demo (#129's three PRs) stitches caller and receiver at **context/session level**:

```text
caller.A2A_INTERACTION.a2a_metadata."a2a:context_id"
==
receiver.agent_events.session_id
```

This works because `convert_a2a_request_to_agent_run_request` ([`request_converter.py:111`](https://github.com/google/adk-python/blob/main/src/google/adk/a2a/converters/request_converter.py#L111) in `adk-python`) sets `session_id := request.context_id`. But **per-span `a2a_task_id` propagation** onto receiver spans is not in place: a single A2A context can carry multiple tasks across requests, and the receiver-side ADK runtime never sees `RequestContext.task_id` as a first-class field, so the BQ AA Plugin has no way to stamp it on individual receiver spans.

Closing this gap unlocks **per-task lineage** in the auditor graph — currently the auditor can stitch the session boundary but cannot say "this specific tool call on the receiver corresponds to this specific delegation event on the caller."

## Scope (two-place change)

This is **not** a single-repo issue. The work splits cleanly into:

### Upstream `adk-python` change (out of this repo)

`request_converter.py` `convert_a2a_request_to_agent_run_request` needs to plumb `request.task_id` into either `RunConfig.custom_metadata` or an A2A-specific invocation-context field, so the receiver runtime carries the task_id through every span emitted during that A2A invocation.

Multi-task interleaving consideration: since `context.task_id` is currently fixed for the duration of a single `execute()` call (see [`a2a_agent_executor_impl.py:124-244`](https://github.com/google/adk-python)), a per-invocation stamp is sufficient inside that boundary. Receiver-side task propagation across requests sharing one A2A context is the real concern — propagation should be event/request-scoped, not only session-scoped.

### SDK plugin change (this repo, downstream of the upstream change)

`bigquery_agent_analytics_plugin.py` needs to read the propagated `task_id` from the receiver's invocation context and stamp it onto `attributes.a2a_metadata.\"a2a:task_id\"` for every receiver-side span, not just the caller-side `A2A_INTERACTION` event.

Once both sides land, the SDK view from #136 (`adk_a2a_interactions`) and the demo's auditor projection (`build_joint_graph.py`'s `remote_agent_invocations`) automatically benefit — `a2a_task_id` becomes per-span on the receiver side and the auditor can `JOIN ... ON caller.a2a_task_id = receiver.a2a_task_id` for true per-task lineage.

## Acceptance criteria

- [ ] Upstream `adk-python` change merged that plumbs `RequestContext.task_id` into the receiver's runtime such that the BQ AA Plugin can read it during span emission.
- [ ] BQ AA Plugin change merged that stamps `a2a:task_id` onto `attributes.a2a_metadata` for every receiver-side span during an A2A invocation.
- [ ] `examples/a2a_joint_lineage_demo/`'s `joint_property_graph.gql.tpl` extended to surface `a2a_task_id` on receiver spans (a new `RemoteTaskInvocation` or equivalent node label).
- [ ] BigQuery Studio Block 4 (right-to-explanation) extended to walk `a2a_task_id` so an auditor can ask "which specific task on the receiver corresponds to this delegation."

## Out of scope

- The A2A protocol itself doesn't need changes; `task_id` is already on the wire.
- Streaming / long-running A2A semantics (out of scope for the current demo, see #129's known limitations).

## Related

- Issue #129 — implementation contract for the three merged PRs (#132, #133, #135, #136).
- Companion follow-ups: cross-org IAM/redaction fixture, cross-ontology concept alignment.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.