Skip to content

feat(adk): trace workflow nodes and tool calls - #895

Merged
Abhijeet Prasad (AbhiPrasad) merged 2 commits into
mainfrom
abhi/instrument-adk-workflows-9245626f
Oct 8, 2026
Merged

Abhijeet Prasad (AbhiPrasad) merged 2 commits into
mainfrom
abhi/instrument-adk-workflows-9245626f

Conversation

@AbhiPrasad

@AbhiPrasad Abhijeet Prasad (AbhiPrasad) commented Oct 8, 2026 •

Copy link
Copy Markdown
Member
  • Add task spans for ADK Workflow and graph node execution while preserving existing agent spans.
  • Add tool spans for ADK workflow _ToolNode calls, including arguments and outputs.
  • Cover direct workflow tool nodes and a recorded Gemini agent/tool turn with tests.

Closes #863.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-08T17:31:41.991139Z 1a91a89 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6ac39ce4d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment thread py/src/braintrust/integrations/adk/tracing.py Outdated
Comment thread py/src/braintrust/integrations/adk/integration.py
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 6744578 into main Oct 8, 2026
83 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi/instrument-adk-workflows-9245626f branch October 8, 2026 18:00
Abhijeet Prasad (AbhiPrasad) added a commit that referenced this pull request Oct 9, 2026
## AI Summary

With `braintrust.auto_instrument()`, every Gemini request made through
Google ADK produced two nested `llm` spans with the same token usage:
ADK's `llm_call [...]` and Google GenAI's `generate_content`. Trace
summaries counted the request's tokens and LLM calls twice.

ADK always sends model calls through a separately instrumented provider
client, so this PR lets that integration own the `llm` span and its
usage. The JS SDK's ADK plugin and our pydantic-ai, DSPy and LlamaIndex
integrations already work this way.

- **ADK span:** `llm_call [...]` is now a `task` span and no longer logs
token metrics or usage metadata. It keeps its input, output,
model/provider/tools metadata, `llm_call_type` and
`time_to_first_token`. GenAI's `generate_content` remains the only `llm`
span and carries the full usage: tool-use prompt tokens, reasoning
tokens and `usage_by_modality`.
- **`setup_adk()`:** it now also enables the Google GenAI integration,
so `setup_adk()`-only users still get a Gemini `llm` span with tokens.
The import happens inside the function, so the `wrap_*` helpers don't
pay for it. `auto_instrument()` enables both already, and
`auto_instrument(google_genai=False)` still turns GenAI off.

Fixes #896 (SDK-525).

## Before / after

One Gemini request replaying the recorded `test_adk_captures_metrics`
response, each mode in a fresh process:

| Mode | Before: `llm` spans | Before: tokens (prompt / completion) |
After: `llm` spans | After: tokens (prompt / completion) |
|---|---|---|---|---|
| `auto_instrument()` (reported case) | 2 | 58 / 10 | 1 | 29 / 5 |
| `setup_adk()` only | 1 (ADK) | 29 / 5 | 1 (GenAI) | 29 / 5 |
| GenAI only | 1 | 29 / 5 | 1 | 29 / 5 |

## Behavior changes

- Spans named `llm_call [...]` are now `task` spans. Queries filtering
ADK spans by `type = llm` will match GenAI's `generate_content` instead.
- ADK agents on non-Gemini models (LiteLlm, Claude, custom model
classes) only get token usage when that provider's integration is on.
`auto_instrument()` turns them on; with `setup_adk()` alone, those calls
no longer get token metrics. The `setup_adk()` docstring now says so.
- Users who call only the manual `wrap_flow()` helper, without
`setup_adk()`, need GenAI instrumentation enabled to keep token metrics.

## Tests

No cassettes were re-recorded. GenAI instrumentation doesn't change the
outgoing HTTP request, so the existing recordings replay unchanged.

- **`auto_test_scripts/test_auto_adk.py`:** runs the reported
`auto_instrument()` scenario in a subprocess against the recorded Gemini
response. It asserts that only `generate_content` carries usage and that
its parent is a `task`-typed `llm_call`.
- **`test_adk_captures_metrics`:** covers the `setup_adk()`-only path
with the same assertions.
- **Other ADK tests:** they now use a shared
`_assert_provider_owns_llm_spans` helper, which checks one GenAI `llm`
child per ADK model call, with only those children carrying usage. Tests
that inspect ADK's request shape select the `llm_call` spans by name.
- **Red / green:** both regression tests failed before the fix, with two
`llm` spans of 29/5 tokens each. Against `main`'s source, 7 tests fail;
with the fix, all pass.

## Validation

- **`test_google_adk(latest)`:** 18 passed, including the workflow tests
from #895, which this PR is rebased onto.
- **`test_google_adk(2.6.3)` and `test_google_adk(1.14.1)`:** 15 passed,
3 skipped each; the skips are the workflow-only tests. The 1.14.1
session resolves `google-genai` 1.75.0, which GenAI instrumentation
supports.
- **`test_google_genai(latest)`:** 43 passed, 2 skipped.
- **`test_core -k lazy`:** passed. Importing
`braintrust.integrations.adk` still loads neither `google.genai` nor
`google.adk`.
- **Lint:** `make lint` and `make pylint` pass.
- **Not tested live:** nothing ran against the live Gemini API or the
Braintrust dashboard. All runs replay recorded responses.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- sfk:bot-coauthor -->
Co-authored by @starfolkai[bot]

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

google-adk: instrument Workflow nodes and workflow tool calls

2 participants