Skip to content

BQAA Java preview readiness: parity and safety gaps vs Python plugin #1316

Description

@caohy1988

Summary

The Java BigQuery Agent Analytics plugin is close to internal dogfood, but it does not look ready to announce as preview parity with the Python BQAA plugin yet. This issue tracks the fixes needed before preview.

Reviewed (pinned SHAs — main has since moved, so all Java line references in this issue and its comments are against the Java SHA below):

  • Java google/adk-java at ce6af87e209e9cc718fb987ef1c01665e0be2432
  • Python google/adk-python at 38d715cbae2ab160ea1833baa3eebd8c3c93120f (the follow-up verification comment below cross-checked against Python 400f512d812a0c92ebee5d13b5e7448516a55eae; the behaviors cited here match across both)

P1 preview blockers

  • Add sensitive-key redaction in Java logging/truncation.

    • Java JsonFormatter.smartTruncate recursively copies object fields without redacting secrets.
    • Python redacts client_secret, access_token, refresh_token, id_token, api_key, password, and temp:* before logging.
    • Add tests for nested maps, tool args/results, session state, A2A/custom metadata, and custom tags.
  • Fix HITL and user-message resume handling.

    • Java onUserMessageCallback checks functionCall() and emits HITL_*_COMPLETED.
    • Python handles user-message function_response parts; HITL responses emit HITL_*_COMPLETED, and non-HITL long-running tool resume responses emit TOOL_COMPLETED with pair keys.
    • Add pause_kind and function_call_id parity for long-running tool joins.
  • Align event taxonomy with Python before preview.

    • Java currently emits STATE_DELTA for every event, even when there is no state delta.
    • Python only emits STATE_DELTA for non-empty state changes and also emits AGENT_TRANSFER, EVENT_COMPACTION, AGENT_STATE_CHECKPOINT, and TOOL_PAUSED.
    • Update Java view definitions for the added event types.
  • Preserve BQAA execution-tree span semantics under ambient OpenTelemetry.

    • Java currently prefers ambient OTel span IDs when present.
    • Python keeps span_id and parent_span_id as the BQAA internal execution tree when the plugin stack exists; ambient OTel is used for trace_id and optional correlation metadata.
    • This is important so parent_span_id points to another BigQuery row rather than a framework span that was never logged.
  • Make table bootstrap production-safe.

    • Java creates the table without timestamp partitioning; Python creates day partitioning on timestamp.
    • Java sets tableEnsured = true before table check/create/upgrade succeeds, so a first-run IAM/table race can prevent retries in the same process.
    • Mark ensured only after successful setup; keep retrying after setup failures.

P2 parity and preview-contract gaps

  • Decide and document default table/view behavior.

    • Java defaults to dataset agent_analytics, table events, and createViews(false).
    • Python defaults to table agent_events and create_views=True.
    • If Java keeps different defaults, preview docs should call that out clearly.
  • Add ADK envelope parity.

    • Python stamps attributes.adk with schema version, app name, source event id, node, branch, scope, route/render/rewind metadata, and long-running pair keys.
    • Java currently has flatter event-specific attributes and lacks the canonical envelope path used by Python views/joins.
  • Ensure root agent name is initialized.

    • Java TraceManager.initTrace() sets root agent name but does not appear to be called by the plugin, so attributes.root_agent_name can remain the sentinel value.
  • Guard workflow/no-agent callbacks.

    • Python resolves the agent column defensively when InvocationContext.agent is absent and falls back to Event.author for source-event rows.
    • Java directly uses invocationContext.agent().name(), which may drop rows if workflow-driven callbacks have no current agent.

Suggested test checklist

  • Secret redaction for nested payloads and all logging paths.
  • Empty state_delta produces no STATE_DELTA row.
  • User-message functionResponse emits HITL completion or long-running TOOL_COMPLETED as appropriate.
  • TOOL_PAUSED/TOOL_COMPLETED rows share function_call_id and pause_kind for joins.
  • Ambient OTel trace is preserved while BQAA span_id / parent_span_id remain internally joinable.
  • Table creation sets timestamp partitioning and clustering.
  • Failed table setup is retried on later events.
  • Java view SQL includes the Python-parity event types and pair-key columns.

References

Metadata

Metadata

Assignees

Labels

waiting on reporterWaiting for reaction by reporter. Failing that, maintainers will eventually closed it as stale.

Fields

No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions