fix: BigQuery plugin — A2A tool classification, self-consistent span tree, and A2A metadata#5325
Draft
caohy1988 wants to merge 4 commits intogoogle:mainfrom
Draft
Conversation
…SFER_A2A When a RemoteA2aAgent is registered via sub_agents, the BigQuery analytics plugin now correctly classifies transfers to it as "TRANSFER_A2A" instead of the generic "TRANSFER_AGENT". Classification is call-level: a single TransferToAgentTool with mixed local and A2A targets produces the correct label per invocation based on the selected agent_name. The fix is localized to the plugin — no changes to TransferToAgentTool or the ADK core. The plugin resolves the target agent at runtime via the invocation context's agent tree. Fixes google#5073 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…_callback The error callback path was still calling _get_tool_origin(tool) without the tool_args and tool_context needed for call-level A2A classification, leaving failed remote A2A transfers misclassified as TRANSFER_AGENT. Adds a callback-level regression test that exercises on_tool_error_callback with a TransferToAgentTool targeting a RemoteA2aAgent and asserts the logged tool_origin is TRANSFER_A2A. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…data Fixes two BigQuery analytics plugin issues: **google#5310 — phantom parent_span_id references:** When OTel instrumentation was active, _resolve_ids() derived parent_span_id from ambient framework spans (execute_tool, call_llm, etc.) that are never written to BQ, creating dangling references. The fix flips priority: plugin-stack span_id/parent_span_id are now preferred, with ambient OTel only used as a fallback when the plugin stack has no span. All 6 post-pop callbacks now always pass both span_id_override and parent_span_id_override from the plugin stack, removing the has_ambient gating. **google#5311 — A2A metadata not surfaced in BQ:** RemoteA2aAgent attaches correlation metadata (a2a:task_id, a2a:context_id, a2a:request, a2a:response) to event.custom_metadata, but on_event_callback() only logged STATE_DELTA and HITL events. The fix adds A2A_INTERACTION event detection: when an event carries a2a:request or a2a:response, it is logged with the truncated a2a:response as content and all a2a:* keys under attributes.a2a_metadata. Fixes google#5310, Fixes google#5311 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
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. |
Collaborator
|
Response from ADK Triaging Agent Hello @caohy1988, thank you for creating this PR! It looks like you have not yet signed the Contributor License Agreement (CLA). Please visit https://cla.developers.google.com/ to sign the agreement. This is necessary for us to be able to merge your contribution. Thanks! |
Without this entry the plugin creates the raw BQ rows but never generates a typed per-event view for A2A_INTERACTION, so users consuming the plugin through its generated views would not see the new A2A rows or extracted fields. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Apr 14, 2026
This was referenced Apr 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #5073, #5310, and #5311
Three fixes to the
BigQueryAgentAnalyticsPlugin, all localized to the plugin — no changes to ADK core.Fix 1: Classify TransferToAgentTool transfers to RemoteA2aAgent as TRANSFER_A2A (#5073)
When a
RemoteA2aAgentis registered viasub_agents=[], the plugin now correctly classifies transfers to it asTRANSFER_A2Ainstead of the genericTRANSFER_AGENT. Classification is call-level: a singleTransferToAgentToolwith mixed local and A2A targets produces the correct label per invocation based on the selectedagent_name.Changes:
_find_transfer_target()helper — searches the agent tree (sub-agents, parent, peers) for the transfer target_get_tool_origin()with optionaltool_args/tool_contextfor call-level transfer classificationafter_tool_callbackandon_tool_error_callbackto passtool_args/tool_contextTransferToAgentToolTRANSFER_AGENT(unchanged)TransferToAgentToolRemoteA2aAgentTRANSFER_A2A(new)Fix 2: Self-consistent BQ span tree (#5310)
When OTel instrumentation was active,
_resolve_ids()derivedparent_span_idfrom ambient framework spans (execute_tool,call_llm,invoke_agent,send_data) that are never written to BQ, creating phantom references. In production datasets, 92.8% of LLM_RESPONSE events and 10.3% of TOOL events had danglingparent_span_idvalues.Root cause:
_resolve_ids()Layer 2 (ambient OTel) unconditionally overrode the plugin stack'sspan_id/parent_span_id, and all 6 post-pop callbacks suppressed plugin-stack overrides when an ambient span was present (None if has_ambient else ...).Fix:
_resolve_ids(): plugin-stackspan_id/parent_span_idare now the preferred source. Ambient OTel only providestrace_id(always) and falls back for span IDs only when the plugin stack has no span.after_agent,after_run,after_model,after_tool,on_model_error,on_tool_error): always pass bothspan_id_overrideandparent_span_id_overridefrom the plugin stack. Thehas_ambientgating is removed.This ensures every
parent_span_idin BQ references aspan_idthat also exists in BQ, producing a self-consistent execution tree.Fix 3: Surface A2A metadata in BQ (#5311)
RemoteA2aAgentalready attaches correlation metadata (a2a:task_id,a2a:context_id,a2a:request,a2a:response) toevent.custom_metadataon both legacy (lines 504-520) and v2 (lines 575-590) A2A paths. However,on_event_callback()only loggedSTATE_DELTAand HITL events — the A2A metadata was silently dropped before reaching BigQuery.Fix:
on_event_callback()now detects events carryinga2a:requestora2a:responseincustom_metadataand logs anA2A_INTERACTIONevent with:content: truncateda2a:responsepayload (the remote agent's answer)attributes.a2a_metadata: all truncateda2a:*keys for cross-reference JOINsA2A_INTERACTIONadded to_EVENT_VIEW_DEFSwith extracted columns:response_content,a2a_task_id,a2a_context_id,a2a_request,a2a_responsea2a:task_id/a2a:context_id(no request/response payload) are not loggedE2E Validation (real Gemini + real BigQuery)
Tested with a real multi-agent setup:
26 rows landed in BigQuery. Results:
parent_span_idrefsA2A_INTERACTIONeventsa2a:task_id,a2a:responsemetadataTRANSFER_A2AclassificationTest plan
tool_originnot set to"A2A"whenRemoteA2aAgentis used viasub_agents#5073: A2A sub-agent, local sub-agent, A2A peer, mixed-target per-call, fallback without argstool_originnot set to"A2A"whenRemoteA2aAgentis used viasub_agents#5073 error path:on_tool_error_callbackwithRemoteA2aAgenttarget_resolve_idstests updated to reflect new priority rules_resolve_idstests: plugin-stack-wins-over-ambient, ambient-fallback-when-no-stackA2A_INTERACTIONtests: response metadata, request-only metadata, irrelevant metadata skipped, no metadata skipped🤖 Generated with Claude Code