Skip to content

feat(bq-plugin): Schema auto-upgrade, tool provenance (incl. A2A), HITL tracing, and span hierarchy fix#4556

Draft
caohy1988 wants to merge 1 commit intogoogle:mainfrom
caohy1988:feat/bq-plugin-enhancements-4554
Draft

feat(bq-plugin): Schema auto-upgrade, tool provenance (incl. A2A), HITL tracing, and span hierarchy fix#4556
caohy1988 wants to merge 1 commit intogoogle:mainfrom
caohy1988:feat/bq-plugin-enhancements-4554

Conversation

@caohy1988
Copy link

@caohy1988 caohy1988 commented Feb 19, 2026

Summary

Implements three of the five enhancements from #4554 (the plugin-side items), plus a bug fix for #4561:

  • Schema Auto-Upgrade (Item 5): Additive-only schema migration that automatically adds missing columns to existing BQ tables. Enabled by default (auto_schema_upgrade=True). A adk_schema_version label on the table tracks which version was applied.
  • Tool Provenance (Item 4): Adds tool_origin to TOOL_* event content, distinguishing six origin types: LOCAL, MCP, A2A, SUB_AGENT, TRANSFER_AGENT, and UNKNOWN via isinstance() checks on the tool object. A2A origin is detected by checking if an AgentTool wraps a RemoteA2aAgent.
  • HITL Tracing (Item 3): Emits dedicated HITL event types (HITL_CONFIRMATION_REQUEST, HITL_CREDENTIAL_REQUEST, HITL_INPUT_REQUEST + _COMPLETED variants) by detecting synthetic adk_request_* function calls in the event stream (on_event_callback) and user-sent completion responses (on_user_message_callback). Backwards-compatible — existing queries continue to work.
  • Span Hierarchy Fix (Span Hierarchy and Duration Inconsistency in BigQueryAgentAnalyticsPlugin #4561): Removes context.attach()/context.detach() calls from TraceManager.push_span(), attach_current_span(), and pop_span(). The plugin was injecting its spans into the shared OTel context, which corrupted the framework's span hierarchy when an external exporter (e.g. opentelemetry-instrumentation-vertexai) was active.

Schema Auto-Upgrade Design

How it works:

  1. On startup, _ensure_schema_exists() checks if the BQ table exists
  2. If the table is new → creates it with the canonical schema + adk_schema_version = "1" label
  3. If the table exists and auto_schema_upgrade=True (default):
    • Reads the adk_schema_version label from the table
    • If the label matches the current _SCHEMA_VERSION → skips (already up to date)
    • Otherwise, diffs actual columns vs. canonical schema, appends missing columns, and stamps the new version label

Key properties:

Property Detail
Additive only Only adds new columns — never drops, renames, or alters existing ones
Idempotent Version label ensures the diff runs at most once per schema version
Fail-safe Errors are logged, not raised — a failed upgrade doesn't crash the plugin
No previous schemas stored The diff compares actual table columns vs. current canonical schema — no need to track v1/v2/v3 definitions
Default enabled Safe because it's additive + idempotent; prevents silent column drift when upgrading ADK

Future schema changes:

  1. Add new SchemaField entries to _get_events_schema()
  2. Bump _SCHEMA_VERSION from "1" to "2"
  3. On next startup, _maybe_upgrade_schema sees "1" ≠ "2" → diffs → adds new columns → stamps "2"

Tool Origin Categories

Origin Detection Example
LOCAL isinstance(tool, FunctionTool) User-defined Python functions
MCP isinstance(tool, McpTool) MCP server tools (stdio/SSE)
A2A AgentTool wrapping RemoteA2aAgent Remote A2A protocol agents
SUB_AGENT isinstance(tool, AgentTool) (non-A2A) Local sub-agent delegation
TRANSFER_AGENT isinstance(tool, TransferToAgentTool) Agent-to-agent transfer
UNKNOWN Fallback for unrecognized BaseTool subclasses Custom tool implementations

HITL Tracing Design

The adk_request_credential, adk_request_confirmation, and adk_request_input names are synthetic function calls injected by the ADK framework — they never pass through before_tool_callback/after_tool_callback. HITL detection therefore lives in:

  • on_event_callback — detects adk_request_* FunctionCall parts in events emitted by the framework (request events)
  • on_user_message_callback — detects adk_request_* FunctionResponse parts in user messages (completion events)

Key Design Decisions

Decision Rationale
auto_schema_upgrade defaults to True Additive + idempotent + fail-safe; prevents silent column drift
Schema version starts at "1" Clean starting point; bumped 1 → 2 → 3 as schema evolves
No stored previous schemas Diff-based: compares actual columns vs. canonical schema
HITL detected via event stream adk_request_* are synthetic FunctionCalls that bypass tool callbacks
tool_origin in content dict (not column) Avoids schema change; content JSON is the extensibility point
Remove context.attach() (#4561) Plugin uses internal contextvar stack; OTel ambient context must not be mutated

Files Changed

  • src/google/adk/plugins/bigquery_agent_analytics_plugin.py — Core implementation
  • tests/unittests/plugins/test_bigquery_agent_analytics_plugin.py — 34 new tests

Test plan

  • 12 schema auto-upgrade tests: create with label, skip when disabled, add missing columns, skip when version matches, error handling, preserve existing columns, no-label tables, older version labels, idempotent, update_fields, default config, create_table Conflict
  • 6 tool provenance tests (LOCAL, MCP, A2A, SUB_AGENT, TRANSFER_AGENT, UNKNOWN)
  • 4 HITL unit tests (confirmation request, credential request, completion, no HITL for regular events)
  • 2 HITL end-to-end tests (full Runner confirmation flow with MockModel + BQ plugin; regular tool produces no HITL events)
  • 5 span hierarchy isolation tests
  • All 139 plugin tests pass (105 existing + 34 new)
  • End-to-end verified: multi-agent demo with all 6 tool_origin types logged to BigQuery with correct OTel span hierarchy
  • Autoformatter applied (pyink + isort)

Closes #4554
Fixes #4561

🤖 Generated with Claude Code

@google-cla
Copy link

google-cla bot commented Feb 19, 2026

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @caohy1988, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the BigQuery agent analytics plugin by introducing three key features. It provides an opt-in mechanism for automatic BigQuery table schema evolution, ensuring that new columns are seamlessly integrated into existing tables. It also enriches tool event logs with detailed provenance information, allowing for a clearer understanding of tool origins within the system. Finally, it adds granular tracing for Human-in-the-Loop interactions, providing more specific insights into agent-user collaborations without impacting current analytics workflows.

Highlights

  • Schema Auto-Upgrade: Introduced an opt-in auto_schema_upgrade flag to automatically add missing columns to existing BigQuery tables and track schema versions using table labels for governance.
  • Tool Provenance: Added tool_origin to TOOL_* event content, distinguishing tool sources as LOCAL, MCP, SUB_AGENT, TRANSFER_AGENT, or UNKNOWN.
  • HITL Tracing: Implemented additional Human-in-the-Loop (HITL) specific events (HITL_CONFIRMATION_REQUEST, HITL_CREDENTIAL_REQUEST, HITL_INPUT_REQUEST, and their _COMPLETED variants) for adk_request_* tools, ensuring backward compatibility with existing analytics queries.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/google/adk/plugins/bigquery_agent_analytics_plugin.py
    • Defined constants for schema versioning and Human-in-the-Loop (HITL) tool names and event mappings.
    • Implemented a new helper function _get_tool_origin to determine the source of a tool (e.g., LOCAL, MCP, SUB_AGENT).
    • Added auto_schema_upgrade configuration option to BigQueryLoggerConfig.
    • Modified the _ensure_schema_exists method to incorporate schema version labeling and trigger auto-upgrade if enabled.
    • Introduced _maybe_upgrade_schema method to add missing columns to an existing BigQuery table and update its schema version label.
    • Updated before_tool_callback, after_tool_callback, and on_tool_error_callback to include the tool_origin in event content and to emit specific HITL request/completion events for relevant tools.
  • tests/unittests/plugins/test_bigquery_agent_analytics_plugin.py
    • Added a new test class TestSchemaAutoUpgrade to verify the functionality of schema auto-upgrade, including table creation, column addition, version matching, and error handling.
    • Added a new test class TestToolProvenance to confirm correct tool origin identification for various tool types.
    • Added a new test class TestHITLTracing to ensure that HITL-specific events are correctly emitted for adk_request_* tools and not for regular tools.
Activity
  • All 124 plugin tests passed, including 19 newly added tests.
  • Code formatting was applied using pyink and isort.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@adk-bot adk-bot added the tools [Component] This issue is related to tools label Feb 19, 2026
@adk-bot
Copy link
Collaborator

adk-bot commented Feb 19, 2026

Response from ADK Triaging Agent

Hello @caohy1988, thank you for your contribution!

It looks like the Contributor License Agreement (CLA) has not been signed. Please sign the CLA to proceed with the review process. You can find more information in the "checks" section at the bottom of the pull request.

Thank you!

@caohy1988 caohy1988 marked this pull request as draft February 19, 2026 17:22
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The pull request introduces several significant enhancements to the BigQuery Agent Analytics plugin, including an opt-in schema auto-upgrade feature, tool provenance tracking, and dedicated HITL (Human-in-the-loop) tracing. The implementation of the schema auto-upgrade is robust, using table labels for versioning and ensuring that only additive changes are made to existing BigQuery tables. Tool provenance correctly identifies the origin of tools (LOCAL, MCP, SUB_AGENT, etc.) while handling inheritance hierarchies appropriately (e.g., ensuring TransferToAgentTool is distinguished from its parent FunctionTool). The HITL tracing adds valuable visibility into human-interaction tools without breaking existing query patterns. The code is well-structured, follows existing patterns, and includes comprehensive unit tests covering all new functionality and edge cases.

@caohy1988 caohy1988 changed the title feat(bq-plugin): Schema auto-upgrade, tool provenance, and HITL tracing feat(bq-plugin): Schema auto-upgrade, tool provenance, HITL tracing, and span hierarchy fix Feb 20, 2026
@caohy1988 caohy1988 changed the title feat(bq-plugin): Schema auto-upgrade, tool provenance, HITL tracing, and span hierarchy fix feat(bq-plugin): Schema auto-upgrade, tool provenance (incl. A2A), HITL tracing, and span hierarchy fix Feb 20, 2026
…n hierarchy fix to BigQuery Agent Analytics plugin

This CL adds four enhancements to the BigQuery Agent Analytics plugin and fixes a span hierarchy corruption bug.

- **Schema Auto-Upgrade:** Additive-only schema migration that automatically adds missing columns to existing BQ tables on startup. A `adk_schema_version` label on the table (starting at `"1"`, bumped with each schema change) makes the check idempotent — the diff runs at most once per version. Enabled by default (`auto_schema_upgrade=True`) because upgrades are additive-only and fail-safe. Pre-versioning tables (no label) are treated as outdated, diffed, and stamped. No previous schema versions need to be stored; the logic diffs actual columns against the current canonical schema.

- **Tool Provenance:** Adds `tool_origin` to TOOL_* event content, distinguishing six origin types — `LOCAL` (FunctionTool), `MCP` (McpTool), `A2A` (AgentTool wrapping RemoteA2aAgent), `SUB_AGENT` (AgentTool), `TRANSFER_AGENT` (TransferToAgentTool), and `UNKNOWN` (fallback) — via `isinstance()` checks with lazy imports to avoid circular dependencies.

- **HITL Tracing:** Emits dedicated HITL event types (`HITL_CONFIRMATION_REQUEST`, `HITL_CREDENTIAL_REQUEST`, `HITL_INPUT_REQUEST` + `_COMPLETED` variants) for human-in-the-loop interactions. Detection lives in `on_event_callback` (for synthetic `adk_request_*` FunctionCall events emitted by the framework) and `on_user_message_callback` (for `adk_request_*` FunctionResponse completions sent by the user), not in tool callbacks — because `adk_request_*` names are synthetic function calls that bypass `before_tool_callback`/`after_tool_callback` entirely.

- **Span Hierarchy Fix (google#4561):** Removes `context.attach()`/`context.detach()` calls from `TraceManager.push_span()`, `attach_current_span()`, and `pop_span()`. The plugin was injecting its spans into the shared OTel context, which corrupted the framework's span hierarchy when an external exporter (e.g. `opentelemetry-instrumentation-vertexai`) was active — causing `call_llm` to be re-parented under `llm_request` and parent spans to show shorter durations than children. The plugin now tracks span_id/parent_span_id via its internal contextvar stack without mutating ambient OTel context.

Total tests: 139 (up from 105).

Closes google#4554
Fixes google#4561

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@caohy1988 caohy1988 force-pushed the feat/bq-plugin-enhancements-4554 branch from 330c8e6 to 0fb959d Compare February 20, 2026 06:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tools [Component] This issue is related to tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Span Hierarchy and Duration Inconsistency in BigQueryAgentAnalyticsPlugin Enhance ADK BigQuery Agent Analytics Plugin

2 participants

Comments