🔴 Required Information
Describe the Bug:
FunctionNodes in an ADK 2 graph Workflow are invisible to BigQueryAgentAnalyticsPlugin. A workflow made of function nodes produces BigQuery rows for the invocation and for any Agent nodes, but not a single row that identifies a function node or carries its result.
Two independent causes, both narrow:
-
NodeRunner never dispatches plugin callbacks. rg plugin_manager src/google/adk/workflow/ returns zero matches across all 29 files. Agent nodes are covered only incidentally, because _llm_agent_wrapper.py:325 calls agent.run_async(ic) and the callbacks fire from inside BaseAgent. FunctionNode._run_impl has no equivalent path, so before_agent_callback / after_agent_callback / the tool callbacks never fire for it.
-
BigQueryAgentAnalyticsPlugin.on_event_callback ignores Event.output. Function-node events carry their payload in Event.output with Event.content unset (_base_node.py:179, Event(output=validated)). Every content path in on_event_callback reads event.content or event.actions; rg 'event\.output' src/google/adk/plugins/bigquery_agent_analytics_plugin.py returns zero matches. So the one hook that does fire for function nodes discards their payload.
The net effect is that a node emits an event, the plugin receives it, and nothing is written.
Steps to Reproduce:
pip install google-adk==2.3.0
- Run the script under Minimal Reproduction Code below. It needs no GCP access —
_log_event is stubbed to record the event_type of each row the plugin would write.
- Compare the recorded rows against the two nodes that ran.
Expected Behavior:
A two-node workflow should produce BigQuery rows that identify step_one and step_two and carry their outputs, comparable to the AGENT_STARTING / AGENT_COMPLETED coverage an Agent node gets.
Observed Behavior:
agent/tool callbacks fired: NONE
on_event_callback saw:
path='repro_wf@1/step_one@1' output=True content=False
path='repro_wf@1/step_two@1' output=True content=False
BigQuery rows the plugin would write: ['USER_MESSAGE_RECEIVED', 'INVOCATION_STARTING', 'INVOCATION_COMPLETED']
Three rows, none referencing either node. The events reach on_event_callback with correct node_info.path, so the identity information is present and simply unused.
In a real workflow the only node-derived rows are incidental STATE_DELTA entries from nodes that happen to write ctx.state — nodes that only return a value are entirely absent.
Environment Details:
- ADK Library Version:
google-adk==2.3.0 (also verified against main @ 27548e39)
- Desktop OS: macOS 15 (darwin 24.6.0)
- Python Version: 3.13
Model Information:
- Are you using LiteLLM: No
- Which model is being used: N/A — the repro contains no LLM call
🔴 Required Information
Describe the Bug:
FunctionNodes in an ADK 2 graphWorkfloware invisible toBigQueryAgentAnalyticsPlugin. A workflow made of function nodes produces BigQuery rows for the invocation and for anyAgentnodes, but not a single row that identifies a function node or carries its result.Two independent causes, both narrow:
NodeRunnernever dispatches plugin callbacks.rg plugin_manager src/google/adk/workflow/returns zero matches across all 29 files.Agentnodes are covered only incidentally, because_llm_agent_wrapper.py:325callsagent.run_async(ic)and the callbacks fire from insideBaseAgent.FunctionNode._run_implhas no equivalent path, sobefore_agent_callback/after_agent_callback/ the tool callbacks never fire for it.BigQueryAgentAnalyticsPlugin.on_event_callbackignoresEvent.output. Function-node events carry their payload inEvent.outputwithEvent.contentunset (_base_node.py:179,Event(output=validated)). Every content path inon_event_callbackreadsevent.contentorevent.actions;rg 'event\.output' src/google/adk/plugins/bigquery_agent_analytics_plugin.pyreturns zero matches. So the one hook that does fire for function nodes discards their payload.The net effect is that a node emits an event, the plugin receives it, and nothing is written.
Steps to Reproduce:
pip install google-adk==2.3.0_log_eventis stubbed to record theevent_typeof each row the plugin would write.Expected Behavior:
A two-node workflow should produce BigQuery rows that identify
step_oneandstep_twoand carry their outputs, comparable to theAGENT_STARTING/AGENT_COMPLETEDcoverage anAgentnode gets.Observed Behavior:
Three rows, none referencing either node. The events reach
on_event_callbackwith correctnode_info.path, so the identity information is present and simply unused.In a real workflow the only node-derived rows are incidental
STATE_DELTAentries from nodes that happen to writectx.state— nodes that only return a value are entirely absent.Environment Details:
google-adk==2.3.0(also verified againstmain@27548e39)Model Information: